2.8 阅读 Lisp (Reading Lisp)

上一节我们所定义的 our-member 以五个括号结尾。更复杂的函数定义更可能以七、八个括号结尾。刚学 Lisp 的人看到这么多括号会感到气馁。这叫人怎么读这样的程序,更不用说编了?怎么知道哪个括号该跟哪个匹配?

答案是,你不需要这么做。 Lisp 程序员用缩排来阅读及编写程序,而不是括号。当他们在写程序时,他们让文字编辑器显示哪个括号该与哪个匹配。任何好的文字编辑器,特别是 Lisp 系统自带的,都应该能做到括号匹配(paren-matching)。在这种编辑器中,当你输入一个括号时,编辑器指出与其匹配的那一个。如果你的编辑器不能匹配括号,别用了,想想如何让它做到,因为没有这个功能,你根本不可能编 Lisp 程序 [1]

有了好的编辑器之后,括号匹配不再会是问题。而且由于 Lisp 缩排有通用的惯例,阅读程序也不是个问题。因为所有人都使用一样的习惯,你可以忽略那些括号,通过缩排来阅读程序。

任何有经验的 Lisp 黑客,会发现如果是这样的 our-member 的定义很难阅读:

  1. (defun our-member (obj lst) (if (null lst) nil (if
  2. (eql (car lst) obj) lst (our-member obj (cdr lst)))))

但如果程序适当地缩排时,他就没有问题了。可以忽略大部分的括号而仍能读懂它:

  1. defun our-member (obj lst)
  2. if null lst
  3. nil
  4. if eql (car lst) obj
  5. lst
  6. our-member obj (cdr lst)

事实上,这是你在纸上写 Lisp 程序的实用方法。等输入程序至计算机的时候,可以利用编辑器匹配括号的功能。