2017-06-10 2 views
0

Dies ist ein Zitat zum Thema "Kompilierung und Makroexpansion", aus dem Buch Common Lisp: A gentle introduction to symbolic computation.Kompilierung und Makros

(defmacro bad-announce-macro() 
(format t "~%Hi mom!")) 
(defun say-hi() 
(bad-announce-macro)) 
> (compile 'say-hi) 
Hi, mom! 
SAY-HI 
> (say-hi) 
NIL 

Im obigen Beispiel wurde das Makro als Teil des von Kompilieren SAY-HI Prozesses erweitert. Also der Compiler sagte ‘‘Hi, mom!’’ Das Ergebnis der Makro war NIL, so dass was in den Körper von SAY-HI kompiliert wurde. Wenn wir die kompilierte SAY-HI Funktion aufrufen, sagt das nichts, weil das Makro durch seine Erweiterung ersetzt wurde.


In diesem Zitat sagt der Autor, dass

das Makro mit der Expansion

Gute

ersetzt wurde, so sollte es nicht atleast zeigt die gedruckte "Hi mom!"? Denn obwohl das Makro nichts zurückgibt, wird es trotzdem durch etwas ersetzt (es ist Expansion). Basierend auf dem Code stellte ich die Hypothese auf, dass
, wenn eine Funktion aufgerufen wird, nachdem es kompiliert wurde, alle Makros, die in seinem Körper aufgerufen werden, in das Ergebnis, das sie zurückgeben, nicht in was auch immer sie in ihren eigenen Körpern haben .

Ich bin mir nicht sicher, ob das richtig ist. Und der Grund dafür ist auch nicht klar.

+1

Die Erweiterung eines Makros ist der Rückgabewert des Makros. Da das Makro "NIL" zurückgibt, ist seine Erweiterung "NIL", und das ist, wodurch es in der "SAY-HI" -Funktion ersetzt wird. – jkiiski

+0

@jkiiski: Aber warum druckt die Funktion '' Hallo Mama! '' Bis sie nicht kompiliert wird? – Mooncrater

+1

Das Makro wird erweitert, wenn der Code kompiliert wird (die Nebenwirkungen des Makros treten während der Erweiterung auf). Bis dahin wird der Code interpretiert (und das Makro wird im laufenden Betrieb erweitert, wenn die Funktion aufgerufen wird), unabhängig davon, welche Implementierung Sie verwenden. – jkiiski

Antwort

2

Wie oft ein Makro erweitert wird, ist nicht angegeben.

Ausgelegt Lisp in LispWorks:

CL-USER 49 > (say-hi) 

Hi mom! 
Hi mom! 
NIL 

Die Makroerweiterung wird hier zweimal zur Laufzeit erfolgt.

Im kompilierten Code erwarten wir, dass keine Makroerweiterung zur Laufzeit erforderlich ist. So in Ihrem Beispiel nichts wird gedruckt, da Ihre generierten Code tut nichts:

CL-USER 50 > (compile 'say-hi) 

Hi mom! 
SAY-HI 
NIL 
NIL 

CL-USER 51 > (say-hi) 
NIL 

Die Makroerweiterung ist NIL.

CL-USER 52 > (macroexpand '(bad-announce-macro)) 

Hi mom! 
NIL  ; <- the macro expansion 
T