Back to essays

Why I Still Code in OCaml

Wesley Tan
5 min read
TechnologyProgramming

In a world dominated by JavaScript, Python, and increasingly Rust, admitting you write OCaml feels almost quaint. Like showing up to a startup hackathon with a functional programming textbook from 1998.

But I keep coming back to OCaml. Not out of nostalgia or academic stubbornness, but because it fundamentally changes how I think about code.

Type Systems as Thought Partners

The best thing about OCaml isn't the syntax or the performance, it's the type system. When you write OCaml, the compiler isn't just checking for errors. It's helping you think through the structure of your problem.

Consider a simple example: modeling a payment system. In Python or JavaScript, you might represent payment states as strings: "pending", "completed", "failed". Easy enough. But what happens when you need to add "refunded" or "partially_paid"? You search through your codebase, update string comparisons, and hope you caught everything.

In OCaml, you'd use a variant type:

type payment_status =
  | Pending
  | Completed of { transaction_id: string; timestamp: float }
  | Failed of { error: string }
  | Refunded of { original_transaction: string; refund_amount: float }

Now the type system forces you to handle every case. Add a new state? The compiler will show you every place that needs updating. Miss a case? It won't compile. The type system becomes documentation that can't go out of date.

Learning to Think in Types

But more importantly, working with a strong type system trains you to think about data structure and program flow differently. You learn to "make illegal states unrepresentable", to design types such that invalid combinations simply can't exist in your codebase.

This discipline carries over to other languages. Even when I'm writing TypeScript or Python, I find myself thinking: how would I model this in OCaml? What invariants am I trying to maintain? How can I structure this so errors are caught at compile time rather than runtime?

The Joy of Immutability

OCaml is also deeply functional, which means data is immutable by default. This takes getting used to, you can't just mutate variables or modify objects in place. But once you adapt, it's liberating.

Bugs caused by unexpected mutations vanish. Reasoning about concurrency becomes tractable. You can refactor with confidence because functions that don't mutate state are far easier to understand and test.

The Practical Tradeoff

Of course, OCaml isn't perfect for everything. The ecosystem is smaller. The community is niche. If you're building a web app or mobile application, you'll probably reach for JavaScript or Swift.

But for systems that demand correctness, compilers, type checkers, financial systems, OCaml shines. And more broadly, learning OCaml makes you a better programmer in any language.

Final Thoughts

I don't write everything in OCaml. But I'm glad I learned it, and I return to it whenever I need to think clearly about complex systems. In an industry that often prioritizes speed over rigor, OCaml is a reminder that sometimes, the best way to move fast is to think carefully first.