Common lisp:prog2 的 return 值是多少?
Common lisp: what is the return value of prog2?
人们会期望 prog2
不同于 prog1
和 progn
在 return 评估 第二个 的结果表达式分别代替 first 和 last。
然而,HyperSpec 说了一些不同的东西(强调我的):
prog2 evaluates first-form, then second-form, and then forms, yielding as its only value the primary value yielded by first-form.
这意味着 prog2
会 return 与 prog1
一样(并且实际上表现得很好)!
有趣的是,HyperSpec 中的示例证实了 预期的 而不是 指定的 行为:
(setq temp 1) => 1
(prog2 (incf temp) (incf temp) (incf temp)) => 3
temp => 4
(prog2 1 (values 2 3 4) 5) => 2
这是标准中的错字还是我漏掉了更深层次的东西?
这似乎是 known issue with the ANSI standard (the full list can be found on CLiki).
我已经用 SBCL 2.0.1 和最新版本的 Allegro 对其进行了测试,在这两种情况下它的行为都符合预期(而不是指定的):
CL-USER> (prog2
(print "1st")
(print "2nd")
(print "3rd"))
"1st"
"2nd"
"3rd"
"2nd"
想想看,连缩进都这么暗示。
感兴趣的话,我可以将以下代码输入到 Portacle (Emacs / SLIME / SBCL) 中:
(prog2
(print "1st")
(print "2nd")
(print "3rd"))
我将光标放在 prog2
上,并使用了键序列 M-.
。这显示了 SBCL 实际在做什么。
(sb-xc:defmacro prog2 (form1 result &body body)
`(prog1 (progn ,form1 ,result) ,@body))
所以 SBCL 是对提供的表格进行模式匹配。第一个参数是形式form1
,第二个参数是形式result
,其他的都是body
。函数 progn
returns 在评估 form1
时形式 result
的值,并且 prog1
在评估 body
.[=22 时也会选择该值=]
结论 - 它正在做明智的事情,而不是 Hyperspec 所说的。
人们会期望 prog2
不同于 prog1
和 progn
在 return 评估 第二个 的结果表达式分别代替 first 和 last。
然而,HyperSpec 说了一些不同的东西(强调我的):
prog2 evaluates first-form, then second-form, and then forms, yielding as its only value the primary value yielded by first-form.
这意味着 prog2
会 return 与 prog1
一样(并且实际上表现得很好)!
有趣的是,HyperSpec 中的示例证实了 预期的 而不是 指定的 行为:
(setq temp 1) => 1 (prog2 (incf temp) (incf temp) (incf temp)) => 3 temp => 4 (prog2 1 (values 2 3 4) 5) => 2
这是标准中的错字还是我漏掉了更深层次的东西?
这似乎是 known issue with the ANSI standard (the full list can be found on CLiki).
我已经用 SBCL 2.0.1 和最新版本的 Allegro 对其进行了测试,在这两种情况下它的行为都符合预期(而不是指定的):
CL-USER> (prog2
(print "1st")
(print "2nd")
(print "3rd"))
"1st"
"2nd"
"3rd"
"2nd"
想想看,连缩进都这么暗示。
感兴趣的话,我可以将以下代码输入到 Portacle (Emacs / SLIME / SBCL) 中:
(prog2
(print "1st")
(print "2nd")
(print "3rd"))
我将光标放在 prog2
上,并使用了键序列 M-.
。这显示了 SBCL 实际在做什么。
(sb-xc:defmacro prog2 (form1 result &body body)
`(prog1 (progn ,form1 ,result) ,@body))
所以 SBCL 是对提供的表格进行模式匹配。第一个参数是形式form1
,第二个参数是形式result
,其他的都是body
。函数 progn
returns 在评估 form1
时形式 result
的值,并且 prog1
在评估 body
.[=22 时也会选择该值=]
结论 - 它正在做明智的事情,而不是 Hyperspec 所说的。