Le macro vengono espanse quando il file viene compilato?


13

Ho una macro che deve essere espansa in ogni singola istanza del suo utilizzo in fase di compilazione. C'è un modo in cui posso specificare che sia così senza passare attraverso la base di codice e racchiudendo accuratamente ogni chiamata eval-when-compile?

Risposte:


13

Tutte le macro raggiungibili dal compilatore di byte vengono espanse durante la compilazione. "Raggiungibile" significa essenzialmente non essere quotato.

Il corpo di defuns, defmacros, lambdas, sono tutti compilati in byte quando il file sorgente che li contiene è compilato in byte. Quindi sì, qualsiasi macro al loro interno verrà espansa, purché non sia racchiusa tra virgolette ( '). Un errore molto comune è quello di racchiudere lambdas in una citazione e, in effetti, è per questo che nonlambda dovresti mai citare la tua s .

Questo è uno dei grandi vantaggi delle macro, purché siano ben scritte, non incidono sulle prestazioni di runtime. L'altro vantaggio è la loro potenza e versatilità, ovviamente. Lo svantaggio è che stai manipolando la sintassi, non gli oggetti, quindi c'è molto spazio per i problemi, alcuni inaspettati, altri inevitabili.


7

Come Malabarba ha già spiegato, le macro vengono espanse durante la compilazione dei byte. Se un file non viene compilato, le macro vengono espanse quando il file viene caricato (espansione macro desiderosa).

Non fare affidamento su questo, però. È uno stile pessimo. In genere non puoi aspettarti che il codice che utilizza la tua macro sia effettivamente compilato e dovresti generalmente eseguire il minor codice possibile durante la compilazione. In particolare, usa le macro appena e solo se non c'è altro modo. Come regola generale, utilizzare le macro solo per la sintassi e mai per la semantica (o funzionalità).

Le macro sono un'astrazione che perde. La loro espansione è codificata nel codice target al momento della compilazione e non può essere modificata in modo retrospettivo. Il codice target successivamente dipende sulla implementazione specifica della macro al momento dell'espansione. In particolare, dipende da tutte le API interne utilizzate nel corpo della macro.

Di conseguenza non è possibile modificare nessuna di queste API o qualsiasi cosa su cui faccia affidamento l'espansione della macro, senza violare alcun codice compilato sulla propria macro.

L'uso liberale di macro per la funzionalità apre la strada all'inferno delle dipendenze .


Ottimi punti da tenere a mente quando si scrive o si usano le macro.
Sean Allred,

"L'uso liberale di macro per la funzionalità apre la strada all'inferno delle dipendenze". Fino a una settimana fa, package.el aveva un bug che interrompeva completamente l'installazione del pacchetto in situazioni di legittimità delle macro perfettamente legittime.
Malabarba,

@Malabarba Vuoi fornire dettagli?
lunaryorn,

@lunaryorn Ecco qua . Brutto piccolo problema.
Malabarba,

1
@lunaryorn Sono d'accordo che le macro sono pericolose (modificherò anche la mia risposta per sembrare meno elogi :), ma non credo che il bug ne sia stato un esempio specifico. Quel bug aveva altre manifestazioni (meno aggravanti) che non coinvolgono affatto le macro. Ha inoltre causato problemi con le dipendenze delle funzioni.
Malabarba,
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.