lexical for-in/for-of loose end

Allen Wirfs-Brock allen at wirfs-brock.com
Thu Feb 2 18:08:38 PST 2012

On Feb 2, 2012, at 5:07 PM, Jason Orendorff wrote:

> On Thu, Feb 2, 2012 at 5:52 PM, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:
>> Unfortunately, having thought about it a bit since the meeting, I'm less
>> convinced. We didn't look too deeply at possible capture scenarios such as:
>> let geti;
>> for (let i=(geti = function() {return i},expr), expr, incr = function(i++),
>> decr=function(i--), cmp=function(){return i<n}; cmp();incr()) {
>>        let j=i;
>>        i +=10;
>>        decr();
>>        ...
>>        If (j+-9 !== i) ...
>>        ...
>> }
> What?! We should not reward people writing code like that.
> I would be fine with the initializer-expression not being in the scope
> of i at all.

No reward, it is simply what the current syntax permits, and it is important that semantics are consistently applied.  The initialization semantics I assume here are exactly the same that would apply if if the let clause  of the for was pulled out and used as a standalone statement. In general, excluding i from the visibility of the initializer expression would prevent writing recursive functions definitions such as:

   const fact = function (n) {return n<=1 ? 1 : n*fact(n-1)};

for-in works well with a per iteration binding because there is no header code that runs between iterations.  The various desugarings that have been proposed to provide a fresh copy for each iteration of this form of for work for propagating simple values between the header and each iteration but not for closure captures.

Plus, the desugarings aren't things that are really suitable for teaching the semantics to everyday JS programmers.  You instead have to say something like:

Ok, this is really complicated but here goes.  For each let/const declared in the for header, a fresh variable is located in the loop body for each iteration of the loop. However, the values of the loop variables are automatically copied from the previous iteration into the next iterations.  This means that basic expression operator will work in the loop header pretty much like you would expect.  But be careful if you use any function expressions in the for header because the loop variables they reference may not be from the current iteration and any changes to loop variable they make may not have the effect you intended.  But, hey you probably shouldn't do those things so it really doesn't matter what it really does.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20120202/a41c58f4/attachment.html>

More information about the es-discuss mailing list