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

Johannes Spangenberg johannes.spangenberg at hotmail.de
Thu Oct 24 00:21:52 UTC 2024


Hi, here are my two cents after following the discussions. I personally 
find the limitation a little bit annoying. In my experience, most other 
languages (JS, Python, C++, Rust, ...) allow to capture (non-final) 
variables in lambdas. At least Java is the only language where I have 
noticed this limitation so far. However, I also don't find this 
limitation too bothersome.

> I think Ron has captured the stewardship argument about how we would 
> like users to view the language: that the two sorts of loops, assuming 
> each are "well behaved", should be interchangeable, refactorable to 
> each other, etc, and that the differences in scoping should be an 
> "implementation detail."

I think it is hard to explain that we may consider the variable of an 
old-style for-loop to be scoped to the individual iteration. Consider 
the behavior of the following code:

    for (int i = 0; i < 4; i++) {
         if (...) {
             i += 1;
         }
    }

Changes on the variable made inside the body will affect future 
iterations. In other words, you would than need to explain that 
actually, the scope of the variable depends on whether the variable is 
modified within the body. I think you are better off just explaining 
that there is a special case implemented for allowing capturing 
variables of old-style for-loops.

>> 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.
>
> Here I don't think I agree. It's not like developers are avoiding loop 
> because the capture rules are what they are. If you need a loop, you 
> need a loop. Maybe they are avoiding capturing lambdas - but again, 
> replaced with what? Anonymous inner classes will have similar issues. 
> And if you need capture you need capture - you can't make that go 
> away. Perhaps they are disguising the capture a little harder, by 
> using an array, or an AtomicXYZ. But I'd say that, while the numbers 
> we have seen might surely underestimate things a bit, I don't expect 
> to see dramatic differences in the wild.
>
I would estimate that in 80 % of cases where I encountered the 
limitation, I ended up to refactor the code by either introducing an 
Iterable, so that I can use an enhanced for-loop, by extracting the 
content of the loop into a separate method, or by replacing the lambda 
with a named class. However, I think in a noticeable amount of cases, 
the code also got more readable after spending the additional time.

At the end, I find the proposal which is special-cased to the for-loop a 
bit strange. While I wouldn't have a problem with it, I think it would 
always stay a feature specifically implemented for this style of loops. 
I don't think that you can explain it away. Also, as it has been shown 
earlier in the discussion, this solution would elevate the pain for not 
even half of the affected cases. I think that Java should remove the 
limitation in even more cases (as was proposed earlier), or focus on 
making enhanced for-loops more usable (for example by providing ranges). 
Note that in my experience, many languages (e.g. the same as mentioned 
at the start of this email) seem to put much more focus on making the 
enhanced for-loop the default.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20241024/b0acd180/attachment-0001.htm>


More information about the amber-dev mailing list