You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
52 lines
1.5 KiB
52 lines
1.5 KiB
2 years ago
|
|
||
|
Exercise 2.81: Louis Reasoner has noticed that
|
||
|
apply-generic may try to coerce the arguments to each other’s type even
|
||
|
if they already have the same type. Therefore, he reasons, we need to put
|
||
|
procedures in the coercion table to
|
||
|
coerce arguments of each type to
|
||
|
their own type. For example, in addition to the
|
||
|
scheme-number->complex coercion shown above, he would do:
|
||
|
|
||
|
|
||
|
(define (scheme-number->scheme-number n) n)
|
||
|
(define (complex->complex z) z)
|
||
|
|
||
|
(put-coercion 'scheme-number 'scheme-number
|
||
|
scheme-number->scheme-number)
|
||
|
|
||
|
(put-coercion 'complex 'complex
|
||
|
complex->complex)
|
||
|
|
||
|
|
||
|
With Louis’s coercion procedures installed, what happens if
|
||
|
apply-generic is called with two arguments of type scheme-number
|
||
|
or two arguments of type complex for an operation that is not found in
|
||
|
the table for those types? For example, assume that we’ve defined a generic
|
||
|
exponentiation operation:
|
||
|
|
||
|
|
||
|
(define (exp x y)
|
||
|
(apply-generic 'exp x y))
|
||
|
|
||
|
and have put a procedure for exponentiation in the Scheme-number
|
||
|
package but not in any other package:
|
||
|
|
||
|
|
||
|
;; following added to Scheme-number package
|
||
|
(put 'exp
|
||
|
'(scheme-number scheme-number)
|
||
|
(lambda (x y)
|
||
|
(tag (expt x y))))
|
||
|
; using primitive expt
|
||
|
|
||
|
|
||
|
What happens if we call exp with two complex numbers as arguments?
|
||
|
|
||
|
Is Louis correct that something had to be done about coercion with arguments of
|
||
|
the same type, or does apply-generic work correctly as is?
|
||
|
|
||
|
Modify apply-generic so that it doesn’t try coercion if the two
|
||
|
arguments have the same type.
|
||
|
|
||
|
|