From: Slobodan Blazeski
Subject: Is it possible to specialize method on type instead of class?
Date: 
Message-ID: <ae6426ee-948d-4dcd-9d44-7018ee23063f@h2g2000yqg.googlegroups.com>
For example something like:
104 >(defmethod foo ((i atom))
                   i)

Error: ATOM is not the name of a class
  1 (continue) Try finding the class ATOM again
  2 (abort) Return to level 0.
  3 Return to top loop level 0.

Type :b for backtrace, :c <option number> to proceed,  or :? for other
options

bobi

From: Pillsy
Subject: Re: Is it possible to specialize method on type instead of class?
Date: 
Message-ID: <7bb45265-fc91-4676-8d09-2f33d2094145@x6g2000vbg.googlegroups.com>
On Jun 1, 5:48 am, Slobodan Blazeski <·················@gmail.com>
wrote:

> For example something like:
> 104 >(defmethod foo ((i atom))
>                    i)

The answer is no, and I think it's pretty easy to convince yourself
that the answer *should* be no. Consider:

(defmethod foo ((x (integer 0 10)))
  (princ "This is a small integer!"))

(defmethod foo ((a (and integer (satisfies oddp))))
  (princ "This an odd integer!"))

What should (FOO 3) do?

Cheers,
Pillsy
From: Slobodan Blazeski
Subject: Re: Is it possible to specialize method on type instead of class?
Date: 
Message-ID: <6deb0508-02b2-404a-9cef-b190c485c8fc@s31g2000vbp.googlegroups.com>
On Jun 1, 3:33 pm, Pillsy <·········@gmail.com> wrote:
> On Jun 1, 5:48 am, Slobodan Blazeski <·················@gmail.com>
> wrote:
>
> > For example something like:
> > 104 >(defmethod foo ((i atom))
> >                    i)
>
> The answer is no, and I think it's pretty easy to convince yourself
> that the answer *should* be no. Consider:
>
> (defmethod foo ((x (integer 0 10)))
>   (princ "This is a small integer!"))
>
> (defmethod foo ((a (and integer (satisfies oddp))))
>   (princ "This an odd integer!"))
>
> What should (FOO 3) do?

Ok agreed. Thanks to everybody for their explanations.

cheers
bobi
From: Pascal J. Bourguignon
Subject: Re: Is it possible to specialize method on type instead of class?
Date: 
Message-ID: <87iqjg2mhj.fsf@galatea.local>
Slobodan Blazeski <·················@gmail.com> writes:
> [... anything but the question in the message body ...]

No, it is not.

What may trouble you is that there are system classes defined for a
lot of predefined types, but not all.


C/USER[30]> (find-class 'integer)
#1=#<BUILT-IN-CLASS INTEGER>
C/USER[31]> (find-class 'fixnum)

*** - FIND-CLASS: FIXNUM does not name a class
The following restarts are available:
ABORT          :R1      Abort main loop
C/Break 1 USER[32]> :q
C/USER[33]> 


-- 
__Pascal Bourguignon__
From: Thomas M. Hermann
Subject: Re: Is it possible to specialize method on type instead of class?
Date: 
Message-ID: <h00p12$5sq$1@news.eternal-september.org>
Pascal J. Bourguignon wrote:
> Slobodan Blazeski <·················@gmail.com> writes:
>> [... anything but the question in the message body ...]
> 
> No, it is not.
> 
> What may trouble you is that there are system classes defined for a
> lot of predefined types, but not all.
> 
> 
> C/USER[30]> (find-class 'integer)
> #1=#<BUILT-IN-CLASS INTEGER>
> C/USER[31]> (find-class 'fixnum)
> 
> *** - FIND-CLASS: FIXNUM does not name a class
> The following restarts are available:
> ABORT          :R1      Abort main loop
> C/Break 1 USER[32]> :q
> C/USER[33]> 
> 
> 

The fun thing is that if your implementation doesn't have a class for
the type you want, find another that does. This is from SBCL.

CL-USER> (find-class 'complex)
#<BUILT-IN-CLASS COMPLEX>
CL-USER> (find-class 'float)
#<BUILT-IN-CLASS FLOAT>
CL-USER> (find-class 'single-float)
#<BUILT-IN-CLASS SINGLE-FLOAT>
CL-USER> (find-class 'double-float)
#<BUILT-IN-CLASS DOUBLE-FLOAT>
CL-USER> (find-class 'fixnum)
#<BUILT-IN-CLASS FIXNUM>
CL-USER>

The SINGLE-FLOAT, DOUBLE-FLOAT and FIXNUM classes are not specified in
the standard. I'm not aware of a condensed list or table of types and
corresponding classes, hopefully someone will point one out. Most of the
time I'm not sure and have to simply look the type up in the Hyperspec
to see if there is a built-in class.

Hope that helps,

Tom
From: Thomas A. Russ
Subject: Re: Is it possible to specialize method on type instead of class?
Date: 
Message-ID: <ymi4ouz7qc6.fsf@blackcat.isi.edu>
"Thomas M. Hermann" <··········@gmail.com> writes:

> The SINGLE-FLOAT, DOUBLE-FLOAT and FIXNUM classes are not specified in
> the standard. I'm not aware of a condensed list or table of types and
> corresponding classes, hopefully someone will point one out.

  http://www.lispworks.com/documentation/HyperSpec/Body/sec_4-3-7.html#classtypecorrespondence

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Thomas A. Russ
Subject: Re: Is it possible to specialize method on type instead of class?
Date: 
Message-ID: <ymir5y3690n.fsf@blackcat.isi.edu>
···@sevak.isi.edu (Thomas A. Russ) writes:

> "Thomas M. Hermann" <··········@gmail.com> writes:
> 
> > The SINGLE-FLOAT, DOUBLE-FLOAT and FIXNUM classes are not specified in
> > the standard. I'm not aware of a condensed list or table of types and
> > corresponding classes, hopefully someone will point one out.
> 
>   http://www.lispworks.com/documentation/HyperSpec/Body/sec_4-3-7.html#classtypecorrespondence

Correction:  That URL doesn't work.

 http://www.lispworks.com/documentation/HyperSpec/Body/04_cg.htm#classtypecorrespondence
From: Slobodan Blazeski
Subject: Re: Is it possible to specialize method on type instead of class?
Date: 
Message-ID: <f8810712-57dc-4a96-ba5e-db8022b4e296@r13g2000vbr.googlegroups.com>
On Jun 1, 4:36 pm, "Thomas M. Hermann" <··········@gmail.com> wrote:
> Pascal J. Bourguignon wrote:
> > Slobodan Blazeski <·················@gmail.com> writes:
> >> [... anything but the question in the message body ...]
>
> > No, it is not.
>
> > What may trouble you is that there are system classes defined for a
> > lot of predefined types, but not all.
>
> > C/USER[30]> (find-class 'integer)
> > #1=#<BUILT-IN-CLASS INTEGER>
> > C/USER[31]> (find-class 'fixnum)
>
> > *** - FIND-CLASS: FIXNUM does not name a class
> > The following restarts are available:
> > ABORT          :R1      Abort main loop
> > C/Break 1 USER[32]> :q
> > C/USER[33]>
>
> The fun thing is that if your implementation doesn't have a class for
> the type you want, find another that does. This is from SBCL.
>
> CL-USER> (find-class 'complex)
> #<BUILT-IN-CLASS COMPLEX>
> CL-USER> (find-class 'float)
> #<BUILT-IN-CLASS FLOAT>
> CL-USER> (find-class 'single-float)
> #<BUILT-IN-CLASS SINGLE-FLOAT>
> CL-USER> (find-class 'double-float)
> #<BUILT-IN-CLASS DOUBLE-FLOAT>
> CL-USER> (find-class 'fixnum)
> #<BUILT-IN-CLASS FIXNUM>
> CL-USER>
>
> The SINGLE-FLOAT, DOUBLE-FLOAT and FIXNUM classes are not specified in
> the standard. I'm not aware of a condensed list or table of types and
> corresponding classes, hopefully someone will point one out. Most of the
> time I'm not sure and have to simply look the type up in the Hyperspec
> to see if there is a built-in class.
>
> Hope that helps,
I was more interested in user defined types, but anyway I usually stay
away from implementation specific extensions unless there is no other
way.

cheers
bobi
>
> Tom
From: Pascal J. Bourguignon
Subject: Re: Is it possible to specialize method on type instead of class?
Date: 
Message-ID: <878wkc2ei7.fsf@galatea.local>
"Thomas M. Hermann" <··········@gmail.com> writes:

> Pascal J. Bourguignon wrote:
>> Slobodan Blazeski <·················@gmail.com> writes:
>>> [... anything but the question in the message body ...]
>> 
>> No, it is not.
>> 
>> What may trouble you is that there are system classes defined for a
>> lot of predefined types, but not all.
>> 
>> 
>> C/USER[30]> (find-class 'integer)
>> #1=#<BUILT-IN-CLASS INTEGER>
>> C/USER[31]> (find-class 'fixnum)
>> 
>> *** - FIND-CLASS: FIXNUM does not name a class
>> The following restarts are available:
>> ABORT          :R1      Abort main loop
>> C/Break 1 USER[32]> :q
>> C/USER[33]> 
>> 
>> 
>
> The fun thing is that if your implementation doesn't have a class for
> the type you want, find another that does. This is from SBCL.
>
> CL-USER> (find-class 'complex)
> #<BUILT-IN-CLASS COMPLEX>
> CL-USER> (find-class 'float)
> #<BUILT-IN-CLASS FLOAT>
> CL-USER> (find-class 'single-float)
> #<BUILT-IN-CLASS SINGLE-FLOAT>
> CL-USER> (find-class 'double-float)
> #<BUILT-IN-CLASS DOUBLE-FLOAT>
> CL-USER> (find-class 'fixnum)
> #<BUILT-IN-CLASS FIXNUM>
> CL-USER>
>
> The SINGLE-FLOAT, DOUBLE-FLOAT and FIXNUM classes are not specified in
> the standard. I'm not aware of a condensed list or table of types and
> corresponding classes, hopefully someone will point one out. Most of the
> time I'm not sure and have to simply look the type up in the Hyperspec
> to see if there is a built-in class.

When you read CLHS, however, there is a difference between the
specifications of FIXNUM and INTEGER:

    Type FIXNUM

    Supertypes:

    fixnum, integer, rational, real, number, t

vs.

    System Class INTEGER

    Class Precedence List:

    integer, rational, real, number, t


Clearly, one is specified to be a type and the other to be a system class.  

If SBCL commits the errors of implementing FIXNUM as a system-class,
well, conformants programs cannot condone this deviant behavior.


(defmethod m ((x integer)) ...) ; conformant program     (ie. portable)

(defmethod m ((x fixnum))  ...) ; non-conformant program (ie. non-portable)


-- 
__Pascal Bourguignon__
From: Willem Broekema
Subject: Re: Is it possible to specialize method on type instead of class?
Date: 
Message-ID: <4daa5f45-ce2e-45c4-ad2d-66d738cdfd67@e24g2000vbe.googlegroups.com>
On Jun 1, 4:52 pm, ····@informatimago.com (Pascal J. Bourguignon)
wrote:
> If SBCL commits the errors of implementing FIXNUM as a system-class,

Actually it seems to be explicitly allowed implementation-specific
behaviour, see § 4.3.7 "Integrating Types and Classes":

"Individual implementations may be extended to define other type
specifiers to have a corresponding class."

- Willem
From: Pascal J. Bourguignon
Subject: Re: Is it possible to specialize method on type instead of class?
Date: 
Message-ID: <87zlcr1yk7.fsf@galatea.local>
Willem Broekema <········@gmail.com> writes:

> On Jun 1, 4:52�pm, ····@informatimago.com (Pascal J. Bourguignon)
> wrote:
>> If SBCL commits the errors of implementing FIXNUM as a system-class,
>
> Actually it seems to be explicitly allowed implementation-specific
> behaviour, see � 4.3.7 "Integrating Types and Classes":
>
> "Individual implementations may be extended to define other type
> specifiers to have a corresponding class."


Yes, but still for a program to be conformant, it shall avoid
implementation dependant extensions, or at the very least, behave
properly in their presence.

So basically, if you want to write conformant code, you have the
choice of writing:

    #+#.(cl:if (cl:ignore-errors (cl:find-class 'cl:fixnum)) '(:and) '(:or))
    (pushnew :has-fixnum-class *features*)
    #+has-fixnum-class (defmethod m ((x integer)) (do-integer-stuff x))
    #+has-fixnum-class (defmethod m ((x fixnum))  (do-fixnum-stuff x))
    #-has-fixnum-class (defmethod m ((x integer)) (if (fixnump x)
                                                      (do-fixnum-stuff x)
                                                      (do-integer-stuff x)))
vs.

    (defmethod m ((x integer)) (if (fixnump x)
                                  (do-fixnum-stuff x)
                                  (do-integer-stuff x)))

I don't think the first option is worth it.

-- 
__Pascal Bourguignon__
From: ·····@franz.com
Subject: Re: Is it possible to specialize method on type instead of class?
Date: 
Message-ID: <bd993825-d72b-463d-a3e1-9ed0b0f71ec1@o30g2000vbc.googlegroups.com>
On Jun 1, 7:52 am, ····@informatimago.com (Pascal J. Bourguignon)
wrote:
> "Thomas M. Hermann" <··········@gmail.com> writes:
>
> > The fun thing is that if your implementation doesn't have a class for
> > the type you want, find another that does. This is from SBCL.
>
> > The SINGLE-FLOAT, DOUBLE-FLOAT and FIXNUM classes are not specified in
> > the standard. I'm not aware of a condensed list or table of types and
> > corresponding classes, hopefully someone will point one out. Most of the
> > time I'm not sure and have to simply look the type up in the Hyperspec
> > to see if there is a built-in class.
>
> If SBCL commits the errors of implementing FIXNUM as a system-class,
> well, conformants programs cannot condone this deviant behavior.

As Willem pointed out in another answer, this is not an error on
SBCL's part.

> (defmethod m ((x integer)) ...) ; conformant program     (ie. portable)
>
> (defmethod m ((x fixnum))  ...) ; non-conformant program (ie. non-portable)

This is, of course, true, but no more true than it is of programs
which use FFI or sockets or ...

These extensions are explicitly granted for implementations precisely
so that they can meet needs of their users. In the case of floats, for
example, the allowance for the existence of single-float/double-float
(pus the others, if appropriate to the way the implementation chose to
divide their floating point hardware and software), it averts the
problem one can run into by just declaring a value to be a float -
implementations which only implement one kind of float don't have any
trouble with a float declaration, because short-float, single-float,
double-float, and long-float are all the same and the code can be made
efficient.  But the price the implementation (and thus the user) pays
to get the choice of the equivalent of C float and double types at the
hardware level is easily offset by the fact that the choice is
available, and that one can choose between higher precision and better
space savings.  In the same way, if an implementation subclass its
built-in classes in such a way that the user is able to specialize on
that subclass, then for those implementations that support it, the
user is better off, with more efficient code.

If the user wants to create a perfectly portable program, would he use
single-float or fixnum as a specializer?  Of course not.  But neither
would he use sockets, or ffi, or any other useful extension that is
available,   Perhaps someone will want to do a survey on
implementations, to see what can be reasonably expected re portability
of built-ins

Duane
From: Kaz Kylheku
Subject: Re: Is it possible to specialize method on type instead of class?
Date: 
Message-ID: <20090613063251.259@gmail.com>
On 2009-06-01, Slobodan Blazeski <·················@gmail.com> wrote:
> For example something like:
> 104 >(defmethod foo ((i atom))
>                    i)
>
> Error: ATOM is not the name of a class

Hi Bobi,

Indeed atoms do not constitute a class. Philosophically, why not?  Because the
set of atoms is negatively defined: anything and everything that is not a cons
is an atom.

(Okay, that's not really a reason; we could have a type, which would be
an immediate subtype of T, from which all classes are understood
to be derived, other than conses. But we don't.)

So what we can do is write a method which captures all objects, and then a
method which captures conses:

;; capture all objects
(defmethod foo ((obj t))
  )

;; capture conses
(defmethod foo ((obj cons))
 )

Since conses go to the more specific method, you can put atom-specific
logic into the T specialization. The only way that the T specialization
can be reached with a cons argument is if the cons specialization
invokes (call-next-method). Just don't do that. :)
From: ··············@excite.com
Subject: Re: Is it possible to specialize method on type instead of class?
Date: 
Message-ID: <ce7ba62c-5231-4035-b193-2d155938384c@q2g2000vbr.googlegroups.com>
On Jun 1, 12:14 pm, Kaz Kylheku <········@gmail.com> wrote:

-see above-

Is it easy to define in your own code a new class (ATOM or FIXNUM in
the above examples) that operates like the system class INTEGER does?
From: Thomas A. Russ
Subject: Re: Is it possible to specialize method on type instead of class?
Date: 
Message-ID: <ymizlcr6boe.fsf@blackcat.isi.edu>
··············@excite.com writes:

> On Jun 1, 12:14��pm, Kaz Kylheku <········@gmail.com> wrote:
> 
> Is it easy to define in your own code a new class (ATOM or FIXNUM in
> the above examples) that operates like the system class INTEGER does?

No.

Because the existing system objects will not be members of your new
class, so dispatch wouldn't work.

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Kaz Kylheku
Subject: Re: Is it possible to specialize method on type instead of class?
Date: 
Message-ID: <20090613114407.235@gmail.com>
On 2009-06-01, ··············@excite.com <··············@excite.com> wrote:
> On Jun 1, 12:14 pm, Kaz Kylheku <········@gmail.com> wrote:
>
> -see above-
 
(')(')
  ..  
 ,--. 


I can't see a thing.

> Is it easy to define in your own code a new class (ATOM or FIXNUM in
> the above examples) that operates like the system class INTEGER does?

No.
From: Pascal J. Bourguignon
Subject: Re: Is it possible to specialize method on type instead of class?
Date: 
Message-ID: <87vdnf1y6b.fsf@galatea.local>
··············@excite.com writes:

> On Jun 1, 12:14�pm, Kaz Kylheku <········@gmail.com> wrote:
>
> -see above-
>
> Is it easy to define in your own code a new class (ATOM or FIXNUM in
> the above examples) that operates like the system class INTEGER does?

No, because the objects that would belong to your class may already
belong to an existing system class; you'd have to define a subclass,
but there's no way to make the existing (potential) lisp objects be
instances of your own subclass.  Moreover, an object could not be
instance of several classes.


Nonetheless, in the case of ATOM there's a way to define a method
called only on these atoms:

(defmethod m ((an-atom t)) 
  (princ "Called only for atoms. "))

(defmethod m ((a-cons cons))
  (princ "Never called for atoms. "))

Since atom = (compose not consp).


-- 
__Pascal Bourguignon__
From: Slobodan Blazeski
Subject: Re: Is it possible to specialize method on type instead of class?
Date: 
Message-ID: <02010475-70f0-4964-9f35-0f762062df3d@e24g2000vbe.googlegroups.com>
On Jun 1, 6:14 pm, Kaz Kylheku <········@gmail.com> wrote:
> On 2009-06-01, Slobodan Blazeski <·················@gmail.com> wrote:
>
> > For example something like:
> > 104 >(defmethod foo ((i atom))
> >                    i)
>
> > Error: ATOM is not the name of a class
>
> Hi Bobi,
>
> Indeed atoms do not constitute a class. Philosophically, why not?  Because the
> set of atoms is negatively defined: anything and everything that is not a cons
> is an atom.
>
> (Okay, that's not really a reason; we could have a type, which would be
> an immediate subtype of T, from which all classes are understood
> to be derived, other than conses. But we don't.)
>
> So what we can do is write a method which captures all objects, and then a
> method which captures conses:
>
> ;; capture all objects
> (defmethod foo ((obj t))
>   )
>
> ;; capture conses
> (defmethod foo ((obj cons))
>  )
That's exactly what I'm doing. I have a method for sequences, arrays
and t. The problem is that I want to fail if user tries to dispatch on
say Hash-table or whatever is not defined as number,char,symbol .

bobi
>
> Since conses go to the more specific method, you can put atom-specific
> logic into the T specialization. The only way that the T specialization
> can be reached with a cons argument is if the cons specialization
> invokes (call-next-method). Just don't do that. :)