2012-06-13 10 views
5

jestem trochę zdezorientowany przez Wynikiem tego przykładu:zestaw samochodowy! i niech w języku schematu

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


(define q (mk-q)) 

q 
=> ((x) x) 

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

Zastanawiam się dlaczego oba x atomy zostały zastąpione procedurą set-car! (moje pierwsze przypuszczenie co wynik byłby było ((x) y))?

Na przykład:

(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! 

Dlaczego oba x s w pierwszym przykładzie wymienić?

+2

Ponieważ minusy komórka jest zasadniczo dwa wskaźniki do wartości. Podczas pisania '(cons l l)' tworzysz dwa wskaźniki do tego samego obiektu. Po zmianie obiektu oba wpisy nadal wskazują ten sam obiekt. –

+0

Początkowo błędnie odczytałem to jako set-carl, co było zabawne w wodnej sile głodnej nastolatki. – Bill

Odpowiedz

4

W pierwszym przykładzie, masz coś równoważnego do tego:

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

Jak widać, nie tylko jedencons komórka z x w pozycji car, który jest udostępniony w dwóch różnych częściach z wynikowej struktury listy. Po wykonaniu (set-car! (cdr q) 'y)x w pojedynczej komórce zostanie zastąpiony przez y we wszystkich częściach, w których jest udostępniany. Pamiętając, że oba (cons 'x null) komórki są naprawdę takie same, jedziemy z tym:

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

do tego:

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

Na drugim przykładzie zastosowanie te same rozważania (wszystkie trzy (cons 'x null) komórki są rzeczywiście sam jeden jest wspólny), ale ty wymieniasz cały cons komórkę, więc w zasadzie mamy zamiar z tego:

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

do tego:

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

Aby udowodnić mój punkt widzenia, że ​​oba przykłady w kwestii wykazania takiej samej sytuacji, wykonanie tego wyrażenia:

(define q2 (mk-q2)) 
(set-car! (cadr q2) 'y) ; notice the extra `a` 
q2 
=> '((y) (y) y) 
Powiązane problemy