* 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
