2011-10-20 13 views
8

Necesitamos paréntesis aquí para hacer una llamada de función anónimallamada de función en -> roscado macro

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

¿Por qué no hay necesidad de paréntesis alrededor map+fmap+ y en estos ejemplos?

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) 

Respuesta

16

El documentation para el estado -> y ->> macros que las formas después de la primera parámetro se envuelven en listas si no están listas ya. Entonces la pregunta es por qué esto no funciona para los formularios #() y (fn ..)? La razón es que ambos formularios están en forma de lista en el momento en que se expande la macro.

Por ejemplo

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

tiene la forma (fn [x] ...) en el momento de expansión, por lo que la macro piensa "genial, es una lista, sólo voy a insertar el 3 en la segunda posición de la lista (fn ..)." Invocando macroexpansion, esto es lo que obtenemos:

(fn 3 [x] (println x)) 

que por supuesto no funciona. Del mismo modo para #():

(-> 3 #(println %)) 

se expande a

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

Es por eso que necesitamos los parens adicionales.