2013-06-16 6 views
16

Da Common Lisp die Funktionsargumente bewerten in von links nach rechts um, warum nicht eine normale Funktion verwenden würden:Common Lisp: Warum ist die Prognose eine spezielle Form?

(defun progn2 (&rest body) 
    (first (last body))) 

statt besondere Form?

+1

Enthält 'defun 'nicht bereits eine implizite' progn'? Überprüfen Sie die Makro-Erweiterung von 'defun'. – tuscland

+5

Die Antworten von @ sds und @ RainerJoswig sind wichtige Punkte. Die 'values' in der Antwort von @sds sind etwas, das Sie ab und zu auffangen können, und das Verhalten, das @RainerJoswig beschreibt, ist sehr wichtig, besonders wenn Sie anfangen, makrobasierte Formulare der obersten Ebene in Ihre Quelle zu schreiben; Wenn diese mehr produzieren als die Form, die als Top-Level behandelt werden soll, dann braucht man "Prognose". –

Antwort

24

Es gibt auch ein weiteres Merkmal von PROGN, die Sie nicht mit einer Funktion erhalten können:

Stellen Sie sich vor diesen Code in einer Datei von Common Lisp Code:

(progn 
    (defmacro foo())) 

gegen

(my-progn 
    (defmacro foo())) 

Mit PROGN behandelt der Compiler das Formular DEFMACRO als Formular der obersten Ebene. Das bedeutet zum Beispiel, dass der Compiler bemerkt, dass es eine Makrodefinition gibt und sie in der Kompilierzeitumgebung verfügbar macht.

Mit einer Funktion MY-PROGN erkennt der Compiler das Formular DEFMACRO nicht, da es nicht auf oberster Ebene ist.

+3

Was "Top-Level-Form" bedeutet? – 1ambda

22

progn liefert alle Werte der letzten Form es, Ihre Funktion gibt nur die erste auswertet: wird

(progn (values 1 2 3)) 
=> 1, 2, 3 
(progn2 (values 1 2 3)) 
=> 1 

Ein weiteres wichtiges Merkmal von progn (erwähnt von Rainer ersten), dass es all seine Formen hält top-level , die es ermöglicht, dass Makros auf multiple Formulare erweitert werden (siehe z. B. meine Antwort auf "“value returned is unused” warning when byte-compiling a macro").