Voglio dimostrare la mia mancanza di conoscenza con un esempio.
Utilizzando le seguenti due definizioni macro,
(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 prima macro ombreggia qualsiasi variabile denominata max
che può verificarsi nel corpo e la seconda no, che può essere mostrata con il seguente esempio:
(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)))))
Per quanto ho imparato, la valutazione di una chiamata macro funziona in questo modo:
La macro viene valutata due volte. Innanzitutto il corpo viene valutato e restituisce un modulo. Questo modulo viene quindi valutato di nuovo.
Fin qui tutto bene.
Ma se suppongo che la macro restituisca davvero una porzione di testo che sembra essere una forma lisp, che viene poi interpretata, ottengo un conflitto che mi rende incapace di capire l'esempio sopra.
Quale pezzo di testo make-symbol
restituisce la seconda macro che utilizza , in modo che non si verifichino ombre? Nella mia comprensione, avrebbe senso un nome di simbolo scelto a caso estremamente estremo.
Se uso pp-macroexpand...
entrambe le macro restituisco la stessa espansione.
Qualcuno è in grado di aiutarmi a uscire da questa confusione?
print-gensym
e print-circle
per t
voi sarà in grado di vedere la differenza nelle espansioni di macro.
#:max
. Cosa significa ? Sono molto interessato a maggiori dettagli.
#:
è solo una convenzione della stampante per indicare un simbolo uninterned (questo è quello che print-gensym
si accende), non v'è più in dettaglio nel manuale: (elisp) Creating Symbols
.