Multiple Representations and Generic Operations

Adding a new type Adding a new operation Explicit dispatch (cond on type tags) Edit every operation Data-directed (operation table) Install a package

Message passing (objects as closures) Easy (new constructor) Edit every type

;; Complex numbers in two representations (SICP 2.4), with data-directed dispatch

;; An operation table: (op type) → procedure
(define *op-table* '())
(define (put op type item) (set! *op-table* (cons (list (list op type) item) *op-table*)))
(define (get op type)
  (let ((entry (assoc (list op type) *op-table*)))
    (if entry (cadr entry) #f)))

(define (attach-tag tag contents) (cons tag contents))
(define (type-tag datum) (car datum))
(define (contents datum) (cdr datum))

;; Rectangular package
(define (install-rectangular-package)
  (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)))
  (put 'real-part 'rectangular real-part)
  (put 'imag-part 'rectangular imag-part)
  (put 'magnitude 'rectangular magnitude)
  (put 'angle 'rectangular angle)
  (put 'make-from-real-imag 'rectangular (lambda (x y) (attach-tag 'rectangular (cons x y)))))

;; Polar package
(define (install-polar-package)
  (define (magnitude z) (car z))
  (define (angle z) (cdr z))
  (put 'real-part 'polar (lambda (z) (* (magnitude z) (cos (angle z)))))
  (put 'imag-
…