Gibt es einen Vorteil für dieses Makro?

8

Ich lese Practical Common Lisp von Peter Seibel. In Kapitel 9 führt er den Leser durch die Erstellung eines Unit Testing Rahmen, und er enthält das folgende Makro, um festzustellen, ob eine Liste nur aus wahren Ausdrücken besteht:

%Vor%

Ich bin mir nicht sicher, was der Vorteil eines Makros ist, aber es scheint, dass das Folgende klarer und effizienter für dynamische Werte wäre:

%Vor%

Hat das Makro den Vorteil, dass es zur Laufzeit für alle Aufrufe, die zur Kompilierungszeit erweitert werden, effizienter ist? Oder ist es eine Paradigma Sache? Oder versucht das Buch nur Ausreden zu geben, um verschiedene Muster in Makros zu üben?

    
testclcl 27.01.2016, 05:23
quelle

2 Antworten

7

Ihre Beobachtung ist grundsätzlich richtig; und in der Tat kann deine Funktion einfach sein:

%Vor%

Da das Makro alle Argumente von links nach rechts bedingungslos auswertet und T liefert, wenn sie alle wahr sind, ist es im Grunde nur eine Inline-Optimierung, die von einer Funktion ausgeführt werden kann. Funktionen können angefordert werden, um mit (declaim 'inline ...) eingezeichnet zu werden. Außerdem können wir mit define-compiler-macro trotzdem ein Compiler-Makro für die Funktion schreiben. Mit diesem Makro können wir die Erweiterung erzeugen, und haben dies als eine Funktion, die wir apply und sonst indirekt auf.

können

Andere Möglichkeiten, das Ergebnis in der Funktion zu berechnen:

%Vor%

Das Beispiel sieht wie eine Makroübung aus: Erstellen eines Gensyms und Generieren von Code mit loop . Außerdem ist das Makro der Ausgangspunkt für etwas, das in einem Unit-Test-Framework erscheinen könnte.

    
Kaz 27.01.2016, 05:52
quelle
9

In diesem Fall spielt es keine Rolle, aber für zukünftige Versionen könnte es sinnvoller sein, ein Makro zu verwenden. Macht es Sinn, ein Makro zu verwenden? Abhängig vom Anwendungsfall:

Verwenden einer Funktion

%Vor%

Beachten Sie, dass Lisp zur Laufzeit sieht, dass combine-results eine Funktion ist. Es wertet dann die Argumente aus. Dann ruft er die Funktion combine-results mit den Ergebniswerten auf. Diese Bewertungsregel ist fest in Common Lisp codiert.

Das bedeutet: Der Code der Funktion wird ausgeführt, nachdem die Argumente ausgewertet wurden.

Verwenden eines Makros

%Vor%

Da Lisp erkennt, dass es sich um ein Makro handelt, ruft es das Makro bei Makroerweiterungszeit auf und generiert Code. Was der generierte Code ist, hängt vollständig vom Makro ab. Was dies erlaubt, ist, Code wie folgt zu generieren:

%Vor%

Dieser Code wird dann ausgeführt. So könnten Sie beispielsweise Systemvariablen einrichten, Fehlerhandler bereitstellen, eine Berichtsmaschine einrichten usw. Jedes einzelne Formular könnte dann auch in eine andere Form eingebettet werden. Und nachdem die Funktionen ausgeführt wurden, könnte man etwas bereinigen, Berichte erstellen usw. prepare-an-environment und embed-it wären Makros oder spezielle Operatoren , die sicherstellen, dass ein bestimmter Code vor , um und nach den eingebetteten Formularen, die wir zur Verfügung gestellt haben.

Wir würden Code ausführen vor , um und nach die bereitgestellten Formulare. Ist das nützlich? Es könnte sein. Es könnte für ein umfangreicheres Test-Framework nützlich sein.

Wenn Ihnen das bekannt vorkommt, dann würden Sie sehen, dass man mit CLOS-Methoden (primär, vor, nach, herum) eine ähnliche Code-Struktur bekommen kann. Die Tests würden in einer primären Methode ausgeführt und der andere Code würde als um , vor und nach Methoden ausgeführt werden.

Beachten Sie, dass ein Makro auch drucken kann (siehe den Kommentar von Hans23), überprüfen und / oder ändern Sie die bereitgestellten Formulare.

    
Rainer Joswig 27.01.2016 10:03
quelle