(->> x & forms)
Threads the expr through the forms. Inserts x as the last item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the last item in second form, etc.
;; An example of using the "thread-last" macro to get
;; the sum of the first 10 even squares.
user=> (->> (range)
(map #(* % %))
(filter even?)
(take 10)
(reduce +))
1140
;; This expands to:
user=> (reduce +
(take 10
(filter even?
(map #(* % %)
(range)))))
1140
user=> (def c 5)
user=> (->> c (+ 3) (/ 2) (- 1))
3/4
;; and if you are curious why
user=> (use 'clojure.walk)
user=> (macroexpand-all '(->> c (+ 3) (/ 2) (- 1)))
(- 1 (/ 2 (+ 3 c)))
;; let's compare thread first (->) and thread last ( ->> )
user=> (macroexpand '(-> 0 (+ 1) (+ 2) (+ 3)))
(+ (+ (+ 0 1) 2) 3)
user=> (macroexpand '(->> 0 (+ 1) (+ 2) (+ 3)))
(+ 3 (+ 2 (+ 1 0)))
;; ->> and -> by simple string concatenation
;; Effectively (str " jmd" "hello")
user=> (->> "hello" (str " jmd"))
" jmdhello"
;; Effectively (str "hello" " jmd")
user=> (-> "hello" (str " jmd"))
=> "hello jmd"
;; It is OK to omit the parentheses if a function takes only one argument
(->> [1 2 [3 4] 5]
flatten ; no parenthesis
(map inc))
=> (2 3 4 5 6)
;; It's OK to include anonymous function in the thread, but don't forget
;; to put in an extra pair of parentheses to call the function
(->> [1 2 3 4 5]
((fn [coll] (map inc coll))) ; double parentheses
(apply +))
=> 20
;; the short hand form of the anonymous function works the same
(->> [1 2 3 4 5]
(#(map inc %)) ; double parentheses
(apply +))
;; For large threads you can use commas (interpreted as whitespaces)
;; to visualize where the items are going to be inserted.
;; Takes the first 5 even numbers
user=> (->> (range)
(filter even?)
(take 5))
=> (0 2 4 6 8)
;; with two commas (you can use one if you prefer)
user=> (->> (range)
(filter even? ,,)
(take 5 ,,))
=> (0 2 4 6 8)
;; For instance:
;; (filter even? ,,)
;; means
;; (filter even? (range))