JDK-8300691 - final variables in for loop headers should accept updates
John Rose
john.r.rose at oracle.com
Wed Oct 23 19:28:27 UTC 2024
On 23 Oct 2024, at 3:14, Maurizio Cimadamore wrote:
> …
> So yes, a big part of this exercise is in trying to keep variable names meaning the same thing no matter where they appear (captured or not). If we start snapshotting everything, then you have two version of a local, the one snapshotted and captured e.g. inside a lambda, and the one (maybe mutable!) available outside.
Good summary.
> …
> Of course you can argue it both ways: by making the new capture treatment only available for induction variables in for loops (where the variable is not mutated in the body) we do reduce (not eliminate!) the chances of somebody observing different values for the same induction variable.
I don’t see the sub-point about “not eliminate”; I think the reduction is complete to the point of elimination, because of the special (weird) properties of the old-for loop.
For me the unique justification of final-shadowing a variable (1) declared by the old-for loop and (2) exactly in the body of the loop means that “somebody can observe” variations in the value of that variable exactly and only in the old-for loop header. That fulfills the goal of fully eliminating chances for somebody seeing unexpected values. With the admitted exception of the old-for loop header, but that is exactly where everybody EXPECTS to see such variations.
So the chance of surprise is (uniquely) low for this (very particular) case. That’s why I think we should use apply the (helpful? interesting?) idea of final-shadowing exactly in this one circumstance where it will cause very much more benefit than surprise. (Do we use final-shadowing again? Maybe not, but for me it is a clarifying concept.)
I also think the feature will be enjoyed far more than “20 or 30” times, or whatever corpus analysis tells us. Corpus analysis by definition measures the way people have used the language in the past, and that is often affected by their avoidance of sharp corners in the language. I believe this little polish of a central syntax in Java will affect the way people shape their code in the future. At least, it will for me, because I know I’ve done extra work to avoid the sharp corner in the past.
— John
P.S. Archie, I don’t think character positions should be appealed to; that’s not a natural tactic for the JLS. (Despite some very low-level and odd rules about forward references between field initializers, which sort of depend on character positions.) Appealing to character positions instead of block structure inhibits understanding of code at the AST level (which IDEs want to do). If I were going in that direction I’d piggy-back on the reachability analysis the JLS already has, in order to track setting of finals. I’d ask, “can the captured variable be reassigned in some code B reachable from the capture point A?” in a way analogous to asking “can this final, once assigned at point A, ever be reassigned at point B?” Note the connection to finals, which is not accidental. Finals are all about saying, “this variable is only a value, and does not provide access to a future evolution of states”.
More information about the amber-dev
mailing list