5

我对这个例子的结果有点困惑:

(define mk-q
  (lambda ()
    (let ([l '(x)])
      (cons l l))))


(define q (mk-q))

q
=> ((x) x)

(set-car! (cdr q) 'y)
=> ((y) y)

我想知道为什么两个x原子都被set-car!程序替换了(我对结果的第一个猜测是((x) y))?

例如:

(define mk-q2
  (lambda ()
    (let ([l '(x)])
      (cons l (cons l l)))))

(define q2 (mk-q2))
(set-car! (cdr q2) 'y)
=> ((x) y x) which fits my understanding of set-car!

为什么第一个示例中的两个xs 都被替换了?

4

1 回答 1

4

在第一个示例中,您有与此等效的内容:

(define cell (cons 'x null))
(define q (cons cell cell))

如您所见,该位置只有一个 cons单元格,它在结果列表结构的两个不同部分中共享。当您在单个单元格中执行时,它被共享的所有部分替换。记住这两个单元格实际上是相同的,我们从这个开始:xcar(set-car! (cdr q) 'y)xy(cons 'x null)

(cons (cons 'x null) (cons 'x null))
; '((x) x)

对此:

(cons (cons 'y null) (cons 'y null))
; '((y) y)

对于第二个例子,同样的考虑也适用(所有三个(cons 'x null)单元实际上是同一个被共享的),但是你要替换整个cons单元,所以基本上我们从这个开始:

(cons (cons 'x null) (cons (cons 'x null) (cons 'x null)))
; '((x) (x) x)

对此:

(cons (cons 'x null) (cons 'y (cons 'x null)))
; '((x) y x)

为了证明我的观点,问题中的两个示例都演示了相同的情况,请执行以下表达式:

(define q2 (mk-q2))
(set-car! (cadr q2) 'y) ; notice the extra `a`
q2
=> '((y) (y) y)
于 2012-06-13T11:26:12.800 回答