Using 'this' in default parameters

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

Using 'this' in default parameters

` Mystery .
Hi all,

During the development of an ES6 web application, I came across a situation where I wanted to bind 'this' of the outer function to a parameter of an inner function, here is a quick snippet demonstrated what I'm trying to do:

function outer() {
  function inner(_this = this) {
    console.log(_this.a);
  }
  inner.call({});
}
outer.call({a: 1});

In the latest Firefox, the above script prints 'undefined'. This seems pretty counter-intuitive, and it also fails when I try to pass 'this.a' as default value for the parameter of the inner function. I wonder if this is an intended behavior? Thanks in advance.

Yours,
Charles Weng

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

Re: Using 'this' in default parameters

Bergi
` Mystery . wrote:
> During the development of an ES6 web application, I came across a situation
> where I wanted to bind 'this' of the outer function to a parameter of an
> inner function

Use an arrow function for that:
```
function outer() {
     const inner = (_this = this) => {
         console.log(_this.a); // 1
     }
     inner.call({});
}
outer.call({a: 1});

> In the latest Firefox, the above script prints 'undefined'. This seems
> pretty counter-intuitive, and it also fails when I try to pass 'this.a' as
> default value for the parameter of the inner function. I wonder if this is
> an intended behavior? Thanks in advance.

Yes, it is intended, and pretty intuitive - default initialisers are
evaluated in the scope of the called function, at the call - they're not
values that are computed at the time of the definition of the function.

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

Re: Using 'this' in default parameters

` Mystery .
Hi,

Thanks for the replies. I'm aware of the arrow functions, but the reason I don't use them here is that I wish to bind a custom context to the inner function (i.e. preserve the "this" passed while calling the inner function, like a custom context for promise callbacks for example) and use some variables in the outer function's context as well (might be a class method). Guess I should fallback to old "saving this to a variable" technique in this situation.

IMHO I don't think the default parameters should be evaluated within the context of the function being called, at least not while it's outside of function body's region...... Is there a specific reason to do that, or it's just a design preference?

Yours,
Charles Weng

On Fri, Jan 29, 2016 at 9:27 PM Bergi <[hidden email]> wrote:
` Mystery . wrote:
> During the development of an ES6 web application, I came across a situation
> where I wanted to bind 'this' of the outer function to a parameter of an
> inner function

Use an arrow function for that:
```
function outer() {
     const inner = (_this = this) => {
         console.log(_this.a); // 1
     }
     inner.call({});
}
outer.call({a: 1});

> In the latest Firefox, the above script prints 'undefined'. This seems
> pretty counter-intuitive, and it also fails when I try to pass 'this.a' as
> default value for the parameter of the inner function. I wonder if this is
> an intended behavior? Thanks in advance.

Yes, it is intended, and pretty intuitive - default initialisers are
evaluated in the scope of the called function, at the call - they're not
values that are computed at the time of the definition of the function.

Regards,
  Bergi
_______________________________________________
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: Using 'this' in default parameters

Andrea Giammarchi-2
Hi Charles, I think this discussion is not really appropriate for this ML but I'd like to point out you have already all possible solutions.

For instance, you don't need to bond at all for your case since you use `.call` already. Please be sure you understand what `.call` does because it's kinda pointless to use both `.call` and `.bind` or bound variables.

Example:

```js
function outer() {
  function inner() {
    console.log(this.a);
  }
  inner.call({});
}
outer.call({a: 1});
```

If you need to bring in the default `this` arrow function does exactly that and it will be pointless to `.call` an arrow function with a different context.

```js
function outer() {
  const inner = () => {
    console.log(this.a);
  };
  inner.call({}); // or just inner();
}
outer.call({a: 1});
```

If you'd like to create an inner function with a different context you can use `.bind` which has been in core for quite a while and its purpose is exactly that one.

```js
function outer() {
  const inner = function () {
    console.log(this.a);
  }.bind({});
  inner();
}
outer.call({a: 1});
```

As you can see the last thing we need is yet another way to bind something in the language ... but of course, if you really want to use the `var self = this` pattern you are free to do that, no need to change specifications though.

Eventually, what you might want is a hsortcut for function like `->` instead of `=>` could be ... but that's a whole different story.

Best Regards



On Fri, Jan 29, 2016 at 3:14 PM, ` Mystery . <[hidden email]> wrote:
Hi,

Thanks for the replies. I'm aware of the arrow functions, but the reason I don't use them here is that I wish to bind a custom context to the inner function (i.e. preserve the "this" passed while calling the inner function, like a custom context for promise callbacks for example) and use some variables in the outer function's context as well (might be a class method). Guess I should fallback to old "saving this to a variable" technique in this situation.

IMHO I don't think the default parameters should be evaluated within the context of the function being called, at least not while it's outside of function body's region...... Is there a specific reason to do that, or it's just a design preference?

Yours,
Charles Weng

On Fri, Jan 29, 2016 at 9:27 PM Bergi <[hidden email]> wrote:
` Mystery . wrote:
> During the development of an ES6 web application, I came across a situation
> where I wanted to bind 'this' of the outer function to a parameter of an
> inner function

Use an arrow function for that:
```
function outer() {
     const inner = (_this = this) => {
         console.log(_this.a); // 1
     }
     inner.call({});
}
outer.call({a: 1});

> In the latest Firefox, the above script prints 'undefined'. This seems
> pretty counter-intuitive, and it also fails when I try to pass 'this.a' as
> default value for the parameter of the inner function. I wonder if this is
> an intended behavior? Thanks in advance.

Yes, it is intended, and pretty intuitive - default initialisers are
evaluated in the scope of the called function, at the call - they're not
values that are computed at the time of the definition of the function.

Regards,
  Bergi
_______________________________________________
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



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

Re: Using 'this' in default parameters

Jason Orendorff
In reply to this post by ` Mystery .
On Fri, Jan 29, 2016 at 8:14 AM, ` Mystery . <[hidden email]> wrote:
> IMHO I don't think the default parameters should be evaluated within the
> context of the function being called, at least not while it's outside of
> function body's region...... Is there a specific reason to do that, or it's
> just a design preference?

Sure, there is a reason: it's about how defaults are used.

Most defaults are probably constants or empty objects. Those don't
need to refer to any variables at all, so we can set them aside.

Of the rest, I suspect *most* refer to previous parameters:

    function send(sender, recip, message, onBehalfOf=sender) { ... }

or the `this` for the current method call:

    class MyArray {
        ...
        slice(start=0, stop=this.length) { ... }
    }

The only way to support these is to put the arguments in scope.

(Another reason is consistency. This is how `var` initializers already
work, and have always worked: initializers are in the scope of the
bindings being initialized, and can use the values of previously
initialized bindings on the same line of code.)

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

Re: Using 'this' in default parameters

` Mystery .

Hi,

@Andrea Giammarchi
Sorry, perhaps I didn't express myself clearly. I use .call() to manually bind the context "this" to a function, and yes, the last one is exactly what I need, accessing both contexts (inner and outer) which I couldn't manage without using an additional variable, as described in the following snippet:

```js
function outer() {
  const inner = function (_this = this) {
    console.log(this.b, _this.a);
  };
  inner.call({b: 1});
}
outer.call({a: 2});
```

@Jason Orendorff
I see. If JavaScript is going to support calling class functions with class members as default parameters, it has to parse the default values with the given "this" context at calling. Perhaps that's also the reason why the most language does not support this feature, like C++ and Python..... but it's JavaScript :)

Thanks guys for the patient explanation.

Yours,
Charles Weng

On Fri, Jan 29, 2016 at 10:41 PM Jason Orendorff <[hidden email]> wrote:
On Fri, Jan 29, 2016 at 8:14 AM, ` Mystery . <[hidden email]> wrote:
> IMHO I don't think the default parameters should be evaluated within the
> context of the function being called, at least not while it's outside of
> function body's region...... Is there a specific reason to do that, or it's
> just a design preference?

Sure, there is a reason: it's about how defaults are used.

Most defaults are probably constants or empty objects. Those don't
need to refer to any variables at all, so we can set them aside.

Of the rest, I suspect *most* refer to previous parameters:

    function send(sender, recip, message, onBehalfOf=sender) { ... }

or the `this` for the current method call:

    class MyArray {
        ...
        slice(start=0, stop=this.length) { ... }
    }

The only way to support these is to put the arguments in scope.

(Another reason is consistency. This is how `var` initializers already
work, and have always worked: initializers are in the scope of the
bindings being initialized, and can use the values of previously
initialized bindings on the same line of code.)

-j

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

Re: Using 'this' in default parameters

Andrea Giammarchi-2
Sorry Charles, I'm not sure I understand. Would this work?

```js
function outer() {
  const inner = (_this) => {
    console.log(this.b, _this.a);
  };
  inner({b: 1});
}
outer.call({a: 2});
```

that should produce what you expect already, right? I think it's misleading to use `.call` with a bound/arrow function, as it's misleading to have two different `this` in params or body.

Just my pov


On Fri, Jan 29, 2016 at 4:37 PM, ` Mystery . <[hidden email]> wrote:

Hi,

@Andrea Giammarchi
Sorry, perhaps I didn't express myself clearly. I use .call() to manually bind the context "this" to a function, and yes, the last one is exactly what I need, accessing both contexts (inner and outer) which I couldn't manage without using an additional variable, as described in the following snippet:

```js
function outer() {
  const inner = function (_this = this) {
    console.log(this.b, _this.a);
  };
  inner.call({b: 1});
}
outer.call({a: 2});
```

@Jason Orendorff
I see. If JavaScript is going to support calling class functions with class members as default parameters, it has to parse the default values with the given "this" context at calling. Perhaps that's also the reason why the most language does not support this feature, like C++ and Python..... but it's JavaScript :)

Thanks guys for the patient explanation.

Yours,
Charles Weng

On Fri, Jan 29, 2016 at 10:41 PM Jason Orendorff <[hidden email]> wrote:
On Fri, Jan 29, 2016 at 8:14 AM, ` Mystery . <[hidden email]> wrote:
> IMHO I don't think the default parameters should be evaluated within the
> context of the function being called, at least not while it's outside of
> function body's region...... Is there a specific reason to do that, or it's
> just a design preference?

Sure, there is a reason: it's about how defaults are used.

Most defaults are probably constants or empty objects. Those don't
need to refer to any variables at all, so we can set them aside.

Of the rest, I suspect *most* refer to previous parameters:

    function send(sender, recip, message, onBehalfOf=sender) { ... }

or the `this` for the current method call:

    class MyArray {
        ...
        slice(start=0, stop=this.length) { ... }
    }

The only way to support these is to put the arguments in scope.

(Another reason is consistency. This is how `var` initializers already
work, and have always worked: initializers are in the scope of the
bindings being initialized, and can use the values of previously
initialized bindings on the same line of code.)

-j


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

Re: Using 'this' in default parameters

` Mystery .
Yes, the example you show is sufficient for most scenarios.
However the situation I came across is more complex: The custom Promise class I implemented uses .call() to bind the same "this" scope object across different .then() tasks, so they can exchange variables just simply by storing them in "this". Of course it will work if I just pass that environment object as a parameter, but it would require a lot of work to modify other callbacks that does not use "this" of the outer function. Perhaps I should stick to storing a "self" variable instead of introducing so many changes. ;)

Andrea Giammarchi <[hidden email]>于2016年1月30日周六 00:07写道:
Sorry Charles, I'm not sure I understand. Would this work?

```js
function outer() {
  const inner = (_this) => {
    console.log(this.b, _this.a);
  };
  inner({b: 1});
}
outer.call({a: 2});
```

that should produce what you expect already, right? I think it's misleading to use `.call` with a bound/arrow function, as it's misleading to have two different `this` in params or body.

Just my pov


On Fri, Jan 29, 2016 at 4:37 PM, ` Mystery . <[hidden email]> wrote:

Hi,

@Andrea Giammarchi
Sorry, perhaps I didn't express myself clearly. I use .call() to manually bind the context "this" to a function, and yes, the last one is exactly what I need, accessing both contexts (inner and outer) which I couldn't manage without using an additional variable, as described in the following snippet:

```js
function outer() {
  const inner = function (_this = this) {
    console.log(this.b, _this.a);
  };
  inner.call({b: 1});
}
outer.call({a: 2});
```

@Jason Orendorff
I see. If JavaScript is going to support calling class functions with class members as default parameters, it has to parse the default values with the given "this" context at calling. Perhaps that's also the reason why the most language does not support this feature, like C++ and Python..... but it's JavaScript :)

Thanks guys for the patient explanation.

Yours,
Charles Weng

On Fri, Jan 29, 2016 at 10:41 PM Jason Orendorff <[hidden email]> wrote:
On Fri, Jan 29, 2016 at 8:14 AM, ` Mystery . <[hidden email]> wrote:
> IMHO I don't think the default parameters should be evaluated within the
> context of the function being called, at least not while it's outside of
> function body's region...... Is there a specific reason to do that, or it's
> just a design preference?

Sure, there is a reason: it's about how defaults are used.

Most defaults are probably constants or empty objects. Those don't
need to refer to any variables at all, so we can set them aside.

Of the rest, I suspect *most* refer to previous parameters:

    function send(sender, recip, message, onBehalfOf=sender) { ... }

or the `this` for the current method call:

    class MyArray {
        ...
        slice(start=0, stop=this.length) { ... }
    }

The only way to support these is to put the arguments in scope.

(Another reason is consistency. This is how `var` initializers already
work, and have always worked: initializers are in the scope of the
bindings being initialized, and can use the values of previously
initialized bindings on the same line of code.)

-j


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

Re: Using 'this' in default parameters

Andrea Giammarchi-2
Agreed there should be no changes in specs.

However, you can solve with both utilities, one overwriting `call` (yak)

```js
const boundCall = (f) => {f.call=(...a)=>f.apply(null,a);return f};

function outer() {
  const inner = boundCall((_this) => {
    console.log(this.a, _this.b);
  });
  inner.call({b: 1});
}
outer.call({a: 2});
```

and one creating Python like callbacks that will receive the `self` as first argument.

```js
const snake = (f) => function snake(...a) {
  return f.apply(this, [this].concat(a));
};

const outer = snake((outerSelf) => {
  const inner = snake((innerSelf) => {
    console.log(outerSelf.a, innerSelf.b);
  });
  inner.call({b: 1});
});
outer.call({a: 2});
```

As you can see there are plenty of different tricks you can use to make your custom Promise do whatever you but if you want a hint do not ever call a method `call` or `apply` ... it's the most misleading name you could think of, no matter what's the purpose, IMHO

Regards








On Fri, Jan 29, 2016 at 5:31 PM, ` Mystery . <[hidden email]> wrote:
Yes, the example you show is sufficient for most scenarios.
However the situation I came across is more complex: The custom Promise class I implemented uses .call() to bind the same "this" scope object across different .then() tasks, so they can exchange variables just simply by storing them in "this". Of course it will work if I just pass that environment object as a parameter, but it would require a lot of work to modify other callbacks that does not use "this" of the outer function. Perhaps I should stick to storing a "self" variable instead of introducing so many changes. ;)

Andrea Giammarchi <[hidden email]>于2016年1月30日周六 00:07写道:
Sorry Charles, I'm not sure I understand. Would this work?

```js
function outer() {
  const inner = (_this) => {
    console.log(this.b, _this.a);
  };
  inner({b: 1});
}
outer.call({a: 2});
```

that should produce what you expect already, right? I think it's misleading to use `.call` with a bound/arrow function, as it's misleading to have two different `this` in params or body.

Just my pov


On Fri, Jan 29, 2016 at 4:37 PM, ` Mystery . <[hidden email]> wrote:

Hi,

@Andrea Giammarchi
Sorry, perhaps I didn't express myself clearly. I use .call() to manually bind the context "this" to a function, and yes, the last one is exactly what I need, accessing both contexts (inner and outer) which I couldn't manage without using an additional variable, as described in the following snippet:

```js
function outer() {
  const inner = function (_this = this) {
    console.log(this.b, _this.a);
  };
  inner.call({b: 1});
}
outer.call({a: 2});
```

@Jason Orendorff
I see. If JavaScript is going to support calling class functions with class members as default parameters, it has to parse the default values with the given "this" context at calling. Perhaps that's also the reason why the most language does not support this feature, like C++ and Python..... but it's JavaScript :)

Thanks guys for the patient explanation.

Yours,
Charles Weng

On Fri, Jan 29, 2016 at 10:41 PM Jason Orendorff <[hidden email]> wrote:
On Fri, Jan 29, 2016 at 8:14 AM, ` Mystery . <[hidden email]> wrote:
> IMHO I don't think the default parameters should be evaluated within the
> context of the function being called, at least not while it's outside of
> function body's region...... Is there a specific reason to do that, or it's
> just a design preference?

Sure, there is a reason: it's about how defaults are used.

Most defaults are probably constants or empty objects. Those don't
need to refer to any variables at all, so we can set them aside.

Of the rest, I suspect *most* refer to previous parameters:

    function send(sender, recip, message, onBehalfOf=sender) { ... }

or the `this` for the current method call:

    class MyArray {
        ...
        slice(start=0, stop=this.length) { ... }
    }

The only way to support these is to put the arguments in scope.

(Another reason is consistency. This is how `var` initializers already
work, and have always worked: initializers are in the scope of the
bindings being initialized, and can use the values of previously
initialized bindings on the same line of code.)

-j



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

Re: Using 'this' in default parameters

` Mystery .

Worth mentioning that D3.js, a popular visualization and SVG manipulating library that I'm using heavily in my project, uses .call() to bind DOM elements and invoke callbacks. Difficult to change that behavior without overriding built-in function as you said, although I'm expecting something cooler like: function (self = this) {}...... But never mind, thanks~

Yours,
Charles Weng


Andrea Giammarchi <[hidden email]>于2016年1月30日周六 00:56写道:
Agreed there should be no changes in specs.

However, you can solve with both utilities, one overwriting `call` (yak)

```js
const boundCall = (f) => {f.call=(...a)=>f.apply(null,a);return f};

function outer() {
  const inner = boundCall((_this) => {
    console.log(this.a, _this.b);
  });
  inner.call({b: 1});
}
outer.call({a: 2});
```

and one creating Python like callbacks that will receive the `self` as first argument.

```js
const snake = (f) => function snake(...a) {
  return f.apply(this, [this].concat(a));
};

const outer = snake((outerSelf) => {
  const inner = snake((innerSelf) => {
    console.log(outerSelf.a, innerSelf.b);
  });
  inner.call({b: 1});
});
outer.call({a: 2});
```

As you can see there are plenty of different tricks you can use to make your custom Promise do whatever you but if you want a hint do not ever call a method `call` or `apply` ... it's the most misleading name you could think of, no matter what's the purpose, IMHO

Regards








On Fri, Jan 29, 2016 at 5:31 PM, ` Mystery . <[hidden email]> wrote:
Yes, the example you show is sufficient for most scenarios.
However the situation I came across is more complex: The custom Promise class I implemented uses .call() to bind the same "this" scope object across different .then() tasks, so they can exchange variables just simply by storing them in "this". Of course it will work if I just pass that environment object as a parameter, but it would require a lot of work to modify other callbacks that does not use "this" of the outer function. Perhaps I should stick to storing a "self" variable instead of introducing so many changes. ;)

Andrea Giammarchi <[hidden email]>于2016年1月30日周六 00:07写道:
Sorry Charles, I'm not sure I understand. Would this work?

```js
function outer() {
  const inner = (_this) => {
    console.log(this.b, _this.a);
  };
  inner({b: 1});
}
outer.call({a: 2});
```

that should produce what you expect already, right? I think it's misleading to use `.call` with a bound/arrow function, as it's misleading to have two different `this` in params or body.

Just my pov


On Fri, Jan 29, 2016 at 4:37 PM, ` Mystery . <[hidden email]> wrote:

Hi,

@Andrea Giammarchi
Sorry, perhaps I didn't express myself clearly. I use .call() to manually bind the context "this" to a function, and yes, the last one is exactly what I need, accessing both contexts (inner and outer) which I couldn't manage without using an additional variable, as described in the following snippet:

```js
function outer() {
  const inner = function (_this = this) {
    console.log(this.b, _this.a);
  };
  inner.call({b: 1});
}
outer.call({a: 2});
```

@Jason Orendorff
I see. If JavaScript is going to support calling class functions with class members as default parameters, it has to parse the default values with the given "this" context at calling. Perhaps that's also the reason why the most language does not support this feature, like C++ and Python..... but it's JavaScript :)

Thanks guys for the patient explanation.

Yours,
Charles Weng

On Fri, Jan 29, 2016 at 10:41 PM Jason Orendorff <[hidden email]> wrote:
On Fri, Jan 29, 2016 at 8:14 AM, ` Mystery . <[hidden email]> wrote:
> IMHO I don't think the default parameters should be evaluated within the
> context of the function being called, at least not while it's outside of
> function body's region...... Is there a specific reason to do that, or it's
> just a design preference?

Sure, there is a reason: it's about how defaults are used.

Most defaults are probably constants or empty objects. Those don't
need to refer to any variables at all, so we can set them aside.

Of the rest, I suspect *most* refer to previous parameters:

    function send(sender, recip, message, onBehalfOf=sender) { ... }

or the `this` for the current method call:

    class MyArray {
        ...
        slice(start=0, stop=this.length) { ... }
    }

The only way to support these is to put the arguments in scope.

(Another reason is consistency. This is how `var` initializers already
work, and have always worked: initializers are in the scope of the
bindings being initialized, and can use the values of previously
initialized bindings on the same line of code.)

-j



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

Re: Using 'this' in default parameters

Bergi
In reply to this post by Jason Orendorff
Jason Orendorff wrote:

> On Fri, Jan 29, 2016 at 8:14 AM, ` Mystery . <[hidden email]> wrote:
>> IMHO I don't think the default parameters should be evaluated within the
>> context of the function being called, at least not while it's outside of
>> function body's region...... Is there a specific reason to do that, or it's
>> just a design preference?
>
> Sure, there is a reason: it's about how defaults are used.
>
> Most defaults are probably constants or empty objects. Those don't
> need to refer to any variables at all, so we can set them aside.

Well, primitive-valued constants are fine. But if you have an empty
object constant, which is statically attached to the function instance
instead of being re-evaluated at every call, that would surely cause
enough havoc already :-)

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

Paren-free heads strawman

kdex
In reply to this post by ` Mystery .
I've noticed that there's a strawman that has been left untouched for quite a while, namely [strawman:paren_free](http://wiki.ecmascript.org/doku.php?id=strawman:paren_free).

It intends to make parentheses in heads optional, making, for instance:
```js
if x > 3 {
    /* … */
}
```
equivalent to:
```js
if (x > 3) {
    /* … */
}
```
Does anyone know if there are still any efforts to bring this into a future version of EcmaScript?

The strawman hasn't been updated for five years, and I have the feeling that this addition was forgotten about.
The last time I've heard anyone from TC39 talk about paren-free heads was at [GOTO Aarhus 2013](https://www.youtube.com/watch?v=Nlqv6NtBXcA).

Note that the strawman also talks about backward compatibility:
> For backward compatibility, we support parenthesized heads with any sub-statement. To preserve the LR(1) grammar this requires factoring out OtherStatement.
>
> Thus, this proposal is intended to make no backward-incompatible syntactic or semantic changes to ES5. “Paren-free” is now > purely a relaxation of syntax rules.

If anyone seeks to try this out, Mozilla's [Narcissus](https://github.com/mozilla/narcissus/) has been supporting it for years now. You can enable it via `--paren-free`.
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Paren-free heads strawman

Bob Myers
I love the paren-free head idea. But as an obsessive user of non-braced single-statement if/for/while bodies, I don't see the advantage of making the head paren-free at the cost of mandating braces for the body.

Has either of the following been considered:

```js
if i < 3: foo();
if i < 3 do foo();
```

--
Bob

On Mon, Feb 1, 2016 at 4:43 PM, kdex <[hidden email]> wrote:
I've noticed that there's a strawman that has been left untouched for quite a while, namely [strawman:paren_free](http://wiki.ecmascript.org/doku.php?id=strawman:paren_free).

It intends to make parentheses in heads optional, making, for instance:
```js
if x > 3 {
    /* … */
}
```

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

Re: Using 'this' in default parameters

Tab Atkins Jr.
In reply to this post by Bergi
On Sun, Jan 31, 2016 at 3:59 PM, Bergi <[hidden email]> wrote:

> Jason Orendorff wrote:
>> On Fri, Jan 29, 2016 at 8:14 AM, ` Mystery . <[hidden email]> wrote:
>>> IMHO I don't think the default parameters should be evaluated within the
>>> context of the function being called, at least not while it's outside of
>>> function body's region...... Is there a specific reason to do that, or
>>> it's
>>> just a design preference?
>>
>> Sure, there is a reason: it's about how defaults are used.
>>
>> Most defaults are probably constants or empty objects. Those don't
>> need to refer to any variables at all, so we can set them aside.
>
> Well, primitive-valued constants are fine. But if you have an empty object
> constant, which is statically attached to the function instance instead of
> being re-evaluated at every call, that would surely cause enough havoc
> already :-)

I was about to send almost this exact reply. ^_^  This is actually
*very* important, and can't be set aside - Python got it wrong, which
is why if you want an argument to default to an empty list, for
example, you have to do:

def foo(bar=None):
  # or any sentinel value, but None is almost always usable
  if bar is None:
    bar = []
  ...

Otherwise you get a single array created at function definition time
and shared by all calls that default that parameter. ^_^  JS made the
right ergonomic decision for this, but of course some use-cases are
negatively affected in the trade-off, but none of them are made
impossible, or even difficult, as several people in this thread have
shown.

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