[closer-devel] Introducing new "type" classes

Pascal Costanza pc at p-cos.net
Sat Feb 16 16:17:20 UTC 2008


Hey,

On 15 Feb 2008, at 16:58, Marco Antoniotti wrote:

> Hi
>
> this is a little OT wrt Closer, but this is probably the venue where  
> most of the expertise meets.
>
> In CLOS you have classes for INTEGER, REAL etc etc.  You can then  
> write methods like
>
> 	(defmethod foo ((i integer)) ...)
>
> Now, we cannot write methods like
>
> 	(defmethod foo ((i (integer 1 42))) ...)
>
> and this may be ok.

That's actually relatively easy: Just write a macro 'my-defmethod that  
expands into a number of methods with eql specializers (42 different  
methods in this case). ;)

> However, i am playing around with things like
>
> 	(deftype positive-integer () '(integer 1 *))
>
> is there any magic I can conjure to (semi) portably having a class  
> named POSITIVE-INTEGER that actually corresponds to the type  
> definition?

The specializers are used to determine the applicability of methods.  
The result of compute-applicable-methods must be a list of applicable  
method, sorted according to their specificity (!). This is where the  
problem is: As soon as you try to use more general types than classes  
and eql specializers, you get into trouble with sorting. For example,  
assume you have two methods specilaized on the types (satisfies oddp)  
and (satisfies primep), and both trigger, which one gets executed first?

The general problem here is that you need to analyze the specificity  
statically, without running any of the predicates. This is generally  
not possible. (Consider (satisfies haltp). ;)

If you allow for subsets, you get similar problems, although  
superficially speaking, they seem more tractable. But consider you  
have two methods specialized on the types (integer 0 *) and (integer 1  
10) - which one is more specific? Hard to tell.

Christophe Rhodes has worked on the technical issues in the CLOS MOP  
to be able to plug in new specializers, and implemented this for SBCL.  
However, this covers 'only' the technical aspects of the MOP, not the  
semantic issues sketched above. Jim Newton has come up with an idea  
how to turn the decision which methods are more specific into a  
property of the respective generic function. This doesn't really solve  
the issue, you still need ad-hoc solutions, but at least they can look  
different for different generic functions, which I think is an  
improvement. (Both Christophe and Jim have written papers about their  
ideas, presented at last year's European Lisp Workshop.)

For pragmatic purposes, a compromise could be to have a two-step  
process: Base the applicability on classes and eql-specializers, and  
then use a filter to get rid of methods you actually don't want. A  
method definition could then look like this:

(defmethod* foo ((x integer))
   (:filter (x (integer 1 10)))
   ...)

Maybe this could be added as new qualifiers and the filtering could  
then be part of a user-defined method combination. This would then be  
portable.

However, I don't know how much this would be an improvement over this:

(defmethod foo ((x integer))
   (unless (typep x '(integer 1 10))
     (return-from foo (call-next-method)))
   ...)

[These thoughts are a bit random, sorry for that. But they are a rough  
summary of my views on this issue I have developed so far...]


Pascal

-- 
1st European Lisp Symposium (ELS'08)
http://prog.vub.ac.be/~pcostanza/els08/

Pascal Costanza, mailto:pc at p-cos.net, http://p-cos.net
Vrije Universiteit Brussel, Programming Technology Lab
Pleinlaan 2, B-1050 Brussel, Belgium








More information about the closer-devel mailing list