17

既然 Common Lisp 的函数参数按从左到右的顺序计算,为什么不使用普通函数:

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

而不是特殊形式?

4

2 回答 2

27

还有另一个功能是PROGN您无法使用的:

想象一下 Common Lisp 代码文件中的这段代码:

(progn
  (defmacro foo () ))

对比

(my-progn
  (defmacro foo () ))

使用PROGN编译器会将DEFMACRO表单视为顶级表单。这意味着例如编译器会注意到有一个宏定义并使其在编译时环境中可用。

使用 function MY-PROGN,编译器将无法识别DEFMACRO表单,因为它不在顶层。

于 2013-06-17T07:36:11.810 回答
24

progn返回它评估的最后一个形式的所有值,您的函数只返回第一个:

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

(Rainer 首先提到)的另一个关键特性progn是它保持其所有形式的顶层,这使得宏可以扩展到多种形式(例如,参见我对““返回的值是未使用的”警告时字节时的回答- 编译宏”)。

于 2013-06-16T22:03:01.583 回答