* 2.4 Multiple Representations for Abstract Data how to isolate different design choices to coexist in a program? - type tags :: data objects that include explicit information about how it should be processed - data-directed :: style of programming by additively assembling systems with generic operations ** 2.4.1 representations for complex numbers develop a system for complex number arithmetic with two underlying implementations: - rectangular form - polar form #+BEGIN_SRC scheme (define (add-complex z1 z2) (make-from-real-imag (+ (real-part z1) (real-part z2)) (+ (imag-part z1) (real-part z2)))) (define (sub-complex z1 z2) (make-from-real-imag (- (real-part z1) (real-part z2)) (- (imag-part z1) (real-part z2)))) (define (mul-complex z1 z2) (make-from-mag-ang (* (magnitude z1) (magnitude z2)) (+ (angle z1) (angle z2)))) (define (div-complex z1 z2) (make-from-mag-ang (/ (magnitude z1) (magnitude z2)) (- (angle z1) (angle z2)))) #+END_SRC two lispers take on the challenge... #+BEGIN_SRC scheme ;; BEN BITDIDDLE (define (real-part z) (car z)) (define (imag-part z) (cdr z)) (define (magnitude z) (sqrt (+ (square (real-part z)) (square (imag-part z))))) (define (angle z) (atan (imag-part z) (real-part z))) (define (make-from-real-imag x y) (cons x y)) (define (make-from-mag-ang r a) (cons (* r (cos a)) (* r (sin a)))) #+END_SRC #+BEGIN_SRC scheme ;; ALYSSA P. HACKER (define (real-part z) (* (magnitude z) (cos (angle z)))) (define (imag-part z) (* (magnitude z) (sin (angle z)))) (define (magnitude z) (car z)) (define (angle z) (cdr z)) (define (make-from-real-imag x y) (cons (sqrt (+ (square x) (square y))) (atan y x))) (define (make-from-mag-ang r a) (cons r a)) #+END_SRC ** 2.4.2 tagged data to keep this two systems and to keep them separate, you could make a tagging system for data #+BEGIN_SRC scheme (define (attach-tag type-tag contents) (cons type-tag contents)) (define (type-tag datum) (if (pair? datum) (car datum) (error "Bad tagged datum -- TYPE-TAG" datum))) (define (contents datum) (if (pair? datum) (cdr datum) (error "Bad tagged datum -- CONTENTS" datum))) #+END_SRC and then it would be simple to identify the said type #+BEGIN_SRC scheme (define (rectangular? z) (eq? (type-tag z) 'rectangular)) (define (polar? z) (eq? (type-tag z) 'polar)) #+END_SRC and so alyssa and ben could use this in their procedures, then name their procedures to reflect the work they are doing #+BEGIN_SRC scheme (define (magnitude z) (cond ((rectangular? z) (magnitude-rectangular (contents z))) ((polar? z) (magnitude-polar (contents z))) (else (error "Unknown type -- MAGNITUDE" z)))) #+END_SRC we will come back to this in ยง2.5 ** 2.4.3 data-directed programming and additivity