意料之外的 Nil (Unexpected Nils)

当函数抱怨传入 nil 作为参数时,通常是程序先前出错的徵兆。数个内置操作符返回 nil 来指出失败。但由于 nil 是一个合法的 Lisp 对象,问题可能之后才发生,在程序某部分试着要使用这个信以为真的返回值时。

举例来说,返回一个月有多少天的函数有一个 bug;假设我们忘记十月份了:

  1. (defun month-length (mon)
  2. (case mon
  3. ((jan mar may jul aug dec) 31)
  4. ((apr jun sept nov) 30)
  5. (feb (if (leap-year) 29 28))))

如果有另一个函数,企图想计算出一个月当中有几个礼拜,

  1. (defun month-weeks (mon) (/ (month-length mon) 7.0))

则会发生下面的情形:

  1. > (month-weeks 'oct)
  2. Error: NIL is not a valud argument to /.

问题发生的原因是因为 month-lengthcase 找不到匹配 。当这个情形发生时, case 返回 nil 。然后 month-weeks ,认为获得了一个数字,将值传给 // 就抱怨了。

在这里最起码 bug 与 bug 的临床表现是挨着发生的。这样的 bug 在它们相距很远时很难找到。要避免这个可能性,某些 Lisp 方言让跑完 casecond 又没匹配的情形,产生一个错误。在 Common Lisp 里,在这种情况里可以做的是使用 ecase ,如 14.6 节所描述的。