[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: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
- Date: Fri, 17 Apr 87 14:49 EDT
- In-reply-to: <2754594256-919057@Jenner>
Date: Thu, 16 Apr 87 16:04:16 CDT
From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
Thanks for the comments. I hope the others will comment as well (but
I'm certainly willing to wait a few days).
If multiple initargs that fill the same slot are supplied, which value ends up
in the slot is indeterminate.
In what sense do you mean "indeterminate"? Do you mean "defined to be
one of those values, but not defined as to which of them", such that it
would be legal to use a random number generator to decide?
Yes. "which value" should be "which of those values". I certainly won't complain
if someone proposes a determinate action here instead.
We could check, at run time for make-instance that two initargs that fill
the same slot are not getting a value.
For the constructors, we can check at compile time that they don't specify in
their lambda list two initargs filling the same slot. This would be a
restriction for constructors.
Those are good ideas. I agree with the constructor one. I'm not so sure about
the make-instance one, because I just noticed that Common Lisp allows duplicate
keyword arguments in a function call and mandates that the leftmost argument
prevails. One could argue that this should extend to arguments that have different
names but fill the same slot.
I was concerned about the speed of a runtime check either to do what you
(Patrick) suggested, or to do what I just mentioned above. However,
after consulting our implementation I see that it is easy to do,
although we are not currently using the mechanism to address the issue
of multiple initargs filling the same slot. Briefly, you detect at
compile time (or the first time a class is instantiated) that there are
multiple possible initargs, and then you assign a bit in a bit mask to
record whether the given slot has been filled. If you see an initarg
that fills a slot whose bit is already set, you either ignore it
(leftmost duplicate prevails) or check what keyword was used the
previous time (signal an error except in the case where Common Lisp says
the leftmost duplicate prevails).
Given all this, I added the following to my proposal (philosophy section):
>> What if multiple initargs that fill the same slot are supplied?
If the same initarg is given more than once in the arguments to make-instance,
the leftmost occurrence prevails, as required by Common Lisp.
If two different initargs that fill the same slot are given in the arguments
to make-instance, the leftmost occurrence prevails (alternatively we could
make this an error, but I think it's simpler to treat it the same as two
occurrences of the same initarg).
A :constructor option whose lambda-list has more than one parameter that
fills a single slot signals an error, whether or not the parameter names
are eq (see proposal below for how it is possible for non-eq parameters
to fill the same slot).
I also added the following related clarification:
When :default-initargs defaults an initarg that
fills a slot, it is treated the same as an :initform slot-option for purposes
of inheritance (note well: the class that specifies the :default-initargs
may not know whether the initarg fills a slot or not, and indeed this may
depend on which subclass of that class we are dealing with). If a single
class specifies more than one default value for a single slot, via
:default-initargs or :initform or both, an error is signalled.
Is this agreeable?
Initargs don't have to be keywords, but the entire object creation might not work
very well if any of initargs is not a keyword:
In common Lisp, :allow-other-keys T works only for keyword value pairs. We would
have to slightly change its meaning for make-instance.
In practice this is probably implemented by calling all of the
initialize-instance methods with all of the initargs and automatically adding
&allow-other-keys to the lambda-list in defmethod.
This won't work if there is an initarg which is not a key. The methods that
can be called during object creation (like those on allocate-instance) would be
easier to code if they knew that they would get keyword-value pairs. (if I
understand correctly, those methods would get all the arguments supplied to
make-instance, right?)
I can't understand what you're getting at here. Could you send a follow-up
message this is more explicit?
>> Can step 2 return an existing object instead of allocating storage,
aborting the remaining steps?
No, to do "interning" you must build a higher-level interface around
make-instance. Make-instance always makes.
I am wondering if you propose to enforce this. What if somebody defines an
:around method for ALLOCATE-INSTANCE and does not call-next-method but returns
an interned object instead ? Is it an error?
I don't see how it would be possible to enforce a restriction that the value
returned by ALLOCATE-INSTANCE is not EQ to any other object in the world.
However, note that in your example the value returned by ALLOCATE-INSTANCE
is going to have every one of its slots stored into, and is going to have
its INITIALIZE-INSTANCE methods run, so the effect might not be what the user
intended. What I was really getting at with my philosophy question is "should
a way be provided for the metaclass to be able to completely bypass the
entire action of MAKE-INSTANCE?" and my answer to that is "no". In my file
copy of the proposal I changed this section to the following:
>> Can step 2 return an existing object instead of allocating storage,
aborting the remaining steps?
Step 2 can return anything it wants, but the remaining steps are still
executed. To do "interning" you must build a higher-level interface around
make-instance; make-instance always makes. No way is provided for the
metaclass to be able to completely bypass the entire action of MAKE-INSTANCE.
Is this agreeable?