From: Sergio
Subject: Re: How make an abstract class in CLOS?
Date: 
Message-ID: <lTwW4.1683$Qk4.16609@telenews.teleline.es>
Thanks!!.
Well, i'm still thinking at C++ object system when i make CLOS algoritms.
CLOS, with it's generic functions seems to be different that C++ with
sending messages method, with methods encapsulated in class.

coming back to my question, when i asked for abstract class...
I have an OMT model with a superclase and several subclass. The subclass
share identical metods ( thay are in the superclass ) but implement a
specific method in each class. BUT I MUST FORBID make instances of the
superclase, because they are "incomplete" objects. Well, my brain makes
smoke when i translate from spanish to english so ... i hope you understand
me :(((

BYE.
Sergio escribi� en mensaje ...
>How can i make an abstract class using defclass?
>
>THANKS.
>
>
>

From: Anders Vinjar
Subject: Re: How make an abstract class in CLOS?
Date: 
Message-ID: <copg0r9wbve.fsf@clara.uio.no>
>>> "S" == Sergio  <········@teleline.es> writes:
    S> method in each class. BUT I MUST FORBID make instances of
    S> the superclase, because they are "incomplete"
    S> objects.

Lots of ways to do this.  You might want to specialize a :before
method for "initialize-instance" for the superclass in question.
From: Frode Vatvedt Fjeld
Subject: Re: How make an abstract class in CLOS?
Date: 
Message-ID: <2hln11b6cm.fsf@dslab7.cs.uit.no>
"Sergio" <········@teleline.es> writes:

> The subclass share identical metods ( thay are in the superclass )
> but implement a specific method in each class. BUT I MUST FORBID
> make instances of the superclase, because they are "incomplete"
> objects.

Lisp programmers tend to have faith in themselves not to make
instances of classes unless they have a reason to. So my first answer
would be "just don't make instances of it". If you really want to
prevent it, I guess you could do something like this:

(defmethod make-instance ((class abstract-class) &rest ignore)
  (warn "Someone tried to make an instance of abstract-class!")
  nil)

-- 
Frode Vatvedt Fjeld
From: Bj�rn Remseth
Subject: Re: How make an abstract class in CLOS?
Date: 
Message-ID: <sjfn1lhs01b.fsf@tyrfing.ifi.uio.no>
Frode Vatvedt Fjeld <······@acm.org> writes:

> Lisp programmers tend to have faith in themselves not to make
> instances of classes unless they have a reason to. So my first answer
> would be "just don't make instances of it". If you really want to
> prevent it, I guess you could do something like this:
> 
> (defmethod make-instance ((class abstract-class) &rest ignore)
>   (warn "Someone tried to make an instance of abstract-class!")
>   nil)

... or you could let some MOP hackery to do it for you, but as you
say, it really is unecessary.

-- 
                                                    (Rmz)

Bj\o rn Remseth   !Institutt for Informatikk    !Net:  ···@ifi.uio.no
Phone:+47 91341332!Universitetet i Oslo, Norway !ICBM: N595625E104337
From: Tim Bradshaw
Subject: Re: How make an abstract class in CLOS?
Date: 
Message-ID: <ey3g0r99lmm.fsf@cley.com>
* Frode Vatvedt Fjeld wrote:
> Lisp programmers tend to have faith in themselves not to make
> instances of classes unless they have a reason to. So my first answer
> would be "just don't make instances of it". If you really want to
> prevent it, I guess you could do something like this:

> (defmethod make-instance ((class abstract-class) &rest ignore)
>   (warn "Someone tried to make an instance of abstract-class!")
>   nil)

You may be being more sophisticated than I'm assuming, but this won't
work unless you do MOPpery, because MAKE-INSTANCE is called with an
object which is the class of the object you want to make, and the
class of *that* object will be STANDARD-CLASS.

You can get around this without the MOP by having EQL methods for
MAKE-INSTANCE, but that's pretty horrid.

With the (or a) MOP it becomes very easy:

    (defclass abstract-class (standard-class)
      ())

    (defmethod make-instance ((class abstract-class) &rest junk)
      (declare (ignore junk))
      (error "Making an instance of an abstract class"))


    (defclass abstract-super ()
      (...)
      (:metaclass abstract-class))

    (defclass concrete-sub (abstract-super)
      (...))

or something like that should work.

--tim
From: Tim Moore
Subject: Re: How make an abstract class in CLOS?
Date: 
Message-ID: <8gf0b8$kfa$0@216.39.145.192>
On 23 May 2000, Tim Bradshaw wrote:

> You can get around this without the MOP by having EQL methods for
> MAKE-INSTANCE, but that's pretty horrid.
> 

How about a primary method on initialize-instance or shared-initialize?

(defmethod initialize-instance ((class abstract-class) &rest junk)
  (declare (ignore junk))
  (error "Someone tried to make an instance of abstract-class!"))

Tim
From: Tim Bradshaw
Subject: Re: How make an abstract class in CLOS?
Date: 
Message-ID: <ey33dn8an9t.fsf@cley.com>
* Tim Moore wrote:
> On 23 May 2000, Tim Bradshaw wrote:
>> You can get around this without the MOP by having EQL methods for
>> MAKE-INSTANCE, but that's pretty horrid.
>> 

> How about a primary method on initialize-instance or shared-initialize?

> (defmethod initialize-instance ((class abstract-class) &rest junk)
>   (declare (ignore junk))
>   (error "Someone tried to make an instance of abstract-class!"))

This makes all subclasses of ABSTRACT-CLASS noninstantiable, which is
unlikely to be what you want.

--tim
From: Tim Moore
Subject: Re: How make an abstract class in CLOS?
Date: 
Message-ID: <8gfsun$1ao$0@216.39.145.192>
On 23 May 2000, Tim Bradshaw wrote:

> * Tim Moore wrote:
> > How about a primary method on initialize-instance or shared-initialize?
> 
> > (defmethod initialize-instance ((class abstract-class) &rest junk)
> >   (declare (ignore junk))
> >   (error "Someone tried to make an instance of abstract-class!"))
> 
> This makes all subclasses of ABSTRACT-CLASS noninstantiable, which is
> unlikely to be what you want.

Damn, you're right.  Somehow I thought that a new initialize-instance
method got defined for each class, but on further reflection that couldn't
be right.  Shows what I know.

Tim
From: Raymond Toy
Subject: Re: How make an abstract class in CLOS?
Date: 
Message-ID: <4nhfbokvdk.fsf@rtp.ericsson.se>
>>>>> "Tim" == Tim Moore <·····@herschel.bricoworks.com> writes:

    Tim> On 23 May 2000, Tim Bradshaw wrote:
    >> * Tim Moore wrote:
    >> > How about a primary method on initialize-instance or shared-initialize?
    >> 
    >> > (defmethod initialize-instance ((class abstract-class) &rest junk)
    >> >   (declare (ignore junk))
    >> >   (error "Someone tried to make an instance of abstract-class!"))
    >> 
    >> This makes all subclasses of ABSTRACT-CLASS noninstantiable, which is
    >> unlikely to be what you want.

    Tim> Damn, you're right.  Somehow I thought that a new initialize-instance
    Tim> method got defined for each class, but on further reflection that couldn't
    Tim> be right.  Shows what I know.

Now I'm confused.  Why wouldn't an initialize-instance specialized to
a sub-class of abstract-class do the right thing?  Only when there is
no initialize-instance for the sub-class would the method for
abstract-class be called and produce an error right?

Ray
From: Tim Bradshaw
Subject: Re: How make an abstract class in CLOS?
Date: 
Message-ID: <ey3vh04863y.fsf@cley.com>
* Raymond Toy wrote:
>>>>>> "Tim" == Tim Moore <·····@herschel.bricoworks.com> writes:

> Now I'm confused.  Why wouldn't an initialize-instance specialized to
> a sub-class of abstract-class do the right thing?  Only when there is
> no initialize-instance for the sub-class would the method for
> abstract-class be called and produce an error right?

Yes, but you can't write this method-of-the-subclass, because you
don't know what it should do.  The default primary method for
INITIALIZE-INSTANCE is system-supplied, and although there's
information about what it does (call SHARED-INITIALIZE), it's not
clear to me that that is *all* it does.  The obvious approach to
overriding the default primary method would be something that at some
point does (CALL-NEXT-METHOD) to make sure the default behaviour
happens (or just define an :AFTER method in the normal way...), but
this won't work in this case because you have to hop over (several
levels of) superclass to actually get at the method you want to call.

Actually, I think I'm wrong about all this -- hyperspec Section 7.1.7
seems to mean that it is the case that all INITIALIZE-INSTANCE does is
call SHARED-INITIALIZE, so you could define your own methods for it.
(I guess I should elide all the previous para now...).

It would still be a bit clunky I think as you'd either have to do some
cleverness with mixing classes (define a method signalling an error on
ABSTRACT-CLASS, and one that does the default thing on
NON-ABSTRACT-CLASS, then you can define non-abstract subclasses by
ensuring NON-ABSTRACT-CLASS ends up ahead of ABSTRACT-CLASS in the
CPL:

	(defclass noninstantiable (... abstract-class ...) ...)
	(defclass instantiable (... non-abstract-class
				... noninstantiable ...) ...)

) or define lots of methods for INITIALIZE-INSTANCE for all the
subclasses.

--tim
From: Raymond Toy
Subject: Re: How make an abstract class in CLOS?
Date: 
Message-ID: <4n66s3llj0.fsf@rtp.ericsson.se>
>>>>> "Tim" == Tim Bradshaw <···@cley.com> writes:

    Tim> Yes, but you can't write this method-of-the-subclass, because you
    Tim> don't know what it should do.  The default primary method for
    Tim> INITIALIZE-INSTANCE is system-supplied, and although there's
    Tim> information about what it does (call SHARED-INITIALIZE), it's not
    Tim> clear to me that that is *all* it does.  The obvious approach to
    Tim> overriding the default primary method would be something that at some
    Tim> point does (CALL-NEXT-METHOD) to make sure the default behaviour
    Tim> happens (or just define an :AFTER method in the normal way...), but
    Tim> this won't work in this case because you have to hop over (several
    Tim> levels of) superclass to actually get at the method you want to call.

    Tim> Actually, I think I'm wrong about all this -- hyperspec Section 7.1.7
    Tim> seems to mean that it is the case that all INITIALIZE-INSTANCE does is
    Tim> call SHARED-INITIALIZE, so you could define your own methods for it.
    Tim> (I guess I should elide all the previous para now...).

Yes, if I delete that paragraph, I feel much better about my limited
understanding of CLOS---I wasn't totally off base. :-)

    Tim> It would still be a bit clunky I think as you'd either have to do some
    Tim> cleverness with mixing classes (define a method signalling an error on
    Tim> ABSTRACT-CLASS, and one that does the default thing on
    Tim> NON-ABSTRACT-CLASS, then you can define non-abstract subclasses by
    Tim> ensuring NON-ABSTRACT-CLASS ends up ahead of ABSTRACT-CLASS in the
    Tim> CPL:

    Tim> 	(defclass noninstantiable (... abstract-class ...) ...)
    Tim> 	(defclass instantiable (... non-abstract-class
    Tim> 				... noninstantiable ...) ...)

    Tim> ) or define lots of methods for INITIALIZE-INSTANCE for all the
    Tim> subclasses.

Yes, this sounds quite messy if you really want to use abstract-class
with multiple-inheritance.  Fortunately, I haven't had any reason to
go down that path with my CLOS stuff.

Ray
From: Frode Vatvedt Fjeld
Subject: Re: How make an abstract class in CLOS?
Date: 
Message-ID: <2hd7mcc437.fsf@dslab7.cs.uit.no>
Tim Bradshaw <···@cley.com> writes:

> You can get around this without the MOP by having EQL methods for
> MAKE-INSTANCE, but that's pretty horrid.

Yes, I made a slight mistake, but I don't really think eql
specialization is so bad:

(defmethod make-instance ((class (eql (find-class abstract-class))) &rest ignore)
  (warn "Don't do this.")
  nil)


It also occurred to me that the equivalent of an abstract class in CL
would be a generic function for which there is no applicable method
(given some particular arguments). The need to "forbid" this in other
languages can maybe partly be attributed to the fact that they often
don't have run-time error handling (conditions), hence the problem
_must_ be tackled at compile-time, if at all.

-- 
Frode Vatvedt Fjeld
From: Tim Bradshaw
Subject: Re: How make an abstract class in CLOS?
Date: 
Message-ID: <ey366s4ap09.fsf@cley.com>
* Frode Vatvedt Fjeld wrote:
> Tim Bradshaw <···@cley.com> writes:
>> You can get around this without the MOP by having EQL methods for
>> MAKE-INSTANCE, but that's pretty horrid.

> Yes, I made a slight mistake, but I don't really think eql
> specialization is so bad:

> (defmethod make-instance ((class (eql (find-class abstract-class))) &rest ignore)
>   (warn "Don't do this.")
>   nil)

It probably is bad in that it's likely to make MAKE-INSTANCE be slower
for all calls, and that may be on all sorts of critical paths.

(I'm not sure enough about implementation techniques here to be sure
it really does make it slow, but I've certainly heard it claimed that
it may.)

Anyway, the MOPpy solution is kind of easy enough that it's tempting
to use that on systems with enough MOP.
From: Frode Vatvedt Fjeld
Subject: Re: How make an abstract class in CLOS?
Date: 
Message-ID: <2h8zx0batn.fsf@dslab7.cs.uit.no>
Tim Bradshaw <···@cley.com> writes:

> It probably is bad in that it's likely to make MAKE-INSTANCE be slower
> for all calls, and that may be on all sorts of critical paths.
> [...]
> Anyway, the MOPpy solution is kind of easy enough that it's tempting
> to use that on systems with enough MOP.

Well, when you give an example and say "don't do this", subtle points
about performance are not really a concern. That said, I'd guess that
EQL-specialization is much faster than class-specialization, since it
involves a single pointer comparison (I'm still guessing) rather than
looking up some class hierarchy.

-- 
Frode Vatvedt Fjeld
From: Tim Bradshaw
Subject: Re: How make an abstract class in CLOS?
Date: 
Message-ID: <ey3ya5089md.fsf@cley.com>
* Frode Vatvedt Fjeld wrote:

> Well, when you give an example and say "don't do this", subtle points
> about performance are not really a concern. 

Yes, I'm sorry if I implied anything I didn't mean to.

> That said, I'd guess that
> EQL-specialization is much faster than class-specialization, since it
> involves a single pointer comparison (I'm still guessing) rather than
> looking up some class hierarchy.

I'm not sure, I'd actually like to know this.  My intuition is that
it's slower, but I think that `intuition' may be the result of people
*saying* it's slower rather than any actual feeling for how CLOS
works, and that in turn may be because it was slow in PCL or
something.  If any implementors read this I'd like to know the real
story for a modern CLOS implementation.

I tried it on ACL (MAKE-INSTANCE with an EQL method never used vs
MAKE-INSTANCE with a method specialised on a metaclass which is never
used), and I can't measure any difference -- the time is probably
dominated by all the consing and initialisation rather than dispatch.
So as far as that goes, I was wrong.

--tim
From: Jeff Dalton
Subject: Re: How make an abstract class in CLOS?
Date: 
Message-ID: <x2k8gkau8c.fsf@todday.aiai.ed.ac.uk>
Tim Bradshaw <···@cley.com> writes:

> * Frode Vatvedt Fjeld wrote:

> > ... I'd guess that
> > EQL-specialization is much faster than class-specialization, since it
> > involves a single pointer comparison (I'm still guessing) rather than
> > looking up some class hierarchy.

Any reasonable CLOS implementation would avoid any time-consuming
lookup in the class hierarchy, at least most of the time.  I'm not
sure how sophisticated CLOS implementations get, but I'd expect
them (a) to cache the results of any slow method lookup and (b) to
use "special" dispatchers that "knew" something about what methods
had been defined.

So for instance if all the specialisation was EQL, a dispatcher that
handled that case efficiently could be installed. 

Remember that for EQL-specialization, there might be different methods
for different objects, just as their might be different methods for
different classes.  The chief difference is that to find the method
based on the class of the argument, you have to extract the class of
the argument, which could be as simple as one memory reference.
(Even that might be avoided if the generic function thought it
was going to see the same argument value often enough, since it
could associate the method with the object rather than its class,
rather as if the method had been EQL-specialised.)

> I'm not sure, I'd actually like to know this.  

So would I.  My guess is that less effort has been put into optimising
the cases that involve EQL-specialisation.

-- jeff
From: Hartmann Schaffer
Subject: Re: How make an abstract class in CLOS?
Date: 
Message-ID: <392ac3cc@news.sentex.net>
In article <····················@telenews.teleline.es>,
	"Sergio" <········@teleline.es> writes:
> Thanks!!.
> Well, i'm still thinking at C++ object system when i make CLOS algoritms.
> CLOS, with it's generic functions seems to be different that C++ with
> sending messages method, with methods encapsulated in class.
> 
> coming back to my question, when i asked for abstract class...
> I have an OMT model with a superclase and several subclass. The subclass
> share identical metods ( thay are in the superclass ) but implement a
> specific method in each class. BUT I MUST FORBID make instances of the
> superclase, because they are "incomplete" objects. Well, my brain makes

how about defining a meke method rhat raises an error (i am sure that is
possible, but my referennce is on a machine that currently is down))

> smoke when i translate from spanish to english so ... i hope you understand
> me :(((


-- 

Hartmann Schaffer