90 likes | 99 Views
This recitation covers the concepts of set-car!, set-cdr!, and aliasing in mutable data structures in the context of the book Structure and Interpretation of Computer Programs (SICP).
E N D
6001structure & interpretation of computer programsrecitation 11/ october 31, 1997
overview • today’s ideas • set-car! and set-cdr! • aliasing & object equality • cyclic data structures
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
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
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!
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
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
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
1 6 2 5 3 4 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