cons cell(Cons 单元) 是包含两个存储位的对象,分别称为 CAR 位和 CDR 位。每个位都可以存放任意 Lisp 对象。我们也将这个 Cons 单元的 CAR 位当前存放的对象称为它的 CAR,CDR 位同理。
list列表 是由一系列 Cons 单元串联而成的结构:每个 Cons 单元的 CDR 位,要么存放着下一个 Cons 单元,要么存放着空列表。空列表实际上就是符号 nil。详细,See 列表。由于绝大多数 Cons 单元都用作列表的一部分,我们把由 Cons 单元构成的任何结构统称为 list structure列表结构。
给 C 程序员的说明:Lisp 列表相当于由 Cons 单元构成的 linked list链表。因为 Lisp 中的指针是隐式的,我们不区分 Cons 单元位中是 “存放值” 还是 “指向值”。
因为 Cons 单元在 Lisp 中如此核心,我们也给不是 Cons 单元的对象起了一个名字:这类对象称为 atoms原子。
列表的读取语法与打印表示完全一致:由左圆括号、任意数量的元素、右圆括号组成。以下是列表示例:
(A 2 "A") ; 包含三个元素的列表 () ; 不含元素的列表(空列表) nil ; 不含元素的列表(空列表) ("A ()") ; 只有一个元素的列表:字符串"A ()"(A ()) ; 包含两个元素的列表:A和空列表 (A nil) ; 与上一行等价 ((A B C)) ; 只有一个元素的列表 ; (该元素本身是一个含三个元素的列表)。
在读取时,括号内的每个对象都会成为列表的一个元素。也就是说,每个元素都会生成一个 Cons 单元。该 Cons 单元的 CAR 位存放元素本身、CDR 位指向列表中的下一个 Cons 单元。最后一个 Cons 单元的 CDR 位被设为 nil
CAR 与 CDR 这两个名称来源于 Lisp 历史。最早的 Lisp 运行在 IBM 704 计算机上,该机将字分为地址部分(address)和减量部分(decrement);CAR 是提取寄存器地址部分内容的指令,CDR 是提取寄存器减量部分内容的指令。与之相对,Cons 单元因创建它们的函数 cons 而得名,而 cons 取自其用途:构造(construction)单元。