Dies ist ein Zweifel, der mich immer neugierig gemacht hat.
Warum müssen die Definitionen, die ein Common-Lisp-Makro verwenden, neu kompiliert werden, wenn wir es modifizieren (abgesehen davon, dass wir natürlich das modifizierte Common-Lisp-Makro neu kompilieren)?
Vielen Dank im Voraus.
Common Lisp-Makros sind Code-Substitutionen, sie treten bei "Makro-Expansionszeit" auf. Für interpretierten Code kann "Laufzeit" sein. Für kompilierten Code ist es fast immer während der "Kompilierzeit".
Sobald der Code ersetzt wurde, gibt es keinen Verweis auf das Makro im resultierenden kompilierten Code (die ursprüngliche Quelle auf der Festplatte hat dies immer noch, wenn die Makroverwendung in einer Datei gespeichert wurde).
In einem Lisp-System, das alle "pre-macro extension" -Funktionskörper speichert und darüber informiert, welche Makros wo verwendet wurden, würde es etwas Bequemlichkeit geben und automatisch alles neu kompilieren, das ein bestimmtes Makro verwendet (möglicherweise rekursiv). das wurde aus dem Standard heraus gelassen.
Normalerweise schreibe ich meine Utility-Makros schon sehr früh in der Entwicklung, daher brauche ich diese Funktionalität nicht, und ich bin insgesamt glücklicher ohne sie, als wenn ich damit arbeiten würde Bildgröße ziemlich, nicht all dies zu verfolgen).
Beachten Sie, dass möglicherweise erforderlich ist.
Der Grund ist, dass Makros in kompilierten Implementierungen nur einmal zur Kompilierzeit expandiert werden und das Makro selbst im generierten Code nicht vorhanden ist.
Um klarer zu sein, beachte
%Vor% Wenn der Compiler f
code analysiert, wird er auf
und die Verweise auf das Makro badsquare
sind nicht unbedingt mehr vorhanden. Wenn Sie also das Makro badsquare
auf etwas anderes umdefinieren, hat dies keine Auswirkungen auf f
, es sei denn, Sie kompilieren es auch neu.
Die Verwendung eines Makros, das sich geändert hat, wird nur dann neu erstellt, wenn:
Das alte Makro hatte einen Fehler . Was es bedeutet, dass ein Makro einen Fehler hat, ist, dass es schlechten Code generiert. Der fehlerhafte Code muss vom festen Makro neu generiert werden.
Der alte Makro-generierte sucky Code . Wir wollen den Code mit dem neuesten und größten Makro neu kompilieren, das den schönsten Code generiert.
Die Laufzeitunterstützung für das alte Makro wird gelöscht . Der alte Makro-generierte Code, der Aufrufe an spezielle Laufzeit-Unterstützungsfunktionen macht, die auch von dem Paket bereitgestellt werden. Einige dieser Funktionen gehen in der neuen Version des Makropakets verloren oder ändern sich auf rückwärtskompatible Weise. Wenn die neuen Funktionen installiert werden, funktioniert der vorhandene kompilierte Code nicht ordnungsgemäß. Corrolary: Beachten Sie bei der Wartung von Makropaketen, die Runtime-Unterstützung bieten, Code, der möglicherweise nicht neu kompiliert wird und einen Plan für die Aufrechterhaltung der Kompatibilität und die Veralterung enthält.
Konsistenz . Sie haben mehrere Makros mehrmals geändert, aber Sie haben abhängig vom Makro nur einige Funktionen oder Quelldateien neu kompiliert, andere jedoch vernachlässigt. Sie testen also ein "Frankenstein-Monster" -Bild, das Makro-Erweiterungen enthält, die nicht mehr aus dem Quellcode wiederhergestellt werden können. Und jede Prüfung, die du tust, ist nur für dieses Bild gültig. Wenn etwas kaputt geht, könnte das an der Inkonsistenz liegen, und Sie verschwenden Zeit damit, nicht existierende Fehler zu verfolgen. Oder umgekehrt: Etwas funktioniert gut, aber nur aufgrund der Kombination von altem und neuem Code. Sie möchten alles von Grund auf neu erstellen, so dass Sie eine gut definierte Basis für das Testen der Software oder das Verpacken einer Version haben.
Schnittstellenänderung . Die Syntax des Makros hat sich geändert, daher muss der Code aktualisiert werden, um das neue Makro zu verwenden. Während es möglich ist, dass der alte Binärcode, der mit dem alten Makro erweitert wurde, weiterhin verwendet werden kann, haben Sie die Situation, dass Binärdateien laufen, die in Bezug auf den aktualisierten Quellcode veraltet sind (bringt uns zum vorherigen Konsistenzpunkt zurück) ).
Wenn keine dieser Bedingungen zutrifft, können wir es uns erlauben, bei der Neukompilierung von Code, der von Makros abhängt, faul zu sein.
Tags und Links macros lisp common-lisp