For loops with per-iteration variables

David-Sarah Hopwood david.hopwood at industrial-designers.co.uk
Mon Oct 13 21:47:16 PDT 2008


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



More information about the Es-discuss mailing list