2010-11-29 15 views
8

PourquoiClojure macroexpand

(macroexpand '(.. arm getHand getFinger)) 

ÉTENDU pour

(. (. arm getHand) getFinger) 

tout

(macroexpand '(-> arm getHand getFinger)) 

se développe pour

(getFinger (clojure.core/-> arm getHand)) 

En d'autres termes, pourquoi le -> ne se développe pas complètement dans le second exemple?

Répondre

10

macroexpand seulement développe le formulaire jusqu'à ce que le symbole dans la position de fonction ne soit pas une macro. La raison pour laquelle vous remarquez cela dans le cas de -> est que la macro -> est récursive.

Dans votre cas, vous voulez macroexpand-all forme clojure.walk

+0

C'est en fait la raison pour laquelle j'ai demandé. Est-ce que macroexpand n'a pas développé '->' jusqu'à ce que ce ne soit pas une macro? J'ai regardé le code source pour '->' et il semble finir par se résoudre à "([x form] (if (seq? Form) (avec-meta' (~ (première forme) ~ x ~ @ (forme suivante)) (forme de méta)) (forme de liste x))) "Peut-être que je ne comprends pas correctement. – Ralph

+1

@Ralph: 'macroexpand' ne développe pas les macros dans les sous-formulaires, donc' (-> bras getHand getFinger) 'se développe en' (clojure.core/-> (clojure.core/-> bras getHand) getFinger) 'qui s'étend (car -> est une macro) à '(getFinger (clojure.core/-> arm getHand))'. L'expansion s'arrête ici car 'getFinger' n'est pas une macro. – Brian

+0

Merci. Je l'ai maintenant. – Ralph