store/[org.clojure/clojure "1.8.0"] clj::clojure.core/->

Community Documentation

Edit

Arities

[expr & forms] -> Val

Docs

Known as "thread-first".

Sequentially threads expr through the forms, inserting expr as the second item (first argument) of the 1st form, that form as the first argument of the 2nd form and soforth. Returns the result of the last form.

If a form is not a list, Eg. is a bare symbol, set, keyword or other structure, then a list is created with the form as the 1st element and the threaded expr as the 2nd element.

See also

Source

(defmacro ->
  "Threads the expr through the forms. Inserts x as the
  second 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
  second item in second form, etc."
  {:added "1.0"}
  [x & forms]
  (loop [x x, forms forms]
    (if forms
      (let [form (first forms)
            threaded (if (seq? form)
                       (with-meta `(~(first form) ~x ~@(next form)) (meta form))
                       (list form x))]
        (recur threaded (next forms)))
      x)))

Example 1

Edit
(-> [1 2 3]
    (conj 4)) ; (conj [1 2 3] 4)
; [1 2 3 4]

Example 2

Edit
;; Your own REPL! (Read Eval Print Loop)

;; We would need a little helper macro for that
;; It does what its name says - loops forever
(defmacro loop-forever [& body] `(loop [] ~@body (recur)))
;; => #'user/loop-forever

;; Your own REPL
(loop-forever (println (eval (read))))                                                                     
;; < (+ 1 2)
;; > 3

;; If you read the above code left to right (outside in) it reads LPER.
;; Inside out it reads REPL alright.

;; Sometimes it might be easier to read code outside in, just like a sequence of steps:
;; 1. Read, 2. Eval, 3. Print, 4. Loop
;; Here's how -> helps you:

(-> (read) (eval) (println) (loop-forever))                                                                
;; < (+ 1 2)
;; > 3

;; Does that read easier for you? If it does, -> is your friend!

;; To see what Clojure did behind the scenes with your -> expression:
(require 'clojure.walk)
;; => nil

(clojure.walk/macroexpand-all '(-> (read) (eval) (println) (loop-forever)))
;; => (loop* [] (println (eval (read))) (recur))

;; You can even use ->'s cousin ->> to setup your own REPL:
(->> (read) (eval) (println) (while true))
;; < (+ 1 2)
;; > 3

;; Can you see why we can't use -> to write the above?

Example 3

Edit
(def c 5)
;; => #'user/c

(-> c (+ 3) (/ 2) (- 1))                          
;; => 3

;; and if you are curious why
(use 'clojure.walk)
;; => nil

(macroexpand-all '(-> c (+ 3) (/ 2) (- 1)))
;; => (- (/ (+ c 3) 2) 1)

Example 4

Edit
;; Use of `->` (the "thread-first" macro) can help make code
;; more readable by removing nesting. It can be especially
;; useful when using host methods:

;; Arguably a bit cumbersome to read:
(first (.split (.replace (.toUpperCase "a b c d")
                         "A"
                         "X")
               " "))
;; => "X"

;; Perhaps easier to read:
(-> "a b c d" 
    .toUpperCase 
    (.replace "A" "X") 
    (.split " ") 
    first)
;; => "X"

;; It can also be useful for pulling values out of deeply-nested
;; data structures:
(def person 
  {:name "Mark Volkmann"
   :address {:street "644 Glen Summit"
             :city "St. Charles"
             :state "Missouri"
             :zip 63304}
   :employer {:name "Object Computing, Inc."
              :address {:street "12140 Woodcrest Dr."
                        :city "Creve Coeur"
                        :state "Missouri"
                        :zip 63141}}})
;; => #'user/person

(-> person :employer :address :city)
;; => "Creve Coeur"

;; same as above, but with more nesting
(((person :employer) :address) :city)
;; => "Creve Coeur"

;; Note that this operator (along with ->>) has at times been
;; referred to as a 'thrush' operator.

;; From http://clojure-examples.appspot.com/clojure.core/-%3E

Uses on crossclj