Je veux démontrer mon manque de connaissances avec un exemple.
En utilisant les deux définitions de macro suivantes,
(defmacro for (var from init to final do &rest body)
"Execute a simple for loop: (for i from 1 to 10 do (print i))."
(let ((tempvar 'max))
`(let ((,var ,init)
(,tempvar ,final))
(while (<= ,var ,tempvar)
,@body
(setq ,var (1+ ,var))))))
(defmacro for (var from init to final do &rest body)
"Execute a simple for loop: (for i from 1 to 10 do (print i))."
(let ((tempvar (make-symbol "max")))
`(let ((,var ,init)
(,tempvar ,final))
(while (<= ,var ,tempvar)
,@body
(setq ,var (1+ ,var))))))
la première macro masque toutes les variables nommées max
qui peuvent se produire dans le corps et la seconde non, ce qui peut être montré avec l'exemple suivant:
(let ((max 0)) ;; this variable is shadowed if the first macro defintion is used
(for i from 1 to 3 do
(setq square (* i i))
(if (> square max)
(princ (format "\n%d %d" i square)))))
Pour autant que j'ai appris l'évaluation d'un macro appel fonctionne comme ceci:
La macro est évaluée deux fois. Le corps est d'abord évalué et retourne un formulaire. Ce formulaire est ensuite évalué à nouveau.
Jusqu'ici tout va bien.
Mais si je suppose que la macro renvoie vraiment un morceau de texte qui se trouve être une forme lisp, qui est ensuite interprétée, j'obtiens un conflit qui me rend incapable de comprendre l'exemple ci-dessus.
Quel morceau de texte la deuxième macro qui utilise make-symbol
retourne-t-elle, afin qu'il n'y ait pas d'observation À mon avis, un nom de symbole choisi au hasard extrêmement improbable aurait du sens.
Si j'utilise les pp-macroexpand...
deux macros, renvoyez la même extension.
Est-ce que quelqu'un peut m'aider à sortir de cette confusion?
print-gensym
et print-circle
pour t
vous pourrez voir la différence dans les extensions de macro.
#:max
. Qu'est-ce que ça veut dire ? Je suis très intéressé par plus de détails.
#:
est juste une convention de l'imprimante pour indiquer un symbole uninterned (ce qui est ce qui print-gensym
se met en marche), il est plus en détail dans le manuel: (elisp) Creating Symbols
.