January 19 meeting notes

Grant Husbands esdiscuss at grant.x43.net
Fri Jan 20 04:25:06 PST 2012

Jon Zeppieri wrote:
> Is there a version of this desugaring that deals with recursive
> bindings in the initializer expression of the loop?

How about something like this?
(given for (let <varName> = <initExpr>; <testExpr>; <updateExpr>) { <body> } )

  let <varName> = <initExpr>;
  while(true) {
    if (!<testExpr>) { break breakTarget; }
    let <tempVar> = <varName>;
      // There might be a better way to copy values to/from shadowed variables
      // (using temporaries seems a bit weak)
      let <varName> = <tempVar>;
      continueTarget: { <body> }
      <tempVar> = <varName>;
    <varName> = <tempVar>;

That way, all of the variable references in initExpr, testExpr and
updateExpr refer to a singular copy and all of the variable references
in body refer to the iteration-scoped ones.

So, looking at your example:
> for (let [i, inc] = [0, function() {i++;}]; i < n; inc()) ...

I think it now has the desired behaviour. However, people calling inc
from inside the body will still be surprised. I think solving that
probably requires something more advanced than a desugaring, as it
means the loop variables captured by that function (or, alternatively,
ones captured inside the body) need to point at different variables at
different times.

There's also an abstraction leakage if one breaks in the body, in that
the inner <varName> doesn't get copied to the outer one. All in all,
not a great desugaring, but I thought it might be worth offering.

Maybe disallowing capture in the for (let ...;...;...) head would be easier.

Grant Husbands.

More information about the es-discuss mailing list