RFR: 8341782: Allow lambda capture of basic for() loop variables as with enhanced for() [v2]
Archie Cobbs
acobbs at openjdk.org
Fri Oct 11 14:16:13 UTC 2024
On Fri, 11 Oct 2024 10:13:08 GMT, Maurizio Cimadamore <mcimadamore at openjdk.org> wrote:
>>> It's almost as if the "well-behaved" region "captures" the variables that it uses and makes them temporarily effectively final... which then begs the question, why not just cut out the middle man? That would then put us in a situation where any variable could be captured anywhere (which some have argued for), i.e., everything is effectively final at the point of capture.
>>
>> I am a long-time requester of this feature, in JDK-8300691. I also considered whether other loops have a generalization, but gave it up after some thought. I realized that the distinctive feature of old-for loops is their ability to bind variables that are not visible outside of the for loop, and also is the distinction between the region of the for loop header and for loop body. Due to the traditional way these loops are used, it is very common (though not 100% universal) that such variables may be mutated in the header but are not mutated in the body. The presence of two syntactic regions, one where variation is OK and one where variation is absent, is a very special feature of old-for, and one which frustrates folks that want to use lambdas in the _latter_ region. In the latter region, there is no benefit to telling the user "do not capture this because it might be different later on" (the rationale for non-capture of non-finals) because the only "later on" is another exec
ution of the same loop body, in a different trip of the loop.
>>
>> All this is to suggest why I think this request (and mine) should be _specifically and exactly only for old-for loops_, because they key off of specific and unique syntactic features (variable declaration + two syntax regions).
>>
>> Therefore, I am pleading that we not confuse ourselves by attempting a generalization here. Discarding the specifics of old-for loops in quest of some greater generalization is (IMO) a doomed effort, and even if it ultimately pans out, it should not stop us from dealing with the specifics of old-for loops. If we are smart enough to come up with such a generalization, we will be smart enough to fit it into the current proposal, which is limited to the hardwired specifics of old-for loops.
>>
>> I am the originator of the rule that forbids capture of non-finals (in Java 1.1). I can tell you why it got there (if not how people think about it today).
>>
>> The decision was made (after prototyping) _not to capture_ a full mutable state. (…Such as a constant pointer to a one-element mutable array.) There are numero...
>
>> Thanks for the bug fix suggestion. Should be fixed in [00181f7](https://github.com/openjdk/jdk/commit/00181f7f1b458ab38efc8ffee933e97f5f07419a).
>
> Looks good!
[ Caveat: we're obviously spilling outside this bounds of this PR but hey it's an interesting discussion... ]
> The feature I'm talking about (and maybe some of you may remember me talking about this before) is a re-declaration of a previously declared variable as (now) being final. Let's call it "subsequently-final":
That's a neat idea - thanks for that perspective. Essentially, this would allow you to apply the `final` keyword at any point along the control flow path(s) in which a variable is visible, instead of only at its declaration. In fact, why not just reuse the `final` keyword (thus back-porting its meaning to be "Can't be reassigned from here on out")?
Of course this would be a compile-time thing; as one might expect, there is a parallel runtime concept/debate around "freezing" etc.
All of which points to the central importance of immutability and also therefore treading carefully to get the language concepts right.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/21415#discussion_r1797022767
More information about the compiler-dev
mailing list