Disclaimer: The reviewed version was from the Manning Early Access Program in PDF form.

Summary

Clojure In Action is a great book for a developer looking to expand their skills into a new language area. It assumes the reader has a reasonable level of understanding of major technologies and practices. This is not a beginners book. The writing is thoughtful and clear. A common theme throughout the book is that concepts are developed in much the same way that one might develop a solution in the real world. For example in the section on messaging, we first look at a cheap and cheerful message passing system, then the author observes that the solution mixes “interfacing with the messaging system” and “handling the messages”. The simple solution is then enhanced to allow a clean separation. The system is then further developed into a large scale distributed processing system with robust error handling etc.

My feelings after reading the book are that learning clojure will make you a better developer, even if you don’t use the language directly. The approach taken by the language, as discussed in this book, will help you think about problems in different ways. Be warned tho, if you don’t have familiarity with LISPs there is a lot to learn before you can progress. The author addresses this early on, when he talks in chapter 3 about the ‘productivity ravine’. This is that familiar feeling when learning a new way of doing something you experience a steep drop in productivity and have to work hard to climb back up (and hopefully) surpass your previous level.

I’d argue that because the LISP concepts are less familiar than most the ravine is particularly deep in this case. There are certain concepts that you really have to conquer before you can really do anything. The first few forays into the clojure REPL will be a frustrating experience. Having said that the book is structured with this is mind. I would advise really studying part 1 closely to build a good foundation before moving onto real world examples in part 2 or you won’t be making the most of the book.

Structure of the Book

The book is divided into two parts

Getting Started – Need to know all this to ‘grok’ clojure Getting Real – Can dip in and out as required as a reference to learn the clojure slant on a particular technology

Part I – Getting Started

The Getting Started section is a well pitched overview of the clojure language structure and delves into some of the compelling features that make clojure attractive for certain classes of programs. It tackles head on the barriers, perceived or otherwise, to learning the language. The most common phrase you will hear when anyone discusses a lisp based language like clojure is that the syntax is ‘hard’, or that ‘all those parentheses’ make life difficult. The author makes a good case why these criticisms are unwarranted.

In my view the unfamiliarity, rather than the complexity of the syntax is what jars with newcomers to the language. One of the key points about LISP is that there really is very *little* syntax and that it’s so uniform. An interesting observation is that since clojure is so much more compact than java, often if you compare two equivalent programs, one written in clojure, the other in java – it will be the clojure program that will have *less* parentheses and they won’t be as structured!

I found this first section really useful in consolidating my rudimentary knowledge. I enjoyed (re)discovering some aspects of software that I had forgotten. The section on how clojure handles polymorphism via multi-methods was a great enlightenment on the limitations of C++ “inheritance based” dispatch. The great Alan Kay is quoted here to highlight that there are other ways to achieve the goal….

“Actually, I invented the term Object Orientation and I can tell you that C++ is not what I had in mind”.

The author avoids the trap of simply telling us what’s wrong with a particular approach and instead takes the positive path of explaining which of the limitations clojure overcomes.

Rich Hickey (Clojure’s creator) realised that, with the myriad java libraries out there, any JVM language MUST interact with java. I was a bit disappointed with the coverage of this key area in chapter 5. Sure all the key points are covered, but I felt that they deserved a more practical approach, more examples to properly illustrate the clojure forms here.

Chapter 6 about state and concurrency follows a, hopefully by now, familiar pattern. First we read about the problems with the mish-mash of state/identity and traditional approaches to handling these conflicts. Immutability as a default is well justified in the text. We then learn about the tools clojure provides to tackle the different aspects of this thorny problem. This is an area where clojure has made some bold choices. The success of the language as a whole will hinge on whether the these choices allow us to solve the upcoming problems with the an acceptable level of fuss and ceremony.

Part II – Getting Real

The Getting Real section takes a practical approach to real world problems. It will serve as a useful reference for how to get started with various tasks in clojure.

First it starts off in chapter 8 with an introduction to support for Test Driven Development(TDD) specifically in clojure. The section expands into how to deal with method stubbing and mocking and ends with advice about organizing tests. In common with the earlier sections a good conceptual level of TDD knowledge is assumed, this section is not going to convince you that TDD is the right or wrong thing for you, but if you’re already drinking the TDD kool-aid, you’ll feel very at home here.

The book starts shifting up through the gears in Chapter 9 about data storage. It has example code for connecting to MySQL, HBASE and Redis is discussed. Obviously each of these technologies have their own chunk of bookshelf dedicated to them, so here we’re just learning enough to be dangerous! The book shows how easy evaluating and hacking around on these technologies is in the clojure REPL. The HBASE example stores a deep object graph and retrieves it in a few dozen lines, quite refreshing if you’re used to battling with JPA / Hibernate annotations in Java (the text doesn’t provide anything like a production ready solution, but the potential is clear).

This demonstrates both the power of clojure but also highlights one of the major barriers to learning. Clojure code is very ‘dense’. You can get a lot done in a relatively small number of lines, but to understand those lines you need to have internalized the key APIs. I found it useful to have a REPL open as I read so I could invoke the ‘doc’ and ‘find-doc’ function easily to help me decode the code I was reading.

The chapter on “clojure and the web” talks about the leading clojure web frameworks. One of the key attractions of web programming is that you can very easily see the fruits of your labours, this chapter will help you see something in your browser pretty quickly, but I don’t believe that, currently, clojure is really the right tool for writing complex web apps. The text doesn’t do much to change my mind. There is very active development in the clojure community in this space, so I’ll certainly revisit this view in a few months time. Simple web-services may be a good fit here however.

Chapter 11, about scaling though messaging, is where the power of clojure really starts to come through. By the end of the chapter we have developed a distributed processing system in around 200 lines of code. If you’re like me you will spend a long time studying those 200 lines to really decipher the meaning. The amazing possibilities of macros comes through here, but again this is where the reader really needs to put the time in to understand what’s going on. This isn’t a criticism of the book, I found myself going back to earlier descriptions a few times and realised that I hadn’t properly followed the authors explanations the first time round, but that with a bit more knowledge on my part the fog cleared.

Chapter 12 introduces some common ‘large scale’ tasks and talks about clojure / Hadoop integration. Again the author’s style here is helpful in quickly seeing the opportunities clojure can offer in this space.

Chapters 13 – 15 fill in the gaps in our clojure learning with information about the last few features of clojure that haven’t been covered yet. The macro section is excellent but difficult. The author notes that.

“Finally, we’ll look at writing macros that generate other macros. This can be tricky, and we’ll look at a simple example of such a macro. Understanding macro-generating macros is a sign of being on the path to macro zen”

(page 358)

He also addresses the motivations for moving computation from run-time to compile time, a key benefit of macros, that I hadn’t properly appreciated before reading this book. We see an example of generating, at compile time, a cryptographic tableau for a rotation based cypher.

I don’t feel I’ve achieved clojure zen or even macro zen yet, but I’m more confident that I’m on the right path with the help of this book.

Recommended.

About the Reviewer

Neale Swinnerton (@sw1nn) has been a professional software developer for over 20 years, mostly in the financial services industry. He recently started investigating startup opportunities.