Possible records tweak
john.r.rose at oracle.com
Mon Apr 27 22:31:38 UTC 2020
On Apr 27, 2020, at 2:00 PM, Dan Smith <daniel.smith at oracle.com> wrote:
>> On Apr 24, 2020, at 3:34 PM, John Rose <john.r.rose at oracle.com> wrote:
>> On Apr 24, 2020, at 12:43 PM, Dan Smith <daniel.smith at oracle.com> wrote:
>>>> On Apr 24, 2020, at 1:32 PM, Remi Forax <forax at univ-mlv.fr> wrote:
>>>>> (Which, in hindsight, might have been a good rule for _all_ constructors, if there was another way to initialize the fields. Surely would have eliminated much verifier complexity.)
>>>> accessing to the identity hashcode or the current class inside a constructor is valid (i believe) but those are a corner cases.
>>> Ah, yes. This generalizes to calling methods that safely operate on an already-initialized superclass (typically instance methods of the superclass).
>>> If we someday have abstract records or other forms of user-defined superclasses, it will be quite reasonable to call the superclass's instance methods from the subclass's constructor.
>> So maybe `super` is DA but `this` is DU, just like in the code
>> before the super-constructor call. (I’m abusing the terms DA/DU
>> like Brian is, and you call out, but they are close to correct.)
> I think this means I can't call inherited method 'getParentWidget()' or some static utility 'computeWidgetOfParent(this)' method (e.g., 'identityHashCode(this)'). I *can* call 'super.getParentWidget()'.
> It's a do-able way to apply some discipline. Feels a little heavy on the "you can't do that" side and light on the "we'll guarantee better programs" side—because of course, once you've called the super method, it can do whatever it wants with the object.
> Overall, my sense is that controlling all accesses of 'this' (explicit and implicit) is more ambitious than we really want/need here. Airtight constructors are a problem for another day. Prohibiting assignment to the instance fields is more manageable.
I’m obviously not proposing airtight constructors—although you get
that as a forced move (and probably a pleasant one, to boot), for free,
whenever you choose to use inline classes.
Let's keep the existing problems with constructors as they are: You
can call a super method, which via an override can “see” an incomplete
instance. This means that if we forbid “this” in record default constructors,
if there is a sneaky way to get “super”, then the usual sneaky things can
happen. In fact, if we forbid “this.x = y” (only) then the same sneaky
things can happen.
The question is see right now is whether forbidding “this” or forbidding
“this.x = y” is simpler. I think the former is simpler. The latter is less
restrictive, but more complex. Which leads to a better user experience?
The simpler, as long as the extra restriction does not require the user
to resort to complex workarounds.
My observations about “super” are a red herring, I guess; I’m just reaching
for an escape hatch away from the proposed restrictions about “this”.
(I just noticed that “super” is DU before the “super” call, so it’s not as
useful as I thought. I don’t want to entangle the present discussion with
lame proposals for extending the usefulness of the “super” keyword.)
More information about the amber-spec-experts