1.1.1 Lisp 原子

在 Lisp 中,我们一直称作单词的东西,正式名称是原子(atom)。 该术语源自 atom 一词的本义:“不可分割(indivisible)”。 在 Lisp 看来,列表中使用的这些单词无法再拆分成更小的部分并保持原有程序含义; 数字以及 ‘+’ 这类单字符符号同样如此。 与之相对,和古代原子观念不同,列表是可以拆分的。 (See car cdr & cons 基础函数。)

在列表中,原子之间由空白符分隔,它们可以紧邻括号。

严格来说,Lisp 中的列表由括号包裹,内部可以是: 由空白符分隔的原子、其他列表,或二者兼有。 列表可以只包含一个原子,也可以完全为空。 不包含任何内容的列表写作:(),称为空列表(empty list)。 与其他对象不同,空列表同时被视为原子和列表。

原子和列表的文本表示形式统称为符号表达式(symbolic expression), 更简洁的说法是S-表达式。 单独使用的表达式(expression)一词, 既可以指其文本形式,也可以指计算机内存中的原子或列表本身。 人们通常并不严格区分这两种含义。 (此外,许多文档中也用形式(form)作为表达式的同义词。)

顺带一提,构成我们宇宙的原子当初被命名时,人们以为它们不可分割; 但后来发现物理原子并非不可拆分, 既可以从原子中剥离出部分,也可以将其裂变为大小大致相等的两部分。 物理原子的命名在人们认识其真实本质之前就过早确定了。 在 Lisp 中,某些类型的原子(例如数组)也可以拆分成部分, 但拆分机制与列表不同。 就列表操作而言,列表中的原子是不可分割的。

和英语类似,构成 Lisp 原子的单个字母的含义, 与字母组合成单词后的含义完全不同。 例如,表示南美树懒的单词 ‘ai’, 含义与两个独立单词 ‘a’ 和 ‘i’ 完全无关。

自然界中的原子种类繁多,但 Lisp 中的原子只有少数几类: 例如数字(numbers),如 37、511、1729; 以及符号(symbols),如 ‘+’、‘foo’、‘forward-line’。 前面示例中列出的单词都是符号。 在日常 Lisp 交流中,“原子(atom)”一词并不常用, 因为程序员通常会更精确地说明原子类型。 Lisp 编程主要处理列表中的符号(有时是数字)。 (顺便一提,前面这句括号内的说明是一个合法的 Lisp 列表, 因为它由原子(此处为符号)构成,以空白符分隔并被括号包裹,不含非 Lisp 标点。)

双引号之间的文本 — 即使是句子或段落 — 同样属于原子。示例如下:

'(this list includes "text between quotation marks.")

在 Lisp 中,这段带引号的文本连同标点和空格整体构成一个原子。 这类原子称为字符串(string),即 “字符序列(string of characters)”, 常用于计算机向人类输出可读信息。 字符串是与数字、符号不同的原子类型,用途也不一样。