Scala, OCaml and Haskell, oh my!

Posted on October 3, 2013 by Nick

In my previous job, I made heavy use of Scala. I came across it sometime around version 2.7.7, and it was the first language I really fell in love with. My employer at the time made heavy use of Java and the JVM; by writing in Scala, I could link trivially with existing code and allow others to make use of my code without having to learn a new language, whilst getting all the benefits of writing in a modern, statically typed functional language.

Unfortunately my new employer has, for a couple of good reasons and a slew of bad ones, a strong bias against anything that runs on the JVM. I’ve used Scala for a couple of side projects, but the likelihood of anything JVM-based being allowed for my main work is minimal. Code here mostly seems to be written in Perl or Python or C, none of which was appealing. Perl and C I’ve always thought of as languages that I ‘should learn’, but having played with them I’m fairly convinced that the only reason for learning them is to see brilliant examples of how not to do things. Anyway, I had a couple of projects to do, so it seemed like a good opportunity to learn and compare the other two big static functional languages out there, Haskell and OCaml.

OCaml

I started with OCaml first. The local functional programming group (Cambridge NonDysFunctional Programmers) was holding an OCaml session hosted by OCaml labs, and Anil Madhavapeddy (one of the authors of Real World OCaml) was giving an introduction based on an alpha copy of the book. I had a chat with Anil and various of the other developers there, and they introduced me to the Jane Street Core library (which replaces the somewhat anaemic standard core library) and the OPAM package manager and I set off to write a fairly simple program for deploying specific LXC containers onto our farm machines.

And… it was okay. It’s a language that there’s much to like about: it’s pretty fast, has an awesome module system, a terse syntax. And yet… it just doesn’t inspire the same sort of joy that I originally found programming in Scala. To a large extent, I think this may be a matter of aestetics. When I came across Scala, it appealed to me because of the simplicity of the core spec and the amount of power that comes from it. A lot of effort seemed to have been put into coming up with a simple core of sufficient generality to allow the more powerful structure on top to be expressed in terms of it.

With OCaml, I think I felt the lack of this structure. In ultimately trivial ways, but ways which strongly affect my sense of the language’s aesthetic. There’s two almost disjoint type systems - one for values, the other for modules. One can define a functor as module A = functor(x : B) -> or as module A(x : B) =. Nobody seems to use the former syntax, and as far as I can see it offers no benefit over the latter. There’s a keyword rec that needs to be there when defining recursive functions. There’s a whole object system that people seem to advise you not to use, and which most of the libraries seem to avoid.

It just feels like a bit of a mess. I get no sense of a cohesive whole from it, rather a set of semi-interacting features stacked in a haphazard pile. I still like it - I’d choose it above most other languages out there - but I think I would find it hard to love.

Haskell

My second project involved building a package management system (or at least finding one to use). I’m a big fan of Archlinux: like scala, it has a simple core that allows you to develop a lot of power. The package format in particular is very nice - writing a package is as simple as defining a single file and running one command, which puts it well above any others I’ve come across (although Nix looks interesting.) This was particularly useful for our case, where we wanted to be able to easily construct packages for pieces of software used in genetics research. Unfortunately, the standard tools for Arch use binary builds, and we were keen to be able to archive sources for the various bits of software in use. Looking around for tools to solve this, I came across Aura, an AUR helper which looked like it could easily be retrofitted to support building packages from scratch from the ABS. More to the point, it was written in Haskell.

I’ve played a little bit with Haskell before, writing a couple of trivial programs, but never enough to get past the stage where the types stopped being a pain and started helping you: I would get to the end of coding and then spend an hour trying to arrange forM, mapM, liftM, bind and their ilk in order to get the thing to compile. Working on Aura was the first big project I carried out using Haskell, the first time I used Cabal or had to work out command line argument parsing.

Overall, it went better than my experience with OCaml. The language feels much more clearly defined; outside perhaps a few areas like FFI, I’m confident that I understand the keywords and syntax. The standard library also feels much more consistent; one of the problems with using the Jane Street Core library was that I’d have to go converting between types if I used a function from outside of there, whereas the Haskell core libraries are truly core and shared appropriately. They were also more extensive, covering just about everything I needed to do in terms of system calls. It was still a little bit of a pain working with monad stacks (things such as [Io String] were particularly annoying to deal with), but it also had advantages: in OCaml, I naturally wanted to eschew mutable global state, but wasn’t certain what to do with runtime configuration. Being forced into a purely function world led me to the reader monad and ultimately made the code a lot tidier, a lesson I can take back and use even in Scala, where such purity isn’t enforced.

Ultimately, I ended up writing a companion utility to the original OCaml utility in Haskell, and then rewrote the original in Haskell as well in order to share functionality. Of course, it’s possible that had I done things the other way around, I’d have been rewriting them both in OCaml instead!

Comparison

So, how do they compare? This isn’t meant to be an objective comparison - as noted earlier, a lot has to do with my sense of aestetics - but here are some thoughts about things I like or dislike in the different languages:

Scala

Like:

Dislike:

OCaml

Like:

Dislike:

Haskell

Like:

Dislike:

Conclusion

So, anyway, a brief and biased view of the three main languages I’ve been using this year. I have also written a couple of things in C, but if I were to compare that then the ‘dislike’ list would overflow the page, so we’d better leave it off for now. I still love Scala, but I suspect I will be writing more Haskell in the immediate future, possibly coming back to OCaml if I have a particular problem to which I think it’ll be amenable.

blog comments powered by Disqus