Arrow methods

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

Arrow methods

Sultan
As the name suggests; An update to the grammar related to methods on objects/classes to support arrow methods:

today: {render() { return 'Hello' }}
proposed addition: {render() => 'Hello'}

This could be some-what linked to class fields in the class variant; That is what does "this" refer to when used in a class.

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

Re: Arrow methods

J Decker


On Fri, Nov 16, 2018 at 11:23 AM Sultan <[hidden email]> wrote:
As the name suggests; An update to the grammar related to methods on objects/classes to support arrow methods:

today: {render() { return 'Hello' }}
proposed addition: {render() => 'Hello'}

proposed addition: {render:() => 'Hello'}
 
This could be some-what linked to class fields in the class variant; That is what does "this" refer to when used in a class.
_______________________________________________
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: Arrow methods

Sultan
The missing colon ":" is intentional.

On Fri, Nov 16, 2018 at 10:57 PM J Decker <[hidden email]> wrote:


On Fri, Nov 16, 2018 at 11:23 AM Sultan <[hidden email]> wrote:
As the name suggests; An update to the grammar related to methods on objects/classes to support arrow methods:

today: {render() { return 'Hello' }}
proposed addition: {render() => 'Hello'}

proposed addition: {render:() => 'Hello'}
 
This could be some-what linked to class fields in the class variant; That is what does "this" refer to when used in a class.
_______________________________________________
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: Arrow methods

Isiah Meadows-2
Not sure what the benefit here is:

- You can do `foo: () => bar` for objects
- You can do `foo = () => bar` for class instances using the public fields proposal.

This leaves out self-binding, but you could always use a local variable if necessary. (It's like one extra line, maybe 3, and it's not common at all.)
On Fri, Nov 16, 2018 at 15:09 Sultan <[hidden email]> wrote:
The missing colon ":" is intentional.

On Fri, Nov 16, 2018 at 10:57 PM J Decker <[hidden email]> wrote:


On Fri, Nov 16, 2018 at 11:23 AM Sultan <[hidden email]> wrote:
As the name suggests; An update to the grammar related to methods on objects/classes to support arrow methods:

today: {render() { return 'Hello' }}
proposed addition: {render() => 'Hello'}

proposed addition: {render:() => 'Hello'}
 
This could be some-what linked to class fields in the class variant; That is what does "this" refer to when used in a class.
_______________________________________________
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: Arrow methods

Sultan
Consistency and sugar. Changing from arrow and non-arrow method is a diff between `=>` where:

foo() {} mirrors foo: function () {}
foo() => {} mirrors foo: () => {}

Also the "this" reference in the second variant is not the class instance i.e it is part of the shared prototype.

It has an added reach in usefulness when you consider nested classes:

class A {
  foo() {
    return class B {
      bar() => {
        return this // refers to instance A
      }
    }
  }
}

This is not possible today without creating a self-like variable for bar to reference A's instance; Which is one of the points arrow functions addressed.

On Fri, Nov 16, 2018 at 11:15 PM Isiah Meadows <[hidden email]> wrote:
Not sure what the benefit here is:

- You can do `foo: () => bar` for objects
- You can do `foo = () => bar` for class instances using the public fields proposal.

This leaves out self-binding, but you could always use a local variable if necessary. (It's like one extra line, maybe 3, and it's not common at all.)
On Fri, Nov 16, 2018 at 15:09 Sultan <[hidden email]> wrote:
The missing colon ":" is intentional.

On Fri, Nov 16, 2018 at 10:57 PM J Decker <[hidden email]> wrote:


On Fri, Nov 16, 2018 at 11:23 AM Sultan <[hidden email]> wrote:
As the name suggests; An update to the grammar related to methods on objects/classes to support arrow methods:

today: {render() { return 'Hello' }}
proposed addition: {render() => 'Hello'}

proposed addition: {render:() => 'Hello'}
 
This could be some-what linked to class fields in the class variant; That is what does "this" refer to when used in a class.
_______________________________________________
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: Arrow methods

Tab Atkins Jr.
On Fri, Nov 16, 2018 at 12:42 PM Sultan <[hidden email]> wrote:
>
> Consistency and sugar. Changing from arrow and non-arrow method is a diff between `=>` where:
>
> foo() {} mirrors foo: function () {}
> foo() => {} mirrors foo: () => {}

Yes, but note that the first one *actually contains sugar* - it lets
you omit a decent chunk of characters (at bare minimum, nine) and puts
the name next to the arg-list again, like how normal functions look.

The second lets you omit exactly one character. It also makes it look
*more* like a named function declaration, while arrow functions are
always name-less, so it's not helping you return to a "normal" form
either.

> Also the "this" reference in the second variant is not the class instance i.e it is part of the shared prototype.
>
> It has an added reach in usefulness when you consider nested classes:
>
> class A {
>   foo() {
>     return class B {
>       bar() => {
>         return this // refers to instance A
>       }
>     }
>   }
> }
>
> This is not possible today without creating a self-like variable for bar to reference A's instance; Which is one of the points arrow functions addressed.

Instance methods that don't refer to the instance are definitely the
exception, not the rule. Reading this code, I would *absolutely*
expect on first and probably second glances for `this` to be referring
to the B instance, not the A instance. Binding A's `this` to a
different name is actually a readability *aid* in this circumstance,
unlike the many cases that arrow functions were designed to replace.

This looks to me like a decent argument *against* the suggestion. :/

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

Re: Arrow methods

T.J. Crowder-2
On Fri, Nov 16, 2018 at 9:52 PM Tab Atkins Jr.
<[hidden email]> wrote:
> ...while arrow functions are always name-less...

Minor nit-pick: Arrow functions are often named:

```js
const foo = () => {
    console.log(foo.name);
    throw new Error();
};
foo();
```

Running that, you'll see something like this in the console:

```text
foo
Uncaught Error
    at foo ((index):35)
    at (index):3
```

(Edge doesn't show the stack trace in the console, but if you step into `foo`, it shows the proper name in the call stack.)

Search for SetFunctionName in the spec to find all the various places anonymous function expressions (both traditional and arrow) assign names to functions as of ES2015. (Basically: Anywhere the expression result is assigned to a variable, constant, or default parameter value; or when it's assigned to a property in an object initializer [but *not* when assigned to a property on an existing object].)

</nit-pick> ;-)

-- T.J. Crowder

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

Re: Arrow methods

T.J. Crowder-2
In reply to this post by Sultan
On Fri, Nov 16, 2018 at 8:42 PM Sultan
<[hidden email]> wrote:

> It has an added reach in usefulness when you consider nested
> classes:
>
>     class A {
>       foo() {
>         return class B {
>           bar() => {
>             return this // refers to instance A
>           }
>         }
>       }
>     }
>
> This is not possible today without creating a self-like variable
> for bar to reference A's instance; Which is one of the points
> arrow functions addressed.

It is, just not within the `class` construct:

```js
class A {
  foo() {
    class B {
    }
    B.prototype.bar = () => {
      return this; // refers to instance A
    };
    return B;
  }
}
```

I agree with Tab Atkins Jr.: In your nested classes example, I'd expect `this` within `bar` to be the `B` instance, not the `A` instance. I think the more natural definition of that syntax (if it were adopted) would be a prototype function that is effectively auto-bound to the instance at construction time, like this common pattern today:

```js
class B {
  constructor() {
    this.bar = this.bar.bind(this);
  }
  bar() {
    return this;
  }
}
```

In fact I could see some benefit to that syntax, since people use class fields for that use-case which can make mocking difficult.

But I'm not keen on that syntax with the semantics you're proposing.

-- T.J. Crowder

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

RE: Arrow methods

Ron Buckton

C# has a similar syntax for shorthand expression bodies (https://github.com/dotnet/roslyn/wiki/New-Language-Features-in-C%23-6#expression-bodies-on-method-like-members):

 

```cs

class Point {

  private int x;

  private int y;

 

  …

 

  // expression bodied getters (read-only)

  public int X => x;

  public int Y => y;

 

  // expression bodied method

  public Point Move(int dx, int dy) => new Point(x + dx, y + dy);

}

```

 

From: es-discuss <[hidden email]> On Behalf Of T.J. Crowder
Sent: Sunday, November 18, 2018 6:31 AM
To: Sultan <[hidden email]>
Cc: [hidden email]
Subject: Re: Arrow methods

 

On Fri, Nov 16, 2018 at 8:42 PM Sultan
<[hidden email]> wrote:
> It has an added reach in usefulness when you consider nested
> classes:
>
>     class A {
>       foo() {
>         return class B {
>           bar() => {
>             return this // refers to instance A
>           }
>         }
>       }
>     }
>
> This is not possible today without creating a self-like variable
> for bar to reference A's instance; Which is one of the points
> arrow functions addressed.

It is, just not within the `class` construct:

```js
class A {
  foo() {
    class B {
    }
    B.prototype.bar = () => {
      return this; // refers to instance A
    };
    return B;
  }
}
```

I agree with Tab Atkins Jr.: In your nested classes example, I'd expect `this` within `bar` to be the `B` instance, not the `A` instance. I think the more natural definition of that syntax (if it were adopted) would be a prototype function that is effectively auto-bound to the instance at construction time, like this common pattern today:

```js
class B {
  constructor() {
    this.bar = this.bar.bind(this);
  }
  bar() {
    return this;
  }
}
```

In fact I could see some benefit to that syntax, since people use class fields for that use-case which can make mocking difficult.

But I'm not keen on that syntax with the semantics you're proposing.

-- T.J. Crowder


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

Re: Arrow methods

Andrea Giammarchi-2
In reply to this post by T.J. Crowder-2
Once upon a time we've discussed the "thin arrow" so that `{method: () -> this.name, name: 'any'}` would've worked as expected.

At that time it was considered "an arrow too far".

Regards

On Sun, Nov 18, 2018 at 3:30 PM T.J. Crowder <[hidden email]> wrote:
On Fri, Nov 16, 2018 at 8:42 PM Sultan
<[hidden email]> wrote:

> It has an added reach in usefulness when you consider nested
> classes:
>
>     class A {
>       foo() {
>         return class B {
>           bar() => {
>             return this // refers to instance A
>           }
>         }
>       }
>     }
>
> This is not possible today without creating a self-like variable
> for bar to reference A's instance; Which is one of the points
> arrow functions addressed.

It is, just not within the `class` construct:

```js
class A {
  foo() {
    class B {
    }
    B.prototype.bar = () => {
      return this; // refers to instance A
    };
    return B;
  }
}
```

I agree with Tab Atkins Jr.: In your nested classes example, I'd expect `this` within `bar` to be the `B` instance, not the `A` instance. I think the more natural definition of that syntax (if it were adopted) would be a prototype function that is effectively auto-bound to the instance at construction time, like this common pattern today:

```js
class B {
  constructor() {
    this.bar = this.bar.bind(this);
  }
  bar() {
    return this;
  }
}
```

In fact I could see some benefit to that syntax, since people use class fields for that use-case which can make mocking difficult.

But I'm not keen on that syntax with the semantics you're proposing.

-- T.J. Crowder
_______________________________________________
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