I’ve been learning Clojure in Amsterdam, so to speak.
It all came about when I decided I was going to learn a new programming language as a Summer project, and as usual turned out to be a little more complex than that.
The Amsterdam bit is easy enough to explain – I’ve been using my DigitalOcean VPS for a few months now as a sort of “home away from home”, which allows me to use Sublime Text remotely1 from my iPad and get a surprising amount of stuff done without having to cart a full blown laptop around.
The Clojure bit, well… not so much, hence the rest of this post.
Why Clojure?
Even though Python still gives me the most bang for the buck (both in terms of productivity as well as performance, provided you know what you’re doing), most of the hard stuff I’m tackling these days falls into two broad categories:
- Moderate to heavy concurrency across multiple machines
- High-volume data processing (in either throughput or size)
I’ve been able to tackle both reasonably well with Python by tapping into PyPy or gevent for a little extra speed, but even though I love the Python standard library and ecosystem, I was not too happy with the abstractions readily at hand or the amount of hoops I was going through to tackle a few specific problems, so I decided to explore alternatives.
I started out by looking at Erlang again, then at the Actor model in Pykka, then at Akka (at which point I branched out into Scala, Java, etc.) and eventually came to the conclusion that all the low-hanging fruit didn’t require so much of a paradigm change as a mindset change in the way I was doing things.
Clojure also scratched a few particular itches that had been bothering me of late:
- It runs on the JVM, and although I hate the quasi-religion Java has become (in terms of language and IDE dogmas), the ecosystem is huge, the performance is (by and large) excellent, and we do a fair amount of unconventional Java that I’d like to be able to leverage somehow.
- Being a LISP dialect, it is both familiar enough2 to be easy to read and highly appealing to my sense of aesthetics
- It has a clean, unfettered approach at single-system concurrency (and these days anything that doesn’t tackle concurrency well is a non-starter for me), and a number of open-source options for orchestrating tasks across machines.
But what clinched it was the community. The more I read about Clojure (and about what people were doing with it) the more appealing I found it to be, largely because the average level of discourse was way above what I’m used to getting in, say, the JavaScript or Go blogs I follow.
So I started working through the Clojure Koans piecemeal and doing a few mini-projects3 that made me aware of a few interesting wrinkles:
- Using Java on a Mac has become awkward, and is sure to become a massive pain as we move towards Mavericks (plus I really don’t like running Oracle software on my machine).
- Python spoiled me somewhat in terms of libraries. Its “batteries included” approach is a severe contrast with Clojure’s relative sparseness and reliance on the Java ecosystem (I fully expect a couple of dependency management nightmares in the near future).
- The language core is stable, but bits around it are evolving fairly quickly (core.async being a case in point).
- There are more back-ends under active development than you’d expect - including, of course, ClojureScript, and even clojure-py, which is somewhat stale but that I managed to get running under Pythonista on the iPad.
I’m not (at all) sold on ClojureScript, though - the intermediate compilation step makes it feel clunky and inelegant, and I wish someone would rip out all the JavaScript bits and just plug it directly atop V8 somehow. Maybe someone will eventually tackle that.
Why Not Go, Erlang, Haskell, etc?
Go is still a trifle too unstable (and unfinished) as far as I’m concerned. I’m already familiar with it and even tried Revel, but I’d rather wait until it matures somewhat.
I have no significant trouble coding in it (except for some syntactic aberrations), but it just isn’t inspiring enough – it’s a low-abstraction language that feels like a step back in terms of how to tackle unsolved problems, whereas Clojure makes it easy to abstract away computing and cast problems as logic – quite often tackling things in different ways.
So Go will likely become my “new C”, if you will.
Erlang is something I’m familiar with, but that I never took to. I loathe the cumbersome syntax, but above all the arcaneness of the whole thing. Elixir is, by comparison, a lot more interesting, but I haven’t come across any problems that seem to be easier to solve with it – at least not if I want those solutions to be maintained by others.
Haskell has always felt completely alien to me, and even though I suspect I’ll eventually end up taking a longer look, it’s just too far off the beaten track right now.
In the end, the choice boils down to which one had the most potential to teach me a new way of thinking with the least pain – and in that regard, Clojure wins hands down so far.
The REPL Siren Call
There are quite a few parallels with what I went through a few years back when learning Python.
I started out learning Python at an interpreter prompt (and to this day have one permanently open everywhere I work), and am getting to grips with Clojure in mostly the same way, alternating between Sublime Text’s REPL plugin and Light Table.
Light Table is brilliant but rather unstable at the moment4, so I only use it occasionally – but it does have the nice bonus of supporting live Python and JavaScript evaluation, which makes it a perfectly natural fit for my usual workflow.
All things considered, though, and given that I spent most of my time using IPython over the past couple of weeks to run test cases and plot charts, I can’t help but wonder what a Clojure version of IPython could be like.
IDE-wise, I’ve also played around with Nightcode a bit, and it shows promise – largely because it’s relatively simple and focused when compared to traditional IDEs, which I mostly abhor.
There’s plently more to be said about Clojure, but I won’t bore you with it – as usual, I’ve been amassing a number of interesting resources and there is plenty more out there, so I encourage you to take a look for yourself.
Personally, and considering I’m devoting a fairly small percentage of time to getting to grips with it, I expect to have something interesting to show for my efforts in six months or so, and only become truly proficient in about a year (again, mostly like it was with Python).
Who knows, maybe next year I’ll even have the time to have a go at the Clojure Cup.
-
This setup works wonderfully for me in Jump Desktop - I’ve been using the beta versions ever since they included SSH private key support (now shipping) and a fair amount of keyboard and speed tweaks, so it’s as good as having a “full” computer provided you have a low-latency mobile connection. ↩︎
-
Ironically, one of the first things I ever used on a Mac was Common LISP back when I started college and it was one of the supporting languages for my AI courses, so “going back” to it is somewhat fitting. ↩︎
-
One of which was a small benchmark we ran internally, and where Clojure knocked most everything else out of the park (including Go) ↩︎
-
Especially when coupled with OpenJDK 7 in Ubuntu 13.04 – I’ve since simultaneously upgraded to the latest alpha and downgraded to OpenJDK 6, and things seem much more reliable. ↩︎