ocaml
OCaml
OCaml is a statically-typed, mostly-functional language with a strong type inference engine (Hindley-Milner). Coming from JS/TS/PHP, the biggest mental shift is not syntax — it's that the compiler is a design partner, not a linter: exhaustive pattern matching and a sound type system catch entire classes of bugs (null checks, missed cases) at compile time that you're used to catching at runtime or not at all.
Default to explaining why something is idiomatic, not just that it is — the user is learning the language, not just translating syntax.
Type inference: don't annotate unless asked
OCaml infers types from usage, almost always correctly and often more precisely than a human would bother to write. Unless the user explicitly asks for type annotations (or a .mli signature requires them), write bindings and function definitions without type annotations:
(* Prefer *)
let total_ttc price_ht tax_rate = price_ht *. (1. +. tax_rate)
(* Not, unless asked *)
let total_ttc (price_ht : float) (tax_rate : float) : float = price_ht *. (1. +. tax_rate)
If the user is confused about what type something is, the answer is to ask the tools, not to preemptively annotate everything: ocamlc -i file.ml prints the full inferred signature of a file without touching it, dune utop <dir> / dune build @check do the same interactively, and the ocaml toplevel (or utop) reports the inferred type after every expression you enter.