Concise functions, Nonexistent lambdas, Explicit tail calls

Jon Zeppieri jaz at
Tue Dec 9 20:59:50 PST 2008

On Tue, Dec 9, 2008 at 10:22 PM, Brendan Eich <brendan at> wrote:
> On Dec 9, 2008, at 5:54 PM, Jon Zeppieri wrote:
>> Those were encodings of a for loop that binds the variables in its
>> initialization expression on every iteration.  It's not surprising
>> that it would be complicated to take a user's "i++" and, essentially,
>> turn it into "rebind i with i + 1."
> You're right, that was an extra complication. But something like it will
> come up with for (let x in o), even if we leave the for(let x = ...;;) loop
> binding semantics var-like. There's strong demand for a fresh let binding
> each time through a for-in or for-each-in loop.

Since there is no updateExpr to worry about, that isn't a problem.
The real problem with for/in is that the set of property names can
change under you as the loop executes.  Since the language doesn't
define a way to get a 'cursor' into an object's keys, I'm making it

for (let x in o) body; ==>(with fresh x per iteration)

$_FOR_IN: {
  let $loop = lambda(x, $v) {
    if (x) {
      let $v0 = (lambda() { $_FOR_IN_BODY: { body; } })();
      $loop(Object.getNextKey(0, x), $v0);
    } else {

  $loop(Object.getNextKey(o, null), <empty>);

... where the fictional Object.getNextKey(o, null) returns the first key in o.

Something I omitted from the previous example: 'break' and 'continue'
in body need to be rewritten.
   break; ==> return : $_FOR_IN $v;
   continue; ==> return : $_FOR_IN_BODY $v;

Obviously, that's not the whole story.  There could be labeled breaks
or continues already there, and 'body' can contain its own nested
loops, functions, &c.  I'm still a bit fuzzy on the 'break' and
'continue' rewriting rules.  Dave?


More information about the Es-discuss mailing list