列表不是atom,这是这里的重要部分。符号虽然是原子,但这意味着当它们相同时,它们驻留在同一内存中,它们就像数字一样,确实可以看作是指针。符号也不是可变的,符号foo
就像一个数字3
。
然而,列表不是原子,两个列表或字符串具有相同内容的向量可以很好地驻留在内存的两个不同位置。
eq?
仅对内存位置进行测试。eqv?
等效测试,那是模糊的,它取决于哪个实现,Scheme标准对此相当自由,它只说它必须至少是eq?
基本的超集。equal?
另一方面,对结构相等性进行测试并递归执行,因此这是一个非常昂贵的操作,这就是为什么符号通常比字符串更适合标识符。
(define l1 (list 1 2 3))
(define l2 (list 1 2 3))
(eq? l1 l2) ; ===> #f in most implementations
(equal? l1 l2) ; ===> #t in all implementations
(eqv? l1 l2) ; ===> #t in some implementations
(define l3 (cdr l1))
(define l4 (cdr l1))
(eq? l3 l4) ; ===> #t, this means that they 'share memory', if you change l3 or l4, l1 will change with it, beware. This is how car and cdr work, they do not copy.
(define l6 (cons 1 l4));
(eq? l1 l6) ; ===> #f again, cons does allocate new memory, but the tails may very well share it, s in this case, l6 does share its tail with all lists except l2 here in memory.
另外,有点术语, cons 创建一个对,这与两个元素的列表不同,它创建一个对(a . b)
,该列表(a b)
实际上与该对相同(a . (b . ()))
此外, cons 和 car 和 cdr 是原语,您在下面看到的实现是计算机程序的结构和实现中的演示,表明它们并不是严格需要的,但是将它们作为原语会显着提高性能,所以最好不要重新定义你的缺点、汽车和 cdrs。