yazz.com
yazz.com

Reputation: 58786

What does -> do in clojure?

I have seen the clojure symbol -> used in many places, but I am unsure as to what this symbol is called and does, or even whether it is part of standard clojure. Could someone explain this to me?

Upvotes: 30

Views: 8384

Answers (6)

Nicolas Modrzyk
Nicolas Modrzyk

Reputation: 14197

-> uses the result of a function call and send it, in sequence, to the next function call.

So, the easier example would be:

 (-> 2 (+ 3))

Returns 5, because it sends 2, to the next function call (+ 3)

Building up on this,

(-> 2 
  (+ 3) 
  (- 7))

Returns -2. We keep the result of the first call, (+ 3) and send it to the second call (- 7).

As noted by @bending, the accepted answer would have been better showing the doto macro.

(doto person
  (.setFName "Joe")
  (.setLName "Bob")
  (.setHeight [6 2]))

Upvotes: 32

dansalmo
dansalmo

Reputation: 11686

I did not fully get what -> (thrush or thread) did until I visualized it like this:

(-> expr f1 f2 f3)  ;same as (f3 (f2 (f1 expr)))

(-> expr            ;same as form above
    f1              ;just a different visual layout
    f2
    f3)

;this form is equivalant and shows the lists for f1, f2, f3.
(->         expr     ; expr treaded into first form
        (f1     )    ;  |   result threaded into next form
    (f2          )   ;  |   and so on...
(f3               )) ;  V   the lists (f1

(f3 (f2 (f1 expr)))  ;the result is the same as this  

Here are some examples:

(-> 41 inc dec inc)   ;same as (inc (dec (inc 41)))
42

(->            41     ;same as above but more readable
          (inc   )
     (dec         )
(inc               ))
42

(inc (dec (inc 41)))  ;easier to see equivalence with above form.
42

(-> 4 (* 4 3) (- 6))  ;same as (- (* 4 3 4) 6)
42 

(->   4               ;      4
   (*   3 4)          ;   (* 4 3 4)
(-           6))      ;(- (* 4 3 4) 6)
42

(- (* 4 3 4) 6)       ;easier to see equivalence with above form.
42

Upvotes: 15

Psyllo
Psyllo

Reputation: 674

'->' is a macro. The best way to describe it, I think, is in the example of the "dot special form" for which it serves the purpose of making the code more terse and legible as is indicated on the clojure.org website's explanation of the The Dot special form

(.. System (getProperties) (get "os.name"))

expands to:

(. (. System (getProperties)) (get "os.name"))

but is easier to write, read, and understand. See also the -> macro which can be used similarly:

(-> (System/getProperties) (.get "os.name"))

There is also 'doto'. Let's say you have a single object on which you'd like to call several consecutive setters. You could use 'doto'.

(doto person
  (.setFName "Joe")
  (.setLName "Bob")
  (.setHeight [6 2]))

In the above example the setters don't return anything, making 'doto' the appropriate choice. The -> would not work in place of 'doto' unless the setters returned 'this'.

So, those are some techniques related to the -> macro. I hope that helps explain not only what they do, but also why they exist.

Upvotes: 9

Alex Baranosky
Alex Baranosky

Reputation: 50064

You can see for yourself:

(macroexpand `(-> 42 inc dec))

Upvotes: 3

Teresa Siegmantel
Teresa Siegmantel

Reputation: 903

It's a way to write code left to right, instead of inside out, e.g.

(reduce (map (map xs bar) foo) baz)

becomes

(-> xs (map bar) (map foo) (reduce baz))

You might want to read the source, it's here.

EDIT: Fixed my confusion of -> with ->>, thanks to amalloy. Sadly my example is now quite unlikely to appear in practice.

Upvotes: 17

Rafe Kettler
Rafe Kettler

Reputation: 76955

It's called the thrush operator. It's best explained here.

Upvotes: 0

Related Questions