Book Review - Programming Clojure
Buy it now
One Minute Bottom Line
|Overall, Programming Clojure succeeds in what it sets out to do, but follow-up volumes entitled Real World Clojure or The Clojure Cookbook somewhere down the line would be helpful in taking general use of Clojure to the next level by providing more concrete examples and guidance now the language has stabilized somewhat. Read this book and watch the videos, podcasts & screencasts linked from the Clojure web site and you will have had the best introduction possible for now.|
Along with the many screencasts & tutorials already available on the Internet, Programming Clojure provides an invaluable introduction for the first-time Lisp programmer or Java programmer looking for an alternate JVM language. The language and its use are described effectively, and the example application referred to throughout the book is a useful reference for anyone new to functional programming on how to incrementally build an application in a functional language - something confusing to most programmers used to imperative languages.
The first few chapters introduce Clojure, in particular exploring why the JVM needs another language and why a Lisp dialect is a good candidate. Starting with downloading Clojure, setting up the runtime and using the REPL - Clojure's interactive environment - helps anxious programmers get their hands dirty quickly. Before getting into actual coding, the chapter covers loading Clojure libraries and reading the self-documenting code, and the book's story arc project - an ant-like build system called Lancet - is also introduced. As the chapter summary says, it's a bit of a whirlwind tour, with some subjects (such as dealing with Clojure libraries) seeming a little out of place and lacking context, but everything covered will start to mean more in later chapters.
Exploring Clojure works through core language features: Forms covers how Clojure code is structured, read and compiled, and is important to understanding Lisp syntax and how the Clojure compiler works. It also covers the core data structures such as lists, maps and structs. Reader Macros shows how basic forms have shortcuts resulting in even more concise code. Being a functional language, Functions seems alarmingly short at first glance, but then it turns out to be one of those things where the rules are simple and their application is straightforward enough that nothing else is required. Data structures are covered in some detail in Vars, Bindings and Namespaces - if anything, probably the most confusing section for Java programmers as this is where the functional programming concept of immutable data first starts to appear. Flow Control and Where's my for Loop? deal with another point of confusion for imperative refugees.
Working with Java will be the chapter of most interest to Java programmers looking for another JVM language to learn, and Clojure's ability to leverage existing Java libraries has been a major contributor to its success so far. Clojure's ability to use Java APIs is rendered somewhat inelegant by the object-oriented nature of the JVM but, leaving aside the basics, this chapter clearly explains some of the gotchas and workarounds (such as using metadata type hints to prevent performance-crippling reflection).
As a Lisp dialect, Clojure's focus is on processing data represented as lists or list-like data structures, but Clojure takes this one step further into the Java world by unifying its data structures and many of Java's collections APIs as Sequences, which allows a wide variety of data structures to be processed using a single API. Unifying Data with Sequences covers this in detail, including once again clear explanations of how Clojure's sequence API builds on and greatly enhances Java's built-in collections.
Functional Programming and Concurrency are the chapters most Java programmers will want to read more than once. Language syntax aside, they cover the areas where any functional language, and particularly Clojure, differs significantly from imperative languages. Key functional concepts such as laziness and recursion lead into how Clojure handles concurrency very differently from Java through its use of Software Transactional Memory, Atoms, Agents and Vars. Writing concurrent applications correctly is hard, but these chapters together explain well how Clojure helps make the job a lot easier. Unfortunately, this leaves the reader with the feeling that Clojure actually has too many mechanisms for handling concurrency, with no clear idea of which works best under what circumstances. Whether this is the fault of the language or the text though is uncertain.
The Snake game application used as a concurrency example also provides some insight into integrating Clojure with Swing - something that is not covered elsewhere in the book and which almost deserves a chapter in its own right as Swing is arguably one of the more complex Java APIs Clojure can interact quite nicely with.
Macros and Multimethods dig deeper into the language itself and detail some of the features which Clojure programmers can use to streamline the language syntax and make it their own by developing DSLs. Again, the Lancet example helps by giving a real-world context to the explanations.
Clojure in the Wild ties up some of the loose ends that Java programmers will be asking about by now: how do I unit test my code? How do I access databases? Can I write web applications in Clojure?
Trying to explain all the nuances of a language as rich as Clojure is difficult, and on occasion the text mirrors the language's own syntax with lists of examples that can seem repetitive after a while, but the Lancet example application helps tremendously by giving the just-covered features some context and real-world usage. Some features important to application developers, such as unit testing, database access and web application development are left until the final chapters and are a little light, but this is understandable given that some of these things derive from libraries which were, at the time of writing, still heavily in development and subject to change. In fact, publication of the book was effectively held off until Clojure reached its stable 1.0 release.
Some mention is made of suitable development environments or editors, such as Emacs clojure-mode or the Eclipse/Netbeans/IntelliJ plugins, but due again to the unstable nature of Clojure at the time this consists entirely of web links to the various editors. Structuring a project and managing it with one of these editors is an exercise left to the reader, but some guidance over and above Lancet would have been useful.
I've always wondered what the fuss was about Lisp and have tried SBCL & Scheme in the past but found them quirky & difficult to work with. Coming from a Java background, Clojure immediately gives me something I can relate to (the JVM and the Java libraries) and makes it the most approachable Lisp variant I've tried so far. Programming Clojure has been an excellent introduction to the language and both are well worth a look for jaded Java programmers looking for a change.
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)