For loops with per-iteration variables
David-Sarah Hopwood
david.hopwood at industrial-designers.co.uk
Mon Oct 13 21:27:24 PDT 2008
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:
>>
>> let ($i = 0) {
>> for (;
>> let (i = $i) {i < 10};
>> let (i = $i) {{i++;} $i = i;}} {
>> let (i = $i) {...};
>> }
>> }
>>
>> ?
>
> 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); } }
or, to handle break and continue properly given an 'escape' construct
that works similarly to that in E, something like:
label: for (let i = initExpr; condExpr; updateExpr) { body }
==>
{ let ($loop = lambda(i) {
escape {
if (condExpr) {
{ body } (updateExpr); $loop(i);
}
} catch ['break', label] {}
catch ['continue', label] {(updateExpr); $loop(i);}
}) { $loop(initExpr); } }
This also straightforwardly generalizes to multiple variables.
I withdraw the contention that it is too magical.
--
David-Sarah Hopwood
More information about the Es-discuss
mailing list