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-
…