Clarification on function default param values

Brendan Eich brendan at mozilla.com
Mon Sep 30 20:57:11 PDT 2013


> Brandon Benvie <mailto:bbenvie at mozilla.com>
> September 30, 2013 8:48 PM
> I'm actually now really curious what the following does:
>
> ```
> function foo(x, y = (() => { arguments[0] = "foo"; return "bar" })()) {
>   return [x, y];
> }

Easy: arguments is an early error in the body of an arrow.

http://wiki.ecmascript.org/doku.php?id=harmony:arrow_function_syntax

/be
>
> foo(5);
> ```
>
> Arrow functions are not implicitly strict currently, right? If so, the 
> above should return `["foo", "bar"]`.
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
> Brandon Benvie <mailto:bbenvie at mozilla.com>
> September 30, 2013 8:21 PM
>
>
> I believe it is transpilable if you use an inner function scope. 
> Someone correct me if my translations are semantically incorrect:
>
>
> ES6:
> ```js
> var x = 1, y = 2;
> function foo(x = 3, y = y, z = y) {
>   return [x, y, z];
> }
> ```
>
> ES3:
> ```js
> var x = 1, y = 2;
> function foo(x, y, z) {
>   // defaults
>   if (x === undefined) {
>     x = 3;
>   }
>   if (y === undefined) {
>     y = y; // essentially a no-op
>   }
>   if (z === undefined) {
>     z = y;
>   }
>
>   // body
>   return (function(x, y, z){
>     return [x, y, z];
>   }).call(this, x, y, z);
> }
> ```
>
>
> ES6:
> ```js
> var x = 1, y=2;
> function foo(x=3, y= (x = undefined, 4)) {
>   return [x,y];
> }
> ```
>
> ES3:
> ```js
> var x = 1, y=2;
> function foo(x, y) {
>   // defaults
>   if (x === undefined) {
>     x = 3;
>   }
>   if (y === undefined) {
>     y = (x = undefined, 4);
>   }
>
>   // body
>   return (function(x, y) {
>     return [x, y];
>   }).call(this, x, y);
> }
> ```
>
>
> ES6:
> ```js
> function foo(bar = function() { return 'param-inner' }) {
>   var ret = bar();
>   function bar() {
>     return 'body-inner';
>   }
>   return ret;
> }
> ```
>
> ES3:
> function foo(bar) {
>   // defaults
>   if (bar === undefined) {
>     bar = function() { return 'param-inner'; };
>   }
>
>   // body
>   return (function(bar){
>     var ret = bar();
>     function bar() {
>       return 'body-inner';
>     }
>     return ret;
>   }).call(this, bar);
> }
>
>
>
>
> A clearer example of my own which I think demonstrates the scoping 
> better (or exposes a problem with my understanding):
>
> ES6
> ```js
> function foo(x, y = function() { return x }) {
>   x++;
>   return x + y();
> }
>
> foo(1); // is this 3 or 4?
> ```
>
> ES3:
> ```js
> function foo(x, y) {
>   // defaults
>   if (y === undefined) {
>     y = function() { return x };
>   }
>
>   // body
>   return (function(x, y) {
>     x++;
>     return x + y();
>   }).call(this, x, y);
> }
>
> foo(1); // 3
> ```
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
> Dmitry Soshnikov <mailto:dmitry.soshnikov at gmail.com>
> September 30, 2013 3:51 PM
>
> On Mon, Sep 30, 2013 at 1:17 PM, Jeff Morrison <lbljeffmo at gmail.com 
> <mailto:lbljeffmo at gmail.com>> wrote:
>
>     So I think during the last meeting it was decided that we'd now
>     have two scopes for functions with default param values: One for
>     head/params, and one for the function body.
>
>
> Just re-read meeting notes, OK, cool on two scopes (seems like they 
> are not in the spec yet). Want to double-check though: whether it will 
> be possible to transpile now to ES3? From what I've seen in the notes, 
> the head-scope will be able to access `this` value of the activation, 
> etc. Not sure how to transpile now. Could someone give an example of a 
> wrapper scope please, and confirm whether it's transpilable now?
>
>     Was it also agreed that we'd use let-binding (vs var-binding) for
>     the default-value expressions?
>
>     I also just wanted to clarify some of the awkward edge-case
>     scenarios as I understand them to be sure we're all on the same page:
>
>     var x=1, y=2;
>     function foo(x=3, y=y, z=y) {
>       return [x, y, z];
>     }
>     foo(); // [3, undefined, undefined] ? or [3, 2, 2] ?
>     foo(2); // [2, undefined, undefined];
>     foo(2, 3); // [2, u];
>     x; // 1
>     y; // 2
>
>
>     var x = 1, y=2;
>     function foo(x=3,y=x+1) {
>       return [x, y];
>     }
>     foo(); // [3, 4];
>     foo(2); // [2, 4];
>     foo(2, 3); // [2, 3];
>     x; // 1
>     y; // 2
>
>
>     var x = 1, y=2;
>     function foo(x=3, y=(x=undefined,4)) {
>       return [x,y];
>     }
>     foo(); // [undefined, 4]
>     foo(2); // [undefined, 4]
>     foo(2, 3); // [2, 3] ? or [undefined, 3] ?
>     x; // 1
>     y; // 2
>
>
>     function foo(bar=(function() { return 'param-inner'; })) {
>       var ret = bar();
>       function bar() {
>         return 'body-inner';
>       }
>       return ret;
>     }
>     foo(); // 'body-inner'
>     foo(function() { return 'futility'; }); // 'body-inner'
>
>
> Good examples, but in order to answer I need to see the exact 
> structure of the head-scope. Because of `this` value I'm afraid it 
> won't be static-time transformable or something.
>
> Dmitry
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
> Jeff Morrison <mailto:lbljeffmo at gmail.com>
> September 30, 2013 1:17 PM
> So I think during the last meeting it was decided that we'd now have 
> two scopes for functions with default param values: One for 
> head/params, and one for the function body.
> Was it also agreed that we'd use let-binding (vs var-binding) for the 
> default-value expressions?
>
> I also just wanted to clarify some of the awkward edge-case scenarios 
> as I understand them to be sure we're all on the same page:
>
> var x=1, y=2;
> function foo(x=3, y=y, z=y) {
>   return [x, y, z];
> }
> foo(); // [3, undefined, undefined] ? or [3, 2, 2] ?
> foo(2); // [2, undefined, undefined];
> foo(2, 3); // [2, u];
> x; // 1
> y; // 2
>
>
> var x = 1, y=2;
> function foo(x=3,y=x+1) {
>   return [x, y];
> }
> foo(); // [3, 4];
> foo(2); // [2, 4];
> foo(2, 3); // [2, 3];
> x; // 1
> y; // 2
>
>
> var x = 1, y=2;
> function foo(x=3, y=(x=undefined,4)) {
>   return [x,y];
> }
> foo(); // [undefined, 4]
> foo(2); // [undefined, 4]
> foo(2, 3); // [2, 3] ? or [undefined, 3] ?
> x; // 1
> y; // 2
>
>
> function foo(bar=(function() { return 'param-inner'; })) {
>   var ret = bar();
>   function bar() {
>     return 'body-inner';
>   }
>   return ret;
> }
> foo(); // 'body-inner'
> foo(function() { return 'futility'; }); // 'body-inner'
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>


More information about the es-discuss mailing list