OCaml: a Rust developer's first impressions

Rust developers exploring OCaml are finding strong similarities in type systems and algebraic data types, but also sharp contrasts in paradigms: OCaml’s functional bias, powerful type inference, and new algebraic effects in v5 make it feel both elegant and alien to those used to Rust’s explicit lifetimes and imperative style. Commenters debate performance, error handling (exceptions vs `Result`/panics), and the practical impact of linked lists, recursion, and generics, while noting that OCaml’s tooling (especially OPAM and Windows support) and learning curve can be real barriers. Many see Rust as a successful “ML-inspired” systems language that brought advanced type-checking to a wider audience, whereas OCaml remains attractive for expressiveness and safety but less accessible for everyday or corporate use.

Relationship between OCaml/ML and Rust

  • Many see Rust as “an ML with a borrow checker” rather than OCaml as “Rust without” one.
  • Rust’s appeal is often attributed to ML-style features: algebraic data types, Option/Result, powerful type inference, pattern matching.
  • Others argue Rust is too imperative and lacks features like higher‑kinded types and proper GC-backed closures to be a “true ML.”
  • Rust originally had a GC and evolved toward a C++ replacement with strong safety guarantees.

Safety, Exceptions, and Panics

  • Some criticize OCaml’s pervasive exceptions as making control flow harder to reason about and complicating “safety” proofs.
  • Counterpoint: exceptions don’t harm memory safety in a GC language; the real issue is “exception safety,” which Rust also struggles with via panics and unwind semantics.
  • Rust panics are compared to exceptions; they can be caught, but many recommend panic=abort or avoiding panics outside main.

Performance and Use Cases

  • Disagreement over whether ML languages are “ass slow.”
  • Several claim OCaml/F# sit performance-wise near Java/C# and far above Python/Ruby, especially with native code and arrays instead of lists.
  • Rust succeeds by applying ML-like types to systems programming and memory safety, where GC’d MLs are seen as too heavy.

Types, Inference, and Interfaces

  • Strong type inference is praised as reducing boilerplate, but some miss explicit annotations for readability and clearer error locations.
  • Suggested compromise: annotate function parameters and public interfaces while letting the compiler infer the rest.
  • .mli interface files are defended as powerful for encapsulation and large-scale structure, though others find separate files duplicative and inconvenient.
  • Highly generic inferred types can be hard to understand; some argue they improve reasoning (“theorems for free”), others say they obscure intent.

FP Style: Lists, Recursion, and Iterators

  • Beginners are overexposed to linked lists and recursion; experienced developers say real OCaml often uses arrays, sequences, and mutable structures where appropriate.
  • Linked lists are still ubiquitous but not always optimal for performance.
  • Rust users note a similar split between iterator chains and imperative loops.

Learning Curve, Productivity, and Tooling

  • Several describe a steep paradigm shift from imperative/OOP to functional style; weeks or months may not be enough to feel productive.
  • OCaml is seen as great intellectually but less obviously practical for some tasks like competitive programming.
  • Tooling is mixed: OCaml 5 effects and modern stdlib improvements are praised; OPAM is criticized as fragile, especially on Windows, though others consider it strong compared to some ecosystems.