Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Preventing a class from being instantiated

218 views
Skip to first unread message

James A. Crippen

unread,
Nov 28, 2001, 9:40:07 PM11/28/01
to
How do I prevent a class from being instantiated under any
circumstances? I am constructing a largish class tree and the
rootmost classes are really only meant as umbrella classes that
shouldn't be instantiated at any time. I'm not sure exactly how to
prevent them from being instantiated, however. Any ideas?

'james

--
James A. Crippen <ja...@unlambda.com> ,-./-. Anchorage, Alaska,
Lambda Unlimited: Recursion 'R' Us | |/ | USA, 61.20939N, -149.767W
Y = \f.(\x.f(xx)) (\x.f(xx)) | |\ | Earth, Sol System,
Y(F) = F(Y(F)) \_,-_/ Milky Way.

Bruce Hoult

unread,
Nov 28, 2001, 9:53:04 PM11/28/01
to
In article <m3vgfu5...@kappa.unlambda.com>, ja...@unlambda.com
(James A. Crippen) wrote:

> How do I prevent a class from being instantiated under any
> circumstances? I am constructing a largish class tree and the
> rootmost classes are really only meant as umbrella classes that
> shouldn't be instantiated at any time. I'm not sure exactly how to
> prevent them from being instantiated, however. Any ideas?

Presumably you can add a method to make-instance, specialized on the
class object a a singleton, and have that method throw an error.

-- Bruce

Wade Humeniuk

unread,
Nov 28, 2001, 9:54:01 PM11/28/01
to
> How do I prevent a class from being instantiated under any
> circumstances? I am constructing a largish class tree and the
> rootmost classes are really only meant as umbrella classes that
> shouldn't be instantiated at any time. I'm not sure exactly how to
> prevent them from being instantiated, however. Any ideas?

I assume you are asking the CLOS counterpart to C++ abstract classes. How
would it be possible in your application to arbitrarily instantiate any
class?

Solution #1 This is not meant to be flippant.
Just never write any code that instantiates the class.

Solution #2

(defmethod initialize-instance :before ((obj forbidden-abstract-class) &rest
initargs)
(error "Cannot Instatiate Abstract Class"))

Wade


Kaz Kylheku

unread,
Nov 28, 2001, 10:27:25 PM11/28/01
to
In article <m3vgfu5...@kappa.unlambda.com>, James A. Crippen wrote:
>How do I prevent a class from being instantiated under any
>circumstances?

One good way is not to write that class, and consequently not
encumber the user of the class with your restrictions.

> I am constructing a largish class tree and the
>rootmost classes are really only meant as umbrella classes that
>shouldn't be instantiated at any time. I'm not sure exactly how to
>prevent them from being instantiated, however. Any ideas?

How about writing some documentation which describe the purpose
of your classes according to your view of the world as their author.
People that agree will then not instantiate them.

Kenny Tilton

unread,
Nov 28, 2001, 11:25:35 PM11/28/01
to
(defmethod initialize-instance :before ((self abstract-only) &key)
(assert (not (eql (type-of self 'abstract-only)))))

if you have this concern a lot, you can define a macro:

(defmacro abstractify (classname)
`(defmethod initialize-instance :before ((self ,classname) ..etc..

an approach from the other direction would be:

(defclass rootmost ..whatever)

(defmethod i-i :before ((self rootmost) &key instantiable
&allow-other-keys))
(assert instantiable))

(defclass instantiable ()
()
(:default-initargs :instantiable t))

then inherit instantiable as needed. or flip the arrow with an ABSTRACT
mixin class.

if you want fully to recreate C++ under CL, maybe a metaclass would be
in order.

kenny
clinisys

Pierre R. Mai

unread,
Nov 28, 2001, 11:09:29 PM11/28/01
to
"Wade Humeniuk" <hume...@cadvision.com> writes:

> > How do I prevent a class from being instantiated under any
> > circumstances? I am constructing a largish class tree and the
> > rootmost classes are really only meant as umbrella classes that
> > shouldn't be instantiated at any time. I'm not sure exactly how to
> > prevent them from being instantiated, however. Any ideas?

> Solution #2


>
> (defmethod initialize-instance :before ((obj forbidden-abstract-class) &rest
> initargs)
> (error "Cannot Instatiate Abstract Class"))

That will not work, because the method will also be called for
instances of subclasses.

You probably want to define an eql-method on make-instance instead:

(defmethod make-instance
((class (eql (find-class 'forbidden-abstract-class))) &rest initargs)


(error "Cannot Instatiate Abstract Class"))

[ Sidenote: In CMU CL you need to use pcl::find-class here ]

Regs, Pierre.

--
Pierre R. Mai <pm...@acm.org> http://www.pmsf.de/pmai/
The most likely way for the world to be destroyed, most experts agree,
is by accident. That's where we come in; we're computer professionals.
We cause accidents. -- Nathaniel Borenstein

Wade Humeniuk

unread,
Nov 29, 2001, 12:17:06 AM11/29/01
to
>
> That will not work, because the method will also be called for
> instances of subclasses.
>

Yah, you are right.

> You probably want to define an eql-method on make-instance instead:
>
> (defmethod make-instance
> ((class (eql (find-class 'forbidden-abstract-class))) &rest initargs)
> (error "Cannot Instatiate Abstract Class"))

This is better because the error is signalled before much CLOS machinery
gets executed.

Wade


James A. Crippen

unread,
Nov 29, 2001, 3:42:55 AM11/29/01
to
"Pierre R. Mai" <pm...@acm.org> writes:

> "Wade Humeniuk" <hume...@cadvision.com> writes:
>
> > > How do I prevent a class from being instantiated under any
> > > circumstances? I am constructing a largish class tree and the
> > > rootmost classes are really only meant as umbrella classes that
> > > shouldn't be instantiated at any time. I'm not sure exactly how to
> > > prevent them from being instantiated, however. Any ideas?
>
> > Solution #2
> >
> > (defmethod initialize-instance :before ((obj forbidden-abstract-class) &rest
> > initargs)
> > (error "Cannot Instatiate Abstract Class"))
>
> That will not work, because the method will also be called for
> instances of subclasses.
>
> You probably want to define an eql-method on make-instance instead:
>
> (defmethod make-instance
> ((class (eql (find-class 'forbidden-abstract-class))) &rest initargs)
> (error "Cannot Instatiate Abstract Class"))

I'll try this. The system is designed to be dynamically extensible by
somewhat random users so I can't just rely on not writing code that
instantiates. Some random user might get it in their head to try
instantiating one of these abstract classes and then various
assumptions in the rest of the system (that I'd rather not have to
explicitly check for) would be invalid.

Of course if I have to extend make-instance the question arises
whether this might be costly. I expect to see lots of instantiation
with no regular pattern during use, so I suppose that I have to decide
which would cost more in the long term: writing explicit checks all
over where assumptions are being made, or slowing down the
make-instance generic with an extra eql method.

Bruce Hoult

unread,
Nov 29, 2001, 6:57:26 AM11/29/01
to
In article <m3r8qi5...@kappa.unlambda.com>, ja...@unlambda.com
(James A. Crippen) wrote:

> Of course if I have to extend make-instance the question arises
> whether this might be costly. I expect to see lots of instantiation
> with no regular pattern during use, so I suppose that I have to decide
> which would cost more in the long term: writing explicit checks all
> over where assumptions are being made, or slowing down the
> make-instance generic with an extra eql method.

The reasonable implementation of eql method dispatch is a hash table,
the speed of which should not depend on the number of methods.

-- Bruce

Francis Leboutte

unread,
Nov 29, 2001, 7:32:48 AM11/29/01
to
ja...@unlambda.com (James A. Crippen) wrote:

>"Pierre R. Mai" <pm...@acm.org> writes:
>
>> You probably want to define an eql-method on make-instance instead:
>>
>> (defmethod make-instance
>> ((class (eql (find-class 'forbidden-abstract-class))) &rest initargs)
>> (error "Cannot Instatiate Abstract Class"))
>
>I'll try this. The system is designed to be dynamically extensible by
>somewhat random users so I can't just rely on not writing code that
>instantiates. Some random user might get it in their head to try
>instantiating one of these abstract classes and then various
>assumptions in the rest of the system (that I'd rather not have to
>explicitly check for) would be invalid.

Another possibility using a mixin and MOP (a class is an
abstract-class if the mixin is one of its direct superclasses):

(defclass abstract-class-mixin ()
())

(defmethod initialize-instance :before ((object
abstract-class-mixin) &key)
(when (member 'abstract-class-mixin
(mop:class-direct-superclasses (class-of object))
:key #'class-name
:test #'eq)
(error "Can not instantiate abstract-class")))

(defclass abstract-class-1 (abstract-class-mixin)
())

It is easy to use. Makes also easy to collect or browse all the
abstract classes

You could define a macro such as :
(def-abstract abstract-class-1 ()
())

This will allow to change easily the implementation if performance is
a problem.

>Of course if I have to extend make-instance the question arises
>whether this might be costly. I expect to see lots of instantiation
>with no regular pattern during use, so I suppose that I have to decide
>which would cost more in the long term: writing explicit checks all
>over where assumptions are being made, or slowing down the
>make-instance generic with an extra eql method.
>
>'james

--
www.algo.be
Logo programming : www.algo.be/logo.html

Tim Bradshaw

unread,
Nov 29, 2001, 7:49:29 AM11/29/01
to
ja...@unlambda.com (James A. Crippen) wrote in message news:<m3vgfu5...@kappa.unlambda.com>...

> How do I prevent a class from being instantiated under any
> circumstances? I am constructing a largish class tree and the
> rootmost classes are really only meant as umbrella classes that
> shouldn't be instantiated at any time. I'm not sure exactly how to
> prevent them from being instantiated, however. Any ideas?

Have a look at my abstract-class (no instances) / final-class (no
subclasses) stuff. It uses the MOP but is known to work in at least
ACL, LW, and CMUCL (and genera, or so the source claims!).

It's at http://www.tfeb.org/lisp/hax.html#ABSTRACT-CLASSES (this URL
will likely change as I have a huge chunk of stuff I want to put up
there and reorganise it all, but probably there will be a forwarding
pointer at least, and anyway it will be about 10 years before I get
around to doing it...)

--tim

Tim Bradshaw

unread,
Nov 29, 2001, 11:19:34 AM11/29/01
to
Bruce Hoult <br...@hoult.org> wrote in message news:<bruce-6D9621....@news.paradise.net.nz>...

>
> The reasonable implementation of eql method dispatch is a hash table,
> the speed of which should not depend on the number of methods.

Yes, but the reasonable implementation of MAKE-INSTANCE with a known
argument is often inlined code...

--tim

Sunil Mishra

unread,
Nov 29, 2001, 12:02:29 PM11/29/01
to
Funny thing is, despite all this work, you would still have to worry
about someone calling change-class on any old instance... Wonder if
sticking the error message on to shared-initialize might help?

I'm with those that think disallowing instantiation might not be such a
great thing to try. Getting into the MOP is relying on a vendor-specific
standard, and thus has its own problems. The only other reliable way I
can think of is to list every function that might be used to create or
modify the instance, and stick an error message on to it.

[ The rest of this message is directed at James Crippen, the original
poster...]

And before doing so, I'd ask myself if it is worth the trouble... The
reason for the meta question is that it is highly improbable that lisp
programmers would try to instantiate the root class instance, if you
advise against it in your documentation. (What would they do with it
anyway?) What you might be looking for is the detection of accidents. I
don't think that should be your responsibility, at least while you are
dealing with decent lisp programmers. Now, if you are using this as a
pedagogical tool, or aiming it at other lisp newbies, it might be a
worthwhile goal. But that doesn't sound like what you are doing either.

Perhaps we ought to help with your intent rather than the question you ask?

Sunil

Marco Antoniotti

unread,
Nov 29, 2001, 12:57:18 PM11/29/01
to

Sunil Mishra <smi...@notmyemail.com> writes:

> Funny thing is, despite all this work, you would still have to worry
> about someone calling change-class on any old instance... Wonder if
> sticking the error message on to shared-initialize might help?

CHANGE-CLASS is a generic function as well, you can always "block"
that using the same EQL trick you use on MAKE-INSTANCE.

All in all I think MAKE-INSTANCE and CHANGE-CLASS are the right places
where to intervene, since the are not operating on an instance yet.

Of course it's two places to change....

Cheers

--
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group tel. +1 - 212 - 998 3488
719 Broadway 12th Floor fax +1 - 212 - 995 4122
New York, NY 10003, USA http://bioinformatics.cat.nyu.edu
"Hello New York! We'll do what we can!"
Bill Murray in `Ghostbusters'.

Pierre R. Mai

unread,
Nov 29, 2001, 1:00:14 PM11/29/01
to
tfb+g...@tfeb.org (Tim Bradshaw) writes:

But if the argument is known, having a non-matching method will not
inhibit that expansion from happening (the expansion will still have
to check for new methods at run-time at any rate).

And the speed of cases where the eql method matches is not very
relevant, given that an error will be raised... ;)

Pierre R. Mai

unread,
Nov 29, 2001, 1:20:43 PM11/29/01
to
ja...@unlambda.com (James A. Crippen) writes:

> I'll try this. The system is designed to be dynamically extensible by
> somewhat random users so I can't just rely on not writing code that
> instantiates. Some random user might get it in their head to try
> instantiating one of these abstract classes and then various
> assumptions in the rest of the system (that I'd rather not have to
> explicitly check for) would be invalid.

When feasible, it would be better to ensure that the "abstract"
classes do meet the assumptions, maybe by providing "harmless"
defaults.

If not then doing the make-instance hack, or something similar is
probably your best bet.

> Of course if I have to extend make-instance the question arises
> whether this might be costly. I expect to see lots of instantiation
> with no regular pattern during use, so I suppose that I have to decide
> which would cost more in the long term: writing explicit checks all
> over where assumptions are being made, or slowing down the
> make-instance generic with an extra eql method.

I don't think that defining such an eql method will have a noticable
effect on make-instance calls. On CMUCL, there is no effect in calls
with either constant or dynamic class arguments.

It usually pays to not worry about CLOS performance, except for the
very tightest inner loops.

Bruce Hoult

unread,
Nov 29, 2001, 5:14:21 PM11/29/01
to
In article <fbc0f5d1.01112...@posting.google.com>,
tfb+g...@tfeb.org (Tim Bradshaw) wrote:

Right. The table lookup is then done at compile-time. Maybe that's not
so easy to do in CL, but in a language with sealing declarations it's
possible (and common) to add a method to make() and still get inline
code. It's quite common for Dylan programs to have abstract classes
which overide make() to return an instance of a concrete subclass e.g.
make(<vector>) returns a <simple-object-vector>.

I guess I should try it with CMUCL, and see what happens...

-- Bruce

Robert Monfera

unread,
Nov 29, 2001, 8:06:03 PM11/29/01
to
Wade Humeniuk wrote:

>>How do I prevent a class from being instantiated under any
>>circumstances? I am constructing a largish class tree and the
>>rootmost classes are really only meant as umbrella classes that
>>shouldn't be instantiated at any time. I'm not sure exactly how to
>>prevent them from being instantiated, however. Any ideas?

> Solution #2
>
> (defmethod initialize-instance :before ((obj forbidden-abstract-class) &rest
> initargs)
> (error "Cannot Instatiate Abstract Class"))


You mean :around
Robert

Pierre R. Mai

unread,
Nov 29, 2001, 8:22:05 PM11/29/01
to
Bruce Hoult <br...@hoult.org> writes:

> In article <fbc0f5d1.01112...@posting.google.com>,
> tfb+g...@tfeb.org (Tim Bradshaw) wrote:
>
> > Bruce Hoult <br...@hoult.org> wrote in message
> > news:<bruce-6D9621....@news.paradise.net.nz>...
> > >
> > > The reasonable implementation of eql method dispatch is a hash table,
> > > the speed of which should not depend on the number of methods.
> >
> > Yes, but the reasonable implementation of MAKE-INSTANCE with a known
> > argument is often inlined code...
>
> Right. The table lookup is then done at compile-time. Maybe that's not
> so easy to do in CL, but in a language with sealing declarations it's
> possible (and common) to add a method to make() and still get inline
> code. It's quite common for Dylan programs to have abstract classes

I fail to see how sealing is relevant in this context. make can't be
a sealed GF, so it is possible that methods are added and removed at
run-time. Hence the compiler can IMHO only tentatively inline the
code, bailing out to a more general mechanism at run-time if any
relevant methods have been added/removed.

The situation is identical in CL.

[There are differences, in that the inlined code will also have to
check for changes in the class-hierarchy (including the effects of
class redefinition), which Dylan can sometimes avoid, given sealing
declarations for the relevant classes. That shouldn't come into play
here at all]

> I guess I should try it with CMUCL, and see what happens...

See my other message in this thread.

Bruce Hoult

unread,
Nov 29, 2001, 9:58:34 PM11/29/01
to
In article <87snaxv...@orion.bln.pmsf.de>, "Pierre R. Mai"
<pm...@acm.org> wrote:

> Bruce Hoult <br...@hoult.org> writes:
>
> > In article <fbc0f5d1.01112...@posting.google.com>,
> > tfb+g...@tfeb.org (Tim Bradshaw) wrote:
> >
> > > Bruce Hoult <br...@hoult.org> wrote in message
> > > news:<bruce-6D9621....@news.paradise.net.nz>...
> > > >
> > > > The reasonable implementation of eql method dispatch is a hash
> > > > table,
> > > > the speed of which should not depend on the number of methods.
> > >
> > > Yes, but the reasonable implementation of MAKE-INSTANCE with a known
> > > argument is often inlined code...
> >
> > Right. The table lookup is then done at compile-time. Maybe that's
> > not
> > so easy to do in CL, but in a language with sealing declarations it's
> > possible (and common) to add a method to make() and still get inline
> > code. It's quite common for Dylan programs to have abstract classes
>
> I fail to see how sealing is relevant in this context. make can't be
> a sealed GF, so it is possible that methods are added and removed at
> run-time. Hence the compiler can IMHO only tentatively inline the
> code, bailing out to a more general mechanism at run-time if any
> relevant methods have been added/removed.
>
> The situation is identical in CL.

No, because sealing the whole GF isn't the only option -- in Dylan you
can seal only *part* of the GF.

It very common in high peformance Dylan code to see this idiom: (example
from
http://berlin.ccc.de/cgi-bin/cvsweb/gd/examples/ICFP2001/src/attributes.d
ylan?rev=1.13):


define functional class <attribute> (<object>)
slot value :: <integer> = 0,
init-keyword: value:;
end class <attribute>;

define sealed domain make(singleton(<attribute>));
define sealed domain initialize(<attribute>);


With these declarations, "make" and "initialize" are inlined and don't
check anything, even though their GFs are open. Anything in another
library or at runtime that would invalidate the assumptions made by this
optimization will throw an error, so safety is maintained.

"functional" is an extension to the DRM language spec. It enables
objects of the class to be stored on the stack and passed by copying
rather than allocating them on the heap and passing them by reference.
e.g. it causes "eq" to be defined as the same as "equal". Sometimes
this is a win, sometimes it isn't. In this case it proves to be a big
big win.


> [There are differences, in that the inlined code will also have to
> check for changes in the class-hierarchy (including the effects of
> class redefinition), which Dylan can sometimes avoid, given sealing
> declarations for the relevant classes. That shouldn't come into play
> here at all]

"define sealed domain" was a relatively recent addition to Dylan, but
has been there about as long as the infix syntax, I think. In the Apple
Technology Release compiler and documentation (the prelinimary DRM) it
was called "define inert domain", but it appears to be exactly the same
feature.

Adding the "sealed" attribute to a slot applies "define sealed domain"
to its getter and setter GFs. Adding the "sealed" attribute to a method
applies "define sealed domain" to that GF with those argument types.


> > I guess I should try it with CMUCL, and see what happens...
>
> See my other message in this thread.

Yep, saw that later.

-- Bruce

James A. Crippen

unread,
Nov 29, 2001, 10:15:08 PM11/29/01
to
From what everyone on this thread has said, I've come to the
conclusion that the best thing I can do is make it very clear to the
users that instantiation of the abstract classes is a bad thing,
noting it in documentation and source code. Also, adding some checks
for assumptions about the abstractness of classes in the places where
it will do the most good for preventing mistakes. Being Lisp I'm not
going to write *everything* in the style of an overdefensive C
programmer, but I won't gratuitously assume that everything in the
system is in perfect working order.

I'm with those people who feel that mucking with the MOP is a bad idea
because of the inherent portability problems that can occur. I'd
really rather not end up having to debug MOP problems that could have
been avoided otherwise.

Bruce Hoult

unread,
Nov 29, 2001, 10:38:44 PM11/29/01
to
In article <m38zcp5...@kappa.unlambda.com>, ja...@unlambda.com
(James A. Crippen) wrote:

> From what everyone on this thread has said, I've come to the
> conclusion that the best thing I can do is make it very clear to the
> users that instantiation of the abstract classes is a bad thing,
> noting it in documentation and source code.

Something no one has mentioned, and that I meant to but forgot...

Even if you add a method to, say, make-instance, there is nothing to
stop a determined user from removing it again, or adding their own
method that just calls next-method in place of yours.

Stroustrup says that the protection mechanisms in C++ are to prevent
accident, not fraud. I think that applies here too. If it was
important I think I'd probably add a method to make-instance rather than
rely *only* on the documentation. That's not totally foolproof as there
is always a bigger fool (cue: Erik), but it's probably enough.

-- Bruce

Kaz Kylheku

unread,
Nov 30, 2001, 12:08:12 AM11/30/01
to
In article <m38zcp5...@kappa.unlambda.com>, James A. Crippen wrote:
>From what everyone on this thread has said, I've come to the
>conclusion that the best thing I can do is make it very clear to the
>users that instantiation of the abstract classes is a bad thing,
>noting it in documentation and source code.

In Lisp, you don't need abstract classes, because an object doesn't
have to declare that it inherits a base class in order to be eligible
to implement the interface.

An interface in Lisp is, roughly, a collection of generic functions.
Methods provide the implementation; you define methods that take arguments
of your classes and that's it. There is no commonality that needs to be
factored out into bases that everyone must declare in their supeclass
list.

Interface bases are simply an artifact of a static type system. The whole
purpose of an abstract base class in C++ is to make its single dispatch
run fast; the program has something to aim a pointer at so it can get a
hold of a vtable, and indirectly call to the implementation of a virtual
function in some base somewhere. The type of the base class pointer,
along with other constraints in the language, provide static assurance
that the machine language translation can blindly index into the vtable
and perform an indirect call.

In other words, declaring inheritance from an empty base class,
or declaring that a class implemenets some interface, is a form of
optimization, like declaring a variable to be a certain kind of integer.
It has nothing to do with object-orientation.

Erik Naggum

unread,
Nov 30, 2001, 12:55:15 AM11/30/01
to
* James A. Crippen

| From what everyone on this thread has said, I've come to the conclusion
| that the best thing I can do is make it very clear to the users that
| instantiation of the abstract classes is a bad thing, noting it in
| documentation and source code. Also, adding some checks for assumptions
| about the abstractness of classes in the places where it will do the most
| good for preventing mistakes. Being Lisp I'm not going to write
| *everything* in the style of an overdefensive C programmer, but I won't
| gratuitously assume that everything in the system is in perfect working
| order.

The near hysterical need to protect programmers from doing stupid things
has always mystified me. E.g., if you need to control access to your
class slots with public, protected, and private, this only means that you
are telling too many people too much. If you give people a source file
that contains all the names of all the slots with a silly string to make
access difficult, all that your protection scheme relies on is that your
users are unable to edit that file, which is obviously nuts. Instead of
protecting yourself from problems, you force people who think you made a
mistake to edit the file or make a copy, and then they get out of synch.
Of course, people would go "oh, no, you should not do that" if you said
you had done this, but that is the core of this social protection scheme
-- it has _nothing_ to do with what is in those files. Since programmers
who want to add a method to a supposedly public class will have to engage
in header file editing, already, the threshold to do this is much lower
than one might think. Of course, maintaining "bit-level compatibility"
with other code compiled with the unedited header file is kind of hard,
and may lead to all sorts of hard-to-detect problems, but trust me, this
is done all the time, because the languages are so stupidly designed.

Common Lisp tends to assume that programmers are not lunatics who need to
be protected from themselves. So instead of forcing people to read and
then edit or copy "header files", they have the introspective abilities
they need right there in the development system. And Common Lisp folks
go "oh, no, you should not do that" if you use slot-value to access a
slot that has not be documented to be publicly accessible.

Similarly, the "pure abstract class" is a compile-time issue in some
"object-oriented" languages, but if you trust programmers not to do so
many stupid things, the only protection you need is already there: There
are presumably no generic functions that would dispatch on the class that
should never be instantiated. (This would apply to mixin-classes, for
instance, which are only supplying some new slots and/or supply a method
that is already known to exist in the classes they are mixed in with.)

In other words, you should already have the necessary mechanism in your
code if you simply omit methods that dispatch on the abstract class.
Is this not sufficient?

///
--
The past is not more important than the future, despite what your culture
has taught you. Your future observations, conclusions, and beliefs are
more important to you than those in your past ever will be. The world is
changing so fast the balance between the past and the future has shifted.

Erik Naggum

unread,
Nov 30, 2001, 1:10:23 AM11/30/01
to
* Bruce Hoult

| That's not totally foolproof as there is always a bigger fool (cue:
| Erik), but it's probably enough.

Are there really no psychiatrists near you who could help you get over
your coping problems? No friends or anybody else who cares about you who
could tell you to get over your personal problems? No girlfriend, not
even a _pet_ who can tell you that you have lost your mental balance?

You keep attacking me for no reason at all. I find your behavior pattern
evidence that you actually _are_ retarded, specifically: devoid of the
prerequisite intelligence to understand what you are doing to yourself.
Thus, you are not _able_ to control yourself, but will continue to make
similar idiotic remarks in the future, in order to prove that you are an
asshole on a mission. Your next idiotic remark of the same kind will be
the only proof we need of your mental state and that you should be put in
global kill-files.

Bruce Hoult

unread,
Nov 30, 2001, 1:30:04 AM11/30/01
to
In article <32160894...@naggum.net>, Erik Naggum <er...@naggum.net>
wrote:

> * Bruce Hoult
> | That's not totally foolproof as there is always a bigger fool (cue:
> | Erik), but it's probably enough.
>
> Are there really no psychiatrists near you who could help you get over
> your coping problems? No friends or anybody else who cares about you
> who
> could tell you to get over your personal problems? No girlfriend, not
> even a _pet_ who can tell you that you have lost your mental balance?

Friends, girlfriend, cat: check. Psychiatrists: no idea.


> You keep attacking me for no reason at all.

It's called a "joke", Erik.

-- Bruce

Erik Naggum

unread,
Nov 30, 2001, 1:49:53 AM11/30/01
to
* Bruce Hoult

| It's called a "joke", Erik.

Every idiot claims that what he said was a joke when he gets caught.

In any case: acquire some _taste_, you anti-social retard.

Please note: if you think the above is offensive, it is of course a joke
and you did not get it. If you do not find it offensive, it is of course
not a joke, and you did not get it. This is not a joke. Get it?

Bruce Hoult

unread,
Nov 30, 2001, 2:38:33 AM11/30/01
to
In article <32160917...@naggum.net>, Erik Naggum <er...@naggum.net>
wrote:

> * Bruce Hoult


> | It's called a "joke", Erik.
>
> Every idiot claims that what he said was a joke when he gets caught.

It was pretty obvious that it was a joke. You seem to take great
delight in calling me a retard or an idiot or a fool or mentally
unstable, and have done it -- sometimes at great length -- literally
dozens of times in this newsgroup, and probably more than half a dozen
times in the "nil" thread alone. For no better reason than that you
disagree with me on technical or political or perhaps rhetorical grounds.

I self-deprecatingly called myself a "fool" in order to save you the
bother of pointing it out YET again, and everyone else of reading it.
Not that that stopped you.


> Please note: if you think the above is offensive, it is of course
> a joke and you did not get it. If you do not find it offensive, it
> is of course not a joke, and you did not get it. This is not a
> joke. Get it?

Yep. It's offensive, and at the same time a standing joke.

-- Bruce

lars_lundback

unread,
Nov 30, 2001, 3:59:38 AM11/30/01
to

I don't get you.

It should be clear by now that there are few axioms in programming.
Like nil/null/false. Like when is something a pattern or a tools based
on observed patterns? One discovers these things through experience.


On Fri, 30 Nov 2001 20:38:33 +1300, Bruce Hoult <br...@hoult.org>
wrote:

>It was pretty obvious that it was a joke. You seem to take great
>delight in calling me a retard or an idiot or a fool or mentally
>unstable, and have done it -- sometimes at great length -- literally
>dozens of times in this newsgroup, and probably more than half a dozen
>times in the "nil" thread alone. For no better reason than that you
>disagree with me on technical or political or perhaps rhetorical grounds.

A fool is someone who acts foolishly in the eyes of others. The same
goes for an idiot.

Would you feel better if Erik (and others) consistently said "you act
foolishly, you say foolish things and you keep doing it regardless of
our responses"? Why do you perceive that "fool" and "idiot" are such
absolute damning terms that you must keep "defending" yourself at any
cost?

A few other posters to c.l.l arrive at this stage: endless clashes
with Erik. The reason is usually that they do not read him carefully
enough. Review the postings _carefully_ and if possible with neutral
eyes. You may see things in a new light ...

Lars


Janis Dzerins

unread,
Nov 30, 2001, 4:55:55 AM11/30/01
to
Bruce Hoult <br...@hoult.org> writes:

It is not a joke. Don't you really get it?

--
Janis Dzerins

Eat shit -- billions of flies can't be wrong.

Andreas Bogk

unread,
Nov 30, 2001, 8:40:37 AM11/30/01
to
Lars Lundback writes:

> Would you feel better if Erik (and others) consistently said "you act
> foolishly, you say foolish things and you keep doing it regardless of
> our responses"? Why do you perceive that "fool" and "idiot" are such
> absolute damning terms that you must keep "defending" yourself at any
> cost?

Well, how would you feel if someone keeps calling you retarded, a
lunatic, an idiot, a fool, imbecile? For no other reason than that
you disagree on a certain point?

As soon as one brings in an argument that's contradicting Eriks, he
starts calling people names, assuming that the only explanation is
that the guy on the other side is too stupid to understand *his*
argument. Even if this were true, his behaviour would be
unacceptable, much worse is that he doesn't even try to explain where
the contradiction is, let alone considering that it is *him* who might
be wrong, or that it may be his fault that the other person didn't
understand his argument, because he failed to communicate it properly.

> A few other posters to c.l.l arrive at this stage: endless clashes
> with Erik. The reason is usually that they do not read him carefully
> enough. Review the postings _carefully_ and if possible with neutral
> eyes. You may see things in a new light ...

I did. His intelligence seems to be above average, so some of the
things he writes actually make sense. It is unfortunate that this
makes him so arrogant that it is impossible to have a discussion with
him.

If somebody behaved like that in my team, I would fire him without
thinking twice about his intelligence. The possible damage to the
team is a bigger threat than having to find a replacement.

I will do as several people suggested to me in personal communication:
I'll just stop taking Erik seriously.

Andreas

--
"In my eyes it is never a crime to steal knowledge. It is a good
theft. The pirate of knowledge is a good pirate."
(Michel Serres)

Pierre R. Mai

unread,
Nov 30, 2001, 9:03:39 AM11/30/01
to
Bruce Hoult <br...@hoult.org> writes:

> > I fail to see how sealing is relevant in this context. make can't be
> > a sealed GF, so it is possible that methods are added and removed at
> > run-time. Hence the compiler can IMHO only tentatively inline the
> > code, bailing out to a more general mechanism at run-time if any
> > relevant methods have been added/removed.
> >
> > The situation is identical in CL.
>
> No, because sealing the whole GF isn't the only option -- in Dylan you
> can seal only *part* of the GF.

Sorry, I forgot that Dylan doesn't have method combinations (nor class
redefinition). With only known primary methods and an unchanging
class hierarchy, sealing does allow the check to be removed, of
course. With either of those features present, you would either have
to make onerous non-local restrictions based on the sealing
declaration, or you would still have to make the check.

> "define sealed domain" was a relatively recent addition to Dylan, but
> has been there about as long as the infix syntax, I think. In the Apple
> Technology Release compiler and documentation (the prelinimary DRM) it
> was called "define inert domain", but it appears to be exactly the same
> feature.

Yes, I was aware of the existence of that feature, but didn't make the
connection, due to my underlying assumption about the existence of at
least standard method combination.

Paolo Amoroso

unread,
Nov 30, 2001, 9:34:20 AM11/30/01
to
On Fri, 30 Nov 2001 05:55:15 GMT, Erik Naggum <er...@naggum.net> wrote:

> Common Lisp tends to assume that programmers are not lunatics who need to
> be protected from themselves. So instead of forcing people to read and

Since you indirectly mention the Moon, there's a potentially relevant
anecdote.

Early versions of the software of the Apollo Guidance Computer used on
Apollo spacecrafts, i.e. both the Command Module and the Lunar Module,
included lots of checks for preventing astronauts from performing
potentially dangerous manoeuvres.

The main contribution from astronauts--i.e. pilots--to the design was to
ask that all those checks be removed. As someone recently said in an
Apollo-related mailing list, think of what might have happened if the
Apollo 13 LM computer detected an "unusual" engine firing.


Paolo
--
EncyCMUCLopedia * Extensive collection of CMU Common Lisp documentation
http://web.mclink.it/amoroso/ency/README
[http://cvs2.cons.org:8000/cmucl/doc/EncyCMUCLopedia/]

Marco Antoniotti

unread,
Nov 30, 2001, 9:49:55 AM11/30/01
to

ja...@unlambda.com (James A. Crippen) writes:

> From what everyone on this thread has said, I've come to the
> conclusion that the best thing I can do is make it very clear to the
> users that instantiation of the abstract classes is a bad thing,
> noting it in documentation and source code. Also, adding some checks
> for assumptions about the abstractness of classes in the places where
> it will do the most good for preventing mistakes. Being Lisp I'm not
> going to write *everything* in the style of an overdefensive C
> programmer, but I won't gratuitously assume that everything in the
> system is in perfect working order.
>
> I'm with those people who feel that mucking with the MOP is a bad idea
> because of the inherent portability problems that can occur. I'd
> really rather not end up having to debug MOP problems that could have
> been avoided otherwise.

I still think that the methods on MAKE-INSTANCE and CHANGE-CLASS are a
good solution.

Kenny Tilton

unread,
Nov 30, 2001, 10:16:51 AM11/30/01
to

Paolo Amoroso wrote:
> The main contribution from astronauts--i.e. pilots--to the design was to
> ask that all those checks be removed. As someone recently said in an
> Apollo-related mailing list, think of what might have happened if the
> Apollo 13 LM computer detected an "unusual" engine firing.

Anyone else see that chilling video of a highly computerized airliner
(being tested so just crew fortunately) making a perfect three-point
landing into a forest as its pilots fought and failed to override the
computer?

On approach the pilots decided to abort and began a climb, but the
computer compensated and managed to complete the landing, tho the runway
was then a few miles back. :(

kenny
clinisys

Andreas Bogk

unread,
Nov 30, 2001, 10:32:23 AM11/30/01
to
"Pierre R. Mai" <pm...@acm.org> writes:

> Sorry, I forgot that Dylan doesn't have method combinations (nor class
> redefinition). With only known primary methods and an unchanging

Yes, it looks like method combinations are really a missing feature in
Dylan. Class redefinition worked in Apple Dylan's interactive
environment,as far as I can remember.

I wonder whether method combination could be introduced in Dylan
without a performance penalty. Lots of the Dylan design tradeoffs
revolve around insisting to have objects all the way down, while still
being able to generate fast code.

Kent M Pitman

unread,
Nov 30, 2001, 10:46:29 AM11/30/01
to
Andreas Bogk <and...@andreas.org> writes:

> If somebody behaved like that in my team, I would fire him without
> thinking twice about his intelligence. The possible damage to the
> team is a bigger threat than having to find a replacement.

[Just a philosophical aside, for those who like that kind of thing.
Those who don't, just skip this. No technical remarks enclosed.]

One thing I've learned in my time as a "language diplomat" (or whatever
inflated term I can get away with calling the one who gets elected to go
into voting situations with other members of the CL community :-), is this:

There is a BIG difference between a "team" (a company that can ruthlessly
demand its own way and fire anyone who doesn't agree) and a "community"
(especially a global community with multiple sovereigns, as occurs with the
national standards bodies, though it's really remarkably similiar, and
probably not accidentally so, at the intercorporate level within a nation,
at least within the US, where we allow companies to indulge pretty close to
the sense of absolute autonomy without government intervention in the name
of any greater good). That chief difference is that the people you don't
like and whose support you need in order to consider you have a team do not
work for you and cannot be fired. You are stuck with them. And they are
your tactical equal. So unless you learn to work with them, on those terms,
pleasant or not, you don't move ahead.

Incidentally, as an aside, this is the reason a charter document (such as
http://world.std.com/~pitman/CL/x3j13-86-020.html
is so important. It doesn't directly give power, but indirectly it does
because once someone has agreed to a premise (and everyone on the committee
had to buy into that one), cognitive dissonance becomes a powerful ally.
Being able to say "You promised you'd do x" is about the closest you can get
in a world where you can't fire anyone to saying "You must do x". But beyond
that, and common sense reasoning, no one in such a setting has power over
another.

As a further aside, this is the thing Perot never understood about US
politics. He always wanted to envision the US Government as a badly
run company, needing an executive to pull things together and
centralize orders. He really does not appear to grasp the notion of
separation of powers in the US government, and that there is a purpose
to having the US Congress not "answer to" the US president. The requirement
for consensus is what keeps dictatorships from forming.

Back to the original point, the inability to fire or ban people here
is what keeps monopolies (whether of commerce or of opinion) from
forming. The "team" here, if there is one at all, is not a group in
which you can replace people. That isn't the nature of free societies
nor even of consensus-based ruled societies. One has to live with the
cards one is dealt.

Erik Naggum

unread,
Nov 30, 2001, 12:32:14 PM11/30/01
to
* Andreas Bogk

| Well, how would you feel if someone keeps calling you retarded, a
| lunatic, an idiot, a fool, imbecile? For no other reason than that you
| disagree on a certain point?

It is never about disagreement. You were not called anything at all as
long as you _disagreed_. But this is quite typical. Those who actually
_are_ retarded think it is about disagreement, and they always resort to
this idiotic "argument".

A person who is a pathological liar does not just _disagree_ with others.
A thief who breaks into a person's house, does not merely _disagree_ with
him on the concept of property rights. Someone who drives under the
influence of drugs or alcohol does not just _disagree_ with the limits
and traffic rules. Yes, they probably _also_ disagree, but the criminal
mind is indeed marked by the failure to understand that disagreement is
not a reason for anybody to react harshly. Breaking rules and acting on
false premises, however, is. However, since you have a criminal mind,
and go on to prove it beyond reasonable doubt, you think that you are
being attacked for _disagreeing_ with the prevailing rules, as if it were
a free speech issue or you should have been respected for your "opinion".

Some people are so amazingly smart (by your standards) that they wonder
what happened when something unexpected occurs. You are not that smart.
That means that you react with an urge to defend yourself when you think
you see something hurtful to yourself. Only insecure _and_ stupid people
do that. Only people with _inflated_ egos respond violently when others
challenge their inflated egos with _facts_. Only people with _inflated_
egos respond violently when people _disagree_ with them, and therefore
think that others react to disagreement. Spread of disinformation is not
disagreement. Osama bin Laden does not "disagree" with George W. Bush on
the policies of the United States in the Middle East. Yet you can bet
that if he were half a smart as he is rumored to be, he will argue that
he "only expressed his disagreement" when defending himself and cannot
understand why he caused Afghanistan to be bombed.

| As soon as one brings in an argument that's contradicting Eriks, he
| starts calling people names, assuming that the only explanation is that
| the guy on the other side is too stupid to understand *his* argument.

This is again the typical defense made by retarded people. That it is in
fact false, that there is lots of available counter-evidence and that it
is so stupid a thing to say that it is more self-incriminating than
anything they have previously said or done, does not bother them. This
is about _making_up_ things to attack other people for, and then getting
more insistent when their victim objects to it.

Exaggeration is the favorite tool of the dysfunctional mind. And you who
made such a stink about _logic_. That I demonstrated that you are devoid
of logical thinking skills, has caused you to take this personally, but
at least you have stopped bragging about logic. That is good, and
probably goes to show that I was indeed right: You have never been
challenged on your thinking skills, but had a hugely inflated ego that
has been cut down to size. This is good for you, provided that you do
not develop a cancerous growth of arrogant ignorance, but you are on the
way there.

| I did. His intelligence seems to be above average, so some of the things
| he writes actually make sense. It is unfortunate that this makes him so
| arrogant that it is impossible to have a discussion with him.

You only observe it from this point of view because you are too stupid to
recognize your own arrogancae from _ignorance_.

| If somebody behaved like that in my team, I would fire him without
| thinking twice about his intelligence. The possible damage to the team
| is a bigger threat than having to find a replacement.

If you behaved the way you have in any professional setting, you would be
fired for incompetence before I had time to react.

| I will do as several people suggested to me in personal communication:
| I'll just stop taking Erik seriously.

This only reflects very badly on yourself. Like a few other prize morons
here, you may never understand what happened.

If you have a working brain, use it to go back over and re-read your
_own_ contributions, and accept the blame for your own behavior. This is
what morons are unable to do, and intelligent people figure out quickly.

I have _never_ met a person of reasonable intelligence who failed to see
how he could make every piece of criticism go away. Indeed, I have come
to make it a test for reasonable intelligence that they do, and it works
amazingly well. You failed. Lots of people have realized this already.
_They_ would not mail you and tell you that you are a moron, however.

Erik Naggum

unread,
Nov 30, 2001, 12:48:55 PM11/30/01
to
* Andreas Bogk

| If somebody behaved like that in my team, I would fire him without
| thinking twice about his intelligence. The possible damage to the
| team is a bigger threat than having to find a replacement.

A normally intelligent person would have taken my comments to _you_ as
being precisely "you are fired! get the hell out of here!" You did not
understand this, did you? It was because of the "possible damage to the
team" that existed here before you arrived that you are being chastised
for your behavioral and attitude problems. You did not understand this,
did you? But since you _are_ such a moron and feel so righteous about
continuing to post so much insanity, you do not even _recognize_ this as
you write your stupid drivel about firing me. You are the epitome of
arrogance. You have the introspective skills of a mad dog. Insight into
one's own behavior and impact on others is not something that comes until
one is fairly well above average. You are not. I find some enjoyment in
"proving" that people like you, who come only to make a disturbance in a
community, are indeed far too unintelligent to _understand_ what they do.

Incidentally, I do not go to work for morons, so you would never _get_ a
chance to fire me. Neither do I hire morons, so you would not be in
danger of being fired by me, either. Amazingly, so many so much smarter
people than you exist that working relationships with people who _think_
do not look like USENET discussions with arrogant morons. That you do
not even recognize this is somewhat alarming. It might indicate that you
are _actually_ at the best of your professional performance when you act
the way you do in this newsgroup. It would be inconcveiable for _me_ to
think of even the most egregiously rabid idiot as if he was trying to
sell himself to a prospective employer, but you apparently think your
actions here have been a sales pitch to _your_ future employers, not to
mention people who would have to take your instructions. I am actually
very happy that I have prevented a large number of people from ever doing
_business_ with you as you proclaim that you would behave the same way
towards people who pay you as people who do not. I have never made that
mistake. I do not bite the hand that feeds me. I do, however, kill the
dogs who bite mine when I feed them in a voluntary medium like USENET.
You, the mad dog of Dylan, would not understand the difference or your
own role in this interplay.

You _are_ a retard, Andreas Bogk. Adjust accordingly. If I had to deal
with you professionally, I would have told you to hold the onions and
give me large fries.

Vassil Nikolov

unread,
Nov 30, 2001, 1:17:12 PM11/30/01
to
A couple of points to add to the discussion.

(1) One could also consider an approach where constructors are
supplied for the appropriate classes (MAKE-FOO, MAKE-BAR, etc.,
or MAKE-THING, which accepts only an appropriate class to
instantiate, if that class needs to be determined at run time),
and the programmers are asked not to call MAKE-INSTANCE at all,
at least for classes in the provided hierarchy. (Or are the
users so random that they cannot be asked even that?) This
approach is analogous to just calling slot accessors and
refraining from calling SLOT-VALUE, and makes it harder to
instantiate the wrong class by accident. There could also be a
MAKE-THE-ABSTRACT-CLASS constructor which provides some
suitable notification to the programmer.

(2) If one decides to put some restraints on instantiating the
`abstract' class, perhaps a `gentler' approach would be more
productive, like issuing only a warning (or just logging a
message somewhere), rather than signalling an error.

(3) I don't know how often this would occur in practice, but at
least in theory I can think of a need to instantiate the
`abstract' class. Consider a scenario where the program needs
to create the object early (perhaps to store a reference to it
somewhere), when it doesn't know yet which specific class it
needs. Then an instance of the `abstract' class might be
created, to be subjected to CHANGE-CLASS later as necessary.

---Vassil.

Pierre R. Mai

unread,
Nov 30, 2001, 1:04:45 PM11/30/01
to
Andreas Bogk <and...@andreas.org> writes:

> "Pierre R. Mai" <pm...@acm.org> writes:
>
> > Sorry, I forgot that Dylan doesn't have method combinations (nor class
> > redefinition). With only known primary methods and an unchanging
>
> Yes, it looks like method combinations are really a missing feature in
> Dylan. Class redefinition worked in Apple Dylan's interactive
> environment,as far as I can remember.
>
> I wonder whether method combination could be introduced in Dylan
> without a performance penalty. Lots of the Dylan design tradeoffs
> revolve around insisting to have objects all the way down, while still
> being able to generate fast code.

Adding different pre-programmed method combinations should pose no
problem:

- Call the current Dylan method combination, simple-method-combination
and make it the default. No performance impact should result.
- Add what is called standard-method-combination in CL as
advanced-method-combination. Come up with useful definitions of the
various GF and method declarations. A certain amount of performance
impact is going to be necessary.
- Repeat for other M-Cs you can think of.

Adding user-programmable method combinations to the mix seems more
problematic, because it probably presupposes programmability at
compile-time, and it might be difficult to reconcile with the
declaration business.

That said, while doing it this way might be in the Dylan spirit, I
personally find the "static is the default" of Dylan to be rather
contrary to the whole point of a lot of things, including that of
standard-method-combination. The static-by-default approach can, IMHO
only work, if the original programmer knows best. The problem in my
eyes is that in a statistically significant proportion of the cases he
doesn't, but rather goes with the default, without thinking things
through (which is also rather difficult, without having a way to see
into the future). The default in CL might result in slower than
necessary code. The default in Dylan will result in the inability to
correct a problem, even if you can prove to your own satisfaction that
overriding the original programmers decision is safe (the no-way-out
problem).

Standard-Method-Combination is at its most powerful, when it allows me
to add code to and override code in a GF in places that the original
programmer didn't anticipate. If he did, he could just as easily have
made the :before, :after, and :around segments into their own GFs.
Not as elegant as s-m-c, but not fatally so.

So defaulting to simple-m-c would IMHO not realize most of the
advantages of standard-m-c. Defaulting to standard-m-c will cost you,
especially since sealed domain declarations on such a GF shouldn't
prohibit adding non-primary methods on superclasses.

But then again, my preferences run counter to the whole
"static-by-default" business in Dylan, so feel free to discount them.

Andreas Bogk

unread,
Nov 30, 2001, 1:36:51 PM11/30/01
to
Erik Naggum <er...@naggum.net> writes:

> That means that you react with an urge to defend yourself when you think
> you see something hurtful to yourself. Only insecure _and_ stupid people
> do that.

You're right, people smarter than me would have killfiled you much
earlier.

> Only people with _inflated_ egos respond violently when others
> challenge their inflated egos with _facts_. Only people with _inflated_
> egos respond violently when people _disagree_ with them, and therefore
> think that others react to disagreement.

I wish you would hear your own advice.

> I have _never_ met a person of reasonable intelligence who failed to see
> how he could make every piece of criticism go away. Indeed, I have come

I'm sick of weeding through hundreds of lines of insults and rhetoric
tricks to find your pieces of criticism that would be worth responding
to.

If I can't hear you anymore, will you still exist?

*plonk*

Jochen Schmidt

unread,
Nov 30, 2001, 2:48:58 PM11/30/01
to
Pierre R. Mai wrote:
> Adding user-programmable method combinations to the mix seems more
> problematic, because it probably presupposes programmability at
> compile-time, and it might be difficult to reconcile with the
> declaration business.

LispWorks has a facility called "method-combination templates" that can be
used to construct user-defined method-combinations at runtime without
needing the compiler. The most common cases seem to be already available
and LW warns on delivery that you have to add a special method-combination
template to the code.
The whole thing is described in the Delivery manual which is available over
the net:

http://www.xanalys.com/software_tools/reference/lwl41/deluser/D_166.HTM#HEADING166-0


ciao,
Jochen

--
http://www.dataheaven.de

Andreas Bogk

unread,
Nov 30, 2001, 2:09:05 PM11/30/01
to
"Pierre R. Mai" <pm...@acm.org> writes:

> But then again, my preferences run counter to the whole
> "static-by-default" business in Dylan, so feel free to discount them.

I'm not sure whether the "sweet spot" between dynamism and performance
has been hit by Dylan either. I consider it a good thing that I can
create, say, my own numeric class that ends up with the same
performance the built-in integers have. On the other hand, the
majority of classes don't have such strict performance requirements,
so making the dynamic case the default could have been a better
choice.

I think there are similiar tradeoffs in CL, I have seen the
recommendation to use a struct instead of a class when performance
matters.

Erik Naggum

unread,
Nov 30, 2001, 2:56:18 PM11/30/01
to
* Andreas Bogk

| You're right, people smarter than me would have killfiled you much
| earlier.

No, people smarter than you would not have gotten into this mess to begin
with. Again, you demonstrate that you cannot think clearly when under
pressure. I did not come out of nowhere to attack you -- you did get a
number of warnings and you decided to pick a fight. Now you lose, and
you are trying to salvage your pride. It is _truly_ pathetic to watch.

> Only people with _inflated_ egos respond violently when others challenge
> their inflated egos with _facts_. Only people with _inflated_ egos
> respond violently when people _disagree_ with them, and therefore think
> that others react to disagreement.

| I wish you would hear your own advice.

It is typical of people of very, very low self-esteem to play the stupid
mirror game when they are given advice, trying to reflect everything back
at whoever told them something. This demonstrates that it is much more
important to them to take revenge and defend themselves than to think,
which is actually one of the things I want to demonstrate about you guys.

> I have _never_ met a person of reasonable intelligence who failed to see
> how he could make every piece of criticism go away. Indeed, I have come

| I'm sick of weeding through hundreds of lines of insults and rhetoric
| tricks to find your pieces of criticism that would be worth responding to.

So act smarter! THINK! You have received this advice dozens of times,
yet the only thing you do is act more and more stupid. This is why it is
becoming increasingly obvious that you _are_ retarded.



| If I can't hear you anymore, will you still exist?

Yes, and you will still read my articles to see what I say about your
pathetic behavior. The reason is the same as that which prompted you to
attack me in the first place. (Of course, you will think of it as self-
defense, but _you_ were in fact never under attack. This you will never
understand.)

Kent M Pitman

unread,
Nov 30, 2001, 3:21:40 PM11/30/01
to
vniko...@poboxes.com (Vassil Nikolov) writes:

> A couple of points to add to the discussion.
>
> (1) One could also consider an approach where constructors are
> supplied for the appropriate classes (MAKE-FOO, MAKE-BAR, etc.,
> or MAKE-THING,

Yes, I've sometimes even just put something in the INITIALIZE-INSTANCE
method that looks like

(unless *inside-make-thing*
(error "You muse use ~S to create this object." 'make-thing))

I don't think that solution is totally general to the full class of situations
being expressed here, but you're right to point it out as a sometimes option.

It also reminds me of another option, though, which is that sometimes
the class name can be internal to a package, and does not have to be
exported. Sometimes one wants to export an abstract class, and then the
problem under discussion still exists, but when it's just a class you made
for internal purposes, you can rely on people programming your own package
to use it according to specialized constraints known to your design team,
and the package system can tell other people "hands off".

I think it's a design mistake that CL doesn't simply have a :abstract-class
option. Flavors had it (can't remember what it was called, but probably
:abstract-flavor), and I'm not sure why it was omitted for CLOS. Perhaps
it was just accidental. The design of CLOS was a process that was very
insular and I don't know much about; Richard Gabriel, who's been posting
here recently about patterns, was a key part of it and might know if there
was a discussion of this. (hint, hint, rpg, that's your cue)

This feature is hard to add as an implementation extension per se because
the spec specifically requires DEFCLASS not to have extensions. One has to
actually shadow DEFCLASS and use a different symbol that expands into the
other defclass, which to be honest, seems to me to have just the same
tree-walking consequences but isn't restricted by the standard. (you can
explain that decision at the same time, rpg. i remember asking back then
and not understanding/believing the answer, though i'd still love to, just
out of sheer curiosity)

Kent M Pitman

unread,
Nov 30, 2001, 3:37:05 PM11/30/01
to
Andreas Bogk <and...@andreas.org> writes:

> I'm not sure whether the "sweet spot" between dynamism and performance
> has been hit by Dylan either. I consider it a good thing that I can
> create, say, my own numeric class that ends up with the same
> performance the built-in integers have. On the other hand, the
> majority of classes don't have such strict performance requirements,
> so making the dynamic case the default could have been a better
> choice.

Part of me agrees, but part of me asks: How would one go about knowing
whether they had these performance requirements or not. Seems to me
that any data structure could be optimized, and that for some reason
compilers work heavily on optimizing numbers. But C enum types, to
take an example, are a place where work is taken to optimize what Lisp
might think of as one of those "other classes" (we use symbols).
Seems to me any data type for which you could determine enough
constraints might be folded into some simpler rep and part of the
design problem is to figure out what linguistic cues are required to
do such folding. e.g., might a struct of only 5 booleans be
represented in a manner like a single-byte character? Or a short
float? Indeed, if short floats were not in use in the application,
could their type tag be recycled for this other use so that they
didn't have to go through normal class decoding? That would take a
pretty careful design system-wide to make sure you weren't violating
hidden assumptions by such on-the-spot retooling. Compilers usually
don't (or, for accidental reasons, can't) do this amount of extra
work, but surely there are places where they could. Maybe also
determining "when it's worth it" is as hard or harder than determining
how to do it...

> I think there are similiar tradeoffs in CL, I have seen the
> recommendation to use a struct instead of a class when performance
> matters.

Note that a struct (short for "structure class") is a class. It is, so far
as I understand it, a limitation of time that we didn't better complete the
integration of structure class with standard class. It would have been nice
for this to be simply be a metaclass option to DEFCLASS so that people didn't
treat it as if it were something unrelated to DEFCLASS, but I guess there was
some detail work that needed to be spec'd out to make this seem up better.
Even so, I cringe every time I see these talked about as two separate
techniques, as opposed to standard-class and structure-class being two of
many possible techniques under the general framework of CLOS classes.
(Not that such was the primary point of your remark, of course. I apologize
for dragging the topic sideways to make this point.)

Lieven Marchand

unread,
Nov 30, 2001, 12:06:11 PM11/30/01
to
Erik Naggum <er...@naggum.net> writes:

> The near hysterical need to protect programmers from doing stupid things
> has always mystified me. E.g., if you need to control access to your
> class slots with public, protected, and private, this only means that you
> are telling too many people too much. If you give people a source file
> that contains all the names of all the slots with a silly string to make
> access difficult, all that your protection scheme relies on is that your
> users are unable to edit that file, which is obviously nuts. Instead of
> protecting yourself from problems, you force people who think you made a
> mistake to edit the file or make a copy, and then they get out of synch.

You underestimate the beautiful design of C++ which has made this
editing completely unneccessary. [0]

#define protected public
#define private public
#include <your_precious_abstraction.h>

A lot of compiler implementors forget to use only variables in
compiler namespace as arguments to their macros in compiler specific
include files. [1]

[0] note to C++ standard gurus: yes this violates the ODR and causes
undefined behaviour. It has a reasonable change of working on some
implementations though.

[1] They may have caught up now. It's been more than four years I've
had to look at C++.

--
Lieven Marchand <m...@wyrd.be>
She says, "Honey, you're a Bastard of great proportion."
He says, "Darling, I plead guilty to that sin."
Cowboy Junkies -- A few simple words

Pierre R. Mai

unread,
Nov 30, 2001, 3:59:22 PM11/30/01
to
Andreas Bogk <and...@andreas.org> writes:

> "Pierre R. Mai" <pm...@acm.org> writes:
>
> > But then again, my preferences run counter to the whole
> > "static-by-default" business in Dylan, so feel free to discount them.
>
> I'm not sure whether the "sweet spot" between dynamism and performance
> has been hit by Dylan either. I consider it a good thing that I can
> create, say, my own numeric class that ends up with the same
> performance the built-in integers have. On the other hand, the
> majority of classes don't have such strict performance requirements,
> so making the dynamic case the default could have been a better
> choice.

Indeed that's been my concern, although I understand the rationale for
going with the static case, given the intended audience, which already
fell once for the "pay-as-you-go" illusion.

I'm all for having sealing declarations and similar optional (from the
point of view of the user, but often also from the implementation's
point of view) permissions to the compiler that allow generation of
extremely fast code at the cost of flexibility in those few spots in a
program where it matters.

> I think there are similiar tradeoffs in CL, I have seen the
> recommendation to use a struct instead of a class when performance
> matters.

Classes which are instances of structure-class (commonly called
structures) offer the implementation a number of possibilities for
optimization, that classes which are instances of standard-class
don't:

- Single inheritance, so a simple class inheritance tree, not a DAG
- No class redefinition, hence no changes in the inheritance tree
- No change-class of instances, hence no need for storage indirection

This enables the usual trick of hard-coded constant slot offsets
(similar to the primary class declarations in Dylan), and eliminates
some other overhead.

That said, modern CLOS implementations will also do a great amount of
optimization for common cases (even CMUCL/PCL does lots of that,
details of which I post from time to time, and it isn't one of the
fastest CLOS implementations around).

The important thing IMHO is that the language doesn't default you to
use one or the other...

Bruce Hoult

unread,
Nov 30, 2001, 11:05:55 PM11/30/01
to
In article <sfwg06w...@shell01.TheWorld.com>, Kent M Pitman
<pit...@world.std.com> wrote:

> I think it's a design mistake that CL doesn't simply have a
> :abstract-class option. Flavors had it (can't remember what it
> was called, but probably :abstract-flavor), and I'm not sure why
> it was omitted for CLOS. Perhaps it was just accidental.

Dylan has it and there are a bunch of abstract classes in both the
numeric tower and the collection classes.

-- Bruce

Carl Shapiro

unread,
Dec 1, 2001, 12:38:45 AM12/1/01
to
Kent M Pitman <pit...@world.std.com> writes:

> I think it's a design mistake that CL doesn't simply have a :abstract-class
> option. Flavors had it (can't remember what it was called, but probably
> :abstract-flavor), and I'm not sure why it was omitted for CLOS. Perhaps
> it was just accidental.

ISLISP has a class option :abstractp which allows one to create
abstract classes. How did it make its way in there?

Kenny Tilton

unread,
Dec 1, 2001, 1:08:15 AM12/1/01
to

>
> Kent M Pitman <pit...@world.std.com> writes:
>
> > I think it's a design mistake that CL doesn't simply have a :abstract-class
> > option.

OK, i have a fix.

I suggest that any abstract class be named: @class-name@

there's a nice precedent in the fix we settled on for *specials* being
so different.

I like @ because it's got an "a" for abstract in it, and because:
sometimes I have heard the term "mix-in" used for such things, and the
full @ character looks like the swirl you get when you are mixing stuff
in a bowl.

:)

kenny
clinisys

Kent M Pitman

unread,
Dec 1, 2001, 2:30:32 AM12/1/01
to
Kenny Tilton <kti...@nyc.rr.com> writes:

Hmm.

I'll assume the :) at the end means I don't have to point out that * was
already in use as an operator name and so didn't rob the space of possible
readmacro characters but that @ is something some users might not want
taken away from them as such an option. (I think ,@ is handled specially
in comma's syntax so that it wouldn't matter.)

So probably **class-name** is better. Still leaving ***...***, etc. for
other purposes.

:)

Erik Naggum

unread,
Dec 1, 2001, 8:45:41 AM12/1/01
to
* Kenny Tilton

| I suggest that any abstract class be named: @class-name@

Please do not use up a very useful macro character like that. This is
almost as bad as suggesting that people actually _use_ $ as the first
position in symbol names -- it is such an obvious thing to want to use
for non-constituent macro purposes. % is always available as a normal
constituent character and is frequently used to mar "internal" symbols,
which to me seems what an abstract class is, but I do _not_ see the need
for syntactic suger-coating of symbol names just to keep losers from
instantiating an abstract class.

///
--
THE past is not more important than the future, despite what your culture

Vassil Nikolov

unread,
Dec 1, 2001, 11:38:14 AM12/1/01
to
Kent M Pitman <pit...@world.std.com> wrote in message news:<sfwadx3...@shell01.TheWorld.com>...
> Kenny Tilton <kti...@nyc.rr.com> writes:
[...]

> > I suggest that any abstract class be named: @class-name@
[...]
> > :)
[...]

> So probably **class-name** is better. Still leaving ***...***, etc. for
> other purposes.
>
> :)

And using gensyms as names of `abstract' classes is left as an exercise
for the programmer...

:)

---Vassil.

Marco Antoniotti

unread,
Dec 1, 2001, 1:17:37 PM12/1/01
to

Erik Naggum <er...@naggum.net> writes:

> * Kenny Tilton
> | I suggest that any abstract class be named: @class-name@
>
> Please do not use up a very useful macro character like that. This is
> almost as bad as suggesting that people actually _use_ $ as the first
> position in symbol names -- it is such an obvious thing to want to use
> for non-constituent macro purposes. % is always available as a normal
> constituent character and is frequently used to mar "internal" symbols,
> which to me seems what an abstract class is, but I do _not_ see the need
> for syntactic suger-coating of symbol names just to keep losers from
> instantiating an abstract class.
>

As an aside, using '$' breaks under (older?) versions of MCL. This is
the reason why the infix package uses

#I(a + b)

instead of the LaTeX-ish

$a + b$

(as it did in an earlier version).

Bradley J Lucier

unread,
Dec 3, 2001, 12:04:10 PM12/3/01
to
I've used virtual classes a bit in Meroon, a CLOS-like (sort-of) object
system for Scheme. After struggling with things a bit, I decided that
I shouldn't use virtual classes unless the virtual class defines at least some
slots that will be common to all subclasses of the class. Otherwise,
having the virtual classes just get in the way.

Brad

Brian P Templeton

unread,
Dec 4, 2001, 8:37:41 PM12/4/01
to
Erik Naggum <er...@naggum.net> writes:

> * Andreas Bogk
> | Well, how would you feel if someone keeps calling you retarded, a
> | lunatic, an idiot, a fool, imbecile? For no other reason than that you
> | disagree on a certain point?
>

[...]


> Some people are so amazingly smart (by your standards) that they wonder
> what happened when something unexpected occurs. You are not that smart.
> That means that you react with an urge to defend yourself when you think
> you see something hurtful to yourself. Only insecure _and_ stupid people
> do that. Only people with _inflated_ egos respond violently when others
> challenge their inflated egos with _facts_. Only people with _inflated_
> egos respond violently when people _disagree_ with them, and therefore
> think that others react to disagreement. Spread of disinformation is not
> disagreement. Osama bin Laden does not "disagree" with George W. Bush on
> the policies of the United States in the Middle East. Yet you can bet
> that if he were half a smart as he is rumored to be, he will argue that
> he "only expressed his disagreement" when defending himself and cannot
> understand why he caused Afghanistan to be bombed.
>

BPT's collary to Godwin's law: As a Usenet discussion grows longer,
the probability of a comparison involving Osama bin Laden or al Queda
approaches one.

:)

[...]

--
BPT <b...@tunes.org> /"\ ASCII Ribbon Campaign
backronym for Linux: \ / No HTML or RTF in mail
Linux Is Not Unix X No MS-Word in mail
Meme plague ;) ---------> / \ Respect Open Standards

cbbr...@acm.org

unread,
Dec 4, 2001, 8:46:16 PM12/4/01
to
Brian P Templeton <b...@tunes.org> writes:
> Erik Naggum <er...@naggum.net> writes:
>
> > * Andreas Bogk
> > | Well, how would you feel if someone keeps calling you retarded, a
> > | lunatic, an idiot, a fool, imbecile? For no other reason than that you
> > | disagree on a certain point?
> >
> [...]
> > Some people are so amazingly smart (by your standards) that they wonder
> > what happened when something unexpected occurs. You are not that smart.
> > That means that you react with an urge to defend yourself when you think
> > you see something hurtful to yourself. Only insecure _and_ stupid people
> > do that. Only people with _inflated_ egos respond violently when others
> > challenge their inflated egos with _facts_. Only people with _inflated_
> > egos respond violently when people _disagree_ with them, and therefore
> > think that others react to disagreement. Spread of disinformation is not
> > disagreement. Osama bin Laden does not "disagree" with George W. Bush on
> > the policies of the United States in the Middle East. Yet you can bet
> > that if he were half a smart as he is rumored to be, he will argue that
> > he "only expressed his disagreement" when defending himself and cannot
> > understand why he caused Afghanistan to be bombed.

> BPT's collary to Godwin's law: As a Usenet discussion grows longer,
> the probability of a comparison involving Osama bin Laden or al
> Queda approaches one.

The strange part is that in the above, the two "leaders'" names could
be switched in position and it would make about the same amount of
sense in about the same way.

Another "strange but true" thing is that about the only
previously-known use (before the O.b.L. situation) of the term "al
Quaeda" was as the title of the translation, into Arabic, of the
apparently-rather-popular-in-Arabic novel, _Foundation_, by Isaac
Asimov. Some parallels between its story and the expectations of the
Arab terror network can be drawn.

(On the other hand, Isaac Asimov was an atheist Russian Jew who moved
to the United States, and, more particularly, New York City. None of
those qualities would appear terribly appealing to a terrorist network
that conspicuously despises Russians, Americans, Jews, and considers
itself a sort of "Hand of Allah.")
--
(reverse (concatenate 'string "moc.enworbbc@" "enworbbc"))
http://www.cbbrowne.com/info/x.html
"It is always convenient to have villains whom you can have no qualms
about seeing shot, blown up, or run over by large man-made objects;
the Gestapo are particularly appropriate for this." -- Jeff Meyer

0 new messages