我正在为 R7RS 方案编写一个解释器,以便更全面地了解 Scheme 编程语言。
根据我的理解,如果两个列表参数表示内存中的相同位置,eqv?
必须返回#t
。但是,我不确定列表的cdr
是否必须始终为 eqv:
(define l '(a b c))
(eqv? (cdr l) (cdr l)) ; #t of #f?
我所知道的缺失部分是特定列表的cdr
是否必须始终指向特定位置。对于特定列表,cdr
每次在列表中调用时都必须始终返回相同的子列表,还是可以返回一个全新的子列表?
(我知道我可以使用现有的方案解释器经验地测试这一点,但我主要对标准规定的内容感兴趣)。
eq?
是指针相等(符号、布尔值、空列表)eqv?
对于eq?
和相同基元值(数字、字符)的所有内容#t
equal?
对于eqv?
的所有内容和看起来相同的值都#t
cdr
是访问器。(cdr l)
将返回相同的指针,因此(eq? (cdr l) (cdr l)) ; ==> #t
eqv?
和equal?
,因为它们在较低级别的相等谓词时保证#t
。
请注意,这不是相反的方式。(equal? "test" "test"); ==> #t
但(eqv? "test" "test")
可以是#f
的,也可以是#t
的。不同行为的原因是,如果在读取代码时重用常量数据而不是创建新的数据。
通常在指针中存储基元值。例如。在 64 位机器上,最后 3 位始终为 0,因为我们访问的是对齐的单词。方案实现通常然后编码 0-7 来指示类型,通常当它为 0 时,其余位根本不是位置,而是嵌入在指针中的数字。这样,您可以拥有一个使用 6 个单词的列表(1 2 3)
。3 对,每对 2 个字,但当数字适合 61 位大小时,没有用于数字的内存。这就是为什么数字和字符经常eq?
,而在报告中没有保证。