Commit Diff


commit - 4f0a073a8d931b85d019d5bbc41c505004924033
commit + 08ec40a1e9b3debbfa960a940681340be7f12389
blob - 2da8fccc0d8af901f57c4cb3b373ece496b7637d
blob + 88a185f8b4eb89352c8f98775d5d072c6742c990
--- README.md
+++ README.md
@@ -8858,15 +8858,15 @@ When a function’s behavior depends on the type of va
 call that function polymorphic. Many of Clojure’s core functions, like conj or
 reduce, are polymorphic: we can conj into maps, vectors, sets, and lists, and
 each does something different. Often, our own code is implicitly polymorphic by
-virtue of using other polymorphic functions: (defn add-bird [coll] (conj coll
-:bird)) can add birds to lots of different things.
+virtue of using other polymorphic functions: `(defn add-bird [coll] (conj coll
+:bird))` can add birds to lots of different things.
 
 When we need a function whose behavior explicitly depends on its arguments, we
 can use ad-hoc approaches, like if, cond, or case. The instance?, type, and
 supers functions let us choose what to do based on the type of the value.
 
-When we need an open function—one whose behavior can be extended to new things
-later—we use a multimethod, an interface, or a protocol. Multimethods are the
+When we need an open function-one whose behavior can be extended to new things
+later - we use a multimethod, an interface, or a protocol. Multimethods are the
 most general approach: they use a dispatch function, which receives the
 function’s arguments and decides which implementation to call. They’re not
 limited to dispatching by argument type: they can use arbitrary values and
@@ -8883,11 +8883,11 @@ nothing stopping you from writing your own documented 
 using definterface+, which does so automatically. Interfaces are slightly
 faster; prefer them when performance matters.
 
-To create instances of a new type, we have reify. Like (fn [x] ...), reify
-generates an anonymous type—it can have interfaces and protocols as supertypes,
+To create instances of a new type, we have reify. Like `(fn [x] ...)`, reify
+generates an anonymous type - it can have interfaces and protocols as supertypes,
 and provides implementations for those types, but has no (predictable,
 meaningful) name. When we want to name our types—perhaps so that other people
-can extend them later—we use deftype and defrecord. Most of the time, defrecord
+can extend them later - we use deftype and defrecord. Most of the time, `defrecord`
 is most useful: they work like maps out of the box. However, deftype is
 available should we need to construct bare-bones types with unusual behaviors.
 
@@ -8898,52 +8898,52 @@ concepts often in Clojure. A topic for later discussio
 ### Problems
 
 Write a sorted function that uses cond and instance? to convert lists to sorted
-lists (using (sort ...)), and sets to sorted sets (using (into (sorted-set)
-...)).
+lists (using `(sort ...)`), and sets to sorted sets (using `(into (sorted-set)
+...)`).
 
-Rewrite sorted as a multimethod. Using defmethod, extend sorted to handle maps.
+Rewrite sorted as a multimethod. Using `defmethod`, extend sorted to handle maps.
 
-Add a checked-off field to the GroceryList type, and use it to store a set of
+Add a checked-off field to the `GroceryList` type, and use it to store a set of
 items that are already in the cart. Write a check-off function that takes a
 grocery list and checks off an item on it, by adding that item to the
-checked-off set: (check-off my-list eggs)
+checked-off `set: (check-off my-list eggs)`.
 
-Write a remaining function which takes a GroceryList and returns the items that
+Write a remaining function which takes a `GroceryList` and returns the items that
 haven’t been checked off yet.
 
-Change the definition of print-out for GroceryList to take the checked-off set
-into account, printing an [x] in front of checked-off items.
+Change the definition of print-out for `GroceryList` to take the checked-off set
+into account, printing an `[x]` in front of checked-off items.
 
-Imagine Clojure had no built-in sets. Make up a Set protocol with some basic
-operations, like add-element, has-element?, and remove-element.
+Imagine Clojure had no built-in sets. Make up a `Set` protocol with some basic
+operations, like `add-element`, `has-element?`, and `remove-element`.
 
 Using a vector or list to store your elements, write a basic implementation of
-your Set protocol. Experiment to make sure adding the same item twice doesn’t
+your `Set` protocol. Experiment to make sure adding the same item twice doesn’t
 add two copies.
 
-Try making larger and larger sets–say, with ten, a thousand, and a hundred
-thousand elements. Use (time (has-element? some-set 123)) to see how your set
+Try making larger and larger `sets–say`, with ten, a thousand, and a hundred
+thousand elements. Use `(time (has-element? some-set 123))` to see how your set
 performance changes with size. Why is this?
 
 Write a different implementation of a Set, which uses a map to store its
 elements. Compare its performance to your list-based set.
 
-The deref function uses an interface called clojure.lang.IDeref to return the
-current value of a container type. Using deftype, define your own container
-type. Try @(MyContainer :hi) to verify that you can get the value of your
-container (:hi) back.
+The `deref` function uses an interface called `clojure.lang.IDeref` to return the
+current value of a container type. Using `deftype`, define your own container
+type. Try `@(MyContainer :hi)` to verify that you can get the value of your
+container `(:hi)` back.
 
-[advanced] So far, we’ve worked only with immutable types. deftype lets us
-define mutable types by tagging a field with ^:unsynchronized-mutable, like so:
-(deftype DangerBox [^:unsynchronized-mutable value] ...). Design a Mutable
-protocol with a (write! box value) function to overwrite the value of a mutable
-container. Using (set! field value), build your own mutable container type
-which supports both Mutable and IDeref. Confirm that you can change its value
-using write!, and read it back using @.
+[advanced] So far, we’ve worked only with immutable types. `deftype` lets us
+define mutable types by tagging a field with `^:unsynchronized-mutable`, like so:
+`(deftype DangerBox [^:unsynchronized-mutable value] ...)`. Design a `Mutable`
+protocol with a `(write! box value)` function to overwrite the value of a mutable
+container. Using `(set! field value)`, build your own mutable container type
+which supports both `Mutable` and `IDeref`. Confirm that you can change its value
+using `write!`, and read it back using `@`.
 
 [advanced] Use your mutable container as a counter by reading its current state
-and writing back a value one greater–e.g. via (write! box (inc @box)). Using
-dotimes, perform many updates in a row, and verify that the final value of the
+and writing back a value one greater–e.g. via `(write! box (inc @box))`. Using
+`dotimes`, perform many updates in a row, and verify that the final value of the
 counter is the same as the number you passed to dotimes.
 
 [advanced] Run this dotimes increment loop in two threads at once, using