small medium large xlarge

Programming Clojure, Third Edition


Cover image for Programming Clojure, Third Edition

Programming Clojure, Third Edition


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.

Customer Reviews

Programming Clojure is an inspiration of Clojure knowledge and has furthered my
understanding of the nuances of Clojure. One of the new sections includes a stepby-
step on building an application that made me want to drop everything and
code along.

- Nola Stowe

CTO/Founder, Ruby Geek, LLC

If you are interested in learning the ins and outs of the Clojure language, Programming Clojure will provide you with a valuable resource. The book not only covers
the basics of the language, but also builds on the basics to allow readers to understand
and apply more advanced concepts like spec and macros.

- Joy Clark

Consultant, innoQ Deutschland GmbH

This book is very effective at teaching Clojure’s unique take on functional programming
and data manipulation. It explains concepts clearly and covers the mechanics
of nearly every part of the language, with helpful commentary that goes beyond
the code.

- Ghadi Shayban

Engineer, healthfinch

The third edition of Programming Clojure is an excellent resource for new and old
Clojure programmers. It provides a thorough account of the language’s rationale
and features, including approachable explanations of more recent features like
transducers and spec.

- Michael Fogleman


See All Reviews

Choose Your Format(s)

  • $26.95 In Stock
  • Ebooks are DRM free.

  • Ebook delivery options.

About this Title

Pages: 302
Published: 2018-02-21
Release: P1.0 (2018-02-20)
ISBN: 978-1-68050-246-6

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?

A: Clojure was always conceived with the intent to be a general purpose language targeted at domains where its hosted languages (Java, C#, JavaScript) were prevalent. Those languages cover a lot of territory, and Clojure has been used in a wide variety of domains as well. However, the majority of Clojure developers are creating multi-tier information systems (server + web UI) where they can share code (in Clojure and ClojureScript) across the tiers. These kinds of systems take full advantage of Clojure’s portability and its focus on the representation and transformation of information. Typical domains that take maximum advantage are financial services, ecommerce, healthcare, energy, legal, entertainment, and more.

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.

What You Need

  • Java 6 or higher
  • Clojure 1.9

Contents & Extracts

  • Acknowledgments
  • Preface
  • Introduction
    • Who This Book Is For
    • What’s in This Book
    • How to Read This Book
    • Notation Conventions
    • Web Resources and Feedback
    • Downloading Sample Code
  • Getting Started
    • Simplicity and Power in Action
    • Clojure Coding Quick Start
    • Navigating Clojure Libraries
    • Wrapping Up
  • Exploring Clojure excerpt
    • Reading Clojure
    • Functions
    • Vars, Bindings, and Namespaces
    • Metadata
    • Calling Java
    • Comments
    • Flow Control
    • Where’s My for Loop?
    • Wrapping Up
  • Unifying Data with Sequences
    • Everything Is a Sequence
    • Using the Sequence Library
    • Lazy and Infinite Sequences
    • Clojure Makes Java Seq-able
    • Calling Structure-Specific Functions
    • Wrapping Up
  • Functional Programming excerpt
    • Functional Programming Concepts
    • How to Be Lazy
    • Lazier Than Lazy
    • Recursion Revisited
    • Eager Transformations
    • Wrapping Up
  • Specifications
    • Defining Specs
    • Validating Data
    • Validating Functions
    • Generative Function Testing excerpt
    • Wrapping Up
  • State and Concurrency
    • Concurrency, Parallelism, and Locking
    • Refs and Software Transactional Memory
    • Use Atoms for Uncoordinated, Synchronous Updates
    • Use Agents for Asynchronous Updates
    • Managing Per-Thread State with Vars
    • A Clojure Snake
    • Wrapping Up
  • Protocols and Datatypes
    • Programming to Abstractions
    • Interfaces
    • Protocols
    • Datatypes
    • Records
    • reify
    • Wrapping Up
  • Macros
    • When to Use Macros
    • Writing a Control Flow Macro
    • Making Macros Simpler
    • Taxonomy of Macros
    • Wrapping Up
  • Multimethods
    • Living Without Multimethods
    • Defining Multimethods
    • Moving Beyond Simple Dispatch
    • Creating Ad Hoc Taxonomies
    • When Should I Use Multimethods?
    • Wrapping Up
  • Java Interop
    • Creating Java Objects in Clojure
    • Calling Clojure From Java
    • Exception Handling
    • Optimizing for Performance
    • A Real-World Example
    • Wrapping Up
  • Building an Application
    • Getting Started
    • Developing the Game Loop
    • Representing Progress
    • Implementing Players
    • Interactive Play
    • Documenting and Testing Your Game
    • Farewell


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.