Tennent's correspondence principle and loop-local variable capture

Mark S. Miller erights at google.com
Thu Jun 30 16:47:59 PDT 2011


On Thu, Jun 30, 2011 at 4:39 PM, Brendan Eich <brendan at mozilla.com> wrote:

> On Jun 30, 2011, at 4:27 PM, Mark S. Miller wrote:
>
> 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.)
>
>
> Here it is:
>
> https://mail.mozilla.org/pipermail/es-discuss/2008-October/007819.html
>

That's the one, thanks.



>
> The whole thread is at
>
> https://mail.mozilla.org/pipermail/es-discuss/2008-October/thread.html#7844
>
> Please see Jon Zeppieri's reply in particular, quote:
>
> I think the real problem here is
> that the <updateExpr>, as written by the user, is (or, rather, usually
> is) an assignment, and you should give the user what the user asked
> for.
>
> I also find it odd that
>
> {
>     let x = 0;
>     for (; x < n; x++) ...
> }
>
> should have different behavior than
>
> for (let x = 0; x < n; x++) ...
>
> -Jon
>
> -----
>

This is a valid criticism.



>
> The for(;;) loop is unstructured, the update part after ; really is any
> mutating expression you want (or a pure no-op, even). Specializing *only*
> let binding updates of certain forms (++, +=, -=, *=, what else? How about
> calls to functions that capture the loop variable and mutate it?) is too
> subtle and special. That's why I call it "wrong".
>

This is not. My desugaring does not descend into, special case, or transform
the updateExpr. Any Expression may appear here. In fact, as far as my
desugaring is concerned, any Statement could appear here.




>
> Let's not get hung up on the for(;;) loop. It is an imperative construct.
>

I don't feel strongly about this -- it's just an "it would be nice if we
could fix this." If not, I won't shed any tears.



>
> I think a more important extension to consider, where we have new syntax on
> which to cleanly hang fresh bindings, is something from Algol and C++:
> allowing 'let' to start the condition or discriminant in if, while, and
> switch heads:
>
>   if (let tmp = expensive_condition()) {
>     // tmp in scope here and here only.
>   }
>
>   while (let j = frob(i)) {
>     // j in scope and fresh each iteration here.
>     i = update(i);
>   }
>

Interesting.




> etc.
>
> /be
>



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


More information about the es-discuss mailing list