Reputation: 191189
Clojure's ->>
macro thread the form from the last argument, when ->
form from the first.
user=> (->> a (+ 5) (let [a 5]))
10
However, I get an exception when I used the operations exchanged.
user=> (-> a (let [a 5]) (+ 5))
CompilerException java.lang.IllegalArgumentException: let requires a vector for its binding in user:1, compiling:(NO_SOURCE_PATH:1:7)
Furthermore, I expect these two operations will get me the same results, which is not.
user=> (-> 0 (Math/cos) (Math/sin))
0.8414709848078965
user=> (->> 0 (Math/sin) (Math/cos))
1.0
What's wrong? How's the ->
and ->>
macros work?
Upvotes: 0
Views: 126
Reputation: 191189
The ->
macro inserts the argument as the first argument for the given function, not giving the argument to the last function.
Likewise ->>
inserts as the last argument.
user=> (macroexpand '(-> x (- 1)))
(- x 1)
user=> (macroexpand '(->> x (- 1)))
(- 1 x)
Two simple examples:
user=> (-> 1 (- 1) (- 2))
-2
user=> (->> 1 (- 1) (- 2))
2
As for the first example, -2 == (- (- 1 1) 2)
, and for the second 2 == (- 2 (-1 1))
As a result, we get the same results for the unary functions.
user=> (macroexpand '(-> 0 Math/sin Math/cos))
(. Math cos (clojure.core/-> 0 Math/sin))
user=> (macroexpand '(->> 0 Math/sin Math/cos))
(. Math cos (clojure.core/->> 0 Math/sin))
So, only ->>
makes sense in the question.
user=> (macroexpand '(->> a (+ 5) (let [a 5])))
(let* [a 5] (clojure.core/->> a (+ 5)))
user=> (macroexpand '(-> a (+ 5) (let [a 5])))
IllegalArgumentException let requires a vector for its binding in user:1 clojure.core/let (core.clj:4043)
Upvotes: 5