Re arranging code - oliyh/learning-clojure GitHub Wiki

Threading macros

The macros -> and ->> allow you to re-arrange your code into a more human-readable form. Consider the following for a function that doubles a number, then adds 8, then divides by 2:

(fn [x] (/ (+ (* x 2) 8) 2))

We are taking a number, doing something to it, doing something to the result of it, then doing something to the result of that. This is what the threading macro does - -> inserts the result of the first form as the first argument of the second form, and so on. The following code will be arranged in the same way at run time:

(fn [x] 
  (-> x 
    (* 2)
    (+ 8)
    (/ 2)))

->> works in the same way, but it passes the result of the previous form as the second argument in the next form. That is, the following two functions will be identical at run time:

(fn [x] 
  (->> x 
    (* 2)
    (+ 8)
    (/ 2)))

(fn [x] (/ 2 (+ 8 (* 2 x))))

Note because + and * are commutative it doesn't matter if you use -> or ->>, the results are the same, but as / is not this function returns a different result from the one above.

Conditionals

Nested if statements can be avoided with cond. This takes predicate / expression pairs and evaluates each predicate for truthiness in order, returning the expression when the predicate is true.

The two functions below are equivalent:

(defn describe-if [x] 
  (if (neg? x) "Negative" 
    (if (zero? x) "Zero" 
      (if (< x 1) "Small" "Big"))))

(defn describe-cond [x]
  (cond
    (neg? x) "Negative"
    (zero? x) "Zero"
    (< x 1) "Small"
    :default "Big"))