Blob


1 (define (apply-generic op . args)
2 (define (can-coerce-into? types target-type)
3 (andmap (lambda (type)
4 (or (equal? type target-type)
5 (get-coercion type target-type)))
6 types))
7 (define (find-coercion-target types)
8 (ormap
9 (lambda (target-type)
10 (if (can-coerce-into? types target-type)
11 target-type
12 #f))
13 types))
14 (define (coerce-all args target-type)
15 (map (lambda (arg)
16 (let ((arg-type (type-tag arg)))
17 (if (equal? arg-type target-type)
18 arg
19 ((get-coercion arg-type target-type) arg))))
20 args))
21 (define (no-method type-tags)
22 (error "No method for these types"
23 (list op type-tags)))
24 (let ((type-tags (map type-tag args)))
25 (let ((proc (get op type-tags)))
26 (if proc
27 (apply proc (map contents args))
28 (let ((target-type (find-coercion-target type-tags)))
29 (if target-type
30 (apply
31 apply-generic
32 (append (list op)
33 (coerce-all args target-type)))
34 (no-method type-tags)))))))