Вызов функции в -> потоковый макрос

#clojure

#clojure

Вопрос:

Здесь нам нужны круглые скобки, чтобы вызвать анонимную функцию

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

Почему нет необходимости в круглых скобках вокруг map и fmap в этих примерах?

 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)
  

Ответ №1:

В «>документации для -> ->> макросов и указано, что формы после первого параметра упаковываются в списки, если они еще не являются списками. Итак, вопрос в том, почему это не работает для #() and (fn ..) forms? Причина в том, что обе формы находятся в форме списка во время развертывания макроса.

Например

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

получает (fn [x] ...) форму во время расширения, поэтому макрос думает: «Отлично, это список, я просто вставлю 3 во вторую позицию (fn ..) списка». Вызывая макрорасширение, вот что мы получаем:

 (fn 3 [x] (println x))
  

что, конечно, не работает. Аналогично для #() :

 (-> 3 #(println %))
  

расширяется до

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

Вот почему нам нужны дополнительные скобки.