lexical for-in/for-of loose end
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
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