Hey! Thanks for reading! Just a reminder that I wrote this some years ago, and may have much more complicated feelings about this topic than I did when I wrote it. Happy to elaborate, feel free to reach out to me! 😄
🎵 The song for this post is Prince Fleaswallow's rap from Parappa the Rapper, by Masaya Matsuura 🎵
My most popular original tweet is from 2013:
Haskell holds me, a hysterical mess, crying and wailing over SML's body. "It should've been you!!" I yell, knowing it won't change anything.— 💣 b∀BГO 💣 (@SrPablo) June 5, 2013
I really love playing with and thinking about programming languages.1 I often get asked which my favorite is, and while I struggle to answer, I often say that if I designed one, it'd look most like Standard ML.2 Even by Pablo standards, it's a dead language.
It was always a dodge that I avoided OCaml this long. That said, I'm happy to announce that this blog is now built on OCaml, after years of being built on Racket. I wrote a static site generator that still has plenty of holes, and while I don't recommend anyone else use it in its current state, I feel comfortable enough to build my site with it going forward.
If you see bugs in the site, please report them! 😅
Closing the correctness gap
- writing tests with a ton of mocks
- debugging bad state
If you're familiar with OCaml, you'll know that these are tasks the languages greatly reduces. Your programs are a little harder to write, but much easier to maintain. You'll note my codebase, at this point in time, has no tests. This isn't ideal! Testing is great! But I'd never even conceive of writing other software this way in another language, because I wouldn't have confidence that the system I build would have its invariants preserved.
Closing the performance gap
If you spend enough time in dynamic, interpreted languages, you forget how fast computers really are. I didn't think I'd get to "launch" this project until I implemented a cache, much like Frog has, that determines what files have changed and only rebuilds the parts of the site as necessary. A clean build in Frog takes me about 16 seconds, and one from cache takes about 3.
When I first ran a complete build, my OCaml project built the entire site in less than a second. This is not a burn on Racket or Frog! They are amazing products by amazing people that I wholeheartedly admire! But there is a real joy in seeing optimized, compiled code work as quickly as it does.
I'm committed to continuing to try as much as I can in OCaml this year.
What's not great
Impacts of smaller community
When considering an OCaml library, my process was
Can I install this with OPAM? If not, I didn't include it: I really would prefer to stick to reproducible builds with a simple packaging mechanism.
How do I use this? I'd download it, look at its signatures in utop, and usually look at the source code itself (like this file in the Markdown parser, or this one in the ISO8601 date formatter). This is kind of the System Working As Designed, but it's a bit more exploratory than working in many other ecosystems.
Getting a working setup
There are several different ways to install OCaml's tools, and when you do install them you find that there are dozens, each individually handling a different part of the build chain. I misunderstood an instruction on the merlin install, so I was coding blind for a longer time than I would have liked.
In fairness, this is broken everywhere (though Haskell Platform and
Racket's single download are quite pleasant). Telling folks to download
nvm or rvm or virtualenv and how to
pip install or
npm install for these tools has a learning curve too. But they more-or-less
follow the same conventions, and per above, have a lot more resources online to
debug where they don't work.
While I think Reason and all the subsequent new attention is a good thing, it causes some angst over which to use, and exacerbates a lot of the above since it's yet another fragment in that ecosystem.
If you want to give it a try, I'd take a look at Real World OCaml, available online and very comprehensive.
If you can, try to get Merlin set up, and work with a
utop instance nearby.
They'll really shorten your dev cycle.
2. ^ Dream language would have SML modules and types, Erlang-like VM and OTP, Lisp syntax. Such a combination is probably impossible and I'm probably missing a few other features, but those are a few of my favorite things.
Thanks for the read! Disagreed? Violent agreement!? Feel free to drop me a line at , or leave a comment below! I'd love to hear from you 😄