[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