Come viene determinato l'ambito variabile per le macro?


11

Prendi la seguente macro di esempio, definita in macro.el.

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

E prendere la seguente funzione, definita in un file diverso , function.el.

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

Quando function.elviene compilato byte, verrà some-variableassociato con associazione lessicale o dinamica?

Capisco che dipende dall'utilizzo del file -*- lexical-binding: t; -*-, quindi la mia domanda riguarda specificamente le seguenti situazioni:

  1. Se function.elutilizza l'associazione lessicale, ma macro.elnon lo fa.
  2. Se macro.elutilizza l'associazione lessicale, ma function.elnon lo fa.

Fa differenza se some-varè stato dichiarato globale (con un defvar) all'interno function.el? Se lo fa, sono particolarmente interessato al caso in cui non è così .


Penso che Jisang Yoo ne abbia parlato in dettaglio a yoo2080.wordpress.com/2013/08/14/…
phils

Non lo so per certo, ma scommetto che l'espansione macro eredita la semantica di associazione dal sito di espansione, non dalla definizione macro. Ciò avrebbe senso dal momento che l'espansione è effettivamente sostituita nel sito di chiamata. Ma: perché vuoi saperlo? Intendi scrivere codice che si basa effettivamente su questi dettagli ?!
lunaryorn,

@lunaryorn la macro non si basa completamente su questo, ma potrebbe produrre bug sorprendenti per l'utente se non rispetta l'associazione del file in cui è utilizzato.
Malabarba

@Malabarba Scrivi la tua macro in modo da non fare affidamento sull'associazione nel buffer di destinazione, quindi. O ancora meglio, non usare affatto una macro.
lunaryorn,

@lunaryorn Non ero abbastanza chiaro. La macro è solo un modulo let e funziona come pubblicizzato in entrambi i modi. Voglio solo assicurarmi che questo modulo segua lo scoping specificato nel file in cui è espanso. Questa domanda fa parte dello scoprire se ciò accade automaticamente o se devo codificarlo nella macro.
Malabarba,

Risposte:


9

Il tipo di scoping attivo per l' (let ((some-variable ..)) ...)esempio nel tuo esempio è quello attivo nel sito della chiamata macro (cioè quello che si applica a some-function).

Una macro può sapere quale tipo di ambito verrà utilizzato per il codice che restituisce controllando il valore della lexical-bindingvariabile.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.