6001 structure & interpretation of computer programs recitation 11/ october 31, 1997
overview today’s ideas set-car! and set-cdr! aliasing & object equality cyclic data structures 2/24/2019 daniel jackson
mutable data structures how set! differs from set-car! and set-cdr! set! changes a FRAME set-car! and set-cdr! change a CONS CELL mutable structures all data structures are made of cons cells so all we need to modify data structures are set-car! : a way to change what’s in the first compartment set-cdr! : a way to change what’s in the second compartment (in fact, set-car! alone is enough. can you implement a mutable pair with set-car! alone?) contract after (set-car! c x), (car c) evaluates to x after (set-cdr! c y), (cdr c) evaluates to y … assuming that c names a cons cell 2/24/2019 daniel jackson
mutable abstract type example vector abstract type might now have operations like set-x-component! scale-vector! sample code (define (scale-vector! v k) (set-car! v (* k (car v))) (set-cdr! v (* k (cdr v)))) sample use (define v (make-vector 3 4)) (x-coord v) ==> 3 (scale-vector! v 2) (x-coord v) ==> 6 aside: beneficent side effects sometimes we allow operations to mutate the representation so that no changes are visible through the abstraction barrier examples balancing a tree memoizing results of queries 2/24/2019 daniel jackson
a puzzle another version of scale-vector? (define (scale-vector! v k) (set! v (cons (* k (car v)) (* k (cdr v))))) won’t work because creates a new cons cell doesn’t change the existing one draw env diagram for (scale-vector! v k) hangs a new frame in which v points to the same cell as v in the global frame changes this binding, but never changes that cell! 2/24/2019 daniel jackson
aliasing a puzzle (define x (cons 1 2)) (define y x) (car x) ==> 1 (set-car! y 2) (car y) ==> 2 what’s going on? draw box & pointer diagram after (define y x), both vars name the same cons cell so a change through either name is visible through the other terminology two names for the same object are said to be aliases in practice aliasing can be a big problem: may make it hard to understand code but very common in object oriented code 2/24/2019 daniel jackson
object equality can we test whether vars are aliases? if x and y name cons cells (eq? x y) ==> #t when they denote the same one (equal? x y) ==> #t when their values would print out in the same way object equality versus value equality example after (define x (cons 1 2)) (define y (cons 1 2)) (define z y) x and y are value equal, but x and z are object equal (eq? x y) ==> #f (equal? x y) ==> #t (eq? x z) ==> #t (equal? x z) ==> #t so a change to x will appear to be achange to z but not y (set-car! x 3) (car y) ==> 1 (car z) ==> 3 2/24/2019 daniel jackson
cyclic structures puzzle complete (define x …) so that (car x) ==> 1 (car (cdr x)) ==> 1 (car (cdr (cdr x))) ==> 1 (car (cdr (cdr (cdr x)))) ==> 1 … , forever and (eq? x (cdr x)) ==> #t solution code (define x (let ((c (cons 1 nil))) (set-cdr! c c) c)) property (eq? c (cdr c)) ==> #t 2/24/2019 daniel jackson
circular buffer (basic) model always contains at least one element values inserted to right of bar values popped from right of bar pop! returns last value inserted basic operations make-circular-buffer : T –> CB insert! : CB x T –> undefined remove! : CB –> T rotate-left! : CB –> undefined rotate-right! : CB –> undefined size : CB –> int implementation hints use only a singly-linked list same number of cons cells as value in the buffer all ops are 0(1) time except for rotate-right! and size 1 6 2 5 4 3 2/24/2019 daniel jackson