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

Re: Constructors



Evidently my proposal for constructors wasn't very well written, since
so far no one who has read it (and sent mail) has understood it.

    Date: 2 Oct 87 11:32 PDT
    From: Danny Bobrow <Bobrow.pa@Xerox.COM>

    (2) Coordination with class redefinition

    Moon argues that creating an option makes constructors lexically local.
    But the validity of the constructor is dependent on information that is
    inherited from many classes and methods.  Hence being included in the
    class definition is not as useful as say the :initarg or :accessor
    slot-options, which are adjacent to all the information used in their
    construction.  And :initarg or :accessor slot-options don't effect
    anything in subclasses (except for optimizations)

I can't understand anything in the above paragraph.  I never said
anything about lexical locality, unless you mean "A much simpler way is
to make the constructor syntactically part of the DEFCLASS, so it
naturally gets updated at the same time as the rest of the DEFCLASS.",
which refers to the linkage between the class and the constructor
function necessary for the automatic updating discussed below.  The
:initarg and :accessor slot options certainly do affect subclasses.
However, I don't see that's relevant, since the :constructor option does
not affect subclasses.  The effect of the :accessor slot option
certainly does depend on sub and superclasses, in any system that
optimizes compilation of SLOT-VALUE, because the position of a slot
is not determined by the single DEFCLASS form.  I'm obviously missing
whatever point you were trying to make here.

	Making this updating automatic is a convenience for
	programmers, so they don't have to remember to do it by hand.

    I don't undertand which things can be done automagically.  If I change
    the name of an initarg or method keyword argument, should the text in
    which constructors used the old name be changed?  Clearly not.  What
    other changes can be handled that are interesting?  What Moon is
    suggesting is a general mechanism for notifying the user when the names
    of keyword arguments change in a method, so calls can be changed.  

That's certainly not what I'm proposing.

I thought it was clear from the two sentences preceding the one you
quoted what was being updated: "its initargs and their default values."
I should have also mentioned compiler optimizations in this paragraph,
rather than deferring them to later.  Although :default-initargs is
enough to make the point, compiler optimizations are in practice the
major part of the updating burden.

Look, it's very simple.  If we're going to have a way to optimize out
the interpretive processing that a naive implementation of MAKE-INSTANCE
has to do, and generate specialized compiled code for making instances,
then we have to have some way to redo this optimization when something
changes.  I claim it would be terrible for programmers to have to do
that by hand.  I claim that constructors are a better way to keep track of
this automatically than any other way, because the special processing is
confined to a system generated function, and kept away from user written
functions.  So what are the alternatives?  We can decide that we don't
care about speeding up object creation that much, or someone can propose
a specific, coherent alternative.

	(3) More efficient than MAKE-INSTANCE
      ...
	Gregor has argued that calls to MAKE-INSTANCE with a constant
	first argument can be equally optimized
      ...In either case, if we are going to have this type of
	mechanism, I would much rather make it explicitly visible as a
	:CONSTRUCTOR option than have it operating behind the scenes in
	some vaguely defined way.

    But I thought the whole point of optimization mechanisms is that they
    would operate behind the scenes.  I don't quite understand the phrase
      "the inherent complexity of making that mechanism generally available"
    in this context.  I thought this was specific to make-instance, and that
    the only other mechanism was a hidden mechanism for generating functions
    from a particular type of call, rather than the optimization tricks.

I guess neither of us can figure out what the other is talking about here.
Maybe my previous paragraph makes this more clear: I hope so.  If not, you
should respond with something very specific, such as an example showing
exactly what a programmer would write to get an efficient constructor.
Perhaps it should be something that has the same semantics as

(defclass class1 ()
	  ((a :initarg :a)
	   (b :initarg :b)))

(defclass class2 (class1)
	  ((c :initarg :c)
	   table)
  (:default-initargs :b 1)
  (:constructor make-2 (a &optional n b c)))

(defmethod initialize-instance :after ((x class2) &key (n 10))
  (setf (slot-value x 'table) (make-array n)))

(make-2 "foo" 5)


    My high order conclusion is that
     -  constructors are for writers of code, not readers, 

I agree or disagree depending on what you mean.  The :constructor option
is primarily an aid to writers of code, although of course it's somewhat
easier to read than the equivalent written out as a defun.  Calling a
function to construct something, instead of calling MAKE-INSTANCE
directly, is primarily an aid to readers of code, although it's also
useful to writers, as any form of modularity is.

     -  optimizations should be for system implementers,
	not something that we force the casual user to be aware of

Precisely why I want to package the optimization into a :constructor option
instead of making it visible to the writer of the function to construct something.

     -  programming environments should support finding callers of methods
    whose arguments have changed.  We might ask what hooks CLOS should
    provide for such an environmental feature.

I assume when you say "methods" you mean "generic functions"; people don't
call methods.  I don't think CLOS has to provide any hooks for this, since
I don't think the issue is significantly different for generic functions
than for regular functions.  I agree wholeheartedly that programming
environments should provide support for this.