Ich möchte meinen Mangel an Wissen anhand eines Beispiels demonstrieren.
Verwenden Sie die folgenden zwei Makrodefinitionen:
(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))))))
Das erste Makro schattiert alle benannten Variablen, max
die im Körper auftreten können, und das zweite nicht, was anhand des folgenden Beispiels gezeigt werden kann:
(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)))))
Soweit ich erfahren habe, funktioniert die Auswertung eines Makroaufrufs folgendermaßen:
Das Makro wird zweimal ausgewertet. Zuerst wird der Körper ausgewertet und gibt ein Formular zurück. Dieses Formular wird dann erneut ausgewertet.
So weit, ist es gut.
Wenn ich jedoch davon ausgehe, dass das Makro wirklich einen Textblock zurückgibt, der zufällig eine Lisp-Form ist und dann interpretiert wird, entsteht ein Konflikt, der mich dazu bringt, das obige Beispiel nicht zu verstehen.
Welchen Textblock gibt das zweite Makro, das make-symbol
return verwendet, so dass keine Schattenbildung auftritt? Nach meinem Verständnis wäre ein extrem unwahrscheinlicher, zufällig gewählter Symbolname sinnvoll.
Wenn ich pp-macroexpand...
beide Makros verwende, wird dieselbe Erweiterung zurückgegeben.
Kann mir jemand aus dieser Verwirrung helfen?
print-gensym
und print-circle
auf setzen , können t
Sie den Unterschied in den Makroerweiterungen sehen.
#:max
. Was bedeutet das ? Ich bin sehr an weiteren Details interessiert.
#:
ist nur eine Konvention des Druckers ein uninterned Symbol , um anzuzeigen , (das ist , was print-gensym
antörnt), gibt es mehr ausführlich im Handbuch: (elisp) Creating Symbols
.