Generator issue: exceptions while initializing arguments

Brendan Eich brendan at
Mon Sep 10 14:23:17 PDT 2012

Brendan Eich wrote:
> Morever, the opening left brace does not make a scope boundary between 
> formals and local vars. It doesn't even make a hoisting boundary for 
> functions:
> js> function f(x){ function x(){}; return x; }
> js> f(42)
> function x(){}

I plead jetlag. Still not quite what I wanted. Try this:

js> function f(x){ function x(){}; return [arguments[0], x]; }
js> f(42)
[function x(){}, function x(){}]

If hoisting stopped at the { then one might expect, even with one scope 
contour in which to bind 'x', that arguments[0] would be 42. Not so, but 
of course with arguments a magic object whose element accessors alias 
formal parameters, this still doesn't prove enough.

But I claim it does show backward compatibility constraints that we must 
satisfy, while also minimizing the complexity of the user's cognitive 
model, and of the spec. The sweet spot for me is to fold formal 
parameters into the body, as far as default parameters and anything else 
involving expression evaluation go.

Yes, we could complicate the spec with temporal dead zones for 
parameters to the right, so that

   function f(a, b=a, c=d, d=42) {...}

would either find an outer 'd' for the c parameter default value, or 
throw on read from a temporally dead 'd' parameter. But given the 
var-like nature of args in ES1-5:

   function f(x) { var x; return x; } // identity function
   function f(x) { arguments[i]=42; return x; } // 42 if i=0

the simplest, or least mentally burdensome in full (avoiding splitting 
cases into compatible and new), way forward is for parameters to be 
var-like bindings in the same scope as top level var and function (but 
not let), and for default parameters to be evaluated as if in the body, 
first thing after any implicit yield (if in a generator function), as 
Jason suggested.


More information about the es-discuss mailing list