Common Lisp: Why progn is a special form?

2019-02-11 20:36发布

问题:

Since Common Lisp's function arguments evaluate in left-to-right order, why wouldn't use an ordinary function:

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

instead of special form?

回答1:

There is also another feature of PROGN which you can't get with a function:

Imagine this code in a file of Common Lisp code:

(progn
  (defmacro foo () ))

vs.

(my-progn
  (defmacro foo () ))

With using PROGN the compiler will treat the DEFMACRO form as a top-level form. That means for example that the compiler notes that there is a macro definition and makes it available in the compile-time environment.

Using a function MY-PROGN, the compiler won't recognize the DEFMACRO form, because it is not at top-level.



回答2:

progn returns all the values of the last form it evaluates, your function returns just the first one:

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

Another critical feature of progn (mentioned by Rainer first) is that it keeps all its forms top-level, which makes it possible for macros to expand to multiple forms (see, e.g., my answer to "“value returned is unused” warning when byte-compiling a macro").



标签: common-lisp