Living Clojure

Preparation

1. install java
2. install Leiningen
3. create a new project `lein new wonderland`
4. entering REPL: `cd wonderland; lein repl`

Chapter 1. The Structure of Clojure

simple values or literals simply evaluate to themselves, for example:

• integer: `12`
• decimal: `12.43`
• ratio: `1/3`
• character: `\j`
• keyword: `:jam`
• string: `"jam"`
• boolean: `true`, `false`
• null: `nil`

expressions

``(+ 1 (+ 8 3))``

collections

• lists
• vectors
• maps
• sets

all collections are immutable and persistent.

Immutable means the value of the collection does not change. A function to change a collection gives you back a new version of the collection.

Persistent means collections will do smart creations of new versions of themselves by using structural sharing.

Lists

Lists are collections of data what you want to access from the top of the list.

to create a list, simply put a quote in front of the parents:

``'(1 2 "jam" :marmalade-jar)``

you can mix and match values in a collections.

this is also valid:

``'(1, 2, "jam", :bee)``

commas are ignored and treated like whitespace. (but just use spaces)

some basic functions:

``````(first '(:rabbit :pocket-watch :marmalade :door))
;; -> :rabbit
(cons 5 '()) ;; same as (cons 5 nil)
;; -> (5)
(cons 4 (cons 5 nil))
;; -> (4 5)
'(1 2 3 4 5)
;; -> (1 2 3 4 5)
(list 1 2 3 4 5)
;; -> (1 2 3 4 5)``````

Vectors

Vectors are for collections of data that you want to access anywhere by position.

to create vector, use square brackets

``````[:jar1 1 2 3 :jar2]
(first [:jar1 1 2 3 :jar2])
;; -> :jar1
(rest [:jar1 1 2 3 :jar2])
;; ->  (1 2 3 :jar2)
;; return a list``````

``````(nth [:jar1 1 2 3 :jar2] 0)
;; -> :jar1
(nth [:jar1 1 2 3 :jar2] 2)
;; -> 2

vectors have better index access performance than lists, if you need to access the elements of collection by index, use a vector.

more common functions

``````(count [1 2 3 4])
;; -> 4
(conj [:toast :butter] :jam :honey)
;; -> [:toast :butter :jam :honey]
(conj '(:toast :butter) :jam :honey)
;; -> (:honey :jam :toast :butter)``````

`conj` adds to a collection in the most natural way for the data structure. for lists, it adds to the beginning. for vectors, it adds to the end.

Maps

Maps are for key-value pairs.

to create maps, use curly braces:

``{:jam1 "strawberry" :jam2 "blackberry"}``

maps are the one place that it can be idiomatic to leave the commas in for readability:

``{:jam1 "strawberry", :jam2 "blackberry"}``

get a value from maps

``````(get {:jam1 "strawberry", :jam2 "blackberry"} :jam2)
;; -> "blackberry"
;; get with a default value, put it as the last argument

a more idiomatic way to get value from maps:

``````(:jam2 {:jam1 "strawberry" :jam2 "blackberry" :jam3 "marmalade"})
;; -> "blackberry"``````

when using keyword as key, the key itself is also a function.

get keys and values:

``````(keys {:jam1 "strawberry" :jam2 "blackberry" :jam3 "marmalade"})
;; -> (:jam3 :jam2 :jam1)
(vals {:jam1 "strawberry" :jam2 "blackberry" :jam3 "marmalade"})

(remember, collections are immutable, below you actually get a new version of collection)

to update value:

``````(assoc {:jam1 "red" :jam2 "black"} :jam1 "orange")
;; -> {:jam2 "black", :jam1 "orange"}``````

to remove value:

``````(dissoc {:jam1 "strawberry" :jam2 "blackberry"} :jam1)
;; -> {:jam2 "blackberry"}``````

merge:

``````(merge {:jam1 "red" :jam2 "black"}
{:jam1 "orange" :jam3 "red"}
{:jam4 "blue"})
;; -> {:jam4 "blue", :jam3 "red", :jam2 "black", :jam1 "orange"}``````

Sets

Sets are for collections of unique elements.

create a set with `#{}`

``````#{:red :blue :white :pink}
;; duplicate are not allowed
#{:red :blue :white :pink :pink}
;; -> error``````

common sets functions in `clojure.set`:

``````;; union
;; combine all
(clojure.set/union #{:r :b :w} #{:w :p :y})
;; -> #{:y :r :w :b :p}
;; difference
;; takes elements away from one of the sets
(clojure.set/difference #{:r :b :w} #{:w :p :y})
;; -> #{:r :b}
;; intersection
;; return only shared elements
(clojure.set/intersection #{:r :b :w} #{:w :p :y})
;; -> #{:w}``````

convert other collecions to sets:

``````(set [:rabbit :rabbit :watch :door])
;; -> #{:door :watch :rabbit}
(set {:a 1 :b 2 :c 3})
;; -> #{[:c 3] [:b 2] [:a 1]}``````

get element from a set:

``````(get #{:rabbit :door :watch} :rabbit)
;; -> :rabbit
(get #{:rabbit :door :watch} :jar)
;; -> nil
;; use keyword as a function
(:rabbit #{:rabbit :door :watch})
;; -> :rabbit
;; the set itself can be used as a function to do the same thing
(#{:rabbit :door :watch} :rabbit)
;; -> :rabbit``````

check if element exists:

``````(contains? #{:rabbit :door :watch} :rabbit)
;; -> true
(contains? #{:rabbit :door :watch} :jam)
;; -> false``````

``````(conj #{:rabbit :door} :jam)
;; -> #{:door :rabbit :jam}``````

remove element from a set:

``````(disj #{:rabbit :door} :door)
;; -> #{:rabbit}``````

Symbols

Clojure symbols refer to values. when a symbol is evaluated, it returns the thing it refer to.

`def` gives something a name, so we can refer to it.

``````(def developer "Alice")
;; -> #'user/developer``````

`def` created a var object in the default namespace (`user`) for the symbol `developer`.

``````developer
;; -> "Alice"
user/developer
;; -> "Alice"``````

when you want to have a temporary var, use `let`.

`let` allows us to have bindings to symbols that are only available within the context of the `let`.

What happens in a `let`, stays in the `let`.

``````(def developer "Alice")
;; -> #'user/developer
(let [developer "Alice in Wonderland"]
developer)
;; -> "Alice in Wonderland"``````

the bindings of `let` are in a vector form. It expects pairs of symbol and values.

``````(let [developer "Alice in Wonderland"
rabbit "White Rabbit"]
[developer rabbit])
;; -> ["Alice in Wonderland" "White Rabbit"]``````
• use `def` to create global vars.
• use `let` to create temporary bindings.

Creating a function

`defn` takes following arguments:

• name of the function
• a vector of parameters
• body of the function
``````    (defn follow-the-rabbit [] "Off we go!")
;; -> #'user/follow-the-rabbit
(follow-the-rabbit)
;; -> "Off we go!"
(defn shop-for-jam [jam1 jam2]
:jam1 jam1
:jam2 jam2})
;; -> #'user/shop-for-jam

anonymous functions

``````;; return a function
(fn [] (str "Off we go" "!"))
;; invoke it directly
((fn [] (str "Off we go" "!")))
;; -> "Off we go!"
;; shorthand, use # in front of the parens:
(#(str "Off we go" "!"))
;; -> "Off we go!"
;; for parameters
;; if only 1 parameter, just use %
(#(str "Off we go" "!" " - " %) "again")
;; -> "Off we go! - again"
;; more than 1, just %1, %2 ...
(#(str "Off we go" "!" " - " %1 %2) "again" "?")
;; -> "Off we go! - again?"``````

`defn` is just the same as using `def` and binding the name to the anonymous function:

``````(def follow-again (fn [] (str "Off we go" "!")))
;; -> #'user/follow-again
(follow-again)
;; -> "Off we go!"``````

Namespaces

create a new namespace:

``(ns alice.favfoods)``

check current namespace:

``*ns*``

3 main ways of using libs in your namespace using require:

1. use `require` expression with the namespace as argument.
``    (require 'clojure.set)``
1. use `require` expression with an alias using `:as`.
``````    (require '[alice.favfoods :as af])
;; it's also common to see it nested within the ns:
(ns wonderland
(:require [alice.favfoods :as af]))``````
1. use `require` with the namespace and the `:refer :all` options.
``````    (ns wonderland
(:require [alice.favfoods :refer :all]))``````

however, the last way may create conflicts and also hard to read the code.

there's also a `use` expression that is the same as the `require` with `:refer :all`.

sum up

``````(ns wonderland
(:require [clojure.set :as s]))
(defn common-fav-foods [foods1 foods2]
(let [food-set1 (set foods1)
food-set2 (set foods2)
common-foods (s/intersection food-set1 food-set2)]
(str "Common Foods: " common-foods)))
(common-fav-foods [:jam :brownies :toast]
[:lettuce :carrots :jam])
;; -> "Common Foods: #{:jam}"``````

Chapter 2. Flow and Functional Transformations

expression and form

expression is code that can be evaluated for a result.

form is term for a valid expression that can be evaluated.

``(first)``

is an expression but not a valid form.

Controlling the Flow with Logic

``````(class true)
;; -> java.lang.Boolean
(true? true)
;; -> true
(true? false)
;; -> false
(false? false)
;; -> true
(false? true)
;; -> false
(nil? nil)
;; -> true
(nil? 1)
;; -> false
(not true)
;; -> false
(not false)
;; -> true
(not nil)
;; -> true``````

remember, `nil` is logically false in tests.

``````(= :drinkme :drinkme)
;; -> true
;; collection equality is special:
(= '(:drinkme :bottle) [:drinkme :bottle])
;; -> true
;; not= is a shortcut for (not (= x y))
(not= :drinkme :4)
;; -> true``````

Logic Tests on Collections

``````(empty? [:table :door :key])
;; -> false
(empty? [])
;; -> true
(empty? {})
;; -> true
(empty? '())
;; -> true``````

if we look at the definition of `empty?`, there is `seq`:

``````(defn empty?
[coll] (not (seq coll)))``````

In Clojure, there are the collection and sequence abstractions.

The collections are simply a collection of elements.

The `seq` function turns the collection into a sequence.

A sequence is a walkable list abstraction for the collection data structure.

``````(empty? [])
;; -> true
(seq [])
;; -> nil``````

remember, use `seq` to check for not empty instead of `(not (empty? x))`. this is because `nil` is treated as logically false in tests.

``````;; every? takes a predicate and a collection as arguments
(every? odd? [1 3 5])
;; -> true
(every? odd? [1 2 3 4 5])
;; -> false``````

A predicate is a function that returns a value used in a logic test.

create a predicate:

``````(defn drinkable? [x]
(= x :drinkme))
(every? drinkable? [:drinkme :drinkme])
;; -> true
;; use anonymous function
(every? (fn [x] (= x :drinkme)) [:drinkme :drinkme])
;; -> true
;; or
(every? #(= % :drinkme) [:drinkme :drinkme])
;; -> true``````

other logical test functions:

``````(not-any? #(= % :drinkme) [:drinkme :poison])
;; -> false
(not-any? #(= % :drinkme) [:poison :poison])
;; -> true
(some #(> % 3) [1 2 3 4 5])
;; -> true``````

`some` function can be used with a set to return the element, or the first matching element of the sequence.

``````;; set is a function of its own member
(#{1 2 3 4 5} 3)
;; -> 3
(some #{3} [1 2 3 4 5])
;; -> 3
(some #{4 5} [1 2 3 4 5])
;; -> 4``````

Harnessing the Power of Flow Control

`if` takes 3 parameters

1. the expression that is the logical test.
2. (if the test expression evaluates to true), evaluates the 2nd parameter.
3. (if false), evaluates the 3rd parameter.
``````    (if true "it is true" "it is false")
;; -> "it is true"
(if false "it is true" "it is false")
;; -> "it is false"
(if nil "it is true" "it is false")
;; -> "it is false"
(if (= :drinkme :drinkme)
"Try it"
"Don't try it")
;; -> "Try it"``````

combining `let` and `if`

``````(let [need-to-grow-small (> 5 3)]
(if need-to-grow-small
"drink bottle"
"don't drink bottle"))
;; -> "drink bottle"``````

or just use `if-let`:

``````(if-let [need-to-grow-small (> 5 1)]
"drink bottle"
"don't drink bottle"))
;; -> "drink bottle"``````

if you only want to do one thing when test is true, use `when`

`when` takes a predicate, if it is logical true, it will evaluate the body. otherwise, it returns `nil`.

``````(defn drink [need-to-grow-small]
(when need-to-grow-small "drink bottle"))
(drink true)
;; -> "drink bottle"
(drink false)
;; -> nil``````

there is also a `when-let`:

``````(when-let [need-to-grow-small true]
("drink bottle")
;; -> "drink bottle"
(when-let [need-to-grow-small false]
("drink bottle")
;; -> nil``````

when we want to test for mutiple things, use `cond`:

``````(let [bottle "drinkme"]
(cond
(= bottle "poison") "don't touch"
(= bottle "drinkme") "grow smaller"
(= bottle "empty") "all gone"))
;; -> "grow smaller"
``````

in the `cond` clause, once a logical test returns true and the expression is evaluated, none of the other test clauses are tried.

``````(let [x 5]
(cond
(> x 10) "bigger than 10"
(> x 4) "bigger than 4"
(> x 3) "bigger than 3"))
;; -> "bigger than 4"``````

for returning a default value instead of `nil`, use `:else`

``````(let [bottle "mystery"]
(cond
(= bottle "poison") "don't touch"
(= bottle "drinkme") "grow smaller"
(= bottle "empty") "all gone"
:else "unknown"))
;; -> "unknown"``````

`case` is shortcut for the `cond` where there is only one test value and it can be compared with an `=`:

``````(let [bottle "drinkme"]
(case bottle
"poison" "don't touch"
"drinkme" "grow smaller"
"empty" "all gone"))
;; -> "grow smaller"``````

however, `case` will throw an exception for no matching test. simply add an extra value as default:

``````(let [bottle "mystery"]
(case bottle
"poison" "don't touch"
"drinkme" "grow smaller"
"empty" "all gone"
"unknown"))
;; -> "unknown"``````

Functions Creating Functions and Other Neat Expressions

partial is a way of currying in Clojure. Currying is a way to generate a new function with an argument partially applied.

``````(defn adder [x y]
(+ x y ))
;; -> 7
;; -> 15``````

comp creates a new function that combines other functions. It takes any number of functions as its parameters and returns the composition of those functions going from right to left.

``````(defn toggle-grow [direction]
(if (= direction :small) :big :small))
(defn oh-my [direction]
(str "Oh My! You are growing " direction))
(oh-my (toggle-grow :small))
;; -> "Oh My! You are growing :big"
;; or use comp
(defn surprise [direction]
((comp oh-my toggle-grow) direction))``````

Destructuring

destructuring allows you to assign named bindings for the elements in things like vectors and maps.

``````(let [[color size] ["blue" "small"]]
(str "The " color " door is " size))
;; -> "The blue door is small"``````

the destructuring knew what values to bind by the placement of the symbols in the binding expression.

``````;; without destructuring:
(let [x ["blue" "small"]
color (first x)
size (last x)]
(str "The " color " door is " size))
;; -> "The blue door is small"``````

to keep th initial data structure as a binding, use `:as` keyword:

``````(let [[color [size] :as original] ["blue" ["small"]]]
{:color color :size size :original original})
;; -> {:color "blue", :size "small", ":original ["blue" ["small"]]}``````

destructuring can also be done with maps:

``````(let [{flower1 :flower1 flower2 :flower2}
{:flower1 "red" :flower2 "blue"}]
(str "The flowers are " flower1 " and " flower2))
;; -> "The flowers are red and blue"``````

specify default values with `:or`:

``````(let [{flower1 :flower1 flower2 :flower2 :or {flower2 "missing"}}
{:flower1 "red"}]
(str "The flowers are " flower1 " and " flower2))
;; -> "The flowers are red and missing"``````

`:as` works in maps too:

``````(let [{flower1 :flower1 :as all-flowers}
{:flower1 "red"}]
[flower1 all-flowers])
;; -> ["red" {:flower1 "red"}]``````

most of the time, you will want to give the same name to the binding as the name of the key, use `:keys` directive:

``````(let [{:keys [flower1 flower2]}
{:flower1 "red" :flower2 "blue"}]
(str "The flowers are " flower1 " and " flower2))
;; -> "The flowers are red and blue"``````

destructuring is also available to use on parameters while defining functions with `defn`:

``````(defn flower-colors [{:keys [flower1 flower2]}]
(str "The flowers are " flower1 " and " flower2))
(flower-colors {:flower1 "red" :flower2 "blue"})
;; "The flowers are red and blue"))``````

The Power of Laziness

Clojure can also work with infinite lists.

``````(take 5 (range))
;; -> (0 1 2 3 4)``````

calling `range` returns a lazy sequence, you an specify an end for the range by passing it a parameter:

``````(range 5)
;; -> (0 1 2 3 4)
(class (range 5))
;; -> clojure.lang.LazySeq``````

but when you don't specify an end, the default is infinity.

`repeat` can be used to generate an infinite sequence of repeated items:

``````(repeat 3 "rabbit")
;; -> ("rabbit" "rabbit" "rabbit")
(class (repeat 3 "rabbit"))
;; -> clojure.lang.LazySeq``````

`repeatedly` takes a function that will be repeatedly executed over and over again.

``````(repeat 5 (rand-int 10))
;; -> (7 7 7 7 7)
(repeatedly 5 #(rand-int 10))
;; -> (1 5 8 4 3)

(take 10 (repeatedly #(rand-int 10)))``````

`cycle` takes a collection as an argument and returns a lazy sequence of the items in the collection repeated infinitely.

``````(take 3 (cycle ["big" "small"]))
;; -> ("big" "small" "big")``````

`rest` will return a lazy sequence when it operates on a lazy sequence:

``````(take 3 (rest (cycle ["big" "small"])))
;; -> ("small" "big" "small")``````

Recursion

``````(def adjs ["normal"
"too small"
"too big"
"is swimming"])
(def alice-is [in out]
(if (empty? in)
out
(alice-is
(rest in)
(conj out (str "Alice is " (first in))))))

you can also do it with `loop`

``````(defn alice-is [input]
(loop [in input
out []]
(if (empty? in)
out
(recur (rest in)
(conj out (str "Alice is " (first in)))))))

`recur` jumps back to the recursion point, which is the beginning of the loop, and rebinds with new parameters.

using `recur` also has another very important advantage. It provides a way of not "consuming the stack" for recursive calls:

``````(defn countdown [n]
(if (= n 0)
n
(countdown (- n 1))))
(countdown 3)
;; -> 0
(countdown 100000)
;; -> StackOverflowError``````

in the recursive call, a new frame was added to the stack for every function call, `recur` only needs one stack at a time.

``````(defn countdown [n]
(if (= n 0)
n
(recur (- n 1))))
(countdown 100000)
;; -> 0``````

In general, always use `recur` when you are doing recursive calls.

The Functional Shape of Data Transformations

map

``````(def animals [:mouse :duck :dodo :lory :eaglet])
(map #(str %) animals)
;; -> (":mouse" ":duck" ":dodo" ":lory" ":eaglet")
(class (map #(str %) animals))
;; -> clojure.lang.LazySeq``````

`map` returns a lazy sequence.

`doall` forces evaluation of the side effets:

``````(def animal-print (doall (map #(println %) animals)))
;; -> do the println
(animal-print)
;; return value only but no println
``````

`map` can also take more than one collection to map against. It uses each collection as a parameter to the function.

the `map` function will terminate when the shortest collection ends. because of this, we can even use an infinite list with it:

``````(def animals ["mouse" "duck" "dodo" "lory" "eaglet"])
(map gen-animal-string animals (cycle ["brown" "black"]))``````

reduce

differs from `map` in that you can change the shape of the result.

``````(reduce + [1 2 3 4 5])
;; -> 15
(reduce (fn [r x] (+ r (* x x))) [1 2 3])
;; -> 14``````

unlike `map`, you cannot `reduce` an infinite sequence (e.g., `range`)

filter

takes a predicate and a collection as an argument.

``````(filter (complement nil?) [:mouse nil :duck nil])
;; -> (:mouse :duck)``````

`complement` function takes the function and returns a function that takes the same arguments, but returns the opposite truth value.

``````((complement nil?) nil)
;; -> false``````

remove

takes a predicate and a collection.

``````(remove nil? [:mouse nil :duck nil])
;; -> (:mouse :duck)``````

for

``````(for [animal [:mouse :duck :lory]]
(str (name animal)))
;; -> ("mouse" "duck" "lory")``````

the result is a lazy sequence.

if more than one collection is specified in the `for`, it will iterate over them in a nested fashion.

``````(for [animal [:mouse :duck :lory]
color [:red :blue]]
(str (name color) (name animal)))``````

`:let` modifier:

``````(for [animal [:mouse :duck :lory]
color [:red :blue]
:let [animal-str (str "animal-" (name animal))
color-str (str "color-" (name color))
display-str (str animal-str color-str)]]
display-str)``````

`:when` modifier:

``````(for [animal [:mouse :duck :lory]
color [:red :blue]
:let [animal-str (str "animal-" (name animal))
color-str (str "color-" (name color))
display-str (str animal-str color-str)]
:when (= color :blue)]
display-str)``````

flatten

takes any nested collection and returns the contents in a single flattened sequence:

``````(flatten [[:duck [:mouse] [[:lory]]]])
;; -> (:duck :mouse :lory)
``````

into

takes the new collection and returns all the items of the collection `conj`-ed on to it:

``````(into [] '(1 2 3))
;; -> [1 2 3]
(into (sorted-map) {:b 2 :a 1 :z3})

// vectors into maps
(into {} [[:a 1] [:b 2] [:c 3]])
// maps into vectors
(into [] {:a 1, :b 2, :c 3})``````

partition

`partition` is useful for dividing up collections:

``````(partition 3 [1 2 3 4 5 6 7 8 9 10])
;; -> ((1 2 3) (4 5 6) (7 8 9))
(partition-all 3 [1 2 3 4 5 6 7 8 9 10])
;; -> ((1 2 3) (4 5 6) (7 8 9) (10))``````

`partition-by` takes a function and applies it to every element in the collection. it creates a new partition every time the result changes:

``````(partition-by #(= 6 %) [1 2 3 4 5 6 7 8 9 10])
;; -> ((1 2 3 4 5) (6) (7 8 9 10))
``````

Chapter 3. State and Concurrency

Using Atoms for independent Items

Atoms are designed to store the state of something that is independent, meaning we can change the value of it independently of changing any other state.

``(def who-atom (atom :caterpillar))``

to see the value of the atom, need to dereference it with a preceding `@`:

``````who-atom
;; -> #<Atom@....: :caterpillar>
@who-atom
;; -> :caterpillar``````

changes to atom are always made synchronously.

first is using `reset!`, replaces old value with new value and returns the new value:

``````(reset! who-atom :chrysalis)
@who-atom
;; -> :chrysalis``````

the other way is with `swap!`, applies a function on the old value and sets it to the new value:

``````(def change [state]
(case state
:caterpillar :chrysalis
:chrysalis :butterfly
:butterfly))
(swap! who-atom change)
@who-atom
;; -> :chrysalis
(swap! who-atom change)
@who-atom
;; -> :butterfly  ``````

when using `swap!`, the function used must be free of side effects.

`swap!` operator reads the value of the atom and applies the function on it, then compares the current value of the atom again to make sure that another thread hasn't changed it. if the value has changed in the meantime, it will retry.

this means any side effects in functions might be executed multiple times.

``````(def counter (atom 0))
@counter
;; -> 0
;; the understore `_` is the name of the value, we don't care here.
(dotimes [_ 5] (swap! counter inc))
@counter
;; -> 5``````

to use multiple threads on this, use the `future` form. the `future` form takes a body and executes it in another thread.

``````(let [n 5]
(future (dotimes [_ n] (swap! counter inc)))
(future (dotimes [_ n] (swap! counter inc)))
(future (dotimes [_ n] (swap! counter inc))))
@counter
;; -> 15``````

if we use a function with side effect:

``````(defn inc-print [val]
(println val)
(inc val))
(let [n 2]
(future (dotimes [_ n] (swap! counter inc-print)))
(future (dotimes [_ n] (swap! counter inc-print)))
(future (dotimes [_ n] (swap! counter inc-print)))``````

you can see some values printed multiple times.

Using Refs for Coordinated Changes

What if we have more than one thing that needs to change in a coordinated fashion? `refs` allows coordinated shared state.

that makes them different from atoms is that you need to change their values within a transaction. Clojure uses software transactional memory (STM) to accomplish this.

All actions on refs within the transaction are:

• Atomic: updates will occur to all the refs, if something goes wrong, none of them will be updated.
• Consistent: optional validator function can be used to check value before the transaction commits.
• Isolated: transaction has its own isolated view of the world, it will not see any effects from other transactions.
``````(def alice-height (ref 3))
(def right-hand-bites (ref 10))``````

like atoms, use a preceding `@` to dereference refs:

``````@alice-height
;; -> 3``````

`alter` form takes a ref and a function to apply to the current value (similar to `swap!`)

``````(defn eat-from-right-hand []
(when (pos? @right-hand-bites)
(alter right-hand-bites dec)
(alter alice-height #(+ % 24))))
(eat-from-right-hand)
;; -> IllegalStateException No transaction running``````

we need to run this in a transaction, we do this by using a `dosync` form. it will coordinate any state changes within the form in a transaction.

``````(dosync (eat-from-right-hand))
;; -> 27
@alice-height
;; -> 27
@right-hand-bites
;; -> 9``````

``````(let [n 2]
(future (dotimes [_ n] (eat-from-right-hand)))
(future (dotimes [_ n] (eat-from-right-hand)))
(future (dotimes [_ n] (eat-from-right-hand))))
@alice-height
;; -> 147
@right-hand-bites
;; -> 4``````

the function of the `alter` must be side-effect free too, the reason is the same: there would be retries.

there is another function called `commute` that we could use instead of `alter`, it also must be called in a transaction.

the difference between them is `commute` will not retry during the transaction. instead, it will use an in-transaction-value in the meantime, finally setting the `ref` value at the commit point in the transaction.

this feature is very nice for speed and limiting retries.

on the other hand, the function that `commute` applied must be commutative (execute order does not matter, like addition), or have a last-one-in-wins behavior.

the example above can use `commute` instead of `alter`.

Transactions that involve time-consuming computations and a large number of refs are most likely to be retried. If you are looking to limit retries, this is a reason you might prefer an atom with a map of state over many refs.

when you have one ref what is defined in relation to another ref, use `ref-set` instead of `alter`:

``````(def x (ref 1))
(def y (ref 1))
(defn new-values []
(dosync
(alter x inc)
(ref-set y (+ 2 @x)))) ;; use ref-set
(let [n 2]
(future (dotime [_ n] (new-values)))
(future (dotime [_ n] (new-values))))
@x
;; -> 5
@y
;; -> 7``````

Using Agents to Manage Changes on Their Own

atoms and refs are synchronous, agents are used for independent and asynchronous changes.

if you don't need the result right away, you can pass it to an agent for processing.

``````(def who-agent (agent :caterpillar))
@who-agent
;; -> caterpillar``````

we can change the state of an agent by using `send`.

``````(def change [state]
(case state
:caterpillar :chrysalis
:chrysalis :butterfly
:butterfly))
(send who-agent change)
@who-agent
;; -> :chrysalis``````

unlike `swap!` and `alter`, `send` returns immediately.

there is another way to dispatch an action to the agent, with `send-off`. the difference is `send-off` should be used for potentially I/O-blocking actions.

`send` uses a fixed thread pool, good for CPU-bound operations. `send-off` uses an expandable thread pool necessary to avoid an I/O-bound thread pool from blocking:

agents can also handle transactions with their action, means we could change refs within an agent action, or send actions only if the transaction commits.

when there's an Exception:

``````(def who-agent (agent :caterpillar))
(defn change [state]
(case state
:caterpillar :chrysalis
:chrysalis :butterfly
:butterfly))
(defn change-error [state]
(throw (Exception. "Boom!")))
(send who-agent change-error)
;; -> failed
@who-agent
;; -> :caterpillar``````

the agent's state did not change. the agent itself is now failed.

The exception has been cached, and next time an action is processed, the agent's error will be thrown:

``````(send-off who-agent change)
;; -> Exception Boom!``````

you can inspect agent's erorr with `agent-errors`:

``````(agent-errors who-agent)
;; -> Exception Boom!``````

the agent will stay in this failed state until the agent is restarted with `restart-agent`, which clears its errors and resets the state of the agent:

``````(restart-agent who-agent :caterpillar)
;; -> :caterpillar
(send who-agent change)

@who-agent
;; -> :chrysalis``````

to control how the agent responds to errors, use `set-error-mode!`, it can be set to either `:fail` or `:continue`:

``(set-error-mode! who-agent :continue)``

If it is set to `:continue` and we assign an error handler with the `set-error-handler-fn!` function, the error handler will happen on an agent exception, but the agent itself will continue on without a need for a restart:

``````(defn err-handler-fn [a ex]
(println "error " ex " value is " @a))
(set-error-mode! who-agent :continue)
(set-error-handler! who-agent err-handler-fn)
(send who-agent change-error)
;; -> print out
@who-agent
;; -> :caterpillar
;; however the agent will continue on without a restart for the next call
(send who-agent change)
@who-agent
;; -> :chrysalis``````

to sum up:

``````| Type | Communication | Coordination |
|-
| Atom | Synchronous | Uncoordinated |
| Ref | Synchronous | Coordinated |
| Agent | Asynchronous | Uncoordinated |``````

Chapter 4. Java Interop and Polymorphism

Clojure uses the `new` and `.` special form to interact with Java classes.

``````String cString = new String("caterpillar");
cString.toUpperCase();``````

clojure's equivalent:

``(. "caterpillar" toUpperCase)``

or

``(.toUpperCase "caterpillar")``

if the jave method takes arguments, they are included after the object.

``````String c1String = new String("caterpillar");
String c2String = new String("pillar");
c1String.indexOf(c2);``````

clojure's equivalent:

``(.indexOf "caterpillar" "pillar")``

in clojure, the first argument is the string we want to call the method on, and the second is the argument.

use `new` to create instance of Java object:

``(new String "Hi!!")``

Another way to create an instance of a Java class is to use a shorthand form by using a dot right after the class name:

``(String. "Hi!!")``

to import Java classes, do it by using `:import` in the namespace form:

``````(ns caterpillar.network

to execute static methods on java class, use a forward slash (`/`):

``(InetAddress/getByName "localhost")``

to get a property off of an object, use the dot notation:

``(.getHostName (InetAddress/getByName "localhost"))``

we can also use full qualified names without importing:

``(java.net.InetAddress/getByName "localhost")``

there is also a `doto` macro, which allows us to take a java object and then act on it with a list of operations:

``````(def sb (doto (StringBuffer. "Who ")
(.append "are ")
(.append "you?")))
(.toString sb)
;; -> "Who are you?"``````

without `doto`:

``````(def sb
(.append
(.append
(StringBuffer. "Who ")
"are ")
"you?"))``````

Practical Polymorphism

``````(defn who-are-you [input]
(cond
(= java.lang.String (class input)) "String - Who are you?"
(= clojure.lang.Keyword (class input)) "Keyword - Who are you?"
(= java.lang.Long (class input)) "Number - Who are you?"))
(who-are-you :alice)
;; -> Keyword
(who-are-you "alice")
;; -> String
(who-are-you 123)
;; -> Number
(who-are-you true)
;; -> nil``````

we can express this with polymorphism in clojure with multimethods.

first specifies how it is going to dispatch. that is, how it is going to decide which of the following methods to use:

``````(defmulti who-are-you class)
(defmethod who-are-you java.lang.Keyword [input]
(str "String - Who are you? " input))
(defmethod who-are-you clojure.lang.Keyword [input]
(str "Keyword - Who are you? " input))
(defmethod who-are-you java.lang.Long [input]
(str "Number - Who are you? " input))
(who-are-you :alice)
;; -> Keyword
(who-are-you "alice")
;; -> String
(who-are-you 123)
;; -> Number
(who-are-you true)
;; Exception``````

we can also provide a default dispatch method using the `:default` keyword:

``````(defmethod who-are-you :default [input]
(str "I don't know - who are you?" input))
(who-are-you true)
;; -> I don't know ...``````

any function can be given to dispatch on. we can even inspect the value of a map as input:

``````(defmulti eat-mushroom (fn [height]
(if (< height 3)
:grow
:shrink)))
(defmethod eat-mushroom :grow [_]
"Eat the right side to grow.")
(defmethod eat-mushroom :shrink [_]
"Eat the left side to shrink.")
(eat-mushroom 1)
;; -> ... grow
(eat-mushroom 9)
;; -> ... shrink``````

Another way to use polymorphism in clojure is to use protocols.

protocols can handle polymorphism elegantly with groups of functions.

``````(defprotocol BigMushroom
(eat-mushroom [this]))``````

the parameter `this` is the thing that we are going to perform the function on:

``````(extend-protocol BigMushroom
java.lang.String
(eat-mushroom [this]
(str (.toUpperCase this) " mmm tasty!"))
clojure.lang.Keyword
(eat-mushroom [this]
(case this
:grow "Eat the right side!"
:shrink "Eat the left side!"))
java.lang.Long
(eat-mushroom [this]
(if (< this 3)
:grow "Eat the right side to grow!"
:shrink "Eat the left side to shrink!")))
(eat-mushroom "Big Mushroom")
;; -> "BIG MUSHROOM mmm tasty!"
(eat-mushroom :grow)
;; -> "Eat the right side!"
(eat-mushroom 1)
;; -> "Eat the right side to grow!"``````

we are using protocols to add methods to existing data structure. what if we want to add our own data structure?

Clojure's answer to this is data types.

there're two solutions:

if you need structured data, use `defrecord`, which creates a class with a new type.

if you just need an object with a type to save memory, use `deftype`.

defrecord

the `defrecord` form defineds the fields that the class will hold:

``````(defrecord Mushroom [color height])
;; -> caterpillar.network.Mushroom``````

now can create new object with a dot notation:

``````(def regular-mushroom (Mushroom. "white and blue polka dots" "2 inches"))
(class regular-mushroom)
;; -> caterpillar.network.Mushroom``````

we can get the values with the dot-dash that is preferred over the dot-prefix for accessing fields:

``````(.-color regular-mushroom)
;; -> "white ..."
(.-height regular-mushroom)
;; -> "2 inches"``````

we can combine structured data type with protocols to implement interfaces:

``````(defprotocol Edible
(bite-right-side [this])
(bite-left-side [this]))``````

implement the protocol:

``````(defrecord WonderlandMushroom [color height]
Edible
(bite-right-side [this]
(str "The " color " bite makes you grow bigger"))
(bite-left-side [this]
(str "The " color " bite makes you grow smaller")))``````

then another data type implements `Edible`:

``````(defrecord RegularMushroom [color height]
Edible
(bite-right-side [this]
(str "The " color " bite tastes bad"))
(bite-left-side [this]
(str "The " color " bite tastes bad too")))``````

construct our mushroom objects:

``````(def alice-mushroom (WonderlandMushroom. "blue dots" "3 inches"))
(def reg-mushroom (RegularMushroom. "brown" "1 inch"))
(bite-right-side alice-mushroom)
;; -> "The blue dots bite makes you grow bigger"
(bite-right-side reg-mushroom)
;; -> "The brown bite tastes bad"``````

A real-world example of protocols is implementing different types of persistence. which is one data type writes to different types of data sources, one to database and one to s3 bucket for example.

deftype

sometimes we don't really care about the structure or the map lookup features provided by `defrecord`, we just need an object with a type to save memory.

in this case we should reach for `deftype`:

``````(defprotocol Edible
(bite-right-side [this])
(bite-left-side [this]))
(deftype WonderlandMushroom []
Edible
(bite-right-side [this]
(str "The bite makes you grow bigger"))
(bite-left-side [this]
(str "The bite makes you grow smaller")))
(deftype RegularMushroom []
Edible
(bite-right-side [this]
(bite-left-side [this]
(str "The bite tastes bad too")))
(def alice-mushroom (WonderlandMushroom.))
(def reg-mushroom (RegularMushroom.))
(bite-right-side alice-mushroom)
;; -> "The bite makes you grown bigger"
(bite-right-side reg-mushroom)
;; -> "The bite tastes bad"``````

the main difference between using protocols with `defrecord` and `deftype` is how you want your data organized.

if you want structure data, choose `defrecord`, otherwise, use `deftype`.

Caution

think before you use protocols.

sometimes you could have more simple solution without using protocols.

``````(def bite-right-side [mushroom]
(if (= (:type mushroom) "wonderland")
"The bite makes you grow bigger"
(bite-right-side {:type "wonderland"})
;; -> "The bite makes you grown bigger"
(bite-right-side {:type "regular"})
;; -> "The bite tastes bad"``````

Chapter 5. How to Use Clojure Projects and Libraries

to create a new project skeleton:

``\$ lein new serpent-talk``

for namespace and filename, dashes are not being valid in java class names.

so always use understores for directories and filenames, and use dashes for namespaces.

show dependencies as tree:

``\$ lein deps :tree``

run main function of a namespace from the command line using `lein run -m`:

``\$ lein run -m serpent-talk.talk "Hello pigeon"``

you can also add this to `project.clj` file specifying the main function:

``:main serpent-talk.talk``

then can run with:

``\$ lein run "Hello pigeon"``

Chapter 6. Communication with core.async

create a new project with `core.async`

``\$ lein new async-tea-party``

add dependency to `project.clj`:

``````:dependencies [[org.clojure/clojure "1.6.0"]
[org.clojure/core.async "xxx"]]``````

include `core.async` in the namespace (`src/async_tea_party/core.clj` file):

``````(ns async-tea-party.core
(:require [clojure.core.async :as async]))``````

Basics of core.async Channels

create a channel:

``(def tea-channel (async/chan))``

there are two main ways that you get things on and off channels: synchronously and asynchronously.

• `>!!`: a blocking put, puts data on the channel synchronously.
• `<!!`: a blocking take, takes data off the channel synchronously.
• `>!`: an async put, puts data on the channel asynchronously, needs to be used with a `go` block.
• `<!`: an async take, takes data off the channel asynchronously, needs to be used with a `go` block.

so when you see `!!` it means a blocking call.

the `tea-channe` created above is an unbuffered channel, the main thread would block until it got taken off. (it will also lock up REPL)

to create a buffered channel:

``(def tea-channel (async/chan 10))``

now test with the blocking put:

``````(async/>!! tea-channel :cup-of-tea)
;; -> true``````

get it off with a blocking take:

``````(async/<!! tea-channel)
;; -> :cup-of-tea``````

to close a channel:

``(async/close! tea-channel)``

this closes the channel to new inputs, however, if there are still values on it, they can be taken off. when the channel is finally empty, it will return a `nil`.

``````(async/>!! tea-channel :cup-of-tea-2)
(async/>!! tea-channel :cup-of-tea-3)
(async/>!! tea-channel :cup-of-tea-4)
(async/close! tea-channel)
;; -> nil
;; new puts will fail
(async/>!! tea-channel :cup-of-tea-5)
;; -> false
;; but existing values can be taken
(async/<!! tea-channel)
;; -> :cup-of-tea-2
(async/<!! tea-channel)
;; -> :cup-of-tea-3
(async/<!! tea-channel)
;; -> :cup-of-tea-4
;; until it's empty
(async/<!! tea-channel)
;; -> nil``````

also `nil` is special, you can not put it on a channel:

``````(async/>!! tea-channel nil)
;; Exception   ``````

so `nil` lets us know that the channel is empty.

now try async:

``````(let [tea-channel (async/chan)]
(async/go (async/>! tea-channel :cup-of-tea-1))
(async/go (println "Thanks for the " (async/<! tea-channel))))
;; Will print to stdout:
;; Thanks for the :cup-of-tea-1``````