Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function call in -> threading macro

Tags:

clojure

We need parentheses here to make a call of anonymous function

user=> (-> [1 2 3 4] (conj 5) (#(map inc %)))
(2 3 4 5 6)

Why there is no need for parentheses around map+ and fmap+ in these examples?

user=> (def map+ #(map inc %))
#'user/map+
user=> (-> [1 2 3 4] (conj 5) map+)
(2 3 4 5 6)

user=> (defn fmap+ [xs] (map inc xs))
#'user/fmap+
(-> [1 2 3 4] (conj 5) fmap+)
(2 3 4 5 6)
like image 943
4e6 Avatar asked Oct 20 '11 15:10

4e6


1 Answers

The documentation for the -> and ->> macros state that the forms after the first parameter are wrapped into lists if they are not lists already. So the question is why does this not work for #() and (fn ..) forms? The reason is that both forms are in list form at the time the macro expands.

For example

(-> 3 (fn [x] (println x)))

gets the (fn [x] ...) form at expansion time, so the macro thinks "great, it's a list, I'll just insert the 3 in the second position of the (fn ..) list." Invoking macroexpansion, this is what we get:

(fn 3 [x] (println x))

which of course doesn't work. Similarly for #():

(-> 3 #(println %))

is expanded to

(fn* 3 [p1__6274#] (println p1__6274#))

That's why we need the extra parens.

like image 104
Paul Avatar answered Nov 11 '22 03:11

Paul