¿Cómo se determina el alcance variable para macros?

11

Tome el siguiente ejemplo de macro, definido en macro.el.

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

Y tomar la siguiente función, definida en un archivo diferente , function.el.

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

Cuando function.else compila byte, ¿ some-variablese vinculará bajo enlace léxico o dinámico?

Entiendo que esto depende de si el archivo se usa -*- lexical-binding: t; -*-, por lo que mi pregunta se refiere específicamente a las siguientes situaciones:

  1. Si function.elusa enlace léxico, pero macro.elno lo hace.
  2. Si macro.elusa enlace léxico, pero function.elno lo hace.

¿Hace alguna diferencia si some-varse ha declarado global (con un defvar) dentro function.el? Si lo hace, estoy específicamente interesado en el caso donde no lo ha hecho .

Malabarba
fuente
Creo Jisang Yoo cubrió esto en cierto detalle en yoo2080.wordpress.com/2013/08/14/...
PHILS
No estoy seguro, pero apuesto a que la expansión macro hereda la semántica de enlace del sitio de expansión, no de la definición de macro. Eso tendría sentido ya que la expansión se sustituye realmente en el sitio de la llamada. Pero: ¿por qué quieres saber? ¿Tiene la intención de escribir código que realmente se base en estos detalles?
lunaryorn
@lunaryorn la macro no confiar plenamente en esto, pero podría producir errores sorprendentes para el usuario si no respeta la unión del archivo se utiliza en.
Malabarba
@Malabarba Escriba su macro de una manera que no se base en el enlace en el búfer de destino, entonces. O incluso mejor, no use una macro en absoluto.
lunaryorn
@lunaryorn No estaba muy claro. La macro es solo una forma let, y funciona como se anuncia de cualquier manera. Solo quiero asegurarme de que este formulario de let siga el alcance especificado en el archivo en el que se expande. Esta pregunta es parte de averiguar si eso ocurre automáticamente o si necesito codificar eso en la macro.
Malabarba

Respuestas:

9

El tipo de alcance activo para el (let ((some-variable ..)) ...)en su ejemplo, es el activo en el sitio de la llamada de macro (es decir, el que se aplica a some-function).

Una macro puede saber qué tipo de alcance se utilizará para el código que devuelve al verificar el valor de la lexical-bindingvariable.

Stefan
fuente