<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<font size="4"><font face="monospace">Thinking more on this -- I
think there is significant simplicity dividend here if we relax
our goals a little bit. Supporting constructs such as<br>
</font></font><br>
<font size="4"><font face="monospace"><font size="4"><font face="monospace"> if (bar) <br>
this(f(bar));<br>
else<br>
this(g(bar), 0);<br>
<br>
would require a full DA/DU analysis, but if the goal is
really "allow statements before the this/super", we can get
by with a considerably simpler feature. <br>
<br>
On the latter path, we define a grammar production for
"constructor body" that amounts to:<br>
<br>
statement*<br>
[super | this]?<br>
</font></font></font></font><font size="4"><font face="monospace"><font size="4"><font face="monospace"><font size="4"><font face="monospace"><font size="4"><font face="monospace"> statement*<br>
<br>
We further constrain the statement grammar /
description to exclude `this(...)` or `super(...)`
calls, since the only place they can appear is in a
constructor, and now there's a place for them to
explicitly live. <br>
<br>
</font></font></font></font>We can use similar
language to say "if there isn't a super/this, you get one
for free at the top" as we do today. <br>
<br>
We can use similar "introduces a static context" approach
for the statements prior to the super/this, and the
super/this, as we do today. This is enough to prevent use
of `this`, explicitly or implicitly, in the statements
preceding the explicit super/this, including in lambdas, try
blocks, etc. <br>
<br>
I don't think there's any need to update DA/DU. <br>
<br>
This brings the spec footprint down considerably, while
still eliminating complex/risky workarounds around "super
first". <br>
<br>
</font></font></font></font>
<div class="moz-cite-prefix">On 1/24/2023 6:16 PM, Brian Goetz
wrote:<br>
</div>
<blockquote type="cite" cite="mid:5bb5403b-25b5-bf1e-8d74-d91db89da0c6@oracle.com">
<font size="4"><font face="monospace">Hit "send" a little too
soon. <br>
<br>
The assertion that governs "no use of `this` in a super/this
call" is in 8.8.7.1:<br>
<br>
<blockquote type="cite">An explicit constructor invocation
statement introduces a static context (§8.1.3),<br>
which limits the use of constructs that refer to the current
object. Notably, the<br>
keywords this and super are prohibited in a static context
(§15.8.3, §15.11.2),<br>
as are unqualified references to instance variables,
instance methods, and type<br>
parameters of lexically enclosing declarations (§6.5.5.1,
§6.5.6.1, §15.12.3).</blockquote>
<br>
This needs to be generalized to speak about the use of `this`
throughout the constructor body; basically, that you can never
use `this` (explicitly or implicitly) prior to to the
super/this call. <br>
<br>
There are a few ways you could do this:<br>
<br>
- A full-blown treatment of DA/DU for `this`;<br>
- An extension of the "introduces a static context" used in
this section, that covers the entire initial segment of the
constructor body up through and including the this/super-call.<br>
<br>
Similarly, you'll need a way to restate the "if it doesn't
start with `this/super`, you get an implicit super" to the
more flexible notion being outlined here. This is tricky
because the obvious way to do this is to run DA/DU on the
explicit body of the constructor and ask if `this` is DA at
all points where the constructor could complete normally, and
if not, prepend a super() call and rerun DA/DU. This moves us
from a strictly syntactic rule to one that appeals to a
complex analysis. <br>
<br>
We can simplify this analysis a lot by lowering the target,
from one that is based on DA to funneling through a single
super/this choke point, where a ctor body with an explicit
super/this looks like:<br>
<br>
statement*<br>
super/this call<br>
statement*<br>
<br>
This would rule out constructs like:<br>
<br>
Foo() { <br>
if (bar) <br>
this(f(bar));<br>
else<br>
this(g(bar), 0);<br>
}<br>
<br>
but is a lot simpler to specify and still offers the "stuff
before super" benefit. <br>
<br>
<br>
<br>
<br>
</font></font><br>
<div class="moz-cite-prefix">On 1/24/2023 6:01 PM, Brian Goetz
wrote:<br>
</div>
<blockquote type="cite" cite="mid:8ac4afe5-3e70-324d-6ce9-2609f7e6b83c@oracle.com"> The
basic design seems sound enough. Probably time to dig to the
next level, which is assessing the spec impact. <br>
<br>
The places to start are Ch16 (definite assignment) and 8.8.7
(constructor bodies). <br>
<br>
<div class="moz-cite-prefix">On 1/24/2023 4:24 PM, Archie Cobbs
wrote:<br>
</div>
<blockquote type="cite" cite="mid:CANSoFxsw4z0YUvn0qPQzD9--RN_-1Er1rhRpPM38LCjLvHzNYg@mail.gmail.com">
<div dir="ltr">
<div dir="ltr">On Tue, Jan 24, 2023 at 2:21 PM Brian Goetz
<<a href="mailto:brian.goetz@oracle.com" moz-do-not-send="true" class="moz-txt-link-freetext">brian.goetz@oracle.com</a>>
wrote:</div>
<div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div> <br>
<blockquote type="cite">
<div dir="ltr">
<div class="gmail_quote">
<div>This made me realize there is another
missing requirement:</div>
<div>
<ul>
<li>Upon normal return from a constructor,
the `this` reference must be DA <br>
</li>
</ul>
</div>
</div>
</div>
</blockquote>
<br>
So, I think this is true by definition; on normal
return from a super/this/implicit super call, then
`this` *is* DA. <br>
<br>
You can simplify the rule about try blocks to:<br>
<br>
- if `this` is DU on entry to a try block, it must be
DU on normal completion of the try block. <br>
<br>
Can you simplify further, while still preventing
`this` calls inside a try block? I don't think so,
since we might want to allow a try block before the
super/this call.<br>
</div>
</blockquote>
<div><br>
</div>
<div>Ok thanks. I admit I'm getting a little out of my
league here.<br>
</div>
<div><br>
</div>
<div>Does this sound correct?</div>
<div style="margin-left:40px"><br>
</div>
<div>
<div style="margin-left:40px"> The JLS will be modified
as follows:<br>
<br>
* Remove the requirement that `super()` or `this()`
appear as the first statement in a constructor<br>
* Add superclass initialization to the existing
constructor dataflow analysis as follows:<br>
* The `this` reference is considered DU on entry
to the constructor<br>
* Before a `this()` or `super()` call, the `this`
reference must be DU<br>
* After a `this()` or `super()` call, the `this`
reference is considered DA<br>
* Before normal completion of the constructor,
the `this` reference must be DA<br>
* If `this` is DU on entry to a `try` block, it
must be DU on normal completion of the `try` block<br>
* If no explicit `this()` or `super()` appears in
a constructor, it is treated as if the first line of
the constructor were `super()`<br>
* Add the following restrictions on constructors:<br>
* No access to `this`, other than assignments to
fields, may occur unless `this` is DA<br>
* `super()` and `this()` may not appear within
any `try { }` block<br>
* Clarify that non-static field initializers and
initialization blocks are executed immediately after
`super()` invocation, wherever it occurs (see
"Initialization Order" below)<br>
</div>
<br>
</div>
<div><br>
</div>
<div>Thanks,</div>
<div> -Archie</div>
</div>
<br>
-- <br>
<div dir="ltr" class="gmail_signature">Archie L. Cobbs<br>
</div>
</div>
</blockquote>
<br>
</blockquote>
<br>
</blockquote>
<br>
</body>
</html>