【问题标题】:Common Lisp: Why progn is a special form?Common Lisp:为什么 progn 是一种特殊形式?
【发布时间】:2013-06-12 19:37:52
【问题描述】:

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

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

而不是特殊形式?

【问题讨论】:

  • defun 不是已经包含隐含的progn 了吗?检查defun的宏扩展。
  • @sds 和 @RainerJoswig 的回答都很重要。 @sds 的答案中的 values 是您偶尔会发现的东西,@RainerJoswig 描述的行为非常重要,尤其是当您开始将基于宏的顶级表单放入源代码时;如果这些生成的表单超出了应被视为顶级的表单,那么您需要progn。

标签: common-lisp


【解决方案1】:

PROGN 还有一个功能是你无法通过函数获得的:

想象一下这个代码在一个 Common Lisp 代码文件中:

(progn
  (defmacro foo () ))

对比

(my-progn
  (defmacro foo () ))

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

使用函数MY-PROGN,编译器将无法识别DEFMACRO 形式,因为它不在顶层。

【讨论】:

  • top-level-form 是什么意思?
【解决方案2】:

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"的回答)。

【讨论】:

    猜你喜欢
    • 2016-02-01
    • 2015-07-03
    • 1970-01-01
    • 1970-01-01
    • 2015-03-14
    • 2019-01-18
    • 2015-09-06
    • 2015-04-04
    • 2019-12-24
    相关资源
    最近更新 更多