Werden Makros beim Kompilieren der Datei erweitert?

13

Ich habe ein Makro, das bei jeder einzelnen Instanz seiner Verwendung zur Kompilierungszeit erweitert werden muss. Gibt es eine Möglichkeit, dies anzugeben, ohne die Codebasis zu durchlaufen und jeden Anruf sorgfältig mit zu verpacken eval-when-compile?

Sean Allred
quelle

Antworten:

13

Alle vom Byte-Compiler erreichbaren Makros werden beim Übersetzen erweitert. "Erreichbar" bedeutet im Wesentlichen, nicht zitiert zu werden.

Der Körper von defuns, defmacros, lambdas wird alle bytegemischt, wenn die Quelldatei, die sie enthält, bytegemischt wird. Also ja, jedes Makro in ihnen wird erweitert, solange sie nicht in einem Anführungszeichen ( ') enthalten sind. Ein sehr häufiger Fehler besteht darin, lambdas in ein Zitat zu setzen. Aus diesem Grund sollten Sie niemals Ihr lambdas zitieren .

Dies ist einer der großen Vorteile von Makros. Solange sie gut geschrieben sind, haben sie keinen Einfluss auf die Laufzeitleistung. Der andere Vorteil ist natürlich ihre Kraft und Vielseitigkeit. Der Nachteil ist, dass Sie die Syntax manipulieren und nicht Objekte. Es gibt also viel Raum für Probleme, manche unerwartet, andere unvermeidlich.

Malabarba
quelle
7

Wie Malabarba bereits erklärt hat, werden Makros während der Bytekompilierung erweitert. Wenn eine Datei nicht kompiliert wird, werden Makros beim Laden der Datei erweitert (eifrige Makroerweiterung).

Verlassen Sie sich jedoch nicht darauf. Es ist sehr schlechter Stil. Sie können im Allgemeinen nicht erwarten, dass der Code, der Ihr Makro verwendet, tatsächlich kompiliert wird, und Sie sollten während der Kompilierung im Allgemeinen so wenig Code wie möglich ausführen . Insbesondere verwenden Makros kaum und nur , wenn es keine andere Möglichkeit gibt. Als Faustregel gilt, dass Makros nur für die Syntax und niemals für die Semantik (oder Funktionalität) verwendet werden.

Makros sind eine undichte Abstraktion. Ihre Erweiterung ist zum Zeitpunkt der Kompilierung fest im Zielcode codiert und kann nicht nachträglich geändert werden. Der Zielcode hängt anschließend von der spezifischen Implementierung des Makros zum Zeitpunkt der Erweiterung ab. Dies hängt insbesondere von allen internen APIs ab, die im Makrotext verwendet werden.

Infolgedessen können Sie weder diese API noch irgendetwas, auf das sich die Makroerweiterung stützt, ändern, ohne Code zu beschädigen, der für Ihr Makro kompiliert wurde.

Die liberale Verwendung von Makros für die Funktionalität ebnet den Weg zur Abhängigkeitshölle .

Mondhorn
quelle
Sehr gute Punkte, die beim Schreiben oder Verwenden von Makros beachtet werden sollten.
Sean Allred
"Die liberale Verwendung von Makros für die Funktionalität ebnet den Weg zur Abhängigkeitshölle." Bis vor einer Woche hatte package.el einen Fehler, der die Paketinstallation unter absolut legitimen Abhängigkeiten von Makros völlig zum Erliegen brachte.
Malabarba
@Malabarba Möchten Sie Details mitteilen?
Lunaryorn
@lunaryorn Hier gehts . Schlimmes kleines Problem.
Malabarba
1
@lunaryorn Ich stimme zu, dass Makros gefährlich sind (ich werde sogar meine Antwort bearbeiten, um weniger lobend zu klingen :), aber ich glaube nicht, dass dieser Fehler eine bestimmte Instanz davon war. Dieser Fehler hatte andere (weniger erschwerende) Manifestationen, die überhaupt keine Makros beinhalteten. Es verursachte auch Probleme mit Funktionsabhängigkeiten.
Malabarba