Published: February 2018
Drowning in unnecessary complexity, unmanaged state, and tangles of spaghetti code? In the best tradition of Lisp, Clojure gets out of your way so you can focus on expressing simple solutions to hard problems. Clojure cuts through complexity by providing a set of composable tools—immutable data, functions, macros, and the interactive REPL. Written by members of the Clojure core team, this book is the essential, definitive guide to Clojure. This new edition includes information on all the newest features of Clojure, such as transducers and specs.
Clojure joins the flexibility and agility of Lisp with the reach, stability, and performance of Java. Combine Clojure’s tools for maximum effectiveness as you work with immutable data, functional programming, and safe concurrency to write programs that solve real-world problems.
Start by reading and understanding Clojure syntax and see how Clojure is evaluated. From there, find out about the sequence abstraction, which combines immutable collections with functional programming to create truly reusable data transformation code. Clojure is a functional language; learn how to write programs in a functional style, and when and how to use recursion to your advantage. Discover Clojure’s unique approach to state and identity, techniques for polymorphism and open systems using multimethods and protocols, and how to leverage Clojure’s metaprogramming capabilities via macros. Finally, put all the pieces together in a real program.
New to this edition is coverage of Clojure’s spec library, one of the most interesting new features of Clojure for describing both data and functions. You can use Clojure spec to validate data, destructure data, explain invalid data, and generate large numbers of tests to verify the correctness of your code.
With this book, you’ll learn how to think in Clojure, and how to take advantage of its combined strengths to build powerful programs quickly.
5 Tips for Thinking in Clojure
1. Rely on your REPL. Clojure (like other LISP languages) intends to provide a “live” development experience where you are actively manipulating and testing the program while you develop the code. To take full advantage of Clojure, it’s essential to work in a development environment that allows you to interactively evaluate parts of your code while you develop. We are fortunate to have a variety of tool choices in Clojure that can satisfy those demands.
2. Maps, not Objects. Developers coming from object-oriented languages are likely to look for the ability to create classes or objects to hold their data. Clojure takes a more direct and flexible approach to data, primarily storing information attributes in heterogenous maps. Rather than providing class-specific interfaces, Clojure provides a single generic data interface for creating, accessing, and transforming attribute-oriented information. The result is that modeling data and managing the evolution of data over time is generally much more generic and immediate than the equivalent operations in object-oriented languages.
3. Collections, not Loops. Imperative languages encourage you to write loops that manipulate data elements one-by-one. In Clojure, you instead think primarily in collections, not loops. When transformations need to be applied, you use a functional approach to describe the transformation from one collection to another, which may involve mapping, filtering, or otherwise transforming data at the collection level.
4. Isolate State. Clojure is not a pure functional language - it has constructs readily available to create and manage state, perform I/O, etc. However, most Clojure developers minimize the number of functions that work with these kinds of constructs. As much as possible, Clojure functions tend to be small and pure, just simple transformations of data to data. Clojure’s model for all state manipulation is to describe stateful change as a function from prior state to new state. Stateful change thus becomes little more than the application of pure functions to data.
5. Have Fun! Many people find Clojure to be one of the most enjoyable languages they’ve ever used. There is very little ceremony in the code, a literal syntax to easily represent data, a huge library of functions available for transforming data, and access to all of the existing functionality of the underlying host platform via either interop or libraries. Clojure gets out of the way and lets you get to work!
Q&A with author Alex Miller
Q: Why did you get involved with the 3rd edition of Programming Clojure?
A: The first edition of Programming Clojure was important because it was the first Clojure book available. Stuart Halloway worked closely with Rich Hickey, the creator of Clojure, to capture the key ideas behind Clojure and let that philosophy shine through. I first picked up Clojure about the time this book was published and I found it to be a helpful and insightful guide. It has been a great challenge and pleasure to revisit this material that I used to learn Clojure myself from the other side of the page.
Q: What’s changed since the 2nd edition?
A: Aaron Bedra provided an excellent update in the second edition of Programming Clojure for the release of Clojure 1.3, which provided both a lot of new features and an overhaul of certain parts of the language (like numerics). In this third edition, everything has been brought up to date with Clojure 1.9, the latest release. I have included new material on features added since the last edition like transducers and spec. Additionally, many of the longer examples have been updated to take advantage of the latest features and functions of the language.
Q: What kinds of problems are best solved with Clojure?
Q: How portable is code between the different dialects of Clojure, ClojureScript, and ClojureCLR?
A: At the heart of Clojure is the ability to represent data (using Clojure collections) and transform it using sequences and transducers. In almost all cases, code that creates and manipulates data, controls flow, or creates and invokes functions is exactly the same on all of these platforms. The areas where they start to differ is where the host platforms differ with respect to managing state or concurrency, or working with I/O, date/time, etc - places where Clojure and its dialects rely more heavily on the hosted platform. However, Clojure includes the ability to create conditional code such that minor host differences can be covered in a single cross-platform source file and users of that code don’t have to worry about those differences.
Q: What’s the role of the new Clojure spec library?
A: The spec library is perhaps the most important new feature added to Clojure in years. Clojure does a fantastic job of providing tools for representing any domain in data, and then manipulating that data. However, the combination of dynamic typing and generic data transformation means that while code be very concise and reusable, it’s sometimes hard to see at a glance the shape of the data flowing through your system. Specs provide a language for describing your data and the functions that use it. This language is based on predicate functions (code you already have) and once you write your specs you gain a whole host of tools for using them to validate data according to a spec, parse data into its constituent pieces, explain why an invalid value is invalid, automatically generate example data, detect invalid function calls, and even automatically test functions using generated data. Specs are quickly becoming an essential part of the Clojure toolset for managing data.
Alex Miller was about to give up on programming as irretrievably complex when he found Clojure, which renewed his love for code. Alex works by day on improving Clojure and spends his off hours organizing the Strange Loop conference and playing music with his kids.
Stuart Halloway is a founder and president of Cognitect (formerly Relevance). He is a Clojure committer, and a developer of the Datomic database. Stuart has written a number of books and technical articles. Of these, he is most proud of Programming Clojure.
Aaron Bedra is CTO and CSO at Eligible. He is the creator of Repsheet, an open source threat intelligence toolkit, and a frequent open source contributor. He enjoys sharing his password with friends and family and wearing questionable hats.
Published: February 2018