David-Sarah Hopwood wrote: > David-Sarah Hopwood wrote: >> David-Sarah Hopwood wrote: >>> Mark S. Miller wrote: >>>> [...] I recommend the per-iteration view. If we can >>>> agree quickly on per-iteration, then >>>> >>>> for (const x = ...) {...x...} >>>> >>>> should be allowed in ES3.1 (whether or not const hoists to block >>>> start). After ES3.1 >>>> >>>> for (const i :T[i] = ...) {...; a[i] = function(){...i...}; ...} >>>> >>>> would then mean what it should mean. Cool. >>> Not so fast :-) Consider: >>> >>> for (let i = 0; i < 10; i++) { ... } >>> >>> In the "i++", which iteration's 'i' is the LeftHandSideExpression >>> referring to? Or does this expand to something like: >>> [snip] >> This expansion is wrong for the case where the body updates i. >> I'll have to think about it some more. > > MarkM is right that it just falls out of the natural tail-recursive > encoding of a for loop. I got the above expansion wrong by trying to do > it imperatively, which was silly -- the tail-recursive expansion is much > simpler: > > for (let i = initExpr; condExpr; updateExpr) { body } > ==> > { let ($loop = lambda(i) { > if (condExpr) { > { body } (updateExpr); $loop(i); > } > }) { $loop(initExpr); } }
Argh. Still wrong (the updateExpr updates the previous iteration's variable, rather than the next iteration's, which means that a closure that captures the variable in iteration n will end up seeing its value in iteration n+1). To fix that problem it should be: for (let i = initExpr; condExpr; updateExpr) { body } ==> { let ($loop = lambda(i) { (updateExpr); if (condExpr) { { body } $loop(i); } }, i = initExpr) { if (condExpr) { { body } $loop(i); } } } > This also straightforwardly generalizes to multiple variables. Yes, it still does. -- David-Sarah Hopwood _______________________________________________ Es-discuss mailing list Es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss