<div dir="ltr"><div>I'm curious about this possible future language tweak and have been looking at it more closely: <a href="https://bugs.openjdk.org/browse/JDK-8300691" target="_blank">https://bugs.openjdk.org/browse/JDK-8300691</a></div><div><br></div><div>I think this would be a nice practical change that fits well within the Amber ambit. However, I'm stuck on one question.<br></div><div><br></div><div>To summarize, there are two independent changes being proposed:</div><div><ol><li>Prevent statements in for() loop steps from causing for() loop variables to lose their "effectively final" status</li><li>Allow final for() loop variables to be mutated in the for() step (but not the for() body)</li></ol></div><div><div>Change #1 would allow code like this:</div><div><br></div><div style="margin-left:40px"><span style="font-family:monospace">for (int i = 0; i < 10; i++) {<br></span></div><div style="margin-left:40px"><span style="font-family:monospace">    Runnable r = () -> System.out.println(i);   // hooray, "i" is effectively final<br></span></div><div style="margin-left:40px"><span style="font-family:monospace">}</span></div></div><div><div><br></div><div><div>Change #2 would allow code like this:</div><div><br></div><div style="margin-left:40px"><span style="font-family:monospace">for (final int i = 0; i < 10; i++) {<br></span></div><div style="margin-left:40px"><span style="font-family:monospace">    System.out.println(i);          // we can rest assured "i" can't change in here<br></span></div><div style="margin-left:40px"><span style="font-family:monospace">}<br></span></div><br></div><div>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.<br></div><div><br></div><div>For example, these two examples do not compile:</div><div><br></div><div style="margin-left:40px"><span style="font-family:monospace">final int x = 0;</span></div><div style="margin-left:40px"><span style="font-family:monospace">while (x != 0)</span></div><div style="margin-left:40px"><span style="font-family:monospace">    System.out.println(x);         // error: unreachable statement<br></span></div><div style="margin-left:40px"><span style="font-family:monospace">System.out.println("done");</span></div><div><br></div><div><div style="margin-left:40px"><span style="font-family:monospace">final </span><span style="font-family:monospace">int x = 0;</span></div><div style="margin-left:40px"><span style="font-family:monospace">while (x == 0)</span></div><div style="margin-left:40px"><span style="font-family:monospace">    System.out.println(x);</span></div><div style="margin-left:40px"><span style="font-family:monospace">System.out.println("done");        // error: unreachable statement</span></div><div><br></div><div>We shouldn't expect the equivalent for() statements to compile either, and in fact today they don't:<br></div></div><div style="margin-left:40px"><br></div><div style="margin-left:40px"><span style="font-family:monospace">for (final int x = 0; x != 0; )<br>    System.out.println(x); </span><span style="font-family:monospace">        // error: unreachable statement</span><br><span style="font-family:monospace">System.out.println("done");</span></div><div><br></div><div style="margin-left:40px"><span style="font-family:monospace">for (final int x = 0; x == 0; )<br>    System.out.println(x);<br>System.out.println("done");</span><span style="font-family:monospace">        // error: unreachable statement</span></div><div><br></div><div><div><div>But now suppose we add a step, which Change #2 would newly allow:<br></div></div><div style="margin-left:40px"><br></div><div style="margin-left:40px"><span style="font-family:monospace">for (final int x = 0; x != 0; x++)<br>    System.out.println(x); </span><span style="font-family:monospace">        // error: unreachable statement... ?</span><br><span style="font-family:monospace">System.out.println("done");</span></div><div><br></div><div style="margin-left:40px"><span style="font-family:monospace">for (final int x = 0; x == 0; x++)<br>    System.out.println(x);<br>System.out.println("done");</span><span style="font-family:monospace">        // NOT an unreachable statement</span></div><div><br></div><div>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.<br></div></div><div><div><br></div><div>Alternatively, the compiler could change its behavior to never consider final loop variables as constant expressions, but this could break existing code.<br></div><br><div>Of course, if Change #2 had too many issues, Change #1 would still be useful on its own.<br></div><div><br></div><div>Thoughts?<br></div><br></div><div>Thanks,<br></div><div>-Archie<br></div></div><div><br><span class="gmail_signature_prefix">-- </span><br><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature">Archie L. Cobbs<br></div></div></div>