[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Object creation discussion (at last!)
- To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
- Subject: Re: Object creation discussion (at last!)
- From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
- Date: Mon, 27 Apr 87 14:28:13 CDT
- In-reply-to: Msg of Mon, 27 Apr 87 01:30 EDT from "David A. Moon" <Moon@scrc-stony-brook.arpa>
Date: Mon, 27 Apr 87 01:30 EDT
From: "David A. Moon" <Moon@scrc-stony-brook.arpa>
Subject: Object creation discussion (at last!)
I can see from the misunderstanding in the mail that I did an abysmal job
of communicating my ideas. I'll try to send a more comprehensible essay
tomorrow, but for now I would like to just clarify a couple of points and
then make some comments on excerpts from the mail in places where they
might help communication.
Complexity and simplicity are partly matters of taste, and largely matters
of point of view. I try to take the point of view of the majority of
programmers, who are using the outer interfaces of the system without
necessarily understanding everything that's going on inside. No matter how
beautifully we explain it, most programmers simply won't read beyond the
point where they think they know everything they need to know to get their
immediate job done. Now, it may be that we will decide that we would
rather make life more complicated for people writing initialization methods
in order to make the conceptual explanation shorter. That would be okay
with me if it's done for good reasons, but we shouldn't just dismiss the
other way without understanding it and understanding why I proposed it. I
have a feeling this message isn't going to explain it adequately either,
and if that happens I will apologize and follow up with a more carefully
One key point that I was trying to convey, and I think partially succeeded,
was the need for information hiding (abstraction) in the arguments to
make-instance and in relations among the various initialization
specifications attached to a class and its superclasses.
Another key point, which I don't think came through, was that each initarg
should be explicitly defined, and should be defined in exactly one place.
This is simply good modularity.
Some aspects of what I proposed were reacting to user complaints about the
way Flavors does it. I have the ambition of making this new standard
better than Flavors.
All this leads to the idea that initargs of types 2 and 4 (in the
nomenclature of my 16 Apr message) should be defined by methods, since
their meaning is implemented by methods. Similarly, type 3 should be
defined by slot-options, since their meaning is entirely involved with
slots. In Flavors, type 4 have the ugly property that they have to be
defined in two places, once in the method that implements them and again in
a defflavor form; it's easy to get these two places out of sync. Hence the
proposal to use the lambda-list of a defmethod as the way to define these
I would stress this point further by saying that an object system is
going to be appreciated for its ease of use during program development.
Adding a new method is a normal thing to do and will be easier
(faster,...) on most implementation than DEFCLASS redefinition which is
a more traumatic operation (potential obsolescence of class...). Adding
a new initarg keyword to make-class for 2 or 4 does not make the class
obsolete. We shouldn't be forced to reevaluate DEFCLASS for such a small
and upwardly compatible change.
Date: Thu, 23 Apr 87 08:03:20 pst
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
From subsequent discussion, it seems as if an additional DEFCLASS
option, :DEFAULT-INITARGS is being proposed. I wonder if this
is needed, considering that a user can already specify an initialization
value via the :INITFORM option? Perhaps the metaclass ought to
attend to this? Or the :INITFORM and :DEFAULT-INITARGS options should
This indicates that I completely failed to convey what :default-initargs is
about, and that in turn may possibly indicate that :default-initargs should
be flushed. In my proposal there are two ways to specify a default for an
initarg: at the point of definition, and remotely. To explain: when
defining an initarg one can specify right there, locally, a default value
form. For initargs that fill slots, this is the existing :initform
slot-option; no need to invent anything new there. For initargs that are
implemented by methods, this is the existing defaulting mechanism in the
lambda-list; again, no need to invent anything new. Now for remote
defaulting: here the idea is that one class defines what an initarg means,
while a second class specifies a default for it; this is :default-initargs.
When you mix the two classes together, the default meets up with the
implementation and things work. The reason remote defaulting is desirable
is twofold: (1) it's often useful when mixing classes together for one
class to customize another class by specifying initialization options, in
addition to the existing ability to customize a class by shadowing or
wrapping methods; (2) for modularity reasons, when class A customizes class
B by specifying an initarg that class B defines, class A shouldn't have to
know whether the initarg fills a slot or is implemented by a method. If
not for reason (2), remote defaulting wouldn't require a new mechanism,
because it could be implemented using the existing mechanism of :initform
for slot initargs plus call-next-method-with-arguments (proposed but not
yet accepted) for method initargs. But I think reason (2) is important.
Date: 23 Apr 87 18:24 PDT
What is the purpose of :initform anymore? You only need it when you
want to specify the default value for a slot that isn't set by any
initarg. This means that we have two mechanisms which do almost the
same thing -- initargs which set slots are almost a superset of
initforms. This is a sure sign of bad modularity.
On the contrary, I think it's a sign of good modularity! The two
mechanisms do almost the same thing inside the implementation, but from the
point of view of someone on the outside who doesn't know the information
that is supposed to be hidden from him by modular abstraction, they do
rather different things. I could give a longer explanation of what I mean,
but it's late, this message is already too long to ask anyone to read
carefully, and I think I would just be repeating what I said a bit earlier.
(defclass position ()
(:default-initargs (nil 0 x)
(nil 0 y)))
What I am trying to do is seperate what I perceive as the separate parts
of what is going on into separate places.
The reason I don't like this is that the information about a slot is no
longer all in one place. Another way of saying it is that I think that
information in defclass should be organized spatially rather than
temporally, i.e. information pertaining to one slot should be together,
rather than putting information pertaining to one phase of object creation
together. One of the ways that I think defclass is better than defflavor
is that it has done a better job of spatial organization by putting more
of the information about a slot into slot options instead of scattering it
around in various options some of which refer back to the slot by name.
I see :default-initargs being on the client side (make-instance and
such) and :initform being on the implementor side. One will supersede the
other, but conceptually they are different and should be kept different.