By Developers, For Developers

Historical errata for Clojure Applied

PDF PgPaper PgTypeDescriptionFixed onComments
30ERROR

The code listing for import-data-fast has has the conditions inverted.
The easiest fix is to change (if …) to (if-not …)

See: https gist.github.com/christianromney/6e522a174e536714b09c

2015-04-09
12TYPO

Defult Entities -> Default Entities

2015-04-09
22ERROR

In the example of extending protocols to protocols dynamically at runtime, the assert statement is missing the boolean (false) trigger condition.

(assert (str “Unhandled entity: ” entity)) should be
(assert false (str “Unhandled entity: ” entity))

2015-04-09
23SUGGEST

The last sentence of the first paragraph of the section entitled “Choosing the Right Collection” reads:

“We expect that you are already familiar with the basics of the four primary Clojure collections—lists, vector, sets, and maps.”

Vector ought to agree in number with the other items in the sequence and therefore requires pluralization.

2015-04-09
24TYPO

In the last sentence of the first paragraph under “Sequential Collections”, the contraction “it’s” should be changed to the possessive pronoun “its”.

2015-04-09
25SUGGEST

The segue sentence immediately preceding the section on Sorted Collections reads: “Instead we need the ability to create sorted sets and maps.”

I don’t know if “Instead” is the proper formulation. Perhaps something like:

“Sometimes, however, we need …”

2015-04-09
32TYPO

The last sentence of the second paragraph following the code example contains a typo: “bull import”

s/bull/bulk/

2015-04-10
39TYPO

Tiny typo in the output of the code at the top of the page. The previous page had:

(def p (->Pair :a :b)
(seq p)

and the output is shown as (:a :B) ;; note the capital :B. Obviously, it should be (:a :b).
Cheers.

2015-04-10
35TYPO

(defn contains-val?…)
(contains-vals? units #{:oz})

the call should be (contains-val? units #{:oz}) val?, not vals?

2015-04-10
30ERROR

Polarity of the if statement in catalog-import/src/catalog_import/core.clj is reversed. As written, it will immediately return an empty persistent vector if the input data is non-empty.

2015-04-10
viiTYPO

Middle of 3rd paragraph of Introduction, missing apostrophe in “trapping your opponents king”.

2015-04-13
30TYPO

In the last paragraph before the “Updating Maps” heading, the first sentence says “Elements inside lists and vectors are typically not updated, instead sequential
collection largely just add and remove elements at the collection’s insertion point.” Should be plural: “sequential collections largely add…” Also I suspect the “instead” should begin a new sentence.

2015-04-13
33SUGGEST

In the ‘Indexed Access’ section, Records can be treated as indexed collections to an extent. They can’t be used in the functional position. Perhaps this can be clarified as follows:

‘Records that we saw while modeling our domain also implement the map interfaces and can be treated, to an extent, as indexed collections as well.’

‘Second, by invoking the collection itself with a key, though this method is not supported by Records.’

2015-04-16
33SUGGEST

The first paragraph under “Indexed Access” says “Maps and vectors are the two indexed collections,” and then goes on to describe vectors and records, but not maps. Also, the description of vectors seems a bit unclear. Perhaps this could be reworded to something like “Vectors use a zero-based positional index, while maps are indexed by arbitrary keys, typically keywords. Records, which we saw while modeling our domain, also implement the map interfaces…” etc.

2015-04-16
35TYPO

Bottom of page, “If you’re willing to get your hands dirty with Java, the Clojure collections also
implement the Java collection interfaces, including java.util.Collection and
it’s contains() method” — should be “its contains() method”.

2015-04-13
43ERROR

The the code example defines the semi-major-axis function as two divided by the sum of the aphelion and perihelion. It should be the sum divided by 2, not 2 divided by the sum.

2015-04-14
54ERROR

The direction of the relationships depicted in the class diagram should be reversed. For example, the Cart ‘knows about’ Customer and LineItem, not vice versa.

Also, in the diagram, the space in the ‘Line Item’ class name should be removed.

2015-07-04
51TYPO

s/retrive/retrieve/

Last sentence on the page begins:

“To retrive the smallest N planets…”

should be

“To retrieve the smallest N planets…”

2015-04-14
67ERROR

The code listing for shipping/src/shopping/single.clj should return cart when it’s finished, rather than the empty items seq. (“… One thread (person) follows a list and returns a cart full of delicious junk food. …”)

2015-04-14
102ERROR

(def score (map (hash-map :words %1
:happy (happy %1)
:sad (sad %1))))

is missing a # before (hash-map

2015-04-14
39ERROR

On pages 39 & 40 should the (if (seq items) ….) statements be (if (not (seq items)) …)

2015-04-14
56ERROR

The order of arguments is reverse:
{:dept (get-in [:catalog-item :dept] line-item)
should be
{:dept (get-in line-item [:catalog-item :dept])

2015-04-14
61TYPO

A double ‘in’
“Occasionally, you ll need to model the changes in
the application s world, to track changes in in data. Specifically, you want to
hold onto a reference to a set of data that changes.”

2015-04-15
66SUGGEST

The first two sentences in the last paragraph before the section entitled “Managed Updates with Atom” read, “A var stores mutable data in local memory and is not managed. Atoms manage synchronous transformation to their stored value but do not coordinate these changes.”

It is a little unclear to the reader (this one, anyway) precisely what is meant by the verb “to manage.” What does it mean, specifically, that a var isn’t managed? What guarantees does it provide and why would I want to use one?

2015-05-18
67ERROR

The implementation of go-shopping-naive has a bug in the alternative clause of the conditional. This code works:

(defn go-shopping-naive
“Returns a list of items purchased”
[shopping-list]
(loop [[item & items] shopping-list
cart #{}]
(if (seq items)
(recur items (conj cart item))
(conj cart item))))

2015-04-15
66SUGGEST

The penultimate sentence before the section “Managed Updates with Atom” reads, “In this section, we’ll provide an overview of atoms,
refs, and var, with examples to demonstrate their use.”

“Var” should become “vars” to agree in number with atoms and refs.

2015-04-16
67SUGGEST

The last sentence of the first paragraph under “Building a Store API” reads, “One way we might choose is with an Atom.”

IMHO, this might read a tiny bit bit better, “One way to model this is with an Atom.”

2015-04-16
49TYPO

Missing right paren after “(filter planet?” in the thread-last version of the total-moons function in the middle of the page.

2015-04-16
53TYPO

In the code defining the CatalogItem and Customer defrecords, the first field name in the list is in a colored font, like the defrecord keyword, and the rest are black. The other two defrecords list all the field names in black.

2015-07-04This is an artifact of the code formatter---name is a keyword in Clojure, and the formatter is picking up on it. In this context, it is scoped. The function 'name' won't be applied. Will think on how to resolve without losing clarity.
70SUGGEST

From the first paragraph of the section entitled “Watching Inventory”:

“Knowing what to restock could be kept in a master list or a config file and refresh periodically, but that may involve worrying about scheduling.”

s/refresh/refreshed/

2015-04-16refresh is the verb here, no change made
27TYPO

The first sentence on page 27 spells “problem” as “probem”.

2015-04-16
66SUGGEST

Near the bottom of the page:

‘A ref stores application state in the ref world using STM’.

STM provides the mechanism through which safe, shared access of Ref values occurs. Perhaps this can be clarified with the following modification:

‘Refs provide controlled transformation of their stored values through STM.’

2015-05-18
30TYPO

“million catalog items catalog items”

2015-04-16
45ERROR

From forums: “In page 45-46, the orbital-period-transformation function takes a star argument, but when it’s used in the orbital-periods functions, there’s no mention of a star object. How is star passed?”

2015-06-29Yep, this was an incomplete rewrite, updated.
20ERROR

Reported in Google Group: “There seems to be a small error in the Value Based Dispatch section on page 8, where the comments don’t match the code. oz and lb seem to be flipped!”

2015-05-18
135SUGGEST

I would strongly recommend replacing “vanity” (excessive pride in or admiration of one’s own appearance or achievements) with “pride” (a feeling or deep pleasure or satisfaction derived from one’s own achievements).

2015-06-02
29ERROR

Change “and pop to remove all but the first order” to “and pop to remove the first order”

2015-04-18
39TYPO

In the output for the seq example for the Pair collection, :B should be :b.

2015-04-18
107OK

Code needs refer all or async alias should be used

2015-06-02The `require` is set up clearly in the first async example, with an alias and referrals for the appropriate functions. Including header information in subsequent examples creates too much visual clutter without meaningful content. \n \nThank you!
29ERROR

I believe the code example should use if-not rather than if, or the if/else case should be swapped.

2015-04-20
32TYPO

The code examples speak of `map-vals` but the text says `map-values` a couple of places.

2015-04-20
102ERROR

The definition of score omits the # reader-sugar needed to make an anonymous function:

;; RuntimeException Unable to resolve symbol: %1 in this context
(def score (map (hash-map :words %1
:happy (happy %1)
:sad (sad %1))))

;; fixed version:
(def score (map #(hash-map :words %1
:happy (happy %1)
:sad (sad %1))))

2015-04-20
126ERROR

(seq p) should return (:a :b). The “b” shouldn’t be capitalized.

2015-04-23
52TYPO

“These can be removed wtih distinct…” , with is misspelled

2015-04-27
70TYPO

In the ‘shopping/store.clj’ code sample, line 1. I think you meant ‘declare’, not ‘define’.

2015-05-18
70SUGGEST

shopping/store.clj code sample, line 6:
I find local vars that shadow builtins like ‘key’ to be confusing.

2015-07-04
76SUGGEST

in the fn ‘go-shopping’ you use (not (empty? coll)), which is discouraged. Also, I would go with (if (empty? coll) …), so the more complex code is in the ‘else’ branch.

2015-07-04
9TYPO

4th paragraph, 2nd sentence, after the comma: missing a “to”.

… but most people don’t seem [TO] notice since …

2015-05-01
79ERROR

The go-shopping-naive function will neglect to put the last item in the shopping list into the cart. Suggestion:

(if item …

rather than

(if (seq items) …

2015-07-04
80SUGGEST

As written the code won’t work (at least for Clojure 1.6) as the
inventory is initially empty, and stock throws a NullPointerException
when stocking unseen items.

Suggested improvement:

#+begin_src clj
(defn stock
“stock an item on shelves”
[item]
(swap! inventory update-in [item] (fnil inc 0)))
#+end_src

2015-07-04
69ERROR

(:bacon @shopping/store)

should be (I think):

(:bacon @inventory)

2015-05-18
72OK

The dawdle function uses maybe? which is never defined, I think.
Something like this, perhaps?

#+begin_src clj
(defn maybe?
“invokes f 30% of the time”
[f]
(when (> 3 (rand-int 10))
(f)))
#+end_src

2015-06-02This is defined in the code, however didn't make it into the text. It is almost exactly as you describe: \n \n(defn maybe? [f] (if (= 0 (rand-int 3)) (f)))
75ERROR

The buy-candy function uses a add-item-to-cart function that is
not shown.

Could it perhaps be repcaled with conj?

2015-05-18
75ERROR

The report method is used before it is defined.

I believe the function for attaching a validator to the shopping cart is incorrect.
There’s several issues (I believe):

1. The keyword to attach the validator fn is :validator, not validator-fn.
2. The validator should be attached as an option to ref, not a wrapper around it.
3. An anonymous function is used, but % is never injected at the right place.
4. There’s a superfluous set of brackets around the anonymous function.

Suggested replacement:

#+begin_src clj
(def shopping-cart (ref #{}
:validator #(not (contains? % :candy))))
#+end_src

2015-05-18Wow. Nice catches. That was pretty terrible. Thanks!
8ERROR

The “money” symbol in the ns macro is quoted.

2015-05-18
12ERROR

(ns ’money) ; there is a quote on the “money” symbol

2015-05-18
18-19ERROR

In both the multimethod and extend-protocol for Recipe, don’t you need to pass the `store’ argument into the mapping across recipe ingredients? Something like:

(map #(cost % store) (:ingredients recipe))

2015-06-29Yep, fixed.
20SUGGEST

The unit conversion is a bit hard to follow due to choice of argument name. For example, in the lb to oz method, the 16 carries the unit oz/lb and in my mind would most naturally be multiplied by an argument named lb (instead of oz) since “oz = lb * 16oz/lb”. Similarly for the oz to lb method. Suggest swapping the variable names.

2015-05-18
12SUGGEST

Text and example code in this section uses :USD but code shown
previously uses :usd, which gives two different “currencies” that
only differ in case. It might be best to be consistent here.

2015-05-18
121ERROR

The start-knowledge-engine function uses a go-loop without []. I believe it should say rather than (go-loop (let …

2015-06-02
143TYPO

‘yiields’ should be yields

2015-05-11
117SUGGEST

simple-map is a function defined to show a simplified version of clojure.core/map functionality.

clojure.core/map will return an empty seq if the given collection is nil, or empty.

The simple-map function in the book will return nil if (seq coll) is nil - meaning the collection is nil or empty.

I think that it may be misleading for simple-map to be defined in a way where it would return a nil value for nil/empty collections when the real clojure.core/map always returns a seq.

This is a subtle point, but I think it is potentially confusing.

2015-06-29I do not think this difference is relevant to the point of the example, so I'm not planning to make the suggested change. \n \nThere is much more to say about the nature of sequences and sequence functions (see http://insideclojure.org/2015/01/02/sequences/ for some previous writing on the subject). My best description of sequence function signatures like map is that they take and return "seqables" and this version of the function does conform to that description.
39TYPO

In the diagram of interface relationships, the Associative box has “counted?” instead of “associative?” as its predicate.

2015-06-29Yep, fixed.
153TYPO

Change .: into : at the end of this paragraph:

> […] check this property for positive integers by replacing gen/int with gen/pos-int.:

2015-06-29Yep, fixed.
161TYPO

maps #{} should be maps {} in this bulletpoint:

#+begin_src text
collections: edn allows lists (), sets #{}, maps #{} and vectors []. The rules are identical to Clojure’s.
#+end_src

2015-06-29Yep, fixed.
198TYPO

my-web-app.war.dedeploy should be my-web-app.war.dodeploy.

2015-06-29Yep, fixed.
128ERROR

In the start lifecycle should probably be: (reset! (:status component) :running).

2015-06-29Yep, fixed.
76ERROR

```
(defn assignment [child]
(get-in @assignments child))
```

should be using `get` rather than `get-in` as the latter
expects a seq and throws an error otherwise:

```
(defn assignment [child]
(get @assignments child))
```

2015-07-04
78SUGGEST

The second call to `report` in `go-shopping` is (presumably) meant to go after the kids are finished shopping, but executes immediately because the go-loop doesn’t block. I suggest wrapping the `(println “done shopping”)` in a `do` block and move the second `report` there. Something like this:

```
(defn go-shopping []
(init)
(report)
(let [kids (chan 10)]
(doseq [k my-kids]
(>!! kids k))

(go-loop [kid (<! kids)]
(if (not (empty? @shopping-list))
(do (go
(send-child-for-item kid (assign-item-to-child kid) kids))
(recur (<! kids)))
(do (println “done shopping.”)
(report))))))
```

(This also adds initialisation of the “kids” queue that is nowhere else seen.)

2015-07-04
196TYPO

java -jar target/p-service-0.0.1-SNAPSHOT-standalone.jar

should probably be:

java -jar target/my-service-0.0.3-SNAPSHOT-standalone.jar

(Changing p-service to my-service and version 0.0.1 to 0.0.3.)

2015-06-29Yep, fixed.
47SUGGEST

If it would not bloat the page count too much, it would be nice (for me) to have code blocks present on the same page (not split by page breaks).

2015-06-29The book has not yet been through the final typesetting process where this will be addressed.
9TYPO

(defn $ [m n] (->Money ( n (:amount m) (:currency m))))

should be

(defn $ [m n] (->Money ( n (:amount m)) (:currency m)))

2015-08-06fixed
9TYPO

If more than three arguments are passed to make-money, they are ignored in this implementation.

Sould be:

If more than two arguments are passed to make-money, they are ignored in this implementation.

2015-08-06Fixed.
72ERROR

go-shopping now returns a vector but go-shopping-naive (p69) returned a set.

2015-08-09
73TYPO

:when (not= (key ov) (key nv))] kw)]

Are you shure this fragment compares the values associated to the same key in the maps ov and nv?

I’m not very used to watches but this code seems very strange to me (but I can be wrong).

2015-08-06the 'key' in question should be 'kw'. this is an artifact of an earlier edit when we were eliminating shadowing symbols.
55TYPO

(require ’[money :refer [make-money +$ *$])

should be

(require ’[money :refer [make-money +$ *$]])

2015-08-06fixed
98TYPO

In the following figure we will look at the results where the number of products (N) is 32, 128, 512, and 2048. Since the default partition size is 512, when N >= 512, the fold will not actually be parallel

I think it should be N <= 512

2015-08-06fixed
128ERROR

(start [component]
(reset! component :running)
(process-messages status msg-chan)
(handle-responses status response-chan)
component)

The reset! should be:

reset! (:status component) :running)

2015-08-06fixed
593TYPO

Section “Be Precise” in chapter “Appendix 2: Thinking in Clojure”

“Functions effect a single transformation.”
Should be
“Functions affect a single transformation.”

“effect” is misused, it should be “affect” - with an “a”.

2015-08-06No change, effect is proper usage.
79TYPO

[…] If the go-loop and strange alien alphabet pieces (<!, >>!) look unfamiliar, […]

Dunno about async “>>!”.
Maybe try “>!!”?
Code example seems correct, though.
Thankies!

2015-08-06fixed
133TYPO

The :user and :dev profiles are well-known and on by default in Leiningen,

Dunno any “:user” lein profile, maybe try ":prod?
Thankies!

2015-08-06:user is a thing - see https://github.com/technomancy/leiningen/blob/stable/doc/PROFILES.md \n \nNo change made.
171TYPO

Joe lost his analyst role

2015-08-06fixed
26TYPO

In the code…

(defn make-money
([] (make-money 0))
([amount] (make-money amount :usd))
([amount currency] (->Money amount currency)))

([amount] (make-money amount :usd)) should be ([amount] (make-money amount (:usd currencies)))
OR
([amount currency] (Money amount currency))) should be ([amount currency] (>Money amount (currency currencies))))

As it is now, the make-money function doesn’t pass a Currency record to the Money constructor.

2016-04-21We went through a few iterations of the money code. Must've missed that one. We'll get to it in the next printing. Thanks.
55ERROR

#LineItem{:quantity 3,
:catalog-item #CatalogItem{:number 664,
:dept :clothing,
:desc “polo shirt L”,
:amount 2515
:currency :usd},

Catalog item has a reference to Money and not direct reference to amount and currency. It ought to be

#LineItem{:quantity 3,
:catalog-item #CatalogItem{:number 664,
:dept :clothing,
:desc “polo shirt L”,
:price #Money{:amount 2515
:currency :usd}},

2016-04-21Agreed.
228TYPO

p 228 epub version: superfluous use of “and”

(​defn​ in-stock?
​“check if an item is in stock”​
[item]
(​let​ [cnt (item @inventory)]
(​and​ (​pos?​ cnt))))

2016-04-21Looks like we pruned something and left the and. Will fix in next printing. Thanks.
7SUGGEST

“When defining constructors with optional arguments, you can use destruc- turing1 for clarity [example] This allows any number of optional arguments, binding f3 and f4 based on their position.”

This text describes pulling out f3 and f4 specifically with array destructuring.

“You can use this technique to define a constructor function that takes zero or more fields, prioritized by dependency. Let’s look at a snippet…”

But the snippet does not actually use array destructuring similar to the example in the beginning of the section.

2016-04-21Thanks! We'll get this fixed in the next printing.
70ERROR

In the following code,

(defn init
“set up store with inventory”
[items]
(set-validator! inventory no-negative-values?)
(swap! inventory items))

`reset!` should be used instead of `swap!`. As it stands the inventory atom gets set to nil.

2016-04-21
4831SUGGEST

#(conj %1 %2) is redundant, should just be `conj`

Same thing on the following page

2016-04-21
123SUGGEST

```
(go-loop [request (<! ch-in)
response (fire-rules ke request)]
(>! ch-out response)
(when @active (recur))
```

Won’t this block forever waiting for input, even if `active` is set to false? IOW, "
The stop-knowledge-engine function sets the active flag to false, allowing the go block to stop looping. " is slightly misleading, especially since “the owner of the incoming channel should be closing that channel when that component is stopped.”

If the component really wants to be in control of the `go-loop`, it should set up a separate channel and read from both `ch-in` and this channel with an `alts!` call.

2016-04-21
153TYPO

“And finally, the shopping-list function takes a recipe and builds a shopping list, combining ingredients if necessary.”

There is no “shopping-list” function in the code above this description.

2016-04-21
9ERROR

(make-money) doesn’t return a money record with a Currency, but with a keyword. So:

#user.Money{:amount 0, :currency :usd}

instead of the expected:

#money.Money{:amount 1, :currency #money.Currency{:divisor 100,
:sym “USD”,

2016-04-21Thanks for letting us know. This will be straightened out in the next printing.
9ERROR

In your definition of the function make-money, the one-parameter form of the function passes in the keyword symbol :usd as the default currency value, instead of a Currency object, to three-parameter form of the function, which in turn passes it to the factory function ->Money.

But this seems to be inconsistent with the definition of the record Money, which has a type hint indicating that the parameter currency should be a Currency object.

As a result, if you run the sample code, (make-money) and (make-money 1) do not return the results you show, but instead return a “Money” object with a keyword :usd instead of the USD Currency object.

Basically, there’s a type error. This is paper page 9 of the book, in the book’s first code sample, from money.clj. Or maybe I’m misunderstanding something?

2016-04-21Thanks for letting us know. This will be straightened out in the next printing.
53ERROR

In the first code example in the section ‘Sorting and Duplicate Removal’, we have done erroneous extra parens.

(take 5 (sort (map (:name planets))))

Should be

(take 5 (sort (map :name planets)))

2016-04-21
9ERROR

(defn make-money
([] (make-money 0))
([amount] (make-money amount :usd))
([amount currency] (->Money amount currency)))

This supplies `:usd` as currency while probably the intent was to supply `(:usd currencies)` as currency for the to be created money record.

[Note from Alex: this errata is a duplicate from errata #78780, so closing. Thanks!]

2015-10-09
15TYPO

For example, a Recipe might have multiple authors. In this case, we may not want to rely on nesting at instead refer to an entity by a well-known identifier.

Should be:

… rely on nesting and instead refer to an entity…

2016-04-21Good catch, thanks! This'll be fixed in the next printing.
10388TYPO

“Now we’ll the fire…” should be “Now we’ll fire the…”.

2016-04-21
69SUGGEST

In the last paragraph the sentence does not refer to the previous code example while sounding as if it makes a reference to the problem described by the code example:

“The transducer forms will use reduced to signal early termination and also avoid realizing results beyond the requested ranges.”

I found this a bit confusing, it seemed to suggest that the functions in the code example are transducers while they’re not.

2016-04-21
166ERROR

In the second paragraph the text says that the string generated does not include a time offset. In fact it does, ‘Z’ represents UTC (offset 00:00).

2016-04-21
17TYPO

lack of closing bracket in code example

(ns ch1.validate
(:require [schema.core :as s])

2016-04-21Thanks! This'll be fixed in the next printing.
51TYPO

doublicated “are”
“value are are referred”

2016-04-21
102TYPO

“In core.async, we call these processes go blocks (in a nod to similar concepts
in the Go language). Inside go blocks we use channels, though the put and
take operations are <! and >!.”

Isn’t the put operation >! and take <! in go blocks? This is the case when using threads (viz. put is >!!) and the go-block example claims take is <!
….
(when-some [val (<! c)]

2016-04-21That could be clearer. Thank you.
154TYPO

The example of running quick-check to test the `identity-conversion-prop` is a duplicate of the example of the `conversion-order-prop` test.

cljapplied/src/ch8/check.clj
(def identity-conversion-prop
(prop/for-all [u gen-unit
n gen/s-pos-int]
(= n (convert u u n))))

The identity-conversion-prop is a test-check property that says for all units u and
positive integers n, converting to the same u must return n.
We can run quick-check to verify that this property holds:

cljapplied/src/ch8/check.clj
(def conversion-order-prop
(prop/for-all [u1 gen-unit
u2 gen-unit
u3 gen-unit
u4 gen-unit
n gen/s-pos-int]
Prepared exclusively for Alan Powell
report erratum • discuss
Property-Based Tests with test.check
• 155
(= (->> n (convert u1 u2) (convert u2 u3) (convert u3 u4))
(->> n (convert u1 u3) (convert u3 u2) (convert u2 u4)))))
=> (tc/quick-check 100 identity-conversion-prop)
{:result true, :num-tests 100, :seed 1424055070008}

2016-04-21
119ERROR

The description of solo-mode in the second to last paragraph makes it sound like :mute and :pause affect the channels which are soloed. Setting solo-mode on a mix determines the handling of messages on the non-soloed channels: whether they’re consumed or held.

Looking at the source for mix, it appears that mix defaults to a solo-mode of :mute. That might be worth mentioning.

2016-04-21Excellent. We'll make this clear in the next printing.
72ERROR

The function shop-for-item has the docstring in the wrong position, it’s defined as

(defn shop-for-item [cart item]
“docstring”
)

So the docstring is just discarded..

2016-04-21Thank you, you're quite correct.
146TYPO

paragraph 3, line 5: “text execution” -> “test execution”

2016-04-21
59ERROR

in (defn revenue-by-department …), the function (reduce-kv …) requires 3 arguments. The initial value {} is missing.

2016-04-21Thanks!
51TYPO

I think that on this phrase the word are is duplicated.

> We’ve defined a planet? helper function that tests whether an entity is a Planet. In Clojure, functions that return a truthy value are are referred to as predi- cates. They’re often given names that end with ?. Typically most domains you define will have a number of helper predicates.

2016-04-21Nice. Thanks.
50ERROR

The find-planet function is wrong in saying there is no useful initial value. In fact, nil is a very useful initial value, otherwise the first planet is used as the initial reduction value (and so its name is never checked). Consider:

user=> (find-planet [{:name “Earth”}] “Mars”)
{:name “Earth”}
user=> (find-planet [{:name “Earth”} {:name “Mars”}] “Earth”)
nil

2016-04-21
82SUGGEST

This sentence does not make sense to me:
“You
should be as follows along your application’s development path”
Also the previous- and the next sentence are confusing me.

2016-04-21
76SUGGEST

The first thing I noticed was that in the init function when shopping-list is created the keyword :butter is included, which is not in the store. This made me then comb through more carefully to realize that :candy is the only thing that is actually retrieved from the store in the rest of the family_async.clj example code. send-child-for-item, assign-item-to-child, collect-assignment. None of these use the store, which I think was one of the things that may have been intended.

2016-04-21...right. Okay. Thank you, and we'll get this knocked out by the next printing.
123ERROR

There is a code snippet on this page:

(defn start-knowledge-engine
[{:keys (ch-in ch-out rules active) :as ke}]
(go-loop [request (<! ch-in)
response (fire-rules ke request)]
(>! ch-out response)
(when @active (recur))))

This will not actually run because of the missing arguments to occur. Verified with core.async 0.2.374 / clojure 1.8

2016-04-21
163ERROR

The code example

(binding [data-readers {’my/card #’cards/card-reader}] (read-string “#my/card \\”2c\\“”))

is presented as a way to dynamically bind a new data-reader. However, the text does not mention this only works for the clojure.core read-string and not the clojure.edn read-string.

Given the dire warnings on page 160 (PDF edition) of the (unintended) consequences of using clojure.core read-string this is very confusing.

2018-06-10Thank you. Quite correct. The way to handle this is to pass in the reader map as the :readers option to edn/read-string: \n \n (edn/read-string {:readers {'my/card #'cards/card-reader}} "#my/card \\"2h\\"") \n \nor more generically: \n \n(edn/read-string {:readers *data-readers* "#my/card \\"2h\\"") \n \nFixed in second printing. \n
12ERROR

with-open is used on a BufferedImage, which results in an exception (close field not found) when calling make-planet-image.

2018-06-10Thank you. Fixed in second printing.
11TYPO

In the second (def) (for “apollo-11”), the “true” value is combined on the same line as the launched date. In the previous example (“apollo-4”) these were on separate lines.

2018-06-10Good eye!
9ERROR

(make-money)
will not produce given output
;-> #money.Money{:amount 0, :currency #money.Currency{:divisor 100, :sym “USD”, :desc “US Dollars”}}
instead it will produce
;-> #money.Money{:amount 0, :currency :usd}
because of make-money method doesn’t perform lookup in currencies map

2018-06-10Thank you for letting us know. This is fixed in the next printing.
23SUGGEST

It says “Clojure doesn’t allow protocols to extend protocols”, but actually it’s possible and doesn’t raise any exception.

2018-06-09Clarified.
40SUGGEST

The section ‘Custom Printing for Types’ in chapter 2 oversimplifies the
printing apparatus.

Printing for the reader (prn etc.) versus printing for humans
(println etc.) is primarily distinguished via the print-readably
dynamic var as far as I can tell.

Accessing the print-dup method needs explicit rebinding of print-dup.
Some newer types don’t even implement print-dup. For example, eduction
supports print-readably but not print-dup.

In any case I think as it is, this section simplifies a little too much
– I referred to this section to learn how I should support custom
printing for my new type, but now I am confused and not sure which of
these mechanisms covers which purpose exactly.

Thank you!

2018-06-10Thank you. These are worth mentioning, and we've included a little more explanation for the next printing. FWIW, `print-dup` is intended to be used when the returned string (say, from prn-string) will be captured with the intention of reading it back in as data via the reader. `the *print-readably* var is true by default, and indicates that the print method should escape all non-printable characters, and provide some additional context.
13ERROR

In the new-money function definition, the Money constructor call’s second argument should be a currency from the currencies map declared previously, since the Money record specifies a Currency record type for its second field. The call should be (->Money 0 (:usd currencies)). This is related to the reported erratum on page 9.

2018-06-10
8670ERROR

Line 20 - (swap! inventory items) should be (swap! inventory conj items)

122TYPO

The defrecord KnowledgeEngine form is missing its closing parenthesis.

Categories: