因为IF(<- HyperSpec 链接)的语法定义为:
if test-form then-form [else-form] => result*
没有开始或结束标记。有一个 THEN-FORM 而不是 THEN-FORM*。PROGN 是一种定义表单序列的机制,其中表单从左到右执行并返回最后一个表单的值。
它可以这样定义:
my-if test-form (then-form*) [(else-form*)] => result*
(defmacro my-if (test then &optional else)
(assert (and (listp then) (listp else)) (then else))
`(if ,test (progn ,@then) (progn ,@else)))
(my-if (> (random 10) 5)
((print "high")
:high)
((print "low")
:low))
好吧,已经有一个支持多种形式的构造:COND。
(cond ((> (random 10) 5)
(print "high")
:high)
(t
(print "low")
:low))
典型的风格是在必须尝试多个替代方案并且有多个 then/else-forms 时使用 COND。当只有一个测试并且同时存在 then 和 else 形式时,使用 IF。对于其他情况,有 WHEN 和 UNLESS。WHEN 和 UNLESS 仅支持一种或 THEN 形式(不支持 else 形式)。
我想最好有至少一个条件形式(在这种情况下是 IF )没有额外的括号层。写作
(if (> (random 10) 5)
(progn
(print "high")
:high)
(progn
(print "low")
:low))
然后是要付出很小的代价。要么编写额外的 PROGN,要么切换到 COND 变体。如果您的代码真的可以从具有多个 then 和 else 形式的 IF 中受益,那么只需编写该宏(见上文)。Lisp 拥有它,因此您可以成为自己的语言设计师。考虑引入宏很重要:我的宏是否正确?它检查错误吗?这值得么?它可读(对其他人?)?