2017-09-02 1 views
2

Je ne comprends pas comment obtenir l'expansion complète de la macro.Pourquoi la macro-expansion ne développe pas les formes imbriquées dans Clojure?

Avec ce code

(when true (when true true)) 

je voudrais obtenir la pleine expansion macro

(if true (do (if true (do true))) 

Mais je ne peux pas

Je comprends macroexpansion-1 va résoudre le premier niveau d'expansion:

(macroexpand-1 '(when true (when true true))) 

(if true (do (when true true))) 

Mais pourquoi quand je l'appelle à nouveau macroexpand-1 (c'est ce que devrait faire macroexpand):

(macroexpand-1 '(if true (do (when true true)))) 

J'ai obtenu exactement le même résultat?

(if true (do (when true true))) 

Je m'attendais à une expansion complète de macro.

La macro-extension fonctionne-t-elle uniquement avec les formulaires de niveau supérieur?

Je suis au courant d'une fonction expand-all dans l'espace de noms clojure.walk, donc je suppose macroexpand ne fonctionne pas sur les structures imbriquées. Ai-je raison ?

Répondre

6

Vous avez raison.

Voir aussi https://clojuredocs.org/clojure.core/macroexpand

où il est dit:

Remarque ni macroexpand-1, ni macroexpand développer des macros dans les sous-formulaires.

Et en effet macroexpand-t-tout l'expansion récursive:

> (clojure.walk/macroexpand-all '(when true (when true true))) 
(if true (do (if true (do true)))) 

Voir aussi https://clojuredocs.org/clojure.walk/macroexpand-all

où il est dit:

effectue récursive tous les macroexpansions possibles sous forme.

Votre exemple

(macroexpand-1 '(if true (do (when true true)))) 

pourrait vous confondre, mais il fait que les documents disent:

(forme macroexpand-1) Si la forme représente une forme macro, retourne son expansion , sinon retourne le formulaire.

Donc, puisque « si » est pas une macro, il retourne juste si, sans entrer dans les sous-formulaires ...