Clarification on function default param values

classic Classic list List threaded Threaded
24 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Clarification on function default param values

Jeff Morrison
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
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Clarification on function default param values

Jeff Morrison
Typo in first scenario fixed

On 9/30/13 1:17 PM, Jeff Morrison 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.
> 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, undefined, undefined];
> 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
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Clarification on function default param values

Dmitry Soshnikov
In reply to this post by Jeff Morrison

On Mon, Sep 30, 2013 at 1:17 PM, Jeff Morrison <[hidden email]> 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
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Clarification on function default param values

Matthew Robb
var f = function(a=this){}

would transpile to something like:

var f = (function(){

function __funcHead__(){
a=this;
}
function __funcBody__(){
// do stuff
}

var a;

return function(a){__funcHead__.apply(this, arguments);return __funcBody__.call(this)}

}());

If my interpretation is correct.


On Mon, Sep 30, 2013 at 3:51 PM, Dmitry Soshnikov <[hidden email]> wrote:

On Mon, Sep 30, 2013 at 1:17 PM, Jeff Morrison <[hidden email]> 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
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss




--
- Matthew Robb

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Clarification on function default param values

Brandon Benvie-2
On 9/30/2013 7:34 PM, Matthew Robb wrote:

> var f = function(a=this){}
>
> would transpile to something like:
>
> var f = (function(){
>
> function __funcHead__(){
> a=this;
> }
> function __funcBody__(){
> // do stuff
> }
>
> var a;
>
> return function(a){__funcHead__.apply(this, arguments);return
> __funcBody__.call(this)}
>
> }());
>
> If my interpretation is correct.
>

Not exactly. We're talking about lexical scopes, not function scopes.
|this| applies at the function scope (aside from global and arrowfunc
scope).
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Clarification on function default param values

Brandon Benvie-2
In reply to this post by Dmitry Soshnikov
On 9/30/2013 3:51 PM, Dmitry Soshnikov wrote:
> 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?

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
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Clarification on function default param values

Brandon Benvie-2
I'm actually now really curious what the following does:

```
function foo(x, y = (() => { arguments[0] = "foo"; return "bar" })()) {
   return [x, y];
}

foo(5);
```

Arrow functions are not implicitly strict currently, right? If so, the
above should return `["foo", "bar"]`.
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Clarification on function default param values

Brendan Eich-3
> Brandon Benvie <mailto:[hidden email]>
> 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
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss
>
> Brandon Benvie <mailto:[hidden email]>
> 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
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss
>
> Dmitry Soshnikov <mailto:[hidden email]>
> September 30, 2013 3:51 PM
>
> On Mon, Sep 30, 2013 at 1:17 PM, Jeff Morrison <[hidden email]
> <mailto:[hidden email]>> 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
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss
> Jeff Morrison <mailto:[hidden email]>
> 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
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss
>
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Clarification on function default param values

Brandon Benvie-2
On 9/30/2013 8:57 PM, Brendan Eich wrote:
> Easy: arguments is an early error in the body of an arrow.

Ok cool, that simplifies my previous examples a bit then. Instead of
using `call` and specifying the name of each argument, you can just use
`.apply(this, arguments)`.
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Clarification on function default param values

André Bargull-2
In reply to this post by Brendan Eich-3
> 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

This restriction is  not specified in the rev19 draft. Currently arrow functions don't have an own `arguments` binding, but instead access the outer functions `arguments` object, similar to `this`. Disallowing the identifier "arguments" in PrimaryExpressions also should imply disallowing "arguments" as a BindingIdentifier, which shifts arrow functions again into "almost strict-mode".

- André

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Clarification on function default param values

Andreas Rossberg-4
In reply to this post by Jeff Morrison
On 30 September 2013 22:17, Jeff Morrison <[hidden email]> 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.
> Was it also agreed that we'd use let-binding (vs var-binding) for the
> default-value expressions?

I'm not entirely sure, actually. We discussed some pretty obscene
examples that would arise form doing a var-like thing, while nobody
came up with an example where it would be useful. I think in the end
the tendency was towards let-like, although I don't remember a formal
consensus. I assume let-like in my replies below.

> 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];
> }

All parameters are in scope in the default expressions, so y is never
going to resolve to the global var binding. Also, all defaults are
being evaluated and bound left to right.

For more examples, see also my slides, which weren't yet linked in the
meeting notes that Rick posted:

https://github.com/rwaldron/tc39-notes/blob/master/es6/2013-09/default-arguments.pdf


> foo(); // [3, undefined, undefined] ? or [3, 2, 2] ?
> foo(2); // [2, undefined, undefined];

These two would throw, because y is used before being bound (just like
'let y=y' throws).

> foo(2, 3); // [2, undefined, undefined];

This one would be  [2, 3, 3].

> 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];

No, [2, 3] for the latter.

> 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];
> }

This one I really dislike. I had actually proposed to disallow
assignment to other parameters in default expressions, but that got a
lot of resistance.

> foo(); // [undefined, 4]
> foo(2); // [undefined, 4]

Yes.

> foo(2, 3); // [2, 3] ? or [undefined, 3] ?

[2, 3], the default expressions are not evaluated if the argument
isn't undefined.

> 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'

Yes.

/Andreas
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Clarification on function default param values

Andrea Giammarchi-2
In reply to this post by Brandon Benvie-2
Just a quick one.
I think the best representation in ES3 or 5 would be the following

```javascript
function foo(x, y, z) {
  switch(arguments.length) {
    case 0: x = 1;
    case 1: y = 2;
    case 2: z = 3;
  }
  // whatever logic involved, i.e.
  return x + y + z;
}
```

no break and no default is meant.



On Mon, Sep 30, 2013 at 8:21 PM, Brandon Benvie <[hidden email]> wrote:
On 9/30/2013 3:51 PM, Dmitry Soshnikov wrote:
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?

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
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Clarification on function default param values

Brendan Eich-3
No, we are using undefined actual parameter value, not argument.length,
to trigger defaulting -- as discussed many times and cited by me (again)
recently in reply to Oliver. Please do not go backward.

/be

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Clarification on function default param values

Allen Wirfs-Brock
In reply to this post by André Bargull-2

On Oct 1, 2013, at 12:03 AM, André Bargull wrote:

> 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

This restriction is  not specified in the rev19 draft. Currently arrow functions don't have an own `arguments` binding, but instead access the outer functions `arguments` object, similar to `this`. Disallowing the identifier "arguments" in PrimaryExpressions also should imply disallowing "arguments" as a BindingIdentifier, which shifts arrow functions again into "almost strict-mode".

- André

The restriction we want and how to enforce it is not all that clear.

We don't really want to have an "almost strict" mode for the body of arrow functions, if that was going to be the case I think it would be much better to simply say that arrow functions are always strict.

The spec. currently applies the static semantics of strict mode formal parameters (no duplicate names, can't name a parameter 'eval' or 'arguments') to arrow function formal parameters, but in all other ways both the formal parameter list (think default value expressions) and the arrow function body follow the strictness of the surrounding code.

that means things like the following are valid in non-strict arrow functions:

() =>  {function arguments() {}; return arguments}
() => {let arguments =5; ...}

So we can't just statically disallow 'arguments' references in a ConciseBodu

Also, we have to have consistent behavior for an 
  eval('arguments')
that appears in a ConciseBody.

Here are possible reasonable alternatives for handling arguments in arrow functions:

1) nothing special, same rules as a FunctionExpression. An arguments object is available and strict/non-strict distinctions apply both statically and dynamically.

2) nothing special, but strict arguments object.  Just like #1 except it always has a strict mode arguments object (no joining of augments elements and formal parameters

3) #2, plus strict mode parameter naming restrictions are also applied (no duplicates, can't use 'eval' or 'arguments' as parameter names)

4) no-arguments objects with shadowing, 'arguments' binds to undefined.  Arrow functions do not have an arguments objects but they have an implicit constant binding of 'arguments' in their parameter scope whose value is undefined.  References to 'arguments' in the body evaluate to undefined. (unless, non-strict and there are explicit declarations of the name 'arguments');

5) no-arguments objects with shadowing, 'arguments' is in temporal dead zone.  Arrow functions do not have an arguments objects but they have an implicit binding of 'arguments' in their parameter scope that is never marked as initialized.  References to 'arguments' in the body throw because they are temporal dead zone references. (unless, non-strict and there are explicit declarations of the name 'arguments' that shadow the parameter level binding);

6) nothing special, but no arguments object, normal lexical scoping. Like #1 except that there is no arguments object or local binding of 'arguments'.  References to arguments resolve via the enclosing scope.

7) strict mode name restrictions, but no arguments object, normal lexical scoping. Like #3 except that there is no arguments object or local binding of 'arguments'.  References to arguments resolve via the enclosing scope.

The rev19 spec. current has approximately #7 but there isn't anything final about that.  It sounds to me like some think either #3 or #4 is the plan of record although I don't think we've talked about it at a TC39 meeting that this level of detail.

I think #3 would be a good solution. So is #7.

#3 probably would seem reasonable to JS programmers. #7 probably is what lexical scoping heads would expect. #4 or #5 is a completely new semantics that I don't think anyone expects.

Allen







_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Clarification on function default param values

Andrea Giammarchi-2
In reply to this post by Brendan Eich-3
I see. Does `null` count as undefined too or it must be explicitly undefined ? not that using a transpiler this matters much ... just curious about how the ES < 6 will look like.


On Tue, Oct 1, 2013 at 11:02 AM, Brendan Eich <[hidden email]> wrote:
No, we are using undefined actual parameter value, not argument.length, to trigger defaulting -- as discussed many times and cited by me (again) recently in reply to Oliver. Please do not go backward.

/be



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Clarification on function default param values

Erik Arvidsson
In reply to this post by Allen Wirfs-Brock
3 and 7 both seems good. Personally I prefer #7 but I'm worried that
it might be too surprising that arguments refers to the outer
function.

On Tue, Oct 1, 2013 at 11:11 AM, Allen Wirfs-Brock
<[hidden email]> wrote:

>
> On Oct 1, 2013, at 12:03 AM, André Bargull wrote:
>
>> 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
>
>
> This restriction is  not specified in the rev19 draft. Currently arrow
> functions don't have an own `arguments` binding, but instead access the
> outer functions `arguments` object, similar to `this`. Disallowing the
> identifier "arguments" in PrimaryExpressions also should imply disallowing
> "arguments" as a BindingIdentifier, which shifts arrow functions again into
> "almost strict-mode".
>
> - André
>
>
> The restriction we want and how to enforce it is not all that clear.
>
> We don't really want to have an "almost strict" mode for the body of arrow
> functions, if that was going to be the case I think it would be much better
> to simply say that arrow functions are always strict.
>
> The spec. currently applies the static semantics of strict mode formal
> parameters (no duplicate names, can't name a parameter 'eval' or
> 'arguments') to arrow function formal parameters, but in all other ways both
> the formal parameter list (think default value expressions) and the arrow
> function body follow the strictness of the surrounding code.
>
> that means things like the following are valid in non-strict arrow
> functions:
>
> () =>  {function arguments() {}; return arguments}
> () => {let arguments =5; ...}
>
> So we can't just statically disallow 'arguments' references in a ConciseBodu
>
> Also, we have to have consistent behavior for an
>   eval('arguments')
> that appears in a ConciseBody.
>
> Here are possible reasonable alternatives for handling arguments in arrow
> functions:
>
> 1) nothing special, same rules as a FunctionExpression. An arguments object
> is available and strict/non-strict distinctions apply both statically and
> dynamically.
>
> 2) nothing special, but strict arguments object.  Just like #1 except it
> always has a strict mode arguments object (no joining of augments elements
> and formal parameters
>
> 3) #2, plus strict mode parameter naming restrictions are also applied (no
> duplicates, can't use 'eval' or 'arguments' as parameter names)
>
> 4) no-arguments objects with shadowing, 'arguments' binds to undefined.
> Arrow functions do not have an arguments objects but they have an implicit
> constant binding of 'arguments' in their parameter scope whose value is
> undefined.  References to 'arguments' in the body evaluate to undefined.
> (unless, non-strict and there are explicit declarations of the name
> 'arguments');
>
> 5) no-arguments objects with shadowing, 'arguments' is in temporal dead
> zone.  Arrow functions do not have an arguments objects but they have an
> implicit binding of 'arguments' in their parameter scope that is never
> marked as initialized.  References to 'arguments' in the body throw because
> they are temporal dead zone references. (unless, non-strict and there are
> explicit declarations of the name 'arguments' that shadow the parameter
> level binding);
>
> 6) nothing special, but no arguments object, normal lexical scoping. Like #1
> except that there is no arguments object or local binding of 'arguments'.
> References to arguments resolve via the enclosing scope.
>
> 7) strict mode name restrictions, but no arguments object, normal lexical
> scoping. Like #3 except that there is no arguments object or local binding
> of 'arguments'.  References to arguments resolve via the enclosing scope.
>
> The rev19 spec. current has approximately #7 but there isn't anything final
> about that.  It sounds to me like some think either #3 or #4 is the plan of
> record although I don't think we've talked about it at a TC39 meeting that
> this level of detail.
>
> I think #3 would be a good solution. So is #7.
>
> #3 probably would seem reasonable to JS programmers. #7 probably is what
> lexical scoping heads would expect. #4 or #5 is a completely new semantics
> that I don't think anyone expects.
>
> Allen
>
>
>
>
>
>
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss
>



--
erik
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Clarification on function default param values

Brendan Eich-3
In reply to this post by Andrea Giammarchi-2
Andrea Giammarchi wrote:
> Does `null` count as undefined too

No. See the draft spec and many threads and meeting notes.

/be
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Clarification on function default param values

Mark S. Miller-2
In reply to this post by Erik Arvidsson
I agree that the discussions as I remember them do not go into this level of detail. Thanks for being so explicit about precise choices.

However, I do recall that the consensus we had was enough to rule out #3, or indeed any solution where arrow functions have their own arguments object. And even if I recall wrongly, I do think arrow functions should not get their own arguments object -- that's too surprising from an arrow-function-as-smalltalk-block-like perspective. 

#7 can be explained in a memorable way: 

Generally variables are brought into scope by an explicitly appearing defining occurrence. Two exceptions are the "function" brings into scope both "this" and "arguments". These remain in scope until shadowed by a nested "function" or by an explicit definition. Note that "this" can never be explicitly defined, and "arguments" can only be explicitly defined in non-strict code.

As of ES6, a variety of other function-defining constructs, like "function", implicitly bring into scope a new "this" and "argument". Arrow-functions are not one of these. Within an arrow function, both "this" and "arguments" are lexically captured from the enclosing context.




On Tue, Oct 1, 2013 at 11:19 AM, Erik Arvidsson <[hidden email]> wrote:
3 and 7 both seems good. Personally I prefer #7 but I'm worried that
it might be too surprising that arguments refers to the outer
function.

On Tue, Oct 1, 2013 at 11:11 AM, Allen Wirfs-Brock
<[hidden email]> wrote:
>
> On Oct 1, 2013, at 12:03 AM, André Bargull wrote:
>
>> Brandon Benvie <mailto:[hidden email] 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
>
>
> This restriction is  not specified in the rev19 draft. Currently arrow
> functions don't have an own `arguments` binding, but instead access the
> outer functions `arguments` object, similar to `this`. Disallowing the
> identifier "arguments" in PrimaryExpressions also should imply disallowing
> "arguments" as a BindingIdentifier, which shifts arrow functions again into
> "almost strict-mode".
>
> - André
>
>
> The restriction we want and how to enforce it is not all that clear.
>
> We don't really want to have an "almost strict" mode for the body of arrow
> functions, if that was going to be the case I think it would be much better
> to simply say that arrow functions are always strict.
>
> The spec. currently applies the static semantics of strict mode formal
> parameters (no duplicate names, can't name a parameter 'eval' or
> 'arguments') to arrow function formal parameters, but in all other ways both
> the formal parameter list (think default value expressions) and the arrow
> function body follow the strictness of the surrounding code.
>
> that means things like the following are valid in non-strict arrow
> functions:
>
> () =>  {function arguments() {}; return arguments}
> () => {let arguments =5; ...}
>
> So we can't just statically disallow 'arguments' references in a ConciseBodu
>
> Also, we have to have consistent behavior for an
>   eval('arguments')
> that appears in a ConciseBody.
>
> Here are possible reasonable alternatives for handling arguments in arrow
> functions:
>
> 1) nothing special, same rules as a FunctionExpression. An arguments object
> is available and strict/non-strict distinctions apply both statically and
> dynamically.
>
> 2) nothing special, but strict arguments object.  Just like #1 except it
> always has a strict mode arguments object (no joining of augments elements
> and formal parameters
>
> 3) #2, plus strict mode parameter naming restrictions are also applied (no
> duplicates, can't use 'eval' or 'arguments' as parameter names)
>
> 4) no-arguments objects with shadowing, 'arguments' binds to undefined.
> Arrow functions do not have an arguments objects but they have an implicit
> constant binding of 'arguments' in their parameter scope whose value is
> undefined.  References to 'arguments' in the body evaluate to undefined.
> (unless, non-strict and there are explicit declarations of the name
> 'arguments');
>
> 5) no-arguments objects with shadowing, 'arguments' is in temporal dead
> zone.  Arrow functions do not have an arguments objects but they have an
> implicit binding of 'arguments' in their parameter scope that is never
> marked as initialized.  References to 'arguments' in the body throw because
> they are temporal dead zone references. (unless, non-strict and there are
> explicit declarations of the name 'arguments' that shadow the parameter
> level binding);
>
> 6) nothing special, but no arguments object, normal lexical scoping. Like #1
> except that there is no arguments object or local binding of 'arguments'.
> References to arguments resolve via the enclosing scope.
>
> 7) strict mode name restrictions, but no arguments object, normal lexical
> scoping. Like #3 except that there is no arguments object or local binding
> of 'arguments'.  References to arguments resolve via the enclosing scope.
>
> The rev19 spec. current has approximately #7 but there isn't anything final
> about that.  It sounds to me like some think either #3 or #4 is the plan of
> record although I don't think we've talked about it at a TC39 meeting that
> this level of detail.
>
> I think #3 would be a good solution. So is #7.
>
> #3 probably would seem reasonable to JS programmers. #7 probably is what
> lexical scoping heads would expect. #4 or #5 is a completely new semantics
> that I don't think anyone expects.
>
> Allen
>
>
>
>
>
>
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss
>



--
erik
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



--
    Cheers,
    --MarkM

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Clarification on function default param values

Andrea Giammarchi-2
I need to read everything Brendan suggested but if anyone would be so kind to refresh my memories on this arrow function I'd appreciate that. I don't need much more than yes/no as answer, thanks.

  1. `var o = {method: () => this};` will o.method() return o ? (I guess nope)

Considering the following code:

```javascript
var Proto = (function(){
  this.method = () => this;
  return this.constructor;
}.bind(function Proto() {}.prototype));
```
  2. will it work as expected per each `new Proto` object ? (I guess nope, everything referred to Proto.prototype)

Considering the following code:

```javascript
var o = {i: 0};

(function(O){

  O.fatMethod = (i) => i + this.i;
  O.justMethod = function (i) {
    return i + O.i;
  };

}.bind(o,O));
```

  3. will the `fatMethod` be ideally/theoretically/technically faster to execute once made hot through JIT capable engines (or made preventively hot since immutable in such form) ?

My bonus, humble, honest, and final question would be:

  4. what kind of problem is this fat arrow feature trying to solve exactly, if it cannot be used for classes, direct methods assignment, but only for some runtime event assignment instead of using bind and still being unable to remove that listener later on ?

Thanks a lot in advance for any refreshing and/or enlightening answer, it's actually a while I am wondering this stuff.

Best Regards






On Tue, Oct 1, 2013 at 11:59 AM, Mark S. Miller <[hidden email]> wrote:
I agree that the discussions as I remember them do not go into this level of detail. Thanks for being so explicit about precise choices.

However, I do recall that the consensus we had was enough to rule out #3, or indeed any solution where arrow functions have their own arguments object. And even if I recall wrongly, I do think arrow functions should not get their own arguments object -- that's too surprising from an arrow-function-as-smalltalk-block-like perspective. 

#7 can be explained in a memorable way: 

Generally variables are brought into scope by an explicitly appearing defining occurrence. Two exceptions are the "function" brings into scope both "this" and "arguments". These remain in scope until shadowed by a nested "function" or by an explicit definition. Note that "this" can never be explicitly defined, and "arguments" can only be explicitly defined in non-strict code.

As of ES6, a variety of other function-defining constructs, like "function", implicitly bring into scope a new "this" and "argument". Arrow-functions are not one of these. Within an arrow function, both "this" and "arguments" are lexically captured from the enclosing context.




On Tue, Oct 1, 2013 at 11:19 AM, Erik Arvidsson <[hidden email]> wrote:
3 and 7 both seems good. Personally I prefer #7 but I'm worried that
it might be too surprising that arguments refers to the outer
function.

On Tue, Oct 1, 2013 at 11:11 AM, Allen Wirfs-Brock
<[hidden email]> wrote:
>
> On Oct 1, 2013, at 12:03 AM, André Bargull wrote:
>
>> Brandon Benvie <mailto:[hidden email] 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
>
>
> This restriction is  not specified in the rev19 draft. Currently arrow
> functions don't have an own `arguments` binding, but instead access the
> outer functions `arguments` object, similar to `this`. Disallowing the
> identifier "arguments" in PrimaryExpressions also should imply disallowing
> "arguments" as a BindingIdentifier, which shifts arrow functions again into
> "almost strict-mode".
>
> - André
>
>
> The restriction we want and how to enforce it is not all that clear.
>
> We don't really want to have an "almost strict" mode for the body of arrow
> functions, if that was going to be the case I think it would be much better
> to simply say that arrow functions are always strict.
>
> The spec. currently applies the static semantics of strict mode formal
> parameters (no duplicate names, can't name a parameter 'eval' or
> 'arguments') to arrow function formal parameters, but in all other ways both
> the formal parameter list (think default value expressions) and the arrow
> function body follow the strictness of the surrounding code.
>
> that means things like the following are valid in non-strict arrow
> functions:
>
> () =>  {function arguments() {}; return arguments}
> () => {let arguments =5; ...}
>
> So we can't just statically disallow 'arguments' references in a ConciseBodu
>
> Also, we have to have consistent behavior for an
>   eval('arguments')
> that appears in a ConciseBody.
>
> Here are possible reasonable alternatives for handling arguments in arrow
> functions:
>
> 1) nothing special, same rules as a FunctionExpression. An arguments object
> is available and strict/non-strict distinctions apply both statically and
> dynamically.
>
> 2) nothing special, but strict arguments object.  Just like #1 except it
> always has a strict mode arguments object (no joining of augments elements
> and formal parameters
>
> 3) #2, plus strict mode parameter naming restrictions are also applied (no
> duplicates, can't use 'eval' or 'arguments' as parameter names)
>
> 4) no-arguments objects with shadowing, 'arguments' binds to undefined.
> Arrow functions do not have an arguments objects but they have an implicit
> constant binding of 'arguments' in their parameter scope whose value is
> undefined.  References to 'arguments' in the body evaluate to undefined.
> (unless, non-strict and there are explicit declarations of the name
> 'arguments');
>
> 5) no-arguments objects with shadowing, 'arguments' is in temporal dead
> zone.  Arrow functions do not have an arguments objects but they have an
> implicit binding of 'arguments' in their parameter scope that is never
> marked as initialized.  References to 'arguments' in the body throw because
> they are temporal dead zone references. (unless, non-strict and there are
> explicit declarations of the name 'arguments' that shadow the parameter
> level binding);
>
> 6) nothing special, but no arguments object, normal lexical scoping. Like #1
> except that there is no arguments object or local binding of 'arguments'.
> References to arguments resolve via the enclosing scope.
>
> 7) strict mode name restrictions, but no arguments object, normal lexical
> scoping. Like #3 except that there is no arguments object or local binding
> of 'arguments'.  References to arguments resolve via the enclosing scope.
>
> The rev19 spec. current has approximately #7 but there isn't anything final
> about that.  It sounds to me like some think either #3 or #4 is the plan of
> record although I don't think we've talked about it at a TC39 meeting that
> this level of detail.
>
> I think #3 would be a good solution. So is #7.
>
> #3 probably would seem reasonable to JS programmers. #7 probably is what
> lexical scoping heads would expect. #4 or #5 is a completely new semantics
> that I don't think anyone expects.
>
> Allen
>
>
>
>
>
>
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss
>



--
erik
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



--
    Cheers,
    --MarkM

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Clarification on function default param values

Dmitry Soshnikov
In reply to this post by Brandon Benvie-2



On Mon, Sep 30, 2013 at 8:21 PM, Brandon Benvie <[hidden email]> wrote:
On 9/30/2013 3:51 PM, Dmitry Soshnikov wrote:
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?

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);
}
```


OK. Thanks for the example. There are some edge cases with transpiling to ES3, e.g. if the inner function mutates the arguments.callee by attaching a new property to it, or something (the property is attached to the inner function then, not to the outer wrapper). But transpiling cases shouldn't stop the actual spec for engines of course.

Also, what about using other parameter transforms in conjunction, e.g. rest parameters and destructuring: are they duplicated in the signature of the inner function, is their coded are injected into the inner function or to the outer one?

 


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
```


Yeah, this one is debatable though. I think it's either, or. Both variants can be correct, depending on how it's speced. If it's spected that the defaults are evaluated in the function scope, then it shouldn't be a surprise that the if can be 4 (and in this case we probably don't need two scopes. Wondering, can all the edge cases be covered by the single sentence in the spec: "All default values are evaluated in the scope of a function"? Or those edge cases are too not-obvious from the programmers perspectives?).

Dmitry

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
12