# Recitation 17

### 1 Forms of Data & Equality

How do each of these individual expressions evaluate?

(+ 3 (cadr '(cons 5 7)))
(+ 3 '(cadr (cons 5 7)))
'(+ 3 (cadr (cons 5 7)))

(eq? 'hello 'hello)
(eq? "hello" "hello")
(let ((hello 'hello)) (eq? hello hello))
(let ((hello "hello")) (eq? hello hello))

(eq? (cons 1 2) (cons 1 2))
(eqv? (cons 1 2) (cons 1 2))
(equal? (cons 1 2) (cons 1 2))
(let ((c (cons 1 2))) (eq? (car c) (car c)))

(eq? (+ 1 1) 2)
(eqv? (+ 1 1) 2)

### 2 Mutation

How do each of these sequences evaluate?

(define p '(a b c))
(define q (cdr p))
(set-car! q 'd)
p

(define p '(a b c))
(define q (cdr p))
(set! q 'd)
p

(define p '(a b c))
(define q (cdr p))
(set-cdr! q p)
p

(define (c) (let ((x 0)) (set! x (+ 1 x)) x))
(c)
(c)

(define c (let ((x 0)) (lambda () (set! x (+ 1 x)) x)))
(c)
(c)

(define c (let ((x 0)) (lambda () (set! x (+ 1 x)) x)))
((lambda (x y) (- x y)) (c) (c))

(define x 3)
(define (f y) (set! x y))
(f 4)
x

(define x 3)
(define (f x) (set! x x))
(f 4)
x

(define x 3)
(define (f x) (set! x 5))
(f x)
x

### 3 Environment Model

Are these equivalent? Translate into lambdas to see.

(let ((x 1) (y 2)) (+ x y))
(let* ((x 1) (y 2)) (+ x y))
(let ((x 1)) (let ((y 2)) (+ x y)))

### 4 Data Abstraction

Write code for a "coin" ADT with operations
Assume you have a procedure p such that (p) is #t/#f with probability 50:50

make-coin: -> Coin
is-tails: Coin -> Bool
toss: Coin -> Void

Write code for a "range" ADT with operations

make-range: Int, Int -> Range
join: Range, Range -> Range
is-in: Int, Range -> Bool

### 5 Object Oriented Programming

(define (make-counter)
(let ((val 0))
(lambda (msg)
(cond ((eq? msg 'up) (set! val (+ val 1)))
((eq? msg 'down) (set! val (- val 1)))
((eq? msg 'show) (display val) (newline))))))

To the above definition, add the following methods:
-- reset to zero
-- increment by i

(define (make-account name bal)
(lambda (msg)
(case msg
((CHARGE-FEE) (lambda (self) (set! bal (- bal 10))))
(else (no-method)))))

To the above definition,
-- write a method DEPOSIT that deposits an amount and charges a fee
-- write a method BALANCE that returns the balance
-- (note \$10 fee for transaction)

(define (make-savings-account name bal min)
(let ((account (make-account name bal)))
(lambda (msg)
(case msg
((CHARGE-FEE) (lambda (self) (set! bal (- bal (if (> bal min) 0 10))))))
(else (get-method msg account))))))

To the above definition,
-- rewrite CHARGE-FEE so it uses superobject's CHARGE-FEE and BALANCE
-- write a method DIRECT-DEPOSIT that uses superobject's DEPOSIT to deposit some amt
-- (note no fee if balance above min)

Daniel Jackson
November 3, 1999