Seasoned Schemerの150ページにある次の関数は、各リストのcdrを変更し、変更が両方に影響したかどうかを確認することで、2つのリストが同じIDを持っている(つまり同じメモリを占有している)かどうかを確認します。
(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)は、これら2つのリスト(2番目の引数は最初の引数の適切なサブセットであるためメンバーのほとんどを共有する必要があります)が実際には異なるコピーを持っていることを確認します同じメンバー。これはどうして可能ですか?!
このアイデアに少しひねりを加えるには:
(set-cdr! (cddr a_list) a_list)
今a_list
は循環的です。この関数を使用してテストすると、2つの引数、つまりとsame?
が同相の場合にのみ#tが登録されます。 (same? a_list a_list)
(same? a_list (cdddr a_list))
[編集回答は、承認された投稿のコメントチェーンの一番下にあります]