JDK-8300691 - final variables in for loop headers should accept updates
Archie Cobbs
archie.cobbs at gmail.com
Tue Oct 22 18:35:58 UTC 2024
On Mon, Oct 21, 2024 at 8:13 PM John Rose <john.r.rose at oracle.com> wrote:
> I think there might be something worth doing with some concept possibly
> denotable as “effectively frozen”, so I read quickly through much of this
> thread but failed to find the definition of “frozen” per se (that is,
> explicitly, not effectively, frozen). Lots of references with
> “you-know-what-I-mean” quotes, but I can’t tell what “frozen” is supposed
> to mean here.
>
> (I will thank anyone who points out the definition in this thread of
> “frozen”. But I will plough forward with my own attempt…)
>
My apologies for "effectively frozen", it was an off-the-cuff placeholder,
but a poor one because as you point out "freezing" and "frozen" have their
own (mostly unrelated) history.
Anyway, here's the definition we were using... maybe a better term would be
"quiescent"? Let v be a variable, and let P be a character position in a
source file. Then *v is *quiescent* at P* if there exists no position Q ≥ P
at which there exists an assignment to, or mutation of, v.
Then a variable may be captured by a lambda at P only if it's quiescent at
P. Note, locations Q ≥ P include the lambda itself so this enforces no
mutations within the lambda.
The thought was that "quiescent" might be a candidate pragmatic answer
(read: compromise that satisfies no one :) as it's easy to understand and
would permit most capturing scenarios while still avoiding the most acute
form of the ambiguity that "effectively final" was designed to avoid. As a
data point, this change would allow elimination of 94% of the "dummy
variables" in the JDK itself.
Re: "final shadowing - that is a nice concept - it aligns with the reality
of what actually happens (usually a good thing).
> Along that slippery slope we quickly fall into the question of opening the
> floodgates, and doing final-shadowing on all lambdas everywhere....
>
> Why did’t we do this? There are number of reasons, but the core design
> goal for capture (of up-level variables in both lambdas and inner classes)
> was to eliminate the opportunity to observe a divergence in the behavior of
> the original up-level variable, as opposed to the name which represents it
> in the lambda.
>
This made me realize this issue really is all just about naming. For
example, outer instances are captured just like variables, but we don't
have a problem there because the captured version of the variable has a
different name inside the nested class vs. outside (i.e., "Outer.this" vs.
"outer", if you create the nested class via "outer.new Inner()").
So with a captured variable, we are using the same name for what are in
reality two different things. But instead of saying "these are really two
different things" we say "there is only one possible value this/these
things could have no matter where you are and so you can just pretend there
is only one thing".
> This is obviously a good goal, since code is easier to read when the same
> name means the same thing everywhere, as opposed to “sometimes the live
> variable and sometimes a snapshot I already took”, which is what lambda
> snapshots give you.
>
Entering personal opinion territory here... I wouldn't see such a big
downside with allowing capture of any variable. Maybe that's just because I
know how it really works? It's just a read-only snapshot taken at that
point. Even if it were a new concept, that's just not a hard concept to
grasp... especially in light of the many trickier Java topics like
superclass constructors invoking subclass methods, mutual recursion between
class initializers, anything to do with multi-threaded code...
To me the "effectively final" requirement is like a baby gate that you have
to step over every time you walk between the kitchen and the dining room.
It's not a huge obstacle or anything, but it makes you wonder, who are the
toddlers we are trying to protect here? And haven't they all grown up by
now? :)
Now back to practical reality... I've drafted a fix
<https://bugs.openjdk.org/browse/JDK-8341785> for basic for() loops & would
be interested in your feedback.
Thanks,
-Archie
--
Archie L. Cobbs
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20241022/6565931e/attachment-0001.htm>
More information about the amber-dev
mailing list