来自Seasoned Schemer的 pg 150 的以下函数通过改变每个列表的 cdr 然后检查更改是否影响两者来确定两个列表是否具有相同的身份(即占用相同的内存):
(define same?
(lambda (c1 c2)
(let ((t1 (cdr c1))
(t2 (cdr c2)))
(set-cdr! c1 1)
(set-cdr! c2 2)
(let ((v (= (cdr c1) (cdr c2))))
(set-cdr! c1 t1)
(set-cdr! c2 t2)
v))))
现在,如果我定义a_list
如下:
(define a_list (list 'a 'b 'c 'd))
并评估
(same? a_list (cdr a_list))
该函数返回#f,调试器(Dr. Racket)确认这两个列表——它们应该共享它们的大部分成员,因为第二个参数是第一个参数的真子集——实际上确实有不同的副本相同的成员。这怎么可能?!
稍微改变一下这个想法:
(set-cdr! (cddr a_list) a_list)
现在a_list
是周期性的。如果我用它测试这个函数,same?
它只在两个参数同相时注册#t,即(same? a_list a_list)
和(same? a_list (cdddr a_list))
。
[编辑答案在已接受帖子评论链的底部]