JDK-8300691 - final variables in for loop headers should accept updates

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Mon Oct 21 16:36:24 UTC 2024


>
> Example A:
>
> for (int i = 0; i < 10; i++) {
>     Runnable r = () -> System.out.println(i);
> }
>
> Example B:
>
> for (int i = 0; i < 10; ) {
>     Runnable r = () -> System.out.println(i);
>     i++;
> }
>
> I am claiming that Example A is much clearer than Example B in terms 
> of ambiguity (which is the whole problem "effectively final" was 
> invented to solve).
>
> Now the above claim is a claim about what developers intuitively 
> perceive, so it's fuzzy by nature and I could certainly be in the 
> minority view here!
>
> All I can confidently say is that after thinking about it and looking 
> at the examples in the JDK, my own developer intuition would be 
> comfortable with an "effectively frozen at the point of capture" rule, 
> and I would be pleased with the resulting ability to get rid of almost 
> all of my "dummy variables". To me Example A is perfectly clear, while 
> Example B is less clear.
>
> I'm curious what your "developer intuition" thinks. Do you look at 
> Examples A and B and perceive them as equally ambiguous?

I also find A better. What I'm trying to say is that if a developer is 
confused (by the i++) on what "frozen" means for a loop variable, they 
won't find any clarity in our explanation that "lexically scoping trumps 
everything else". E.g. whether a developer reads the STEP part of a loop 
as part of the body (after the end of the body) or not is, I believe, a 
very subjective thing - and one which affects how any change we make in 
the area will be perceived (IMHO).

>
> Taking a step back, the observation that motivates the original 
> proposal (to me at least) is that developers perceive each iteration 
> of the body of a for() loop as its own thing, with the loop variable 
> serving the same role as a method parameter. That is, the body of a 
> for() loop is just a parameterized block of code - i.e., a thing we 
> usually call a "method" - that you "invoke" multiple times, and the 
> loop variable is the parameter. One can view a for() loop as just a 
> special syntax for inlining a method that you want to invoke multiple 
> times in succession with a sequence of parameter values. So just as 
> method parameters are effectively final within their methods, so 
> should loop variables be "effectively final" within their loop bodies.
If that is how a developer perceives a loop, I agree that either these 
new rules, or the old one pose no issue whatsoever.
>
> Again, we're in the domain of "developer intuition" and "perception" 
> so things are fuzzy... and compiler developers may not constitute a 
> representative sample :)

That's what I'm a bit worried about. My general feeling is that there 
will be users that will find your explanation perfectly rational - and 
some other users who will need to find a coping mechanism as to why the 
+= in the STEP of a for loop is to be interpreted less literally.

Of course, as with every new proposed feature, we hear a lot from 
developers who think that the new proposal addresses a specific pain 
point that they thought should never existed in the first place. But we 
tend to hear less about a less vocal portion of users who might just be 
silently ok with the status quo. Or maybe, in this instance, we don't 
hear from them because they aren't there (although, Tagir expressed some 
concerns [1], so I have to assume there are such developers out there  
_somewhere_ :-) )

[1] - 
https://mail.openjdk.org/pipermail/amber-dev/2024-September/008922.html


>
> -Archie
>
> -- 
> Archie L. Cobbs
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20241021/df6cc098/attachment.htm>


More information about the amber-dev mailing list