->>

added
1.1

ns
clojure.core

type
macro

(->> 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))