玩具总动员
这是个原子吗?
是的。
因为字符串(字母、数字、字符、以字母或特殊字符)是原子。
这是个列表吗?
是的。
因为这是用括号把一个原子括起来的。
因为这是用括号把一个原子集合括起来的。
因为这时候两个S-表达式用括号括起来的。
不是。
因为第一个S-表达式是列表,包含两个原子,第二个S-表达式是一个原子。
这是个S-表达式吗?
是的。
因为所有原子都是S-表达式。
因为所有列表也是S-表达式。
因为用括号括起来的也是S-表达式。
空列表
既是列表,也是S-表达式。
问题:空列表是不是原子?
它括号内有0个S-表达式。
总结:不使用
Cons
单元的数据结构称为原子。
数字,字符,字符串,向量和空表’( )都是原子。’( )既是原子,又是表。
Scheme 五法
car 之法则,基本元件 car 仅定义为针对非空列表
car
取,非空列表的第一个S-表达式
cdr
取,非空列表剩下的S-表达式
注:不能请求原子、空列表的cdr
cdr 之法则,基本元件 cdr 仅定义为针对非空列表,任意非空列表的 cdr 总是另一个列表。
参考上述cdr
cons 之法则,基本元件 cons 需要两个参数。第二个参数必须是一个列表。结果是一个列表。
因为 cons
添加原子到列表的开头处
因为 cons
添加任意的S-表达式到列表开头处
cons
有两个参数
- 第一个参数是任意S-表达式
- 第二个参数是任意列表
注:第二个参数必须是列表
另外,(quote( ) )是空列表的记法。
所有的记号都会依据
Scheme
的求值规则求值:
所有记号都会从最内层的括号依次向外层括号求值,
且最外层括号返回的值将作为S-表达式的值。
一个被称为引用(quote
)的形式可以用来阻止记号被求值。它是用来将符号或者表原封不动地传递给程序,而不是求值后变成其它的东西。
Null? 之法则,基本元件Null? 仅定义为针对列表
null? 仅仅能针对列表,得到True 或 False
(null? a)
a 是 spaghetti
实际上,除非 a 是空列表,否则对任意a ,(null? a)都是假
注:不能对原子请求null?
。
atom?
只有一个参数。该参数可以是任意S-表达式
S:
(define atom?
(lambda (x)
(and (not (pair? x)) (not (null? x)))))
L:
(defun atom? (x)
(not (listp x)))
例: (atom? (cdr l))
这里 l 是(Harry)
False 因为(cdr l) 空列表,空列表不是原子。
eq? 之法则,基本元件 eq? 需要两个参数。每个参数都必须是一个非数字的原子
问题:真还是假,a1 和 a2 是相同的原子?
在这里,a1 是Harry,a2 是Harry
(eq? a1 a2)
True
注:
实际上,列表也可能作为eq?
的参数,只要两个列表相同。
实际上,某些数字也可能作为eq?
的参数。