2012-06-13 29 views
5

tôi chút nhầm lẫn bởi kết quả của ví dụ này:bộ xe hơi! và để trong ngôn ngữ chương trình

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


(define q (mk-q)) 

q 
=> ((x) x) 

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

Tôi tự hỏi tại sao cả hai x nguyên tử đã được thay thế bởi set-car! thủ tục (đoán đầu tiên của tôi cho những gì kết quả sẽ là ((x) y))?

Ví dụ:

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

Tại sao đều x s trong ví dụ đầu tiên thay thế?

+2

Bởi vì về cơ bản một tế bào khuyết điểm là hai con trỏ đến giá trị. Khi bạn viết '(cons l l)' bạn tạo hai con trỏ tới cùng một đối tượng. Khi bạn thay đổi đối tượng, cả hai mục vẫn trỏ đến cùng một đối tượng. –

+0

Ban đầu tôi đọc nhầm điều này như là set-carl, điều thú vị trong một loại thiếu niên đói. – Bill

Trả lời

4

Trong ví dụ đầu tiên, bạn có một cái gì đó tương đương như sau:

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

Như bạn có thể thấy, chỉ có mộtcons tế bào với x ở vị trí car, đang được chia sẻ trong hai phần khác nhau của cấu trúc danh sách kết quả. Khi bạn thực thi (set-car! (cdr q) 'y), x trong ô đơn lẻ sẽ được thay thế bằng y trong tất cả các phần được chia sẻ. Luôn nhớ rằng cả hai (cons 'x null) tế bào thực sự giống nhau, chúng ta sẽ từ này:

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

này:

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

Đối với ví dụ thứ hai cân nhắc tương tự áp dụng (cả ba (cons 'x null) tế bào thực sự là cùng một được chia sẻ), nhưng bạn đang thay thế một cons tế bào toàn bộ, vì vậy về cơ bản chúng ta sẽ từ này:

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

này:

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

Để chứng minh quan điểm của tôi rằng cả hai trong những ví dụ trong câu hỏi thể hiện tình huống tương tự, thực hiện biểu thức này:

(define q2 (mk-q2)) 
(set-car! (cadr q2) 'y) ; notice the extra `a` 
q2 
=> '((y) (y) y) 
Các vấn đề liên quan