William E. Byrd & Daniel P. Friedman
Praise for the First Edition
The authors blaze through many of the classics of both functional programming and
industry programming in a whirlwind tour of Clojure that feels at times more like a
class-five tropical storm. You’ll learn fast!
—From the Foreword by Steve Yegge, Google
The Joy of Clojure wants to make you a better programmer, not just a better Clojure
programmer. I would absolutely recommend this to anyone I know who had an interest
in Clojure and/or functional programming.
Teaches the Tao of Clojure and, oh boy, it’s such a joy! Simply unputdownable!
—Baishampayan Ghose (BG)
Cofounder & CTO, Qotd, Inc.
The Clojure community, present and future, will be grateful for this book.
Discover the why not just the how of Clojure
Politecnico di Torino
The Joy of Clojure really lives up to its name! Every page oozes with the excitement
@fogus and @chrishouser have for the language and its community. This is exactly
what makes this book such an enjoyable read, it’s hard not to get drawn into the beauty
of Clojure when you have two convinced developers sharing their passion with you.
—Amazon Reader M.K.
What Irma Rombauer did for cooking, Fogus and Houser have done for Clojure!
By going beyond the basics, this book equips the reader to think like a native speaker
Creator of the Leiningen build tool, Heroku
A fun exploration of functional programming and Lisp.
Cofounder, Woven, Inc.
The Joy of Clojure
For online information and ordering of this and other Manning books, please visit
www.manning.com. The publisher offers discounts on this book when ordered in quantity.
For more information, please contact
Special Sales Department
Manning Publications Co.
20 Baldwin Road
PO Box 261
Shelter Island, NY 11964
©2014 by Manning Publications Co. All rights reserved.
No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in
any form or by means electronic, mechanical, photocopying, or otherwise, without prior written
permission of the publisher.
Many of the designations used by manufacturers and sellers to distinguish their products are
claimed as trademarks. Where those designations appear in the book, and Manning
Publications was aware of a trademark claim, the designations have been printed in initial caps
or all caps.
Recognizing the importance of preserving what has been written, it is Manning’s policy to have
the books we publish printed on acid-free paper, and we exert our best efforts to that end.
Recognizing also our responsibility to conserve the resources of our planet, Manning books
are printed on paper that is at least 15 percent recycled and processed without the use of
Manning Publications Co.
20 Baldwin Road
PO Box 261
Shelter Island, NY 11964
Printed in the United States of America
1 2 3 4 5 6 7 8 9 10 – EBM – 19 18 17 16 15 14
To Timothy Hart—a hacker of the highest order.
Rest in peace.
PART 1 FOUNDATIONS ..............................................................1
Clojure philosophy 3
Drinking from the Clojure fire hose
Dipping your toes in the pool 51
PART 2 DATA TYPES ................................................................67
On scalars 69
PART 3 FUNCTIONAL PROGRAMMING .....................................115
Being lazy and set in your ways 117
Functional programming 136
PART 4 LARGE-SCALE DESIGN................................................. 171
Combining data and code 194
Mutation and concurrency 224
PART 5 HOST SYMBIOSIS .......................................................275
Why ClojureScript? 310
PART 6 TANGENTIAL CONSIDERATIONS ..................................331
Data-oriented programming 333
Thinking programs 393
Clojure changes the way you think 423
foreword to the second edition xix
foreword to the first edition xxi
about this book xxvii
about clojure xxxvii
about the cover illustration xxxix
The Clojure way
Simplicity 4 Freedom to focus
Clarity 6 Consistency 7
Why a(nother) Lisp?
But what’s with all the parentheses?
Functional programming 16
A workable definition of functional programming 16
The implications of functional programming 17
Why Clojure isn’t especially object-oriented 17
Defining terms 17 Imperative “baked in”
OOP gives you, Clojure provides 19
Most of what
Drinking from the Clojure fire hose
Scalars: the base data types
Numbers 26 Integers 27 Floating-point numbers 27
Rationals 28 Symbols 28 Keywords 28 Strings 29
Putting things together: collections
Making things happen: calling functions
Vars are not variables 31
Anonymous functions 32 Creating named functions with def
and defn 33 Functions with multiple arities 33 In-place
functions with #() 34
Locals, loops, and blocks
Preventing things from happening: quoting 39
Evaluation 39 Quoting 40
splicing 42 Auto-gensym 42
Using host libraries via interop 43
Accessing static class members (Clojure only) 43 Creating
instances 43 Accessing instance members with the .
operator 44 Setting instance fields 44 The .. macro 44
The doto macro 45 Defining classes 45
Throwing and catching
Modularizing code with namespaces
Creating namespaces using ns 47 Loading other namespaces
with :require 48 Loading and creating mappings with
:refer 48 Creating mappings with :refer 49 Loading Java
classes with :import 49
Dipping your toes in the pool
What’s truth? 52
nil vs. false 53
Nil pun with care
Don’t create Boolean objects
Your assignment, should you choose to accept it 55
Destructuring with a vector 56 Destructuring with a map 57
Destructuring in function parameters 59 Destructuring vs.
accessor methods 59
Using the REPL to experiment 59
Experimenting with seqs 59 Experimenting with graphics 61
Putting it all together 63 When things go wrong 63 Just for
PART 2 DATA TYPES ......................................................... 67
Truncation 70 Promotion 71 Overflow
Underflow 72 Rounding errors 72
Trying to be rational 73
Why be rational?
How to be rational 74
When to use keywords
Applications of keywords
Symbols and namespaces
Syntax 82 Regular-expression functions
mutable matchers 83
Regular expressions—the second problem
Qualifying your keywords
Persistence, sequences, and complexity
“You keep using that word. I do not think it means what you
think it means.” 85 Sequence terms and what they mean 86
Vectors: creating and using them in all their varieties
Building vectors 91 Large vectors 92 Vectors as stacks 95
Using vectors instead of reverse 96 Subvectors 97 Vectors as
map entries 97 What vectors aren’t 98
Lists: Clojure’s code-form data structure
Lists like Lisps like
Lists as stacks
How to use persistent queues
A queue about nothing 101 Putting things on
Getting things 102 Taking things off 102
Basic properties of Clojure sets 103 Keeping your sets in order
with sorted-set 104 The contains? function 105 The
clojure.set namespace 105
Thinking in maps
Hash maps 107 Keeping your keys in order with sorted
maps 108 Keeping your insertions in order with array
Putting it all together: finding the position of items in a
PART 3 FUNCTIONAL PROGRAMMING .............................. 115
Being lazy and set in your ways
On immutability: being set in your ways
What is immutability?
What is immutability for?
Structural sharing: a persistent toy
Familiar laziness with logical-and 124 Understanding the lazyseq recipe 125 Losing your head 128 Employing infinite
sequences 129 The delay and force macros 130
Putting it all together: a lazy quicksort 132
Functions in all their forms
First-class functions 137 Higher-order functions 140 Pure
functions 144 Named arguments 145 Constraining
functions with pre- and postconditions 146
Functions returning closures 149
Passing closures as functions 150
Closing over parameters 150
Sharing closure context 151
Mundane recursion 155 Tail calls and recur 158 Don’t
forget your trampoline 161 Continuation-passing style 163
Putting it all together: A* pathfinding 165
The world 165 Neighbors 165 The A*
implementation 167 Notes about the A* implementation
PART 4 LARGE-SCALE DESIGN ........................................171
Data is code is data
Syntax-quote, unquote, and splicing
Defining control structures
Macro rules of
Defining control structures without syntax-quote 178 Defining
control structures using syntax-quote and unquoting 179
Macros combining forms 180
Using macros to change forms 182
Using macros to control symbolic resolution time
(Arguably) useful selective name
Using macros to manage resources 188
Putting it all together: macros returning functions
Combining data and code
Creating namespaces 196 Expose only what’s needed
Declarative inclusions and exclusions 199
Exploring Clojure multimethods with the Universal
Design Pattern 200
The parts 201 Basic use of the Universal Design Pattern 202
Multimethods to the rescue 203 Ad hoc hierarchies for inherited
behaviors 203 Resolving conflict in hierarchies
Arbitrary dispatch for true maximum power 205
Types, protocols, and records
Records 206 Protocols
base with deftype 217
Building from a more primitive
Mutation and concurrency
Putting it all together: a fluent builder for chess
When to use refs
Using refs for a mutable game board 228 Transactions 230
Embedded transactions 232 The things that STM makes
easy 232 Potential downsides 233 The things that make
STM unhappy 234
Refactoring with refs
Fixing the game board example 235 Commutative change with
commute 237 Vulgar change with ref-set 238 Refs under
When to use agents
In-process vs. distributed concurrency models 241 Controlling
I/O with an agent 243 The difference between send and
send-off 245 Error handling 246 When not to use
When to use atoms
Sharing across threads
When to use locks
Safe mutation through locking
Using Java’s explicit
Vars and dynamic binding 256
The binding macro 257
Creating anonymous vars
Using atoms in transactions
Creating a named var 257
258 Dynamic scope 259
When to use futures
Futures as callbacks
When to use promises
Parallel tasks with promises 269 Callback API to blocking
API 270 Deterministic deadlocks 271
The pvalues macro
The pmap function
A brief introduction to reducer/fold 273
PART 5 HOST SYMBIOSIS ..............................................275
Generating objects on the fly with proxy
A simple dynamic web service
Clojure gen-class and GUI programming 285
Namespaces as class specifications 286 The guts of namespace
compilation 288 Exploring user interface design and
development with Clojure 289
Clojure’s relationship to Java arrays
Types of arrays: primitive and reference 292 Array
mutability 294 Arrays’ unfortunate naming convention 295
Multidimensional arrays 296 Variadic method/constructor
All Clojure functions implement … 297
The java.util.Comparator interface 297 The java.lang.Runnable
interface 298 The java.util.concurrent.Callable interface 299
Using Clojure data structures in Java APIs
The java.util.List interface 300 The java.lang.Comparable
interface 300 The java.util.RandomAccess interface 301
The java.util.Collection interface 301 The java.util.Set
The definterface macro
Generating interfaces on the fly 302
Be wary of exceptions
A bit of background regarding exceptions 305 Runtime vs.
compile-time exceptions 305 Handling exceptions 307
Custom exceptions 308
Implementation vs. interface 311
Compiler internals: analysis vs. emission
Stages of compilation 315 Web Audio 317 Advanced
compilation 321 Generating an externs.js file 324
Compile vs. run
PART 6 TANGENTIAL CONSIDERATIONS .........................331
Code as code, and data as data
A strict line betwixt 334 ORMG 335 Common ways to
derive information from data 337 PLOP 337
Data as data
The benefits of value
Data as code 347
The data-programmable engine 347 Examples of dataprogrammable engines 347 Case study: simple event
Code as data as code
Hart’s discovery and homoiconicity 358 Clojure code is
data 358 Putting parentheses around the specification 358
Advantages of type adornment 364 Type-hinting arguments
and returns 364 Type-hinting objects 366
Ephemeral garbage 366
mutable collections 367
Transients compare in efficiency to
Regaining one-at-a-time laziness
Reexamining memoization 371 A memoization protocol
Abstraction-oriented programming 373
Using primitive longs 375
Using auto-promotion 377
Using primitive doubles
An example reducible collection 379 Deriving your first
reducing function transformer 380 More reducing function
transformers 383 Reducible transformers 385 Performance
of reducibles 386 Drawbacks of reducibles 387
Integrating reducibles with Clojure reduce 387 The fold
function: reducing in parallel 389
A problem of search
A brute-force Sudoku solver
Thinking data via unification
Declarative is the goal
An introduction to core.logic
Potential equality, or satisfiability
It’s all about unification
An introduction to constraint programming 414 Limiting
binding via finite domains 416 Solving Sudoku with finite
Clojure changes the way you think
Thinking in the domain
A ubiquitous DSL 424 Implementing a SQL-like DSL to
generate queries 426 A note about Clojure’s approach to
Some useful unit-testing techniques
Invisible design patterns
Clojure’s first-class design patterns
Error handling and debugging 447
Fare thee well
foreword to the second edition
In this second edition of The Joy of Clojure, Michael Fogus and Chris Houser present a
cornucopia of programming concepts, including many of the topics from the
programming languages course we taught together for many years. Fundamental programming languages concepts close to our hearts that appear in this book include
higher-order functions, lexical scope, closures, tail recursion, mutual recursion, continuations and continuation-passing style, trampolining, lazy sequences, macros, and
relational programming. Most important, Fogus and Houser teach you how to define
your own little languages.
Alan J. Perlis, brilliant language designer and inaugural Turing Award recipient,
famously wrote, “There will always be things we wish to say in our programs that in all
known languages can only be said poorly.” No existing programming language can
express precisely those concepts and abstractions needed for your specific application. The only person who can design a language to solve your exact problem is you.
Creating a little language to solve a specific problem is the most effective technique
yet devised for reducing complexity in software.1 Two well-known examples are database query languages and the formula languages of spreadsheet applications. These
examples are as notable for what they exclude as for what they include, illustrating
another of Perlis’s epigrams: “A programming language is low level when its programs
require attention to the irrelevant.” By only including features relevant to the problem, a well-designed little language is inherently high level.
Database query languages illustrate another fundamental aspect of little languages: writing a complete application requires addressing problems in more than
Jon Bentley popularized the concept of little languages in his article “Programming Pearls: Little Languages,”
Communications of the ACM 29, no. 8 (1986):711-21.
FOREWORD TO THE SECOND EDITION
one domain. An application that performs database queries will also make use of
other languages. A single little language can’t address the exact needs of a nontrivial
application any more than can a single general-purpose language.
For this reason, little languages work best in concert. The ideal technique for writing
a complex program is to slice it into multiple problem-specific pieces and then define
a language for each problem slice. If we slice the program vertically, the result is a
“tower” of languages, layered atop one another. Regardless of how we slice the overall
problem, we can use the right language, and the right paradigm, for each subproblem.
As with recursion, the art of defining little languages encourages—and rewards—
wishful thinking. You might think to yourself, “If only I had a language for expressing
the rules for legal passwords for my login system.” A more involved example—a story,
really—started several years ago, when we thought to ourselves, “If only we had the
right relational language, we could write a Lisp interpreter that runs backward.”2
What does this mean?
An interpreter can be thought of as a function that maps an input expression, such
as (+ 5 1), onto a value—in this case, 6. We wanted to write an interpreter in the style
of a relational database, in which either the expression being interpreted or the value
of that expression, or both, can be treated as unknown variables. We can run the interpreter forward using the query (interpret ‘(+ 5 1) x), which associates the query variable x with the value 6. Better yet, we can run the interpreter backward with the query
(interpret x 6), which associates x with an infinite stream of expressions that evaluate to 6, including (+ 5 1) and ((lambda (n) (* n 2)) 3). (Brainteaser: determine the
behavior of the query (interpret x x).)
Implementing a relational interpreter is tricky, but doing so can be made easier by
using a little language specifically designed for relational programming. In the end,
our wishful thinking led us to build a tower of languages: a relational Lisp interpreter,
on top of a rich relational language, on top of a minimal relational language, on top
of a rich functional language, on top of a minimal functional language.3 (The Lisp
interpreter accepts a minimal functional language, turning the tower of languages
into a circle!) Given the power of this approach, it isn’t surprising that many Lisp
implementations—including the Clojure compiler—are built as layers of languages.
Using what you’ll learn from Fogus and Houser in The Joy of Clojure, you can begin
building your own towers of languages, each with its own syntactic forms and evaluation rules, tailored to your specific problem domains. No technique for software
development is more expressive or more joyful.
WILLIAM E. BYRD AND DANIEL P. FRIEDMAN
Authors of The Reasoned Schemer (MIT Press, 2005)
We use Lisp to refer to any member of a large family of languages that includes Scheme, Racket, Common
Lisp, Dylan, and, of course, Clojure. To us, a Lisp must be homoiconic, have first-class functions, and have
some form of macros. (All three concepts are described in this book.)
3 By relational language, we mean a pure logic programming language; or, as in this example, a pure constraint
logic programming language.
foreword to the first edition
The authors of this book have taken an ambitious and aggressive approach to teaching Clojure. You know how everyone loves to say they teach using the “drinking from a
fire hydrant” method? Well, at times it feels like these guys are trying to shove that fire
hydrant right up ... let’s just say it’s a place where you don’t normally put a fire
hydrant. This isn’t intended as a first book on programming, and it may not be an
ideal first book on Clojure either. The authors assume you’re fearless and, importantly, equipped with a search engine. You’ll want to have Google handy as you go
through the examples. The authors blaze through many of the classics of both functional programming and industry programming in a whirlwind tour of Clojure that
feels at times more like a class-five tropical storm. You’ll learn fast!
Our industry, the global programming community, is fashion-driven to a degree
that would embarrass haute couture designers from New York to Paris. We’re slaves to
fashion. Fashion dictates the programming languages people study in school, the languages employers hire for, the languages that get to be in books on shelves. A naive
outsider might wonder if the quality of a language matters a little, just a teeny bit at
least, but in the real world fashion trumps all.
So nobody could be more surprised than I that a Lisp dialect has suddenly become
fashionable again. Clojure has only been out for three years, but it’s gaining momentum at a rate that we haven’t seen in a new language in decades. And it doesn’t even
or Rails propelled Ruby. Or maybe the killer app for Clojure is the JVM itself. Everyone’s fed up with the Java language, but understandably we don’t want to abandon
our investment in the Java Virtual Machine and its capabilities: the libraries, the configuration, the monitoring, and all the other entirely valid reasons we still use it.
FOREWORD TO THE FIRST EDITION
For those of us using the JVM or .NET, Clojure feels like a minor miracle. It’s an
astoundingly high-quality language, sure—in fact, I’m beginning to think it’s the best
I’ve ever seen—yet somehow it has still managed to be fashionable. That’s quite a
trick. It gives me renewed hope for the overall future of productivity in our industry.
We might just dig ourselves out of this hole we’re in and get back to where every project feels like a legacy-free startup, just like it was in the early days of Java.
There are still open questions about Clojure’s suitability for production shops,
especially around the toolchain. That’s normal and expected for a new language. But
Clojure shows so much promise, such beautiful and practical design principles, that
everyone seems to be jumping in with both feet anyway. I certainly am. I haven’t had
this much fun with a new language since Java arrived on the scene 15 years ago. There
have been plenty of pretenders to the JVM throne, languages that promised to take
the Java platform to unprecedented new levels. But until now, none of them had the
right mix of expressiveness, industrial strength, performance, and just plain fun.
I think maybe it’s the “fun” part that’s helped make Clojure fashionable.
In some sense, all this was inevitable, I think. Lisp—the notion of writing your code
directly in tree form—is an idea that’s discovered time and again. People have tried all
sorts of crazy alternatives, writing code in XML or in opaque binary formats or using
cumbersome code generators. But their artificial Byzantine empires always fall into
disrepair or crush themselves into collapse, while Lisp, the road that wanders through
time, remains simple, elegant, and pure. All we needed to get back on that road was a
modern approach, and Rich Hickey has given it to us in Clojure.
The Joy of Clojure just might help make Clojure as fun for you as it is for us.
This book is about the programming language Clojure. Specifically, this book is about
how to write Clojure code “The Clojure Way.” Even more specifically, this book is
about how experienced, successful Clojure programmers write Clojure code, and how
the language itself influences the way they create software.
You may be asking yourself, “Who are these guys, and why should I listen to them?”
Rather than simply appealing to an authority that you know nothing about, allow us to
take a few moments to explain how this book came about, who we are, and why we
wrote this book in the first place.
Both of us discovered Clojure early on in its life. It’s safe to say that there were
times when the Clojure IRC channel #clojure (on Freenode) contained only ourselves
along with Clojure’s designer—Rich Hickey—and a handful of other people. Our
story in finding the language is similar to the story of many of its early adopters. That
is, our path runs from modern object-oriented languages4 like Java and C++, through
of how we found Clojure are unimportant; the point is that we were both searching
for something that none of the other languages provided.
What does Clojure provide that none of the other languages can or do? In a nutshell, we think that when you understand Clojure’s nature and write code harmonious
to this nature, a new perspective on the art of programming and systems construction
is revealed. Therefore, the answer to what Clojure provides that those other languages
And indeed the younger versions of ourselves were both deeply influenced by the public ponderings of Steve
Yegge and Paul Graham.
don’t is enlightenment (so to speak). We’re not the only ones who feel this way; there
are projects being developed right now that are deeply influenced by Clojure’s nature.
From Datomic to Om5 to Avout to Pedestal, Clojure’s influence is apparent. The
Clojure Way is starting to spread to other programming languages, including (but not
limited to) Scala, Elixir, and Haskell.
In addition to Clojure’s influence in the language design arena, many programmers are using the language every day in their work. The use of Clojure and systems
written in Clojure to solve hard business problems is growing every day. Since we
wrote the first edition, we too have spent our work lives using and learning from
Clojure, and naturally this learning prompted a desire to update this book. Although
the first edition is still relevant from a factual perspective, we felt that a second edition
should include the lessons of our professional use of this amazing language. Nothing
in this book is speculative. Instead, we’ve used every technique and library, from
reducibles to core.logic to data-oriented design, to solve real systems problems.
This book is about the Way of Clojure, written by two programmers who use the
language on a daily basis and have thought long and hard about its nature. We hope
that by thoughtfully reading this book, you can come to an appreciation of Clojure’s
power and importance.
Om is also deeply influenced by the works and ideas of Alan Kay and Bret Victor.