Different handing of "this" vs. "MyClass.this" in definite assignment
Archie Cobbs
archie.cobbs at gmail.com
Fri Dec 2 20:32:40 UTC 2022
Hi John,
Thanks for the great discussion.
I should admit that I only came across this bug because I was trying to do
a clean up of compiler bugs that were already fixed or "easy to fix" as a
way of learning about the compiler code and making some low-level
contributions (if anyone wants to help with the JIRA cleanup see this post
<https://mail.openjdk.org/pipermail/compiler-dev/2022-October/020700.html>
and this post
<https://mail.openjdk.org/pipermail/compiler-dev/2022-October/020767.html>
:)
Of course at first I didn't appreciate that a JLS change was implied and
instead charged ahead with "fixing" the bug and submitting a PR...
After better understanding the implications, I agree making this change is
questionable based on cost/benefit. Surely, uses of "MyClass.this" within
MyClass constructors are uncommon.
But it's an interesting philosophical question so to speak.
I don't have strong opinions either way... I just hope we can decide one
way or the other and resolve the bug :)
The dynamic check idea is quite interesting...
What I’m thinking of (Brian you know this already) is perhaps we could take
> some error conditions for premature use of “this” in value classes and turn
> them into warnings for classic classes, so that code that circumvents the
> DU/DA rules, to obtain access to blank final fields uninitialized, will
> suddenly sprout lint warnings.
>
This relates to the "this escape" warning discussion of a few weeks ago.
I'm (still) working on a prototype for such a warning & hopefully will have
something soon.
As you point out, the dynamic check idea would work for "this escape" as
well... that would be nice down the road.
Presumably with a dynamic scheme you could have "perfect" DU/DA analysis,
albeit at runtime instead of compile time.
-Archie
On Fri, Dec 2, 2022 at 1:30 PM John Rose <john.r.rose at oracle.com> wrote:
> I was there when these rules were written, so I added a comment to the bug
> explaining what’s up here.
>
>
> https://bugs.openjdk.org/browse/JDK-8193904?focusedCommentId=14542315&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-14542315
>
> In short, we have no good changes on the table here. The JLS is the way
> it is at this point intentionally for good reasons, summarized in the above
> comment.
>
> Since changing the JLS is super-expensive, even a neutral change would
> need to be highly beneficial to the whole ecosystem. Removing perceived
> inconsistencies (that have been unchanged for 25 years) is not highly
> beneficial to the whole ecosystem.
>
> I think Archie got at the heart of the problem in this comment here:
>
> > Presumably the reason for the different treatment is because in general
> the qualifying expression could be arbitrarily complex and the compiler
> can't be expected to detect any possible qualification in front of "foo",
> so why even start down that road?
>
> Exactly. Don’t start down that road, unless (1) you know where it goes,
> and (2) that it gets somewhere good, and (3) you can get there before you
> run out of gas. Don’t start just because you like the first billboard you
> see, or on a road which takes you to a tarpit, or with only enough supplies
> to travel on the first day of a week-long trip. I think we might have all
> three problems here.
>
> Regarding (2), better uninitialized variable control is I think the proper
> goal here, not some consistency of all the things. Dynamic checks are
> required to get the next level of value, IMO. Please see my comment on the
> bug for more details.
>
> Regarding the PR: It intentionally changes javac to deviate from the
> JLS. That’s a non-starter. (It got my attention but that’s a limited
> resource!) Before we change javac to make it compile a language we like
> better, we first have to decide to change the JLS. The JLS is not the Java
> Language Suggestions; it is the foundation of our whole ecosystem, and
> every word in it counts. Breaking those words breaks promises of
> compatibility we have made to literally millions of programmers over
> decades.
>
> Regarding tweaks to the Java language: It might be interesting to look up
> the history of Project Coin, where we explicitly solicited, discussed, and
> implemented small improvements to the JLS and (only then) the Java
> toolchain. Amber and Valhalla are the latest venues that we have created
> for making JLS changes, and this time around the changes tend to be larger
> in scale (than in Coin). But we constantly keep in mind the possibility of
> applying Amber or Valhalla feature work more widely or “consistently” (for
> a reasonable sense of “consistent”). By the way, Brian is the final
> authority on such work today, and the present note is my interpretation of
> how JLS evolution is working under his leadership.
>
> Here’s a current (not decades old) example of how static analysis in the
> JLS is evolving and how the rules are adjusted. The JLS have always
> constrained use of “this” in a constructor; you have to call “super” first,
> but then you have your own uninitialized fields you are responsible. (And
> the “super” could have called one of your own overrides, which lets the
> super access the uninitialized value of one of your fields. Turing
> machines are wily beasts.)
>
> Now, Valhalla and Amber are adjusting the rules for initializing fields in
> constructors, so that they are different for classic Java classes, and for
> Valhalla value classes, and for Amber records. With Valhalla value classes
> in the current prototype, there is not “super” call, but you cannot touch
> “this” until every field of “this” is definitely assigned. We could have
> done that from the beginning for all classes, but it would have been a hard
> restriction to live with. Imagine the objections: “You mean I can’t call
> my logging helper function at the top of my constructor?”
>
> Still, though the designs are well-reasoned, the differences bug me a
> little. Since the differences apply to emerging parts of the language, we
> might consider spreading around the rules for value classes so they benefit
> other kinds of code. What I’m thinking of (Brian you know this already) is
> perhaps we could take some error conditions for premature use of “this” in
> value classes and turn them into warnings for classic classes, so that code
> that circumvents the DU/DA rules, to obtain access to blank final fields
> uninitialized, will suddenly sprout lint warnings. (Or even turn the
> Valhalla errors into warnings, if we decide consistency wins at that point;
> it doesn’t always win, not by a long shot.) The extra warnings might be
> tolerable to the ecosystem, and it would be useful for some users (not all)
> to chase down the warnings and either fix code or suppress the warnings
> explicitly.
>
> But, for this idea, as for any other, would the benefits to the ecosystem
> be worth the development cost? A sharper question is, should we pause some
> other language feature before we enact some cleanups or generalizations
> that appeal to us? We can’t do everything at once, and just having a
> clever idea (like better warnings on incomplete “this”) or a clever fix to
> javac code (like Archie’s) doesn’t help us decide what our priorities are.
>
> (And static checks only get us a subset of safety. I hope someday to add
> dynamic checks for uninitialized variables to the mix, to catch more user
> errors sooner.)
>
> If I’ve missed some other goal for this PR besides adjusting DA/DU rules
> and/or increasing “consistency”, I apologize for missing it; it wasn’t
> clear to me. But the above is where my mind goes when the question arises
> “what about the rules for this.x?”
>
> — John
>
--
Archie L. Cobbs
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20221202/e7542c9b/attachment-0001.htm>
More information about the amber-dev
mailing list