If Louis puts the coercion functions into the operations table,
apply-generic will enter an infinite loop:
if the desired operation is not found on types t1 and t2,
find the procedures that coerce t1->t2 and t2->t1
call apply-generic using new arguments created using those coerce procedures
Now when t1 and t2 are the same type the call to apply-generic will be use the same arguments as the initial call and so it will fail again and therefore loops indefinitely.
Poor Louis., we already know that everything Louis he is wrong. In this case
apply-generic works but only when the coerce procedures are installed in the operation table, otherwise it will fail as designed.
(define (apply-generic op . args) (define (signal-error type-tags) (error "No method for these types - APPLY-GENERIC" (list op type-tags))) (define (coerce-types tags args) (let ((type1 (car tags)) (type2 (cadr tags)) (a1 (car args)) (a2 (cadr args))) (if (eq? type1 type2) (signal-error tags) (let ((t1->t2 (get-coercion type1 type2)) (t2->t1 (get-coercion type2 type1))) (cond (t1->t2 (apply-generic op (t1->t2 a1) a2)) (t2->t1 (apply-generic op a1 (t2->t1 a2))) (else (signal-error tags))))))) (let* ((type-tags (map type-tag args)) (proc (get op type-tags))) (cond (proc (apply proc (map contents args))) ((= (length args) 2) (coerce-types type-tags args)) (else (signal-error type-tags)))))