Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I don't really get what's special about OCaml with these points they raise? Wouldn't almost any strongly typed language do? Wouldn't TypeScript also tick all these boxes?

EDIT: I wouldn't choose TypeScript either for this type of use case, but not for the reasons they state, that's my point





Typescript (javascript) is kind of a joke compared to what ocaml brings to the table.

Ocaml has a top in class typesystem, a "faster than Go" compiler and (in 2025) good tooling. It allows you to say fuck it and write a while loop if you need to. Hell you can even do OOP. Also it has an incredible module system and full type inference. It also has an effect system, and good concurrency features (ocaml 5).

I cant say many other languages that has all the same features.


It's the combination with concurrency that makes this a hard problem.

And OCaml excels at solving that sort of problem. OCaml and Erlang are the only two languages that I'm aware of that have a really clean way of doing this, in most other languages there is always some kind of kludge or hack to make it work and at best you're going to do something probabilistic: it seems to work, even under load, so it probably is good now. Until six weeks later on an idle Tuesday the system deadlocks and you have no idea how it happened.


What advantage does OCaml have over Haskell here? I find software transactional memory in Haskell so simple to work with that I have lost all fear of concurrency, but what am I missing out on?

I personally find OCaml more pragmatic than Haskell.

Haskell has a steeper learning curve IMHO: monads are pervasive and are hard to understand, laziness isn't a common programming pattern and it adds complexity. I find type classes confusing as well, it's not always clear where things are defined.

I like that OCaml is close to the hardware, there are no complex abstractions. The module system makes it easy to program in the large (I love mli). If you avoid the more advanced features, it's a super simple language.


I should have specified. I wasn't asking about OCaml vs Haskell in general[0], but what advantage does OCaml have with respect to concurrency?

[0] I think most people just end up post-rationalizing whatever choice they have already invested in, I know I do :) With that in mind, maybe I as a mainly-Haskell dev should instead list some things I miss from OCaml: faster compile times, non-recursive `let` by default, polymorphic variants, labeled arguments


Its mostly about practicality. Haskell is kind of pain when you need IO, as in when you go there there is no way out.

Ocaml is more practical, and less punishing (you can do IO without monads), but the most important diffrence is performance. Haskell is VERY hard to make predictable because its lazy. Ocaml is strict so general system performance is much easier to predict.

But they are sibling languages in my book, while i still prefer ocaml over haskell.


Also IMO the dev tooling is better for OCaml. Far better compile times.

A big part of interacting with APIs (which I imagine Stategraph does) is just dealing with records, and working with records in Haskell is really annoying unless you bring in lenses which bring a lot of complexity.


Tooling was kind of bad previously. But dune has got really good. I like the new dune developer preview thing that is still in beta.

https://preview.dune.build/


Wow that looks slick!

• Stategraph manages Terraform state, so correctness isn't optional

TypeScript has soundness issues that OCaml does not have

• Strongly-typed data structures catch field errors at compile time

TypeScript does have this, although the guarantees are in practice weaker since libraries may have incorrect type definitions

• Type-safe SQL queries prevent schema drift before deployment

There are TypeScript libraries that offer this, so fair point!

• Immutability by default eliminates race conditions

TypeScript is not immutable by default

• PPX generates correct JSON serialization automatically

TypeScript does not have an equivalent to PPX infrastructure AFAIK. If there is, it's definitely not as widely used within the ecosystem compared to PPX for OCaml.

Edit: Downvoters care to respond?


Besides the better type system, OCaml is a compiled language, you don't need workarounds like rewriting code in Rust and Go, as it happens on TypeScript/JavaScript world.

Certainly there are specifics between the type systems that differentiate. TypeScript generally chooses to enforce types in an ergonomic way whereas OCaml chooses to enforce types in a sound way. Whether or not that is a meaningful differentiator for someone is up to them.

This blog post shows the elements of OCaml that motivate us to use it. Is it complete? No. Maybe it should be more explicit that we like using OCaml, and these technical aspects aren't unique but certainly benefits we see.


Functional programming is immutable by default. TypeScript and many other typed languages don't really stop you from clobbering things, particularly with concurrency. Rust does. But immutability with GC is a lot easier to use than Rust if you don't need the performance of Rust.

That is only true since people started equating FP with Haskell.

OCaml as the discussion subject on this thread, allows for mutable data structures, and I am old enough to have been taught Lisp as one possible avenue for FP.


They have mutability, but it's generally not encouraged. The default is immutability.

It is available, that is all that matters.

But what is functional besides haskell? Purescript? Elm I guess. Ocaml is not. It has for loops even. You can write pure functional ocaml but people don't. It mattered a lot less when it didn't have true concurrency, but now clobbering things in ocaml is quite possible.

Define functional?

Even Haskell is not functional in the strictest sense. It has unsafe IO. It can throw exceptions. Functions may not halt.


Fair. Agda, gallina, f* maybe?

My point was that without any escape hatches or magic you can code a segfault starting in ocaml5. That may be true of haskell? It is true of rust too, though the only known way to do it isn't something that is likely to happen by accident and is tracked as a bug. In ocaml5 if you use domain, it is down to experience skill, and some luck to be sure you used atomic when necessary. I'm a bad programmer despite going on four decades of experience. I'm not even remotely methodical. If I adopt ocaml for a project I'm using 4 or adding something that fails the pipeline if it finds domain anywhere.


> you can code a segfault starting in ocaml5

It shouldn't, the OCaml 5 memory model bounds the reach of data races in both space and time. [1] Thread-unsafe code won't be correct when misused, but it will stay memory safe unless you reach for an additional escape hatch (or you find an implementation bug of course).

[1]: https://ocaml.org/manual/5.4/memorymodel.html

I'm much more concerned about the amount of poorly vetted escape hatches in wide use in OCaml, mainly for bindings.


You are right! As of 5.1.1 at least it catches the cross domain access I was using to smash things. From what I am reading it sounds like it didn't work in 5.1 I could go try it in godbolt to find out when it was fixed, but I kind of don't care. Very exciting, I like ocaml and was lamenting the changes.

That makes a lot more sense: The earliest 5.x releases weren't stable at all despite the non-prerelease version numbers. I waited for longer than I wanted to before upgrading from the LTS to 5, but right now it should be ok to switch as long as the few regressions, like the GC pacing issue, don't affect you workload.

Shouldn't most application programmers in OCaml be reaching for EIO or some other well-tested abstraction?

When there was no true concurrency, only preemption, eio was safe. Not now, you can still clobber things.

Edit: i was wrong! Since at least 5.1 it catches the cross domain access and errors gracefully.


Eio didn't exist before multicore OCaml actually, it was designed for it.

FP has nothing to do with mutability. You seem to lack a basic understanding what the common FP languages are, and what FP actully is.

Pure functional programming languages do not allow mutable state. They can simulate it with monads, and they typically have impurities to allow io sode effects, but a for loop is an inherently imperative construct. Mostly functional languages like ocaml have things like ref. Functional languages aren't just about functions being composable and having no side effects, they also require that once a value is bound to a name, that it does not change. That isn't just pedantry either, it is what allows safe concurrency by default.

Ocaml is immutable. It has ref if you need mutation, this is not the default thing you grab tho. Haskell has unsafe and IORef, that does basically the same thing. Scala, rust etc has all escape hatches.

A loop by itself is not non-fp, as i can do the exact same thing via recursion. Its just syntax.

Hell, i can write a never halting program in lambda calculus with a fixed point combinator causing "undefined behaviour".


StandardML (standard metalanguage), scheme?

Doesn't scheme have a set macro? I think for purity you'd have to go to something used for proofs that doesn't actually interact with the world.

OCaml has a much stronger type system than Typescript.

The real question is "why not Rust?". I've used both a fair bit and OCaml's only major advantage IMO is compile time. That doesn't seem compelling enough to put up with the downsides to me.


I'm the CTO of Terrateam. For "why not rust", I have found the downsides of Rust not compelling enough to use it. We don't need close-to-metal performance. We don't really need the borrow checker, a GC is fine. We are immutable by default so the borrow checker doesn't help much there.

Great choice by way, I feel too many reach out for Rust, because they lack the perspective ML type systems are not something introduced by Rust, rather a long linage of languages since ML/Standard ML.

Plus, OCaml kept the SML tradition in its robust module system, with modules as first-class citizens and ML-style functors, this is something hard to see nowadays, even among ML-inspired languages.

The sense I get from some comments is that if you need a type system and to compile to an executable, Rust is the only option, otherwise you can use pretty much anything. But, as you say, MLs have been compiling to binaries for decades. One of the first online books on OCaml is for systems programming.

I know that isn't everyone's view, but I do hope posts like this, even if not technicaly deep, at least let people know that there are lots of options out there.


I don’t like OCaml myself, but I’d pick it over rust here as bare metal perf is not necessary, and time wasting fighting the borrow checker is just not worth it.

It is worth it in my opinion because it's mostly a one-time cost (learning how it works and what is allowed), and in return you get less buggy program structures (it basically forces you not to write spaghetti code). Also you have to worry about it much less if you don't need 100% performance and are happy to clone everything.

Occasionally I do still fight it, e.g. if you want a self-borrowing structure there still isn't a great solution (I think Rust should support position independent borrows) but overall it's fine.


Ocaml has a garbage collector. It's less of a struggle than Rust.

Answer is easy, not everyone needs the performance boost provided by borrow checker, 99% of the time some kind of automatic resource management is good enough.

Rust is a pain

Rust has too many footguns. Ocaml is usually more safe.



Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: