Advertisement
drpyser

compute-applicable-methods-using-classes

Nov 26th, 2015
213
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lisp 2.32 KB | None | 0 0
  1. (defmethod compute-applicable-methods-using-classes ((f typeclass-generic-function) classes)
  2.   (labels ((eql-specializer-applicablep (specializer class)
  3.          (eq class (class-of (eql-specializer-object specializer))))
  4.        (eql-specializerp (obj)
  5.          (subclassp (class-of obj) (find-class 'eql-specializer)))
  6.        (more-specific-specializerp (spec1 spec2)
  7.          (cond ((eql-specializerp spec1) (not (eql-specializerp spec2)))
  8.            ((typeclassp spec1) (and (classp spec2) (subclassp spec1 spec2)))
  9.            ((classp spec1) (or (and (classp spec2) (subclassp spec1 spec2))
  10.                        (typeclassp spec2)))))
  11.        (more-specific-methodp (m1 m2)
  12.          (some (lambda (s1 s2)
  13.              (more-specific-specializerp s1 s2))
  14.            (method-specializers m1)
  15.            (method-specializers m2))))
  16.     (let ((methods (generic-function-methods f)))
  17.       ;if there is a eql specializer which does not satisfies the classes of the arguments
  18.       ;in one of the methods' specializers...
  19.       (if (and (some (lambda (m)
  20.                (some #'eql-specializerp (method-specializers m)))                  
  21.              methods)
  22.            (some (lambda (specializers)
  23.                (every (lambda (s)
  24.                 (eql-specializer-applicablep (car s) (cdr s)))
  25.                   (remove-if-not (lambda (x)
  26.                            (eql-specializerp (car x)))
  27.                          (mapcar #'cons specializers classes))))
  28.              (mapcar #'method-specializers methods)))
  29.       (values '() nil);then applicable-methods cannot be found by the argument's classes
  30.       (if (some (lambda (specs)
  31.               (some (lambda (spec)
  32.                   (and (classp spec)
  33.                    (typeclassp spec)))
  34.                 specs))
  35.             (mapcar #'method-specializers methods))
  36.           (values (sort (remove-if-not (lambda (m)
  37.                          (let ((specs (method-specializers m)))
  38. ;each specializer must agree with the corresponding argument's class
  39.                     (every (lambda (spec c)
  40. ;'implement-typeclassp' is simply a lookup for the typeclass 'spec' in the slot 'typeclasses' of the class 'c'
  41.                          (cond ((typeclassp spec) (implement-typeclassp c spec)))                        
  42.                                ((eql-specializerp spec) (eql-specializer-applicablep spec c))
  43.                                ((classp spec) (subclassp c spec))))
  44.                            specs classes)))
  45.                        methods) #'more-specific-methodp)
  46.               t)
  47.           (call-next-method))))));if there is no typeclass in the method's specializer, calls the default algorithm
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement