# SICP 2.4 Multiple representations for abstract data

Published: 2020-08-26T17:03:55.000Z

I went on vacation and lost cadence on this project. Need to get back on track, remember how to lauch interpreter, etc. :)

In this chapter we will need `get` and `put` functions which could be implemented by similar system functions.

Found this on StackOverflow, of course.

``````(define put 2d-put!)
(define (get a b)
;(display "get ") (display a) (display b) (newline)
(2d-get a b)
)``````

And some setup from previous section:

``````(define variable? symbol?)
(define (same-variable? v1 v2)
(and (variable? v1) (variable? v2) (eq? v1 v2)))
(define (=number? exp num)
(and (number? exp) (= exp num)))``````

## Exercise 2.73

``````(define (deriv exp var)
(cond ((number? exp) 0)
((variable? exp) (if (same-variable? exp var) 1 0))
(else ((get 'deriv (operator exp)) (operands exp)
var))))
(define (operator exp) (car exp))
(define (operands exp) (cdr exp))``````

a) So, in our new derive we do lookup in table instead of `cond` expression. We are not able to move `number?` into lookup, because `number?` is condition for a set of values, not just one value, and table works only with one value.

b)

``````(define (make-sum args)
(define (sum items total nonnum)
(cond
((null? items)
(if (null? nonnum)
total
(cons '+ (if (= total 0)
nonnum
(cons total nonnum)
))
)
)
((number? (car items))
(sum (cdr items) (+ (car items) total) nonnum))
(else
(sum (cdr items) total (cons (car items) nonnum)))
)
)
(sum args 0 '())
)

(define (make-prod m1 m2)
(cond ((or (=number? m1 0) (=number? m2 0)) 0)
((=number? m1 1) m2)
((=number? m2 1) m1)
((and (number? m1) (number? m2)) (* m1 m2))
(else (list '* m1 m2))))

(define (install-derivatives-package)
(define (deriv-sum items var)
(make-sum (map (lambda (e) (deriv e var)) items))
)
(put 'deriv '+ deriv-sum)

(define (deriv-prod items var)
(let ((tail
(if (null? (cddr items))
(cons '* (cdr items))
)
))
(make-sum (list
(make-prod (car items)
(deriv tail var))
(make-prod (deriv (car items) var)
tail)
))
)
)
(put 'deriv '+ deriv-sum)
(put 'deriv '* deriv-prod)
)
(install-derivatives-package) ``````

I think I wrote too much code here because I wanted to support sums and products of multiple arguments.

c) Exponentation

``````(define (make-exp base e)
(cond ((=number? e 0) 1)
((=number? e 1) base)
(else (list '** base e))))

(define (deriv-exp items var)
(let (
(base (car items))
)
(make-prod
e
(make-exp base (- e 1))
)
)
)
(put 'deriv '** deriv-exp)

(deriv '(+ (** x 3) (** x 2)) 'x)``````

d) We could switch arguments inside `get`, or inside `put`, or switch arguments when we call put. That's all what will be needed.

## Exercise 2.74

I skipped it because it is too abstract.

## Exercise 2.75

``````(define (make-from-mag-ang r a)
(define (dispatch op)
(cond ((eq? op 'real-part) (* r (cos a)))
((eq? op 'imag-part) (* r (sin a)))
((eq? op 'magnitude) r)
((eq? op 'angle) a)
(else
(error "Unknown op -- MAKE-FROM-REAL-IMAG" op))))
dispatch)``````

## Exercise 2.76

Skip this too. Because I see no way to verify that I did it correctly. Learning needs feedback.