Scheme 为什么不';这两个不相等吗?

Scheme 为什么不';这两个不相等吗?,scheme,racket,Scheme,Racket,我正在准备考试,我注意到这个问题: Define an object x so that (eq? (car x) (cdr x)) returns #t 我最初认为这会很简单cdr x是一个列表,而car x是一个元素,所以我猜x中的第一个元素应该是一个与x的尾部相等的列表。所以我想到了 (define x (list (list 1) 1)) 在DrRacket中调用car x会导致(列表1),而cdr x也是如此,但当我尝试调用(eq?(car x)(cdr x))时,结果是#f 我到

我正在准备考试,我注意到这个问题:

Define an object x so that (eq? (car x) (cdr x)) returns #t
我最初认为这会很简单
cdr x
是一个列表,而
car x
是一个元素,所以我猜x中的第一个元素应该是一个与x的尾部相等的列表。所以我想到了

(define x (list (list 1) 1))
在DrRacket中调用
car x
会导致
(列表1)
,而
cdr x
也是如此,但当我尝试调用
(eq?(car x)(cdr x))
时,结果是#f


我到底错过了什么?正确答案是什么?

以您使用
(列表1)
的示例为例:

(定义x
(让([尾部(列表1)])
(反对)(反对)
更简单的例子是:

(定义x'(());同:(定义x(cons(list)(list)))
这取决于只有一个空列表对象的事实(即,
(eq?(list 1)(list 1))
始终为false,
(eq?(list)(list))
始终为true)


在一个相关的注释中(尽管就您的测试而言有些过头),您是否知道您还可以制作一个对象
x
,以便
(car x)
(cdr x)
引用与
x
相同的对象

(定义x(使用输入字符串“#0=(#0#.#0#)”读取调用))

:-p

我们可以得到的
汽车和
cdr
不是一个列表。这是一双

使用
cons
创建对,例如:

(定义val(列表1))
(定义val对(cons val val))
(list(list 1)1)
(cons(list 1)(list 1))
相当,其中
list
被调用两次,每次都在内存中返回一个新的、单独的对象,尽管值相等。但是
eq?
仅对同一内存对象返回true

因此,虽然您的想法是合理的,从价值角度来看,这里实际比较的不是价值,而是相同性,就像内存对象的“指针相等性”一样。

问题是为什么

(define x (list (list 1) 1))
(eq? (car x) (cdr x))
给出结果
#f

首先,让我们使用
cons
而不是
list

(list 1)    is the same as  (cons 1 '())
(list a b)  is the same as  (cons a (cons b '())
你的例子变成:

(define x (cons (cons 1 '()) 
                (cons 1 '()))
(eq? (car x) (cdr x))
因为上面有两次表达式
(cons1'())
,所以让我们添加一个索引(这样我们就可以引用表达式了)

(define x (cons (cons_1 1 '()) 
                (cons_2 1 '()))
(eq? (car x) (cdr x))
这表明

(car x) returns the result of (cons_1 1 '())
(cdr x) returns the result of (cons_2 1 '())
调用
(cons A b)
将在内存中分配一个小数据结构,该结构(大致)如下所示:

<tag-for-pairs>  <pointer-to-the-value-a> <pointer-to-the-value-b>

这意味着调用
(cons_1’())
(cons_2 1’())
将分配两对,每对在内存中都有自己的位置(地址)

调用
(eq?x y)
只会比较两个对象
x
y
的位置(地址)。这意味着即使两对对象的内容相等,比较
(eq?(cons_1’())(cons_2 1’())将返回false。

(eq?(列表1)(列表1))=>f