By Developers, For Developers

Historical errata for Programming Clojure, Third Edition

PDF PgPaper PgTypeDescriptionFixed onComments
2SUGGEST

There’s a code formatting bug in epub and mobi versions.

It’s like code areas use two column layout and everything is in the second column.

2017-06-22Thanks, we will take a look.
22ERROR

The quote special form is referred to as a function:

“we can use the quote function”

This seems incorrect.

2017-06-22Thanks, will fix.
39TYPO

Possible misspellng of “it’s” as “its”:

“indicating its a Java object”

2017-06-22Thanks, will fix.
59ERROR

The following statement doesn’t seem quite right:

To see a non-true match, try using some with identity to find the first
non-nil value in a sequence:

(some identity [nil false 1 nil 2])
-> 1

The first non-nil value in [nil false 1 nil 2] looks like the second element of the vector in question, not the third one. The third element appears to be the first non-falsy (non-falsey?) value though.

2017-06-22Thanks, will fix.
37TYPO

“The fact that a person object can be serialized to XML has nothing to do with the person and is metadata.”

Should be “its metadata.”

2017-06-22Thanks, will fix.
xiiSUGGEST

“The user before the prompt tells the namespace you are currently working in.”

Would it not read easier if “tells” is swapped out with “indicates”?

2017-06-22Thanks...
229ERROR

"but notice that in the following code the Clojure version has both fewer dots and fewer parentheses than the Java version:

// Java
“hello”.getClass().getProtectionDomain()
; Clojure
(.. “hello” getClass getProtectionDomain)
"
———————————-
Both code snippets have the same number of dots

2017-06-22Thanks, will fix.
71TYPO

The expression, ([:a :b :c] 5), results in the error java.lang.IndexOutOfBoundsException,
not java.lang.ArrayIndexOutOfBoundException.

Using clojure-1.9.0-alpha17

2017-06-22Yep, will fix.
101ERROR

Every code example is pretty much unreadable in ePub and Mobi versions as there are line breaks inside symbols, etc.
As links (to screenshot) are forbidden in errata, heres a code example from page 101 with incorrect line breaks:
; overly-literal port, do not use
(declare replace-symbol replace-symbol-
expression)
(defn replace-symbol [coll oldsym
newsym]
(if (empty? coll)
()
(cons (replace-symbol-expression
(first coll) oldsym newsym)
(replace-symbol
(rest coll) oldsym newsym))))
(defn replace-symbol-expression [symbol-
expr oldsym newsym]
(if (symbol? symbol-expr)
(if (= symbol-expr oldsym)
newsym
symbol-expr)
(replace-symbol symbol-expr oldsym
newsym)))

2017-08-15This seems to be fixed in my local builds now, but will also confirm with the publisher.
116TYPO

“You can use the special s/nilable operation to extend and existing spec:”

-> “to extend an”

2017-08-15
185TYPO

“The so-called fight club in the story had a set of set of rules.”

“set of” duplication.

2017-08-15
127ERROR

Need to add the following `require` to use `stest/instrument`:

(require ’[clojure.spec.test.alpha :as stest])

2017-08-15
39TYPO

(java.util.Random.)
-> #object[java.util.Random 0x133314b “java.util.Random@133314b”]

“The REPL simply prints out the new Random instance indicating it’s a Java object and specifying its String, hash code, and the result of calling its toString() method.”


I’m new to Clojure and haven’t done Java in a number of years, but I’m not quite sure what “specifying its String” means. How is that different than calling its toString() method?

It seems to refer to the part of the output that says “java.util.Random.” Is this maybe supposed to say “specifying its class”?

2017-10-20Yep, that's a typo. Should be class.
66TYPO

“Clojure will automatically obtain a sequence from a collections”

Collections should be singular

2017-10-20
107TYPO

‘transforamtions’ is a typo in the sentence

Removing the intermediate sequences can result in a significant reduction in
memory usage, particularly if the size of the input collection is large or the
number of transforamtions is large.

2017-10-20
80TYPO

obtain a sequence from a collections,
should be
obtain a sequence from a collection,

2017-10-20
92SUGGEST

Can you create links to the rules/guidelines on page 83 in the PDF document?
A link would be useful also on page 93.

And on pages 88 and 89, but there you refer to them guidelines, not rules.

2017-10-20
2511TYPO

In “The third line is the return value fom the println expression”, “fom” should be “from”.

2017-11-27
4834TYPO

Three dots are an ellipsis, not an ellipse. (An ellipse is a squashed circle.)

2017-11-27
5137TYPO

Change “its” to “is therefore” in “The fact that a person object can be serialized to XML has nothing to do with the person and its metadata.”

2017-11-27
5238TYPO

Change “NO_SOURCE_FILE” to “NO_SOURCE_PATH” in “The :file value NO_SOURCE_FILE indicates that the code was entered at the REPL.”

2017-11-27
5440TYPO

In the grammar for “import” on the shaded background, do the square brackets belong there?

2017-11-27
5541TYPO

Change “REPL” to “the REPL” in “This provides a pleasant experience from REPL when exploring.”

2017-11-27
5743TYPO

In the grammar for “loop” on the shaded background, why is there a space between “bindings” and “*”?

Also, just after that, “recursion point” is set in the code font, like “loop” and “recur” in the same sentence, but it’s not code.

2017-11-27
37TYPO

On the section on Metadata, the phrase

“nothing to do with the person and its metadata”

should be

“nothing to do with the person and is metadata”.

2017-11-27
126TYPO

In “The syntax is the same as s/fsdef but omits the function name.”, “s/fsdef” should be “s/fdef”.

2017-11-29
6854TYPO

At the bottom of the page, all three arguments to ‘range’ are optional, so ‘end’ should have a question mark too.

2017-12-13
6955TYPO

In the last example of ‘range’, the ‘->’ that usually precedes the return value is instead mistakenly on the line after it.

2017-12-13
7258TYPO

“You could drop-while to …” should be “You could use drop-while to …”.

2017-12-13
46ERROR

“The index/element pairs of (indexed coll) are bound to the names idx and elt but only when (pred elt) is true.”

How can (pred elt) be evaluated if elt is only bound after (pred elt) evaluates to true?

2017-12-13I think is a case where wording could just be better. The names are bound, the pred is evaluated, and if true, the body is evaluated.
8268TYPO

Add the bracketed “a” to “Write a predicate recently-modified? that checks to see whether [a] File was touched in the last half hour:”

2017-12-13
8874TYPO

Near the bottom of the page, you refer to “the set functions in the clojure namespace”. Shouldn’t that be “the clojure.core namespace”?

2017-12-13
107TYPO

On the final line of the page, ‘transformations’ is misspelled as ‘transforamtions’.

2017-12-31
261TYPO

On the fourth line of the page, ‘function’ is misspelled as ‘functin’ in the sentence “Next, you can handle the update-progress functin using specs …”

2017-12-31
182ERROR

In the def of jaws, the building of a sequence of notes in the text using the construct (Note. pitch 2 duration) fails with the error:
“Error refreshing environment: java.lang.IllegalArgumentException: Unable to resolve classname: Note”

The tests pass when I use (->Note pitch 2 duration) .

172SUGGEST

On your code starting below “Now let’s put it all together.”

To keep your code consistent with your previous, hard-coded make-reader and make-writer functions given on page 168, you should add the String type - and related functions - to your call to the extend-protocol macro (listing beginning on page 172)

215ERROR

These observations may be due to the way I am testing examples as they appear in the text. Maybe more explanation is required to introduce the concepts to a reader.

My tests are located as shown by this example, src/examples/multimethods/account.clj functions/methods are tested in test/examples/multimethods/test/account.clj. In the latter I (:require [examples.multimethods.account :refer :all]) as part of the (ns examples.multimethods.test.account) setup.

My first observation is that (alias ’acc …) does not come through on :refer :all when I am testing. I had to put the same exact alias in my test namespace.

The second problem I encountered was testing the multimethod account-level:
(>= (:balance acct) …) fails with a NullPointerException when I ran the tests. I got the tests to pass by changing this expression to (>= ::balance acct) …). When would the original expression ever work when the account is set up with ::balance?

215ERROR

On my previous submission for this page, about changing :balance to ::balance, I realize that the error is probably when you created test-savings and test-checking. I think you didn’t want/need ::balance there in your def’s, but should have had just :balance, like :id.

All the problems I reported disappear if I just use :balance, except my observation on (alias…)

132ERROR

The function big is missing the argument: x

(defn big? [ ] (> x 100))

54TYPO

The results of the following two functions need to be swapped.
(first {:fname “Aaron” :lname “Bedra})
-> ([:lname ”Bedra“])
The result should be
-> ([:fname ”Aaron"])

(rest {:fname “Aaron” :lname “Bedra”})
-> [:fname “Aaron”]
The result should be
-> ([:lname “Bedra”])

47SUGGEST

The function:
(defn index-filter [pred coll]
(when pred
(for [[idx elt] (indexed coll) :when (pred elt)] idx)))

Could just be:
(defn index-filter [pred coll]
(for [[idx elt] (indexed coll) :when (pred elt)] idx))

I ran both and both yielded the same results.

26TYPO

The docstring for function ‘greeting’ says it returns ‘Hello, username.’ including full stop, so the body should really be `(str “Hello, ” username “.”))`

9783ERROR

Link to “Understanding Clojure’s PersistentVector Implementation” by Karl Krukow doesn’t work.

251ERROR

Top of page 251 defines:

(defn game [word player] ….)

On later pages though the function is invoked as [player word], first on page 254:

(game random-player “hello”)

This causes an error when count is invoked on a Player instead of a word (String): UnsupportedOperationException count not supported on this type: core$reify

111ERROR

reduce would be used to compute a single value, while into could be used to create a collection for output, not opposite as written in the book

59TYPO

“filter takes a predicate and a collection and returns a sequence of objects for which the predicate returns true.”

Possibly, changing “objects” to “the items” makes sense to make clear that Clojure is not object-oriented. But that might be nit-picking. :)

4747ERROR

I believe the “error” claimed in errata #83099 is mistaken.

The second version introduced by the submitter will handle a nil pred differently. The PDF/book version handles a nil pred correctly, whereas the submitters version gives a null pointer exception and returns a different result (null rather than nil).

9783SUGGEST

The broken link mentioned in errata #83473 looks to be a typo in setting up the tinyurl.

The tinyurl given in the PDF/book (…//tinyurl.com/clojure-persistent-vector) resolves to the broken link:
…//blog.higher-order.net/2009/02/01/understanding-clojures-persistentvector-implementation/
whereas the same link without the trailing slash does work:
…//blog.higher-order.net/2009/02/01/understanding-clojures-persistentvector-implementation
(I removed the http: at the beginning to get past the spam prevention disallowing hyperlinks)

132ERROR

Missing x in function definition

what I can see:
(defn big? [ ] (> x 100))

what think should be there:
(defn big? [x] (> x 100))

171ERROR

The definterface example does not compile:
CompilerException java.lang.IllegalArgumentException: Interface methods must not contain ‘-’

175TYPO

make-writer implementation for URL should wrap path into FileOutputStream instead of FileInputStream

(-> dst .getPath FileOutputStream.)

131ERROR

When trying to use the following line I encounter an error: `(s/def ::bowling/roll #{0 1 2 3 4 5 6 7 8 9 10})`. This issue seems to be a known one: clojure.atlassian.net/browse/CLJ-2490.

Here is the text of the error:
```
Syntax error reading source at (REPL:3:49).
Unmatched delimiter: )
```

243TYPO

There is a missing space that breaks compilation. Printed (aset arr2 “fill”) should be (aset arr 2 “fill”)

81SUGGEST

On top of the page below the title ‘Everything Is a Sequence’ is the text:

You can get the first item in a sequence:
- (first aseq)
first returns nil if its argument is empty or nil.

Suggestion:
Actually, first also returns nil if the first element in the sequence is nil.

146TYPO

(defn big? [ ] (> x 100)) example misses x argument.

242TYPO

tinyurl.com/checked-exceptions-mistake link leads to non-existing radio.weblogs.com/0122027/stories/2003/04/01/JavasCheckedExceptionsWereAMistake.html instead of
radio-weblogs.com/0122027/stories/2003/04/01/JavasCheckedExceptionsWereAMistake.html.

15SUGGEST

In the section on “Navigating Clojure Libraries”, we are instructed to test that we can load the sample code for this chapter with "(require ‘examples.introduction)". This failed for me the first time I tried, because I hadn’t yet downloaded the code. Earlier in the section, the book states that require looks on the ’classpath’, but there are no directions on where the classpath is, how to find it, or how I can add something to it. I went back to the earlier section on Downloading the Sample Code, which told me where I can find the code, but not what to do so that require can find it. I found an erratum from the same section for an older edition of the book that mentions lein, but I couldn’t find any references to lein at all in this edition of the book. I can probably Google it, but this is too much friction for a ‘Quick Start’. Can you add more explicit instructions for getting the sample code visible to clj?

15SUGGEST

For anyone on a Mac who gets stuck at the same place I did, it was a simple fix. There was a .clojure directory in my home directory. Inside .clojure is a deps.edn file. There was a line with :paths [“src”] commented out. I uncommented this line. I then copied the entire src directory (not just the contents, but the directory itself) from the downloaded source code and restarted clj. Then things worked described in the book.

Categories: