LISP是LISt Processing的缩写, 这显然暗示了LISP必然包含许多和列表有关的函数, 让我们现在就来检视一些.
最简单的函数大概就是length (尽管一个实际的实现里的length并不会那么简单, 因为它还要考虑"环路"的情况), 它大概可以定义如下.
以下是一些例子.
另外一个很简单的函数是list-ref, 它取出列表某个位置的元素, 以下是一种可能的定义.
然后是一些例子.
现在让我们来引入memq, memv和member, 但首先我们应该讨论一下谓词eq?, eqv?和equal?.
eq?, eqv?和equal?是Scheme中三种不同的判断相等性的谓词. 现在因为读者对于Scheme的理解还不够深入, 即便直截了当地讨论它们的区别, 或许也是没有益处的. 但读者可以这么区分它们, equal?是外延等价的近似物, eq?是内涵等价的近似物, eqv?是用来补充eq?的, 也是内涵等价的近似物. 比如, 请看以下例子.
之所以会出现这样的情况, 是因为每次cons创建的都是"不同"的序对对象.
就此打住.
memq, memv和member仅仅是所用相等谓词不同而已, 其余都是一样的.
一种可能的memq定义如下.
它可以用来判断一个元素是否在列表中, 以下是一些例子.
正如名字所暗示的那样, memq用eq?比较相等, memv用eqv?, member用equal?.
接着, 让我们来看assq, assv和assoc.
在Scheme上下文中, 元素均为序对的列表被称为关联表 (association list), 它可以用来表示对应关系 (的外延).
以下是assq的一种可能定义.
注记.
这也可以类推到c和r之间隔着3个4个a或d的情况. 但是更多, Scheme标准就不保证了.
接下来是一些例子.
也就是说, assq可以根据每个序对的car部分 (一般被称为键) 进行索引.
练习. 编写过程assp, 它接受一个谓词和一个关联表, 然后返回第一个"键满足谓词"的序对, 如果这样的序对不存在, 就返回#f. 以下是一些例子.
symbol?判断一个对象是否是符号, 类似的还有number?, pair?, procedure?等.