1 (define (coerce-to target-type remaining-args result)
2 (if (null? remaining-args)
4 (let* ((arg (car remaining-args))
5 (original-type (type-tag arg)))
6 (if (eq? original-type target-type)
9 (append result (list arg)))
10 (let ((original->target (get-coercion (type-tag arg) target-type)))
12 (coerce-to target-type
14 (append result (list (original->target arg))))
16 (define (put-coercion source-type target-type proc)
17 (put 'coercion (list source-type target-type) proc))
18 (define (get-coercion source-type target-type)
19 (get 'coercion (list source-type target-type)))
21 (define (apply-generic-iter coercion-types)
22 (if (null? coercion-types)
23 (error "No method for these types, and could not coerce"
24 (list op (map type-tag args)))
25 (let ((coerced-args (coerce-to (car coercion-types) args '())))
27 (let ((proc (get op (map type-tag coerced-args))))
29 (apply proc (map contents coerced-args))
30 (apply-generic-iter (cdr coercion-types))))
31 (apply-generic-iter (cdr coercion-types))))))
40 (define (apply-generic op . args)
41 (let* ((type-tags (map type-tag args))
42 (proc (get op type-tags)))
44 (apply proc (map contents args))
45 (let ((unique-types (uniquify type-tags)))
46 (if (> (length unique-types) 1)
47 (apply-generic-iter unique-types)
48 (else (error "No method for this type"
49 (list op type-tags))))))))
52 (define (attach-tag type-tag contents)
53 (if (number? contents)
55 (cons type-tag contents)))
56 (define (apply-generic op . args)
57 (let ((type-tags (map type-tag args)))
58 (let ((proc (get op type-tags)))
60 (apply proc (map contents args))
62 "No method for these types -- APPLY-GENERIC"
63 (list op type-tags))))))
64 (define (integer->rational n)
66 (put 'raise '(integer)
67 (lambda (i) (integer->rational i)))
68 (define (rational->real r)
70 (exact->inexact (/ (numer r) (denom r)))))
71 (put 'raise '(rational)
72 (lambda (r) (rational->real r)))
73 (define (real->complex r)
74 (make-complex-from-real-imag r 0))
76 (lambda (r) (real->complex r)))
78 (apply-generic 'raise x))
80 (define (raise x) (apply-generic 'raise x))
81 (put 'raise '(scheme-number)
83 (if (exact-integer? x)
85 (make-complex-from-real-imag x 0))))
86 (put 'raise '(rational)
88 (make-scheme-number (exact->inexact (/ (numer r) (denom r))))))
90 (define (install-integer-package)
92 (attach-tag 'integer x))
93 (put 'add '(integer integer)
94 (lambda (x y) (tag (+ x y))))
95 (put 'sub '(integer integer)
96 (lambda (x y) (tag (- x y))))
97 (put 'mul '(integer integer)
98 (lambda (x y) (tag (* x y))))
99 (put 'div '(integer integer)
100 (lambda (x y) (make-rational x y)))
101 (put 'equ '(integer integer) =)
102 (put '=zero? '(integer)
103 (lambda (x) (= 0 x)))
105 (lambda (x) (if (integer? x)
107 (error "non-integer value" x))))
110 (define (make-integer n)
111 ((get 'make 'integer) n))
113 (define (install-real-package)
115 (attach-tag 'real x))
116 (put 'add '(real real)
117 (lambda (x y) (tag (+ x y))))
118 (put 'sub '(integer integer)
119 (lambda (x y) (tag (- x y))))
120 (put 'mul '(integer integer)
121 (lambda (x y) (tag (* x y))))
122 (put 'div '(integer integer)
123 (lambda (x y) (tag (/ x y))))
124 (put 'equ? '(real real) =)
126 (lambda (x) (= 0 x)))
128 (lambda (x) (if (real? x)
130 (error "non-real value" x))))
133 (define (make-real n)
134 ((get 'make 'real) n))
136 (define (install-rational-package)
137 (define (make-rat n d)
138 (if (and (integer? n) (integer? d))
140 (cons (/ n g) (/ d g)))
141 (error "non-integer numerator or denominator"
145 (define (install-rectangular-package)
146 (define (make-from-real-imag x y)
147 (if (and (in-tower? x) (in-tower? y))
149 (error "non-real real or imaginary value" (list x y))))
150 (define (make-from-mag-ang r a)
151 (if (and (real? r) (real? a))
152 (cons (* r (cos a)) (* r (sin a)))
153 (error "non-real magnitude or angle" (list r a))))
157 (define (install-polar-package)
158 (define (make-from-mag-ang r a)
159 (if (and (in-tower? r) (in-tower? a))
161 (error "non-real magnitude or angle" (list r a))))
162 (define (make-from-real-imag x y)
163 (if (and (in-tower? x) (in-tower? y))
164 (cons (sqrt (+ (square x) (square y)))
166 (error "non-real real or imaginary value" (list x y))))
169 (define (integer->rational i) (make-rational i 1))
170 (define (rational->real r) (make-real (/ (numer r) (denom r))))
171 (define (real->complex r) (make-complex-from-real-imag r 0))
172 (define (raise x) (apply-generic 'raise x))
174 (define tower-of-types '(integer rational real complex))
176 (define (apply-raise types)
178 (error "Type not found in the tower-of-types"
179 (list x tower-of-types)))
180 ((eq? (type-tag x) (car types))
181 (if (null? (cdr types))
183 (let ((raiser (get-coercion (type-tag x) (cadr types))))
185 (raiser (contents x))
186 (error "No coercion procedure found for types"
187 (list (type-tag x) (cadr types)))))))
188 (else (apply-raise (cdr types)))))
189 (apply-raise tower-of-types))
191 (define (install-integer-package)
193 (attach-tag 'integer x))
194 (put 'add '(integer integer)
195 (lambda (x y) (tag (+ x y))))
196 (put 'sub '(integer integer)
197 (lambda (x y) (tag (- x y))))
198 (put 'mul '(integer integer)
199 (lambda (x y) (tag (* x y))))
200 (put 'div '(integer integer)
201 (lambda (x y) (make-rational x y)))
202 (put 'equ? '(integer integer) =)
203 (put '=zero? '(integer) =zero?)
205 (lambda (x) (if (integer? x)
207 (error "non-integer value" x))))
209 (define (make-integer n)
210 ((get 'make 'integer) n))
212 (define (install-real-package)
214 (attach-tag 'real x))
215 (put 'add '(real real)
216 (lambda (x y) (tag (+ x y))))
217 (put 'sub '(real real)
218 (lambda (x y) (tag (- x y))))
219 (put 'mul '(real real)
220 (lambda (x y) (tag (* x y))))
221 (put 'div '(real real)
222 (lambda (x y) (tag (/ x y))))
223 (put 'equ? '(real real) =)
225 (lambda (x) (= 0 x)))
227 (lambda (x) (if (real? x)
229 (error "non-real value" x))))
231 (define (make-real n)
232 ((get 'make 'real) n))
234 (define (install-rational-package)
235 (define (make-rat n d)
236 (if (and (integer? n) (integer? d))
238 (cons (/ n g) (/ d g)))
239 (error "non-integer numerator or denominator"
243 (define (install-rectangular-package)
244 (define (make-from-real-imag x y)
245 (if (and (in-tower? x) (in-tower? y))
247 (error "non-real real or imaginary value" (list x y))))
248 (define (make-from-mag-ang r a)
249 (if (and (real? r) (real? a))
250 (cons (* r (cos a)) (* r (sin a)))
251 (error "non-real magnitude or angle" (list r a))))
253 (define (install-polar-package)
254 (define (make-from-mag-ang r a)
255 (if (and (in-tower? r) (in-tower? a))
257 (error "non-real magnitude or angle" (list r a))))
258 (define (make-from-real-imag x y)
259 (if (and (in-tower? x) (in-tower? y))
260 (cons (sqrt (+ (square x) (square y)))
262 (error "non-real real or imaginary value" (list x y))))
266 (define (integer->rational i) (make-rational i 1))
267 (define (rational->real r) (make-real (/ (numer r) (denom r))))
268 (define (real->complex r) (make-complex-from-real-imag r 0))
269 (define (raise x) (apply-generic 'raise x))
271 (define tower-of-types '(integer rational real complex))
273 (define (apply-raise types)
275 (error "Type not found in the tower-of-types"
276 (list x tower-of-types)))
277 ((eq? (type-tag x) (car types))
278 (if (null? (cdr types))
280 (let ((raiser (get-coercion (type-tag x) (cadr types))))
282 (raiser (contents x))
283 (error "No coercion procedure found for types"
284 (list (type-tag x) (cadr types)))))))
285 (else (apply-raise (cdr types)))))
286 (apply-raise tower-of-types))
288 (define (integer->rational i) (make-rational i 1))
289 (put-coercion 'integer 'rational integer->rational)
291 (define (rational->real r) (make-real (/ (numer r) (denom r))))
292 (put-coercion 'rational 'real rational->real)
294 (define (real->complex r) (make-complex-from-real-imag r 0))
295 (put-coercion 'real 'complex real->complex)
299 (raise (make-integer 2))
300 (raise (make-rational 3 4))