Generator issue: exceptions while initializing arguments

Brendan Eich brendan at
Wed Sep 12 05:13:14 PDT 2012

Dmitry Soshnikov wrote:
> On Tue, Sep 11, 2012 at 1:33 AM, Brendan Eich <brendan at 
> <mailto:brendan at>> wrote:
>     If you really want the Pythonic default parameter rules
>     (evaluation in definition context) then you need to address the
>     bad case Jason showed:
>       function foo(arg = []) {
>         arg.push('strange');
>         return arg;
>       }
>       foo(); // ['strange']
>       foo(); // ['strange', 'strange']
>     This is a side channel and a big footgun. ES6 default parameters
>     as proposed avoid it.
> Sure, and as I mentioned in my first message -- ES may eval defaults 
> every time at activation, not only once as Python does. But -- still 
> in the outer scope (in the foo.[[Scope]] in your example).

No, you've solved the literal problem but not the problem of supporting 
later parameters' values depending on earlier parameters.

The scope has to be unique to the activation at hand.

> function foo(arg = <expression>) { ... }
> evaluates the <expression> every time at activation as:
> 1. If expression is a literal value, create a *new* value 
> corresponding to literal. Assign to the parameter. Return.

Sorry, special casing like this does not work, the expression could 
contain mutable (object or array) literals but not be a single literal.

> 2 Else, eval the <expression> in foo.[[Scope]]
> The first step covers and fixes Python's issue. The second allows not 
> going to the activation frame and avoid complexities I noted.
> That's said, we should stick either with outer, or with the inner 
> scope for evaluation. The outer seems more logical. Not with both, 
> otherwise it will be too complicated and error prone use cases (which 
> as I note will anyway be banned as a bad practice, so to support it?).

You say it's too error prone but you don't adduce any evidence.

Meanwhile we have lots of extant code that does things like

   function foo(bar, baz) {
     baz = baz || default_baz;

That's the cowpath we are paving.


More information about the es-discuss mailing list