Auto indexing improved for() loops

Brian Goetz brian.goetz at oracle.com
Tue Dec 5 13:52:35 UTC 2023


The issue you raise -- that the for-each loop does not give you access 
to the index, and that to get it you have to fall all the way back to an 
old-style iterator loop -- is a valid concern (in fact, I raised this as 
a comment during JSR 201.)

The syntax that you propose looks pretty "nailed on", though; there are 
contexts in the language where a single variable declaration is used in 
conjunction with some other syntax construct, including the foreach loop:

     for (VariableDecl : Expression)

and contexts where there are multiple variable declarations separated by 
commas (such as method declaration), but no context where there are 
exactly two *and then some weird stuff*.  There is no existing model 
here to appeal to about what

     for (VariableDecl, VariableDecl : Expression)

would mean, which adds cognitive load for users (among other things.)

A more grounded approach would be something like:

     interface ListIndex<T> {
         int index();
         T element();
     }

and allow a ListIndex<T> to be used as the induction variable for an 
iteration:

     for (ListIndex<String> i : strings) {
         ... i.element()  ... i.index()
     }

There are two "obvious" objections; one is that it is more wordy, and 
the other is "mumble mumble but performance".  But the latter goes away 
with Valhalla, so let's not speak of it again.

It seems something we could pursue at some point in the future, but 
probably after Valhalla.



On 12/5/2023 4:00 AM, P Holder wrote:
> I'm participating in Advent of Code 2023 using Java.  It reminds me 
> how I frequently wish I could have an index in a modern for loop 
> without having to resort to using the old/traditional for loop.  Now 
> that the JEP 456 Unnamed Variables & Patterns is progressing nicely I 
> can see how it could be used implicitly to grant my wish.
>
> Instead of writing:
>
> final String[] strings = getSomeStrings();
> int index = 0;
> for (final String str : strings)
> {
>   // use the str and the index
>   index++;
> }
>
> and risking the chance I may forget to place the index++ ... I would 
> rather have something like:
>
> final String[] strings = getSomeStrings();
> for (int index, final String str : strings)
> {
>   // use the str and the index
> }
>
> where the new part "int index" is optional, and the compiler could 
> treat it like "int _" if not specified.  Of course it could also be 
> long, one assumes.
>
> I do realize it's merely syntactic sugar and I do know how to write 
> the code I need, but it does surprise me the number of times I end up 
> writing old for loops simply because I could use the index, but 
> otherwise know doing it the modern way is cleaner and more expressive, 
> if only I had the index too.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20231205/ac069f85/attachment.htm>


More information about the amber-dev mailing list