lexical for-in/for-of loose end

Brendan Eich brendan at mozilla.org
Sun Feb 5 16:10:14 PST 2012

Grant Husbands wrote:
> For what you're talking about, I think this might be an equivalent
> proposal that's more spec-friendly:
> 'Note' all closures (dynamically) created in (lexically) the loop
> initializer.

Only in the initializer? Why should closures formed there be dynamically 
scoped to the current iteration? That's something done nowhere in the 
language as extended by let/const, either in JS1.7+ in SpiderMonkey and 
Rhino, or in draft ES6 so far.

I admit it's yet another non-throwing possibility beyond 0th-iteration 
scope and 1st-iteration scope. It is not the same as evaluating the 
initializer in each iteration's scope, though. Instead there's a dynamic 
scope for closures in the initializer (only those using the 
for(let-declared bindings?) not used for expressions or other closures, 
or something like that.

Dynamic scope is a warning sign, almost always a mistake.

>   Each time you start an iteration, update all the loop
> variable activation record pointers within those to point at the
> current iteration's activation record (which should, with care, have
> the same shape).

Note that non-strict eval can affect the activation's shape.

> Or, here's one that copies the other way (and is probably cleaner):
> 'Note' all closures (dynamically) created in (lexically,
> post-desugaring) the loop body. Each time you end an iteration, update
> all the loop variable activation record pointers to point at a new
> clone of that activation record.

This is a more complex spec than one that models each iteration having 
its own lexical scope. The spec needs only declarative environments, not 
hidden references and pointer updates.

> In each case, you require a list of not-necessarily-predictable size
> to note the closures in. That's not a big problem; it's just something
> you need to be aware of.

As an implementation technique, Chez Scheme's heap boxing and assignment 
conversion could be even better. But this is all beyond the spec.

Still trying to be sure you intended a unique and dynamic scope for the 
initializer (first part) of for(let;;).


More information about the es-discuss mailing list