(partial apply str) and apply-str in clojure ->

If I do the following:

user=> (-> ["1" "2"] (partial apply str)) 
#<core$partial__5034$fn__5040 clojure.core$partial__5034$fn__5040@d4dd758>

... I am returning a partial function. However, if I bind it to a variable:

user=> (def apply-str (partial apply str))
#'user/apply-str
user=> (-> ["1" "2" "3"] apply-str)       
"123"

... the code works as I intended. I would suggest that this is one and the same, but apparently this is not so. Can someone explain why this is for me?

+5
source share
5 answers

-> - a macro, so it should not follow the rules that you expect from the point of view of the application. The macro transforms the source before evaluating the forms. Try macroexpanding forms:

user> (macroexpand '(-> ["1" "2"] (partial apply str)))
(partial ["1" "2"] apply str)

What are you trying to achieve here using the "->" macro?

EDIT: Please Note:

user> ((partial apply str) ["1" "2"])
"12"
+6
source

You do not have to do this.

(->> ["1" "2" "3"] (apply str))

?

+5

, (-> ["1" "2"] (partial apply str)), :

(partial ["1" "2"] apply str), :

["1" "2"] ( , - !), Vars apply str . #<core$partial...>. , IllegalArgumentException, , Var.

+4

โ†’ expr . : (partial ["1" "2"] apply str), parital, .

parital, str expr , , :

(-> ["1" "2"] ((partial apply str)))

: , Clojure.

+1

-> parens apply-str , , . ->, :

(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."
  ([x] x)
  ([x form] (if (seq? form)
              (with-meta `(~(first form) ~x ~@(next form)) (meta form))
              (list form x)))
  ([x form & more] `(-> (-> ~x ~form) ~@more)))

The relevant part is when it deals with two arguments xand form. If formis seq, is xinserted as the second argument in this list. Otherwise, the macro places formand xit in the list. This means that you can use the bare character as an abbreviation for a list containing one character.

user> (macroexpand '(-> 123 (foo)))
(foo 123)
user> (macroexpand '(-> 123 foo))
(foo 123)
0
source

All Articles