Como é determinado o escopo da variável para macros?

11

Veja o exemplo de macro a seguir, definido em macro.el.

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

E tomar a seguinte função, definida em um arquivo diferente , function.el.

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

Quando function.elé compilado por byte, será some-variablevinculado sob ligação lexical ou dinâmica?

Entendo que isso depende de o arquivo ser usado -*- lexical-binding: t; -*-, portanto, minha pergunta diz respeito especificamente às seguintes situações:

  1. Se function.elusa ligação lexical, mas macro.elnão.
  2. Se macro.elusa ligação lexical, mas function.elnão.

Faz diferença se some-varfoi declarado global (com um defvar) por dentro function.el? Se isso acontecer, estou especificamente interessado no caso em que não ocorreu .

Malabarba
fonte
Eu acho que Jisang Yoo cobriu isso com alguns detalhes em yoo2080.wordpress.com/2013/08/14/…
phils
Não sei ao certo, mas aposto que a expansão de macro herda a semântica de ligação do site de expansão, não da definição de macro. Isso faria sentido, já que a expansão é realmente substituída no local da chamada. Mas: por que você quer saber? Você pretende escrever um código que realmente se baseie nesses detalhes ?!
lunaryorn
@lunaryorn a macro não depende completamente sobre isso, mas pode produzir erros surpreendentes para o usuário se ele não respeitar a ligação do arquivo é usado em.
Malabarba
@ Malabarba Escreva sua macro de uma maneira que não dependa da ligação no buffer de destino. Ou melhor ainda, não use uma macro.
lunaryorn
@ Lunaryorn Eu não era muito claro. A macro é apenas um formulário let e funciona como anunciado de qualquer maneira. Eu só quero ter certeza de que esse formulário deixe siga o escopo especificado no arquivo em que foi expandido. Essa questão faz parte da descoberta de se isso acontece automaticamente ou se eu preciso codificá-lo na macro.
Malabarba

Respostas:

9

O tipo de escopo ativo para o (let ((some-variable ..)) ...)seu exemplo é o ativo no site da chamada de macro (ou seja, o que se aplica some-function).

Uma macro pode saber que tipo de escopo será usado para o código retornado, verificando o valor da lexical-bindingvariável.

Stefan
fonte