Wie wird das variable Scoping für Makros bestimmt?

11

Nehmen Sie das folgende Beispielmakro, definiert in macro.el.

(defmacro some-macro (&rest body)
  `(let ((some-variable 1))
     ,@body))

Nehmen Sie die folgende Funktion, die in einer anderen Datei definiert ist function.el.

(defun some-function ()
  (some-macro (do-something)))

Wann function.elwird Byte kompiliert, wird some-variableunter lexikalischer oder dynamischer Bindung gebunden?

Ich verstehe, dass dies davon abhängt, ob die Datei verwendet -*- lexical-binding: t; -*-wird. Meine Frage bezieht sich daher speziell auf die folgenden Situationen:

  1. Wenn function.ellexikalische Bindung verwendet, aber macro.elnicht.
  2. Wenn macro.ellexikalische Bindung verwendet, aber function.elnicht.

Macht es einen Unterschied, ob some-vares im Inneren als global (mit einer Defvar) deklariert wurde function.el? Wenn ja, interessiert mich speziell der Fall, in dem dies nicht der Fall ist .

Malabarba
quelle
Ich denke, Jisang Yoo hat dies unter yoo2080.wordpress.com/2013/08/14/…
phils
Ich weiß es nicht genau, aber ich wette, dass die Makroerweiterung die Bindungssemantik von der Erweiterungssite erbt, nicht von der Makrodefinition. Das wäre sinnvoll, da die Erweiterung tatsächlich an der Anrufstelle ersetzt wird. Aber: Warum willst du das wissen? Beabsichtigen Sie, Code zu schreiben, der sich tatsächlich auf diese Details stützt ?!
Mondhorn
@unaryorn das Makro verlässt sich nicht vollständig darauf, aber es kann überraschende Fehler für den Benutzer erzeugen, wenn es die Bindung der Datei, in der es verwendet wird, nicht
berücksichtigt
@Malabarba Schreiben Sie Ihr Makro so, dass es nicht von der Bindung im Zielpuffer abhängt. Oder noch besser, verwenden Sie überhaupt kein Makro.
Mondhorn
@lunaryorn Ich war nicht ganz klar. Das Makro ist nur ein Let-Formular und funktioniert so oder so wie angekündigt. Ich möchte nur sicherstellen, dass dieses Let-Formular dem in der Datei angegebenen Umfang entspricht, in der es erweitert wurde. Diese Frage ist Teil der Feststellung, ob dies automatisch geschieht oder ob ich das im Makro codieren muss.
Malabarba

Antworten:

9

Die Art des Gültigkeitsbereichs, die für das (let ((some-variable ..)) ...)in Ihrem Beispiel aktiv ist, ist diejenige, die am Ort des Makroaufrufs aktiv ist (dh diejenige, die für gilt some-function).

Ein Makro kann durch Überprüfen des Werts der lexical-bindingVariablen erkennen, welche Art von Gültigkeitsbereich für den zurückgegebenen Code verwendet wird.

Stefan
quelle