JDK-8300691 - final variables in for loop headers should accept updates
Tagir Valeev
amaembo at gmail.com
Wed Sep 11 04:22:27 UTC 2024
Hello!
I think that both changes would be extremely confusing. What Java really
needs is ranges as first-class citizens. In this case, nobody would need
ugly and error-prone classic for loop, and the problem will go away.
Instead for(int i=0; i<10; i++) people will use enhanced for syntax:
for(int i: 0..9) or something like this.
In fact, even today one can easily declare a static method like range(from,
to) which returns an Iterable<Integer>, and modern C2 eliminates boxing
quite efficiently in this case. So probably we should simply write our code
this way?
for(int i: range(0, 10))
Tagir.
On Wed, Sep 11, 2024, 03:16 Archie Cobbs <archie.cobbs at gmail.com> wrote:
> 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/20240911/bd7648f2/attachment-0001.htm>
More information about the amber-dev
mailing list