Practical Clojure

By Luke VanderHart , Stuart Sierra

Practical Clojure Cover Image

This is the first definitive reference for the Clojure language, providing both an introduction to functional programming in general and a more specific introduction to Clojure's features.

Full Description

  • ISBN13: 978-1-4302-7231-1
  • User Level: Beginner to Intermediate
  • Publication Date: June 6, 2010
  • Available eBook Formats: EPUB, MOBI, PDF
  • Print Book Price: $49.99
  • eBook Price: $34.99
Buy eBook Buy Print Book Add to Wishlist

Related Titles

Full Description

This book is the first definitive reference for the Clojure language, providing both an introduction to functional programming in general and a more specific introduction to Clojure’s features. This book demonstrates the use of the language through examples, including features such as software transactional memory (STM) and immutability, which may be new to programmers coming from other languages.

  • Overview of functional programming and description of what sets Clojure apart from other languages
  • Detailed explanation of Clojure’s special features
  • Examples of real-world tasks that are well-suited to Clojure’s capabilities, starting with simple tasks and moving on to more complex applications

What you’ll learn

  • What Clojure is—more than just another Lisp
  • How to set up a Clojure environment
  • The structure and syntax of a Clojure program
  • Java interoperability
  • How to use Clojure for real-world tasks
  • Common idioms of Clojure code

Who this book is for

There are two audiences for this book: any technical person desiring to know what Clojure is and why they might want to use it, and any programmer desiring to learn and use the language. The goals of these two audiences mesh nicely, given that Clojure has several new, cutting-edge features that programmers are unlikely to have encountered before.

Table of Contents

Table of Contents

  1. The Clojure Way
  2. The Clojure Environment
  3. Controlling Program Flow
  4. Data in Clojure
  5. Sequences
  6. State Management
  7. Namespaces and Libraries
  8. Metadata
  9. Multimethods and Hierarchies
  10. Java Interoperability
  11. Parallel Programming
  12. Macros and Metaprogramming
  13. Datatypes and Protocols
  14. Performance
Source Code/Downloads

Downloads are available to accompany this book.

Your operating system can likely extract zipped downloads automatically, but you may require software such as WinZip for PC, or StuffIt on a Mac.

Errata

Please Login to submit errata.

On page 18:

There is a space after "!" in the typed input which is not in the returned value.

On page 32:

In the function "square-or-multiply" the second alternative implementation is wrongly indented.

On page 33:

The output of the prompt is not consistent "#'user/sq" versus "'#user/multiply" (ie. the order of "'" and "#").

On page 44:

The application of arg-switch with a custom function seems wrongly indented (ie. the indentation of "(/ a (* b b)))" and "2 3)".

On page 46:

There is an "-" before rangechecker in the text (which also appears in the index).

On page 46:

"#´user/times-pi" => "#'user/times-pi". This occurs in several places in the book, but a search-replace from "#´" to "#'" could solve this.

On page 53-?:
In all of chapter 4 the symbol "->" is used to denote the result returned from an evaluation, but the symbol is only used in this chapter as far as I can tell.

On page 57:
In the description of the Neg? function:
"returns true if it is > 0" should be "returns true if it is < 0"

On page 58-59:

In the section "Regular Expression Functions" there are additional spaces in front of and behind the regular expressions which should not be there. There are in total 3 additional spaces on page 58 and 6 spaces on page 59.

On page 63:

In the subsections "pop" and "list?" the symbol "´" is used instead of "'" to qoute a list.

On page 65 (epub):

The argument to the re-pattern function appears to have a leading space (" [a-zA-Z]"); however, the value does not (#"[a-zA-Z]*").

On page 66 (epub):

The example argument to the re-seq function contains spaces #" [a-z] ". The result of invoking the function is nil.

To obtain the result printed in the text, remove the leading and trailing space characters.

On page 79:

There is missing a trailing parenthesis in "(map square '(1 2 3 4 5)".

On page 83:

(" value1" "value2" "value3") => ("value1" "value2" "value3")

On page 87:

"(take 10 (cycle" => "(take 7 (cycle"

On page 87:
The given output of the code example "user=> (interpose :a [1 2 3 4])" is wrong. Instead of "(1 :a 2 :a 3 :a 4 :a 5)" the correct/actual output is "(1 :a 2 :a 3 :a 4)".

On page 91:

"has fewer than N items" => "has fewer than N+1 items"

On page 94:

"doall, rdentical" => "doall is identical"

On page 102:

The function "print-contacts" is wrongly indented

On page 103:

There is an empty line missing after the function add-all-initials, and there are two implementations of the function "print-contacts-and-initials".

On page 111:
After this statement: "(dosync (alter my-ref - 10) (alter my-ref + 15)),"
"@my-ref" will return 10, not 5.

On page 142:

As far as I can recall the macro "->" has not been introduced.

On page 153:

"sources" => "source" in the call to Java and the ANT configuration XML.

On page 175:
All occurences of
(rand-expr (println "A") (println "B"))
should be
(rand-expr (println "A") (println "B") (println "C"))

On page 176:
The ++ macro definition seems to be incorrect both the 'then' and 'else' expressions of the if statement are inside the test expression, leading to a 'Too few arguments to if' exception when I try to execute the defmacro as defined.

Also the splicing unquote here ~@(first exprs) throws an exception trying to convert an Integer to an ISeq.

I can define the macro with these changes:

(defmacro ++ [& exprs]
(if (>= 2 (count exprs))
`(+ ~@exprs)
`(+ ~(first exprs) (++ ~@(rest exprs)))))

On page 176:
Missing closing paren on condition line and @ character must not be in front of (first exprs):
(defmacro ++ [& exprs]
(if (>= 2 (count exprs)
`(+ ~@exprs)
`(+ ~@(first exprs) (++ ~@(rest exprs)))))

Should be:
(defmacro ++ [& exprs]
(if (>= 2 (count exprs))
`(+ ~@exprs)
`(+ ~(first exprs) (++ ~@(rest exprs)))))

On page 178:

"<author>luke</author>" => "<author>Luke</author>"

On page 180:

Shouldn't the interface also contain the following signature "public Object method_two()" ?

On page 186:
I'm guessing this was reported long ago, but I don't see any erratum online to verify.

Complete example for datatypes and protocol does not work. paycheck defined in protocol does not match what is defined in HourlyEmployee and SalariedEmployee.

(paycheck [emp hrs])
vs
(paycheck [hrs])

I was able to get this to making the function signatures match.

On page 193:
After verifying the expansion of the macro rand-expr-multi, rand-expr is tested multiple times instead of rand-expr-multi.

Perhaps the REPL snippet could be made a little more concise as well, e.g.:

(dotimes [_ 5]
(rand-expr-multi (println "A") (println "B") (println "C")))

Thanks for a great writeup on Clojure's macros!