The following function from pg 150 of the Seasoned Schemer establishes whether two lists have the same identity (i.e. occupy the same memory) by mutating each list's cdr and then checking whether the change has affected both:
(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))))
Now if I define a_list
as follows:
(define a_list (list 'a 'b 'c 'd))
and evaluate
(same? a_list (cdr a_list))
the function returns #f, and the debugger (Dr. Racket) confirms that these two lists -- which ought to share most of their members since the second argument is a proper subset of the first -- do in fact have different copies of the same members. How is this possible?!
For a slight twist on this idea:
(set-cdr! (cddr a_list) a_list)
Now a_list
is cyclical. If I test this function with same?
it only registers #t when the two arguments are in phase, i.e. (same? a_list a_list)
and (same? a_list (cdddr a_list))
.
[EDIT The answer is at the bottom of the accepted post's comment chain]