OCaml is a surprisingly different language: it has both syntax and semantic features I've not seen elsewhere.
Following the GrokkingALanguage format, let's look at features you may not have seen before.
Merlin is code analysis tool OCaml, offering classic IDE feaetures like go-to-definition, code completion, and type-at-cursor.
That's table stakes: Merlin has some incredible features I've not used elsewhere.
type MyList = | Cons of (int * MyList) | Nil let takes_list (x : MyList) = x
Ask Merlin to destruct
x on the last line, and you get this:
let takes_list (x : MyList) = match x of | Cons _ -> (??) | Nil -> (??)
This makes pattern matching a joy to use.
Merlin has some even more exotic features, such as a type-driven function search.
Even if you've dabbled with Haskell, OCaml has some odd bits of syntax.
[1, 2] is legal syntax, but it's not a list of a numbers. It's actually shorthand for
Precedence can be surprising too:
[let y = 2 in y; 3] doesn't work as you'd expect.
This is particularly unfortunate for blocks:
if true then f 1 else f 2; g 3
g 3 is unconditionally executed!
Nesting match statements can end up with a type error rather than a parse error.
Solution: I've found #ocaml on Freenode to be a great place to ask questions.
ocamlformat will indent your code in a way that makes the precedence obvious too.