The Joy of Clojure by Michael Fogus and Chris Houser
Publisher: Manning Publications
Languages evolve idioms for a reason. Idioms are mental shortcuts to expressive and robust solutions. They are the sign of expertise and true understanding. Mastering those idioms is the hardest part of learning any language. Given that Clojure has been around for almost six years now it has grown its fair share of idiomatic constructs. Some of them are radically different from other Lisps. The Joy of Clojure captures these idioms and serves as a guide for the intermediate Clojure programmer looking to bring his command of Clojure to the next level.
The main reason I choose to invest time in Clojure over other interesting technologies like Scala were the Lisp roots of Clojure. The uniformity and simplicity of the Lisp language family has always attracted me. Initially I had my doubts. I was far from convinced of the simplicity advantage. Clojure has a surprisingly large design space with plenty of syntax (at least compared to other Lisps). This is a double-edged sword. A large design space obviously gives you control over a vast variety of details. Local decisions can be tailored and optimized to specific constraints and circumstances. And a rich syntax may improve the communication value of the code. On the other hand, the readability and immediate accessibility of the code suffers since uniformity is lost. Enter idioms. An established and adapted set of idiomatic coding constructs help us navigate Clojure programs. As such, this book is a valuable guide. In parallel with some hands-on, real-world programming in Clojure I started to build an understanding and appreciation of the philosophy and ideas behind Clojure. There are still some parts of the language where I'm not entirely convinced. Since I'm developing a larger application in Clojure right now I may get opportunities to re-consider my views later. Familiarity is hard to shake-off.
Clojure is often sold as a language for the multi-core world so I would like to contrast it with an other prominent player in the field: Erlang. Rich Hickey, the visionary creator of Clojure, has made a deliberate choice to exclude the message-passing actor model found in Erlang. The two languages simply have different goals. Clojure is optimized for in-process concurrency whereas Erlang excels in a distributed world. Yet I do feel that Erlang's model is the more natural one, even for in-process work. In Erlang the parallelity of the problem itself is expressed through its actors and the protocols between them. In Clojure, parallelity is an active choice. And it always worries me when we have to differentiate between sequential and parallel code. Does they necessarily have to look different?
Unsurprisingly, The Joy of Clojure backs-up the design choice of Clojure. It does so by including an interesting philosophical discussion of actors, with pattern matching, contrasted with Clojure's agents. The former are closed, while Clojure's agents are an open design. The authors are correct in that patterns couple the structure with the logic. In practice (i.e. when I code in Erlang with its heavy reliance on pattern matching) I never found this to be a problem. It's probably because the modules are cohesive enough in themselves. But it definitely made me think which is just what I expect from a good book.
So far programming in Clojure has indeed been a joy to me. With one exception (no pun intended); error handling in Clojure is horrible. Sure, much of it is to blame on the JVM. But as an application programmer it bothers me to get stack traces at a much lower level of abstraction than what my programs express. What you see in a stack trace does not even remotely connect to the surface of the source code you just ran. The situation is likely to get addressed and improve over time.
Other aspects of Clojure are a true lesson in simplicity with lots of elegant design decisions. If there's one thing I dislike within a specific technology it has to be special cases. Special cases are booby traps waiting to catch an unaware programmer. They're a waste of cognitive resources, a manifestation of ugliness. In this respect, Clojure is a fresh breeze. The language is remarkably consistent. Take named arguments as an example. Rather than adding them to the core language, a move that would be straightforward in any Lisp, Clojure choose to generalize its existing support for destructuring to function arguments. The result is increased uniformity and an opportunity to generalize existing knowledge to a new solution element. A truly elegant and beautiful design choice.
As far as the future of the language is concerned Clojure is alive and ever evolving. The core developers seem to be careful about the additions they make. But you still have to revisit and reconsider your acquired idioms with each new version of the language. A book like The Joy of Clojure gets dated rather fast. For example, just as I got around to write this summary, Clojure 1.5 got released. This new release brings a powerful reducers library to the language. It will definitively be interesting to watch the idioms grow around reducers. And perhaps we will soon; rumor has it that the authors work on a second edition of The Joy of Clojure. I make sure to buy my copy when it becomes available. The Joy of Clojure is perhaps a harder read than the topic would necessitate. Yet it's an awarding read filling an important role in the Clojure literature. Just make sure you have a decent grasp of the fundamentals and some practice behind before you try to tackle the book. To a newcomer I would recommend Clojure Programming as a solid introduction. Make The Joy of Clojure the second book you read and expect to re-visit it frequently as your understanding of the language grows. I'm sure I will.
Reviewed March 2013