2011-10-20 11 views
8

musimy nawiasów tutaj, aby nawiązać połączenie z anonimowej funkcjiWywołanie funkcji w -> gwintowania makro

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

Dlaczego nie ma potrzeby stosowania nawiasów wokół map+ i fmap+ w tych przykładach?

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) 

Odpowiedz

16

documentation dla państwa -> i ->> makr że formy po pierwszym parametrem są owinięte w wykazach, jeżeli nie są one już listy. Pytanie brzmi: dlaczego to nie działa dla formularzy #() i (fn ..)? Powodem jest to, że obie formy są w formie listy w momencie, gdy makro się rozwija.

Na przykład

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

dostaje formularz (fn [x] ...) w czasie ekspansji, więc makro myśli „wielki, jest to lista, ja po prostu włóż 3 w drugiej pozycji listy (fn ..)”. Wywołując makroekspansję, otrzymujemy:

(fn 3 [x] (println x)) 

co oczywiście nie działa. Podobnie dla #():

(-> 3 #(println %)) 

jest rozszerzona do

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

Dlatego potrzebujemy dodatkowych nawiasów.