lexical for-in/for-of loose end

Brendan Eich brendan at mozilla.org
Mon Feb 6 07:59:32 PST 2012


Andreas Rossberg wrote:
> On 6 February 2012 16:28, Brendan Eich<brendan at mozilla.org>  wrote:
>> >  Andreas Rossberg wrote:
>>> >>  Agreed. As long as we don't spec something weird, the extra effort for
>>> >>  implementations shouldn't be much more than that of an extra block
>>> >>  around the loop body.
>> >
>> >  To take Allen's best shot and re-fire it, what do you think should happen
>> >  here?
>> >
>> >    for (let i = 0, skip2 = function(){i++}; i<  N; i++) {
>> >      foo();
>> >      if (bar())
>> >        skip2();
>> >    }
>
> Pretty much the same as in
>
>    let i_ = 0, skip2_ = function(){i_++};
>    for (; i_<  N; i_++) {
>      let i = i_, skip2 = skip2_;
>      foo();
>      if (bar())
>        skip2();
>    }

Yes, this is something Jon Zeppieri brought up as a reason not to do 
fresh-binding-per-iteration in for(let;;) -- moving the initializer part 
out of the loop loses the binding-per-iteration.

You've shown b-p-i restored manually, with i_ vs. i renaming, but in the 
likely scenarios the user sees only one "i" variable.

Try this version:

   let i = 0, skip2_ = function(){i++};
   for (; i<  N; i++) {
     foo();
     if (bar())
       skip2();
   }


This must "work" (skip2 must advance the one i binding; note no closure 
capture here) just as it does today. Jon was arguing against a change in 
binding semantics simply due to moving the let into the for-head.

We who were in the TC39 meeting room late the second day have overcome 
Jon's good counter-argument. For the greater good on balance, many of us 
TC39ers want to make for(let;;) a special form, so closure capture works 
as most users expect.

You're right that the trade-off where skip2 fails to update any useful 
loop variable (or the first iteration's loop variable only -- agreed 
that is odd) follows from this greater-good choice. But could we do better?

Making dynamic errors out of skip2-like capture seems bad. We can't 
guarantee early errors. Probably best to avoid adding error cases...

> Probably not what the programmer expected, but as others have said,
> it's a trade-off. This use case seems rare,

Agreed on "rare".

>   rather obfuscated style

This isn't so clear to me, since the case where the let is manually 
hoisteid from the for head does "work", and hackers who learned C or C++ 
may think that moving the let into the head is just better style, not 
obfuscatory.

> IMHO, and you can easily work around it. So probably not something you
> want to be optimizing the language semantics for.

I agree with you, but feel a small nagging doubt.

/be


More information about the es-discuss mailing list