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!

最初の例で両方xの が置き換えられているのはなぜですか?

4

1 に答える 1

4

最初の例では、これと同等のものがあります。

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

ご覧のとおり、その位置にあるセルは1 つだけで、結果のリスト構造の 2 つの異なる部分で共有されています。 単一のセルで実行すると、共有されているすべての部分で置き換えられます。両方のセルが実際には同じであることを思い出して、これから進みます。consxcar(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)

2 番目の例では、同じ考慮事項が適用されます (3 つの(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 に答える