cond
进行递归的例子先前描述的 triangle-recursively
版本是用 if
特殊形式编写的。它也可以使用另一种特殊形式称为 cond
来编写。特殊形式 cond
的名称是单词 ‘conditional’ 的缩写。
尽管在 Emacs Lisp 源代码中并不像 if
那样经常使用 cond
特殊形式,但它被足够频繁地使用,以便解释它是有道理的。
cond
表达式的模板如下:
(cond body…)
其中 body 是一系列列表。
更详细地写出来,模板如下:
(cond (first-true-or-false-test first-consequent) (second-true-or-false-test second-consequent) (third-true-or-false-test third-consequent) …)
当 Lisp 解释器评估 cond
表达式时,它评估第一个元素(即第一个表达式中的 CAR 或 true-or-false-test)。
如果 true-or-false-test 返回 nil
,则跳过该表达式的其余部分,即 consequent,并评估下一个表达式的 true-or-false-test。当找到一个表达式,其 true-or-false-test 返回非 nil
的值时,将评估该表达式的 consequent。consequent 可以是一个或多个表达式。如果 consequent 包含多个表达式,则按顺序评估这些表达式,并返回最后一个的值。如果表达式没有 consequent,则返回 true-or-false-test 的值。
如果没有一个 true-or-false-test 测试为真,cond
表达式返回 nil
。
使用 cond
编写的 triangle
函数如下:
(defun triangle-using-cond (number) (cond ((<= number 0) 0) ((= number 1) 1) ((> number 1) (+ number (triangle-using-cond (1- number))))))
在这个例子中,如果数字小于等于 0,则 cond
返回 0;如果数字为 1,则返回 1;如果数字大于 1,则评估 (+
number (triangle-using-cond (1- number)))
。