ich berühre elisp vor kurzem und versuche zu verstehen, wie elisp makro funktioniert. Das GNU-Tutorial hat eine chapter Surprising-local-Vars für Makro lokale Variable und ich bin verwirrt darüber, wie die Makro-Erweiterung funktioniert.elisp makroexpansion lokale variable
(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
(inc ,var)))))
Es gibt zwei Let-Formen. die ersten
(let ((tempvar (make-symbol "max")))
hat hat nicht das Backquote, die auf dem Makro Ausdruck erweitert ausgewertet wird erhalten, dafür das uninterned Symbol „max“ wird nur in diesem Satz erstellt bekommen. Und das nicht signalisierte Symbol "max" wird zur Laufzeit verloren gehen, sollte es nicht richtig funktionieren?
Aber eigentlich funktioniert es gut. Ich habe versucht, die folgenden:
(for max from 1 to 10 do (print max))
Und die seine Expansion, wie folgend:
(macroexpand '(for max from 1 to 10 do (print max)))
(let ((max 1) (max 10)) (while (<= max max) (print max) (setq max (+ 1 max))))
zwei max Symbol hier, eine gebunden zu 1, eine weitere Schranke bis 10, hat die während Form Ausdruck zwei max Symbol.
wie löst die while-form die zwei verschiedenen das symbol "max" auf?
Sinn machen. Und für die erste Frage, könnten Sie mehr darüber erklären? Die erste Let-Form hat nicht das Backquote, daher wird sie bei expand phrase ausgewertet (das nicht-internierte Symbol wird zu diesem Zeitpunkt erstellt.) Und das erstellte nicht-internierte Symbol wird wahrscheinlich zur Laufzeit nicht existieren der fall: kompilieren sie den elisp code, das macro wird erweitert, das nicht-internierte symbol "max" wird erstellt, beim nächsten mal direkt aus dem byte code, das nicht-internierte symbol "max" existiert nicht, wie geht das Arbeit?). –
Das nicht unterbundene Symbol wird (zumindest) solange leben, wie Referenzen darauf vorhanden sind. Der Makro-Expanded-Code hat einen Verweis auf das nicht-internierte Symbol. Sie erhalten jedes Mal, wenn das Makro expandiert wird, in der Erweiterung ein * anderes * Symbol ohne Unterbrechung. "Uninterned" bedeutet nur und genau, dass Sie das Symbol nicht mit seinem Namen finden können, sondern nur, indem Sie bereits einen Verweis darauf haben. – Vatine
In Common Lisp würde das Setzen von Druckkreis auf T im Allgemeinen Symbole mit demselben Namen mit Leservariablen drucken. Das scheint bei Emacs nicht der Fall zu sein. – coredump