I've used OCaml a bit and found various issues with it:
* Terrible Windows support. With OCaml 5 it's upgraded to "pretty bad".
* The syntax is hard to parse for humans. Often it turns into a word soup, without any helpful punctuation to tell you what things are. It's like reading a book with no paragraphs, capitalisation or punctuation.
* The syntax isn't recoverable. Sometimes you can add a single character and the error message is essentially "syntax error in these 1000 lines".
* Ocamlfmt is pretty bad. It thinks it is writing prose. It will even put complex `match`es on one line if they fit. Really hurts readability.
* The documentation is super terse. Very few examples.
* OPAM. In theory... I feel like it should be great. But in practice I find it to be incomprehensible, full of surprising behaviours, and also surprisingly buggy. I still can't believe the bug where it can't find `curl` if you're in more than 32 Unix groups.
* Optional type annotation for function signatures throws away a significant benefit of static typing - documentation/understanding and nice error messages.
* Tiny ecosystem. Rust gets flak for its small standard library, but OCaml doesn't even have a built in function to copy files.
* Like all FP languages it has a weird obsession with singly linked lists, which are actually a pretty awful data structure.
It's not all bad though, and I'd definitely take it over C and Python. Definitely wouldn't pick it over Rust though, unless I was really worried about compile times.
I would suggest that people interested in using OCaml on Windows (or indeed, OCaml at all) try F# instead. It is still an ML-family language. Incidentally, by targeting the CLR, F# is considerably more deployable (both to users and to developers) than OCaml is. Plus, any old NuGet library written in C# or VB.NET can be used almost trivially in F#. This also solves the problem OP listed about a tiny ecosystem, because the C#/.NET ecosystem is massive.
I couldn't agree more with the parent commenter about OCaml documentation. Functional programmers appear to love terseness to an almost extreme degree. Things like `first` are abbreviated to `fst`, which is just odd. Especially now that good IntelliSense means there is no real functional (heh) difference between typing `.fi` and pressing Tab, and typing `.fs` and pressing Tab.
The F# documentation is comparatively very spiffy and detailed, with plenty of examples[1][2][3].
F# is indeed an ML-family language, but at this point it doesn't have all that much in common with OCaml specifically: it doesn't have the latter's structurally typed object model with inferred row-polymorphic types, nor its extremely powerful module system, not even many convenience features like open variants.
F# is worse because the type inferencing isn't as good. You need to type annotate in more places. It's a drag, because it feels like a missed opportunity to let the machine do work for you.
Additionally, one of the most pleasant and unique features of OCaml, strong named arguments, doesn't exist in F# (except in methods or whatever). Most programming languages don't have this (or it's hamfisted like in more dynamic languages) so it doesn't seem like a loss, unless you are very cozy with them in OCaml.
(I'm bitter about this one because named arguments give safety and convenience. But when you combine them with currying it's like 4 or 5 design patterns that are elegantly provided for you. You just do it implicitly, without ever having to study a book about using them.)
Finally, F# brings back the NULL problem that OCaml worked so hard to eradicate.
A lot of these are learning curve issues, but once you scale them you still permanently suffer with a very deficient, fragmented ecosystem. Until you have built up your own curated set of dependencies for your business stack, anyway.
> * Ocamlfmt is pretty bad. It thinks it is writing prose. It will even put complex `match`es on one line if they fit. Really hurts readability.
I suggest configuring ocamlformat to use the janestreet profile for better defaults.
> * Optional type annotation for function signatures throws away a significant benefit of static typing - documentation/understanding and nice error messages.
People should be providing .mli files, but don't. That said, an IDE with type hints helps this enormously. The VS Code plugin for OCaml is the best experience for noobs, hands down.
> * OPAM. In theory... I feel like it should be great. But in practice I find it to be incomprehensible, full of surprising behaviours, and also surprisingly buggy. I still can't believe the bug where it can't find `curl` if you're in more than 32 Unix groups.
> * Like all FP languages it has a weird obsession with singly linked lists, which are actually a pretty awful data structure
This made me chuckle. I've had that thought before, shouldn't the default be a vector on modern devices? Of course other collection types are available.
The reason why functional languages like linked lists so much is because they are very easy to make immutable without a lot of pain all around. If you implement an immutable vector in a straightforward way, though, you basically need to do a lot of copying for any operation that needs to construct one (the rigmarole with immutable strings, and existence of hacks such as StringBuilder, is a good illustration of the problem).
But you can have a data structure that is more like vector under the hood while still supporting efficient copy-with-modifications. Clojure vectors, for example.
I'd say that functional programming is probably one of the only domains where linked lists actually make sense. Vectors certainty have their use in more places though.
A good compiler will make the lists disappear in many cases. No runtime overhead. I actually love single linked lists as a way to break down sequences of problem steps.
Why would a specific way of structuring data in memory be relevant to breaking down sequences of problem steps?
If what you mean is the ability to think in terms of "first" and "rest", that's just an interface that doesn't have to be backed by a linked list implementation.
This was my problem as well, the object oriented related syntax is just too much. ML of which caml is a version of, has really tight syntax. The “o” in ocaml ruins it imo.
+10 for bad windows support, i think this is a key and weirdly underestimated reason
just to give an idea how bad, until recently, you could not just go to ocaml.org and download ocaml for windows, you had to either download one for mingw or wsl
so for many it was just not installable, i.e. for many we didnt have ocaml for windows, until very very recently
The Windows support is bad because OCaml is a PL designed by people who are deep in Linux life. Windows is not something that keeps them up at night. (Which isn't to say they didn't try, just, you know, not as much as it takes)
One of the things people often neglect to mention in their love letters to the language (except for Anil Madhavapeddy) is that it actually feels UNIXy. It feels like home.
I don't think you would be flagged. Rust definitely has flaws:
* Compile time is only ok. On par with C++.
* Async has a surprisingly number of footguns and ergonomic issues.
* There's no good solution to self-borrowing or partial borrows.
* While using macros is fine, writing them is pretty awful. Fortunately you rarely need to do that. Relatedly it is missing introspection support.
* Sometimes the types and lifetimes get very complex.
But overall I still much prefer it to OCaml. The syntax is much nicer, it's easier to read, the ecosystem and tooling are much better, the documentation is much better, and it actively hates linked lists!
* Crates.io is an unmoderated wasteland of infinite transitive dependency chaos
But my "favourite":
* It's 2025 and allocator-api (or its competitors) is still in nightly only and no sign of stabilizing
I work almost exclusively in Rust, and I like the language but in many respects a) Rust is the language that tokio ate, and b) it has been deluged with people coming from the NodeJS/NPM ecosystem doing Web Scale Development(tm) and its terrible practices around dependency management.
> Crates.io is an unmoderated wasteland of infinite transitive dependency chaos
Well, I'm not sure I agree with that. If by "unmoderated" you mean anyone can upload a crate without going through bureaucratic approvals processes then that seems like a good thing to me!
But you did remind me of one other majorly annoying thing about the crate system: the global namespace. It doesn't have the same security issues as Python's global package namespace, but it is really really annoying because you pretty much have to break large projects down into multiple crates for compile time reasons, and then good luck publishing those on crates.io. Plus you end up with a load of crate names like `myproject-foo`, `myproject-bar`, which is very verbose.
Oh and yeah, the Tokio situation is a bit sad.
Also the proliferation of some types of crates like error handling. This should really be in the standard library by now (or at least fairly soon). Any large project ends up with like 5 different error handling libraries just because dependencies made different choices about which to use. It's not a major issue but it is silly.
Overall though, still my favourite language by far.
> It just genuinely felt like the Go language designers didn’t want to engage with any of the ideas coming from functional programming.
You'd be right.
"The key point here is our programmers are Googlers, they’re not researchers. They’re typically, fairly young, fresh out of school, probably learned Java, maybe learned C or C++, probably learned Python. They’re not capable of understanding a brilliant language but we want to use them to build good software. So, the language that we give them has to be easy for them to understand and easy to adopt. – Rob Pike 1"
"It must be familiar, roughly C-like. Programmers working at Google are early in their careers and are most familiar with procedural languages, particularly from the C family. The need to get programmers productive quickly in a new language means that the language cannot be too radical. – Rob Pike 2"
Talking as someone who wrote OCaml at work for a while, the benefits of functional programming and the type guarantees that it's ilk provides cannot be understated; you only start to reach them, however, once most developers have shifted their way of thinking rather extremely, which is a time cost that that designers of Go did not want new Googlers to pay.
To this day, whenever I see Machine Learning abbreviated, my heart skips a beat, then I become crestfallen as I realize I'm not about to read something about Meta Language.
You believe I'd purposefully misread an abbreviation in a comment about misreading abbreviations, and also coincidentally tried to make fun of two other nationalities (maybe even three, depending on political views), all at the same time?
I mean pohl's joke above whooshed kjmh so it's all fine. The important thing for threads like this one is for us to name drop all of the weird programming languages that we have used, publicly avow the greatness of ones that we have not, and make a New Year's resolution that we will never follow, to actually pick up those great languages and write something in them...
I'd rather have that issue than seeing "AI" plastered all over the place. I'm of the opinion AI should be reserved for artificial general intelligence. These things aren't intelligent yet. They're just em-bloat-ified traditional machine learning techniques. Not that they're useless. I just hate the terminology.
If people start using the term AI, we better be living in I, Robot. Not whatever the hell this is.
We lost this fight at least by 1994 when Sun acquired “Thinking Machines,” which to its credit was bankrupting itself by making highly parallel supercomputers, at least. Now of course there is a new AI company of the same name. If the wrestling world echoes the computing world, one can only wonder what in 5-10 years will be the equivalent of Undertaker throwing Mankind off of Hell In A Cell to plummet 16 feet down through an announcer’s table...
I think Richard Feldman [0] proposed some of the most reasonable theories as to why functional programming isn't the norm. Your language needs to be the platform-exclusive language for a widely used platform, have a killer application for a highly desired application domain, or be backed by a monster war-chest of marketing money to sway opinions.
Since Feldman's talk, Python has grown much faster in popularity in the sense of wide use in the market place... but mostly because it's the scripting language of choice for PyTorch and AI-adjacent libraries/tooling/frameworks which is... a killer application.
I like OCaml. I started evaluating functional programming in it by taking the INRIA course online. I spent the last four and half years working in Haskell. I've built some side projects in Zig. I was a CL stan for many years. I asked this question a lot. We often say, "use the best tool for the job." Often that means, "use the tool that's available."
I think languages like OCaml, Rust, Haskell etc can be "popular," but in the sense that people like to talk about them and want to learn them and be able to use them (at least, as trends come and go). It's different from "popular" as in, "widely adopted."
> mostly because it's the scripting language of choice for PyTorch and AI-adjacent libraries/tooling/frameworks
I would politely disagree. Torch started in Lua, and switched to Python because of its already soaring popularity. Whatever drove Python's growth predates modern AI frameworks
Python was already big for scientists back in 2010. I remember working on Python tooling at the time, and DS/ML was one of our single largest user groups. It was already popular enough to have an IDE specifically for scientific Python use: https://en.wikipedia.org/wiki/Spyder_(software).
As far as I could tell, it had to do with two things. First, Python is notoriously dynamic and extensible, making it possible to implement "sloppy" syntax like advanced slicing or dataframes. But also, those guys had lots of pre-existing C and Fortran code, and Python had one of the easiest extensibility APIs to wrap it as high-level packages. And with IPython, you had a nice REPL with graphing to use all that from, and then of course notebooks happened.
I've dabbled in F# (and aside from the rough setup with little coherent information at the time) had a pretty good time. Actor-based concurrency was easy to grok. The one gotcha was whenever those mutable Arrays entered the picture.
I'd like to hear some practical reasons for preferring OCaml over F#. [Hoping I don't get a lot about MS & .NET which are valid concerns but not what I'm curious about.] I want to know more about day to day usage pros/cons.
It's a matter of trends: F# is losing compatibility with the overall CLR ecosystem due to the churn in C# features with poor F# interop, but F# has already mingled its design with the CLR's, too much to live on its own as a native language. Plus its compiler is slow and the tooling is getting increasingly unstable.
Meanwhile, OCaml got rid of its global lock, got a really fast-compiling native toolchain with stable and improving editor tooling, and has a cleaner language design with some really powerful features unavailable to F#, like modules/functors, GADTs, effects or preprocessors. It somehow got immutable arrays before F#!
F# still has an edge on some domains due to having unboxed types, SIMD, better Windows support and the CLR's overall performance. But the first two are already in the OxCaml fork and will hopefully get upstreamed in the following years, and the third is improving already, now that the opam package manager supports Windows.
> has an edge on some domains due to having unboxed types
If a language makes "unboxed types" a feature, a specific distinction, and has to sell "removing global lock" as something that is a massive breakthrough and not table stakes from 1.0, it can't possibly be compared to F# in favourable light.
I vouched for your dead comment because I get where you're coming from. But OCaml 1.0 was in 1996 in an academic setting. I care about the language I can use now, not the one I didn't use.
Let's not dismiss that their solution to remove the global lock has been both simpler than Python's (better funded?) ongoing work and backwards compatible; and the multicore support came with both a memory model with strong guarantees around data races, and effect handlers which generalize lightweight threads.
I agree that lack of unboxed types is a fatal flaw for several domains (Worse, domains I care about! I usually consider Rust/Go/.NET for those.) But when the comparison with OCaml is favourable to F#, the gap isn't much wider than just unboxed types. F# has an identity crisis between the ML parts and the CLR parts, its C# interop is decaying as the ecosystem evolves, and newer .NET APIs aren't even compatible with F# idioms (here's a .NET 6+ example [1]).
I did get some sense of that where F# sort of (actually is) 2nd class to C# which is slowly gaining some F# features, but F# itself isn't well promoted/supported.
As for missing language features, they can also be a double-edged sword. I slid down that slippery slope in an earlier venture with Scala. (IIRC mostly implicits and compile times).
There are libraries that simulate a lot of these things (e.g. https://github.com/G-Research/TypeEquality for GADTs). You're absolutely right that it's not as first class as in OCaml, but the tools are there if you want them.
I've written type-equality witnesses in F#, they can kinda recover type equalities (with cast methods) but not refute them, so you still need to raise exceptions for those cases.
We’ve used f# professionally for the computations-intensive parts of our product for a couple of years. Here’s what comes to mind:
1. Interop with C# is great, but interop for C# clients using an F# library is terrible. C# wants more explicit types, which can be quite hard for the F# authors to write, and downright impossible for C# programmers to figure out. You end up maintaining a C#-shell for your F# program, and sooner or later you find yourself doing “just a tiny feature” in the C# shell to avoid the hassle. Now you have a weird hybrid code base.
2. Dotnet ecosystem is comprehensive, you’ve got state-of-the web app frameworks, ORMs, what have you. But is all OOP, state abounds, referential equality is the norm. If you want to write Ocaml/F#, you don’t want to think like that. (And once you’ve used discriminated unions, C# error-handling seems like it belongs in the 1980’ies.)
3. The Microsoft toolchain is cool and smooth when it works, very hard to wrangle when it doesn’t. Seemingly simple things, like copying static files to output folders, require semi-archaic invocations in XML file. It’s about mindset: if development is clicking things in a GUI for you, Visual Studio is great (until it stubbornly refuses to do something) ; if you want more Unix/CLI approach, it can be done, and vscode, will sort of help you, but it’s awkward.
4. Compile-times used to be great, but are deteriorating for us. (This is both F# and C#.)
5. Perf was never a problem.
6. Light syntax (indentation defines block structure) is very nice until it isn’t; then you spend 45 minutes how to indent record updates. (Incidentally, “nice-until-it-isn’t” is a good headline for the whole dotnet ecosystem.
7. Testing is quite doable with dotnet frameworks, but awkward. Moreover. you’ll want something like quickcheck and maybe fuzzing; they exist, but again, awkward.
We’ve been looking at ocaml recently, and I don’t buy the framework/ecosystem argument. On the contrary, all the important stuff is there, and seems sometimes easier to use. Having written some experimental code in Ocaml, I think language ergonomics are better. It sort of makes sense: the Ocaml guys have had 35 years or so to make the language /nice/. I think they succeeded, at least writing feels, somehow, much more natural and much less inhibited than writing F#.
OCaml is a much more powerful language. Take a look at functors, for example, or modules as first-class values, or GADTs, or its object system that can do type inference from use:
# let foo x = x#frob;;
val foo : < frob : 'a; .. > -> 'a = <fun>
F# is often called "OCaml for .NET", but it is a misrepresentation. It is an ML-family language for .NET, but aside from that ML core they don't have much in common.
Whether those features are more valuable to you than the ability to tap into .NET libraries depends largely on what you're doing.
> It is an old language, and there are a few features that could probably be left out like the OOP-related features, and some libraries in the ecosystem over-complicate things like in Haskell.
If one can stand a language that is just a little bit older, there is always Standard ML. It is like OCaml, but perfect!
I love SML, and came to OCaml a bit begrudgingly initially just for a larger ecosystem. But, I think the object system gets a unjustly bad wrap. The OCaml object system is dope. It is rarely needed and not the best feature for most use cases, but when you want structurally-typed records, or need open recursion (or need to represent JS objects for the amazing `Js_of_ocaml`), they are a perfect fit.
I love standard ml (I'm currently writing a compiler for it), but it's far from perfect. There are weird special cases in the language definition like the ad-hoc overloading between int and real, or the annoying value restriction. Records also feel half-baked, with no support for updating fields or for partially-specified records where the full set of fields is not known
While it's not yet standard nearly all Standard ML implementations support what has become known as "Successor ML" [0]. A large subset of Successor ML is common to SML/NJ, MLton, Poly/ML, MLKit and other implementations.
That includes record update syntax, binary literals, and more expressive patterns among other deficiencies in Standard ML.
For me the two big remaining issues are:
1) There's only limited Unicode support in both the core language and the standard library. This is a big issue for many real-world programs including these days the compilers for which SML is otherwise a wonderful language.
2) The module system is a "shadow language" [0] which mirrors parts of SML but which has less expressiveness where modules cannot be treated as first-class values in the program. Also if you define infix operators in a module their fixity isn't exported along with the function type. (Little annoyance that gets me every time I am inclined to write Haskell-style code with lots of operators. Though maybe that's just another hint from the universe that I shouldn't write code like that.) Of course, the fix to that would be a fundamentally different language; not a revised SML.
I far preferred Standard ML when I learned both back in the day, but it was OCaml that won the headspace it seemed.
Ironically probably because it had the "O"bjects in it, "which was the style of the time"... something that has since dropped off the trendiness charts.
OCaml has been one of those "almost there" languages since at least 2002. Most of the worthwhile ideas in OCaml will be absorbed into more popular languages by the time existing friction is sorted out. :/
> Our hope is that these extensions can over time be contributed to upstream OCaml.
Yeah, its more just extensions to support their use cases at scale. Think of it more as bleeding edge ocmal, once they work out kinks/concerns they'll get merged back into the language OR if it remains ultra specific it'll stay in oxcaml.
Python gets forked in other investment banks as well. I wouldn’t say that is evidence of any deficiencies, rather they just want to deal with their own idiosyncrasies.
A different perspective is that JS has made practical application of PLT part of their secret sauce, and deepening into their PLT roots is thickening the sauce.
The main user has been writing extensions to the compiler that they test before pushing for integration like they have done for the past twenty years or so. They publish these versions since last year.
Hardly a failure and certainly not something mandatory to keep things from failing over. Your initial comment is extremely disingenuous.
This is the wrong interpretation of the oxcaml project. If you look at the features and work on it, it's primarily performance or parallelism safety features.
The latter going much further than most mainstream languages.
Yeah, but when these things happen I ask myself, is Jane Street successful because of ocaml, or did they just happen to pick ocaml and then make it work?
There might be some power in attracting all the people who happen to love ocaml, if there are enough of competent people to staff your company, but that's more a case of cornering a small niche than picking on technical merits
They've spoken about this before and might not have picked OCaml if they had to make the decision again today. I think at the time it made the most sense.They can also make it work in any language as they claim to only recruit the best and brightest in the world (this may be the truth). My opinion is they could have chosen many languages and had similar results while balancing different trade-offs.
Regarding attracting talent, they've said they don't care about existing knowledge of OCaml as the language part is something they train staff on anyway. Their interviews are brutal from what I recall. I could be an OCaml expert and have no chance of making it through an interview without equal talent in high performance fintech and relevant mathematics.
> I could be an OCaml expert and have no chance of making it through an interview without equal talent in high performance fintech and relevant mathematics.
Unless their hiring process has changed in the past few years, if you're a dev they're not hiring you for your financial skills, just general problem solving and software development ability. It is (was?) the usual Google-style algorithms/data structures rigamarole, but somewhat more challenging.
Do those devs actively use OCaml? I thought most of the folks writing OCaml were writing the actual trade algorithms as opposed to infrastructure folks. My post was made off what I recall their lead technologist saying.
Absolutely. Everyone uses OCaml at Jane Street; pretty much everything at Jane Street is OCaml. If an OCaml version of something doesn't exist, there's a decent enough chance that they'll write it themselves rather than resort to a non-OCaml solution.
Like I said, my information might be a hair out of date, but it's first-hand.
Gotcha. Mine is just some old blog posts and a long talk from the guy that got OCaml started. Nothing like your actual first person experience. Thanks for adding!
Unless you're building another JS, it'd be nice if there were other companies so heavily invested in it. There's a lot out there beyond compiler prototypes and high speed financial trades, but there's not enough talk of people using ocaml for those things.
Ocaml was (historically, at least) used by Facebook for basically all of their linter/compiler/type checker work. The hack checker was in Ocaml, as was the JS thing (flow, maybe?).
So that does seem to be a good use-case for the language.
That was why I mentioned compilers along with HFT. Rust was originally an ocaml based compiler too.
I don't build HFTs and my compilers are just for fun. None of my day jobs have ever been a situation where the smaller ecosystem and community of ocaml was offset by anything ocaml did better than the selected options like .net, Java, go, rails, C or anything else I've touched. Heck, I've written more zig for an employer than ocaml, and that was for a toy DSL engine that we never ended up using.
Because plenty of people have been shipping great projects in Ocaml since it was released so it doesn’t seem to be much of an issue to many.
I doubt Ocaml will be surpassed soon. They just added an effect system to the multicore rewrite so all things being considered, they seem to be pulling even more ahead.
Beginners face the following problems: there's multiple standard libraries, many documents are barely more than type signatures, and data structures aren't printable by default. Experts also face the problem of a very tiny library ecosystem, and tooling that's often a decade behind more mainstream languages (proper gdb support when?). OCaml added multicore support recently, but now there is the whole Eio/Lwt/Async thing.
I used to be a language nerd long ago. Many a fine hour spent on LtU. But ultimately, the ecosystem's size dwarfs the importance of the language itself. I'm sympathetic, since I'm a Common Lisp man, but I don't kid myself either: Common Lisp isn't (e.g.) Rust. I like hacking with a relic of the past, and that's okay too.
TBH I think it's rather a post-hoc rationalization of why the language is not popular.
> there's multiple standard libraries
Scala has a far more fragmented ecosystem with Cats, Scalaz, Zio and Akka. C++ and Java have a bunch of stdlib extensions like boost, Guava, Apache Commons etc.
> many documents are barely more than type signatures
Can be said of most of Java, Kotlin, Scala, Erlang etc etc. Just compiled javadocs, sometimes with a couple of unhelpful lines.
> data structures aren't printable by default
Neither they are in C++
I think the real reason it's not popular is that there are languages which solve more or less the same problems of system programming but look far more familiar to an avg. programmer who was raised on C++ and Java.
I wanted to use OCaml since 2002, since it was a GC'd language with good performance, achieving a lot with relatively few lines of code. Being a language nerd, I was (am?) positively inclined to the language. Yet there was always something that made it notably less pleasant to solve my current problem in than in than some other language.
If it had trouble getting traction with me, that's bad news.
Meanwhile the mainstream has progressed a lot since 2000. GC is the standard, closures are normal, pattern matching and destructuring are increasingly so. While HM-style type inference is not mainstream, local type inference is (and I'm no longer convinced that global type inference is the way). Algebraic data types aren't unusual anymore.
A few years back I just threw in the towel and went with Rust; this happened after I volunteered to improve OCaml's gdb support (including DWARF hell), which went nowhere. I wish Rust compiled faster, and a GC'd language is usually more productive for my problems, but in every other regard it stole what should have been OCaml's thunder. And when popular successor languages eventually appear, they'll do it even better.
Pony's garbage collection and runtime can
yield performance faster than C/C++/Rust because
the compiler eliminates data races at
compile time, and thus no locks are needed.
It features implementations of Dmitri Vyukov
(www.1024cores.net) algorithms for
work stealing and Multi-producer single
consumer queues that use only a single atomic
instruction to read. The designer,
Sylvan Clebsch, is an ex-game-developer and
ex-high-frequency-trading-infrastructure
engineering lead; he knew what he was
doing when he designed the language
for high performance on multicore systems.
On the other hand, you do have to re-wire
your thinking to think in terms of Actors
and their state, and this is kind of hard
to wrap one's head around if you are used
to Go's CSP or the popular async/await
approaches -- it is a somewhat
different paradigm.
There is only one standard library and it shipped with the compiler.
> data structures aren't printable by default
So? That’s the case with most languages. Ocaml has a deriver to make types printable and a REPL which automatically prints for testing.
> tooling that's often a decade behind more mainstream languages
Opam is a fully featured package manager, dune works fine, bucks2 supports Ocaml.
> proper gdb support when?
Ocaml has had a rewindable debugger since approximately forever.
> OCaml added multicore support recently, but now there is the whole Eio/Lwt/Async thing.
Lwt was the default and everyone agrees eio is the future now that effects are there. Async is a Janestreet thing with pretty much no impact on the language outside of Janestreet.
Honestly, I maintained my initial point. Ocaml alleged frictions were always widely overstated.
When I was writing Ocaml professionally 15 years ago, there was no dune and no opam and it was already fairly easy to use the language.
Rocq is an excellent example of something OCaml was designed for. FFTW3 is another great example. Unison too.
Generally, you want stuff where you have to build a fairly large core from scratch. Most programs out there doesn't really fit that too well nowadays. We tend to glue things more than write from nothing.
Rocq, Pfff and Flow, Vpnkit in Docker for Mac and Windows, the web version of Facebook Messenger at a point, Tezos, Unison, the Xen cloud platform, the Mirage unikernel.
Elixir is the closest thing to OCaml that has a chance at semi-mainstream usage IMO.
It has basically all of the stuff about functional programming that makes it easier to reason about your code & get work done - immutability, pattern matching, actors, etc. But without monads or a complicated type system that would give it a higher barrier to entry. And of course it's built on top of the Erlang BEAM runtime, which has a great track record as a foundation for backend systems. It doesn't have static typing, although the type system is a lot stronger than most other dynamic languages like JS or Python, and the language devs are currently adding gradual type checking into the compiler.
I think that a better question is why F# isn't a more popular language, since it's much closer to OCaml, than Elixir and you can use the whole Dotnet ecosystem in F#, which is one of the weakest points of OCaml (no libraries).
The answer is (most likely) Microsoft, I kid you not. I've worked with F# professionally for many years is its incredible how they are literally sitting atop a gold mine that is the output of Microsoft research and do basically nothing with it. Even though it's sold as an ecosystem, .NET revolves around C# and its related tooling.
"Type Providers" are an example of such negligence btw, it's something from the early 2010's that never got popular even though some of its ideas (Typed SQL that can generate compile-time errors) are getting traction now in other ecosystems (like Rust's SQLx).
My team used SQL Providers in a actual production system, combined with Fable (to leverage F# on the front end) and people always commented how our demos had literally 0 bugs, maybe it was too productive for our own good.
I think it’s odd that elixir doesn’t get more love. It ticks a lot of boxes that folks here get excited about, has a great ecosystem and tooling, BEAM is great, and it’s much more syntactically familiar than erlang to my eye. I know of a couple companies aside from the perennial goto examples that built sizable saas products backed by it.
The BEAM VM executing bytecode is slower than a compiled binary. Sure, it is great when compared to Python and other interpreted languages. Not so much when you need fast processing and raw CPU performance. It also loses out to the JVM in performance, but wins in memory consumption.
It is slower, but a big cause of the slowness is a lot of copying (immutable data structures and separate heaps for every process). Nowadays the BEAM has a JIT.
If you use type guards correctly the performance can be surprisingly good. Not C/C++/Rust/Go/Java good, but not too far off either. This is definitely a corner-case though.
But how many things involve fulfilling basic requests over a network pulling information from a database? Most things just don’t need that kind of performance.
Sure for basic, dead CRUD, the choice of middleware language rarely makes any difference.
But even bog-standard business processes eventually find the need for data-processing, crypto and parsing - the use-cases where people code Elixir NIF's. That is why for example you have projects like html5ever_elixir for parsing HTML/XML. Another use case is crypto - you have NIF's for several crypto libraries. Data processing - there are NIF's for Rust polars.
I always wanted to learn Elixir but never had a project where it could show it strengths. Good old PHP works perfectly fine.
Also corporations like their devs to be easily replaceable which is easier with more mainstream languages, so it is always hard for "newer" languages to gain traction. That said I am totally rooting for Elixir.
I think it’s great for boring stuff — the Phoenix web framework is really straightforward. Learning a whole new language paradigm and environment for a professional project you need to be productive in ASAP is definitely the worst kind of ‘not boring’ though.
I know of a Haskell shop and everybody said they’d have a hell of a time finding people… but all them nerds were (and are) tripping over themselves to work there because they love Haskell… though some I’ve talked to ended up not liking Haskell in production after working there. There seems to be a similar dynamic, if a bit less extreme, in Elixir shops.
Elixir is good at managing complexity. I love flattening hierarchy and dealing with edge cases right in function definitions using pattern matching. Every other language without it just feels crippled after getting used to the feature.
You don't get it from language tooling because you are compiling to a bytecode that runs in a virtual machine (BEAM).
The current tool to wrap your bytecode with a VM so that it becomes standalone is Burrito[1], but there's some language support[2] (I think only for the arch that your CPU is currently running? contra Golang) and an older project called Distillery[3].
Having loops is not the defining feature that separates functional from imperative. Where did this idea come from? I'm suddenly seeing it in a lot of places.
It is not the defining feature but loss of the loop is one of the most obvious differences for people who look at a functional language Rust has immutability, pattern matching, etc, but it remains an imperative language with "some functional features". Or this is my subjective analysis.
But, again, loops aren't automatically imperative per se. Consider loop / recur in Clojure for an example. For someone coming from JavaScript, it's not really much different from writing a while loop where every branch has to terminate with an explicit break or continue.
You can be functional "in spirit" more than purely functional. OCaml and Standard ML falls into this category. Ocaml has loops for instance. You might just not see many loops if code is written by OCaml developers, because there's frankly no need to use them in a lot of places. You often want to lift the abstraction level of iteration to an arbitrary data structure such that you get freedom of implementation. See Applicative and Monad.
I really wish people would quit pushing "functional". People equate that with "My programming is now always a recursive logic puzzle."
Talk about "immutable by default". Talk about "strong typing". Talk about "encapsulating side effects". Talk about "race free programming".
Those are the things that programmers currently care about. A lot of current Rust programmers are people who came there almost exclusively for "strong typing".
It's compiled to Erlang, not BEAM bytecode, as the latter is not a stable, backward-compatible API to target, and you lose all of the optimization work put into the Erlang compiler. It's also compiled to JavaScript, so it can run on both the front-end and back-end.
BEAM performance model trades throughput for isolation, which hurts CPU-bound tasks, and ironically, whenever you need speed, you end up using NIFs that break BEAM safety guarantees, and reintroduce the exact fragility Elixir was supposed to avoid.
In 2025, Elixir is a beautiful system for a niche that infrastructure has already abstracted away.
> In 2025, Elixir is a beautiful system for a niche that infrastructure has already abstracted away.
Do you mean Kubernetes?
My mental model of Erlang and Elixir is programming languages where the qualities of k8s are pushed into the language itself. On the one hand this restricts you to those two languages (or other ports to BEAM), on the other hand it allows you to get the kinds of fall over, scaling, and robustness of k8s at a much more responsive and granular level.
> whenever you need speed, you end up using NIFs that break BEAM safety guarantees, and reintroduce the exact fragility Elixir was supposed to avoid.
That's like complaining that unsafe{} breaks Rust's safety guarantees. It's true in some sense, but the breakage is in a smaller and more easily tested place.
It's not isolation which hampers throughput. That's a red herring. In fact, isolation increases throughput, because it reduces synchronization. A group of isolated tasks are embarrassingly parallel by definition.
The throughput loss stems from a design which require excessive communication. But such a design will always be slow, no matter your execution model. Modern CPUs simply don't cope well if cores need to send data between them. Neither does a GPU.
The grand design of BEAM is that you are copying data rather than passing it by reference. A copy operation severs a data dependency by design. Once the copy is handed somewhere, that part can operate in isolation. And modern computers are far better at copying data around than what people think. The exception are big-blocks-of-data(tm), but binaries are read-only in BEAM and thus not copied.
Sure, if you set up a problem which requires a ton of communication, then this model suffers. But so does your GPU if you do the same thing.
As Joe Armstrong said: our webserver is a thousand small webservers, each serving one request.
Virtually none of them have to communicate with each other.
What you wrote is roughly equivalent to this in C:
{
const int x = 1;
{
const int x = 2;
}
}
which is to say, there are two different `x` in there, both immutable, one shadowing the other. You can observe this if you capture the one that is shadowed in a closure:
iex(1)> x = 1
1
iex(2)> f = fn () -> x end
#Function<43.113135111/0 in :erl_eval.expr/6>
iex(3)> x = 2
2
iex(4)> f.()
1
Music being "good" is subjective. A programming language, however, can objectively be better if it allows a subset of programmers to better solve certain problems.
The reason for why OCaml is not more popular, thus, is that this subset is small. The reason for this may be either (a) habit or (b) it's not that much better than other languages. I'm gravitating to (b). OCaml guys seem to be quite dogmatic for the wrong reasons.
I posit (c) it’s from France and written mostly by French people and American naturally gravitates towards languages which generate hype in English and preferably from the USA.
Also it didn’t employ a marketing team to work on outreached and write fancy comments here and some people who have used it for 10 minutes are apparently offended by the Pascal-like syntax and can’t stop discussing it on every Ocaml discussion making every actual users tired.
> OCaml is weird in that it’s a garbage collected language for systems, similar to Go.
I don't understand why this isn't more popular. For most areas, I'd gladly take a garbage collector over manual memory management or explicit borrow checking. I think the GC in D was one of it's best features, but it's downfall nonetheless as everyone got spooked by those two letters.
I like the ML languages, and as many others I spent a lot of time with F#.
I would love to spend more time but even though Microsoft gives it plenty of support (nowhere near as much as C#), the community is just too small (and seems to have gotten smaller).
I kind of wish (like the OP mentioned) there was a ML (ocaml) like language that compiled to Go source. You would get the best of both worlds and access to a huge ecosystem.
I've never used it so can't speak from any experience, and unfortunately it doesn't seem particularly active (and doesn't mention a current status anywhere), and doesn't have a license, so shrug. When it's been posted here (https://news.ycombinator.com/item?id=40211891), people seemed pretty excited about it.
Borgo looks like some guys phd thesis. It looks like it was a fun experiment.
I feel a new simple ocaml like language that just compiled to Go would be really popular, really fast. And it would not even need to build a ecosystem, as Go already have all the things you need.
Yes, in every ML/OCaml tutorial, sooner or later the words object, class, and type inference appear and that’s when a once–minimalist language turns into an academic Frankenstein.
I don't think objects and classes are used much by OCaml programmers (not by me anyway). Type inference is a rather fundamental feature, and fairly easy to understand.
It's not a minimalist language, you know what the "O" in Ocaml stands for right? It's a multi-paradigm language that explicitly accommodates more styles of programming than Caml, it's why it exists.
OCaml is fantastic, but I avoided it and went with Rust for many projects because it had no multicore story and no green threads for a very long time. But it has that now, and I wish I could go back and start everything over in OCaml.
I've also felt very similar, and adopted Rust for those reasons. Even though I'd still love to have a garbage collected, AOT compiled ML-variant, using OCaml still feels like a step backwards now. OCaml's module system and generics feel clumsy and unintuitive now that I've used Rust's Trait system.
As a Rust newbie and seasoned Go dev, I'm pretty interested to knownwhere would people experienced in both OCaml and Haskell, would put it in the spectrum.
Languages have features/constructs. It's better to look at what those are. And far more importantly: how they interact.
Take something like subtyping for instance. What makes this hard to implement is that it interacts with everything else in your language: polymorphism, GADTs, ...
Or take something like Garbage Collection. It's presence/absence has a large say in everything done in said language. Rust is uniquely not GC'ed, but Go, OCaml and Haskell all are. That by itself creates some interesting behavior. If we hand something to a process and get something back, we don't care if the thing we handed got changed or not if we have a GC. But in Rust, we do. We can avoid allocations and keep references if the process didn't change the thing after all. This permeates all of the language.
My team still has 8 year old Haskell systems in production. We pivoted away from the language a few years ago, which I discuss here a bit: https://news.ycombinator.com/item?id=37746386
I personally love ML languages and would be happy to keep developing in them, but the ecosystem support can be a bit of a hassle if you aren't willing to invest in writing and maintaining libraries yourself.
OCaml has some high profile use at Jane Street which is a major fintech firm. Haskell is more research oriented. Both are cool, but wouldn't be my choice for most uses.
OCaml’s REPL is lovely, but I found myself having some friction with initial startup. The build/package system was pretty convoluted, and I ended up choosing JS’s Core stdlib for my needs (a simple compiler). With the new multicore release it’d be cool to see OCaml in some more practical projects!
From an outsider's perspective, it feels like Ocaml has more active development of features, between the new effects system they added in 5 and all the work Janestreet is doing to let Ocaml developers have more control over performance.
F# is not stagnant thankfully, it gets updates with each new version of dotnet (though I haven't checked what is coming with dotnet 10), but I don't recall anything on the level of the above Ocaml changes in years.
Oh yeah I love f#, I need to find more excuses to use it. I just wish it felt like MS was willing to invest more into it. But at least they have not abandoned it and continue to put some resources into its ongoing growth.
I loved Ocaml but now I love TypeScript more. It's got about the same amount of type safety, the ergonomics are better to me, and the packaging and ecosystem tooling are leaps and bounds above anything else.
I absolutely love the idea and methods behind OCaml, but the syntax.....
I also love Haskell and already feel that its syntax is not easy to grok on larger projects, but OCaml basically went "hold my beer" and went to town on that.
OCaml did become popular, but via Rust, which took the best parts of OCaml and made the language more imperative feeling. That's what OCaml was missing!
As someone who has worked professionally in both, programming in rust does not feel much like programming in OCaml. Working with traits in an imperative manual memory managed language is really different than working with proper modules in a mixed paradigm language with an awesome GC.
Rust is very different from Ocaml. Rust is a low level language with a borrow checkers, traits, no first class module system, no GADT, no effects.
The similarities are fairly superficial actually. It’s just that Rust is less behind the PL forefront that people are used to and has old features which look impressive when you discover them like variants.
There is little overlap between what you would sanely use Rust for and what you would use Ocaml for. It’s just that weirdly people use Rust for things it’s not really suited for.
> why isn’t OCaml more popular
I've used OCaml a bit and found various issues with it:
* Terrible Windows support. With OCaml 5 it's upgraded to "pretty bad".
* The syntax is hard to parse for humans. Often it turns into a word soup, without any helpful punctuation to tell you what things are. It's like reading a book with no paragraphs, capitalisation or punctuation.
* The syntax isn't recoverable. Sometimes you can add a single character and the error message is essentially "syntax error in these 1000 lines".
* Ocamlfmt is pretty bad. It thinks it is writing prose. It will even put complex `match`es on one line if they fit. Really hurts readability.
* The documentation is super terse. Very few examples.
* OPAM. In theory... I feel like it should be great. But in practice I find it to be incomprehensible, full of surprising behaviours, and also surprisingly buggy. I still can't believe the bug where it can't find `curl` if you're in more than 32 Unix groups.
* Optional type annotation for function signatures throws away a significant benefit of static typing - documentation/understanding and nice error messages.
* Tiny ecosystem. Rust gets flak for its small standard library, but OCaml doesn't even have a built in function to copy files.
* Like all FP languages it has a weird obsession with singly linked lists, which are actually a pretty awful data structure.
It's not all bad though, and I'd definitely take it over C and Python. Definitely wouldn't pick it over Rust though, unless I was really worried about compile times.
I would suggest that people interested in using OCaml on Windows (or indeed, OCaml at all) try F# instead. It is still an ML-family language. Incidentally, by targeting the CLR, F# is considerably more deployable (both to users and to developers) than OCaml is. Plus, any old NuGet library written in C# or VB.NET can be used almost trivially in F#. This also solves the problem OP listed about a tiny ecosystem, because the C#/.NET ecosystem is massive.
I couldn't agree more with the parent commenter about OCaml documentation. Functional programmers appear to love terseness to an almost extreme degree. Things like `first` are abbreviated to `fst`, which is just odd. Especially now that good IntelliSense means there is no real functional (heh) difference between typing `.fi` and pressing Tab, and typing `.fs` and pressing Tab.
The F# documentation is comparatively very spiffy and detailed, with plenty of examples[1][2][3].
[1]: https://learn.microsoft.com/en-gb/dotnet/fsharp/language-ref...
[2]: https://fsharp.github.io/fsharp-core-docs/
[3]: https://fsprojects.github.io/fsharp-cheatsheet/fsharp-cheats...
F# is indeed an ML-family language, but at this point it doesn't have all that much in common with OCaml specifically: it doesn't have the latter's structurally typed object model with inferred row-polymorphic types, nor its extremely powerful module system, not even many convenience features like open variants.
I find F# nowhere near as good as OCaml and think this comparison is ugly, but if I was forced to use a .NET platform I would almost certainly use F#
> nowhere near as good as OCaml
I'd really like to hear more about this. From what I've used of F# and OCaml, both languages are around 95% the same.
I'll give you my top 3.
F# is worse because the type inferencing isn't as good. You need to type annotate in more places. It's a drag, because it feels like a missed opportunity to let the machine do work for you.
Additionally, one of the most pleasant and unique features of OCaml, strong named arguments, doesn't exist in F# (except in methods or whatever). Most programming languages don't have this (or it's hamfisted like in more dynamic languages) so it doesn't seem like a loss, unless you are very cozy with them in OCaml.
(I'm bitter about this one because named arguments give safety and convenience. But when you combine them with currying it's like 4 or 5 design patterns that are elegantly provided for you. You just do it implicitly, without ever having to study a book about using them.)
Finally, F# brings back the NULL problem that OCaml worked so hard to eradicate.
If you are interested, I think I adress this here https://xvw.lol/en/articles/why-ocaml.html#ocaml-and-f
Thanks, this is a very nice article.
A lot of these are learning curve issues, but once you scale them you still permanently suffer with a very deficient, fragmented ecosystem. Until you have built up your own curated set of dependencies for your business stack, anyway.
> * Ocamlfmt is pretty bad. It thinks it is writing prose. It will even put complex `match`es on one line if they fit. Really hurts readability.
I suggest configuring ocamlformat to use the janestreet profile for better defaults.
> * Optional type annotation for function signatures throws away a significant benefit of static typing - documentation/understanding and nice error messages.
People should be providing .mli files, but don't. That said, an IDE with type hints helps this enormously. The VS Code plugin for OCaml is the best experience for noobs, hands down.
> OPAM
yes
> * OPAM. In theory... I feel like it should be great. But in practice I find it to be incomprehensible, full of surprising behaviours, and also surprisingly buggy. I still can't believe the bug where it can't find `curl` if you're in more than 32 Unix groups.
I couldn’t believe this was an actual bug in opam, and I found it: https://github.com/ocaml/opam/issues/5373
I don’t think that’s an opam bug, it’s an issue with musl, and they just happened to build their binaries with it.
> * Like all FP languages it has a weird obsession with singly linked lists, which are actually a pretty awful data structure
This made me chuckle. I've had that thought before, shouldn't the default be a vector on modern devices? Of course other collection types are available.
The reason why functional languages like linked lists so much is because they are very easy to make immutable without a lot of pain all around. If you implement an immutable vector in a straightforward way, though, you basically need to do a lot of copying for any operation that needs to construct one (the rigmarole with immutable strings, and existence of hacks such as StringBuilder, is a good illustration of the problem).
But you can have a data structure that is more like vector under the hood while still supporting efficient copy-with-modifications. Clojure vectors, for example.
I'd say that functional programming is probably one of the only domains where linked lists actually make sense. Vectors certainty have their use in more places though.
A good compiler will make the lists disappear in many cases. No runtime overhead. I actually love single linked lists as a way to break down sequences of problem steps.
Why would a specific way of structuring data in memory be relevant to breaking down sequences of problem steps?
If what you mean is the ability to think in terms of "first" and "rest", that's just an interface that doesn't have to be backed by a linked list implementation.
> The syntax is hard to parse for humans
This was my problem as well, the object oriented related syntax is just too much. ML of which caml is a version of, has really tight syntax. The “o” in ocaml ruins it imo.
+10 for bad windows support, i think this is a key and weirdly underestimated reason
just to give an idea how bad, until recently, you could not just go to ocaml.org and download ocaml for windows, you had to either download one for mingw or wsl
so for many it was just not installable, i.e. for many we didnt have ocaml for windows, until very very recently
The Windows support is bad because OCaml is a PL designed by people who are deep in Linux life. Windows is not something that keeps them up at night. (Which isn't to say they didn't try, just, you know, not as much as it takes)
One of the things people often neglect to mention in their love letters to the language (except for Anil Madhavapeddy) is that it actually feels UNIXy. It feels like home.
> just to give an idea how bad, until recently, you could not just go to ocaml.org and download ocaml for windows
On the other hand, you could get ocaml for Windows from Microsoft ever since 2005.
F# is not "OCaml for Windows". Not even close.
I wish I could make a list like this about rust in this place and not be flagged.
I don't think you would be flagged. Rust definitely has flaws:
* Compile time is only ok. On par with C++.
* Async has a surprisingly number of footguns and ergonomic issues.
* There's no good solution to self-borrowing or partial borrows.
* While using macros is fine, writing them is pretty awful. Fortunately you rarely need to do that. Relatedly it is missing introspection support.
* Sometimes the types and lifetimes get very complex.
But overall I still much prefer it to OCaml. The syntax is much nicer, it's easier to read, the ecosystem and tooling are much better, the documentation is much better, and it actively hates linked lists!
You missed one:
* Crates.io is an unmoderated wasteland of infinite transitive dependency chaos
But my "favourite":
* It's 2025 and allocator-api (or its competitors) is still in nightly only and no sign of stabilizing
I work almost exclusively in Rust, and I like the language but in many respects a) Rust is the language that tokio ate, and b) it has been deluged with people coming from the NodeJS/NPM ecosystem doing Web Scale Development(tm) and its terrible practices around dependency management.
> Crates.io is an unmoderated wasteland of infinite transitive dependency chaos
Well, I'm not sure I agree with that. If by "unmoderated" you mean anyone can upload a crate without going through bureaucratic approvals processes then that seems like a good thing to me!
But you did remind me of one other majorly annoying thing about the crate system: the global namespace. It doesn't have the same security issues as Python's global package namespace, but it is really really annoying because you pretty much have to break large projects down into multiple crates for compile time reasons, and then good luck publishing those on crates.io. Plus you end up with a load of crate names like `myproject-foo`, `myproject-bar`, which is very verbose.
Oh and yeah, the Tokio situation is a bit sad.
Also the proliferation of some types of crates like error handling. This should really be in the standard library by now (or at least fairly soon). Any large project ends up with like 5 different error handling libraries just because dependencies made different choices about which to use. It's not a major issue but it is silly.
Overall though, still my favourite language by far.
> It just genuinely felt like the Go language designers didn’t want to engage with any of the ideas coming from functional programming.
You'd be right.
"The key point here is our programmers are Googlers, they’re not researchers. They’re typically, fairly young, fresh out of school, probably learned Java, maybe learned C or C++, probably learned Python. They’re not capable of understanding a brilliant language but we want to use them to build good software. So, the language that we give them has to be easy for them to understand and easy to adopt. – Rob Pike 1"
"It must be familiar, roughly C-like. Programmers working at Google are early in their careers and are most familiar with procedural languages, particularly from the C family. The need to get programmers productive quickly in a new language means that the language cannot be too radical. – Rob Pike 2"
Talking as someone who wrote OCaml at work for a while, the benefits of functional programming and the type guarantees that it's ilk provides cannot be understated; you only start to reach them, however, once most developers have shifted their way of thinking rather extremely, which is a time cost that that designers of Go did not want new Googlers to pay.
You would be surprised how many Googlers think the Go team is making bad decision after bad decision.
To this day, whenever I see Machine Learning abbreviated, my heart skips a beat, then I become crestfallen as I realize I'm not about to read something about Meta Language.
ML refers to Meta Language and LLM refers to Languages and Logic Montreal [0], a PL theory group. [0] https://llm.uqam.ca
> PL theory group
I know there are great many Polish people in the world, but why it matters so much in this case? They could have been any nationality, even French!
I believe many people use PL to mean programming language. I'm wondering if your joke just wooshed me.
You believe I'd purposefully misread an abbreviation in a comment about misreading abbreviations, and also coincidentally tried to make fun of two other nationalities (maybe even three, depending on political views), all at the same time?
I would never.
I mean pohl's joke above whooshed kjmh so it's all fine. The important thing for threads like this one is for us to name drop all of the weird programming languages that we have used, publicly avow the greatness of ones that we have not, and make a New Year's resolution that we will never follow, to actually pick up those great languages and write something in them...
> make a New Year's resolution that we will never follow, to actually pick up those great languages and write something in them...
Why must you call me out in this way? How did I wrong you, that I deserve this?
I'd rather have that issue than seeing "AI" plastered all over the place. I'm of the opinion AI should be reserved for artificial general intelligence. These things aren't intelligent yet. They're just em-bloat-ified traditional machine learning techniques. Not that they're useless. I just hate the terminology.
If people start using the term AI, we better be living in I, Robot. Not whatever the hell this is.
Tangential rant. Sorry.
We lost this fight at least by 1994 when Sun acquired “Thinking Machines,” which to its credit was bankrupting itself by making highly parallel supercomputers, at least. Now of course there is a new AI company of the same name. If the wrestling world echoes the computing world, one can only wonder what in 5-10 years will be the equivalent of Undertaker throwing Mankind off of Hell In A Cell to plummet 16 feet down through an announcer’s table...
I believe that current publicly available Ais are more intelligent than a non trivial fraction of adults.
I also think AK would fit better.
AK-42
ML blew my mind back in the late 1980s when I got to use it on a 80286 machine for the first time!
Thanks for posting about ML! I made a post similar to yours a couple of years ago and got downvoted, lol.
Why isn't it more popular?
I think Richard Feldman [0] proposed some of the most reasonable theories as to why functional programming isn't the norm. Your language needs to be the platform-exclusive language for a widely used platform, have a killer application for a highly desired application domain, or be backed by a monster war-chest of marketing money to sway opinions.
Since Feldman's talk, Python has grown much faster in popularity in the sense of wide use in the market place... but mostly because it's the scripting language of choice for PyTorch and AI-adjacent libraries/tooling/frameworks which is... a killer application.
I like OCaml. I started evaluating functional programming in it by taking the INRIA course online. I spent the last four and half years working in Haskell. I've built some side projects in Zig. I was a CL stan for many years. I asked this question a lot. We often say, "use the best tool for the job." Often that means, "use the tool that's available."
I think languages like OCaml, Rust, Haskell etc can be "popular," but in the sense that people like to talk about them and want to learn them and be able to use them (at least, as trends come and go). It's different from "popular" as in, "widely adopted."
[0] https://www.youtube.com/watch?v=QyJZzq0v7Z4
> mostly because it's the scripting language of choice for PyTorch and AI-adjacent libraries/tooling/frameworks
I would politely disagree. Torch started in Lua, and switched to Python because of its already soaring popularity. Whatever drove Python's growth predates modern AI frameworks
Python was already big for scientists back in 2010. I remember working on Python tooling at the time, and DS/ML was one of our single largest user groups. It was already popular enough to have an IDE specifically for scientific Python use: https://en.wikipedia.org/wiki/Spyder_(software).
As far as I could tell, it had to do with two things. First, Python is notoriously dynamic and extensible, making it possible to implement "sloppy" syntax like advanced slicing or dataframes. But also, those guys had lots of pre-existing C and Fortran code, and Python had one of the easiest extensibility APIs to wrap it as high-level packages. And with IPython, you had a nice REPL with graphing to use all that from, and then of course notebooks happened.
I've dabbled in F# (and aside from the rough setup with little coherent information at the time) had a pretty good time. Actor-based concurrency was easy to grok. The one gotcha was whenever those mutable Arrays entered the picture.
I'd like to hear some practical reasons for preferring OCaml over F#. [Hoping I don't get a lot about MS & .NET which are valid concerns but not what I'm curious about.] I want to know more about day to day usage pros/cons.
It's a matter of trends: F# is losing compatibility with the overall CLR ecosystem due to the churn in C# features with poor F# interop, but F# has already mingled its design with the CLR's, too much to live on its own as a native language. Plus its compiler is slow and the tooling is getting increasingly unstable.
Meanwhile, OCaml got rid of its global lock, got a really fast-compiling native toolchain with stable and improving editor tooling, and has a cleaner language design with some really powerful features unavailable to F#, like modules/functors, GADTs, effects or preprocessors. It somehow got immutable arrays before F#!
F# still has an edge on some domains due to having unboxed types, SIMD, better Windows support and the CLR's overall performance. But the first two are already in the OxCaml fork and will hopefully get upstreamed in the following years, and the third is improving already, now that the opam package manager supports Windows.
> has an edge on some domains due to having unboxed types
If a language makes "unboxed types" a feature, a specific distinction, and has to sell "removing global lock" as something that is a massive breakthrough and not table stakes from 1.0, it can't possibly be compared to F# in favourable light.
I vouched for your dead comment because I get where you're coming from. But OCaml 1.0 was in 1996 in an academic setting. I care about the language I can use now, not the one I didn't use.
Let's not dismiss that their solution to remove the global lock has been both simpler than Python's (better funded?) ongoing work and backwards compatible; and the multicore support came with both a memory model with strong guarantees around data races, and effect handlers which generalize lightweight threads.
I agree that lack of unboxed types is a fatal flaw for several domains (Worse, domains I care about! I usually consider Rust/Go/.NET for those.) But when the comparison with OCaml is favourable to F#, the gap isn't much wider than just unboxed types. F# has an identity crisis between the ML parts and the CLR parts, its C# interop is decaying as the ecosystem evolves, and newer .NET APIs aren't even compatible with F# idioms (here's a .NET 6+ example [1]).
[1]: https://sharplab.io/#v2:DYLgZgzgNAJiDUAfA9gBwKYDsAEBlAnhAC7o...
> I'd like to hear some practical reasons for preferring OCaml over F#
Bigger native ecosystem. C#/.net integration is a double edged sword: a lot of libraries, but the libraries are not written in canonical F#.
A lot of language features F# misses, like effect handlers, modules, GADTs etc.
I did get some sense of that where F# sort of (actually is) 2nd class to C# which is slowly gaining some F# features, but F# itself isn't well promoted/supported.
As for missing language features, they can also be a double-edged sword. I slid down that slippery slope in an earlier venture with Scala. (IIRC mostly implicits and compile times).
There are libraries that simulate a lot of these things (e.g. https://github.com/G-Research/TypeEquality for GADTs). You're absolutely right that it's not as first class as in OCaml, but the tools are there if you want them.
I've written type-equality witnesses in F#, they can kinda recover type equalities (with cast methods) but not refute them, so you still need to raise exceptions for those cases.
We’ve used f# professionally for the computations-intensive parts of our product for a couple of years. Here’s what comes to mind:
1. Interop with C# is great, but interop for C# clients using an F# library is terrible. C# wants more explicit types, which can be quite hard for the F# authors to write, and downright impossible for C# programmers to figure out. You end up maintaining a C#-shell for your F# program, and sooner or later you find yourself doing “just a tiny feature” in the C# shell to avoid the hassle. Now you have a weird hybrid code base.
2. Dotnet ecosystem is comprehensive, you’ve got state-of-the web app frameworks, ORMs, what have you. But is all OOP, state abounds, referential equality is the norm. If you want to write Ocaml/F#, you don’t want to think like that. (And once you’ve used discriminated unions, C# error-handling seems like it belongs in the 1980’ies.)
3. The Microsoft toolchain is cool and smooth when it works, very hard to wrangle when it doesn’t. Seemingly simple things, like copying static files to output folders, require semi-archaic invocations in XML file. It’s about mindset: if development is clicking things in a GUI for you, Visual Studio is great (until it stubbornly refuses to do something) ; if you want more Unix/CLI approach, it can be done, and vscode, will sort of help you, but it’s awkward.
4. Compile-times used to be great, but are deteriorating for us. (This is both F# and C#.)
5. Perf was never a problem.
6. Light syntax (indentation defines block structure) is very nice until it isn’t; then you spend 45 minutes how to indent record updates. (Incidentally, “nice-until-it-isn’t” is a good headline for the whole dotnet ecosystem.
7. Testing is quite doable with dotnet frameworks, but awkward. Moreover. you’ll want something like quickcheck and maybe fuzzing; they exist, but again, awkward.
We’ve been looking at ocaml recently, and I don’t buy the framework/ecosystem argument. On the contrary, all the important stuff is there, and seems sometimes easier to use. Having written some experimental code in Ocaml, I think language ergonomics are better. It sort of makes sense: the Ocaml guys have had 35 years or so to make the language /nice/. I think they succeeded, at least writing feels, somehow, much more natural and much less inhibited than writing F#.
OCaml is a much more powerful language. Take a look at functors, for example, or modules as first-class values, or GADTs, or its object system that can do type inference from use:
F# is often called "OCaml for .NET", but it is a misrepresentation. It is an ML-family language for .NET, but aside from that ML core they don't have much in common.Whether those features are more valuable to you than the ability to tap into .NET libraries depends largely on what you're doing.
> It is an old language, and there are a few features that could probably be left out like the OOP-related features, and some libraries in the ecosystem over-complicate things like in Haskell.
If one can stand a language that is just a little bit older, there is always Standard ML. It is like OCaml, but perfect!
I love SML, and came to OCaml a bit begrudgingly initially just for a larger ecosystem. But, I think the object system gets a unjustly bad wrap. The OCaml object system is dope. It is rarely needed and not the best feature for most use cases, but when you want structurally-typed records, or need open recursion (or need to represent JS objects for the amazing `Js_of_ocaml`), they are a perfect fit.
I love standard ml (I'm currently writing a compiler for it), but it's far from perfect. There are weird special cases in the language definition like the ad-hoc overloading between int and real, or the annoying value restriction. Records also feel half-baked, with no support for updating fields or for partially-specified records where the full set of fields is not known
> with no support for updating fields
While it's not yet standard nearly all Standard ML implementations support what has become known as "Successor ML" [0]. A large subset of Successor ML is common to SML/NJ, MLton, Poly/ML, MLKit and other implementations.
That includes record update syntax, binary literals, and more expressive patterns among other deficiencies in Standard ML.
For me the two big remaining issues are:
1) There's only limited Unicode support in both the core language and the standard library. This is a big issue for many real-world programs including these days the compilers for which SML is otherwise a wonderful language.
2) The module system is a "shadow language" [0] which mirrors parts of SML but which has less expressiveness where modules cannot be treated as first-class values in the program. Also if you define infix operators in a module their fixity isn't exported along with the function type. (Little annoyance that gets me every time I am inclined to write Haskell-style code with lots of operators. Though maybe that's just another hint from the universe that I shouldn't write code like that.) Of course, the fix to that would be a fundamentally different language; not a revised SML.
[0] http://mlton.org/SuccessorML
[1] https://gbracha.blogspot.com/2014/09/a-domain-of-shadows.htm...
As I was saying, Successor ML is like OCaml, but perfect!
I've written a fair amount of SML (though years ago) and I can't remember the value restriction ever being an issue.
I certainly agree that SML isn't really a production language, though.
I far preferred Standard ML when I learned both back in the day, but it was OCaml that won the headspace it seemed.
Ironically probably because it had the "O"bjects in it, "which was the style of the time"... something that has since dropped off the trendiness charts.
OCaml has been one of those "almost there" languages since at least 2002. Most of the worthwhile ideas in OCaml will be absorbed into more popular languages by the time existing friction is sorted out. :/
Perhaps OCaml is the Velvet Underground of languages. Only a few thousand people learned OCaml but every one made a programming language[1]
[1]: https://quoteinvestigator.com/2016/03/01/velvet/
Xavier Leroy as Lou Reed... :-) Don't forget the amazing theorem provers too, like Imandra ( https://www.imandra.ai/core ), HOL-Light ( https://hol-light.github.io/ ) and Rocq ( https://rocq-prover.org/ ), ... !
That would be Elm :)
I've been saying for ages! Gleam, Roc, Derw, Gren, Cara, Zokka, and the error messages in Rust.
https://news.ycombinator.com/item?id=45646520#45752905
Roc says hi!
Almost there, but in the meantime supporting a casual squillion dollars of trades at JS
Yes and they had to basically build their own version of the compiler to keep everything from falling over (https://oxcaml.org/).
> Our hope is that these extensions can over time be contributed to upstream OCaml.
Yeah, its more just extensions to support their use cases at scale. Think of it more as bleeding edge ocmal, once they work out kinks/concerns they'll get merged back into the language OR if it remains ultra specific it'll stay in oxcaml.
Not a complete own version lol
Yes but the context of the thread is OCaml being "almost there". Having to build this stuff in-house is pretty good evidence.
I don’t know about that.
Python gets forked in other investment banks as well. I wouldn’t say that is evidence of any deficiencies, rather they just want to deal with their own idiosyncrasies.
See https://calpaterson.com/bank-python.html
A different perspective is that JS has made practical application of PLT part of their secret sauce, and deepening into their PLT roots is thickening the sauce.
Evidence of what?
The main user has been writing extensions to the compiler that they test before pushing for integration like they have done for the past twenty years or so. They publish these versions since last year.
Hardly a failure and certainly not something mandatory to keep things from failing over. Your initial comment is extremely disingenuous.
This is the wrong interpretation of the oxcaml project. If you look at the features and work on it, it's primarily performance or parallelism safety features.
The latter going much further than most mainstream languages.
Yeah, but when these things happen I ask myself, is Jane Street successful because of ocaml, or did they just happen to pick ocaml and then make it work?
There might be some power in attracting all the people who happen to love ocaml, if there are enough of competent people to staff your company, but that's more a case of cornering a small niche than picking on technical merits
They've spoken about this before and might not have picked OCaml if they had to make the decision again today. I think at the time it made the most sense.They can also make it work in any language as they claim to only recruit the best and brightest in the world (this may be the truth). My opinion is they could have chosen many languages and had similar results while balancing different trade-offs.
Regarding attracting talent, they've said they don't care about existing knowledge of OCaml as the language part is something they train staff on anyway. Their interviews are brutal from what I recall. I could be an OCaml expert and have no chance of making it through an interview without equal talent in high performance fintech and relevant mathematics.
> I could be an OCaml expert and have no chance of making it through an interview without equal talent in high performance fintech and relevant mathematics.
Unless their hiring process has changed in the past few years, if you're a dev they're not hiring you for your financial skills, just general problem solving and software development ability. It is (was?) the usual Google-style algorithms/data structures rigamarole, but somewhat more challenging.
Do those devs actively use OCaml? I thought most of the folks writing OCaml were writing the actual trade algorithms as opposed to infrastructure folks. My post was made off what I recall their lead technologist saying.
Absolutely. Everyone uses OCaml at Jane Street; pretty much everything at Jane Street is OCaml. If an OCaml version of something doesn't exist, there's a decent enough chance that they'll write it themselves rather than resort to a non-OCaml solution.
Like I said, my information might be a hair out of date, but it's first-hand.
Gotcha. Mine is just some old blog posts and a long talk from the guy that got OCaml started. Nothing like your actual first person experience. Thanks for adding!
Yes, everybody in JaneStreet is expected to be able to use Ocaml, Neovim, and R/Julia/etc.
Everybody in the company is expected to be able to sling numbers in text on a computer super efficiently.
Clearly Jane Street wouldn't be where it is, a top proprietary trading firm in US, without static type checking.
Unless you're building another JS, it'd be nice if there were other companies so heavily invested in it. There's a lot out there beyond compiler prototypes and high speed financial trades, but there's not enough talk of people using ocaml for those things.
Ocaml was (historically, at least) used by Facebook for basically all of their linter/compiler/type checker work. The hack checker was in Ocaml, as was the JS thing (flow, maybe?).
So that does seem to be a good use-case for the language.
That was why I mentioned compilers along with HFT. Rust was originally an ocaml based compiler too.
I don't build HFTs and my compilers are just for fun. None of my day jobs have ever been a situation where the smaller ecosystem and community of ocaml was offset by anything ocaml did better than the selected options like .net, Java, go, rails, C or anything else I've touched. Heck, I've written more zig for an employer than ocaml, and that was for a toy DSL engine that we never ended up using.
What is this alleged friction?
Because plenty of people have been shipping great projects in Ocaml since it was released so it doesn’t seem to be much of an issue to many.
I doubt Ocaml will be surpassed soon. They just added an effect system to the multicore rewrite so all things being considered, they seem to be pulling even more ahead.
Alleged? Come now.
Beginners face the following problems: there's multiple standard libraries, many documents are barely more than type signatures, and data structures aren't printable by default. Experts also face the problem of a very tiny library ecosystem, and tooling that's often a decade behind more mainstream languages (proper gdb support when?). OCaml added multicore support recently, but now there is the whole Eio/Lwt/Async thing.
I used to be a language nerd long ago. Many a fine hour spent on LtU. But ultimately, the ecosystem's size dwarfs the importance of the language itself. I'm sympathetic, since I'm a Common Lisp man, but I don't kid myself either: Common Lisp isn't (e.g.) Rust. I like hacking with a relic of the past, and that's okay too.
TBH I think it's rather a post-hoc rationalization of why the language is not popular.
> there's multiple standard libraries
Scala has a far more fragmented ecosystem with Cats, Scalaz, Zio and Akka. C++ and Java have a bunch of stdlib extensions like boost, Guava, Apache Commons etc.
> many documents are barely more than type signatures
Can be said of most of Java, Kotlin, Scala, Erlang etc etc. Just compiled javadocs, sometimes with a couple of unhelpful lines.
> data structures aren't printable by default
Neither they are in C++
I think the real reason it's not popular is that there are languages which solve more or less the same problems of system programming but look far more familiar to an avg. programmer who was raised on C++ and Java.
Maybe it's post-hoc?
I wanted to use OCaml since 2002, since it was a GC'd language with good performance, achieving a lot with relatively few lines of code. Being a language nerd, I was (am?) positively inclined to the language. Yet there was always something that made it notably less pleasant to solve my current problem in than in than some other language.
If it had trouble getting traction with me, that's bad news.
Meanwhile the mainstream has progressed a lot since 2000. GC is the standard, closures are normal, pattern matching and destructuring are increasingly so. While HM-style type inference is not mainstream, local type inference is (and I'm no longer convinced that global type inference is the way). Algebraic data types aren't unusual anymore.
A few years back I just threw in the towel and went with Rust; this happened after I volunteered to improve OCaml's gdb support (including DWARF hell), which went nowhere. I wish Rust compiled faster, and a GC'd language is usually more productive for my problems, but in every other regard it stole what should have been OCaml's thunder. And when popular successor languages eventually appear, they'll do it even better.
Off-topic: What language would you say is the closest thing to "Rust with a GC"?
(Rust has refcounting, but it's slow, and needing to handle cycles manually limits its usefulness.)
The closest thing to "Rust with a GC" in my mind is Ponylang or just Pony:
https://www.ponylang.io/ https://github.com/ponylang/ponyc
The Pony community is here:
https://ponylang.zulipchat.com/
Pony's garbage collection and runtime can yield performance faster than C/C++/Rust because the compiler eliminates data races at compile time, and thus no locks are needed.
It features implementations of Dmitri Vyukov (www.1024cores.net) algorithms for work stealing and Multi-producer single consumer queues that use only a single atomic instruction to read. The designer, Sylvan Clebsch, is an ex-game-developer and ex-high-frequency-trading-infrastructure engineering lead; he knew what he was doing when he designed the language for high performance on multicore systems.
On the other hand, you do have to re-wire your thinking to think in terms of Actors and their state, and this is kind of hard to wrap one's head around if you are used to Go's CSP or the popular async/await approaches -- it is a somewhat different paradigm.
GC was standard already in 2000: Perl, Python, Ruby, Java and JS all had GC from day 1.
Crappy GC for most of them, but... fair point.
> there's multiple standard libraries
There is only one standard library and it shipped with the compiler.
> data structures aren't printable by default
So? That’s the case with most languages. Ocaml has a deriver to make types printable and a REPL which automatically prints for testing.
> tooling that's often a decade behind more mainstream languages
Opam is a fully featured package manager, dune works fine, bucks2 supports Ocaml.
> proper gdb support when?
Ocaml has had a rewindable debugger since approximately forever.
> OCaml added multicore support recently, but now there is the whole Eio/Lwt/Async thing.
Lwt was the default and everyone agrees eio is the future now that effects are there. Async is a Janestreet thing with pretty much no impact on the language outside of Janestreet.
Honestly, I maintained my initial point. Ocaml alleged frictions were always widely overstated.
When I was writing Ocaml professionally 15 years ago, there was no dune and no opam and it was already fairly easy to use the language.
> Because plenty of people have been shipping great projects in Ocaml
What applications are written in OCaml? All I can think of (which says more about me than it does about OCaml) is the original Rust compiler.
Even Haskell has Pandoc and Xmonad.
Rocq is an excellent example of something OCaml was designed for. FFTW3 is another great example. Unison too.
Generally, you want stuff where you have to build a fairly large core from scratch. Most programs out there doesn't really fit that too well nowadays. We tend to glue things more than write from nothing.
Rocq, Pfff and Flow, Vpnkit in Docker for Mac and Windows, the web version of Facebook Messenger at a point, Tezos, Unison, the Xen cloud platform, the Mirage unikernel.
For me the issue is ecosystem. The foundations are great but I need more useful and well supported packages.
For example, there is no OAuth2 client library for OCaml [1]
[1] https://ocaml.org/docs/is-ocaml-web-yet
Elixir is the closest thing to OCaml that has a chance at semi-mainstream usage IMO.
It has basically all of the stuff about functional programming that makes it easier to reason about your code & get work done - immutability, pattern matching, actors, etc. But without monads or a complicated type system that would give it a higher barrier to entry. And of course it's built on top of the Erlang BEAM runtime, which has a great track record as a foundation for backend systems. It doesn't have static typing, although the type system is a lot stronger than most other dynamic languages like JS or Python, and the language devs are currently adding gradual type checking into the compiler.
I think that a better question is why F# isn't a more popular language, since it's much closer to OCaml, than Elixir and you can use the whole Dotnet ecosystem in F#, which is one of the weakest points of OCaml (no libraries).
The answer is (most likely) Microsoft, I kid you not. I've worked with F# professionally for many years is its incredible how they are literally sitting atop a gold mine that is the output of Microsoft research and do basically nothing with it. Even though it's sold as an ecosystem, .NET revolves around C# and its related tooling.
"Type Providers" are an example of such negligence btw, it's something from the early 2010's that never got popular even though some of its ideas (Typed SQL that can generate compile-time errors) are getting traction now in other ecosystems (like Rust's SQLx).
My team used SQL Providers in a actual production system, combined with Fable (to leverage F# on the front end) and people always commented how our demos had literally 0 bugs, maybe it was too productive for our own good.
I think it’s odd that elixir doesn’t get more love. It ticks a lot of boxes that folks here get excited about, has a great ecosystem and tooling, BEAM is great, and it’s much more syntactically familiar than erlang to my eye. I know of a couple companies aside from the perennial goto examples that built sizable saas products backed by it.
The BEAM VM executing bytecode is slower than a compiled binary. Sure, it is great when compared to Python and other interpreted languages. Not so much when you need fast processing and raw CPU performance. It also loses out to the JVM in performance, but wins in memory consumption.
It is slower, but a big cause of the slowness is a lot of copying (immutable data structures and separate heaps for every process). Nowadays the BEAM has a JIT.
If you use type guards correctly the performance can be surprisingly good. Not C/C++/Rust/Go/Java good, but not too far off either. This is definitely a corner-case though.
But how many things involve fulfilling basic requests over a network pulling information from a database? Most things just don’t need that kind of performance.
Sure for basic, dead CRUD, the choice of middleware language rarely makes any difference.
But even bog-standard business processes eventually find the need for data-processing, crypto and parsing - the use-cases where people code Elixir NIF's. That is why for example you have projects like html5ever_elixir for parsing HTML/XML. Another use case is crypto - you have NIF's for several crypto libraries. Data processing - there are NIF's for Rust polars.
The backend work I do is just super boring.
I always wanted to learn Elixir but never had a project where it could show it strengths. Good old PHP works perfectly fine.
Also corporations like their devs to be easily replaceable which is easier with more mainstream languages, so it is always hard for "newer" languages to gain traction. That said I am totally rooting for Elixir.
I think it’s great for boring stuff — the Phoenix web framework is really straightforward. Learning a whole new language paradigm and environment for a professional project you need to be productive in ASAP is definitely the worst kind of ‘not boring’ though.
I know of a Haskell shop and everybody said they’d have a hell of a time finding people… but all them nerds were (and are) tripping over themselves to work there because they love Haskell… though some I’ve talked to ended up not liking Haskell in production after working there. There seems to be a similar dynamic, if a bit less extreme, in Elixir shops.
Elixir is good at managing complexity. I love flattening hierarchy and dealing with edge cases right in function definitions using pattern matching. Every other language without it just feels crippled after getting used to the feature.
What does deployment look like? Can you get a static binary easily like with Go?
You don't get it from language tooling because you are compiling to a bytecode that runs in a virtual machine (BEAM).
The current tool to wrap your bytecode with a VM so that it becomes standalone is Burrito[1], but there's some language support[2] (I think only for the arch that your CPU is currently running? contra Golang) and an older project called Distillery[3].
1: https://github.com/burrito-elixir/burrito
2: https://hexdocs.pm/mix/Mix.Tasks.Release.html
3: https://hexdocs.pm/distillery/home.html
If it's functional (recursion vs imperative loops) most people/organizations will not use it. At this point that is just the reality.
Having loops is not the defining feature that separates functional from imperative. Where did this idea come from? I'm suddenly seeing it in a lot of places.
It is not the defining feature but loss of the loop is one of the most obvious differences for people who look at a functional language Rust has immutability, pattern matching, etc, but it remains an imperative language with "some functional features". Or this is my subjective analysis.
But, again, loops aren't automatically imperative per se. Consider loop / recur in Clojure for an example. For someone coming from JavaScript, it's not really much different from writing a while loop where every branch has to terminate with an explicit break or continue.
You can be functional "in spirit" more than purely functional. OCaml and Standard ML falls into this category. Ocaml has loops for instance. You might just not see many loops if code is written by OCaml developers, because there's frankly no need to use them in a lot of places. You often want to lift the abstraction level of iteration to an arbitrary data structure such that you get freedom of implementation. See Applicative and Monad.
its a simplification of immutability and its consequences
I really wish people would quit pushing "functional". People equate that with "My programming is now always a recursive logic puzzle."
Talk about "immutable by default". Talk about "strong typing". Talk about "encapsulating side effects". Talk about "race free programming".
Those are the things that programmers currently care about. A lot of current Rust programmers are people who came there almost exclusively for "strong typing".
Writing OCaml and writing Elixir code is much different for me. OCaml requires more braincells, while Elixir is more flexible.
Gleam also. But i cant justify a non compiled language in many things i do.
gleam is compiled... to erlang bytecode
It's compiled to Erlang, not BEAM bytecode, as the latter is not a stable, backward-compatible API to target, and you lose all of the optimization work put into the Erlang compiler. It's also compiled to JavaScript, so it can run on both the front-end and back-end.
I want a static binary. Not some IR i run on some VM.
I do not think that monads/type system are issue, but yes BEAM runtime is killer feature.
BEAM performance model trades throughput for isolation, which hurts CPU-bound tasks, and ironically, whenever you need speed, you end up using NIFs that break BEAM safety guarantees, and reintroduce the exact fragility Elixir was supposed to avoid.
In 2025, Elixir is a beautiful system for a niche that infrastructure has already abstracted away.
> In 2025, Elixir is a beautiful system for a niche that infrastructure has already abstracted away.
Do you mean Kubernetes?
My mental model of Erlang and Elixir is programming languages where the qualities of k8s are pushed into the language itself. On the one hand this restricts you to those two languages (or other ports to BEAM), on the other hand it allows you to get the kinds of fall over, scaling, and robustness of k8s at a much more responsive and granular level.
> whenever you need speed, you end up using NIFs that break BEAM safety guarantees, and reintroduce the exact fragility Elixir was supposed to avoid.
That's like complaining that unsafe{} breaks Rust's safety guarantees. It's true in some sense, but the breakage is in a smaller and more easily tested place.
It's not isolation which hampers throughput. That's a red herring. In fact, isolation increases throughput, because it reduces synchronization. A group of isolated tasks are embarrassingly parallel by definition.
The throughput loss stems from a design which require excessive communication. But such a design will always be slow, no matter your execution model. Modern CPUs simply don't cope well if cores need to send data between them. Neither does a GPU.
But the isolation is what necessitates (or at least encourages) a design that requires more communication, isn't it?
Not a priori.
The grand design of BEAM is that you are copying data rather than passing it by reference. A copy operation severs a data dependency by design. Once the copy is handed somewhere, that part can operate in isolation. And modern computers are far better at copying data around than what people think. The exception are big-blocks-of-data(tm), but binaries are read-only in BEAM and thus not copied.
Sure, if you set up a problem which requires a ton of communication, then this model suffers. But so does your GPU if you do the same thing.
As Joe Armstrong said: our webserver is a thousand small webservers, each serving one request.
Virtually none of them have to communicate with each other.
immutability?
What's immutable about elixir? It's one of the things which I MISS from Erlang -- immutability.What you wrote is roughly equivalent to this in C:
which is to say, there are two different `x` in there, both immutable, one shadowing the other. You can observe this if you capture the one that is shadowed in a closure:This is like saying Haskell doesn't have immutability because it has the state monad, or that rust doesn't because you can shadow with let.
Data is immutable and thats much more important than whether local variables can be modified imo.
Shadowing is not mutability. The former isn't affected by control flow nor does it affect closures.
Why isn't it more popular if it's so good? Because popularity and merit are not the same thing. People confuse them all the time though.
Check out the most popular music today. Like the top ten songs currently. Do you think those are really the best songs out there?
Popularity is mostly driven by either trends or momentum.
I think popularity and regarded favorably are probably inversely correlated.
Many of the most popular languages are also the most hated. Many of the more niche languages are viewed the most favorably.
It is easy to dislike something yo are familiar with, and easy to be overoptimistic about something you don't know as well.
"the grass is always greener ... "
Music being "good" is subjective. A programming language, however, can objectively be better if it allows a subset of programmers to better solve certain problems.
The reason for why OCaml is not more popular, thus, is that this subset is small. The reason for this may be either (a) habit or (b) it's not that much better than other languages. I'm gravitating to (b). OCaml guys seem to be quite dogmatic for the wrong reasons.
The popularity of a language usually translates into better support, tooling and learning materials.
I posit (c) it’s from France and written mostly by French people and American naturally gravitates towards languages which generate hype in English and preferably from the USA.
Also it didn’t employ a marketing team to work on outreached and write fancy comments here and some people who have used it for 10 minutes are apparently offended by the Pascal-like syntax and can’t stop discussing it on every Ocaml discussion making every actual users tired.
> OCaml is weird in that it’s a garbage collected language for systems, similar to Go.
I don't understand why this isn't more popular. For most areas, I'd gladly take a garbage collector over manual memory management or explicit borrow checking. I think the GC in D was one of it's best features, but it's downfall nonetheless as everyone got spooked by those two letters.
I like the ML languages, and as many others I spent a lot of time with F#.
I would love to spend more time but even though Microsoft gives it plenty of support (nowhere near as much as C#), the community is just too small (and seems to have gotten smaller).
Looking at https://www.tiobe.com/tiobe-index/ numbers fall off pretty quickly from the top 5-7.
Guessing this is the same for OCaml, even if the language as such is nice.
fun fact: the secret sauce that makes fftw fast is a code generator written in ocaml: https://github.com/FFTW/fftw3/tree/master/genfft
I kind of wish (like the OP mentioned) there was a ML (ocaml) like language that compiled to Go source. You would get the best of both worlds and access to a huge ecosystem.
There's Borgo: https://github.com/borgo-lang/borgo
I've never used it so can't speak from any experience, and unfortunately it doesn't seem particularly active (and doesn't mention a current status anywhere), and doesn't have a license, so shrug. When it's been posted here (https://news.ycombinator.com/item?id=40211891), people seemed pretty excited about it.
Borgo looks like some guys phd thesis. It looks like it was a fun experiment.
I feel a new simple ocaml like language that just compiled to Go would be really popular, really fast. And it would not even need to build a ecosystem, as Go already have all the things you need.
Something like what Gleam is for Erlang.
> why isn’t OCaml more popular?
Hashtbl.add table key value
Precedence, nominal inheritance, HKTs, incoherent typeclasses make Scala much less aesthetically pleasant but much more productive.
There's some other stuff, but I personally believe if the tooling was closer to Rust/Go than C, it would be a lot, lot more popular.
Nobody wants to effectively learn a lisp to configure a build system.
Dune is quite good these days. The lisp part is really just sexps (not a full languge). But i kind of get your point.
Yes, in every ML/OCaml tutorial, sooner or later the words object, class, and type inference appear and that’s when a once–minimalist language turns into an academic Frankenstein.
I don't think objects and classes are used much by OCaml programmers (not by me anyway). Type inference is a rather fundamental feature, and fairly easy to understand.
Why does type inference contribute to that issue?
It's not a minimalist language, you know what the "O" in Ocaml stands for right? It's a multi-paradigm language that explicitly accommodates more styles of programming than Caml, it's why it exists.
> Fast compile times
> Fewer abstractions, and an easy to understand runtime
> Strong static guarantees
> Functional programming constructs. Especially pattern matching and sum types.
> Good performance
> Good documentation
I feel this is also Elm!
Elm is pure-functional, unlike OCaml, which has easy escape hatches (refs) when you need mutability.
Well I need both float and double, so cannot even start using it.
One of the best P2P clients ever created is written in OCaml: https://github.com/ygrek/mldonkey
I'm still surprised it can do so many things so well, so fast.
OCaml is fantastic, but I avoided it and went with Rust for many projects because it had no multicore story and no green threads for a very long time. But it has that now, and I wish I could go back and start everything over in OCaml.
I've also felt very similar, and adopted Rust for those reasons. Even though I'd still love to have a garbage collected, AOT compiled ML-variant, using OCaml still feels like a step backwards now. OCaml's module system and generics feel clumsy and unintuitive now that I've used Rust's Trait system.
As a Rust newbie and seasoned Go dev, I'm pretty interested to knownwhere would people experienced in both OCaml and Haskell, would put it in the spectrum.
I don't think it's a spectrum.
Languages have features/constructs. It's better to look at what those are. And far more importantly: how they interact.
Take something like subtyping for instance. What makes this hard to implement is that it interacts with everything else in your language: polymorphism, GADTs, ...
Or take something like Garbage Collection. It's presence/absence has a large say in everything done in said language. Rust is uniquely not GC'ed, but Go, OCaml and Haskell all are. That by itself creates some interesting behavior. If we hand something to a process and get something back, we don't care if the thing we handed got changed or not if we have a GC. But in Rust, we do. We can avoid allocations and keep references if the process didn't change the thing after all. This permeates all of the language.
My team still has 8 year old Haskell systems in production. We pivoted away from the language a few years ago, which I discuss here a bit: https://news.ycombinator.com/item?id=37746386
I personally love ML languages and would be happy to keep developing in them, but the ecosystem support can be a bit of a hassle if you aren't willing to invest in writing and maintaining libraries yourself.
What spectrum? Language practicality? Popularity?
OCaml has some high profile use at Jane Street which is a major fintech firm. Haskell is more research oriented. Both are cool, but wouldn't be my choice for most uses.
What does "it" refer to? Ocaml?
Little known fact: OCaml was at one point called "Zinc" ("Zinc is not Caml").
Perhaps the language would be more lucky with the original name. Zinc is used to galvanize steel and prevent Rust formation[1].
[1] https://en.wikipedia.org/wiki/Galvanization
OCaml’s REPL is lovely, but I found myself having some friction with initial startup. The build/package system was pretty convoluted, and I ended up choosing JS’s Core stdlib for my needs (a simple compiler). With the new multicore release it’d be cool to see OCaml in some more practical projects!
As an OCaml-curious, is this the community recommendation, to choose the Jane Street stdlib if you’re just getting started?
It's probably the path of least resistance if following the Real World OCaml book (https://dev.realworldocaml.org/), which is quite excellent.
Lots of complaints about the OCaml syntax here.. is ReasonML dead?
For something a bit more modern but still related to OCaml, one can try F#.
F# is a practical choice but the language features are quite far behind OCaml now.
{Ecosystem, Functors} - choose 1
From an outsider's perspective, it feels like Ocaml has more active development of features, between the new effects system they added in 5 and all the work Janestreet is doing to let Ocaml developers have more control over performance.
F# is not stagnant thankfully, it gets updates with each new version of dotnet (though I haven't checked what is coming with dotnet 10), but I don't recall anything on the level of the above Ocaml changes in years.
Applicative Computation Expressions are a big deal (added in F# 5). Recent changes have been smaller in scope.
Unfortunately lots of the more advanced stuff seems to be blocked on C# team making a decision. They want a smooth interop story.
But F# remains a solid choice for general purpose programming. It's fast, stable and .NET is mainstream.
Oh yeah I love f#, I need to find more excuses to use it. I just wish it felt like MS was willing to invest more into it. But at least they have not abandoned it and continue to put some resources into its ongoing growth.
F# also has a real slow compiler. Last time hello world took a few secs on brand new mac.
I loved Ocaml but now I love TypeScript more. It's got about the same amount of type safety, the ergonomics are better to me, and the packaging and ecosystem tooling are leaps and bounds above anything else.
You would not really build the same software tho.
> It's got about the same amount of type safety
What?
Came here to say I love Ocaml too
I absolutely love the idea and methods behind OCaml, but the syntax..... I also love Haskell and already feel that its syntax is not easy to grok on larger projects, but OCaml basically went "hold my beer" and went to town on that.
darklang team loved ocaml too. in the end they ended up using f#.
>why isn’t OCaml more popular?
OCaml did become popular, but via Rust, which took the best parts of OCaml and made the language more imperative feeling. That's what OCaml was missing!
As someone who has worked professionally in both, programming in rust does not feel much like programming in OCaml. Working with traits in an imperative manual memory managed language is really different than working with proper modules in a mixed paradigm language with an awesome GC.
Aside from ADTs, what else did Rust take from OCaml?
Ocaml can be as imperative as you need it to be. Or as functional.
It has no dogmatic inclination towards functional. It has a very pragmatic approach to mutation.
Rust is very different from Ocaml. Rust is a low level language with a borrow checkers, traits, no first class module system, no GADT, no effects.
The similarities are fairly superficial actually. It’s just that Rust is less behind the PL forefront that people are used to and has old features which look impressive when you discover them like variants.
There is little overlap between what you would sanely use Rust for and what you would use Ocaml for. It’s just that weirdly people use Rust for things it’s not really suited for.
Offtopic HTML issue to the author: there is a trailing </head> tag at the end of your generated HTML after the </body> (instead of </html>).
I don't see it...the end of the document is:
I updated it just now :).
Fixed it, thanks for pointing it out :)