OCaml Syntax Sucks (2016)

OCaml’s syntax, especially its `let` bindings and lack of clear terminators for constructs like `match`, divides developers between those who find it elegant and those who see it as confusing and error‑prone, particularly for newcomers. Commenters contrast OCaml with related languages such as F#, Haskell, Scala, and variants like ReasonML and ReScript, weighing trade‑offs in async support, tooling, documentation, and type system features. While many acknowledge sharp edges in error messages and library fragmentation, others highlight OCaml’s typing discipline, fast compiler, simple core language, and typing/reading ergonomics as strong advantages once autoformatting and good editor support are in place.

Overall view of OCaml syntax

  • Many find the article’s example misleading; any language can look awful if everything is crammed into one line.
  • Several argue let … in is natural and makes scoping explicit and easy to reason about.
  • Others say OCaml syntax does have problems, but not the ones in the article: main complaints are confusing precedence between let, if, match, fun, and ;, and hard‑to‑trace errors when in is omitted.

Real pain points: matches, errors, and dev UX

  • Repeated criticism that match has no explicit terminator, making nested matches easy to get wrong and producing poor error messages (“the rest of the file is broken”).
  • Error reporting in general is seen as weak, especially for beginners; syntax errors often point at the end of the file.
  • Autoformatting, LSP integration, extra parentheses / begin…end are widely recommended as mitigations.
  • Overall dev experience is polarizing: some advise avoiding OCaml entirely, others describe it as one of their most pleasant professional languages.

Arguments in favor of OCaml’s design

  • Praise for:
    • Whitespace‑insensitive syntax combined with a formatter.
    • Low punctuation density and ergonomic typing.
    • Clear scoping rules (look “upward” for definitions, three core concepts: values, types, modules).
    • Fast compiler, separate compilation, and sane defaults with accessible “escape hatches”.
  • Some like .mli interface files as clean, documentation‑friendly API surfaces, despite their different syntax.

Async, computation expressions, and effects

  • OCaml’s async via libraries (no special language support) is framed as a design strength, similar to Rust/Haskell/Clojure ecosystems.
  • In F#, computation expressions (task {}, async {}, seq {}) spark debate:
    • Pro: powerful, generic abstraction (beyond async), useful for many computational patterns.
    • Con: ugly “sub‑syntax”, high cognitive load when much code is async; preference from some for integrated syntax like async/await.
  • OCaml 5 + effects and structured concurrency are mentioned as promising for direct‑style async.

Ecosystem splits and alternatives

  • Confusion and frustration around the split between OCaml’s stdlib and Jane Street’s Core/Base; many online answers assume Core and have sparse docs.
  • ReasonML, ReScript, and Melange are discussed as alternative syntaxes/targets; perceptions range from “useful bridge to OCaml” to “unappealing JS‑like skin”.
  • Alternatives suggested for similar niches: F#, Scala, Gleam, Standard ML.

Meta and ergonomics

  • Some see low punctuation as readable; others argue it harms “visual parsing” compared to C‑like languages.
  • International keyboard issues with certain ASCII symbols (e.g., backticks) are raised.
  • A side thread proposes HN should discourage non‑HTTPS links; others question the practical threat model.