from inner functions. But built on Clojure’s dynamic Var binding is a more active
mode of error handling, where handlers are pushed into inner functions. In section
11.10, we mentioned that the binding form is used to create thread-local bindings,
but its utility isn’t limited to this use case. In its purest form, dynamic scope is a struc-
tured form of a side effect (Steele 1978). You can use it to push Vars down a call stack
from the outer layers of a function nesting into the inner layers, a technique that we’ll
demonstrate next.
DYNAMIC TREE TRAVERSAL
In section 8.4, we built a simple tree structure for a domain model where each node
was of this form:
{:tag <node form>, :attrs {}, :content [<nodes>]}
As it turns out, the traversal of a tree built from such nodes is straightforward using
mundane recursion, as shown:
(defn traverse [node f]
(when node
(f node)
(doseq [child (:content node)]
(traverse child f))))
For each node in the tree, the function f is called with the node itself, and then each
of the node’s children is traversed in turn. Observe how traverse works for a single
root node:
(traverse {:tag :flower :attrs {:name "Tanpopo"} :content []}
println)
; {:tag :flower, :attrs {:name Tanpopo}, :content []}
But it’s much more interesting if we traverse trees larger than a single node. There-
fore, we can build a quick tree from an XML representation using Clojure’s clojure.
xml/parse function:
(use '[clojure.xml :as xml])
(def DB
(-> "<zoo>
<pongo>
<animal>orangutan</animal>
Download from Wow! eBook <www.wowebook.com>
Error handling and debugging
307
</pongo>
<panthera>
<animal>Spot</animal>
<animal>lion</animal>
<animal>Lopshire</animal>
</panthera>
</zoo>"
.getBytes
(java.io.ByteArrayInputStream.)
xml/parse))
The DB Var contains an animal listing for a small zoo. Note that two of the animals
listed have the elements Spot and Lopshire; both are seemingly out of order for a
zoo. Therefore, we can write a function to handle these nefarious intruders.
Listing 13.8 Handling nefarious tree nodes with exceptions
(defn ^{:dynamic true} handle-weird-animal
[{[name] :content}]
Define error handler
(throw (Exception. (str name " must be 'dealt with'"))))
(defmulti visit :tag)
(defmethod visit :animal [{[name] :content :as animal}]
(case name
"Spot" (handle-weird-animal animal)
"Lopshire" (handle-weird-animal animal)
(println name)))
(defmethod visit :default [node] nil)
The multimethod visit can be used as the input function to the traverse function
and will only trigger when a node with the :tag attribute of :animal is encountered.
When the method triggered on :animal is executed, the node :content is destruc-
tured and checked against the offending Spot and Lopshire values. When found, the
devious node is then passed along to an error handler handle-weird-animal for
reporting.5 By default, the error handler throws an exception. This model of error
handling is the inside-out model of exceptions. But handling errors in this way stops
the processing:
(traverse DB visit)
; orangutan
; java.lang.Exception: Spot must be 'dealt with'
We’ve managed to identify Spot, but the equally repugnant Lopshire escapes our
grasp. It’d be nice to instead use a different version of handle-weird-animal that
allows us to both identify and deal with every such weird creature. We could pass
handle-weird-animal along as an argument to be used as an error continuation,6 but
5
The metadata {:dynamic true} attached to handle-weird-animal isn’t really used in Clojure 1.2, but it
may be required in future versions of Clojure starting with 1.3 to allow the dynamic binding we’re about to
demonstrate.
6
See section 7.3 for more information on continuation-passing style.
Download from Wow! eBook <www.wowebook.com>
308
CHAPTER 13 Clojure changes the way you think
that pollutes the argument list of every function along the way. Likewise, we could
inject catch blocks at a point further down the call chain, say within visit, but we
might not be able to change the source, and if we could it makes for a more insidious
pollution. Instead, using a dynamic binding is a perfect solution, because it allows us
to attach specific error handlers at any depth in the stack according to their appropri-
ate context:
(defmulti handle-weird (fn [{[name] :content}] name))
(defmethod handle-weird "Spot" [_]
(println "Transporting Spot to the circus."))
(defmethod handle-weird "Lopshire" [_]
(println "Signing Lopshire to a book deal."))
(binding [handle-weird-animal handle-weird]
(traverse DB visit))
; orangutan
; Transporting Spot to the circus.
; lion
; Signing Lopshire to a book deal.
As you might expect, this approach works across threads to allow for thread-specific
handlers:
(def _ (future
(binding [handle-weird-animal #(println (:content %))]
(traverse DB visit))))
; orangutan
; [Spot]
; lion
; [Lopshire]
What we’ve outlined here is a simplistic model for a grander error-handling scheme.
Using dynamic scope via binding is the preferred way to handle recoverable errors in
a context-sensitive manner.
13.4.2 Debugging
The natural progression of debugging techniques as discovered by a newcomer to
Clojure follows a fairly standard progression:
1
(println)
2
A macro to make (println) inclusion simpler
3
Some variation on debugging as discussed in this section
4
IDEs, monitoring, and profiling tools
Many Clojure programmers stay at step 1, because it’s simple to understand and also
highly useful, but there are better ways. After all, you’re dealing with Clojure—a
highly dynamic programming environment. Observe the following function:
(defn div [n d] (int (/ n d)))
Download from Wow! eBook <www.wowebook.com>
Error handling and debugging
309
The function div simply divides two numbers and returns an integer value. You can
break div in a number of ways, but the most obvious is to call it with zero as the
denominator: (div 10 0). Such an example would likely not give you cause for con-
cern should it fail, because the conditions under which it fails are fairly limited, well
known, and easily identified. But not all errors are this simple, and the use of println
is fairly limited. Instead, a better tool would likely be a generic breakpoint7 that could
be inserted at will and used to provide a debug console for the current valid execution
context. Imagine it would work as follows:
(defn div [n d] (break) (int (/ n d)))
(div 10 0)
debug=>
At this prompt, you can query the current lexical environment, experiment with dif-
ferent code, and then resume the previous execution as before. As it turns out, such a
tool is within your grasp.
A BREAKPOINT MACRO
We hope that by the end of this section, you’ll understand that Lisps in general, and
Clojure in particular, provide an environment where the whole of the language truly is
“always available” (Graham 1993). First of all, an interesting fact to note is that the
Clojure REPL is available and extensible via the Clojure REPL itself, via the clojure.
main/repl function. By accessing the REPL implementation directly, you can custom-
ize it as you see fit for application-specific tasks.
Typing (clojure.main/repl) at the REPL seemingly does nothing, but rest
assured you’ve started a sub-REPL. What use is this? To start, the repl function takes a
number of named parameters, each used to customize the launched REPL in different
ways. We’ll utilize three such hooks—:prompt, :eval, and :read—to fulfill a break-
point functionality.
OVERRIDING THE REPL’S READER
The repl function’s :read hook takes a function of two arguments: the first corre-
sponding to a desired display prompt, and the second to a desired exit form. We want
the debug console to provide convenience functions—we’d like it to show all of the
available lexical bindings and also to resume execution. It also needs to be able to
read valid Clojure forms, but because that’s too complex a task, we’ll instead farm that
functionality out to Clojure’s default REPL reader.
Listing 13.9 A modest debug console reader
(defn readr [prompt exit-code]
(let [input (clojure.main/repl-read prompt exit-code)]
(if (= input ::tl)
exit-code
input)))
7 The code in this section is based on debug-repl created by the amazing George Jahad, extended by Alex
Osborne, and integrated into Swank-Clojure by Hugo Duncan.
Download from Wow! eBook <www.wowebook.com>
310
CHAPTER 13 Clojure changes the way you think
We can start testing the reader immediately:
(readr #(print "invisible=> ") ::exit)
[1 2 3]
;=> [1 2 3]
(readr #(print "invisible=> ") ::exit)
::tl
;=> :user/exit
The prompt that we specified was of course not printed, and typing ::tl at the
prompt did nothing because the readr function isn’t yet provided to the repl as its
:read hook. But before we do that, we need to provide a function for the :eval hook.
Needless to say, this is a more complex task.
OVERRIDING THE REPL’S EVALUATOR
In order to evaluate things in context, we first need a function cab to garner the bind-
ings in the current context. Fortunately for us, Clojure macros provide an implicit
argument &env that’s a map of the local bindings available at macro-expansion time.
We can then extract from &env the values associated with the bindings and zip them
up with their names into a map for the local context, as shown next.
Listing 13.10 Creating a map of the local context using &env
(defmacro local-context []
(let [symbols (keys &env)]
(zipmap (map (fn [sym] `(quote ~sym)) symbols) symbols)))
(local-context)
;=> {}
(let [a 1, b 2, c 3]
(let [b 200]
(local-context)))
;=> {a 1, b 200, c 3}
The local-context macro provides a map to the most immediate lexical bindings,
which is what we want. But what we really want to do is to provide a way to evaluate
expressions with this contextual bindings map. Wouldn’t you know it, the contextual-
eval function from section 8.1 fits the bill. So now that we have the bulk of the imple-
mentation complete, we’ll now hook into the repl function to provide a breakpoint
facility.
PUTTING IT ALL TOGETHER
The hard parts are done, so to wire them into a usable debugging console is relatively
easy, as shown next.
Listing 13.11 The implementation of a breakpoint macro
(defmacro break []
`(clojure.main/repl
:prompt #(print "debug=> ")
:read readr
:eval (partial contextual-eval (local-context))))
Download from Wow! eBook <www.wowebook.com>
Error handling and debugging
311
Using this macro, we can now debug the original div function:
(defn div [n d] (break) (int (/ n d)))
(div 10 0)
debug=>
Querying locals to find the “problem” is simple:
debug=> n
;=> 10
debug=> d
;=> 0
debug=> (local-context)
;=> {div #<user$div__155 user$div__155@51e67ac>, n 10, d 0}
debug=> ::tl
; java.lang.ArithmeticException: Divide by zero
So there’s the problem! We passed in a zero as the denominator. We should fix that.
MULTIPLE BREAKPOINTS AND BREAKPOINTS IN MACROS
What would be the point if you couldn’t set multiple breakpoints? Fortunately, you
can, as we show in the following listing.
Listing 13.12 Using multiple breakpoints in function keys-apply
(defn keys-apply [f ks m]
(break)
(let [only (select-keys m ks)]
(break)
(zipmap (keys only) (map f (vals only)))))
(keys-apply inc [:a :b] {:a 1, :b 2, :c 3})
debug=> only
; java.lang.Exception: Unable to resolve symbol: only in this context
debug=> ks
;=> [:a :b]
debug=> m
;=> {:a 1, :b 2, :c 3}
debug=> ::tl
debug=> only
;=> {:b 2, :a 1}
debug=> ::tl
;=> {:a 2, :b 3}
And finally, you can use breakpoints within the body of a macro (in its expansion, not
its logic), as shown next.
Listing 13.13 Using a breakpoint in a macro awhen
(defmacro awhen [expr & body]
(break)
`(let [~'it ~expr]
(if ~'it
(do (break) ~@body))))
(awhen [1 2 3] (it 2))
Download from Wow! eBook <www.wowebook.com>
312
CHAPTER 13 Clojure changes the way you think
debug=> it
; java.lang.Exception: Unable to resolve symbol: it in this context
debug=> expr
;=> [1 2 3]
debug=> body
;=> ((it 2))
debug=> ::tl
debug=> it
;=> [1 2 3]
debug=> (it 1)
;=> 2
debug=> ::tl
;=> 3
There’s much room for improvement, but we believe that the point has been made.
Having access to the underpinnings of the language allows you to create a powerful
debugging environment with little code. We’ve run out of ideas by now, so we’ll say
our credo only once more, and we hope by now you believe us.
Clojure changes the way that you think.
13.5
Fare thee well
This book possess many lacunae, but it’s this way by design. In many cases, we’ve
skipped approaches to solving problems via a certain route to avoid presenting non-
idiomatic code. In many examples, we’ve left exposed wiring. For example, the
defcontract macro requires that you partially apply the contract to the function
under constraint instead of providing a comprehensive contract overlay façade. It was
our goal to leave wiring exposed because exposed wiring can be explored, tampered
with, and ultimately enhanced—which we hope you’ll find the motivation to do.
We’ve worked hard to provide a vast array of relevant references should you choose
to further enhance your understanding of the workings and motivations for Clojure.
But it’s likely that we’ve missed some excellent resources, and we hope that you
instead are able to uncover them in time. Finally, this wasn’t a survey of Clojure, and
many of the functions available to you weren’t used in this book. We provide some
pointers in the resource list, but there’s no way that we could do justice to the librar-
ies and applications mentioned and those unmentioned. We implore you to look
deeper into the functionality of not only Clojure, but the rich ecology of libraries and
applications that have sprung up in its relatively short life span.
Thank you for taking the time to read this book; we hope it was as much a pleasure
to read as it was for us to write. Likewise, we hope that you’ll continue your journey
with Clojure. Should you choose to diverge from this path, then we hope that some of
what you’ve learned has helped you to view the art of programming in a new light.
Clojure is an opinionated language, but it and most of its community believe that
these opinions can work to enhance the overall state of affairs in our software indus-
try. The onus is on us to make our software robust, performant, and extensible. We
believe that the path toward these goals lies with Clojure.
Do you?
—FOGUS AND HOUSER 2010
Download from Wow! eBook <www.wowebook.com>
resources
Miscellaneous resources
Abadi, Martin, and Luca Cardelli. 1996. A Theory of Objects. New York: Springer. Although not a math-
ematical concept, object-oriented programming has obtained rigor with this gem.
Abelson, Harold, and Gerald Jay Sussman. 1988. “ Lisp: A Language for Stratified Design.” AI Memo
(MIT) 986.
———. 1996. Structure and Interpretation of Computer Programs. Cambridge, MA: MIT Press. There is no
better book for learning Scheme and the fine art of programming.
Abiteboul, Serge, Richard Hull, and Victor Vianu. 1995. Foundations of Databases. Boston: Addison-
Wesley. Clojure’s clojure.set namespace is actually modeled more on the named conjunctive
algebra, for which this book provides a great reference.
Armstrong, Joe. 2007. Programming Erlang. Raleigh, NC: Pragmatic Bookshelf.
———. 2007. “A History of Erlang.” Proceedings of the Third ACM SIGPLAN Conference on History of Pro-
gramming Languages.
Bagwell, Phil. 2001. Ideal Hash Trees. Technical report. Clojure’s persistent data structures owe a lot to
Phil Bagwell’s paper.
Baker, Henry. 1993. “Equal Rights for Functional Objects or, The More Things Change, The More
They Are the Same.” ACM SIGPLAN OOPS Messenger 4, no. 4.
Beck, Kent. 2002. Test Driven Development: By Example. Boston: Addison-Wesley.
Bloch, Joshua. 2008. Effective Java. Upper Saddle River, NJ: Addison-Wesley.
Boncz, Peter, Zukowski Marcin, and Niels Nes. 2005. “MonetDB/X100: Hyper-Pipelining Query
Execution.” Proceedings of the CIDR Conference. This paper motivated the implementation of
chunked sequences.
Bratko, Ivan. 2000. PROLOG: Programming for Artificial Intelligence. New York: Addison Wesley.
Budd, Timothy. 1995. Multiparadigm Programming in Leda. Reading, MA: Addison-Wesley. This is an
expanded discussion of the complexities wrought from a mono-paradigm approach to software
development.
Clinger, William. 1998. “Proper Tail Recursion and Space Efficiency.” Proceedings of the ACM SIGPLAN
1998 Conference on Programming Language Design and Implementation.
Cormen, Thomas, Charles Leiserson, Ronald Rivest, and Clifford Stein. 2009. Introduction to Algo-
rithms. Cambridge, MA: MIT Press. This is a great reference on algorithmic complexity and Big-
O, and as an added bonus, you could use it to stop a charging rhinoceros.
313
Download from Wow! eBook <www.wowebook.com>
314
RESOURCES
Crockford, Douglas. 2008. JavaScript: The Good Parts. Yahoo Press.
Date, C.J. 2009. SQL and Relational Theory: How to Write Accurate SQL Code. Sebastopol, CA: O’Reilly.
Dijkstra, Edsger Wijbe. 1959. “ A Note on Two Problems in Connexion with Graphs.” Numerische Mathema-
tik 1, no. 1. You could change the h function in listing 7.9 to (defn dijkstra-estimate-cost
[step-cost-est sz y x] 0) to conform to the ideal presented in this paper.
Flanagan, David. 2006. JavaScript: The Definitive Guide. Sebastopol, CA: O’Reilly.
Forman, Ira, and Nate Forman. 2004. Java Reflection in Action. Greenwich, CT: Manning. Although reflec-
tion provides some meta-level manipulation, it’s quite apart from the notion of functions as data.
Friedl, Jeffrey. 1997. Mastering Regular Expressions. Sebastopol, CA: O’Reilly.
Friedman, Daniel, Mitchell Wand, and Christopher T. Haynes. 2001. Essentials of Programming Languages.
Cambridge, MA: MIT Press.
Gabriel, Richard, and Kent Pitman. 2001. “Technical Issues of Separation in Function Cells and Value
Cells.” This is a more thorough examination of the differences between Lisp-1 and Lisp-2.
Gamma, Erich, Richard Helm, Ralph Johnson, and John Vlissides. 1995. Design Patterns: Elements of
Reusable Object-Oriented Software. Reading, MA: Addison-Wesley.
Ghosh, Debasish. 2010. DSLs in Action. Greenwich, CT: Manning. There is a much finer level of distinc-
tion determining what constitutes whole cloth, including that between internal and external DSLs.
In this book, we focus on the classical Lisp model of internal DSLs, but DSLs in Action provides a sur-
vey of many DSL-creation techniques.
Glickstein, Bob. 1997. Writing GNU Emacs Extension s. Sebastopol, CA: O’Reilly.
Goetz, Brian. 2006. Java Concurrency in Practice. Upper Saddle River, NJ: Addison-Wesley. Why haven’t you
read this yet?
Goldberg, David. 1991. “ What Every Computer Scientist Should Know About Floating-Point Arithmetic.”
Computing Surveys (March).
Graham, Paul. 1993. On Lisp. Englewood Cliffs, NJ: Prentice Hall. Is there any book or any author more
influential to the current generation of dynamic programmers than Graham and On Lisp?
———. 1995. ANSI Common Lisp. Englewood Cliffs, NJ: Prentice Hall.
Gray, Jim, and Andreas Reuter. 1992. Transaction Processing: Concepts and Techniques. San Mateo, CA: Mor-
gan Kaufmann Publishers.
Halloway, Stuart. 2009. “ Clojure is a better Java than Java .” Presented at the Greater Atlanta Software
Symposium, Atlanta. The origin of the phrase “Java.next” most likely stems from this talk by
Halloway.
Hart, Peter, Nils Nilsson, and Bertram Raphael. 1968. “A Formal Basis for the Heuristic Determination
of Minimum Cost Paths.” IEEE Transactions on Systems Science and Cybernetics In Systems Science and
Cybernetics 4, no. 2.
Hewitt, Carl, Peter Bishop, and Richard Steiger. 1973. “ A Universal Modular ACTOR Formalism for Arti-
ficial Intelligence .” Proceedings of the Third International Joint Conference on Artificial Intelligence.
Heinlein, Robert. 1966. The Moon Is a Harsh Mistress. New York: Putnam. We had considered offering an
implementation of Mike as an appendix, but we ran over our page count.
Herlihy, Maurice, and Nir Shavit. 2008. The Art of Multiprocessor Programming. Amsterdam; Boston:
Elsevier/Morgan Kaufmann.
Hickey, Rich. 2009. “ Are We There Yet?” Presented at JVM Languages Summit. This wonderful presenta-
tion made firm the popular view of Rich as Philosopher Programmer.
Hofstadter, Douglas. 1979. Gödel, Escher, Bach: An Eternal Golden Braid. New York: Basic Books. See the sec-
tions “Classes and Instances,” “The Prototype Principle,” and “The Splitting-off of Instances from
Classes” for more detail of the topics in section 9.2.
Download from Wow! eBook <www.wowebook.com>
RESOURCES
315
Hoyte, Doug. 2008. Let Over Lambda. Lulu.com. This is an amazing look into the mind-bending power of
Common Lisp macros that provided the motivation for the DSLs section of this book. It will blow
your mind—in a good way.
Hudak, Paul. 2000. The Haskell School of Expression: Learning Functional Programming Through Multimedia.
New York: Cambridge University Press.
Huet, Gerard. 1997. “Functional Pearl: The Zipper.” Journal of Functional Programming.
Hutton, Graham. 1999. “A Tutorial on the Universality and Expressiveness of fold.” Journal of Functional
Programming 9, no. 4.
Kahan, William, and Joseph Darcy. 1998. “How Java’s Floating-Point Hurts Everyone Everywhere.” Pre-
sented at the ACM Workshop on Java for High-Performance Network Computing. This paper pro-
vides more information on the cyclopian nightmares awaiting you in Java floating point.
Keene, Sonya. 1989. Object-Oriented Programming in Common Lisp: A Programmer’s Guide to CLOS. Boston:
Addison-Wesley. The best book on CLOS ever written.
Knuth, Donald. 1997. The Art of Computer Programming: Volume 1 - Fundamental Algorithms. Reading, MA:
Addison-Wesley. This book goes into exquisite detail about the primary characteristics of FIFO
queues and is highly recommended reading.
———. 1998. The Art of Computer Programming, Vol. 3: Sorting and Searching. Reading, MA: Addison-Wesley.
Running quick-sort on a sorted sequence is an O(n2) operation, which for our implementation in
chapter 6 completely defeats its laziness.
Koenig, Dierk, Andrew Glover, Paul King, Guilaume LaForge, and Jon Skeet. 2007. Groovy in Action.
Greenwich, CT: Manning.
Kuki, Hirondo, and William James Cody. 1973. “A Statistical Study of the Accuracy of Floating Point
Number Systems.” Communications of the ACM 1973 16, no. 4.
Laddad, Ramnivas. 2003. AspectJ in Action: Practical Aspect-Oriented Programming. Greenwich, CT:
Manning. We do not do justice to the notion of aspects—so read this instead.
Martin, Robert. 2002. Agile Software Development: Principles, Patterns, and Practices. Upper Saddle River, NJ:
Prentice Hall.
McCarthy, John. 1960. “Recursive Functions of Symbolic Expressions and Their Computation by
Machine, Part I.” Communications of the ACM. This is the essay that started it all.
———. 1962. LISP 1.5 Programmer’s Manual. Cambridge, MA: MIT Press. Lisp had an array type at least as
early as 1962. Sadly, this fact is little known.
McConnell, Steve. 2004. Code Complete: A Practical Handbook of Software Construction. Redmond, WA:
Microsoft Press.
Meyer, Bertrand. 1991. Eiffel: The Language. New York: Prentice Hall. The programming language Eiffel
relies heavily on contract-based programming methodologies, a cornerstone element of Fogus’s
philosophy of Apperception-Driven Development.
———. 2000. Object-Oriented Software Construction. Upper Saddle River, NJ: Prentice Hall.
Michie, Donald. 1968. “ Memo Functions and Machine Learning.” Nature 218.
Mooers, Calvin, and Peter Deutsch. 1965. “TRAC, A Text-Handling Language.”
Moseley, Ben, and Peter Marks. 2006. “Out of the Tar Pit.” Presented at SPA2006.
Mozgovoy, Maxim. 2009. Algorithms, Languages, Automata, and Compilers: A Practical Approach. Sudbury,
MA: Jones and Bartlett Publishers.
Noble, James, and Brian Foote. 2003. “Attack of the Clones.” Proceedings of the 2002 Conference on Pattern
Languages of Programs 13. The clone function is inspired by this paper.
Norvig, Peter. 1991. Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp. San Fran-
cisco: Morgan Kaufman Publishers.
Download from Wow! eBook <www.wowebook.com>
316
RESOURCES
Odersky, Martin, Lex Spoon, and Bill Venners. 2008. Programming in Scala: A Comprehensive Step-by-step
Guide. Mountain View, CA: Artima.
Okasaki, Chris. 1996. “ The Role of Lazy Evaluation in Amortized Data Structures.” Presented at the
International Conference on Functional Programming. This is a much more thorough discussion
of incremental vs. monolithic computation.
———. 1999. Purely Functional Datastructures. Cambridge University Press. Chris Okasaki to the rescue
again! Clojure’s persistent queue implementation is based on Okasaki’s batched queue from this
seminal work.
Olsen, Russ. 2007. Design Patterns in Ruby . Upper Saddle River, NJ: Addison-Wesley
Papadimitriou, Christos. 1986. Theory of Database Concurrency Control. New York: Computer Science
Press, Inc.
Pierce, Benjamin. 2002. Types and Programming Languages. Cambridge, MA: MIT Press. Fun fact: Repre-
senting numbers using lambda calculus is known as church encoding. The church-encoded number
9 would be represented as (fn [f] (fn [x] (f (f (f (f (f (f (f (f (f x))))))))))) in
Clojure.
Raymond, Eric. 2003. The Art of Unix Programming. Reading, MA: Addison-Wesley Professional.
Rosenberg, Doug, Mark Collins-Cope, and Matt Stephens. 2005. Agile Development with ICONIX Process:
People, Process, and Pragmatism. Berkeley, CA: Apress.
Skeel, Robert. 1992. “ Roundoff Error and the Patriot Missile.” SIAM News 25, no. 4: 11.
Steele, Guy L. 1977. “ Lambda: the Ultimate GOTO.” ACM Conference Proceedings.
———. 1990. Common LISP: The Language. Bedford, MA: Digital Press. This is a very witty book in addition
to being packed with information.
Steele, Guy L., and Gerald Sussman. 1978. “The Art of the Interpreter.” AI Memo (MIT) 453.
Stewart, Ian. 1995. Concepts of Modern Mathematics. New York: Dover. These Dover math books are often
true gems. It would be great to see an adventurous publisher print a similar series revolving around
C.S.-relevant topics—monads, category theory, lambda calculus, and so on.
Sussman, Gerald, and Guy L. Steele. 1975. “Scheme: An Interpreter for the Extended Lambda Calculus.”
Higher-Order and Symbolic Computation 11, no. 4. This is a discussion of Scheme’s early implementa-
tion of lexical closures.
Symbolics Inc. 1986. Reference Guide to Symbolics Common Lisp: Language Concepts. Symbolics Release 7 Doc-
ument Set.
Thompson, Simon. 1999. Haskell: The Craft of Functional Programming. Reading, MA: Addison-Wesley.
Ullman, Jeffrey. 1988. Principles of Database & Knowledge-Base Systems Vol. 1: Classical Database Systems.
Rockville, MD: Computer Science Press.
Ungar, David, and Randal Smith. 1987. “ SELF: The power of simplicity.” Presented at the Conference on
Object-Oriented Programming Systems, Languages, and Applications (OOPSLA), Orlando. The
Self programming language is likely the greatest influence on prototypal inheritance.
Van Roy, Peter, and Seif Haridi. 2004. Concepts, Techniques, and Models of Computer Programming.
Cambridge, MA: MIT Press.
Wadler, Philip. 1989. “Theorems for Free!” Presented at the fourth International Conference on Func-
tional Programming and Computer Architecture.
Wampler, Dean, and Alex Payne. 2009. Programming Scala. Sebastopol, CA: O’Reilly.
Download from Wow! eBook <www.wowebook.com>
RESOURCES
317
Whitehead, Alfred North. 1929. Process and Reality: An Essay in Cosmology. Cambridge University Press. For
a general overview of Whitehead, see The Wit And Wisdom of Alfred North Whitehead by A.H. Johnson
(Boston, Beacon Press, 1947).
Williams, Laurie. 2002. Pair Programming Illuminated. Boston: Addison-Wesley Professional. The limita-
tions of the book format only shadow the idealistic model of pair programming.
Online resources
Braithwaite, Reginald. 2007. “Why Why Functional Programming Matters Matters.” http://mng.bz/
2pZP. This column discusses a language-level separation of concerns.
Clementson, Bill. 2008. “Clojure could be to Concurrency-Oriented Programming what Java was to
OOP.” http://bc.tech.coop/blog/081201.html. A much deeper discussion concerning Erlang actors and Clojure agents.
Dekorte, Steve. Io . http://iolanguage.com.
Fogus, Michael. Lithp. http://github.com/fogus/lithp.
Fowler, Martin. 2005. “Fluent Interface.” http://mng.bz/e2r5.
———. 2007. “Mocks Aren’t Stubs.” http://mng.bz/mq95.
Graham, Paul. Arc. www.paulgraham.com/arc.html.
———. 2001. “What Made Lisp Different.” www.paulgraham.com/diff.html. As Paul Graham states,
“The whole language always available” appears as a theme throughout this book and as a finale in
section 13.5.
Houser, Chris. error-kit API . http://mng.bz/07FF. The clojure.contrib.error-kit namespace contains an open error system similar to CL conditions that don’t require recompilation when defining new
error types.
Krukow, Karl. 2009. “Understanding Clojure’s PersistentVector Implementation.” http://mng.bz/tmjv.
Lindholm, Tim, and Frank Yellin. 1999. Java Virtual Machine Specification. http://java.sun.com/docs/
Peter. 1998. “ Design Patterns in Dynamic Programming .” http://norvig.com/design-patterns/.
The section on design patterns was inspired by this presentation.
Tarver Mark. 2008. Functional Programming in Qi. www.lambdassociates.org/Book/page000.htm. Some programming languages perform partial application automatically when a function is
supplied with fewer than the expected number of arguments. One such language is Qi.
———. 2009. “The Next Lisp: Back to the Future .” http://mng.bz/8wA9. The notion of Lisp as a programming language genotype is explored.
_why. Shoes. http://github.com/shoes/shoes.
Yegge, Steve. 2006. “ Execution in the Kingdom of Nouns . ” http://mng.bz/9ApS.
———. 2008. “The Universal Design Pattern.” http://mng.bz/6531. Like many programmers of our generation, we were in many ways inspired and influenced by Steve Yegge’s work—which is why we
asked him to write this book’s foreword.
Download from Wow! eBook <www.wowebook.com>
Download from Wow! eBook <www.wowebook.com>
index
Keywords and symbols
ad-hoc hierarchies 16, 70, 184,
Agents 235, 240, 247, 249–255,
A
B
abstractions 166, 188, 208, 227,
319
Download from Wow! eBook <www.wowebook.com>
320
INDEX
clojure.contrib.repl-utils 52–53
clojure.core 41, 179, 183, 271
clojure.lang.IPersistentStack 86
clojure.set 40, 94, 96, 183, 294
concrete classes 16, 193, 195,
closures 17, 135–141, 197, 230,
C
code
consistency 7–8, 238, 242, 261
constructors 37, 55, 198, 204,
chess 16, 202, 204–205, 241–242
Clojure
Download from Wow! eBook <www.wowebook.com>
INDEX
321
Design Patterns: Elements of
Reusable Object-Oriented
count-tweet-text-task 263–264,
Software 303
E
destructuring 8, 47–48, 54, 57,
D
def 27–28, 135, 137, 181, 271,
defn 17, 27, 136, 164, 181, 271
dynamic binding 287, 293, 306,
Download from Wow! eBook <www.wowebook.com>
322
INDEX
exceptions (continued)
Gödel, Escher, Bach: An Eternal
graphical user interface (GUI)
first-class functions 72, 126,
F
H
First In, First Out (FIFO) 91,
futures 235, 261–263, 265, 269
G
I
fn 26, 28, 82, 135–136, 146, 164
identity 3, 13–14, 71, 202, 211,
Download from Wow! eBook <www.wowebook.com>
INDEX
323
idiomatic 34, 36, 46, 62, 82, 87,
java.util.Collections/sort 223
immutability 7, 14, 30, 77–78,
java.util.concurrent.Blocking-
java.util.concurrent.Callable
java.util.concurrent.locks 260
J
infinite sequence 113, 118, 283
java.util.List 15, 79, 223, 225
java.util.regex.Matcher 48, 75
interfaces 8, 16, 192–193, 195,
java.io.FilterOutputStream 211
K
java.lang.Object 128, 205, 220,
java.lang.StackOverflowError
Download from Wow! eBook <www.wowebook.com>
324
INDEX
L
locking 14, 234, 236, 238, 250,
let 29, 36, 52, 82, 117, 135, 137,
M
metadata 69, 71, 128, 164, 181,
lists 24–25, 33, 79, 90–91, 122,
literal syntax 23–25, 83, 89, 97,
locals 29–30, 72, 117, 136, 143,
Download from Wow! eBook <www.wowebook.com>
INDEX
325
multimethods (continued)
persistent data structures 7, 77,
N
O
primitives 21, 64, 83, 200, 229,
occur-count 288–289
P
protocols 15–16, 121, 189, 192,
Download from Wow! eBook <www.wowebook.com>
326
INDEX
reduce 119, 129, 180, 280, 304
Q
S
R
referential transparency 12, 132
range 51, 68, 83, 90, 117, 282
regular expressions 52, 61, 75
reify 38, 141, 198, 208, 211, 304
records 189, 191, 195, 197–198,
recur 30–31, 142, 144–147, 200
freeing the recursive call 142
rest 46, 78, 80, 89, 91, 115–116,
Download from Wow! eBook <www.wowebook.com>
INDEX
327
side effects 29, 131–132, 154,
transactions 235–236, 239, 241,
symbols 23, 26, 28, 70–71, 159,
T
there ain’t no such thing as a
third-party libraries 171, 194,
U
this 108, 171, 185, 198, 210–211
thread-local 28, 240, 270, 273
thread-local bindings 271–273,
unit testing 128, 292, 298, 302
Download from Wow! eBook <www.wowebook.com>
328
INDEX
V
X
Vars 25, 27, 32–34, 40, 72, 128,
W
Y
vectors 24, 33, 80, 82, 98, 193
Z
Download from Wow! eBook <www.wowebook.com>


FUNCTIONAL PROGRAMMING
THE Joy OF Clojure
SEE INSERT
Fogus Houser
If you’ve seen how dozens of lines of Java or Ruby can dissolve
into just a few lines of Clojure, you’ll know why the authors
of this book call it a “joyful language.” Clojure is a dialect
“You’ll learn fast!”
of Lisp that runs on the JVM. It combines the nice features of a
—From the foreword
scripting language with the powerful features of a production
by Steve Yegge, Google
environment—features like persistent data structures and clean
multithreading that you’ll need for industrial-strength
“Simply unputdownable!”
application development.
—Baishampayan Ghose (BG)
Qotd, Inc .
The Joy of Clojure goes beyond just syntax to show you how to
write fl uent and idiomatic Clojure code. You’ll learn a functional
“Discover the why, not just
approach to programming and will master Lisp techniques
the how of Clojure.”
that make Clojure so elegant and effi
cient. Th
e book gives
—Federico Tomassetti
you easy access to hard soft ware areas like concurrency,
Politecnico di Torino
interoperability, and performance. And it shows you how
great it can be to think about problems the Clojure way.
“What Irma Rombauer
did for cooking, Fogus
What’s Inside
and Houser have done
Th
e what and why of Clojure
for Clojure.”
How to work with macros
—Phil Hagelberg, Sonian
How to do elegant application design
Functional programming idioms
Written for programmers coming to Clojure from another
programming background—no prior experience with
Clojure or Lisp is required.
Michael Fogus is a member of Clojure/core with experience in
distributed simulation, machine vision, and expert systems.
Chris Houser is a key contributor to Clojure who has
implemented several of its features.
For online access to the authors and a free ebook for owners
of this book, go to manning.com/TheJoyofClojure
M A N N I N G
$44.99 / Can $51.99 [INCLUDING eBOOK]