The errata list is a list of errors and their corrections that were found after the product was released. If the error was corrected in a later version or reprint the date of the correction will be displayed in the column titled "Date Corrected".
The following errata were submitted by our customers and approved as valid errors by the author or editor.
Version |
Location |
Description |
Submitted By |
Date submitted |
Date corrected |
|
ch15?
2nd Paragraph after "Getting Setup with CouchDB and Clutch" |
Clutch project's URL has changed.
https://github.com/clojure-clutch/clutch
Old URL in current safari version redirects to that.
Note from the Author or Editor: Correct.
Change
https://github.com/ashafa/clutch
to
https://github.com/clojure-clutch/clutch
|
Mike Fletcher |
Sep 10, 2012 |
May 14, 2014 |
Printed |
Page 26
4th paragraph |
defprotocol spans a line break (without a hyphen) so that it appears as defproto <nl> col. Ideally it would be clearer that this is all one word.
Note from the Author or Editor: Remove line break or add hyphenation in "proto col"
|
Anonymous |
May 04, 2012 |
May 14, 2014 |
PDF |
Page 37
Mutually recursive functions with letfn |
Executing the code in a REPL works if not modified.
(letfn [(odd? [n]
(even? (dec n)))
(even? [n]
(or (zero? n)
(odd? (dec n))))]
(odd? 2))
(odd? 11))
;= true
If you change the last line to execute something false, it produces a StackOverflowError.
(odd? 2)
(odd? 0)
(even? 1)
All produce the StackOverflowError.
I was analyzing the code to see if I could figure out how it works when it reaches a false condition. I couldn't. So I decided to attempt to execute it to learn. It failed.
Thanks.
Note from the Author or Editor: Good catch, sorry for the error!
Change on page 37, replace this code listing:
(letfn [(odd? [n]
(even? (dec n)))
(even? [n]
(or (zero? n)
(odd? (dec n))))]
(odd? 11))
;= true
with this one:
(letfn [(odd? [n]
(if (zero? n)
false
(even? (dec n))))
(even? [n]
(or (zero? n)
(odd? (dec n))))]
(odd? 11))
;= true
|
Jimmie Houchin |
Jul 02, 2012 |
May 14, 2014 |
Printed |
Page 37-38
bottom of 37, top of 38 |
Both definitions of strange-adder have an extra (extraneous) right paren on the end.
Note from the Author or Editor: Only the *second* `strange-adder` definition has an extraneous right paren, top of page 38.
|
Kenneth Beesley |
Apr 03, 2014 |
May 14, 2014 |
Printed, ePub |
Page 42
pitfall padagraph near the end of the page |
Equivalent expression for condition checking in if special form is wrong. It doesn't work for bolean false (it evaluates to true).
Should be (and (not (nil? x)) (not (false? x)))
Note from the Author or Editor: PDF page 42, last line, change
... which is equivalent to (or (not (nil? x)) (true? x)) ...
to :
... which is equivalent to (and (not (nil? x)) (not (false? x))) ...
|
Marko Mitrovic |
Jan 01, 2013 |
May 14, 2014 |
PDF |
Page 56
end of repl interaction |
(= five (StatefulInteger. 42))
;= true
should read:
(= six (StatefulInteger. 42))
;= true
my full interaction:
$ javac StatefulInteger.java
$ mv StatefulInteger.class ../classes/
user> (import 'StatefulInteger)
StatefulInteger
user> (def five (StatefulInteger. 5))
#'user/five
user> (def six (StatefulInteger. 6))
#'user/six
user> (.intValue five)
5
user> (= five six)
false
user> (.setInt five 6)
nil
user> (= five six)
true
user> (defn print-number
[n]
(println (.intValue n))
(.setInt n 42))
#'user/print-number
user> (print-number six)
6
nil
user> (= five six)
false
user> (= five (StatefulInteger. 42))
false
user> (= six (StatefulInteger. 42))
true
Note from the Author or Editor: Thanks for catching that!
Change on page 56:
`(= five (StatefulInteger. 42))`
to
`(= six (StatefulInteger. 42))`
|
lina mist |
May 15, 2012 |
May 14, 2014 |
Printed |
Page 63
1st paragraph |
(reduce max [0 -3 10 48])
;= 10
should be
(reduce max [0 -3 10 48])
;= 48
|
Anonymous |
May 23, 2012 |
May 14, 2014 |
PDF |
Page 77
footnote 35 |
35. It is a common for the names of functions that...
should read something like:
35. It is a common practice for the names of functions that...
or maybe simply:
35. It is common for the names of functions that...
Note from the Author or Editor: Page 77, footnote 35, change
35. It is a common ...
to
35. It is common ...
|
lina mist |
May 19, 2012 |
May 14, 2014 |
Printed |
Page 108
bottom |
Great book! Thanks for writing it.
On my machine:
((comparator compare-magnitude) 10 10000)
;= -1
((comparator compare-magnitude) 100 10)
;= -1
((comparator compare-magnitude) 10 75)
;= -1
not what is in the book.
AFAICS compare-magnitude is not much of a predicate - it is never logically false - no?
Thanks again.
Note from the Author or Editor: PDF page 108, change this function:
(defn compare-magnitude
[a b]
(- (magnitude a) (magnitude b)))
to:
(defn compare-magnitude
[a b]
(neg? (- (magnitude a) (magnitude b))))
|
Anonymous |
Feb 01, 2013 |
May 14, 2014 |
Printed |
Page 109
United States |
The syntax for *1 has not been previously introduced. I presume that it refers to the result of the last operation.
Note from the Author or Editor: A footnote pointing towards the full explanation of *1 et al. is misplaced.
Change:
Move footnote '4' from page 305 to page 109, with the referring superscripted numeral appended to callout #2 on page 109:
"*1 holds the value of the last expression evaluated in the REPL. See REPL-bound vars on page 399 for details."
|
Alan Thompson |
Mar 15, 2013 |
May 14, 2014 |
PDF |
Page 132
Warning note, 1st paragraph |
"Remember that only vectors and unsorted maps and vectors have..." should be "unsorted maps and sets have..." - author made a typo substituting sets to vectors.
Note from the Author or Editor: PDF page 132, change
Remember that only vectors and unsorted maps and vectors have...
to
Remember that only vectors and unsorted maps and sets have...
|
Artem Oboturov |
Jun 17, 2012 |
May 14, 2014 |
Printed |
Page 145
. |
swapped the order of parameter of type set:
you call :
(neighbours %) #{2 3} #{3 } )
but the set are swapped : the correct order of set are , maybe
(neighbours %) #{3 } #{2 3} )
Note from the Author or Editor: Good catch, Thanks!
Change on page 145:
#{2 3} #{3}
to:
#{3} #{2 3}
|
Anonymous |
Jan 16, 2013 |
May 14, 2014 |
PDF |
Page 149
Last complete function definition on page |
The definition of hex-grid is missing two closing parentheses. The last line should be:
:when w] #{v w}))))
Note from the Author or Editor: Bizarre?thanks for catching that print error!
Change:
Add two closing parentheses to the end of the `hex-grid` function.
|
James Elliott |
May 30, 2012 |
May 14, 2014 |
PDF |
Page 150
Top of page |
The definition of hex-outer-walls is missing two closing parentheses. The last line should be:
:when (not (vertices w))] #{v (vec w)}))))
Note from the Author or Editor: Bizarre?thanks for catching that print error.
Change:
Add two closing parentheses to the end of the `hex-outer-walls` function.
|
James Elliott |
May 30, 2012 |
May 14, 2014 |
PDF, Other Digital Version |
Page 190
(defn character |
(ref (dissoc cdata :validators)
should be:
(ref (dissoc cdata :validator)
The latter working snippet in on github:
https://github.com/clojurebook/ClojureProgramming/blob/master/ch04-concurrency-game/src/com/clojurebook/concurrency/game_validators.clj
Note from the Author or Editor: s/:validators/:validator/g
Thanks!
|
Anonymous |
Apr 30, 2012 |
May 14, 2014 |
PDF |
Page 190
enforce-max-health function |
The function enforce-max-health only accepts one parameter, but in the character function 2 values are being passed to it, so you get an arity error if you try to use the code as written.
The easiest fix is to change the parameters in enforce-max-health from [{:keys [name health]}] to just [name health].
Also, it isn't clear in that function that the health being passed to it is the max-health value when the function is being created as a validator, it just happens to be that max-health is set to the health value at the same time. It does state in point 1 that it returns a function that acceps a char's "potential" new state, but still, It might be clearer to declare the variable in enforce-max-health as "max-health" instead of health.
Note from the Author or Editor: Yup, we caught this as well when preparing the sample code repository (i.e. https://github.com/clojurebook/ClojureProgramming/blob/0913e2edc38b38f2da80d41aa2b28d3861a69947/ch04-concurrency-game/src/com/clojurebook/concurrency/game_validators.clj#L29).
Change on page 190:
[{:keys [name health]}]
[name health]
You're right that the parameter should probably be called `max-health`?we'll see about that in the second edition, etc. Thanks!
|
Mark Fisher |
Feb 03, 2013 |
May 14, 2014 |
PDF |
Page 197
Figure 4-3 |
On page 197, the figure 4-3 displays two 'ref b' timeline. The bottom timeline should be 'ref a'. Figure 4-4 displays this correctly.
Note from the Author or Editor: Update figure 4-3. Change bottom "ref b" to "ref a".
|
Francois Nguyen |
May 15, 2012 |
May 14, 2014 |
PDF |
Page 199
2nd line |
"deferencing" should be "dereferencing"
Note from the Author or Editor: s/deferencing/dereferencing
|
Gianluca Torta |
Apr 16, 2014 |
May 14, 2014 |
PDF |
Page 218
1st code listing |
This code listing begins:
(require '[net.cgrand.enlive-html :as enlive])
(use '[clojure.string :only (lower-case)])
(import '(java.net URL MalformedURLException))
but needs to also include:
(use '[clojure.java.io :only (as-url)])
and
(import '(java.util.concurrent BlockingQueue LinkedBlockingQueue))
or typing in the following code won't work.
Note from the Author or Editor: Good catch! We found this before publishing the sample code repository (https://github.com/clojurebook/ClojureProgramming/blob/master/ch04-concurrency-webcrawler/src/com/clojurebook/concurrency/webcrawler.clj), but the book will change shortly as well.
Changes:
On page 219, in the code listing that starts with `(def url-queue (LinkedBlockingQueue.))`, *prepend* this line:
(import '(java.util.concurrent BlockingQueue LinkedBlockingQueue))
On page 220, in the code listing that starts with `(declare run process handle-results)`, *prepend* this line:
(use '[clojure.java.io :only (as-url)])
|
jcDelta |
Jul 26, 2012 |
May 14, 2014 |
PDF |
Page 240
1st code listing |
the first code listing:
(defmacro while
[test & body]
(list 'loop []
(concat (list 'when test) body)
'(recur)))
should be (or similar):
(defmacro while
[test & body]
(list 'loop []
(concat (list 'when test) body
'((recur)))))
so that "recur" is produced as part of the final "when" form.
Note from the Author or Editor: Good catch, thanks!
Change on page 240, replace this code listing:
(defmacro while
[test & body]
(list 'loop []
(concat (list 'when test) body)
'(recur)))
with this one:
(defmacro while
[test & body]
(list 'loop []
(concat (list 'when test) body
'((recur)))))
|
Petr Novotnik |
Jun 15, 2012 |
May 14, 2014 |
PDF |
Page 263
Second paragraph, last sentence |
You have ?Thankfully the term is depreciative enough?? and I think you meant deprecatory or perhaps deprecative?
Note from the Author or Editor: PDF page 263, change
Thankfully, the term is depreciative enough
to
Thankfully, the term is disparaging enough
|
James Elliott |
Jun 05, 2012 |
May 14, 2014 |
PDF |
Page 281
Several evaluated expression at the beginning of the page |
(def felix (schr?dinger-cat))
;= #'user/felix
@felix
;= :dead
(schr?dinger-cat)
;= #<Schr?dingerCat@3248bc64: :dead>
(schr?dinger-cat)
;= #<Schr?dingerCat@3248bc64: :alive>
Function schr?dinger-cat creates an instance of cat. So it must be different objects. As we can see two succesive calls of function returns one object.
Note from the Author or Editor: Whoops, copy/paste error. :-)
Change:
Replace the second occurrence of "3248bc64" with (e.g.) "b28eed01".
|
Yury |
Aug 27, 2012 |
May 14, 2014 |
PDF, Other Digital Version |
Page 285
lat line |
The last line lacks a '}', that is:
:dims (fn [pt] [2 1]))
should be:
:dims (fn [pt] [2 1])})
Wrong also on: https://github.com/clojurebook/ClojureProgramming/blob/7521bcfb52cdf7e598bca3c4e7860d795a67992c/ch06-datatypes-repl-interactions.clj
Note from the Author or Editor: Page 285, last line, add the missing curly brace. Change:
:dims (fn [pt] [2 1]))
to:
:dims (fn [pt] [2 1])})
|
Roberto Mannai |
May 04, 2012 |
May 14, 2014 |
PDF, Other Digital Version |
Page 356
5th element on the list |
"read-only portions of the appropriate java.io.*" should be "read-only portions of the appropriate java.util.*"
Note from the Author or Editor: Page 356, 5th bullet point, change
read-only portions of the appropriate java.io.*
to
read-only portions of the appropriate java.util.*
|
Roberto Mannai |
May 09, 2012 |
May 14, 2014 |
ePub |
Page 372
Example 9-15 step 3 |
The text is bizarrely formatted, with "?proxy requires two vectors as its first two arguments:? superimposed over later text. Issue is visible in iBooks and in Readium.
Note from the Author or Editor: Looks fine in PDF; O'Reilly staff will need to verify/fix for ePub, as I don't have an ePub reader handy.
|
empiricalthought |
Feb 14, 2013 |
May 14, 2014 |
PDF |
Page 380
the last line in the code example (excluding comment lines) |
On the line
(println "Error!" (.getMessage) @e)))
the .getMessage method is missing the parameter. Should be:
(println "Error!" (.getMessage e) @e)))
Note from the Author or Editor: In the code listing on page 380, change:
(println "Error!" (.getMessage) @e)))
to
(println "Error!" (.getMessage e) @e)))
|
Anonymous |
Nov 11, 2013 |
May 14, 2014 |
PDF |
Page 387
4th paragraph |
The note says "Here, we deref the value of the sample-values var", but in the code (both Java and Clojure) the var is named 'keywords'.
Note from the Author or Editor: Change "sample-values" to "keywords" in callout 4 on page 387.
|
Anonymous |
Nov 12, 2013 |
May 14, 2014 |
Printed |
Page 439
2nd paragraph |
Getting the declared methods for the round function uses (round foo), but should be (class round).
So this:
(seq (.getDeclaredMethods (round foo)))
should be:
(seq (.getDeclaredMethods (class round)))
Note from the Author or Editor: Thank you for the report!
Change:
s/round foo/class round/g
|
Ulrik Sandberg |
Sep 02, 2012 |
May 14, 2014 |
PDF |
Page 439
United States |
the return value in
(defn idem ^long [^long x] x)
;= #'user/long
should be #'user/idem
Note from the Author or Editor: PDF page 439, change
(defn idem ^long [^long x] x)
;= #'user/long
to
(defn idem ^long [^long x] x)
;= #'user/idem
|
art gittleman |
Nov 05, 2012 |
May 14, 2014 |
PDF, Other Digital Version |
Page 460
last paragraph |
The factory function:
(defrecord Chihuahua [weight price]
should not get input parameters:
(defrecord Chihuahua []
otherwise the following code in the text will not work:
(main (Chihuahua.))
(Check also: https://github.com/clojurebook/ClojureProgramming/blob/master/ch12-patterns-repl-interactions.clj#L83)
Note from the Author or Editor: PDF page 460, change
(defrecord Chihuahua [weight price]
to
(defrecord Chihuahua []
|
Roberto Mannai |
May 14, 2012 |
May 14, 2014 |
PDF, Other Digital Version |
Page 466
"require" instruction |
Should be "use", not "require":
(use '[ring.middleware cookies session])
(def my-app (-> my-app
wrap-cookies
wrap-session
wrap-logger))
Note from the Author or Editor: Good catch, thanks!
Change on page 466:
Replace
wrap-cookies
with
ring.middleware.cookies/wrap-cookies
and replace
wrap-session
with
ring.middleware.session/wrap-session
|
Roberto Mannai |
May 15, 2012 |
May 14, 2014 |
PDF |
Page 486
attr function definition |
The argument for attrs function should be attr-map instead of attrs. Accordingly, the line
(->> attrs
should be replaced with
(->> attr-map
Note from the Author or Editor: In the code listing on page 486 (in the middle of the page), change:
[attrs] to [attr-map]
AND
->> attrs
to
->> attr-map
|
Anonymous |
Nov 16, 2013 |
May 14, 2014 |
PDF |
Page 492
United States |
The keys passed as properties to DriverManager.getConnection are :username and :password. According to the jdbc spec they should include :user and :password
It may be that :username works with mysql but it doesn't work with db2
Note from the Author or Editor: PDF page 492, change two occurrences of:
:username "login"
both to:
:user "login"
|
Vincent Thomas |
May 31, 2012 |
May 14, 2014 |
PDF |
Page 541
Code callout 2 (and 1) |
Code reads:
((PUT ["/:id" :id #"\d+"]
[id url]
(list "You requested that " url " be assigned id " id))
{:uri "/590" :params {:url "http://clojurebook.com"} :request-method :put})
;= {:status 200, :headers {"Content-Type" "text/html"},
;= :body "You requested that http://clojurebook.com be assigned id 590"}
You don't get the result in the last line from the function
(list "You requested that " url " be assigned id " id))
You can get it from
(str "You requested that " url " be assigned id " id))
Note from the Author or Editor: In the code listing in the middle of page 541, change:
(list
to
(str
|
Peter West |
Jan 02, 2014 |
May 14, 2014 |
PDF |
Page 564
Example 17-4 |
The plugin slot of defproject:
plugins [[lein-ring "0.6.2"]]
is missin the colon. Should be:
:plugins [[lein-ring "0.6.2"]]
Note from the Author or Editor: In Example 17-4, change:
plugins
to
:plugins
|
Anonymous |
Nov 18, 2013 |
May 14, 2014 |
PDF |
Page 586
First paragraph/code block |
In the third example expression (first complete one on this page):
(run* [x]
(fresh [_]
(conso _ 3 [1 2 3])))
;= ((2 3))
the first 3 should be replaced with an x to get the desired output:
(run* [x]
(fresh [_]
(conso _ x [1 2 3])))
;= ((2 3))
Note from the Author or Editor: Good catch!
Change on page 586:
(run* [x]
(fresh [_]
(conso _ 3 [1 2 3])))
to
(run* [x]
(fresh [_]
(conso _ x [1 2 3])))
|
aminggs |
Apr 17, 2012 |
May 14, 2014 |