cond 的递归示例 ¶前面介绍的 triangle-recursively 版本是使用 if 特殊形式编写的。它也可以使用另一种名为 cond 的特殊形式来实现。特殊形式 cond 的名称是单词 ‘conditional’(条件)的缩写。
尽管 cond 特殊形式在 Emacs Lisp 源码中不像 if 那样常用,但其使用频率也足以值得对其进行讲解。
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 表达式求值时,它会依次对 cond 主体内一系列表达式中的第一个表达式的第一个元素(CAR,即真假测试表达式)进行求值。
如果真假测试返回 nil,则该表达式的其余部分(结果表达式)会被跳过,转而对下一个表达式的真假测试进行求值。当找到某个表达式的真假测试返回非 nil 值时,该表达式的结果部分会被求值。结果部分可以是一个或多个表达式。如果结果部分包含多个表达式,这些表达式会按顺序求值,并返回最后一个表达式的值。如果该表达式没有结果部分,则返回真假测试本身的值。
如果所有真假测试均不成立,则 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)))。