Common lisp 公共口齿不清:为什么progn是一种特殊形式?
既然Common Lisp的函数参数按从左到右的顺序计算,为什么不使用普通函数:Common lisp 公共口齿不清:为什么progn是一种特殊形式?,common-lisp,Common Lisp,既然Common Lisp的函数参数按从左到右的顺序计算,为什么不使用普通函数: (defun progn2 (&rest body) (first (last body))) 不是特殊形式?返回它计算的最后一个形式的所有值,而是只返回第一个: (progn (values 1 2 3)) => 1, 2, 3 (progn2 (values 1 2 3)) => 1 progn(Rainer首先提到)的另一个关键特性是它保留了所有的形式,这使得宏可以扩展为多
(defun progn2 (&rest body)
(first (last body)))
不是特殊形式?返回它计算的最后一个形式的所有值,而是只返回第一个:
(progn (values 1 2 3))
=> 1, 2, 3
(progn2 (values 1 2 3))
=> 1
progn
(Rainer首先提到)的另一个关键特性是它保留了所有的形式,这使得宏可以扩展为多种形式(例如,请参见我的答案)。还有另一个用函数无法获得的progn
特性:
(defun progn2 (&rest body)
(first (last body)))
想象一下,在一个公共Lisp代码文件中有这样的代码:
(progn
(defmacro foo () ))
vs
使用PROGN
编译器会将DEFMACRO
表单视为顶级表单。例如,这意味着编译器注意到存在宏定义,并使其在编译时环境中可用
使用函数
MY-PROGN
,编译器将无法识别DEFMACRO
表单,因为它不在顶层。是否defun
已经包含隐式PROGN
?检查defun
的宏展开。@sds和@RainerJoswig的答案都很重要。@sds答案中的值
可能会偶尔出现,而@RainerJoswig描述的行为非常重要,尤其是当您开始在源代码中放置基于宏的顶级表单时;如果这些生成的表单多于应被视为顶级的表单,那么您需要progn
。顶级表单的含义是什么?