由于Common Lisp的函数参数按从左到右的顺序进行求值,为什么不使用普通函数:
(defun progn2 (&rest body)
(first (last body)))
而不是特殊形式?
答案 0 :(得分:26)
还有PROGN
的另一个功能,您无法使用该功能:
想象一下Common Lisp代码文件中的这段代码:
(progn
(defmacro foo () ))
VS
(my-progn
(defmacro foo () ))
使用PROGN
编译器会将DEFMACRO
表单视为顶级表单。这意味着例如编译器注意到存在宏定义并使其在编译时环境中可用。
使用函数MY-PROGN
,编译器将无法识别DEFMACRO
表单,因为它不在顶层。
答案 1 :(得分:23)
progn
返回它评估的最后一个表单的所有值,你的函数只返回第一个:
(progn (values 1 2 3))
=> 1, 2, 3
(progn2 (values 1 2 3))
=> 1
progn
的另一个关键特性(Rainer首先提到)是它保留了所有形式top-level,这使得宏可以扩展为多个形式(请参阅,例如,我对"“value returned is unused” warning when byte-compiling a macro"的回答。