2012-06-13 9 views
5

estoy poco confundido por el resultado de este ejemplo:set-car! y dejar en un lenguaje esquema

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


(define q (mk-q)) 

q 
=> ((x) x) 

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

Me pregunto por qué tanto x átomos han sido reemplazados por set-car! procedimiento (mi primera suposición de lo que sería el resultado fue ((x) y))?

Por ejemplo:

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

Porque son las dos x s en el primer ejemplo reemplazado?

+2

Debido a que una célula contras es esencialmente dos punteros a valores. Cuando escribe '(cons l l)' crea dos punteros al mismo objeto. Cuando cambia el objeto, ambas entradas siguen apuntando al mismo objeto. –

+0

Inicialmente malinterpreté esto como set-carl, lo cual fue entretenido en una especie de fuerza de hambre adolescente. – Bill

Respuesta

4

En el primer ejemplo, que tienen algo equivalente a esto:

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

Como se puede ver, sólo hay unocons celda con x en la posición car, que se comparte en dos partes diferentes de la estructura de lista resultante. Cuando ejecuta (set-car! (cdr q) 'y), el x en la celda individual se reemplaza por y en todas las partes donde se comparte. Recordando que ambos (cons 'x null) células son realmente lo mismo, vamos a partir de esto:

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

a esto:

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

Para el segundo ejemplo se aplican las mismas consideraciones (los tres (cons 'x null) células son en realidad la misma que se comparte), pero usted está reemplazando una célula entera cons, así que básicamente vamos de esto:

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

a esto:

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

para probar mi punto de que los dos ejemplos en la cuestión demuestran la misma situación, se realiza esta expresiones:

(define q2 (mk-q2)) 
(set-car! (cadr q2) 'y) ; notice the extra `a` 
q2 
=> '((y) (y) y) 
Cuestiones relacionadas