JDK-8300691 - final variables in for loop headers should accept updates
Archie Cobbs
archie.cobbs at gmail.com
Tue Sep 10 23:23:15 UTC 2024
I'm curious about this possible future language tweak and have been looking
at it more closely: https://bugs.openjdk.org/browse/JDK-8300691
I think this would be a nice practical change that fits well within the
Amber ambit. However, I'm stuck on one question.
To summarize, there are two independent changes being proposed:
1. Prevent statements in for() loop steps from causing for() loop
variables to lose their "effectively final" status
2. Allow final for() loop variables to be mutated in the for() step (but
not the for() body)
Change #1 would allow code like this:
for (int i = 0; i < 10; i++) {
Runnable r = () -> System.out.println(i); // hooray, "i" is
effectively final
}
Change #2 would allow code like this:
for (final int i = 0; i < 10; i++) {
System.out.println(i); // we can rest assured "i" can't change
in here
}
Change #1 is straightforward but Change #2 raises an issue. A final
initialized variable is not only immutable but also can be a constant
expression, and this affects reachability analysis.
For example, these two examples do not compile:
final int x = 0;
while (x != 0)
System.out.println(x); // error: unreachable statement
System.out.println("done");
final int x = 0;
while (x == 0)
System.out.println(x);
System.out.println("done"); // error: unreachable statement
We shouldn't expect the equivalent for() statements to compile either, and
in fact today they don't:
for (final int x = 0; x != 0; )
System.out.println(x); // error: unreachable statement
System.out.println("done");
for (final int x = 0; x == 0; )
System.out.println(x);
System.out.println("done"); // error: unreachable statement
But now suppose we add a step, which Change #2 would newly allow:
for (final int x = 0; x != 0; x++)
System.out.println(x); // error: unreachable statement... ?
System.out.println("done");
for (final int x = 0; x == 0; x++)
System.out.println(x);
System.out.println("done"); // NOT an unreachable statement
In the first example, the inner statement is still unreachable, so it's OK
for the compiler to still report that error, but in the second example, the
final statement is now obviously reachable, so the compiler must do
something different. Moreover it would be doing something different based
on inspection of the step for mutations to "x", which seems like "spooky
action at a distance" and could be spec-challenging.
Alternatively, the compiler could change its behavior to never consider
final loop variables as constant expressions, but this could break existing
code.
Of course, if Change #2 had too many issues, Change #1 would still be
useful on its own.
Thoughts?
Thanks,
-Archie
--
Archie L. Cobbs
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20240910/583b41b6/attachment.htm>
More information about the amber-dev
mailing list