Макрос ->
добавляет в вашей второй версии скобки около 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)))
Соответствующая часть имеет место, когда речь идет о двух аргументах, x
и form
. Если form
является последовательностью, x
вставляется как второй аргумент в этом списке. В противном случае макрос помещает form
и x
в сам список. Это означает, что вы можете использовать пустой символ в качестве сокращения для списка, содержащего один символ.
user> (macroexpand '(-> 123 (foo)))
(foo 123)
user> (macroexpand '(-> 123 foo))
(foo 123)