--- /dev/null
+#lang racket
+#|
+magnitude is defined in section 2.4.3 as:
+
+(define (magnitude z) (apply-generic 'magnitude z))
+
+In this example z looks as '(complex rectangular 3 . 4))
+
+The apply-generic procedure is defined as follows:
+
+(define (apply-generic op . args)
+ (let ((type-tags (map type-tag args)))
+ (let ((proc (get op type-tags)))
+ (if proc
+ (apply proc (map contents args))
+ (error
+ "No method for these types -- APPLY-GENERIC"
+ (list op type-tags))))))
+
+Here, we find the type-tag of z, in this case, it will be 'complex.
+The table constructed with the generic prodecure "magnitude" was using
+the type of z, namely 'rectangular.
+
+The remedy as suggested by Alyssa is as follows:
+
+(put 'real-part '(complex) real-part)
+(put 'imag-part '(complex) imag-part)
+(put 'magnitude '(complex) magnitude)
+(put 'angle '(complex) angle)
+
+Now, this will add a new column for each of the operations (real-part, imag-part,
+magnitude and angle) for the type '(complex) and install the corresponding function.
+
+Now, when we do (type-tag z), we get 'complex and then we look for the type-specific
+procedure using (get op type-tag) which will give the right procedure.
+
+(apply-generic 'magnitude z)
+
+=> (apply-generic 'magnitude '(complex rectangular x . y)
+
+=> ((get 'magnitude 'complex) '(rectangular x . y)
+
+=> (magnitude '(rectangular x . y))
+
+=> (apply-generic 'magnitude '(rectangular x . y))
+
+=> ((get 'magnitude 'rectangular) '(x . y))
+
+So, apply-generic gets invoked twice.
+
+
+(
+
+|#
--- /dev/null
+#lang racket
+
+;; modify type-tag, contents, and attach-tag so that primitive numbers need not
+;; be tagged.
+
+(define (type-tag datum)
+ (cond
+ [(pair? datum) (car datum)]
+ [(number? datum) 'scheme-number]
+ [else
+ (error "Bad tagged datum -- TYPE-TAG" datum)]))
+
+(define (contents datum)
+ (cond
+ [(pair? datum) (cdr datum)]
+ [(number? datum) datum]
+ [else
+ (error "Bad tagged datum -- CONTENTS" datum)]))
+
+(define (attach-tag type-tag contents)
+ (if (number? contents)
+ contents
+ (cons type-tag contents)))
--- /dev/null
+#lang racket
+
+(define (equ? x y) (apply-generic 'equ? x y))
+
+(define (install-scheme-number-package)
+ (define (equ? x y)
+ (= x y))
+ (put 'equ? '(scheme-number scheme-number) equ?)
+ 'done)
+
+(define (install-rational-number-package)
+ (define (equ? r1 r2)
+ (let* ([n1 (numer r1)]
+ [d1 (denom r1)]
+ [n2 (numer r2)]
+ [d2 (denom r2)]
+ [g1 (gcd n1 d1)]
+ [g2 (gcd n2 d2)])
+ (and (= (/ n1 g1) (/ n2 g2))
+ (= (/ d1 g1) (/ d2 g2)))))
+ (put 'equ? '(rational rational) equ?)
+ 'done)
+
+(define (install-complex-number-package)
+ (define (equ? z1 z2)
+ (and (= (real-part z1) (real-part z2))
+ (= (imag-part z1) (imag-part z2))))
+ (put 'equ? '(complex complex) equ?)
+ 'done)
+
\ No newline at end of file
--- /dev/null
+#lang racket
+
+(define (=zero? x) (apply-generic '=zero? x))
+
+(define (install-scheme-number-package)
+ (define (=zero? x)
+ (zero? x))
+ (put '=zero? '(scheme-number) =zero?)
+ 'done)
+
+(define (install-rational-number-package)
+ (define (=zero? r)
+ (zero? (numer r)))
+ (put '=zero? '(rational) =zero?)
+ 'done)
+
+(define (install-complex-number-package)
+ (define (=zero? z)
+ (and (zero? (real-part z))
+ (zero? (imag-part z))))
+ (put '=zero? '(complex) =zero?)
+ 'done)
+
+
\ No newline at end of file