Name: Anonymous 2008-04-09 18:01
Chapter 2.4 and 2.5 just goes over operator overloading/generics in an outdated and horrible language.
(define (apply-generic op . args)
(let* ((type-tags (map type-tag args))
(args-type-tags (map cons args type-tags))
(proc (get op type-tags))
(error-no-method (lambda () (error "No method for these types"
(list op type-tags)))))
(if proc
(apply proc (map contents args))
(if (> (length args) 1)
; For each argument, try to coerce all the other arguments to that
; specific argument's type.
(let loop ((left-list '())
(right-list (cdr args-type-tags))
(item (car args-type-tags)))
(cond
((call/cc
(lambda (return)
(map (lambda (item-prime)
(cond
((eq? (cdr item-prime) (cdr item))
; They are the same type, no coercion necessary.
(car item-prime))
((get-coercion (cdr item-prime) (cdr item))
=> (lambda (coerce) (coerce (car item-prime))))
(else
; No coercion possible, exit the map!
(return #f))))
(append left-list (cons item right-list)))))
=> (lambda (coerced-args) (apply-generic op coerced-args)))
((null? right-list)
; We've exhausted all possibilities.
(error-no-method))
(else (loop (append left-list (list item))
(cdr right-list)
(car right-list)))))
; Coercion isn't an option for a unary method!
(error-no-method))))))