Exercise 2.81

Source code.


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)))))

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s