Brendan Eich wrote: > I agree we want to capture the first-iteration bindings in any closures in > those declarators' initializers. > > This requires unrolling the loop once. Let's see how the desugaring from: [snip]
For what it's worth, I agree with Mark's (2008) and Brendan's desugarings and hereby withdraw my own, as the value-copying covers barely any more use cases. Without some extensive feature like let-aliasing, as Herby suggested, those solutions as good as we're going to get, though I could have missed some of the discussion so far. By the way, if apparent code duplication in Brendan's desugaring is an issue, a small change will fix that, with little cost, like so: $loopEnd: { let $initdone = false; const $loop = { |d1, ... dN| if (!$initdone) { $initdone = true; d1 = e1, ... dN = eN; } if (!cond) break $loopEnd; body; update; $loop(d1, ... dN); } $loop() } As for modifications done by the for-head's closures, I have no strong opinions. In both proposed desugarings, those modifications would be invisible to the loop body fairly quickly. And in all proposals that don't involve some kind of extensive variable aliasing, the for-head's closures cannot observe values set in the loop body (beyond the first iteration). However, I hope I don't delay consensus by raising the possibility of another desugaring using consts: $loopEnd: { const d1 = e1, ... dN = eN; const $loop = { |d1, ... dN| if (!cond) break $loopEnd; body; update; $loop(d1, ... dN); } $loop(d1, ... dN); } That way, the for-head's closures can't easily have hidden unexpected effects, though they'll still observe incorrect iterated values, and it's less of a sledgehammer than disallowing capture altogether. It's late, so I apologise if I've missed something really obvious or typed garbage. Regards, Grant. _______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss