[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Object creation discussion (at last!)



     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
     written explanation.
     
     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
     initargs.

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
         be merged?
     
     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
         From: Gregor.pa@Xerox.COM
     
         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 ()
     	(x
     	 y)
           (: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.