Owen on software

The Beauty of Clojure

24 August 2015 - Comments

Recently, I’ve been a bit quiet on the blogging front. Part of the reason is that I’ve been learning the programming language Clojure. It’s been emotional.

Lisp Hater

Clojure has been around since 2007. So, it’s taken me a while to get around to exploring it in anger. Actually, I bought The Joy of Clojure1 back in 2013. So how come it took me so long to get around reading it?

I have got a confession. I have been a Lisp hater ever since my first exposure to them at university. And when I say ‘hater’ I am not exaggerating. I hated Lisps with a passion. I just did not understand why anyone would want to write software in a Lisp, given the alternatives. I never got past the parentheses and the prefix notation.

However, the assertion of Clojure developers that it’s the best thing since sliced bread, and the most productive programming language on the planet, pushed me past my phobia of excessive parentheses.

Parentheses - The Horror, The Horror

If you look around at various Clojure articles you’ll find lots of folk downplaying the affect of Lisp parentheses and prefix notation on code readability. Personally, I think that is nonsense; at least for those new to the language.

Most of us have grown-up with languages where we read left-to-right, and where infix notation is the general way maths and logic operators are expressed. It is ingrained in us. The use of s-expressions2 and their resulting prefix notation is in many respects the secret sauce of Clojure. However, it requires you to read right-to-left3 and inside-out. This is counterintuitive to most of us, and takes some getting over. It is a very real barrier to entry for Lisps.

For example, here is some noddy code in Clojure. It just takes a range of numbers, adds two to each of them, and then sums the resulting numbers together.

It’s about as simple as it’s ever going to get. Yet, for those who are not well versed in reading Lisp code, it’s not easy to digest3. Compare it to the equivalent Scala code, below. Make your own mind up.

The irony is that once you’ve gotten past this initial hurdle, s-expressions lay the foundation that make Clojure one of the simplest and most consistent modern programming languages to use. But it does take some effort. Not loads. But it is something you have to push past.

Letting go of static typing

Perhaps the next thing that hits you, coming from a background in Java, is the lack of static type checking. (Or the Functional Programming (FP) paradigm. If you are unfamiliar with FP, I’d suggest you get familiar with it prior to looking at Clojure. That’s my ten pence worth.)

In some ways it’s liberating. After all, who ever wanted to fetch data from a data store, turn marshall it into a fully-fledged object, and then marshall that to JSON? With Clojure you can kiss good-bye to that. The data is just a map right. So is JSON. Boom. Adios anaemic domain model.

On the other hand, it’s a bit like ‘Holy-cow, I’m just receiving a map as an argument to my function! What the hell has it got in it?’ Err, yeah, your guess is as good as mine4.

But if you can live without the typing of Java, then Clojure is remarkably productive.

The Beauty of Clojure

Pretty soon, much to your surprise, you start falling in love with Clojure. The conciseness of the s-expression based syntax, the consistency of the language, the power: it is beautiful.

It’s about this time you find yourself wanting to stand up and salute the genius of John McCarthy, the creator of Lisp, and to thank Rich Hickey for creating a truly pragmatic Lisp dialect for the JVM.

And Clojure, like Scala, is a language for the pragmatists, not the purists. It’s there to build great software with, not to define the perfect language.

Clojure don’t do frameworks

Once you look to start building applications with Clojure something else hits you. There are no Clojure frameworks. They just don’t exist. Everything is composed from libraries5.

In Clojure, functions are a first class citizen of the language. As a result, the language offers an entirely new level of composability over Java. This notion of composable parts manifests itself throughout the Clojure eco-system, where frameworks are seen as tightly coupled monoliths.

This can be a little daunting at first, and is certainly a paradigm shift coming from Java. Initially, it requires a bit more legwork too, as you have to identify the libraries to assemble into your application. But the result is a compact application with minimal bloat-ware.

Plus the legwork is often worth the effort, as many of the libraries you find are elegant and powerful. Just take compojure-api as an example. This will enable you to generate a REST API, including Swagger support, with minimal effort.

Clojure vs Scala

After you get over the paradigm shift required to read a language based on s-expressions, Clojure is simple. Really simple. It is just lists, in lists, in lists …

Scala, by comparison, isn’t. Why would it be? Clojure does Functional Programming (FP), the Lisp way. Scala does OO, FP, static typing, and more. If only for that reason, Scala is pretty much guaranteed to be about three times as complex straight off the bat. And that’s before you throw in implicits, et al.

Don’t get me wrong, I really like Scala. It has typing. I can refactor a huge codebase in my IDE. Good luck trying that with Clojure. But Scala is more complex. By providing both OO and FP models and mutable and immutable approaches Scala gives you a lot of rope to hang yourself with.

Clojure is, in that sense, purer, more opinionated, and ultimately simpler. Clojure is compact.

ClojureScript - the unsung hero

As you journey into Clojure, sooner or later you are going to come across ClojureScript and it’s Facebook React wrappers. If you have ever done web application development with languages and frameworks that transpile to Javascript (like Google Web Toolkit) before, you’ll soon find yourself picking your jaw off the ground.

In combination with tooling, like figwheel, you can achieve a realtime development experience, where your existing browser state is largely maintained on code/CSS updates. Yep, you read that right. Check out this video for a live demo.

Even if you weren’t keen before, the arguments for Clojure start to become incredibly compelling at this point. (Scala also has Scala.js and it’s own equivalent of figwheel called workbench. Although, it currently does not support the same level of state retention during code updates - possibly due to the constraints of static typing.)

Is Clojure ready for the Enterprise?

If I was going to do a startup project today there is no question in my mind that I would go for a Clojure/ClojureScript combination. But would I use it in an Enterprise? I don’t know.

The trouble is the world of Enterprise software development is dominated by a lack of strong technical leadership, resulting in projects riddled with anti-patterns and off-shore development gone terribly terribly wrong. If this is what happens when organisations use a fairly simple and statically typed language like Java, which is relatively easy to quality assure, what would they do with the power inherent in a dynamic and macro-enabled language like Clojure?

So for me, the jury is still out for the Enterprise. And yet, I can’t get past the sheer development speed offered by Clojure(script). There’s no doubt in my mind that I could put a lot of jaws on the ground using it in the Enterprise. It’s just the long-tail implications I’m unsure of.

When it comes to typing, Typed Clojure offers more fuel on the fire. On the one hand, it’s existence seems to indicate that dynamic typing doesn’t scale; that Clojure is missing something. Yet at the same time it offers the possibility to rapidly prototype and later add optional typing where it’s felt necessary.

I’m just not sure you are not better off starting with a statically typed language to begin with, or whether Typed Clojure is really a great middle ground. (Those with strong opinions, please feel welcome to try and convince me!)

All your fn are belong to us

Clojure has worn me down, and freed me from my hatred of Lisps. I’m deeply impressed. Clojure I salute you.

Of course, the trouble is that hardly anyone is using Clojure. <insert sad emoji>. Take a quick look at jobserve. You find there are five times as many Scala job ads as there are for Clojure. And there are about ten times as many job ads for Java as there are for Scala. Until the Enterprise software community buy into Clojure, that is not going to change. Still, here is to hoping for more experiments to explore it’s potential in enterprise-scale software development.

If you are new to Clojure, interested in learning more, and the job prospects haven’t put you off, I’d suggest getting started with the Light Table instarepl and something like Clojure for the Brave and True.

(I’m now using Emacs again after a 15 year absence, but that’s a whole other story for another post!)

[UPDATE: This post ended up trending on Hacker News for a while, which was both cool and unexpected. Lots of interesting comments on the thread, so worth heading over there to check them out.]

  1. FYI - there are better books to get started with. 

  2. I could say a lot more about s-expressions, Clojure, homoiconicity, etc, but I’m not going to. It’s already been said elsewhere, really well. Google it

  3. Clojure does have a couple of macros, thread first and thread last , which help with this to some extent.  2

  4. Both Schema and Typed Clojure aim to solve this issue, although with very different approaches and remits. 

  5. Luminus is not a bad place to start for web applications, as it provides a set of ‘approved’/best-in-class libraries with which you can pull together a fully-featured application. 

Tags: Clojure Scala


comments powered by Disqus