Exercise 2.81

Source code.

a

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.

b

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.

c

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

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s