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:
>
> http://wiki.ecmascript.org/doku.php?id=harmony:iterators
>
>
> > 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:
> >
> http://lists.common-lisp.net/pipermail/parenscript-devel/2010-December/000914.html
> ).
> >
> > 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'
> bindings.
>
> /be
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>



-- 
    Cheers,
    --MarkM
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110630/6ed48632/attachment.html>


More information about the es-discuss mailing list