I am going to dump my thoughts, methods, codes, experiences and rants while learning OCaml into this thread.
This is probably the 5th or 6th time I am attempting to learn an ML, in the past I tried out Reason, OCaml, F# and discontinued for unknown reasons, I don’t remember having any roadblocks or complaints, perhaps laziness. There is no guarantee this will continue either.
I am keeping the documentation and Real World OCaml as primary source of education. The posts will be on a Day <n>: <Place an angry title here> format.
I am going to use paper and pencil to learn the language at first, before getting keyboard happy, a practice I last flowed in 2003 when learning Scheme.
That way I won’t get too ahead of myself and start prematurely assuming things. I also think that Ocaml is a very pencil friendly language.
Set the machine up though. Followed the “Installation Chapter” if Real World OCaml. I also think I will follow their tutorial and scribble some stuff on the paper, rather than the book.
Let’s see how this approach works for me. I will be in no hurry with this.
I was typing this with Chrome in my phone and I realized how annoying this is to switch between tabs with their tab group settings. This gets doubly annoying with the bottom bar which threw me at a 500 year old tab somehow as I was typing. Can anyone suggest a good browser for Android? I hate the UX.
Firefox, absolutely, supports extensions and all! I switch between like 8 browsers on android depending on purpose, but Firefox is my absolute default goto one, especially since its huge speed boost last year!
As promised, I did not touch the computer other than installing the system and running at least one “Hello OCaml” program (Couldn’t prevent myself from doing that). The rest was mostly pencil and paper.
OCaml is very appealing, visually. I don’t think I would have appreciated the | syntax had I not started with an editor. For example, the following code…
let rec sigma f = function
|  -> 0
| x :: l -> f x + sigma f l;;
…does look good in the editor, but when typing it, I would probably feel weird, especially having been a Python programmer for some time. But I have this habit of scratching out extra lines for visual inspection when writing with a pencil, and this made total sense when I was scratching a few programs out. Some more tidbits from my experience:
I totally dig the let rec mentioning of recursion! Explicit is better than implicit.
Treating = as an equality operator will take some time to sink in.
A * B notation is <3 very Cartesian.
Ugh dealing with error through exception, no language could satisfy me with their exceptions, this is because they all do the same things differently, overloading my brain with 10 patterns that could just be one. At least OCaml way is closer to the two language I am currently using most (Python and Elixir, and I usually avoid exception in the latter).
let..in is a form I like, I remember seeing that as an “alternative” in a ReasonML tutorial where they kindof negatively marketed it, but I think I would prefer this syntax.
OPAM looked good, as did Dune, but I mostly read about them, not used them, yet.
Module system is not a paper/pencil friendly system to learn, so saved those pearls for the long weekend.
As an Elixir programmer, I already knew I’d love the pattern matching capabilities of OCaml! I couldn’t have fathomed the beauty and power of their typing system in the first few days but I think I have some idea on what to expect. I will spend the upcoming weeks deciphering those, alongside the toolchains.
I think I am ready to get on the computer with OCaml. And I will change my decision to predominantly use the official Tutorials and use the book “Real World OCaml” instead and use the official ones as reference. The book is very well written.
What I foresee is, the “Module System” will become a bit of challenge for me and probably will be asking help on this region. Or maybe not.
Overall, the first 2/3 days were amazing and I can tell it’s one of those languages that I’d stick to and improve upon.
This is not so much the modern way in OCaml. The standard library is very old and still has a lot of exceptionisms, the core library by jane street is basically a full-out replacement of the std lib with much more modern practices, it is more ‘rusty’, lol.
If you know generics in a language, it’s basically like that. A module is basically a struct that can carry types with it too.
Going to leave paper and pencil and start coding from tomorrow. Lots of things that we’re inconsequential on paper would throw errors for sure, but at least I’ll have more empathy when faced with them!
I don’t actually include Jane Street’s Core/Base because I usually don’t reach for them. That’s one of the, in my opinion, issues with Real World OCaml: it very heavily relies on and presents Core as ‘the alternative standard library that everyone should use’ when in reality it’s a very heavyweight dependency that usually only large applications can justify. It’s also not ported to Windows (same with Jane Street’s Async, which is why I recommend Lwt for concurrency).
I think it’s a good idea to start with the libraries that are shipped with OCaml:
core library (note, not Jane Street Core), this lists the built-in types and exceptions of the language
standard library (Stdlib), this provides a lot of functionality, especially in recent OCaml versions. Especially important: List, String, Set, Map, Hashtbl, Printf. Also look into Sys (e.g. Sys.getenv) and Filename (file name operations, portable directory separator, etc.)
unix library (Unix system calls), the name is a slight misnomer as it also (mostly) works on Windows.
So that leaves the final note–instead of Real World OCaml, I would actually recommend Cornell’s Functional Programming in OCaml, which is based on their lecture notes for their course, with a long history of teaching OCaml (and doesn’t rely on any alternative standard libraries).
By the way, I am enjoying this thread a lot and will be happy to jump in as well if any questions
Does this weight express itself in larger byte size of the final binary, or more load on the GC systems (and thus lags), or anything else?
I am asking because nowadays people don’t seem to care much about byte sizes – Golang and Rust in particular produce fairly large binaries but people still love them. I do prefer smaller binaries but I admit I don’t feel very strongly about it either.
What I always say, contrary to the Jane Street school of thought, is to first check if everything you need is already provided by the standard library (Stdlib) or other dependencies in your existing dependency chain. E.g., need more string utility functions? Many libraries may bring in the stringext dependency already. And so on. There may be no need to bloat the dependency size more.