> > Finally, the inability to use non-effectively-final variables would be > > very limiting. Note that the most classic way to iterate numbers in > > Java is still for loop: > > > > for(int i=0; i<array.length; i++) { > > System.out.println("array[\{i}] = \{array[i]}"); > > } > > > > Inability to do this simple thing would be frustrating. > > I see this as more a deficiency of loop induction variables than lambdas > / other capturing constructs. For the old-school for-loop, we're kind > of hosed because the induction variable is intrinsically mutable, but > for the foreach loop, this is probably fixable; > > for (T x : source) > > could treat x as being freshly declared in each block iteration. We > visited this during Lambda; perhaps this could be revisited. So I'm not > yet convinced that the effectively-final restriction is unreasonable. > And, we can always relax from there, but can't go stricter.
This is a somewhat separate topic but I would be glad to see some improvement here with respect to good old for loops, as I often saw copying to a new variable for the sake of lambda capture inside the loop. Like if a variable is declared at the for loop initializer and it's never modified inside the `for` loop body, then let's assume that before body entry, a fresh variable is created with the same name and assigned to the original variable shadowing the original variable. This way, the counter variable of the classic counting loop will be considered as effectively final inside the loop body (but not inside the condition and update expressions). This will make for (int i=0; i<n; i++) {...} close to for (int i: IntStream.range(0, n).toArray()) {...} But without performance overhead. This change is backward-compatible. With best regards, Tagir Valeev