Tennent's correspondence principle and loop-local variable capture

Brendan Eich brendan at mozilla.com
Thu Jun 30 16:59:40 PDT 2011


On Jun 30, 2011, at 4:47 PM, Mark S. Miller wrote:

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

It is, and you're right, it's not the same as the one I tried to get away with below:



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

But Jon's post, a bit earlier, pointed out how your desugaring did not handle all cases. This led me to think you weren't trying to handle them all. Sorry about that!


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

No tears, no fears. Jon's point about pulling the let out before the loop changing things seems solid. I won't try to generalize it much, but here's an attempt:

So far, prior to 'let', JS's C-style

  for (init; cond; update {
    body
  }

has been what it is in C: sugar for

  init
  while (cond) {
    body
    update
  }

This implies not coupling the parts in new ways, such as a fresh-per-iteration binding when init is "let i = 0" that is initialized only the first time by that " = 0" initialiser, and somewhat magically initialized subsequently from the previous iteration's post-update value of the binding.

See what I mean?

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


More information about the es-discuss mailing list