Tennent's correspondence principle and loop-local variable capture

Brendan Eich brendan at mozilla.com
Thu Jun 30 16:39:05 PDT 2011


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

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
-----

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".

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

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);
  }

etc.

/be
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110630/63fa21ba/attachment.html>


More information about the es-discuss mailing list