Tennent's correspondence principle and loop-local variable capture
Mark S. Miller
erights at google.com
Thu Jun 30 16:27:19 PDT 2011
On Thu, Jun 30, 2011 at 4:07 PM, Brendan Eich <brendan at mozilla.com> wrote:
> On Jun 30, 2011, at 3:33 PM, Vladimir Sedach wrote:
> > Hello,
> > I was recently pointed to the block scoping and TCP discussions by
> > Peter Michaux, and have a question as to how this will affect the
> > capture of loop-local variables by closures created in loops.
> A well-known sore point.
> The good news is that for-in and for-of loops in ES.next, when using let
> (or if implicitly using let, in comprehensions, generator expressions, and
> possibly even the for-of loop statmeent) not var, will result in a fresh
> binding per iteration:
> > Some programming languages (Common Lisp in particular) assign a new
> > binding to loop-local variables on every iteration. JS doesn't do
> > this, but there is a way to introduce a new lexical environment on
> > every iteration with the WITH statement, an idea that I first
> > encountered in the Scheme2JS compiler
> > (http://www-sop.inria.fr/indes/scheme2js/). Parenscript uses this
> > trick for translating Common Lisp to JS (a good discussion of how this
> > shows up in loops is here:
> > However the WITH statement is deprecated. How can per-iteration
> > loop-local variable capture be accomplished with the current proposal,
> > and what effect does the Block Lambda Revival proposal have on this
> > issue?
> See above. 'with' is not lexical in any sense, and it has been removed from
> ES5 strict mode, so it is gone from Harmony / ES.next.
> 'let', on the other hand, is the new var, and we have the opportunity to
> make a fresh binding per iteration when for-in/-of is used with 'let'. This
> is the way to go.
> The old C-style for(;;) loop is a hard case. It really does want a single
> shared-mutable loop control variable. Making 'let' instead of var in for
> (let i = 0; i < N; i++) ... bind afresh on each iteration and communicate
> the ++ update across the loop edge is theoretically doable, but it's wrong.
Why is it wrong? I showed a de-sugaring of for(;;) into lambda that creates
a separate binding per iteration. (I can try to find it in the es-discuss
archive if it would be helpful.)
> There's really only one binding there.
> So for-in/-of will benefit with 'let'. Is that enough? If not, you can
> always nest an explicit block inside the loop and capture its 'let'
> es-discuss mailing list
> es-discuss at mozilla.org
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the es-discuss