2012-06-13 39 views
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 S IN的第一個例子更換?

+2

因爲cons單元實際上是兩個指針值。當你寫'(缺點)'時,你創建了兩個指向同一個對象的指針。當您更改對象時,兩個條目仍然指向同一個對象。 –

+0

我最初誤解爲set-carl,這在一種青少年的飢餓中很有趣。 – Bill

回答

4

在第一個例子,你要這個東西相當於:

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

正如你所看到的,有在car位置x只有一個cons細胞,即在兩個不同的部分被共享的結果列表結構。當您執行(set-car! (cdr q) 'y)時,單個單元格中的x在共享它的所有部分被替換爲y。記住,這兩個(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)