operator overloading proposal

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

operator overloading proposal

Kevin Barabash
Hi everyone,

I've been working on implementing operator overloading and would like to submit a proposal.

I think operator overloading would be a useful addition to the language.  In particular I think it would be useful for defining operations on common mathematical object types such as complex numbers, vectors, matrices, and sets.

I've create a working prototype that consists of:
  • babel plugin that rewrites operators as function calls
  • a polyfill which defines these functions and which call the correct argument-specific function based on the arguments' prototypes
  • Function.defineOperator which can be used to define which function an operator should use for the specified types
  • "use overloading" directive which allows users to opt-in

The design was inspired by some of the slides from http://www.slideshare.net/BrendanEich/js-resp.

– Kevin



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

Re: operator overloading proposal

Kevin Barabash
I forgot to mention in my last email that I'm looking for a champion for this proposal.

On Sat, May 7, 2016 at 5:24 PM, Kevin Barabash <[hidden email]> wrote:
Hi everyone,

I've been working on implementing operator overloading and would like to submit a proposal.

I think operator overloading would be a useful addition to the language.  In particular I think it would be useful for defining operations on common mathematical object types such as complex numbers, vectors, matrices, and sets.

I've create a working prototype that consists of:
  • babel plugin that rewrites operators as function calls
  • a polyfill which defines these functions and which call the correct argument-specific function based on the arguments' prototypes
  • Function.defineOperator which can be used to define which function an operator should use for the specified types
  • "use overloading" directive which allows users to opt-in

The design was inspired by some of the slides from http://www.slideshare.net/BrendanEich/js-resp.

– Kevin




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

Re: operator overloading proposal

G. Kay Lee
I'd say it's way too early to ask for a champion on this because just a quick skimming revealed a lot of places that didn't add up. For example, the proposal suggested that overloading is primarily targeted at making it easier to work with user-defined classes, but curiously a `Function.defineOperator()` method is proposed instead of some syntax that feels more tightly integrated with the class definition syntax.

```
class Point {
    constructor(x, y) {
        Object.assign(this, { x, y });
    }

    toString() {
        return `(${this.x}, ${this.y})`;
    }
}

Function.defineOperator('+', [Point, Point], (a, b) => new Point(a.x + b.x, a.y + b.y));
```

The demo code made this flaw evident - it looks like a giant step backward to define an instance method like this, don't you agree?

It's also apparent that the `@operator decorator` part of the proposal is an effort trying to address this issue, but it really is not the responsibility of the standard to try to define such a thing.

What I'd suggest is that perhaps you should rethink your proposed syntax and redesign it to become an extension of the ES6 class definition syntax.

Another thing is that, IMHO, currently there are too much quirks/conventions in the proposal that feel non-evident and non-flexible which is destined to trip people over from time to time. It would be great to make a proposal that's simple and don't include too much assumptions.

Finally, I'm not sure about the current status of macros, but last I heard of it, they say it's going to make its way into the standard pretty soon (TM), and macros can do much of the things overloading could, and much more.

On Sun, May 8, 2016 at 8:51 AM, Kevin Barabash <[hidden email]> wrote:
I forgot to mention in my last email that I'm looking for a champion for this proposal.

On Sat, May 7, 2016 at 5:24 PM, Kevin Barabash <[hidden email]> wrote:
Hi everyone,

I've been working on implementing operator overloading and would like to submit a proposal.

I think operator overloading would be a useful addition to the language.  In particular I think it would be useful for defining operations on common mathematical object types such as complex numbers, vectors, matrices, and sets.

I've create a working prototype that consists of:
  • babel plugin that rewrites operators as function calls
  • a polyfill which defines these functions and which call the correct argument-specific function based on the arguments' prototypes
  • Function.defineOperator which can be used to define which function an operator should use for the specified types
  • "use overloading" directive which allows users to opt-in

The design was inspired by some of the slides from http://www.slideshare.net/BrendanEich/js-resp.

– Kevin




_______________________________________________
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: operator overloading proposal

Kevin Barabash
I should update the demo code to show the `@operator` decorator in addition to `Function.defineOperator`.

Initially I started out with just the `@operator` decorator, but that meant that each class would have to have knowledge of each of the classes it might want to interact with before hand.  Having a separate `defineOperator` function avoids this situation.

It means that prototype style classes must be converted to the new class syntax before operator overloading could be used.  Lastly, there may be some cases where it makes sense to overload operators with existing 3rd party code or built-in classes, e.g. adding set operations to Set using operator overloading.

It's also apparent that the `@operator decorator` part of the proposal is an effort trying to address this issue, but it really is not the responsibility of the standard to try to define such a thing.

Why not?  The standard defines well-known symbols.  Maybe `@operator` could be a well known decorator (assuming decorators get approved).

Slide 15 from http://www.slideshare.net/BrendanEich/js-resp shows syntax for defining operators in value types which could be adapted as follows for regular classes:

```
class Point {
   constructor(x, y) {
       this.x = +x;
       this.y = +y;
   }
   Point + Number (a, b) {
       return new Point(a.x + b, a.y + b);
   }
   Number + Point (a, b) {
       return new Point(a + b.x, a + b.y);
   }
   Point + Point (a, b) {
       return new Point(a.x + b.x, a.y + b.y);
   }
}
```

Having to define `+` twice for `Point + Number` and `Number + Point` seems like busy work, but maybe it's better to be explicit.  What are you thoughts about this syntax?

Another thing is that, IMHO, currently there are too much quirks/conventions in the proposal that feel non-evident and non-flexible which is destined to trip people over from time to time. It would be great to make a proposal that's simple and don't include too much assumptions.

Could you elaborator what quirks/conventions might trip people up?

Finally, I'm not sure about the current status of macros, but last I heard of it, they say it's going to make its way into the standard pretty soon (TM), and macros can do much of the things overloading could, and much more.

I haven't seen any proposals for macros, could you post a link?







On Sat, May 7, 2016 at 9:55 PM, G. Kay Lee <[hidden email]> wrote:
I'd say it's way too early to ask for a champion on this because just a quick skimming revealed a lot of places that didn't add up. For example, the proposal suggested that overloading is primarily targeted at making it easier to work with user-defined classes, but curiously a `Function.defineOperator()` method is proposed instead of some syntax that feels more tightly integrated with the class definition syntax.

```
class Point {
    constructor(x, y) {
        Object.assign(this, { x, y });
    }

    toString() {
        return `(${this.x}, ${this.y})`;
    }
}

Function.defineOperator('+', [Point, Point], (a, b) => new Point(a.x + b.x, a.y + b.y));
```

The demo code made this flaw evident - it looks like a giant step backward to define an instance method like this, don't you agree?

It's also apparent that the `@operator decorator` part of the proposal is an effort trying to address this issue, but it really is not the responsibility of the standard to try to define such a thing.

What I'd suggest is that perhaps you should rethink your proposed syntax and redesign it to become an extension of the ES6 class definition syntax.

Another thing is that, IMHO, currently there are too much quirks/conventions in the proposal that feel non-evident and non-flexible which is destined to trip people over from time to time. It would be great to make a proposal that's simple and don't include too much assumptions.

Finally, I'm not sure about the current status of macros, but last I heard of it, they say it's going to make its way into the standard pretty soon (TM), and macros can do much of the things overloading could, and much more.

On Sun, May 8, 2016 at 8:51 AM, Kevin Barabash <[hidden email]> wrote:
I forgot to mention in my last email that I'm looking for a champion for this proposal.

On Sat, May 7, 2016 at 5:24 PM, Kevin Barabash <[hidden email]> wrote:
Hi everyone,

I've been working on implementing operator overloading and would like to submit a proposal.

I think operator overloading would be a useful addition to the language.  In particular I think it would be useful for defining operations on common mathematical object types such as complex numbers, vectors, matrices, and sets.

I've create a working prototype that consists of:
  • babel plugin that rewrites operators as function calls
  • a polyfill which defines these functions and which call the correct argument-specific function based on the arguments' prototypes
  • Function.defineOperator which can be used to define which function an operator should use for the specified types
  • "use overloading" directive which allows users to opt-in

The design was inspired by some of the slides from http://www.slideshare.net/BrendanEich/js-resp.

– Kevin




_______________________________________________
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: operator overloading proposal

G. Kay Lee
> Why not? The standard defines well-known symbols. Maybe `@operator` could be a well known decorator (assuming decorators get approved).

Well... you make something into the standard with proposals, not why-nots, so in order to make that happen you need to draft another proposal for well-known decorators. And remember that decorators are essentially just a syntax to apply functions to objects/classes at design time, so what you're proposing is essentially some new global function, which is going against the current trend and effort to better modularize/namespace all these utility functions/methods. And maybe a new mechanism could be drafted for these new well-known decorators, so that we can hide these new functions somewhere... but by now I hope it's becoming clear that it's introducing way too much new surface area for the language in exchange for one small feature.

I haven't seen any proposals for macros, could you post a link?

It has been mentioned and discussed in numerous places over the years, you can find more info on this with some casual googling. For example: https://news.ycombinator.com/item?id=2983420



On Sun, May 8, 2016 at 2:51 PM, Kevin Barabash <[hidden email]> wrote:
I should update the demo code to show the `@operator` decorator in addition to `Function.defineOperator`.

Initially I started out with just the `@operator` decorator, but that meant that each class would have to have knowledge of each of the classes it might want to interact with before hand.  Having a separate `defineOperator` function avoids this situation.

It means that prototype style classes must be converted to the new class syntax before operator overloading could be used.  Lastly, there may be some cases where it makes sense to overload operators with existing 3rd party code or built-in classes, e.g. adding set operations to Set using operator overloading.

It's also apparent that the `@operator decorator` part of the proposal is an effort trying to address this issue, but it really is not the responsibility of the standard to try to define such a thing.

Why not?  The standard defines well-known symbols.  Maybe `@operator` could be a well known decorator (assuming decorators get approved).

Slide 15 from http://www.slideshare.net/BrendanEich/js-resp shows syntax for defining operators in value types which could be adapted as follows for regular classes:

```
class Point {
   constructor(x, y) {
       this.x = +x;
       this.y = +y;
   }
   Point + Number (a, b) {
       return new Point(a.x + b, a.y + b);
   }
   Number + Point (a, b) {
       return new Point(a + b.x, a + b.y);
   }
   Point + Point (a, b) {
       return new Point(a.x + b.x, a.y + b.y);
   }
}
```

Having to define `+` twice for `Point + Number` and `Number + Point` seems like busy work, but maybe it's better to be explicit.  What are you thoughts about this syntax?

Another thing is that, IMHO, currently there are too much quirks/conventions in the proposal that feel non-evident and non-flexible which is destined to trip people over from time to time. It would be great to make a proposal that's simple and don't include too much assumptions.

Could you elaborator what quirks/conventions might trip people up?

Finally, I'm not sure about the current status of macros, but last I heard of it, they say it's going to make its way into the standard pretty soon (TM), and macros can do much of the things overloading could, and much more.

I haven't seen any proposals for macros, could you post a link?







On Sat, May 7, 2016 at 9:55 PM, G. Kay Lee <[hidden email]> wrote:
I'd say it's way too early to ask for a champion on this because just a quick skimming revealed a lot of places that didn't add up. For example, the proposal suggested that overloading is primarily targeted at making it easier to work with user-defined classes, but curiously a `Function.defineOperator()` method is proposed instead of some syntax that feels more tightly integrated with the class definition syntax.

```
class Point {
    constructor(x, y) {
        Object.assign(this, { x, y });
    }

    toString() {
        return `(${this.x}, ${this.y})`;
    }
}

Function.defineOperator('+', [Point, Point], (a, b) => new Point(a.x + b.x, a.y + b.y));
```

The demo code made this flaw evident - it looks like a giant step backward to define an instance method like this, don't you agree?

It's also apparent that the `@operator decorator` part of the proposal is an effort trying to address this issue, but it really is not the responsibility of the standard to try to define such a thing.

What I'd suggest is that perhaps you should rethink your proposed syntax and redesign it to become an extension of the ES6 class definition syntax.

Another thing is that, IMHO, currently there are too much quirks/conventions in the proposal that feel non-evident and non-flexible which is destined to trip people over from time to time. It would be great to make a proposal that's simple and don't include too much assumptions.

Finally, I'm not sure about the current status of macros, but last I heard of it, they say it's going to make its way into the standard pretty soon (TM), and macros can do much of the things overloading could, and much more.

On Sun, May 8, 2016 at 8:51 AM, Kevin Barabash <[hidden email]> wrote:
I forgot to mention in my last email that I'm looking for a champion for this proposal.

On Sat, May 7, 2016 at 5:24 PM, Kevin Barabash <[hidden email]> wrote:
Hi everyone,

I've been working on implementing operator overloading and would like to submit a proposal.

I think operator overloading would be a useful addition to the language.  In particular I think it would be useful for defining operations on common mathematical object types such as complex numbers, vectors, matrices, and sets.

I've create a working prototype that consists of:
  • babel plugin that rewrites operators as function calls
  • a polyfill which defines these functions and which call the correct argument-specific function based on the arguments' prototypes
  • Function.defineOperator which can be used to define which function an operator should use for the specified types
  • "use overloading" directive which allows users to opt-in

The design was inspired by some of the slides from http://www.slideshare.net/BrendanEich/js-resp.

– Kevin




_______________________________________________
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



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

Re: operator overloading proposal

Kevin Barabash
And remember that decorators are essentially just a syntax to apply functions to objects/classes at design time, so what you're proposing is essentially some new global function, which is going against the current trend and effort to better modularize/namespace all these utility functions/methods.

That's a really good point.

It has been mentioned and discussed in numerous places over the years, you can find more info on this with some casual googling. For example:https://news.ycombinator.com/item?id=2983420

Thanks for the link.  I played around with sweet.js a bit over the weekend.  Using macros should work if we went with Python style operator overloading.  Instead of defining methods like _ADD_, _SUB_ etc. we could create some well-known symbols, maybe Symbol.plus, Symbol.times, etc.

```
class Point {
  constructor(x, y) {
    Object.assign(this, {x, y});
  }
  
  [Symbol.add](other) {
    return new Point(this.x + other.x, this.y + other.y);
  }
}

const u = new Point(5, 10);
const v = new Point(1, -2);

const w = u + v;  // desugars to u[Symbol.add](v)
console.log(w);   // { x: 6, y: 8 };
```

This would require default implementations to be defined on Object.prototype for Symbol.plus, Symbol.times, etc.


On Sun, May 8, 2016 at 10:38 PM, G. Kay Lee <[hidden email]> wrote:
> Why not? The standard defines well-known symbols. Maybe `@operator` could be a well known decorator (assuming decorators get approved).

Well... you make something into the standard with proposals, not why-nots, so in order to make that happen you need to draft another proposal for well-known decorators. And remember that decorators are essentially just a syntax to apply functions to objects/classes at design time, so what you're proposing is essentially some new global function, which is going against the current trend and effort to better modularize/namespace all these utility functions/methods. And maybe a new mechanism could be drafted for these new well-known decorators, so that we can hide these new functions somewhere... but by now I hope it's becoming clear that it's introducing way too much new surface area for the language in exchange for one small feature.

I haven't seen any proposals for macros, could you post a link?

It has been mentioned and discussed in numerous places over the years, you can find more info on this with some casual googling. For example: https://news.ycombinator.com/item?id=2983420



On Sun, May 8, 2016 at 2:51 PM, Kevin Barabash <[hidden email]> wrote:
I should update the demo code to show the `@operator` decorator in addition to `Function.defineOperator`.

Initially I started out with just the `@operator` decorator, but that meant that each class would have to have knowledge of each of the classes it might want to interact with before hand.  Having a separate `defineOperator` function avoids this situation.

It means that prototype style classes must be converted to the new class syntax before operator overloading could be used.  Lastly, there may be some cases where it makes sense to overload operators with existing 3rd party code or built-in classes, e.g. adding set operations to Set using operator overloading.

It's also apparent that the `@operator decorator` part of the proposal is an effort trying to address this issue, but it really is not the responsibility of the standard to try to define such a thing.

Why not?  The standard defines well-known symbols.  Maybe `@operator` could be a well known decorator (assuming decorators get approved).

Slide 15 from http://www.slideshare.net/BrendanEich/js-resp shows syntax for defining operators in value types which could be adapted as follows for regular classes:

```
class Point {
   constructor(x, y) {
       this.x = +x;
       this.y = +y;
   }
   Point + Number (a, b) {
       return new Point(a.x + b, a.y + b);
   }
   Number + Point (a, b) {
       return new Point(a + b.x, a + b.y);
   }
   Point + Point (a, b) {
       return new Point(a.x + b.x, a.y + b.y);
   }
}
```

Having to define `+` twice for `Point + Number` and `Number + Point` seems like busy work, but maybe it's better to be explicit.  What are you thoughts about this syntax?

Another thing is that, IMHO, currently there are too much quirks/conventions in the proposal that feel non-evident and non-flexible which is destined to trip people over from time to time. It would be great to make a proposal that's simple and don't include too much assumptions.

Could you elaborator what quirks/conventions might trip people up?

Finally, I'm not sure about the current status of macros, but last I heard of it, they say it's going to make its way into the standard pretty soon (TM), and macros can do much of the things overloading could, and much more.

I haven't seen any proposals for macros, could you post a link?







On Sat, May 7, 2016 at 9:55 PM, G. Kay Lee <[hidden email]> wrote:
I'd say it's way too early to ask for a champion on this because just a quick skimming revealed a lot of places that didn't add up. For example, the proposal suggested that overloading is primarily targeted at making it easier to work with user-defined classes, but curiously a `Function.defineOperator()` method is proposed instead of some syntax that feels more tightly integrated with the class definition syntax.

```
class Point {
    constructor(x, y) {
        Object.assign(this, { x, y });
    }

    toString() {
        return `(${this.x}, ${this.y})`;
    }
}

Function.defineOperator('+', [Point, Point], (a, b) => new Point(a.x + b.x, a.y + b.y));
```

The demo code made this flaw evident - it looks like a giant step backward to define an instance method like this, don't you agree?

It's also apparent that the `@operator decorator` part of the proposal is an effort trying to address this issue, but it really is not the responsibility of the standard to try to define such a thing.

What I'd suggest is that perhaps you should rethink your proposed syntax and redesign it to become an extension of the ES6 class definition syntax.

Another thing is that, IMHO, currently there are too much quirks/conventions in the proposal that feel non-evident and non-flexible which is destined to trip people over from time to time. It would be great to make a proposal that's simple and don't include too much assumptions.

Finally, I'm not sure about the current status of macros, but last I heard of it, they say it's going to make its way into the standard pretty soon (TM), and macros can do much of the things overloading could, and much more.

On Sun, May 8, 2016 at 8:51 AM, Kevin Barabash <[hidden email]> wrote:
I forgot to mention in my last email that I'm looking for a champion for this proposal.

On Sat, May 7, 2016 at 5:24 PM, Kevin Barabash <[hidden email]> wrote:
Hi everyone,

I've been working on implementing operator overloading and would like to submit a proposal.

I think operator overloading would be a useful addition to the language.  In particular I think it would be useful for defining operations on common mathematical object types such as complex numbers, vectors, matrices, and sets.

I've create a working prototype that consists of:
  • babel plugin that rewrites operators as function calls
  • a polyfill which defines these functions and which call the correct argument-specific function based on the arguments' prototypes
  • Function.defineOperator which can be used to define which function an operator should use for the specified types
  • "use overloading" directive which allows users to opt-in

The design was inspired by some of the slides from http://www.slideshare.net/BrendanEich/js-resp.

– Kevin




_______________________________________________
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



_______________________________________________
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: operator overloading proposal

G. Kay Lee
Yes, I think exposing operators through well-known symbols is an interesting idea worthy of more exploration because it's precisely the purpose of well-known symbols to expose and allow manipulation to previously inaccessible internal language behaviors.

On Tue, May 10, 2016 at 1:59 PM, Kevin Barabash <[hidden email]> wrote:
And remember that decorators are essentially just a syntax to apply functions to objects/classes at design time, so what you're proposing is essentially some new global function, which is going against the current trend and effort to better modularize/namespace all these utility functions/methods.

That's a really good point.

It has been mentioned and discussed in numerous places over the years, you can find more info on this with some casual googling. For example:https://news.ycombinator.com/item?id=2983420

Thanks for the link.  I played around with sweet.js a bit over the weekend.  Using macros should work if we went with Python style operator overloading.  Instead of defining methods like _ADD_, _SUB_ etc. we could create some well-known symbols, maybe Symbol.plus, Symbol.times, etc.

```
class Point {
  constructor(x, y) {
    Object.assign(this, {x, y});
  }
  
  [Symbol.add](other) {
    return new Point(this.x + other.x, this.y + other.y);
  }
}

const u = new Point(5, 10);
const v = new Point(1, -2);

const w = u + v;  // desugars to u[Symbol.add](v)
console.log(w);   // { x: 6, y: 8 };
```

This would require default implementations to be defined on Object.prototype for Symbol.plus, Symbol.times, etc.


On Sun, May 8, 2016 at 10:38 PM, G. Kay Lee <[hidden email]> wrote:
> Why not? The standard defines well-known symbols. Maybe `@operator` could be a well known decorator (assuming decorators get approved).

Well... you make something into the standard with proposals, not why-nots, so in order to make that happen you need to draft another proposal for well-known decorators. And remember that decorators are essentially just a syntax to apply functions to objects/classes at design time, so what you're proposing is essentially some new global function, which is going against the current trend and effort to better modularize/namespace all these utility functions/methods. And maybe a new mechanism could be drafted for these new well-known decorators, so that we can hide these new functions somewhere... but by now I hope it's becoming clear that it's introducing way too much new surface area for the language in exchange for one small feature.

I haven't seen any proposals for macros, could you post a link?

It has been mentioned and discussed in numerous places over the years, you can find more info on this with some casual googling. For example: https://news.ycombinator.com/item?id=2983420



On Sun, May 8, 2016 at 2:51 PM, Kevin Barabash <[hidden email]> wrote:
I should update the demo code to show the `@operator` decorator in addition to `Function.defineOperator`.

Initially I started out with just the `@operator` decorator, but that meant that each class would have to have knowledge of each of the classes it might want to interact with before hand.  Having a separate `defineOperator` function avoids this situation.

It means that prototype style classes must be converted to the new class syntax before operator overloading could be used.  Lastly, there may be some cases where it makes sense to overload operators with existing 3rd party code or built-in classes, e.g. adding set operations to Set using operator overloading.

It's also apparent that the `@operator decorator` part of the proposal is an effort trying to address this issue, but it really is not the responsibility of the standard to try to define such a thing.

Why not?  The standard defines well-known symbols.  Maybe `@operator` could be a well known decorator (assuming decorators get approved).

Slide 15 from http://www.slideshare.net/BrendanEich/js-resp shows syntax for defining operators in value types which could be adapted as follows for regular classes:

```
class Point {
   constructor(x, y) {
       this.x = +x;
       this.y = +y;
   }
   Point + Number (a, b) {
       return new Point(a.x + b, a.y + b);
   }
   Number + Point (a, b) {
       return new Point(a + b.x, a + b.y);
   }
   Point + Point (a, b) {
       return new Point(a.x + b.x, a.y + b.y);
   }
}
```

Having to define `+` twice for `Point + Number` and `Number + Point` seems like busy work, but maybe it's better to be explicit.  What are you thoughts about this syntax?

Another thing is that, IMHO, currently there are too much quirks/conventions in the proposal that feel non-evident and non-flexible which is destined to trip people over from time to time. It would be great to make a proposal that's simple and don't include too much assumptions.

Could you elaborator what quirks/conventions might trip people up?

Finally, I'm not sure about the current status of macros, but last I heard of it, they say it's going to make its way into the standard pretty soon (TM), and macros can do much of the things overloading could, and much more.

I haven't seen any proposals for macros, could you post a link?







On Sat, May 7, 2016 at 9:55 PM, G. Kay Lee <[hidden email]> wrote:
I'd say it's way too early to ask for a champion on this because just a quick skimming revealed a lot of places that didn't add up. For example, the proposal suggested that overloading is primarily targeted at making it easier to work with user-defined classes, but curiously a `Function.defineOperator()` method is proposed instead of some syntax that feels more tightly integrated with the class definition syntax.

```
class Point {
    constructor(x, y) {
        Object.assign(this, { x, y });
    }

    toString() {
        return `(${this.x}, ${this.y})`;
    }
}

Function.defineOperator('+', [Point, Point], (a, b) => new Point(a.x + b.x, a.y + b.y));
```

The demo code made this flaw evident - it looks like a giant step backward to define an instance method like this, don't you agree?

It's also apparent that the `@operator decorator` part of the proposal is an effort trying to address this issue, but it really is not the responsibility of the standard to try to define such a thing.

What I'd suggest is that perhaps you should rethink your proposed syntax and redesign it to become an extension of the ES6 class definition syntax.

Another thing is that, IMHO, currently there are too much quirks/conventions in the proposal that feel non-evident and non-flexible which is destined to trip people over from time to time. It would be great to make a proposal that's simple and don't include too much assumptions.

Finally, I'm not sure about the current status of macros, but last I heard of it, they say it's going to make its way into the standard pretty soon (TM), and macros can do much of the things overloading could, and much more.

On Sun, May 8, 2016 at 8:51 AM, Kevin Barabash <[hidden email]> wrote:
I forgot to mention in my last email that I'm looking for a champion for this proposal.

On Sat, May 7, 2016 at 5:24 PM, Kevin Barabash <[hidden email]> wrote:
Hi everyone,

I've been working on implementing operator overloading and would like to submit a proposal.

I think operator overloading would be a useful addition to the language.  In particular I think it would be useful for defining operations on common mathematical object types such as complex numbers, vectors, matrices, and sets.

I've create a working prototype that consists of:
  • babel plugin that rewrites operators as function calls
  • a polyfill which defines these functions and which call the correct argument-specific function based on the arguments' prototypes
  • Function.defineOperator which can be used to define which function an operator should use for the specified types
  • "use overloading" directive which allows users to opt-in

The design was inspired by some of the slides from http://www.slideshare.net/BrendanEich/js-resp.

– Kevin




_______________________________________________
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



_______________________________________________
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: operator overloading proposal

Isiah Meadows-2

I would prefer syntax + internal slots, since you'll know at creation time whether the object has overloaded operators. It's much simpler for the engine to figure out, and it's more performant because you only need to check one thing instead of worrying about inheritance, own properties, etc.

Also, it would be IMHO easier to read than a symbol (the computed property syntax is ugly IMO). Using a different concept than symbols would also fit better with value types whenever any of those proposals make it into the language (either the struct or special syntax).


On Tue, May 10, 2016, 04:03 G. Kay Lee <[hidden email]> wrote:
Yes, I think exposing operators through well-known symbols is an interesting idea worthy of more exploration because it's precisely the purpose of well-known symbols to expose and allow manipulation to previously inaccessible internal language behaviors.

On Tue, May 10, 2016 at 1:59 PM, Kevin Barabash <[hidden email]> wrote:
And remember that decorators are essentially just a syntax to apply functions to objects/classes at design time, so what you're proposing is essentially some new global function, which is going against the current trend and effort to better modularize/namespace all these utility functions/methods.

That's a really good point.

It has been mentioned and discussed in numerous places over the years, you can find more info on this with some casual googling. For example:https://news.ycombinator.com/item?id=2983420

Thanks for the link.  I played around with sweet.js a bit over the weekend.  Using macros should work if we went with Python style operator overloading.  Instead of defining methods like _ADD_, _SUB_ etc. we could create some well-known symbols, maybe Symbol.plus, Symbol.times, etc.

```
class Point {
  constructor(x, y) {
    Object.assign(this, {x, y});
  }
  
  [Symbol.add](other) {
    return new Point(this.x + other.x, this.y + other.y);
  }
}

const u = new Point(5, 10);
const v = new Point(1, -2);

const w = u + v;  // desugars to u[Symbol.add](v)
console.log(w);   // { x: 6, y: 8 };
```

This would require default implementations to be defined on Object.prototype for Symbol.plus, Symbol.times, etc.


On Sun, May 8, 2016 at 10:38 PM, G. Kay Lee <[hidden email]> wrote:
> Why not? The standard defines well-known symbols. Maybe `@operator` could be a well known decorator (assuming decorators get approved).

Well... you make something into the standard with proposals, not why-nots, so in order to make that happen you need to draft another proposal for well-known decorators. And remember that decorators are essentially just a syntax to apply functions to objects/classes at design time, so what you're proposing is essentially some new global function, which is going against the current trend and effort to better modularize/namespace all these utility functions/methods. And maybe a new mechanism could be drafted for these new well-known decorators, so that we can hide these new functions somewhere... but by now I hope it's becoming clear that it's introducing way too much new surface area for the language in exchange for one small feature.

I haven't seen any proposals for macros, could you post a link?

It has been mentioned and discussed in numerous places over the years, you can find more info on this with some casual googling. For example: https://news.ycombinator.com/item?id=2983420



On Sun, May 8, 2016 at 2:51 PM, Kevin Barabash <[hidden email]> wrote:
I should update the demo code to show the `@operator` decorator in addition to `Function.defineOperator`.

Initially I started out with just the `@operator` decorator, but that meant that each class would have to have knowledge of each of the classes it might want to interact with before hand.  Having a separate `defineOperator` function avoids this situation.

It means that prototype style classes must be converted to the new class syntax before operator overloading could be used.  Lastly, there may be some cases where it makes sense to overload operators with existing 3rd party code or built-in classes, e.g. adding set operations to Set using operator overloading.

It's also apparent that the `@operator decorator` part of the proposal is an effort trying to address this issue, but it really is not the responsibility of the standard to try to define such a thing.

Why not?  The standard defines well-known symbols.  Maybe `@operator` could be a well known decorator (assuming decorators get approved).

Slide 15 from http://www.slideshare.net/BrendanEich/js-resp shows syntax for defining operators in value types which could be adapted as follows for regular classes:

```
class Point {
   constructor(x, y) {
       this.x = +x;
       this.y = +y;
   }
   Point + Number (a, b) {
       return new Point(a.x + b, a.y + b);
   }
   Number + Point (a, b) {
       return new Point(a + b.x, a + b.y);
   }
   Point + Point (a, b) {
       return new Point(a.x + b.x, a.y + b.y);
   }
}
```

Having to define `+` twice for `Point + Number` and `Number + Point` seems like busy work, but maybe it's better to be explicit.  What are you thoughts about this syntax?

Another thing is that, IMHO, currently there are too much quirks/conventions in the proposal that feel non-evident and non-flexible which is destined to trip people over from time to time. It would be great to make a proposal that's simple and don't include too much assumptions.

Could you elaborator what quirks/conventions might trip people up?

Finally, I'm not sure about the current status of macros, but last I heard of it, they say it's going to make its way into the standard pretty soon (TM), and macros can do much of the things overloading could, and much more.

I haven't seen any proposals for macros, could you post a link?







On Sat, May 7, 2016 at 9:55 PM, G. Kay Lee <[hidden email]> wrote:
I'd say it's way too early to ask for a champion on this because just a quick skimming revealed a lot of places that didn't add up. For example, the proposal suggested that overloading is primarily targeted at making it easier to work with user-defined classes, but curiously a `Function.defineOperator()` method is proposed instead of some syntax that feels more tightly integrated with the class definition syntax.

```
class Point {
    constructor(x, y) {
        Object.assign(this, { x, y });
    }

    toString() {
        return `(${this.x}, ${this.y})`;
    }
}

Function.defineOperator('+', [Point, Point], (a, b) => new Point(a.x + b.x, a.y + b.y));
```

The demo code made this flaw evident - it looks like a giant step backward to define an instance method like this, don't you agree?

It's also apparent that the `@operator decorator` part of the proposal is an effort trying to address this issue, but it really is not the responsibility of the standard to try to define such a thing.

What I'd suggest is that perhaps you should rethink your proposed syntax and redesign it to become an extension of the ES6 class definition syntax.

Another thing is that, IMHO, currently there are too much quirks/conventions in the proposal that feel non-evident and non-flexible which is destined to trip people over from time to time. It would be great to make a proposal that's simple and don't include too much assumptions.

Finally, I'm not sure about the current status of macros, but last I heard of it, they say it's going to make its way into the standard pretty soon (TM), and macros can do much of the things overloading could, and much more.

On Sun, May 8, 2016 at 8:51 AM, Kevin Barabash <[hidden email]> wrote:
I forgot to mention in my last email that I'm looking for a champion for this proposal.

On Sat, May 7, 2016 at 5:24 PM, Kevin Barabash <[hidden email]> wrote:
Hi everyone,

I've been working on implementing operator overloading and would like to submit a proposal.

I think operator overloading would be a useful addition to the language.  In particular I think it would be useful for defining operations on common mathematical object types such as complex numbers, vectors, matrices, and sets.

I've create a working prototype that consists of:
  • babel plugin that rewrites operators as function calls
  • a polyfill which defines these functions and which call the correct argument-specific function based on the arguments' prototypes
  • Function.defineOperator which can be used to define which function an operator should use for the specified types
  • "use overloading" directive which allows users to opt-in

The design was inspired by some of the slides from http://www.slideshare.net/BrendanEich/js-resp.

– Kevin




_______________________________________________
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



_______________________________________________
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

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

Re: operator overloading proposal

Brian Barnes-3
A note on this from somebody who's entire existence seems dedicated to
stopping as much stuff as possible from getting GC'd, the example below:

 >const u = new Point(5, 10);
 >const v = new Point(1, -2);
 >
 >const w = u + v;  // desugars to u[Symbol.add](v)
 >console.log(w);   // { x: 6, y: 8 };

Could += be a special case?  i.e.,

u+=v;

would call:

Class Point { ... other stuff ...
[whatever the syntax is](pt)
{
this.x+=pt.x;
this.y+=pt.y;
}
}

instead of desugaring to:

u=u+v; // which would cause the creation of an object and
                // leave the other to be collected

For all I know, += might be doing such anyway in some engines, but for
my stuff which is a lot of 3D math that could be a performance killer.
It would be nice to be able to just add points and such, as long as the
overhead is negligible.

[>] Brian

On 5/10/2016 10:52 AM, Isiah Meadows wrote:

> I would prefer syntax + internal slots, since you'll know at creation
> time whether the object has overloaded operators. It's much simpler for
> the engine to figure out, and it's more performant because you only need
> to check one thing instead of worrying about inheritance, own
> properties, etc.
>
> Also, it would be IMHO easier to read than a symbol (the computed
> property syntax is ugly IMO). Using a different concept than symbols
> would also fit better with value types whenever any of those proposals
> make it into the language (either the struct or special syntax).
>
>
> On Tue, May 10, 2016, 04:03 G. Kay Lee
> <[hidden email]
> <mailto:balancetraveller%[hidden email]>> wrote:
>
>     Yes, I think exposing operators through well-known symbols is an
>     interesting idea worthy of more exploration because it's precisely
>     the purpose of well-known symbols to expose and allow manipulation
>     to previously inaccessible internal language behaviors.
>
>     On Tue, May 10, 2016 at 1:59 PM, Kevin Barabash
>     <[hidden email] <mailto:[hidden email]>> wrote:
>
>         > And remember that decorators are essentially just a syntax to
>         apply functions to objects/classes at design time, so what
>         you're proposing is essentially some new global function, which
>         is going against the current trend and effort to better
>         modularize/namespace all these utility functions/methods.
>
>         That's a really good point.
>
>         > It has been mentioned and discussed in numerous places over the
>         years, you can find more info on this with some casual googling.
>         For example:https://news.ycombinator.com/item?id=2983420
>
>         Thanks for the link.  I played around with sweet.js a bit over
>         the weekend.  Using macros should work if we went with Python
>         style operator overloading.  Instead of defining methods like
>         _ADD_, _SUB_ etc. we could create some well-known symbols, maybe
>         Symbol.plus, Symbol.times, etc.
>
>         ```
>         class Point {
>           constructor(x, y) {
>             Object.assign(this, {x, y});
>           }
>
>           [Symbol.add](other) {
>             return new Point(this.x + other.x, this.y + other.y);
>           }
>         }
>
>         const u = new Point(5, 10);
>         const v = new Point(1, -2);
>
>         const w = u + v;  // desugars to u[Symbol.add](v)
>         console.log(w);   // { x: 6, y: 8 };
>         ```
>
>         This would require default implementations to be defined on
>         Object.prototype for Symbol.plus, Symbol.times, etc.
>
>
>         On Sun, May 8, 2016 at 10:38 PM, G. Kay Lee
>         <[hidden email]
>         <mailto:[hidden email]>> wrote:
>
>             > Why not? The standard defines well-known symbols. Maybe `@operator` could be a well known decorator (assuming decorators get approved).
>
>             Well... you make something into the standard with proposals,
>             not why-nots, so in order to make that happen you need to
>             draft another proposal for well-known decorators. And
>             remember that decorators are essentially just a syntax to
>             apply functions to objects/classes at design time, so what
>             you're proposing is essentially some new global function,
>             which is going against the current trend and effort to
>             better modularize/namespace all these utility
>             functions/methods. And maybe a new mechanism could be
>             drafted for these new well-known decorators, so that we can
>             hide these new functions somewhere... but by now I hope it's
>             becoming clear that it's introducing way too much new
>             surface area for the language in exchange for one small feature.
>
>             > I haven't seen any proposals for macros, could you post a link?
>
>             It has been mentioned and discussed in numerous places over
>             the years, you can find more info on this with some casual
>             googling. For example:
>             https://news.ycombinator.com/item?id=2983420
>
>
>
>             On Sun, May 8, 2016 at 2:51 PM, Kevin Barabash
>             <[hidden email] <mailto:[hidden email]>> wrote:
>
>                 I should update the demo code to show the `@operator`
>                 decorator in addition to `Function.defineOperator`.
>
>                 Initially I started out with just the `@operator`
>                 decorator, but that meant that each class would have to
>                 have knowledge of each of the classes it might want to
>                 interact with before hand.  Having a separate
>                 `defineOperator` function avoids this situation.
>
>                 It means that prototype style classes must be converted
>                 to the new class syntax before operator overloading
>                 could be used.  Lastly, there may be some cases where it
>                 makes sense to overload operators with existing 3rd
>                 party code or built-in classes, e.g. adding set
>                 operations to Set using operator overloading.
>
>                 > It's also apparent that the `@operator decorator` part
>                 of the proposal is an effort trying to address this
>                 issue, but it really is not the responsibility of the
>                 standard to try to define such a thing.
>
>                 Why not?  The standard defines well-known symbols.
>                 Maybe `@operator` could be a well known decorator
>                 (assuming decorators get approved).
>
>                 Slide 15
>                 from http://www.slideshare.net/BrendanEich/js-resp shows
>                 syntax for defining operators in value types which could
>                 be adapted as follows for regular classes:
>
>                 ```
>                 class Point {
>                    constructor(x, y) {
>                        this.x = +x;
>                        this.y = +y;
>                    }
>                    Point + Number (a, b) {
>                        return new Point(a.x + b, a.y + b);
>                    }
>                    Number + Point (a, b) {
>                        return new Point(a + b.x, a + b.y);
>                    }
>                    Point + Point (a, b) {
>                        return new Point(a.x + b.x, a.y + b.y);
>                    }
>                 }
>                 ```
>
>                 Having to define `+` twice for `Point + Number` and
>                 `Number + Point` seems like busy work, but maybe it's
>                 better to be explicit.  What are you thoughts about this
>                 syntax?
>
>                 > Another thing is that, IMHO, currently there are too
>                 much quirks/conventions in the proposal that feel
>                 non-evident and non-flexible which is destined to trip
>                 people over from time to time. It would be great to make
>                 a proposal that's simple and don't include too much
>                 assumptions.
>
>                 Could you elaborator what quirks/conventions might trip
>                 people up?
>
>                 > Finally, I'm not sure about the current status of
>                 macros, but last I heard of it, they say it's going to
>                 make its way into the standard pretty soon (TM), and
>                 macros can do much of the things overloading could, and
>                 much more.
>
>                 I haven't seen any proposals for macros, could you post
>                 a link?
>
>
>
>
>
>
>
>                 On Sat, May 7, 2016 at 9:55 PM, G. Kay Lee
>                 <[hidden email]
>                 <mailto:[hidden email]>> wrote:
>
>                     I'd say it's way too early to ask for a champion on
>                     this because just a quick skimming revealed a lot of
>                     places that didn't add up. For example, the proposal
>                     suggested that overloading is primarily targeted at
>                     making it easier to work with user-defined classes,
>                     but curiously a `Function.defineOperator()` method
>                     is proposed instead of some syntax that feels more
>                     tightly integrated with the class definition syntax.
>
>                     ```
>
>                     class Point {
>                         constructor(x, y) {
>                             Object.assign(this, { x, y });
>                         }
>
>                         toString() {
>                             return `(${this.x}, ${this.y})`;
>                         }
>                     }
>
>                     Function.defineOperator('+', [Point, Point], (a, b) => new Point(a.x + b.x, a.y + b.y));
>
>                     ```
>
>                     The demo code made this flaw evident - it looks like
>                     a giant step backward to define an instance method
>                     like this, don't you agree?
>
>                     It's also apparent that the `@operator decorator`
>                     part of the proposal is an effort trying to address
>                     this issue, but it really is not the responsibility
>                     of the standard to try to define such a thing.
>
>                     What I'd suggest is that perhaps you should rethink
>                     your proposed syntax and redesign it to become an
>                     extension of the ES6 class definition syntax.
>
>                     Another thing is that, IMHO, currently there are too
>                     much quirks/conventions in the proposal that feel
>                     non-evident and non-flexible which is destined to
>                     trip people over from time to time. It would be
>                     great to make a proposal that's simple and don't
>                     include too much assumptions.
>
>                     Finally, I'm not sure about the current status of
>                     macros, but last I heard of it, they say it's going
>                     to make its way into the standard pretty soon (TM),
>                     and macros can do much of the things overloading
>                     could, and much more.
>
>                     On Sun, May 8, 2016 at 8:51 AM, Kevin Barabash
>                     <[hidden email]
>                     <mailto:[hidden email]>> wrote:
>
>                         I forgot to mention in my last email that I'm
>                         looking for a champion for this proposal.
>
>                         On Sat, May 7, 2016 at 5:24 PM, Kevin Barabash
>                         <[hidden email]
>                         <mailto:[hidden email]>> wrote:
>
>                             Hi everyone,
>
>                             I've been working on implementing operator
>                             overloading and would like to submit a proposal.
>
>                             I think operator overloading would be a
>                             useful addition to the language.  In
>                             particular I think it would be useful for
>                             defining operations on common mathematical
>                             object types such as complex numbers,
>                             vectors, matrices, and sets.
>
>                             I've create a working prototype that
>                             consists of:
>
>                               * babel plugin that rewrites operators as
>                                 function calls
>                               * a polyfill which defines these functions
>                                 and which call the correct
>                                 argument-specific function based on the
>                                 arguments' prototypes
>                               * Function.defineOperator which can be
>                                 used to define which function an
>                                 operator should use for the specified types
>                               * "use overloading" directive which allows
>                                 users to opt-in
>
>                             More details can be found
>                             at https://github.com/kevinbarabash/operator-overloading.
>                             The babel plugin can be found
>                             at https://github.com/kevinbarabash/babel-plugin-operator-overloading.
>                             I also have a demo project at
>                             https://github.com/kevinbarabash/operator-overloading-demo.
>
>                             The design was inspired by some of the
>                             slides from
>                             http://www.slideshare.net/BrendanEich/js-resp.
>
>                             – Kevin
>
>
>
>
>                         _______________________________________________
>                         es-discuss mailing list
>                         [hidden email]
>                         <mailto:[hidden email]>
>                         https://mail.mozilla.org/listinfo/es-discuss
>
>
>
>                     _______________________________________________
>                     es-discuss mailing list
>                     [hidden email] <mailto:[hidden email]>
>                     https://mail.mozilla.org/listinfo/es-discuss
>
>
>
>                 _______________________________________________
>                 es-discuss mailing list
>                 [hidden email] <mailto:[hidden email]>
>                 https://mail.mozilla.org/listinfo/es-discuss
>
>
>
>             _______________________________________________
>             es-discuss mailing list
>             [hidden email] <mailto:[hidden email]>
>             https://mail.mozilla.org/listinfo/es-discuss
>
>
>
>         _______________________________________________
>         es-discuss mailing list
>         [hidden email] <mailto:[hidden email]>
>         https://mail.mozilla.org/listinfo/es-discuss
>
>
>     _______________________________________________
>     es-discuss mailing list
>     [hidden email] <mailto:[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: operator overloading proposal

Isiah Meadows-2

Here's my thought, if we go with syntax.

```js
class Point {
    // constructor, etc.

    operator +(other) {
        assert(other instanceof Point)
        return new Point(
            this.x + other.x,
            this.y + other.y)
    }

    operator +=(other) {
        assert(other instanceof Point)
        this.x += other.x
        this.y += other.y
    }
}
```


On Tue, May 10, 2016, 11:16 Brian Barnes <[hidden email]> wrote:
A note on this from somebody who's entire existence seems dedicated to
stopping as much stuff as possible from getting GC'd, the example below:

 >const u = new Point(5, 10);
 >const v = new Point(1, -2);
 >
 >const w = u + v;  // desugars to u[Symbol.add](v)
 >console.log(w);   // { x: 6, y: 8 };

Could += be a special case?  i.e.,

u+=v;

would call:

Class Point { ... other stuff ...
[whatever the syntax is](pt)
{
this.x+=pt.x;
this.y+=pt.y;
}
}

instead of desugaring to:

u=u+v;          // which would cause the creation of an object and
                // leave the other to be collected

For all I know, += might be doing such anyway in some engines, but for
my stuff which is a lot of 3D math that could be a performance killer.
It would be nice to be able to just add points and such, as long as the
overhead is negligible.

[>] Brian

On 5/10/2016 10:52 AM, Isiah Meadows wrote:
> I would prefer syntax + internal slots, since you'll know at creation
> time whether the object has overloaded operators. It's much simpler for
> the engine to figure out, and it's more performant because you only need
> to check one thing instead of worrying about inheritance, own
> properties, etc.
>
> Also, it would be IMHO easier to read than a symbol (the computed
> property syntax is ugly IMO). Using a different concept than symbols
> would also fit better with value types whenever any of those proposals
> make it into the language (either the struct or special syntax).
>
>
> On Tue, May 10, 2016, 04:03 G. Kay Lee
> <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     Yes, I think exposing operators through well-known symbols is an
>     interesting idea worthy of more exploration because it's precisely
>     the purpose of well-known symbols to expose and allow manipulation
>     to previously inaccessible internal language behaviors.
>
>     On Tue, May 10, 2016 at 1:59 PM, Kevin Barabash
>     <[hidden email] <mailto:[hidden email]>> wrote:
>
>         > And remember that decorators are essentially just a syntax to
>         apply functions to objects/classes at design time, so what
>         you're proposing is essentially some new global function, which
>         is going against the current trend and effort to better
>         modularize/namespace all these utility functions/methods.
>
>         That's a really good point.
>
>         > It has been mentioned and discussed in numerous places over the
>         years, you can find more info on this with some casual googling.
>         For example:https://news.ycombinator.com/item?id=2983420
>
>         Thanks for the link.  I played around with sweet.js a bit over
>         the weekend.  Using macros should work if we went with Python
>         style operator overloading.  Instead of defining methods like
>         _ADD_, _SUB_ etc. we could create some well-known symbols, maybe
>         Symbol.plus, Symbol.times, etc.
>
>         ```
>         class Point {
>           constructor(x, y) {
>             Object.assign(this, {x, y});
>           }
>
>           [Symbol.add](other) {
>             return new Point(this.x + other.x, this.y + other.y);
>           }
>         }
>
>         const u = new Point(5, 10);
>         const v = new Point(1, -2);
>
>         const w = u + v;  // desugars to u[Symbol.add](v)
>         console.log(w);   // { x: 6, y: 8 };
>         ```
>
>         This would require default implementations to be defined on
>         Object.prototype for Symbol.plus, Symbol.times, etc.
>
>
>         On Sun, May 8, 2016 at 10:38 PM, G. Kay Lee
>         <[hidden email]
>         <mailto:[hidden email]>> wrote:
>
>             > Why not? The standard defines well-known symbols. Maybe `@operator` could be a well known decorator (assuming decorators get approved).
>
>             Well... you make something into the standard with proposals,
>             not why-nots, so in order to make that happen you need to
>             draft another proposal for well-known decorators. And
>             remember that decorators are essentially just a syntax to
>             apply functions to objects/classes at design time, so what
>             you're proposing is essentially some new global function,
>             which is going against the current trend and effort to
>             better modularize/namespace all these utility
>             functions/methods. And maybe a new mechanism could be
>             drafted for these new well-known decorators, so that we can
>             hide these new functions somewhere... but by now I hope it's
>             becoming clear that it's introducing way too much new
>             surface area for the language in exchange for one small feature.
>
>             > I haven't seen any proposals for macros, could you post a link?
>
>             It has been mentioned and discussed in numerous places over
>             the years, you can find more info on this with some casual
>             googling. For example:
>             https://news.ycombinator.com/item?id=2983420
>
>
>
>             On Sun, May 8, 2016 at 2:51 PM, Kevin Barabash
>             <[hidden email] <mailto:[hidden email]>> wrote:
>
>                 I should update the demo code to show the `@operator`
>                 decorator in addition to `Function.defineOperator`.
>
>                 Initially I started out with just the `@operator`
>                 decorator, but that meant that each class would have to
>                 have knowledge of each of the classes it might want to
>                 interact with before hand.  Having a separate
>                 `defineOperator` function avoids this situation.
>
>                 It means that prototype style classes must be converted
>                 to the new class syntax before operator overloading
>                 could be used.  Lastly, there may be some cases where it
>                 makes sense to overload operators with existing 3rd
>                 party code or built-in classes, e.g. adding set
>                 operations to Set using operator overloading.
>
>                 > It's also apparent that the `@operator decorator` part
>                 of the proposal is an effort trying to address this
>                 issue, but it really is not the responsibility of the
>                 standard to try to define such a thing.
>
>                 Why not?  The standard defines well-known symbols.
>                 Maybe `@operator` could be a well known decorator
>                 (assuming decorators get approved).
>
>                 Slide 15
>                 from http://www.slideshare.net/BrendanEich/js-resp shows
>                 syntax for defining operators in value types which could
>                 be adapted as follows for regular classes:
>
>                 ```
>                 class Point {
>                    constructor(x, y) {
>                        this.x = +x;
>                        this.y = +y;
>                    }
>                    Point + Number (a, b) {
>                        return new Point(a.x + b, a.y + b);
>                    }
>                    Number + Point (a, b) {
>                        return new Point(a + b.x, a + b.y);
>                    }
>                    Point + Point (a, b) {
>                        return new Point(a.x + b.x, a.y + b.y);
>                    }
>                 }
>                 ```
>
>                 Having to define `+` twice for `Point + Number` and
>                 `Number + Point` seems like busy work, but maybe it's
>                 better to be explicit.  What are you thoughts about this
>                 syntax?
>
>                 > Another thing is that, IMHO, currently there are too
>                 much quirks/conventions in the proposal that feel
>                 non-evident and non-flexible which is destined to trip
>                 people over from time to time. It would be great to make
>                 a proposal that's simple and don't include too much
>                 assumptions.
>
>                 Could you elaborator what quirks/conventions might trip
>                 people up?
>
>                 > Finally, I'm not sure about the current status of
>                 macros, but last I heard of it, they say it's going to
>                 make its way into the standard pretty soon (TM), and
>                 macros can do much of the things overloading could, and
>                 much more.
>
>                 I haven't seen any proposals for macros, could you post
>                 a link?
>
>
>
>
>
>
>
>                 On Sat, May 7, 2016 at 9:55 PM, G. Kay Lee
>                 <[hidden email]
>                 <mailto:[hidden email]>> wrote:
>
>                     I'd say it's way too early to ask for a champion on
>                     this because just a quick skimming revealed a lot of
>                     places that didn't add up. For example, the proposal
>                     suggested that overloading is primarily targeted at
>                     making it easier to work with user-defined classes,
>                     but curiously a `Function.defineOperator()` method
>                     is proposed instead of some syntax that feels more
>                     tightly integrated with the class definition syntax.
>
>                     ```
>
>                     class Point {
>                         constructor(x, y) {
>                             Object.assign(this, { x, y });
>                         }
>
>                         toString() {
>                             return `(${this.x}, ${this.y})`;
>                         }
>                     }
>
>                     Function.defineOperator('+', [Point, Point], (a, b) => new Point(a.x + b.x, a.y + b.y));
>
>                     ```
>
>                     The demo code made this flaw evident - it looks like
>                     a giant step backward to define an instance method
>                     like this, don't you agree?
>
>                     It's also apparent that the `@operator decorator`
>                     part of the proposal is an effort trying to address
>                     this issue, but it really is not the responsibility
>                     of the standard to try to define such a thing.
>
>                     What I'd suggest is that perhaps you should rethink
>                     your proposed syntax and redesign it to become an
>                     extension of the ES6 class definition syntax.
>
>                     Another thing is that, IMHO, currently there are too
>                     much quirks/conventions in the proposal that feel
>                     non-evident and non-flexible which is destined to
>                     trip people over from time to time. It would be
>                     great to make a proposal that's simple and don't
>                     include too much assumptions.
>
>                     Finally, I'm not sure about the current status of
>                     macros, but last I heard of it, they say it's going
>                     to make its way into the standard pretty soon (TM),
>                     and macros can do much of the things overloading
>                     could, and much more.
>
>                     On Sun, May 8, 2016 at 8:51 AM, Kevin Barabash
>                     <[hidden email]
>                     <mailto:[hidden email]>> wrote:
>
>                         I forgot to mention in my last email that I'm
>                         looking for a champion for this proposal.
>
>                         On Sat, May 7, 2016 at 5:24 PM, Kevin Barabash
>                         <[hidden email]
>                         <mailto:[hidden email]>> wrote:
>
>                             Hi everyone,
>
>                             I've been working on implementing operator
>                             overloading and would like to submit a proposal.
>
>                             I think operator overloading would be a
>                             useful addition to the language.  In
>                             particular I think it would be useful for
>                             defining operations on common mathematical
>                             object types such as complex numbers,
>                             vectors, matrices, and sets.
>
>                             I've create a working prototype that
>                             consists of:
>
>                               * babel plugin that rewrites operators as
>                                 function calls
>                               * a polyfill which defines these functions
>                                 and which call the correct
>                                 argument-specific function based on the
>                                 arguments' prototypes
>                               * Function.defineOperator which can be
>                                 used to define which function an
>                                 operator should use for the specified types
>                               * "use overloading" directive which allows
>                                 users to opt-in
>
>                             More details can be found
>                             at https://github.com/kevinbarabash/operator-overloading.
>                             The babel plugin can be found
>                             at https://github.com/kevinbarabash/babel-plugin-operator-overloading.
>                             I also have a demo project at
>                             https://github.com/kevinbarabash/operator-overloading-demo.
>
>                             The design was inspired by some of the
>                             slides from
>                             http://www.slideshare.net/BrendanEich/js-resp.
>
>                             – Kevin
>
>
>
>
>                         _______________________________________________
>                         es-discuss mailing list
>                         [hidden email]
>                         <mailto:[hidden email]>
>                         https://mail.mozilla.org/listinfo/es-discuss
>
>
>
>                     _______________________________________________
>                     es-discuss mailing list
>                     [hidden email] <mailto:[hidden email]>
>                     https://mail.mozilla.org/listinfo/es-discuss
>
>
>
>                 _______________________________________________
>                 es-discuss mailing list
>                 [hidden email] <mailto:[hidden email]>
>                 https://mail.mozilla.org/listinfo/es-discuss
>
>
>
>             _______________________________________________
>             es-discuss mailing list
>             [hidden email] <mailto:[hidden email]>
>             https://mail.mozilla.org/listinfo/es-discuss
>
>
>
>         _______________________________________________
>         es-discuss mailing list
>         [hidden email] <mailto:[hidden email]>
>         https://mail.mozilla.org/listinfo/es-discuss
>
>
>     _______________________________________________
>     es-discuss mailing list
>     [hidden email] <mailto:[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

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

Re: operator overloading proposal

kdex
@Isiah: Comparing your syntax proposal to `Function.defineOperator`, it appears to me that
overloading an operator multiple times (e. g. unary/binary plus operator) might become painful,
assuming that the semantics follow the same variadic approach that regular functions do.

That is, of course, unless you intend to handle all operator overloads in a single `operator +(...args) {}`
definition. But then again, something like `Function.defineOperator` seems cleaner and suggests implicit
(optional?) type checks with its second argument.

On Dienstag, 10. Mai 2016 15:25:32 CEST Isiah Meadows wrote:

> Here's my thought, if we go with syntax.
>
> ```js
> class Point {
>     // constructor, etc.
>
>     operator +(other) {
>         assert(other instanceof Point)
>         return new Point(
>             this.x + other.x,
>             this.y + other.y)
>     }
>
>     operator +=(other) {
>         assert(other instanceof Point)
>         this.x += other.x
>         this.y += other.y
>     }
> }
> ```
>
> On Tue, May 10, 2016, 11:16 Brian Barnes <[hidden email]> wrote:
>
> > A note on this from somebody who's entire existence seems dedicated to
> > stopping as much stuff as possible from getting GC'd, the example below:
> >
> >  >const u = new Point(5, 10);
> >  >const v = new Point(1, -2);
> >  >
> >  >const w = u + v;  // desugars to u[Symbol.add](v)
> >  >console.log(w);   // { x: 6, y: 8 };
> >
> > Could += be a special case?  i.e.,
> >
> > u+=v;
> >
> > would call:
> >
> > Class Point { ... other stuff ...
> > [whatever the syntax is](pt)
> > {
> > this.x+=pt.x;
> > this.y+=pt.y;
> > }
> > }
> >
> > instead of desugaring to:
> >
> > u=u+v;          // which would cause the creation of an object and
> >                 // leave the other to be collected
> >
> > For all I know, += might be doing such anyway in some engines, but for
> > my stuff which is a lot of 3D math that could be a performance killer.
> > It would be nice to be able to just add points and such, as long as the
> > overhead is negligible.
> >
> > [>] Brian
> >
> > On 5/10/2016 10:52 AM, Isiah Meadows wrote:
> > > I would prefer syntax + internal slots, since you'll know at creation
> > > time whether the object has overloaded operators. It's much simpler for
> > > the engine to figure out, and it's more performant because you only need
> > > to check one thing instead of worrying about inheritance, own
> > > properties, etc.
> > >
> > > Also, it would be IMHO easier to read than a symbol (the computed
> > > property syntax is ugly IMO). Using a different concept than symbols
> > > would also fit better with value types whenever any of those proposals
> > > make it into the language (either the struct or special syntax).
> > >
> > >
> > > On Tue, May 10, 2016, 04:03 G. Kay Lee
> > > <[hidden email]
> > > <mailto:balancetraveller%[hidden email]>> wrote:
> > >
> > >     Yes, I think exposing operators through well-known symbols is an
> > >     interesting idea worthy of more exploration because it's precisely
> > >     the purpose of well-known symbols to expose and allow manipulation
> > >     to previously inaccessible internal language behaviors.
> > >
> > >     On Tue, May 10, 2016 at 1:59 PM, Kevin Barabash
> > >     <[hidden email] <mailto:[hidden email]>> wrote:
> > >
> > >         > And remember that decorators are essentially just a syntax to
> > >         apply functions to objects/classes at design time, so what
> > >         you're proposing is essentially some new global function, which
> > >         is going against the current trend and effort to better
> > >         modularize/namespace all these utility functions/methods.
> > >
> > >         That's a really good point.
> > >
> > >         > It has been mentioned and discussed in numerous places over the
> > >         years, you can find more info on this with some casual googling.
> > >         For example:https://news.ycombinator.com/item?id=2983420
> > >
> > >         Thanks for the link.  I played around with sweet.js a bit over
> > >         the weekend.  Using macros should work if we went with Python
> > >         style operator overloading.  Instead of defining methods like
> > >         _ADD_, _SUB_ etc. we could create some well-known symbols, maybe
> > >         Symbol.plus, Symbol.times, etc.
> > >
> > >         ```
> > >         class Point {
> > >           constructor(x, y) {
> > >             Object.assign(this, {x, y});
> > >           }
> > >
> > >           [Symbol.add](other) {
> > >             return new Point(this.x + other.x, this.y + other.y);
> > >           }
> > >         }
> > >
> > >         const u = new Point(5, 10);
> > >         const v = new Point(1, -2);
> > >
> > >         const w = u + v;  // desugars to u[Symbol.add](v)
> > >         console.log(w);   // { x: 6, y: 8 };
> > >         ```
> > >
> > >         This would require default implementations to be defined on
> > >         Object.prototype for Symbol.plus, Symbol.times, etc.
> > >
> > >
> > >         On Sun, May 8, 2016 at 10:38 PM, G. Kay Lee
> > >         <[hidden email]
> > >         <mailto:[hidden email]>> wrote:
> > >
> > >             > Why not? The standard defines well-known symbols. Maybe
> > `@operator` could be a well known decorator (assuming decorators get
> > approved).
> > >
> > >             Well... you make something into the standard with proposals,
> > >             not why-nots, so in order to make that happen you need to
> > >             draft another proposal for well-known decorators. And
> > >             remember that decorators are essentially just a syntax to
> > >             apply functions to objects/classes at design time, so what
> > >             you're proposing is essentially some new global function,
> > >             which is going against the current trend and effort to
> > >             better modularize/namespace all these utility
> > >             functions/methods. And maybe a new mechanism could be
> > >             drafted for these new well-known decorators, so that we can
> > >             hide these new functions somewhere... but by now I hope it's
> > >             becoming clear that it's introducing way too much new
> > >             surface area for the language in exchange for one small
> > feature.
> > >
> > >             > I haven't seen any proposals for macros, could you post a
> > link?
> > >
> > >             It has been mentioned and discussed in numerous places over
> > >             the years, you can find more info on this with some casual
> > >             googling. For example:
> > >             https://news.ycombinator.com/item?id=2983420
> > >
> > >
> > >
> > >             On Sun, May 8, 2016 at 2:51 PM, Kevin Barabash
> > >             <[hidden email] <mailto:[hidden email]>>
> > wrote:
> > >
> > >                 I should update the demo code to show the `@operator`
> > >                 decorator in addition to `Function.defineOperator`.
> > >
> > >                 Initially I started out with just the `@operator`
> > >                 decorator, but that meant that each class would have to
> > >                 have knowledge of each of the classes it might want to
> > >                 interact with before hand.  Having a separate
> > >                 `defineOperator` function avoids this situation.
> > >
> > >                 It means that prototype style classes must be converted
> > >                 to the new class syntax before operator overloading
> > >                 could be used.  Lastly, there may be some cases where it
> > >                 makes sense to overload operators with existing 3rd
> > >                 party code or built-in classes, e.g. adding set
> > >                 operations to Set using operator overloading.
> > >
> > >                 > It's also apparent that the `@operator decorator` part
> > >                 of the proposal is an effort trying to address this
> > >                 issue, but it really is not the responsibility of the
> > >                 standard to try to define such a thing.
> > >
> > >                 Why not?  The standard defines well-known symbols.
> > >                 Maybe `@operator` could be a well known decorator
> > >                 (assuming decorators get approved).
> > >
> > >                 Slide 15
> > >                 from http://www.slideshare.net/BrendanEich/js-resp shows
> > >                 syntax for defining operators in value types which could
> > >                 be adapted as follows for regular classes:
> > >
> > >                 ```
> > >                 class Point {
> > >                    constructor(x, y) {
> > >                        this.x = +x;
> > >                        this.y = +y;
> > >                    }
> > >                    Point + Number (a, b) {
> > >                        return new Point(a.x + b, a.y + b);
> > >                    }
> > >                    Number + Point (a, b) {
> > >                        return new Point(a + b.x, a + b.y);
> > >                    }
> > >                    Point + Point (a, b) {
> > >                        return new Point(a.x + b.x, a.y + b.y);
> > >                    }
> > >                 }
> > >                 ```
> > >
> > >                 Having to define `+` twice for `Point + Number` and
> > >                 `Number + Point` seems like busy work, but maybe it's
> > >                 better to be explicit.  What are you thoughts about this
> > >                 syntax?
> > >
> > >                 > Another thing is that, IMHO, currently there are too
> > >                 much quirks/conventions in the proposal that feel
> > >                 non-evident and non-flexible which is destined to trip
> > >                 people over from time to time. It would be great to make
> > >                 a proposal that's simple and don't include too much
> > >                 assumptions.
> > >
> > >                 Could you elaborator what quirks/conventions might trip
> > >                 people up?
> > >
> > >                 > Finally, I'm not sure about the current status of
> > >                 macros, but last I heard of it, they say it's going to
> > >                 make its way into the standard pretty soon (TM), and
> > >                 macros can do much of the things overloading could, and
> > >                 much more.
> > >
> > >                 I haven't seen any proposals for macros, could you post
> > >                 a link?
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >                 On Sat, May 7, 2016 at 9:55 PM, G. Kay Lee
> > >                 <[hidden email]
> > >                 <mailto:[hidden email]>> wrote:
> > >
> > >                     I'd say it's way too early to ask for a champion on
> > >                     this because just a quick skimming revealed a lot of
> > >                     places that didn't add up. For example, the proposal
> > >                     suggested that overloading is primarily targeted at
> > >                     making it easier to work with user-defined classes,
> > >                     but curiously a `Function.defineOperator()` method
> > >                     is proposed instead of some syntax that feels more
> > >                     tightly integrated with the class definition syntax.
> > >
> > >                     ```
> > >
> > >                     class Point {
> > >                         constructor(x, y) {
> > >                             Object.assign(this, { x, y });
> > >                         }
> > >
> > >                         toString() {
> > >                             return `(${this.x}, ${this.y})`;
> > >                         }
> > >                     }
> > >
> > >                     Function.defineOperator('+', [Point, Point], (a, b)
> > => new Point(a.x + b.x, a.y + b.y));
> > >
> > >                     ```
> > >
> > >                     The demo code made this flaw evident - it looks like
> > >                     a giant step backward to define an instance method
> > >                     like this, don't you agree?
> > >
> > >                     It's also apparent that the `@operator decorator`
> > >                     part of the proposal is an effort trying to address
> > >                     this issue, but it really is not the responsibility
> > >                     of the standard to try to define such a thing.
> > >
> > >                     What I'd suggest is that perhaps you should rethink
> > >                     your proposed syntax and redesign it to become an
> > >                     extension of the ES6 class definition syntax.
> > >
> > >                     Another thing is that, IMHO, currently there are too
> > >                     much quirks/conventions in the proposal that feel
> > >                     non-evident and non-flexible which is destined to
> > >                     trip people over from time to time. It would be
> > >                     great to make a proposal that's simple and don't
> > >                     include too much assumptions.
> > >
> > >                     Finally, I'm not sure about the current status of
> > >                     macros, but last I heard of it, they say it's going
> > >                     to make its way into the standard pretty soon (TM),
> > >                     and macros can do much of the things overloading
> > >                     could, and much more.
> > >
> > >                     On Sun, May 8, 2016 at 8:51 AM, Kevin Barabash
> > >                     <[hidden email]
> > >                     <mailto:[hidden email]>> wrote:
> > >
> > >                         I forgot to mention in my last email that I'm
> > >                         looking for a champion for this proposal.
> > >
> > >                         On Sat, May 7, 2016 at 5:24 PM, Kevin Barabash
> > >                         <[hidden email]
> > >                         <mailto:[hidden email]>> wrote:
> > >
> > >                             Hi everyone,
> > >
> > >                             I've been working on implementing operator
> > >                             overloading and would like to submit a
> > proposal.
> > >
> > >                             I think operator overloading would be a
> > >                             useful addition to the language.  In
> > >                             particular I think it would be useful for
> > >                             defining operations on common mathematical
> > >                             object types such as complex numbers,
> > >                             vectors, matrices, and sets.
> > >
> > >                             I've create a working prototype that
> > >                             consists of:
> > >
> > >                               * babel plugin that rewrites operators as
> > >                                 function calls
> > >                               * a polyfill which defines these functions
> > >                                 and which call the correct
> > >                                 argument-specific function based on the
> > >                                 arguments' prototypes
> > >                               * Function.defineOperator which can be
> > >                                 used to define which function an
> > >                                 operator should use for the specified
> > types
> > >                               * "use overloading" directive which allows
> > >                                 users to opt-in
> > >
> > >                             More details can be found
> > >                             at
> > https://github.com/kevinbarabash/operator-overloading.
> > >                             The babel plugin can be found
> > >                             at
> > https://github.com/kevinbarabash/babel-plugin-operator-overloading.
> > >                             I also have a demo project at
> > >
> > https://github.com/kevinbarabash/operator-overloading-demo.
> > >
> > >                             The design was inspired by some of the
> > >                             slides from
> > >
> > http://www.slideshare.net/BrendanEich/js-resp.
> > >
> > >                             – Kevin
> > >
> > >
> > >
> > >
> > >                         _______________________________________________
> > >                         es-discuss mailing list
> > >                         [hidden email]
> > >                         <mailto:[hidden email]>
> > >                         https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >                     _______________________________________________
> > >                     es-discuss mailing list
> > >                     [hidden email] <mailto:
> > [hidden email]>
> > >                     https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >                 _______________________________________________
> > >                 es-discuss mailing list
> > >                 [hidden email] <mailto:[hidden email]>
> > >                 https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >             _______________________________________________
> > >             es-discuss mailing list
> > >             [hidden email] <mailto:[hidden email]>
> > >             https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >         _______________________________________________
> > >         es-discuss mailing list
> > >         [hidden email] <mailto:[hidden email]>
> > >         https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >     _______________________________________________
> > >     es-discuss mailing list
> > >     [hidden email] <mailto:[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
> >
>
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: operator overloading proposal

Isiah Meadows-2

You're correct in that the operator doesn't do any type checking (it dispatches from its first argument, but that's just traditional OO).


On Tue, May 10, 2016, 20:28 kdex <[hidden email]> wrote:
@Isiah: Comparing your syntax proposal to `Function.defineOperator`, it appears to me that
overloading an operator multiple times (e. g. unary/binary plus operator) might become painful,
assuming that the semantics follow the same variadic approach that regular functions do.

That is, of course, unless you intend to handle all operator overloads in a single `operator +(...args) {}`
definition. But then again, something like `Function.defineOperator` seems cleaner and suggests implicit
(optional?) type checks with its second argument.

On Dienstag, 10. Mai 2016 15:25:32 CEST Isiah Meadows wrote:
> Here's my thought, if we go with syntax.
>
> ```js
> class Point {
>     // constructor, etc.
>
>     operator +(other) {
>         assert(other instanceof Point)
>         return new Point(
>             this.x + other.x,
>             this.y + other.y)
>     }
>
>     operator +=(other) {
>         assert(other instanceof Point)
>         this.x += other.x
>         this.y += other.y
>     }
> }
> ```
>
> On Tue, May 10, 2016, 11:16 Brian Barnes <[hidden email]> wrote:
>
> > A note on this from somebody who's entire existence seems dedicated to
> > stopping as much stuff as possible from getting GC'd, the example below:
> >
> >  >const u = new Point(5, 10);
> >  >const v = new Point(1, -2);
> >  >
> >  >const w = u + v;  // desugars to u[Symbol.add](v)
> >  >console.log(w);   // { x: 6, y: 8 };
> >
> > Could += be a special case?  i.e.,
> >
> > u+=v;
> >
> > would call:
> >
> > Class Point { ... other stuff ...
> > [whatever the syntax is](pt)
> > {
> > this.x+=pt.x;
> > this.y+=pt.y;
> > }
> > }
> >
> > instead of desugaring to:
> >
> > u=u+v;          // which would cause the creation of an object and
> >                 // leave the other to be collected
> >
> > For all I know, += might be doing such anyway in some engines, but for
> > my stuff which is a lot of 3D math that could be a performance killer.
> > It would be nice to be able to just add points and such, as long as the
> > overhead is negligible.
> >
> > [>] Brian
> >
> > On 5/10/2016 10:52 AM, Isiah Meadows wrote:
> > > I would prefer syntax + internal slots, since you'll know at creation
> > > time whether the object has overloaded operators. It's much simpler for
> > > the engine to figure out, and it's more performant because you only need
> > > to check one thing instead of worrying about inheritance, own
> > > properties, etc.
> > >
> > > Also, it would be IMHO easier to read than a symbol (the computed
> > > property syntax is ugly IMO). Using a different concept than symbols
> > > would also fit better with value types whenever any of those proposals
> > > make it into the language (either the struct or special syntax).
> > >
> > >
> > > On Tue, May 10, 2016, 04:03 G. Kay Lee
> > > <[hidden email]
> > > <mailto:[hidden email]>> wrote:
> > >
> > >     Yes, I think exposing operators through well-known symbols is an
> > >     interesting idea worthy of more exploration because it's precisely
> > >     the purpose of well-known symbols to expose and allow manipulation
> > >     to previously inaccessible internal language behaviors.
> > >
> > >     On Tue, May 10, 2016 at 1:59 PM, Kevin Barabash
> > >     <[hidden email] <mailto:[hidden email]>> wrote:
> > >
> > >         > And remember that decorators are essentially just a syntax to
> > >         apply functions to objects/classes at design time, so what
> > >         you're proposing is essentially some new global function, which
> > >         is going against the current trend and effort to better
> > >         modularize/namespace all these utility functions/methods.
> > >
> > >         That's a really good point.
> > >
> > >         > It has been mentioned and discussed in numerous places over the
> > >         years, you can find more info on this with some casual googling.
> > >         For example:https://news.ycombinator.com/item?id=2983420
> > >
> > >         Thanks for the link.  I played around with sweet.js a bit over
> > >         the weekend.  Using macros should work if we went with Python
> > >         style operator overloading.  Instead of defining methods like
> > >         _ADD_, _SUB_ etc. we could create some well-known symbols, maybe
> > >         Symbol.plus, Symbol.times, etc.
> > >
> > >         ```
> > >         class Point {
> > >           constructor(x, y) {
> > >             Object.assign(this, {x, y});
> > >           }
> > >
> > >           [Symbol.add](other) {
> > >             return new Point(this.x + other.x, this.y + other.y);
> > >           }
> > >         }
> > >
> > >         const u = new Point(5, 10);
> > >         const v = new Point(1, -2);
> > >
> > >         const w = u + v;  // desugars to u[Symbol.add](v)
> > >         console.log(w);   // { x: 6, y: 8 };
> > >         ```
> > >
> > >         This would require default implementations to be defined on
> > >         Object.prototype for Symbol.plus, Symbol.times, etc.
> > >
> > >
> > >         On Sun, May 8, 2016 at 10:38 PM, G. Kay Lee
> > >         <[hidden email]
> > >         <mailto:[hidden email]>> wrote:
> > >
> > >             > Why not? The standard defines well-known symbols. Maybe
> > `@operator` could be a well known decorator (assuming decorators get
> > approved).
> > >
> > >             Well... you make something into the standard with proposals,
> > >             not why-nots, so in order to make that happen you need to
> > >             draft another proposal for well-known decorators. And
> > >             remember that decorators are essentially just a syntax to
> > >             apply functions to objects/classes at design time, so what
> > >             you're proposing is essentially some new global function,
> > >             which is going against the current trend and effort to
> > >             better modularize/namespace all these utility
> > >             functions/methods. And maybe a new mechanism could be
> > >             drafted for these new well-known decorators, so that we can
> > >             hide these new functions somewhere... but by now I hope it's
> > >             becoming clear that it's introducing way too much new
> > >             surface area for the language in exchange for one small
> > feature.
> > >
> > >             > I haven't seen any proposals for macros, could you post a
> > link?
> > >
> > >             It has been mentioned and discussed in numerous places over
> > >             the years, you can find more info on this with some casual
> > >             googling. For example:
> > >             https://news.ycombinator.com/item?id=2983420
> > >
> > >
> > >
> > >             On Sun, May 8, 2016 at 2:51 PM, Kevin Barabash
> > >             <[hidden email] <mailto:[hidden email]>>
> > wrote:
> > >
> > >                 I should update the demo code to show the `@operator`
> > >                 decorator in addition to `Function.defineOperator`.
> > >
> > >                 Initially I started out with just the `@operator`
> > >                 decorator, but that meant that each class would have to
> > >                 have knowledge of each of the classes it might want to
> > >                 interact with before hand.  Having a separate
> > >                 `defineOperator` function avoids this situation.
> > >
> > >                 It means that prototype style classes must be converted
> > >                 to the new class syntax before operator overloading
> > >                 could be used.  Lastly, there may be some cases where it
> > >                 makes sense to overload operators with existing 3rd
> > >                 party code or built-in classes, e.g. adding set
> > >                 operations to Set using operator overloading.
> > >
> > >                 > It's also apparent that the `@operator decorator` part
> > >                 of the proposal is an effort trying to address this
> > >                 issue, but it really is not the responsibility of the
> > >                 standard to try to define such a thing.
> > >
> > >                 Why not?  The standard defines well-known symbols.
> > >                 Maybe `@operator` could be a well known decorator
> > >                 (assuming decorators get approved).
> > >
> > >                 Slide 15
> > >                 from http://www.slideshare.net/BrendanEich/js-resp shows
> > >                 syntax for defining operators in value types which could
> > >                 be adapted as follows for regular classes:
> > >
> > >                 ```
> > >                 class Point {
> > >                    constructor(x, y) {
> > >                        this.x = +x;
> > >                        this.y = +y;
> > >                    }
> > >                    Point + Number (a, b) {
> > >                        return new Point(a.x + b, a.y + b);
> > >                    }
> > >                    Number + Point (a, b) {
> > >                        return new Point(a + b.x, a + b.y);
> > >                    }
> > >                    Point + Point (a, b) {
> > >                        return new Point(a.x + b.x, a.y + b.y);
> > >                    }
> > >                 }
> > >                 ```
> > >
> > >                 Having to define `+` twice for `Point + Number` and
> > >                 `Number + Point` seems like busy work, but maybe it's
> > >                 better to be explicit.  What are you thoughts about this
> > >                 syntax?
> > >
> > >                 > Another thing is that, IMHO, currently there are too
> > >                 much quirks/conventions in the proposal that feel
> > >                 non-evident and non-flexible which is destined to trip
> > >                 people over from time to time. It would be great to make
> > >                 a proposal that's simple and don't include too much
> > >                 assumptions.
> > >
> > >                 Could you elaborator what quirks/conventions might trip
> > >                 people up?
> > >
> > >                 > Finally, I'm not sure about the current status of
> > >                 macros, but last I heard of it, they say it's going to
> > >                 make its way into the standard pretty soon (TM), and
> > >                 macros can do much of the things overloading could, and
> > >                 much more.
> > >
> > >                 I haven't seen any proposals for macros, could you post
> > >                 a link?
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >                 On Sat, May 7, 2016 at 9:55 PM, G. Kay Lee
> > >                 <[hidden email]
> > >                 <mailto:[hidden email]>> wrote:
> > >
> > >                     I'd say it's way too early to ask for a champion on
> > >                     this because just a quick skimming revealed a lot of
> > >                     places that didn't add up. For example, the proposal
> > >                     suggested that overloading is primarily targeted at
> > >                     making it easier to work with user-defined classes,
> > >                     but curiously a `Function.defineOperator()` method
> > >                     is proposed instead of some syntax that feels more
> > >                     tightly integrated with the class definition syntax.
> > >
> > >                     ```
> > >
> > >                     class Point {
> > >                         constructor(x, y) {
> > >                             Object.assign(this, { x, y });
> > >                         }
> > >
> > >                         toString() {
> > >                             return `(${this.x}, ${this.y})`;
> > >                         }
> > >                     }
> > >
> > >                     Function.defineOperator('+', [Point, Point], (a, b)
> > => new Point(a.x + b.x, a.y + b.y));
> > >
> > >                     ```
> > >
> > >                     The demo code made this flaw evident - it looks like
> > >                     a giant step backward to define an instance method
> > >                     like this, don't you agree?
> > >
> > >                     It's also apparent that the `@operator decorator`
> > >                     part of the proposal is an effort trying to address
> > >                     this issue, but it really is not the responsibility
> > >                     of the standard to try to define such a thing.
> > >
> > >                     What I'd suggest is that perhaps you should rethink
> > >                     your proposed syntax and redesign it to become an
> > >                     extension of the ES6 class definition syntax.
> > >
> > >                     Another thing is that, IMHO, currently there are too
> > >                     much quirks/conventions in the proposal that feel
> > >                     non-evident and non-flexible which is destined to
> > >                     trip people over from time to time. It would be
> > >                     great to make a proposal that's simple and don't
> > >                     include too much assumptions.
> > >
> > >                     Finally, I'm not sure about the current status of
> > >                     macros, but last I heard of it, they say it's going
> > >                     to make its way into the standard pretty soon (TM),
> > >                     and macros can do much of the things overloading
> > >                     could, and much more.
> > >
> > >                     On Sun, May 8, 2016 at 8:51 AM, Kevin Barabash
> > >                     <[hidden email]
> > >                     <mailto:[hidden email]>> wrote:
> > >
> > >                         I forgot to mention in my last email that I'm
> > >                         looking for a champion for this proposal.
> > >
> > >                         On Sat, May 7, 2016 at 5:24 PM, Kevin Barabash
> > >                         <[hidden email]
> > >                         <mailto:[hidden email]>> wrote:
> > >
> > >                             Hi everyone,
> > >
> > >                             I've been working on implementing operator
> > >                             overloading and would like to submit a
> > proposal.
> > >
> > >                             I think operator overloading would be a
> > >                             useful addition to the language.  In
> > >                             particular I think it would be useful for
> > >                             defining operations on common mathematical
> > >                             object types such as complex numbers,
> > >                             vectors, matrices, and sets.
> > >
> > >                             I've create a working prototype that
> > >                             consists of:
> > >
> > >                               * babel plugin that rewrites operators as
> > >                                 function calls
> > >                               * a polyfill which defines these functions
> > >                                 and which call the correct
> > >                                 argument-specific function based on the
> > >                                 arguments' prototypes
> > >                               * Function.defineOperator which can be
> > >                                 used to define which function an
> > >                                 operator should use for the specified
> > types
> > >                               * "use overloading" directive which allows
> > >                                 users to opt-in
> > >
> > >                             More details can be found
> > >                             at
> > https://github.com/kevinbarabash/operator-overloading.
> > >                             The babel plugin can be found
> > >                             at
> > https://github.com/kevinbarabash/babel-plugin-operator-overloading.
> > >                             I also have a demo project at
> > >
> > https://github.com/kevinbarabash/operator-overloading-demo.
> > >
> > >                             The design was inspired by some of the
> > >                             slides from
> > >
> > http://www.slideshare.net/BrendanEich/js-resp.
> > >
> > >                             – Kevin
> > >
> > >
> > >
> > >
> > >                         _______________________________________________
> > >                         es-discuss mailing list
> > >                         [hidden email]
> > >                         <mailto:[hidden email]>
> > >                         https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >                     _______________________________________________
> > >                     es-discuss mailing list
> > >                     [hidden email] <mailto:
> > [hidden email]>
> > >                     https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >                 _______________________________________________
> > >                 es-discuss mailing list
> > >                 [hidden email] <mailto:[hidden email]>
> > >                 https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >             _______________________________________________
> > >             es-discuss mailing list
> > >             [hidden email] <mailto:[hidden email]>
> > >             https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >         _______________________________________________
> > >         es-discuss mailing list
> > >         [hidden email] <mailto:[hidden email]>
> > >         https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >     _______________________________________________
> > >     es-discuss mailing list
> > >     [hidden email] <mailto:[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
> >
>

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

Re: operator overloading proposal

Kevin Barabash
I would prefer syntax + internal slots, since you'll know at creation time whether the object has overloaded 
> operators. It's much simpler for the engine to figure out, and it's more performant because you only need to 
> check one thing instead of worrying about inheritance, own properties, etc.

Will operators defined on a class work with instances of a subclass?

Could += be a special case? i.e.,

For sure.  We could define `Symbol.assignPlus`, `Symbol.assignTimes`, etc. with `u += v;` desugaring to `u = u[Symbol.assignPlus](v)`.  The reason why we can't do something do `u[Symbol.assignPlus](v)` is that there's no way to define a method on Number, String, etc. that would reassign their value.

it appears to me that overloading an operator multiple times (e. g. unary/binary plus operator) might become 
> painful, assuming that the semantics follow the same variadic approach that regular functions do.

Another pain point is handling cases where you want one class to interoperate with another.  In one of the example above methods are defined that allow `Point`s and `Number`s to be added to each other.  In order to maintain the commutativity of `+` we need to define `operator+` / `[Symbol.add]` methods on both `Point` and `Number`.  One potential solution to this problem is create `Symbol.plusRight`, `Symbol.timesRight` for all of the commutative/symmetric operators.  

I feel like this ends up making things more complex because there are more methods to implement and the methods have to be more complex b/c they have to do type checking when overloaded.

Maybe `operator+` could work like the `@operator` decorator by calling `Function.defineOperator` behind the scenes.  In this situation, instead of methods being added to classes, the `Function` object has well-defined methods that look up the correct function to call based on the argument types.  `u + v` desugars to `Function[Symbol.plus](u, v)`.  This is definitely slower than internal slots, but if we're doing runtime type checking in the method we may as well have it be automatic.  My hope is to eventually use static typing (flow b/c I'm using babel) to remove the lookup cost.
 

On Tue, May 10, 2016 at 7:07 PM, Isiah Meadows <[hidden email]> wrote:

You're correct in that the operator doesn't do any type checking (it dispatches from its first argument, but that's just traditional OO).


On Tue, May 10, 2016, 20:28 kdex <[hidden email]> wrote:
@Isiah: Comparing your syntax proposal to `Function.defineOperator`, it appears to me that
overloading an operator multiple times (e. g. unary/binary plus operator) might become painful,
assuming that the semantics follow the same variadic approach that regular functions do.

That is, of course, unless you intend to handle all operator overloads in a single `operator +(...args) {}`
definition. But then again, something like `Function.defineOperator` seems cleaner and suggests implicit
(optional?) type checks with its second argument.

On Dienstag, 10. Mai 2016 15:25:32 CEST Isiah Meadows wrote:
> Here's my thought, if we go with syntax.
>
> ```js
> class Point {
>     // constructor, etc.
>
>     operator +(other) {
>         assert(other instanceof Point)
>         return new Point(
>             this.x + other.x,
>             this.y + other.y)
>     }
>
>     operator +=(other) {
>         assert(other instanceof Point)
>         this.x += other.x
>         this.y += other.y
>     }
> }
> ```
>
> On Tue, May 10, 2016, 11:16 Brian Barnes <[hidden email]> wrote:
>
> > A note on this from somebody who's entire existence seems dedicated to
> > stopping as much stuff as possible from getting GC'd, the example below:
> >
> >  >const u = new Point(5, 10);
> >  >const v = new Point(1, -2);
> >  >
> >  >const w = u + v;  // desugars to u[Symbol.add](v)
> >  >console.log(w);   // { x: 6, y: 8 };
> >
> > Could += be a special case?  i.e.,
> >
> > u+=v;
> >
> > would call:
> >
> > Class Point { ... other stuff ...
> > [whatever the syntax is](pt)
> > {
> > this.x+=pt.x;
> > this.y+=pt.y;
> > }
> > }
> >
> > instead of desugaring to:
> >
> > u=u+v;          // which would cause the creation of an object and
> >                 // leave the other to be collected
> >
> > For all I know, += might be doing such anyway in some engines, but for
> > my stuff which is a lot of 3D math that could be a performance killer.
> > It would be nice to be able to just add points and such, as long as the
> > overhead is negligible.
> >
> > [>] Brian
> >
> > On 5/10/2016 10:52 AM, Isiah Meadows wrote:
> > > I would prefer syntax + internal slots, since you'll know at creation
> > > time whether the object has overloaded operators. It's much simpler for
> > > the engine to figure out, and it's more performant because you only need
> > > to check one thing instead of worrying about inheritance, own
> > > properties, etc.
> > >
> > > Also, it would be IMHO easier to read than a symbol (the computed
> > > property syntax is ugly IMO). Using a different concept than symbols
> > > would also fit better with value types whenever any of those proposals
> > > make it into the language (either the struct or special syntax).
> > >
> > >
> > > On Tue, May 10, 2016, 04:03 G. Kay Lee
> > > <[hidden email]
> > > <mailto:[hidden email]>> wrote:
> > >
> > >     Yes, I think exposing operators through well-known symbols is an
> > >     interesting idea worthy of more exploration because it's precisely
> > >     the purpose of well-known symbols to expose and allow manipulation
> > >     to previously inaccessible internal language behaviors.
> > >
> > >     On Tue, May 10, 2016 at 1:59 PM, Kevin Barabash
> > >     <[hidden email] <mailto:[hidden email]>> wrote:
> > >
> > >         > And remember that decorators are essentially just a syntax to
> > >         apply functions to objects/classes at design time, so what
> > >         you're proposing is essentially some new global function, which
> > >         is going against the current trend and effort to better
> > >         modularize/namespace all these utility functions/methods.
> > >
> > >         That's a really good point.
> > >
> > >         > It has been mentioned and discussed in numerous places over the
> > >         years, you can find more info on this with some casual googling.
> > >         For example:https://news.ycombinator.com/item?id=2983420
> > >
> > >         Thanks for the link.  I played around with sweet.js a bit over
> > >         the weekend.  Using macros should work if we went with Python
> > >         style operator overloading.  Instead of defining methods like
> > >         _ADD_, _SUB_ etc. we could create some well-known symbols, maybe
> > >         Symbol.plus, Symbol.times, etc.
> > >
> > >         ```
> > >         class Point {
> > >           constructor(x, y) {
> > >             Object.assign(this, {x, y});
> > >           }
> > >
> > >           [Symbol.add](other) {
> > >             return new Point(this.x + other.x, this.y + other.y);
> > >           }
> > >         }
> > >
> > >         const u = new Point(5, 10);
> > >         const v = new Point(1, -2);
> > >
> > >         const w = u + v;  // desugars to u[Symbol.add](v)
> > >         console.log(w);   // { x: 6, y: 8 };
> > >         ```
> > >
> > >         This would require default implementations to be defined on
> > >         Object.prototype for Symbol.plus, Symbol.times, etc.
> > >
> > >
> > >         On Sun, May 8, 2016 at 10:38 PM, G. Kay Lee
> > >         <[hidden email]
> > >         <mailto:[hidden email]>> wrote:
> > >
> > >             > Why not? The standard defines well-known symbols. Maybe
> > `@operator` could be a well known decorator (assuming decorators get
> > approved).
> > >
> > >             Well... you make something into the standard with proposals,
> > >             not why-nots, so in order to make that happen you need to
> > >             draft another proposal for well-known decorators. And
> > >             remember that decorators are essentially just a syntax to
> > >             apply functions to objects/classes at design time, so what
> > >             you're proposing is essentially some new global function,
> > >             which is going against the current trend and effort to
> > >             better modularize/namespace all these utility
> > >             functions/methods. And maybe a new mechanism could be
> > >             drafted for these new well-known decorators, so that we can
> > >             hide these new functions somewhere... but by now I hope it's
> > >             becoming clear that it's introducing way too much new
> > >             surface area for the language in exchange for one small
> > feature.
> > >
> > >             > I haven't seen any proposals for macros, could you post a
> > link?
> > >
> > >             It has been mentioned and discussed in numerous places over
> > >             the years, you can find more info on this with some casual
> > >             googling. For example:
> > >             https://news.ycombinator.com/item?id=2983420
> > >
> > >
> > >
> > >             On Sun, May 8, 2016 at 2:51 PM, Kevin Barabash
> > >             <[hidden email] <mailto:[hidden email]>>
> > wrote:
> > >
> > >                 I should update the demo code to show the `@operator`
> > >                 decorator in addition to `Function.defineOperator`.
> > >
> > >                 Initially I started out with just the `@operator`
> > >                 decorator, but that meant that each class would have to
> > >                 have knowledge of each of the classes it might want to
> > >                 interact with before hand.  Having a separate
> > >                 `defineOperator` function avoids this situation.
> > >
> > >                 It means that prototype style classes must be converted
> > >                 to the new class syntax before operator overloading
> > >                 could be used.  Lastly, there may be some cases where it
> > >                 makes sense to overload operators with existing 3rd
> > >                 party code or built-in classes, e.g. adding set
> > >                 operations to Set using operator overloading.
> > >
> > >                 > It's also apparent that the `@operator decorator` part
> > >                 of the proposal is an effort trying to address this
> > >                 issue, but it really is not the responsibility of the
> > >                 standard to try to define such a thing.
> > >
> > >                 Why not?  The standard defines well-known symbols.
> > >                 Maybe `@operator` could be a well known decorator
> > >                 (assuming decorators get approved).
> > >
> > >                 Slide 15
> > >                 from http://www.slideshare.net/BrendanEich/js-resp shows
> > >                 syntax for defining operators in value types which could
> > >                 be adapted as follows for regular classes:
> > >
> > >                 ```
> > >                 class Point {
> > >                    constructor(x, y) {
> > >                        this.x = +x;
> > >                        this.y = +y;
> > >                    }
> > >                    Point + Number (a, b) {
> > >                        return new Point(a.x + b, a.y + b);
> > >                    }
> > >                    Number + Point (a, b) {
> > >                        return new Point(a + b.x, a + b.y);
> > >                    }
> > >                    Point + Point (a, b) {
> > >                        return new Point(a.x + b.x, a.y + b.y);
> > >                    }
> > >                 }
> > >                 ```
> > >
> > >                 Having to define `+` twice for `Point + Number` and
> > >                 `Number + Point` seems like busy work, but maybe it's
> > >                 better to be explicit.  What are you thoughts about this
> > >                 syntax?
> > >
> > >                 > Another thing is that, IMHO, currently there are too
> > >                 much quirks/conventions in the proposal that feel
> > >                 non-evident and non-flexible which is destined to trip
> > >                 people over from time to time. It would be great to make
> > >                 a proposal that's simple and don't include too much
> > >                 assumptions.
> > >
> > >                 Could you elaborator what quirks/conventions might trip
> > >                 people up?
> > >
> > >                 > Finally, I'm not sure about the current status of
> > >                 macros, but last I heard of it, they say it's going to
> > >                 make its way into the standard pretty soon (TM), and
> > >                 macros can do much of the things overloading could, and
> > >                 much more.
> > >
> > >                 I haven't seen any proposals for macros, could you post
> > >                 a link?
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >                 On Sat, May 7, 2016 at 9:55 PM, G. Kay Lee
> > >                 <[hidden email]
> > >                 <mailto:[hidden email]>> wrote:
> > >
> > >                     I'd say it's way too early to ask for a champion on
> > >                     this because just a quick skimming revealed a lot of
> > >                     places that didn't add up. For example, the proposal
> > >                     suggested that overloading is primarily targeted at
> > >                     making it easier to work with user-defined classes,
> > >                     but curiously a `Function.defineOperator()` method
> > >                     is proposed instead of some syntax that feels more
> > >                     tightly integrated with the class definition syntax.
> > >
> > >                     ```
> > >
> > >                     class Point {
> > >                         constructor(x, y) {
> > >                             Object.assign(this, { x, y });
> > >                         }
> > >
> > >                         toString() {
> > >                             return `(${this.x}, ${this.y})`;
> > >                         }
> > >                     }
> > >
> > >                     Function.defineOperator('+', [Point, Point], (a, b)
> > => new Point(a.x + b.x, a.y + b.y));
> > >
> > >                     ```
> > >
> > >                     The demo code made this flaw evident - it looks like
> > >                     a giant step backward to define an instance method
> > >                     like this, don't you agree?
> > >
> > >                     It's also apparent that the `@operator decorator`
> > >                     part of the proposal is an effort trying to address
> > >                     this issue, but it really is not the responsibility
> > >                     of the standard to try to define such a thing.
> > >
> > >                     What I'd suggest is that perhaps you should rethink
> > >                     your proposed syntax and redesign it to become an
> > >                     extension of the ES6 class definition syntax.
> > >
> > >                     Another thing is that, IMHO, currently there are too
> > >                     much quirks/conventions in the proposal that feel
> > >                     non-evident and non-flexible which is destined to
> > >                     trip people over from time to time. It would be
> > >                     great to make a proposal that's simple and don't
> > >                     include too much assumptions.
> > >
> > >                     Finally, I'm not sure about the current status of
> > >                     macros, but last I heard of it, they say it's going
> > >                     to make its way into the standard pretty soon (TM),
> > >                     and macros can do much of the things overloading
> > >                     could, and much more.
> > >
> > >                     On Sun, May 8, 2016 at 8:51 AM, Kevin Barabash
> > >                     <[hidden email]
> > >                     <mailto:[hidden email]>> wrote:
> > >
> > >                         I forgot to mention in my last email that I'm
> > >                         looking for a champion for this proposal.
> > >
> > >                         On Sat, May 7, 2016 at 5:24 PM, Kevin Barabash
> > >                         <[hidden email]
> > >                         <mailto:[hidden email]>> wrote:
> > >
> > >                             Hi everyone,
> > >
> > >                             I've been working on implementing operator
> > >                             overloading and would like to submit a
> > proposal.
> > >
> > >                             I think operator overloading would be a
> > >                             useful addition to the language.  In
> > >                             particular I think it would be useful for
> > >                             defining operations on common mathematical
> > >                             object types such as complex numbers,
> > >                             vectors, matrices, and sets.
> > >
> > >                             I've create a working prototype that
> > >                             consists of:
> > >
> > >                               * babel plugin that rewrites operators as
> > >                                 function calls
> > >                               * a polyfill which defines these functions
> > >                                 and which call the correct
> > >                                 argument-specific function based on the
> > >                                 arguments' prototypes
> > >                               * Function.defineOperator which can be
> > >                                 used to define which function an
> > >                                 operator should use for the specified
> > types
> > >                               * "use overloading" directive which allows
> > >                                 users to opt-in
> > >
> > >                             More details can be found
> > >                             at
> > https://github.com/kevinbarabash/operator-overloading.
> > >                             The babel plugin can be found
> > >                             at
> > https://github.com/kevinbarabash/babel-plugin-operator-overloading.
> > >                             I also have a demo project at
> > >
> > https://github.com/kevinbarabash/operator-overloading-demo.
> > >
> > >                             The design was inspired by some of the
> > >                             slides from
> > >
> > http://www.slideshare.net/BrendanEich/js-resp.
> > >
> > >                             – Kevin
> > >
> > >
> > >
> > >
> > >                         _______________________________________________
> > >                         es-discuss mailing list
> > >                         [hidden email]
> > >                         <mailto:[hidden email]>
> > >                         https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >                     _______________________________________________
> > >                     es-discuss mailing list
> > >                     [hidden email] <mailto:
> > [hidden email]>
> > >                     https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >                 _______________________________________________
> > >                 es-discuss mailing list
> > >                 [hidden email] <mailto:[hidden email]>
> > >                 https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >             _______________________________________________
> > >             es-discuss mailing list
> > >             [hidden email] <mailto:[hidden email]>
> > >             https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >         _______________________________________________
> > >         es-discuss mailing list
> > >         [hidden email] <mailto:[hidden email]>
> > >         https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >     _______________________________________________
> > >     es-discuss mailing list
> > >     [hidden email] <mailto:[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
> >
>

_______________________________________________
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: operator overloading proposal

Isiah Meadows-2
1. Yes, they would be inherited, but not on the prototype itself (it would technically be parasitic). It would be modeled with internal slots, so that the properties are themselves immutable and transparent, so the only way to inherit would be via the class syntax or `Reflect.construct`. Engines could model this similarly to prototypes internally, while still appearing to conform to spec, since there's no other way to access the function without explicit reference via a decorator. And if it's not decorated, you can transparently fast path the calls automatically and optimize the function at compile time for exactly the number of arguments (any different is a syntax error, like with getters and setters). 

2. I'm intentionally trying to avoid any semantics that would rely on adding more values to the global scope. First, it's harder to optimize a `hasOwnProperty` check. Second, when you allow properties to be dynamically added, you make it impossible to lower `foo + bar` to a single instruction if they're both numbers, because someone can change the Number prototype to have one of the operators on it, and now, the assumption, previously prevalent, is now invalid. Third, we shouldn't need to add 15+ new symbols to accommodate a simple operation. 

3. If it's pure syntax, you won't have the edge cases of `x += y` having to desugar to `x = x[Symbol.assignPlus](y)` and so on. You just look for an `[[OpAssignPlus]]` on `x`, and if it exists, call it as `x.[[OpAssignPlus]](y)`. Else, you check for `[[OpPlus]]`, and set `x` to `x.[[OpPlus]](y)`. If neither exists, you fall back to the old algorithm. This can be easily optimized by the fact engines only need to check this if the value is an object. Numbers and strings don't have this slot. 

Note: If the right side has an operator defined, but the left side doesn't, and if the operator checked for isn't an assignment one, the right side's operator is checked and called. Or basically, beyond assignment, the mere existence of a slot takes precedence over no slot, to make transitivity easier with primitives. To clarify, in the below case:

```js
class C {
    constructor(x) { this.x = x }
    operator +(x) {
        if (x instanceof C) {
            return this + x.x * 2
        }
        return this.x + x
    }
}

assert(new C(1) + 1 === 1 +1)
assert(1 + new C(1) === 1 + 1)
assert(new C(1) + new C(2) === 1 + 2*2)
assert(new C(2) + new C(1) === 2 + 1*2)
```

On Wed, May 11, 2016, 01:27 Kevin Barabash <[hidden email]> wrote:
I would prefer syntax + internal slots, since you'll know at creation time whether the object has overloaded 
> operators. It's much simpler for the engine to figure out, and it's more performant because you only need to 
> check one thing instead of worrying about inheritance, own properties, etc.

Will operators defined on a class work with instances of a subclass?

Could += be a special case? i.e.,

For sure.  We could define `Symbol.assignPlus`, `Symbol.assignTimes`, etc. with `u += v;` desugaring to `u = u[Symbol.assignPlus](v)`.  The reason why we can't do something do `u[Symbol.assignPlus](v)` is that there's no way to define a method on Number, String, etc. that would reassign their value.

it appears to me that overloading an operator multiple times (e. g. unary/binary plus operator) might become 
> painful, assuming that the semantics follow the same variadic approach that regular functions do.

Another pain point is handling cases where you want one class to interoperate with another.  In one of the example above methods are defined that allow `Point`s and `Number`s to be added to each other.  In order to maintain the commutativity of `+` we need to define `operator+` / `[Symbol.add]` methods on both `Point` and `Number`.  One potential solution to this problem is create `Symbol.plusRight`, `Symbol.timesRight` for all of the commutative/symmetric operators.  

I feel like this ends up making things more complex because there are more methods to implement and the methods have to be more complex b/c they have to do type checking when overloaded.

Maybe `operator+` could work like the `@operator` decorator by calling `Function.defineOperator` behind the scenes.  In this situation, instead of methods being added to classes, the `Function` object has well-defined methods that look up the correct function to call based on the argument types.  `u + v` desugars to `Function[Symbol.plus](u, v)`.  This is definitely slower than internal slots, but if we're doing runtime type checking in the method we may as well have it be automatic.  My hope is to eventually use static typing (flow b/c I'm using babel) to remove the lookup cost.
 

On Tue, May 10, 2016 at 7:07 PM, Isiah Meadows <[hidden email]> wrote:

You're correct in that the operator doesn't do any type checking (it dispatches from its first argument, but that's just traditional OO).


On Tue, May 10, 2016, 20:28 kdex <[hidden email]> wrote:
@Isiah: Comparing your syntax proposal to `Function.defineOperator`, it appears to me that
overloading an operator multiple times (e. g. unary/binary plus operator) might become painful,
assuming that the semantics follow the same variadic approach that regular functions do.

That is, of course, unless you intend to handle all operator overloads in a single `operator +(...args) {}`
definition. But then again, something like `Function.defineOperator` seems cleaner and suggests implicit
(optional?) type checks with its second argument.

On Dienstag, 10. Mai 2016 15:25:32 CEST Isiah Meadows wrote:
> Here's my thought, if we go with syntax.
>
> ```js
> class Point {
>     // constructor, etc.
>
>     operator +(other) {
>         assert(other instanceof Point)
>         return new Point(
>             this.x + other.x,
>             this.y + other.y)
>     }
>
>     operator +=(other) {
>         assert(other instanceof Point)
>         this.x += other.x
>         this.y += other.y
>     }
> }
> ```
>
> On Tue, May 10, 2016, 11:16 Brian Barnes <[hidden email]> wrote:
>
> > A note on this from somebody who's entire existence seems dedicated to
> > stopping as much stuff as possible from getting GC'd, the example below:
> >
> >  >const u = new Point(5, 10);
> >  >const v = new Point(1, -2);
> >  >
> >  >const w = u + v;  // desugars to u[Symbol.add](v)
> >  >console.log(w);   // { x: 6, y: 8 };
> >
> > Could += be a special case?  i.e.,
> >
> > u+=v;
> >
> > would call:
> >
> > Class Point { ... other stuff ...
> > [whatever the syntax is](pt)
> > {
> > this.x+=pt.x;
> > this.y+=pt.y;
> > }
> > }
> >
> > instead of desugaring to:
> >
> > u=u+v;          // which would cause the creation of an object and
> >                 // leave the other to be collected
> >
> > For all I know, += might be doing such anyway in some engines, but for
> > my stuff which is a lot of 3D math that could be a performance killer.
> > It would be nice to be able to just add points and such, as long as the
> > overhead is negligible.
> >
> > [>] Brian
> >
> > On 5/10/2016 10:52 AM, Isiah Meadows wrote:
> > > I would prefer syntax + internal slots, since you'll know at creation
> > > time whether the object has overloaded operators. It's much simpler for
> > > the engine to figure out, and it's more performant because you only need
> > > to check one thing instead of worrying about inheritance, own
> > > properties, etc.
> > >
> > > Also, it would be IMHO easier to read than a symbol (the computed
> > > property syntax is ugly IMO). Using a different concept than symbols
> > > would also fit better with value types whenever any of those proposals
> > > make it into the language (either the struct or special syntax).
> > >
> > >
> > > On Tue, May 10, 2016, 04:03 G. Kay Lee
> > > <[hidden email]
> > > <mailto:[hidden email]>> wrote:
> > >
> > >     Yes, I think exposing operators through well-known symbols is an
> > >     interesting idea worthy of more exploration because it's precisely
> > >     the purpose of well-known symbols to expose and allow manipulation
> > >     to previously inaccessible internal language behaviors.
> > >
> > >     On Tue, May 10, 2016 at 1:59 PM, Kevin Barabash
> > >     <[hidden email] <mailto:[hidden email]>> wrote:
> > >
> > >         > And remember that decorators are essentially just a syntax to
> > >         apply functions to objects/classes at design time, so what
> > >         you're proposing is essentially some new global function, which
> > >         is going against the current trend and effort to better
> > >         modularize/namespace all these utility functions/methods.
> > >
> > >         That's a really good point.
> > >
> > >         > It has been mentioned and discussed in numerous places over the
> > >         years, you can find more info on this with some casual googling.
> > >         For example:https://news.ycombinator.com/item?id=2983420
> > >
> > >         Thanks for the link.  I played around with sweet.js a bit over
> > >         the weekend.  Using macros should work if we went with Python
> > >         style operator overloading.  Instead of defining methods like
> > >         _ADD_, _SUB_ etc. we could create some well-known symbols, maybe
> > >         Symbol.plus, Symbol.times, etc.
> > >
> > >         ```
> > >         class Point {
> > >           constructor(x, y) {
> > >             Object.assign(this, {x, y});
> > >           }
> > >
> > >           [Symbol.add](other) {
> > >             return new Point(this.x + other.x, this.y + other.y);
> > >           }
> > >         }
> > >
> > >         const u = new Point(5, 10);
> > >         const v = new Point(1, -2);
> > >
> > >         const w = u + v;  // desugars to u[Symbol.add](v)
> > >         console.log(w);   // { x: 6, y: 8 };
> > >         ```
> > >
> > >         This would require default implementations to be defined on
> > >         Object.prototype for Symbol.plus, Symbol.times, etc.
> > >
> > >
> > >         On Sun, May 8, 2016 at 10:38 PM, G. Kay Lee
> > >         <[hidden email]
> > >         <mailto:[hidden email]>> wrote:
> > >
> > >             > Why not? The standard defines well-known symbols. Maybe
> > `@operator` could be a well known decorator (assuming decorators get
> > approved).
> > >
> > >             Well... you make something into the standard with proposals,
> > >             not why-nots, so in order to make that happen you need to
> > >             draft another proposal for well-known decorators. And
> > >             remember that decorators are essentially just a syntax to
> > >             apply functions to objects/classes at design time, so what
> > >             you're proposing is essentially some new global function,
> > >             which is going against the current trend and effort to
> > >             better modularize/namespace all these utility
> > >             functions/methods. And maybe a new mechanism could be
> > >             drafted for these new well-known decorators, so that we can
> > >             hide these new functions somewhere... but by now I hope it's
> > >             becoming clear that it's introducing way too much new
> > >             surface area for the language in exchange for one small
> > feature.
> > >
> > >             > I haven't seen any proposals for macros, could you post a
> > link?
> > >
> > >             It has been mentioned and discussed in numerous places over
> > >             the years, you can find more info on this with some casual
> > >             googling. For example:
> > >             https://news.ycombinator.com/item?id=2983420
> > >
> > >
> > >
> > >             On Sun, May 8, 2016 at 2:51 PM, Kevin Barabash
> > >             <[hidden email] <mailto:[hidden email]>>
> > wrote:
> > >
> > >                 I should update the demo code to show the `@operator`
> > >                 decorator in addition to `Function.defineOperator`.
> > >
> > >                 Initially I started out with just the `@operator`
> > >                 decorator, but that meant that each class would have to
> > >                 have knowledge of each of the classes it might want to
> > >                 interact with before hand.  Having a separate
> > >                 `defineOperator` function avoids this situation.
> > >
> > >                 It means that prototype style classes must be converted
> > >                 to the new class syntax before operator overloading
> > >                 could be used.  Lastly, there may be some cases where it
> > >                 makes sense to overload operators with existing 3rd
> > >                 party code or built-in classes, e.g. adding set
> > >                 operations to Set using operator overloading.
> > >
> > >                 > It's also apparent that the `@operator decorator` part
> > >                 of the proposal is an effort trying to address this
> > >                 issue, but it really is not the responsibility of the
> > >                 standard to try to define such a thing.
> > >
> > >                 Why not?  The standard defines well-known symbols.
> > >                 Maybe `@operator` could be a well known decorator
> > >                 (assuming decorators get approved).
> > >
> > >                 Slide 15
> > >                 from http://www.slideshare.net/BrendanEich/js-resp shows
> > >                 syntax for defining operators in value types which could
> > >                 be adapted as follows for regular classes:
> > >
> > >                 ```
> > >                 class Point {
> > >                    constructor(x, y) {
> > >                        this.x = +x;
> > >                        this.y = +y;
> > >                    }
> > >                    Point + Number (a, b) {
> > >                        return new Point(a.x + b, a.y + b);
> > >                    }
> > >                    Number + Point (a, b) {
> > >                        return new Point(a + b.x, a + b.y);
> > >                    }
> > >                    Point + Point (a, b) {
> > >                        return new Point(a.x + b.x, a.y + b.y);
> > >                    }
> > >                 }
> > >                 ```
> > >
> > >                 Having to define `+` twice for `Point + Number` and
> > >                 `Number + Point` seems like busy work, but maybe it's
> > >                 better to be explicit.  What are you thoughts about this
> > >                 syntax?
> > >
> > >                 > Another thing is that, IMHO, currently there are too
> > >                 much quirks/conventions in the proposal that feel
> > >                 non-evident and non-flexible which is destined to trip
> > >                 people over from time to time. It would be great to make
> > >                 a proposal that's simple and don't include too much
> > >                 assumptions.
> > >
> > >                 Could you elaborator what quirks/conventions might trip
> > >                 people up?
> > >
> > >                 > Finally, I'm not sure about the current status of
> > >                 macros, but last I heard of it, they say it's going to
> > >                 make its way into the standard pretty soon (TM), and
> > >                 macros can do much of the things overloading could, and
> > >                 much more.
> > >
> > >                 I haven't seen any proposals for macros, could you post
> > >                 a link?
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >                 On Sat, May 7, 2016 at 9:55 PM, G. Kay Lee
> > >                 <[hidden email]
> > >                 <mailto:[hidden email]>> wrote:
> > >
> > >                     I'd say it's way too early to ask for a champion on
> > >                     this because just a quick skimming revealed a lot of
> > >                     places that didn't add up. For example, the proposal
> > >                     suggested that overloading is primarily targeted at
> > >                     making it easier to work with user-defined classes,
> > >                     but curiously a `Function.defineOperator()` method
> > >                     is proposed instead of some syntax that feels more
> > >                     tightly integrated with the class definition syntax.
> > >
> > >                     ```
> > >
> > >                     class Point {
> > >                         constructor(x, y) {
> > >                             Object.assign(this, { x, y });
> > >                         }
> > >
> > >                         toString() {
> > >                             return `(${this.x}, ${this.y})`;
> > >                         }
> > >                     }
> > >
> > >                     Function.defineOperator('+', [Point, Point], (a, b)
> > => new Point(a.x + b.x, a.y + b.y));
> > >
> > >                     ```
> > >
> > >                     The demo code made this flaw evident - it looks like
> > >                     a giant step backward to define an instance method
> > >                     like this, don't you agree?
> > >
> > >                     It's also apparent that the `@operator decorator`
> > >                     part of the proposal is an effort trying to address
> > >                     this issue, but it really is not the responsibility
> > >                     of the standard to try to define such a thing.
> > >
> > >                     What I'd suggest is that perhaps you should rethink
> > >                     your proposed syntax and redesign it to become an
> > >                     extension of the ES6 class definition syntax.
> > >
> > >                     Another thing is that, IMHO, currently there are too
> > >                     much quirks/conventions in the proposal that feel
> > >                     non-evident and non-flexible which is destined to
> > >                     trip people over from time to time. It would be
> > >                     great to make a proposal that's simple and don't
> > >                     include too much assumptions.
> > >
> > >                     Finally, I'm not sure about the current status of
> > >                     macros, but last I heard of it, they say it's going
> > >                     to make its way into the standard pretty soon (TM),
> > >                     and macros can do much of the things overloading
> > >                     could, and much more.
> > >
> > >                     On Sun, May 8, 2016 at 8:51 AM, Kevin Barabash
> > >                     <[hidden email]
> > >                     <mailto:[hidden email]>> wrote:
> > >
> > >                         I forgot to mention in my last email that I'm
> > >                         looking for a champion for this proposal.
> > >
> > >                         On Sat, May 7, 2016 at 5:24 PM, Kevin Barabash
> > >                         <[hidden email]
> > >                         <mailto:[hidden email]>> wrote:
> > >
> > >                             Hi everyone,
> > >
> > >                             I've been working on implementing operator
> > >                             overloading and would like to submit a
> > proposal.
> > >
> > >                             I think operator overloading would be a
> > >                             useful addition to the language.  In
> > >                             particular I think it would be useful for
> > >                             defining operations on common mathematical
> > >                             object types such as complex numbers,
> > >                             vectors, matrices, and sets.
> > >
> > >                             I've create a working prototype that
> > >                             consists of:
> > >
> > >                               * babel plugin that rewrites operators as
> > >                                 function calls
> > >                               * a polyfill which defines these functions
> > >                                 and which call the correct
> > >                                 argument-specific function based on the
> > >                                 arguments' prototypes
> > >                               * Function.defineOperator which can be
> > >                                 used to define which function an
> > >                                 operator should use for the specified
> > types
> > >                               * "use overloading" directive which allows
> > >                                 users to opt-in
> > >
> > >                             More details can be found
> > >                             at
> > https://github.com/kevinbarabash/operator-overloading.
> > >                             The babel plugin can be found
> > >                             at
> > https://github.com/kevinbarabash/babel-plugin-operator-overloading.
> > >                             I also have a demo project at
> > >
> > https://github.com/kevinbarabash/operator-overloading-demo.
> > >
> > >                             The design was inspired by some of the
> > >                             slides from
> > >
> > http://www.slideshare.net/BrendanEich/js-resp.
> > >
> > >                             – Kevin
> > >
> > >
> > >
> > >
> > >                         _______________________________________________
> > >                         es-discuss mailing list
> > >                         [hidden email]
> > >                         <mailto:[hidden email]>
> > >                         https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >                     _______________________________________________
> > >                     es-discuss mailing list
> > >                     [hidden email] <mailto:
> > [hidden email]>
> > >                     https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >                 _______________________________________________
> > >                 es-discuss mailing list
> > >                 [hidden email] <mailto:[hidden email]>
> > >                 https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >             _______________________________________________
> > >             es-discuss mailing list
> > >             [hidden email] <mailto:[hidden email]>
> > >             https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >         _______________________________________________
> > >         es-discuss mailing list
> > >         [hidden email] <mailto:[hidden email]>
> > >         https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >     _______________________________________________
> > >     es-discuss mailing list
> > >     [hidden email] <mailto:[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
> >
>

_______________________________________________
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: operator overloading proposal

Jordan Harband
Why would you ever want to violate the algebraic properties of operators, such that `a += b` wasn't exactly equivalent to `a = a + b`, `a *= b` not equivalent to `a = a * b`, etc? I'm quite confident that any proposal that allowed for that would get tons of pushback.

On Tue, May 10, 2016 at 11:26 PM, Isiah Meadows <[hidden email]> wrote:
1. Yes, they would be inherited, but not on the prototype itself (it would technically be parasitic). It would be modeled with internal slots, so that the properties are themselves immutable and transparent, so the only way to inherit would be via the class syntax or `Reflect.construct`. Engines could model this similarly to prototypes internally, while still appearing to conform to spec, since there's no other way to access the function without explicit reference via a decorator. And if it's not decorated, you can transparently fast path the calls automatically and optimize the function at compile time for exactly the number of arguments (any different is a syntax error, like with getters and setters). 

2. I'm intentionally trying to avoid any semantics that would rely on adding more values to the global scope. First, it's harder to optimize a `hasOwnProperty` check. Second, when you allow properties to be dynamically added, you make it impossible to lower `foo + bar` to a single instruction if they're both numbers, because someone can change the Number prototype to have one of the operators on it, and now, the assumption, previously prevalent, is now invalid. Third, we shouldn't need to add 15+ new symbols to accommodate a simple operation. 

3. If it's pure syntax, you won't have the edge cases of `x += y` having to desugar to `x = x[Symbol.assignPlus](y)` and so on. You just look for an `[[OpAssignPlus]]` on `x`, and if it exists, call it as `x.[[OpAssignPlus]](y)`. Else, you check for `[[OpPlus]]`, and set `x` to `x.[[OpPlus]](y)`. If neither exists, you fall back to the old algorithm. This can be easily optimized by the fact engines only need to check this if the value is an object. Numbers and strings don't have this slot. 

Note: If the right side has an operator defined, but the left side doesn't, and if the operator checked for isn't an assignment one, the right side's operator is checked and called. Or basically, beyond assignment, the mere existence of a slot takes precedence over no slot, to make transitivity easier with primitives. To clarify, in the below case:

```js
class C {
    constructor(x) { this.x = x }
    operator +(x) {
        if (x instanceof C) {
            return this + x.x * 2
        }
        return this.x + x
    }
}

assert(new C(1) + 1 === 1 +1)
assert(1 + new C(1) === 1 + 1)
assert(new C(1) + new C(2) === 1 + 2*2)
assert(new C(2) + new C(1) === 2 + 1*2)
```

On Wed, May 11, 2016, 01:27 Kevin Barabash <[hidden email]> wrote:
I would prefer syntax + internal slots, since you'll know at creation time whether the object has overloaded 
> operators. It's much simpler for the engine to figure out, and it's more performant because you only need to 
> check one thing instead of worrying about inheritance, own properties, etc.

Will operators defined on a class work with instances of a subclass?

Could += be a special case? i.e.,

For sure.  We could define `Symbol.assignPlus`, `Symbol.assignTimes`, etc. with `u += v;` desugaring to `u = u[Symbol.assignPlus](v)`.  The reason why we can't do something do `u[Symbol.assignPlus](v)` is that there's no way to define a method on Number, String, etc. that would reassign their value.

it appears to me that overloading an operator multiple times (e. g. unary/binary plus operator) might become 
> painful, assuming that the semantics follow the same variadic approach that regular functions do.

Another pain point is handling cases where you want one class to interoperate with another.  In one of the example above methods are defined that allow `Point`s and `Number`s to be added to each other.  In order to maintain the commutativity of `+` we need to define `operator+` / `[Symbol.add]` methods on both `Point` and `Number`.  One potential solution to this problem is create `Symbol.plusRight`, `Symbol.timesRight` for all of the commutative/symmetric operators.  

I feel like this ends up making things more complex because there are more methods to implement and the methods have to be more complex b/c they have to do type checking when overloaded.

Maybe `operator+` could work like the `@operator` decorator by calling `Function.defineOperator` behind the scenes.  In this situation, instead of methods being added to classes, the `Function` object has well-defined methods that look up the correct function to call based on the argument types.  `u + v` desugars to `Function[Symbol.plus](u, v)`.  This is definitely slower than internal slots, but if we're doing runtime type checking in the method we may as well have it be automatic.  My hope is to eventually use static typing (flow b/c I'm using babel) to remove the lookup cost.
 

On Tue, May 10, 2016 at 7:07 PM, Isiah Meadows <[hidden email]> wrote:

You're correct in that the operator doesn't do any type checking (it dispatches from its first argument, but that's just traditional OO).


On Tue, May 10, 2016, 20:28 kdex <[hidden email]> wrote:
@Isiah: Comparing your syntax proposal to `Function.defineOperator`, it appears to me that
overloading an operator multiple times (e. g. unary/binary plus operator) might become painful,
assuming that the semantics follow the same variadic approach that regular functions do.

That is, of course, unless you intend to handle all operator overloads in a single `operator +(...args) {}`
definition. But then again, something like `Function.defineOperator` seems cleaner and suggests implicit
(optional?) type checks with its second argument.

On Dienstag, 10. Mai 2016 15:25:32 CEST Isiah Meadows wrote:
> Here's my thought, if we go with syntax.
>
> ```js
> class Point {
>     // constructor, etc.
>
>     operator +(other) {
>         assert(other instanceof Point)
>         return new Point(
>             this.x + other.x,
>             this.y + other.y)
>     }
>
>     operator +=(other) {
>         assert(other instanceof Point)
>         this.x += other.x
>         this.y += other.y
>     }
> }
> ```
>
> On Tue, May 10, 2016, 11:16 Brian Barnes <[hidden email]> wrote:
>
> > A note on this from somebody who's entire existence seems dedicated to
> > stopping as much stuff as possible from getting GC'd, the example below:
> >
> >  >const u = new Point(5, 10);
> >  >const v = new Point(1, -2);
> >  >
> >  >const w = u + v;  // desugars to u[Symbol.add](v)
> >  >console.log(w);   // { x: 6, y: 8 };
> >
> > Could += be a special case?  i.e.,
> >
> > u+=v;
> >
> > would call:
> >
> > Class Point { ... other stuff ...
> > [whatever the syntax is](pt)
> > {
> > this.x+=pt.x;
> > this.y+=pt.y;
> > }
> > }
> >
> > instead of desugaring to:
> >
> > u=u+v;          // which would cause the creation of an object and
> >                 // leave the other to be collected
> >
> > For all I know, += might be doing such anyway in some engines, but for
> > my stuff which is a lot of 3D math that could be a performance killer.
> > It would be nice to be able to just add points and such, as long as the
> > overhead is negligible.
> >
> > [>] Brian
> >
> > On 5/10/2016 10:52 AM, Isiah Meadows wrote:
> > > I would prefer syntax + internal slots, since you'll know at creation
> > > time whether the object has overloaded operators. It's much simpler for
> > > the engine to figure out, and it's more performant because you only need
> > > to check one thing instead of worrying about inheritance, own
> > > properties, etc.
> > >
> > > Also, it would be IMHO easier to read than a symbol (the computed
> > > property syntax is ugly IMO). Using a different concept than symbols
> > > would also fit better with value types whenever any of those proposals
> > > make it into the language (either the struct or special syntax).
> > >
> > >
> > > On Tue, May 10, 2016, 04:03 G. Kay Lee
> > > <[hidden email]
> > > <mailto:[hidden email]>> wrote:
> > >
> > >     Yes, I think exposing operators through well-known symbols is an
> > >     interesting idea worthy of more exploration because it's precisely
> > >     the purpose of well-known symbols to expose and allow manipulation
> > >     to previously inaccessible internal language behaviors.
> > >
> > >     On Tue, May 10, 2016 at 1:59 PM, Kevin Barabash
> > >     <[hidden email] <mailto:[hidden email]>> wrote:
> > >
> > >         > And remember that decorators are essentially just a syntax to
> > >         apply functions to objects/classes at design time, so what
> > >         you're proposing is essentially some new global function, which
> > >         is going against the current trend and effort to better
> > >         modularize/namespace all these utility functions/methods.
> > >
> > >         That's a really good point.
> > >
> > >         > It has been mentioned and discussed in numerous places over the
> > >         years, you can find more info on this with some casual googling.
> > >         For example:https://news.ycombinator.com/item?id=2983420
> > >
> > >         Thanks for the link.  I played around with sweet.js a bit over
> > >         the weekend.  Using macros should work if we went with Python
> > >         style operator overloading.  Instead of defining methods like
> > >         _ADD_, _SUB_ etc. we could create some well-known symbols, maybe
> > >         Symbol.plus, Symbol.times, etc.
> > >
> > >         ```
> > >         class Point {
> > >           constructor(x, y) {
> > >             Object.assign(this, {x, y});
> > >           }
> > >
> > >           [Symbol.add](other) {
> > >             return new Point(this.x + other.x, this.y + other.y);
> > >           }
> > >         }
> > >
> > >         const u = new Point(5, 10);
> > >         const v = new Point(1, -2);
> > >
> > >         const w = u + v;  // desugars to u[Symbol.add](v)
> > >         console.log(w);   // { x: 6, y: 8 };
> > >         ```
> > >
> > >         This would require default implementations to be defined on
> > >         Object.prototype for Symbol.plus, Symbol.times, etc.
> > >
> > >
> > >         On Sun, May 8, 2016 at 10:38 PM, G. Kay Lee
> > >         <[hidden email]
> > >         <mailto:[hidden email]>> wrote:
> > >
> > >             > Why not? The standard defines well-known symbols. Maybe
> > `@operator` could be a well known decorator (assuming decorators get
> > approved).
> > >
> > >             Well... you make something into the standard with proposals,
> > >             not why-nots, so in order to make that happen you need to
> > >             draft another proposal for well-known decorators. And
> > >             remember that decorators are essentially just a syntax to
> > >             apply functions to objects/classes at design time, so what
> > >             you're proposing is essentially some new global function,
> > >             which is going against the current trend and effort to
> > >             better modularize/namespace all these utility
> > >             functions/methods. And maybe a new mechanism could be
> > >             drafted for these new well-known decorators, so that we can
> > >             hide these new functions somewhere... but by now I hope it's
> > >             becoming clear that it's introducing way too much new
> > >             surface area for the language in exchange for one small
> > feature.
> > >
> > >             > I haven't seen any proposals for macros, could you post a
> > link?
> > >
> > >             It has been mentioned and discussed in numerous places over
> > >             the years, you can find more info on this with some casual
> > >             googling. For example:
> > >             https://news.ycombinator.com/item?id=2983420
> > >
> > >
> > >
> > >             On Sun, May 8, 2016 at 2:51 PM, Kevin Barabash
> > >             <[hidden email] <mailto:[hidden email]>>
> > wrote:
> > >
> > >                 I should update the demo code to show the `@operator`
> > >                 decorator in addition to `Function.defineOperator`.
> > >
> > >                 Initially I started out with just the `@operator`
> > >                 decorator, but that meant that each class would have to
> > >                 have knowledge of each of the classes it might want to
> > >                 interact with before hand.  Having a separate
> > >                 `defineOperator` function avoids this situation.
> > >
> > >                 It means that prototype style classes must be converted
> > >                 to the new class syntax before operator overloading
> > >                 could be used.  Lastly, there may be some cases where it
> > >                 makes sense to overload operators with existing 3rd
> > >                 party code or built-in classes, e.g. adding set
> > >                 operations to Set using operator overloading.
> > >
> > >                 > It's also apparent that the `@operator decorator` part
> > >                 of the proposal is an effort trying to address this
> > >                 issue, but it really is not the responsibility of the
> > >                 standard to try to define such a thing.
> > >
> > >                 Why not?  The standard defines well-known symbols.
> > >                 Maybe `@operator` could be a well known decorator
> > >                 (assuming decorators get approved).
> > >
> > >                 Slide 15
> > >                 from http://www.slideshare.net/BrendanEich/js-resp shows
> > >                 syntax for defining operators in value types which could
> > >                 be adapted as follows for regular classes:
> > >
> > >                 ```
> > >                 class Point {
> > >                    constructor(x, y) {
> > >                        this.x = +x;
> > >                        this.y = +y;
> > >                    }
> > >                    Point + Number (a, b) {
> > >                        return new Point(a.x + b, a.y + b);
> > >                    }
> > >                    Number + Point (a, b) {
> > >                        return new Point(a + b.x, a + b.y);
> > >                    }
> > >                    Point + Point (a, b) {
> > >                        return new Point(a.x + b.x, a.y + b.y);
> > >                    }
> > >                 }
> > >                 ```
> > >
> > >                 Having to define `+` twice for `Point + Number` and
> > >                 `Number + Point` seems like busy work, but maybe it's
> > >                 better to be explicit.  What are you thoughts about this
> > >                 syntax?
> > >
> > >                 > Another thing is that, IMHO, currently there are too
> > >                 much quirks/conventions in the proposal that feel
> > >                 non-evident and non-flexible which is destined to trip
> > >                 people over from time to time. It would be great to make
> > >                 a proposal that's simple and don't include too much
> > >                 assumptions.
> > >
> > >                 Could you elaborator what quirks/conventions might trip
> > >                 people up?
> > >
> > >                 > Finally, I'm not sure about the current status of
> > >                 macros, but last I heard of it, they say it's going to
> > >                 make its way into the standard pretty soon (TM), and
> > >                 macros can do much of the things overloading could, and
> > >                 much more.
> > >
> > >                 I haven't seen any proposals for macros, could you post
> > >                 a link?
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >                 On Sat, May 7, 2016 at 9:55 PM, G. Kay Lee
> > >                 <[hidden email]
> > >                 <mailto:[hidden email]>> wrote:
> > >
> > >                     I'd say it's way too early to ask for a champion on
> > >                     this because just a quick skimming revealed a lot of
> > >                     places that didn't add up. For example, the proposal
> > >                     suggested that overloading is primarily targeted at
> > >                     making it easier to work with user-defined classes,
> > >                     but curiously a `Function.defineOperator()` method
> > >                     is proposed instead of some syntax that feels more
> > >                     tightly integrated with the class definition syntax.
> > >
> > >                     ```
> > >
> > >                     class Point {
> > >                         constructor(x, y) {
> > >                             Object.assign(this, { x, y });
> > >                         }
> > >
> > >                         toString() {
> > >                             return `(${this.x}, ${this.y})`;
> > >                         }
> > >                     }
> > >
> > >                     Function.defineOperator('+', [Point, Point], (a, b)
> > => new Point(a.x + b.x, a.y + b.y));
> > >
> > >                     ```
> > >
> > >                     The demo code made this flaw evident - it looks like
> > >                     a giant step backward to define an instance method
> > >                     like this, don't you agree?
> > >
> > >                     It's also apparent that the `@operator decorator`
> > >                     part of the proposal is an effort trying to address
> > >                     this issue, but it really is not the responsibility
> > >                     of the standard to try to define such a thing.
> > >
> > >                     What I'd suggest is that perhaps you should rethink
> > >                     your proposed syntax and redesign it to become an
> > >                     extension of the ES6 class definition syntax.
> > >
> > >                     Another thing is that, IMHO, currently there are too
> > >                     much quirks/conventions in the proposal that feel
> > >                     non-evident and non-flexible which is destined to
> > >                     trip people over from time to time. It would be
> > >                     great to make a proposal that's simple and don't
> > >                     include too much assumptions.
> > >
> > >                     Finally, I'm not sure about the current status of
> > >                     macros, but last I heard of it, they say it's going
> > >                     to make its way into the standard pretty soon (TM),
> > >                     and macros can do much of the things overloading
> > >                     could, and much more.
> > >
> > >                     On Sun, May 8, 2016 at 8:51 AM, Kevin Barabash
> > >                     <[hidden email]
> > >                     <mailto:[hidden email]>> wrote:
> > >
> > >                         I forgot to mention in my last email that I'm
> > >                         looking for a champion for this proposal.
> > >
> > >                         On Sat, May 7, 2016 at 5:24 PM, Kevin Barabash
> > >                         <[hidden email]
> > >                         <mailto:[hidden email]>> wrote:
> > >
> > >                             Hi everyone,
> > >
> > >                             I've been working on implementing operator
> > >                             overloading and would like to submit a
> > proposal.
> > >
> > >                             I think operator overloading would be a
> > >                             useful addition to the language.  In
> > >                             particular I think it would be useful for
> > >                             defining operations on common mathematical
> > >                             object types such as complex numbers,
> > >                             vectors, matrices, and sets.
> > >
> > >                             I've create a working prototype that
> > >                             consists of:
> > >
> > >                               * babel plugin that rewrites operators as
> > >                                 function calls
> > >                               * a polyfill which defines these functions
> > >                                 and which call the correct
> > >                                 argument-specific function based on the
> > >                                 arguments' prototypes
> > >                               * Function.defineOperator which can be
> > >                                 used to define which function an
> > >                                 operator should use for the specified
> > types
> > >                               * "use overloading" directive which allows
> > >                                 users to opt-in
> > >
> > >                             More details can be found
> > >                             at
> > https://github.com/kevinbarabash/operator-overloading.
> > >                             The babel plugin can be found
> > >                             at
> > https://github.com/kevinbarabash/babel-plugin-operator-overloading.
> > >                             I also have a demo project at
> > >
> > https://github.com/kevinbarabash/operator-overloading-demo.
> > >
> > >                             The design was inspired by some of the
> > >                             slides from
> > >
> > http://www.slideshare.net/BrendanEich/js-resp.
> > >
> > >                             – Kevin
> > >
> > >
> > >
> > >
> > >                         _______________________________________________
> > >                         es-discuss mailing list
> > >                         [hidden email]
> > >                         <mailto:[hidden email]>
> > >                         https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >                     _______________________________________________
> > >                     es-discuss mailing list
> > >                     [hidden email] <mailto:
> > [hidden email]>
> > >                     https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >                 _______________________________________________
> > >                 es-discuss mailing list
> > >                 [hidden email] <mailto:[hidden email]>
> > >                 https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >             _______________________________________________
> > >             es-discuss mailing list
> > >             [hidden email] <mailto:[hidden email]>
> > >             https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >         _______________________________________________
> > >         es-discuss mailing list
> > >         [hidden email] <mailto:[hidden email]>
> > >         https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >     _______________________________________________
> > >     es-discuss mailing list
> > >     [hidden email] <mailto:[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
> >
>

_______________________________________________
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



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

Re: operator overloading proposal

Isiah Meadows-2

Efficiency and optimization. If you're stupid enough to want to violate those priorities in a public API, it's your own fault. But if you want to optimize updating a collection (i.e. zero allocation update for a persistent map) or increment a vector by another without having to create an intermediate vector, you'll want to implement the assignment operator as well as the standard math operator.


On Wed, May 11, 2016, 02:46 Jordan Harband <[hidden email]> wrote:
Why would you ever want to violate the algebraic properties of operators, such that `a += b` wasn't exactly equivalent to `a = a + b`, `a *= b` not equivalent to `a = a * b`, etc? I'm quite confident that any proposal that allowed for that would get tons of pushback.

On Tue, May 10, 2016 at 11:26 PM, Isiah Meadows <[hidden email]> wrote:
1. Yes, they would be inherited, but not on the prototype itself (it would technically be parasitic). It would be modeled with internal slots, so that the properties are themselves immutable and transparent, so the only way to inherit would be via the class syntax or `Reflect.construct`. Engines could model this similarly to prototypes internally, while still appearing to conform to spec, since there's no other way to access the function without explicit reference via a decorator. And if it's not decorated, you can transparently fast path the calls automatically and optimize the function at compile time for exactly the number of arguments (any different is a syntax error, like with getters and setters). 

2. I'm intentionally trying to avoid any semantics that would rely on adding more values to the global scope. First, it's harder to optimize a `hasOwnProperty` check. Second, when you allow properties to be dynamically added, you make it impossible to lower `foo + bar` to a single instruction if they're both numbers, because someone can change the Number prototype to have one of the operators on it, and now, the assumption, previously prevalent, is now invalid. Third, we shouldn't need to add 15+ new symbols to accommodate a simple operation. 

3. If it's pure syntax, you won't have the edge cases of `x += y` having to desugar to `x = x[Symbol.assignPlus](y)` and so on. You just look for an `[[OpAssignPlus]]` on `x`, and if it exists, call it as `x.[[OpAssignPlus]](y)`. Else, you check for `[[OpPlus]]`, and set `x` to `x.[[OpPlus]](y)`. If neither exists, you fall back to the old algorithm. This can be easily optimized by the fact engines only need to check this if the value is an object. Numbers and strings don't have this slot. 

Note: If the right side has an operator defined, but the left side doesn't, and if the operator checked for isn't an assignment one, the right side's operator is checked and called. Or basically, beyond assignment, the mere existence of a slot takes precedence over no slot, to make transitivity easier with primitives. To clarify, in the below case:

```js
class C {
    constructor(x) { this.x = x }
    operator +(x) {
        if (x instanceof C) {
            return this + x.x * 2
        }
        return this.x + x
    }
}

assert(new C(1) + 1 === 1 +1)
assert(1 + new C(1) === 1 + 1)
assert(new C(1) + new C(2) === 1 + 2*2)
assert(new C(2) + new C(1) === 2 + 1*2)
```

On Wed, May 11, 2016, 01:27 Kevin Barabash <[hidden email]> wrote:
I would prefer syntax + internal slots, since you'll know at creation time whether the object has overloaded 
> operators. It's much simpler for the engine to figure out, and it's more performant because you only need to 
> check one thing instead of worrying about inheritance, own properties, etc.

Will operators defined on a class work with instances of a subclass?

Could += be a special case? i.e.,

For sure.  We could define `Symbol.assignPlus`, `Symbol.assignTimes`, etc. with `u += v;` desugaring to `u = u[Symbol.assignPlus](v)`.  The reason why we can't do something do `u[Symbol.assignPlus](v)` is that there's no way to define a method on Number, String, etc. that would reassign their value.

it appears to me that overloading an operator multiple times (e. g. unary/binary plus operator) might become 
> painful, assuming that the semantics follow the same variadic approach that regular functions do.

Another pain point is handling cases where you want one class to interoperate with another.  In one of the example above methods are defined that allow `Point`s and `Number`s to be added to each other.  In order to maintain the commutativity of `+` we need to define `operator+` / `[Symbol.add]` methods on both `Point` and `Number`.  One potential solution to this problem is create `Symbol.plusRight`, `Symbol.timesRight` for all of the commutative/symmetric operators.  

I feel like this ends up making things more complex because there are more methods to implement and the methods have to be more complex b/c they have to do type checking when overloaded.

Maybe `operator+` could work like the `@operator` decorator by calling `Function.defineOperator` behind the scenes.  In this situation, instead of methods being added to classes, the `Function` object has well-defined methods that look up the correct function to call based on the argument types.  `u + v` desugars to `Function[Symbol.plus](u, v)`.  This is definitely slower than internal slots, but if we're doing runtime type checking in the method we may as well have it be automatic.  My hope is to eventually use static typing (flow b/c I'm using babel) to remove the lookup cost.
 

On Tue, May 10, 2016 at 7:07 PM, Isiah Meadows <[hidden email]> wrote:

You're correct in that the operator doesn't do any type checking (it dispatches from its first argument, but that's just traditional OO).


On Tue, May 10, 2016, 20:28 kdex <[hidden email]> wrote:
@Isiah: Comparing your syntax proposal to `Function.defineOperator`, it appears to me that
overloading an operator multiple times (e. g. unary/binary plus operator) might become painful,
assuming that the semantics follow the same variadic approach that regular functions do.

That is, of course, unless you intend to handle all operator overloads in a single `operator +(...args) {}`
definition. But then again, something like `Function.defineOperator` seems cleaner and suggests implicit
(optional?) type checks with its second argument.

On Dienstag, 10. Mai 2016 15:25:32 CEST Isiah Meadows wrote:
> Here's my thought, if we go with syntax.
>
> ```js
> class Point {
>     // constructor, etc.
>
>     operator +(other) {
>         assert(other instanceof Point)
>         return new Point(
>             this.x + other.x,
>             this.y + other.y)
>     }
>
>     operator +=(other) {
>         assert(other instanceof Point)
>         this.x += other.x
>         this.y += other.y
>     }
> }
> ```
>
> On Tue, May 10, 2016, 11:16 Brian Barnes <[hidden email]> wrote:
>
> > A note on this from somebody who's entire existence seems dedicated to
> > stopping as much stuff as possible from getting GC'd, the example below:
> >
> >  >const u = new Point(5, 10);
> >  >const v = new Point(1, -2);
> >  >
> >  >const w = u + v;  // desugars to u[Symbol.add](v)
> >  >console.log(w);   // { x: 6, y: 8 };
> >
> > Could += be a special case?  i.e.,
> >
> > u+=v;
> >
> > would call:
> >
> > Class Point { ... other stuff ...
> > [whatever the syntax is](pt)
> > {
> > this.x+=pt.x;
> > this.y+=pt.y;
> > }
> > }
> >
> > instead of desugaring to:
> >
> > u=u+v;          // which would cause the creation of an object and
> >                 // leave the other to be collected
> >
> > For all I know, += might be doing such anyway in some engines, but for
> > my stuff which is a lot of 3D math that could be a performance killer.
> > It would be nice to be able to just add points and such, as long as the
> > overhead is negligible.
> >
> > [>] Brian
> >
> > On 5/10/2016 10:52 AM, Isiah Meadows wrote:
> > > I would prefer syntax + internal slots, since you'll know at creation
> > > time whether the object has overloaded operators. It's much simpler for
> > > the engine to figure out, and it's more performant because you only need
> > > to check one thing instead of worrying about inheritance, own
> > > properties, etc.
> > >
> > > Also, it would be IMHO easier to read than a symbol (the computed
> > > property syntax is ugly IMO). Using a different concept than symbols
> > > would also fit better with value types whenever any of those proposals
> > > make it into the language (either the struct or special syntax).
> > >
> > >
> > > On Tue, May 10, 2016, 04:03 G. Kay Lee
> > > <[hidden email]
> > > <mailto:[hidden email]>> wrote:
> > >
> > >     Yes, I think exposing operators through well-known symbols is an
> > >     interesting idea worthy of more exploration because it's precisely
> > >     the purpose of well-known symbols to expose and allow manipulation
> > >     to previously inaccessible internal language behaviors.
> > >
> > >     On Tue, May 10, 2016 at 1:59 PM, Kevin Barabash
> > >     <[hidden email] <mailto:[hidden email]>> wrote:
> > >
> > >         > And remember that decorators are essentially just a syntax to
> > >         apply functions to objects/classes at design time, so what
> > >         you're proposing is essentially some new global function, which
> > >         is going against the current trend and effort to better
> > >         modularize/namespace all these utility functions/methods.
> > >
> > >         That's a really good point.
> > >
> > >         > It has been mentioned and discussed in numerous places over the
> > >         years, you can find more info on this with some casual googling.
> > >         For example:https://news.ycombinator.com/item?id=2983420
> > >
> > >         Thanks for the link.  I played around with sweet.js a bit over
> > >         the weekend.  Using macros should work if we went with Python
> > >         style operator overloading.  Instead of defining methods like
> > >         _ADD_, _SUB_ etc. we could create some well-known symbols, maybe
> > >         Symbol.plus, Symbol.times, etc.
> > >
> > >         ```
> > >         class Point {
> > >           constructor(x, y) {
> > >             Object.assign(this, {x, y});
> > >           }
> > >
> > >           [Symbol.add](other) {
> > >             return new Point(this.x + other.x, this.y + other.y);
> > >           }
> > >         }
> > >
> > >         const u = new Point(5, 10);
> > >         const v = new Point(1, -2);
> > >
> > >         const w = u + v;  // desugars to u[Symbol.add](v)
> > >         console.log(w);   // { x: 6, y: 8 };
> > >         ```
> > >
> > >         This would require default implementations to be defined on
> > >         Object.prototype for Symbol.plus, Symbol.times, etc.
> > >
> > >
> > >         On Sun, May 8, 2016 at 10:38 PM, G. Kay Lee
> > >         <[hidden email]
> > >         <mailto:[hidden email]>> wrote:
> > >
> > >             > Why not? The standard defines well-known symbols. Maybe
> > `@operator` could be a well known decorator (assuming decorators get
> > approved).
> > >
> > >             Well... you make something into the standard with proposals,
> > >             not why-nots, so in order to make that happen you need to
> > >             draft another proposal for well-known decorators. And
> > >             remember that decorators are essentially just a syntax to
> > >             apply functions to objects/classes at design time, so what
> > >             you're proposing is essentially some new global function,
> > >             which is going against the current trend and effort to
> > >             better modularize/namespace all these utility
> > >             functions/methods. And maybe a new mechanism could be
> > >             drafted for these new well-known decorators, so that we can
> > >             hide these new functions somewhere... but by now I hope it's
> > >             becoming clear that it's introducing way too much new
> > >             surface area for the language in exchange for one small
> > feature.
> > >
> > >             > I haven't seen any proposals for macros, could you post a
> > link?
> > >
> > >             It has been mentioned and discussed in numerous places over
> > >             the years, you can find more info on this with some casual
> > >             googling. For example:
> > >             https://news.ycombinator.com/item?id=2983420
> > >
> > >
> > >
> > >             On Sun, May 8, 2016 at 2:51 PM, Kevin Barabash
> > >             <[hidden email] <mailto:[hidden email]>>
> > wrote:
> > >
> > >                 I should update the demo code to show the `@operator`
> > >                 decorator in addition to `Function.defineOperator`.
> > >
> > >                 Initially I started out with just the `@operator`
> > >                 decorator, but that meant that each class would have to
> > >                 have knowledge of each of the classes it might want to
> > >                 interact with before hand.  Having a separate
> > >                 `defineOperator` function avoids this situation.
> > >
> > >                 It means that prototype style classes must be converted
> > >                 to the new class syntax before operator overloading
> > >                 could be used.  Lastly, there may be some cases where it
> > >                 makes sense to overload operators with existing 3rd
> > >                 party code or built-in classes, e.g. adding set
> > >                 operations to Set using operator overloading.
> > >
> > >                 > It's also apparent that the `@operator decorator` part
> > >                 of the proposal is an effort trying to address this
> > >                 issue, but it really is not the responsibility of the
> > >                 standard to try to define such a thing.
> > >
> > >                 Why not?  The standard defines well-known symbols.
> > >                 Maybe `@operator` could be a well known decorator
> > >                 (assuming decorators get approved).
> > >
> > >                 Slide 15
> > >                 from http://www.slideshare.net/BrendanEich/js-resp shows
> > >                 syntax for defining operators in value types which could
> > >                 be adapted as follows for regular classes:
> > >
> > >                 ```
> > >                 class Point {
> > >                    constructor(x, y) {
> > >                        this.x = +x;
> > >                        this.y = +y;
> > >                    }
> > >                    Point + Number (a, b) {
> > >                        return new Point(a.x + b, a.y + b);
> > >                    }
> > >                    Number + Point (a, b) {
> > >                        return new Point(a + b.x, a + b.y);
> > >                    }
> > >                    Point + Point (a, b) {
> > >                        return new Point(a.x + b.x, a.y + b.y);
> > >                    }
> > >                 }
> > >                 ```
> > >
> > >                 Having to define `+` twice for `Point + Number` and
> > >                 `Number + Point` seems like busy work, but maybe it's
> > >                 better to be explicit.  What are you thoughts about this
> > >                 syntax?
> > >
> > >                 > Another thing is that, IMHO, currently there are too
> > >                 much quirks/conventions in the proposal that feel
> > >                 non-evident and non-flexible which is destined to trip
> > >                 people over from time to time. It would be great to make
> > >                 a proposal that's simple and don't include too much
> > >                 assumptions.
> > >
> > >                 Could you elaborator what quirks/conventions might trip
> > >                 people up?
> > >
> > >                 > Finally, I'm not sure about the current status of
> > >                 macros, but last I heard of it, they say it's going to
> > >                 make its way into the standard pretty soon (TM), and
> > >                 macros can do much of the things overloading could, and
> > >                 much more.
> > >
> > >                 I haven't seen any proposals for macros, could you post
> > >                 a link?
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >                 On Sat, May 7, 2016 at 9:55 PM, G. Kay Lee
> > >                 <[hidden email]
> > >                 <mailto:[hidden email]>> wrote:
> > >
> > >                     I'd say it's way too early to ask for a champion on
> > >                     this because just a quick skimming revealed a lot of
> > >                     places that didn't add up. For example, the proposal
> > >                     suggested that overloading is primarily targeted at
> > >                     making it easier to work with user-defined classes,
> > >                     but curiously a `Function.defineOperator()` method
> > >                     is proposed instead of some syntax that feels more
> > >                     tightly integrated with the class definition syntax.
> > >
> > >                     ```
> > >
> > >                     class Point {
> > >                         constructor(x, y) {
> > >                             Object.assign(this, { x, y });
> > >                         }
> > >
> > >                         toString() {
> > >                             return `(${this.x}, ${this.y})`;
> > >                         }
> > >                     }
> > >
> > >                     Function.defineOperator('+', [Point, Point], (a, b)
> > => new Point(a.x + b.x, a.y + b.y));
> > >
> > >                     ```
> > >
> > >                     The demo code made this flaw evident - it looks like
> > >                     a giant step backward to define an instance method
> > >                     like this, don't you agree?
> > >
> > >                     It's also apparent that the `@operator decorator`
> > >                     part of the proposal is an effort trying to address
> > >                     this issue, but it really is not the responsibility
> > >                     of the standard to try to define such a thing.
> > >
> > >                     What I'd suggest is that perhaps you should rethink
> > >                     your proposed syntax and redesign it to become an
> > >                     extension of the ES6 class definition syntax.
> > >
> > >                     Another thing is that, IMHO, currently there are too
> > >                     much quirks/conventions in the proposal that feel
> > >                     non-evident and non-flexible which is destined to
> > >                     trip people over from time to time. It would be
> > >                     great to make a proposal that's simple and don't
> > >                     include too much assumptions.
> > >
> > >                     Finally, I'm not sure about the current status of
> > >                     macros, but last I heard of it, they say it's going
> > >                     to make its way into the standard pretty soon (TM),
> > >                     and macros can do much of the things overloading
> > >                     could, and much more.
> > >
> > >                     On Sun, May 8, 2016 at 8:51 AM, Kevin Barabash
> > >                     <[hidden email]
> > >                     <mailto:[hidden email]>> wrote:
> > >
> > >                         I forgot to mention in my last email that I'm
> > >                         looking for a champion for this proposal.
> > >
> > >                         On Sat, May 7, 2016 at 5:24 PM, Kevin Barabash
> > >                         <[hidden email]
> > >                         <mailto:[hidden email]>> wrote:
> > >
> > >                             Hi everyone,
> > >
> > >                             I've been working on implementing operator
> > >                             overloading and would like to submit a
> > proposal.
> > >
> > >                             I think operator overloading would be a
> > >                             useful addition to the language.  In
> > >                             particular I think it would be useful for
> > >                             defining operations on common mathematical
> > >                             object types such as complex numbers,
> > >                             vectors, matrices, and sets.
> > >
> > >                             I've create a working prototype that
> > >                             consists of:
> > >
> > >                               * babel plugin that rewrites operators as
> > >                                 function calls
> > >                               * a polyfill which defines these functions
> > >                                 and which call the correct
> > >                                 argument-specific function based on the
> > >                                 arguments' prototypes
> > >                               * Function.defineOperator which can be
> > >                                 used to define which function an
> > >                                 operator should use for the specified
> > types
> > >                               * "use overloading" directive which allows
> > >                                 users to opt-in
> > >
> > >                             More details can be found
> > >                             at
> > https://github.com/kevinbarabash/operator-overloading.
> > >                             The babel plugin can be found
> > >                             at
> > https://github.com/kevinbarabash/babel-plugin-operator-overloading.
> > >                             I also have a demo project at
> > >
> > https://github.com/kevinbarabash/operator-overloading-demo.
> > >
> > >                             The design was inspired by some of the
> > >                             slides from
> > >
> > http://www.slideshare.net/BrendanEich/js-resp.
> > >
> > >                             – Kevin
> > >
> > >
> > >
> > >
> > >                         _______________________________________________
> > >                         es-discuss mailing list
> > >                         [hidden email]
> > >                         <mailto:[hidden email]>
> > >                         https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >                     _______________________________________________
> > >                     es-discuss mailing list
> > >                     [hidden email] <mailto:
> > [hidden email]>
> > >                     https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >                 _______________________________________________
> > >                 es-discuss mailing list
> > >                 [hidden email] <mailto:[hidden email]>
> > >                 https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >             _______________________________________________
> > >             es-discuss mailing list
> > >             [hidden email] <mailto:[hidden email]>
> > >             https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >         _______________________________________________
> > >         es-discuss mailing list
> > >         [hidden email] <mailto:[hidden email]>
> > >         https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >     _______________________________________________
> > >     es-discuss mailing list
> > >     [hidden email] <mailto:[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
> >
>

_______________________________________________
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



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

Re: operator overloading proposal

Dawid Szlachta
But, do we really need operator overloading? A method can be used instead, I think.

2016-05-11 8:53 GMT+02:00 Isiah Meadows <[hidden email]>:

Efficiency and optimization. If you're stupid enough to want to violate those priorities in a public API, it's your own fault. But if you want to optimize updating a collection (i.e. zero allocation update for a persistent map) or increment a vector by another without having to create an intermediate vector, you'll want to implement the assignment operator as well as the standard math operator.


On Wed, May 11, 2016, 02:46 Jordan Harband <[hidden email]> wrote:
Why would you ever want to violate the algebraic properties of operators, such that `a += b` wasn't exactly equivalent to `a = a + b`, `a *= b` not equivalent to `a = a * b`, etc? I'm quite confident that any proposal that allowed for that would get tons of pushback.

On Tue, May 10, 2016 at 11:26 PM, Isiah Meadows <[hidden email]> wrote:
1. Yes, they would be inherited, but not on the prototype itself (it would technically be parasitic). It would be modeled with internal slots, so that the properties are themselves immutable and transparent, so the only way to inherit would be via the class syntax or `Reflect.construct`. Engines could model this similarly to prototypes internally, while still appearing to conform to spec, since there's no other way to access the function without explicit reference via a decorator. And if it's not decorated, you can transparently fast path the calls automatically and optimize the function at compile time for exactly the number of arguments (any different is a syntax error, like with getters and setters). 

2. I'm intentionally trying to avoid any semantics that would rely on adding more values to the global scope. First, it's harder to optimize a `hasOwnProperty` check. Second, when you allow properties to be dynamically added, you make it impossible to lower `foo + bar` to a single instruction if they're both numbers, because someone can change the Number prototype to have one of the operators on it, and now, the assumption, previously prevalent, is now invalid. Third, we shouldn't need to add 15+ new symbols to accommodate a simple operation. 

3. If it's pure syntax, you won't have the edge cases of `x += y` having to desugar to `x = x[Symbol.assignPlus](y)` and so on. You just look for an `[[OpAssignPlus]]` on `x`, and if it exists, call it as `x.[[OpAssignPlus]](y)`. Else, you check for `[[OpPlus]]`, and set `x` to `x.[[OpPlus]](y)`. If neither exists, you fall back to the old algorithm. This can be easily optimized by the fact engines only need to check this if the value is an object. Numbers and strings don't have this slot. 

Note: If the right side has an operator defined, but the left side doesn't, and if the operator checked for isn't an assignment one, the right side's operator is checked and called. Or basically, beyond assignment, the mere existence of a slot takes precedence over no slot, to make transitivity easier with primitives. To clarify, in the below case:

```js
class C {
    constructor(x) { this.x = x }
    operator +(x) {
        if (x instanceof C) {
            return this + x.x * 2
        }
        return this.x + x
    }
}

assert(new C(1) + 1 === 1 +1)
assert(1 + new C(1) === 1 + 1)
assert(new C(1) + new C(2) === 1 + 2*2)
assert(new C(2) + new C(1) === 2 + 1*2)
```

On Wed, May 11, 2016, 01:27 Kevin Barabash <[hidden email]> wrote:
I would prefer syntax + internal slots, since you'll know at creation time whether the object has overloaded 
> operators. It's much simpler for the engine to figure out, and it's more performant because you only need to 
> check one thing instead of worrying about inheritance, own properties, etc.

Will operators defined on a class work with instances of a subclass?

Could += be a special case? i.e.,

For sure.  We could define `Symbol.assignPlus`, `Symbol.assignTimes`, etc. with `u += v;` desugaring to `u = u[Symbol.assignPlus](v)`.  The reason why we can't do something do `u[Symbol.assignPlus](v)` is that there's no way to define a method on Number, String, etc. that would reassign their value.

it appears to me that overloading an operator multiple times (e. g. unary/binary plus operator) might become 
> painful, assuming that the semantics follow the same variadic approach that regular functions do.

Another pain point is handling cases where you want one class to interoperate with another.  In one of the example above methods are defined that allow `Point`s and `Number`s to be added to each other.  In order to maintain the commutativity of `+` we need to define `operator+` / `[Symbol.add]` methods on both `Point` and `Number`.  One potential solution to this problem is create `Symbol.plusRight`, `Symbol.timesRight` for all of the commutative/symmetric operators.  

I feel like this ends up making things more complex because there are more methods to implement and the methods have to be more complex b/c they have to do type checking when overloaded.

Maybe `operator+` could work like the `@operator` decorator by calling `Function.defineOperator` behind the scenes.  In this situation, instead of methods being added to classes, the `Function` object has well-defined methods that look up the correct function to call based on the argument types.  `u + v` desugars to `Function[Symbol.plus](u, v)`.  This is definitely slower than internal slots, but if we're doing runtime type checking in the method we may as well have it be automatic.  My hope is to eventually use static typing (flow b/c I'm using babel) to remove the lookup cost.
 

On Tue, May 10, 2016 at 7:07 PM, Isiah Meadows <[hidden email]> wrote:

You're correct in that the operator doesn't do any type checking (it dispatches from its first argument, but that's just traditional OO).


On Tue, May 10, 2016, 20:28 kdex <[hidden email]> wrote:
@Isiah: Comparing your syntax proposal to `Function.defineOperator`, it appears to me that
overloading an operator multiple times (e. g. unary/binary plus operator) might become painful,
assuming that the semantics follow the same variadic approach that regular functions do.

That is, of course, unless you intend to handle all operator overloads in a single `operator +(...args) {}`
definition. But then again, something like `Function.defineOperator` seems cleaner and suggests implicit
(optional?) type checks with its second argument.

On Dienstag, 10. Mai 2016 15:25:32 CEST Isiah Meadows wrote:
> Here's my thought, if we go with syntax.
>
> ```js
> class Point {
>     // constructor, etc.
>
>     operator +(other) {
>         assert(other instanceof Point)
>         return new Point(
>             this.x + other.x,
>             this.y + other.y)
>     }
>
>     operator +=(other) {
>         assert(other instanceof Point)
>         this.x += other.x
>         this.y += other.y
>     }
> }
> ```
>
> On Tue, May 10, 2016, 11:16 Brian Barnes <[hidden email]> wrote:
>
> > A note on this from somebody who's entire existence seems dedicated to
> > stopping as much stuff as possible from getting GC'd, the example below:
> >
> >  >const u = new Point(5, 10);
> >  >const v = new Point(1, -2);
> >  >
> >  >const w = u + v;  // desugars to u[Symbol.add](v)
> >  >console.log(w);   // { x: 6, y: 8 };
> >
> > Could += be a special case?  i.e.,
> >
> > u+=v;
> >
> > would call:
> >
> > Class Point { ... other stuff ...
> > [whatever the syntax is](pt)
> > {
> > this.x+=pt.x;
> > this.y+=pt.y;
> > }
> > }
> >
> > instead of desugaring to:
> >
> > u=u+v;          // which would cause the creation of an object and
> >                 // leave the other to be collected
> >
> > For all I know, += might be doing such anyway in some engines, but for
> > my stuff which is a lot of 3D math that could be a performance killer.
> > It would be nice to be able to just add points and such, as long as the
> > overhead is negligible.
> >
> > [>] Brian
> >
> > On 5/10/2016 10:52 AM, Isiah Meadows wrote:
> > > I would prefer syntax + internal slots, since you'll know at creation
> > > time whether the object has overloaded operators. It's much simpler for
> > > the engine to figure out, and it's more performant because you only need
> > > to check one thing instead of worrying about inheritance, own
> > > properties, etc.
> > >
> > > Also, it would be IMHO easier to read than a symbol (the computed
> > > property syntax is ugly IMO). Using a different concept than symbols
> > > would also fit better with value types whenever any of those proposals
> > > make it into the language (either the struct or special syntax).
> > >
> > >
> > > On Tue, May 10, 2016, 04:03 G. Kay Lee
> > > <[hidden email]
> > > <mailto:[hidden email]>> wrote:
> > >
> > >     Yes, I think exposing operators through well-known symbols is an
> > >     interesting idea worthy of more exploration because it's precisely
> > >     the purpose of well-known symbols to expose and allow manipulation
> > >     to previously inaccessible internal language behaviors.
> > >
> > >     On Tue, May 10, 2016 at 1:59 PM, Kevin Barabash
> > >     <[hidden email] <mailto:[hidden email]>> wrote:
> > >
> > >         > And remember that decorators are essentially just a syntax to
> > >         apply functions to objects/classes at design time, so what
> > >         you're proposing is essentially some new global function, which
> > >         is going against the current trend and effort to better
> > >         modularize/namespace all these utility functions/methods.
> > >
> > >         That's a really good point.
> > >
> > >         > It has been mentioned and discussed in numerous places over the
> > >         years, you can find more info on this with some casual googling.
> > >         For example:https://news.ycombinator.com/item?id=2983420
> > >
> > >         Thanks for the link.  I played around with sweet.js a bit over
> > >         the weekend.  Using macros should work if we went with Python
> > >         style operator overloading.  Instead of defining methods like
> > >         _ADD_, _SUB_ etc. we could create some well-known symbols, maybe
> > >         Symbol.plus, Symbol.times, etc.
> > >
> > >         ```
> > >         class Point {
> > >           constructor(x, y) {
> > >             Object.assign(this, {x, y});
> > >           }
> > >
> > >           [Symbol.add](other) {
> > >             return new Point(this.x + other.x, this.y + other.y);
> > >           }
> > >         }
> > >
> > >         const u = new Point(5, 10);
> > >         const v = new Point(1, -2);
> > >
> > >         const w = u + v;  // desugars to u[Symbol.add](v)
> > >         console.log(w);   // { x: 6, y: 8 };
> > >         ```
> > >
> > >         This would require default implementations to be defined on
> > >         Object.prototype for Symbol.plus, Symbol.times, etc.
> > >
> > >
> > >         On Sun, May 8, 2016 at 10:38 PM, G. Kay Lee
> > >         <[hidden email]
> > >         <mailto:[hidden email]>> wrote:
> > >
> > >             > Why not? The standard defines well-known symbols. Maybe
> > `@operator` could be a well known decorator (assuming decorators get
> > approved).
> > >
> > >             Well... you make something into the standard with proposals,
> > >             not why-nots, so in order to make that happen you need to
> > >             draft another proposal for well-known decorators. And
> > >             remember that decorators are essentially just a syntax to
> > >             apply functions to objects/classes at design time, so what
> > >             you're proposing is essentially some new global function,
> > >             which is going against the current trend and effort to
> > >             better modularize/namespace all these utility
> > >             functions/methods. And maybe a new mechanism could be
> > >             drafted for these new well-known decorators, so that we can
> > >             hide these new functions somewhere... but by now I hope it's
> > >             becoming clear that it's introducing way too much new
> > >             surface area for the language in exchange for one small
> > feature.
> > >
> > >             > I haven't seen any proposals for macros, could you post a
> > link?
> > >
> > >             It has been mentioned and discussed in numerous places over
> > >             the years, you can find more info on this with some casual
> > >             googling. For example:
> > >             https://news.ycombinator.com/item?id=2983420
> > >
> > >
> > >
> > >             On Sun, May 8, 2016 at 2:51 PM, Kevin Barabash
> > >             <[hidden email] <mailto:[hidden email]>>
> > wrote:
> > >
> > >                 I should update the demo code to show the `@operator`
> > >                 decorator in addition to `Function.defineOperator`.
> > >
> > >                 Initially I started out with just the `@operator`
> > >                 decorator, but that meant that each class would have to
> > >                 have knowledge of each of the classes it might want to
> > >                 interact with before hand.  Having a separate
> > >                 `defineOperator` function avoids this situation.
> > >
> > >                 It means that prototype style classes must be converted
> > >                 to the new class syntax before operator overloading
> > >                 could be used.  Lastly, there may be some cases where it
> > >                 makes sense to overload operators with existing 3rd
> > >                 party code or built-in classes, e.g. adding set
> > >                 operations to Set using operator overloading.
> > >
> > >                 > It's also apparent that the `@operator decorator` part
> > >                 of the proposal is an effort trying to address this
> > >                 issue, but it really is not the responsibility of the
> > >                 standard to try to define such a thing.
> > >
> > >                 Why not?  The standard defines well-known symbols.
> > >                 Maybe `@operator` could be a well known decorator
> > >                 (assuming decorators get approved).
> > >
> > >                 Slide 15
> > >                 from http://www.slideshare.net/BrendanEich/js-resp shows
> > >                 syntax for defining operators in value types which could
> > >                 be adapted as follows for regular classes:
> > >
> > >                 ```
> > >                 class Point {
> > >                    constructor(x, y) {
> > >                        this.x = +x;
> > >                        this.y = +y;
> > >                    }
> > >                    Point + Number (a, b) {
> > >                        return new Point(a.x + b, a.y + b);
> > >                    }
> > >                    Number + Point (a, b) {
> > >                        return new Point(a + b.x, a + b.y);
> > >                    }
> > >                    Point + Point (a, b) {
> > >                        return new Point(a.x + b.x, a.y + b.y);
> > >                    }
> > >                 }
> > >                 ```
> > >
> > >                 Having to define `+` twice for `Point + Number` and
> > >                 `Number + Point` seems like busy work, but maybe it's
> > >                 better to be explicit.  What are you thoughts about this
> > >                 syntax?
> > >
> > >                 > Another thing is that, IMHO, currently there are too
> > >                 much quirks/conventions in the proposal that feel
> > >                 non-evident and non-flexible which is destined to trip
> > >                 people over from time to time. It would be great to make
> > >                 a proposal that's simple and don't include too much
> > >                 assumptions.
> > >
> > >                 Could you elaborator what quirks/conventions might trip
> > >                 people up?
> > >
> > >                 > Finally, I'm not sure about the current status of
> > >                 macros, but last I heard of it, they say it's going to
> > >                 make its way into the standard pretty soon (TM), and
> > >                 macros can do much of the things overloading could, and
> > >                 much more.
> > >
> > >                 I haven't seen any proposals for macros, could you post
> > >                 a link?
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >                 On Sat, May 7, 2016 at 9:55 PM, G. Kay Lee
> > >                 <[hidden email]
> > >                 <mailto:[hidden email]>> wrote:
> > >
> > >                     I'd say it's way too early to ask for a champion on
> > >                     this because just a quick skimming revealed a lot of
> > >                     places that didn't add up. For example, the proposal
> > >                     suggested that overloading is primarily targeted at
> > >                     making it easier to work with user-defined classes,
> > >                     but curiously a `Function.defineOperator()` method
> > >                     is proposed instead of some syntax that feels more
> > >                     tightly integrated with the class definition syntax.
> > >
> > >                     ```
> > >
> > >                     class Point {
> > >                         constructor(x, y) {
> > >                             Object.assign(this, { x, y });
> > >                         }
> > >
> > >                         toString() {
> > >                             return `(${this.x}, ${this.y})`;
> > >                         }
> > >                     }
> > >
> > >                     Function.defineOperator('+', [Point, Point], (a, b)
> > => new Point(a.x + b.x, a.y + b.y));
> > >
> > >                     ```
> > >
> > >                     The demo code made this flaw evident - it looks like
> > >                     a giant step backward to define an instance method
> > >                     like this, don't you agree?
> > >
> > >                     It's also apparent that the `@operator decorator`
> > >                     part of the proposal is an effort trying to address
> > >                     this issue, but it really is not the responsibility
> > >                     of the standard to try to define such a thing.
> > >
> > >                     What I'd suggest is that perhaps you should rethink
> > >                     your proposed syntax and redesign it to become an
> > >                     extension of the ES6 class definition syntax.
> > >
> > >                     Another thing is that, IMHO, currently there are too
> > >                     much quirks/conventions in the proposal that feel
> > >                     non-evident and non-flexible which is destined to
> > >                     trip people over from time to time. It would be
> > >                     great to make a proposal that's simple and don't
> > >                     include too much assumptions.
> > >
> > >                     Finally, I'm not sure about the current status of
> > >                     macros, but last I heard of it, they say it's going
> > >                     to make its way into the standard pretty soon (TM),
> > >                     and macros can do much of the things overloading
> > >                     could, and much more.
> > >
> > >                     On Sun, May 8, 2016 at 8:51 AM, Kevin Barabash
> > >                     <[hidden email]
> > >                     <mailto:[hidden email]>> wrote:
> > >
> > >                         I forgot to mention in my last email that I'm
> > >                         looking for a champion for this proposal.
> > >
> > >                         On Sat, May 7, 2016 at 5:24 PM, Kevin Barabash
> > >                         <[hidden email]
> > >                         <mailto:[hidden email]>> wrote:
> > >
> > >                             Hi everyone,
> > >
> > >                             I've been working on implementing operator
> > >                             overloading and would like to submit a
> > proposal.
> > >
> > >                             I think operator overloading would be a
> > >                             useful addition to the language.  In
> > >                             particular I think it would be useful for
> > >                             defining operations on common mathematical
> > >                             object types such as complex numbers,
> > >                             vectors, matrices, and sets.
> > >
> > >                             I've create a working prototype that
> > >                             consists of:
> > >
> > >                               * babel plugin that rewrites operators as
> > >                                 function calls
> > >                               * a polyfill which defines these functions
> > >                                 and which call the correct
> > >                                 argument-specific function based on the
> > >                                 arguments' prototypes
> > >                               * Function.defineOperator which can be
> > >                                 used to define which function an
> > >                                 operator should use for the specified
> > types
> > >                               * "use overloading" directive which allows
> > >                                 users to opt-in
> > >
> > >                             More details can be found
> > >                             at
> > https://github.com/kevinbarabash/operator-overloading.
> > >                             The babel plugin can be found
> > >                             at
> > https://github.com/kevinbarabash/babel-plugin-operator-overloading.
> > >                             I also have a demo project at
> > >
> > https://github.com/kevinbarabash/operator-overloading-demo.
> > >
> > >                             The design was inspired by some of the
> > >                             slides from
> > >
> > http://www.slideshare.net/BrendanEich/js-resp.
> > >
> > >                             – Kevin
> > >
> > >
> > >
> > >
> > >                         _______________________________________________
> > >                         es-discuss mailing list
> > >                         [hidden email]
> > >                         <mailto:[hidden email]>
> > >                         https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >                     _______________________________________________
> > >                     es-discuss mailing list
> > >                     [hidden email] <mailto:
> > [hidden email]>
> > >                     https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >                 _______________________________________________
> > >                 es-discuss mailing list
> > >                 [hidden email] <mailto:[hidden email]>
> > >                 https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >             _______________________________________________
> > >             es-discuss mailing list
> > >             [hidden email] <mailto:[hidden email]>
> > >             https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >         _______________________________________________
> > >         es-discuss mailing list
> > >         [hidden email] <mailto:[hidden email]>
> > >         https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >     _______________________________________________
> > >     es-discuss mailing list
> > >     [hidden email] <mailto:[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
> >
>

_______________________________________________
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



_______________________________________________
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: operator overloading proposal

Isiah Meadows-2

That's the current state of things. I think the main issue at hand is ergonomics. Haskell, the MLs, and Swift solved it by allowing inline functions and operators as functions (that wouldn't work in a dynamic language). Scala solved it by magic methods for unary operations and the fact nearly every character is a valid identifier for binary ones (JS can't use that because of back compat issues). Lua, Ruby, Python, and Kotlin solved it by using magic methods. C++ solved it with the `operator` keyword.


On Wed, May 11, 2016, 03:26 Dawid Szlachta <[hidden email]> wrote:
But, do we really need operator overloading? A method can be used instead, I think.

2016-05-11 8:53 GMT+02:00 Isiah Meadows <[hidden email]>:

Efficiency and optimization. If you're stupid enough to want to violate those priorities in a public API, it's your own fault. But if you want to optimize updating a collection (i.e. zero allocation update for a persistent map) or increment a vector by another without having to create an intermediate vector, you'll want to implement the assignment operator as well as the standard math operator.


On Wed, May 11, 2016, 02:46 Jordan Harband <[hidden email]> wrote:
Why would you ever want to violate the algebraic properties of operators, such that `a += b` wasn't exactly equivalent to `a = a + b`, `a *= b` not equivalent to `a = a * b`, etc? I'm quite confident that any proposal that allowed for that would get tons of pushback.

On Tue, May 10, 2016 at 11:26 PM, Isiah Meadows <[hidden email]> wrote:
1. Yes, they would be inherited, but not on the prototype itself (it would technically be parasitic). It would be modeled with internal slots, so that the properties are themselves immutable and transparent, so the only way to inherit would be via the class syntax or `Reflect.construct`. Engines could model this similarly to prototypes internally, while still appearing to conform to spec, since there's no other way to access the function without explicit reference via a decorator. And if it's not decorated, you can transparently fast path the calls automatically and optimize the function at compile time for exactly the number of arguments (any different is a syntax error, like with getters and setters). 

2. I'm intentionally trying to avoid any semantics that would rely on adding more values to the global scope. First, it's harder to optimize a `hasOwnProperty` check. Second, when you allow properties to be dynamically added, you make it impossible to lower `foo + bar` to a single instruction if they're both numbers, because someone can change the Number prototype to have one of the operators on it, and now, the assumption, previously prevalent, is now invalid. Third, we shouldn't need to add 15+ new symbols to accommodate a simple operation. 

3. If it's pure syntax, you won't have the edge cases of `x += y` having to desugar to `x = x[Symbol.assignPlus](y)` and so on. You just look for an `[[OpAssignPlus]]` on `x`, and if it exists, call it as `x.[[OpAssignPlus]](y)`. Else, you check for `[[OpPlus]]`, and set `x` to `x.[[OpPlus]](y)`. If neither exists, you fall back to the old algorithm. This can be easily optimized by the fact engines only need to check this if the value is an object. Numbers and strings don't have this slot. 

Note: If the right side has an operator defined, but the left side doesn't, and if the operator checked for isn't an assignment one, the right side's operator is checked and called. Or basically, beyond assignment, the mere existence of a slot takes precedence over no slot, to make transitivity easier with primitives. To clarify, in the below case:

```js
class C {
    constructor(x) { this.x = x }
    operator +(x) {
        if (x instanceof C) {
            return this + x.x * 2
        }
        return this.x + x
    }
}

assert(new C(1) + 1 === 1 +1)
assert(1 + new C(1) === 1 + 1)
assert(new C(1) + new C(2) === 1 + 2*2)
assert(new C(2) + new C(1) === 2 + 1*2)
```

On Wed, May 11, 2016, 01:27 Kevin Barabash <[hidden email]> wrote:
I would prefer syntax + internal slots, since you'll know at creation time whether the object has overloaded 
> operators. It's much simpler for the engine to figure out, and it's more performant because you only need to 
> check one thing instead of worrying about inheritance, own properties, etc.

Will operators defined on a class work with instances of a subclass?

Could += be a special case? i.e.,

For sure.  We could define `Symbol.assignPlus`, `Symbol.assignTimes`, etc. with `u += v;` desugaring to `u = u[Symbol.assignPlus](v)`.  The reason why we can't do something do `u[Symbol.assignPlus](v)` is that there's no way to define a method on Number, String, etc. that would reassign their value.

it appears to me that overloading an operator multiple times (e. g. unary/binary plus operator) might become 
> painful, assuming that the semantics follow the same variadic approach that regular functions do.

Another pain point is handling cases where you want one class to interoperate with another.  In one of the example above methods are defined that allow `Point`s and `Number`s to be added to each other.  In order to maintain the commutativity of `+` we need to define `operator+` / `[Symbol.add]` methods on both `Point` and `Number`.  One potential solution to this problem is create `Symbol.plusRight`, `Symbol.timesRight` for all of the commutative/symmetric operators.  

I feel like this ends up making things more complex because there are more methods to implement and the methods have to be more complex b/c they have to do type checking when overloaded.

Maybe `operator+` could work like the `@operator` decorator by calling `Function.defineOperator` behind the scenes.  In this situation, instead of methods being added to classes, the `Function` object has well-defined methods that look up the correct function to call based on the argument types.  `u + v` desugars to `Function[Symbol.plus](u, v)`.  This is definitely slower than internal slots, but if we're doing runtime type checking in the method we may as well have it be automatic.  My hope is to eventually use static typing (flow b/c I'm using babel) to remove the lookup cost.
 

On Tue, May 10, 2016 at 7:07 PM, Isiah Meadows <[hidden email]> wrote:

You're correct in that the operator doesn't do any type checking (it dispatches from its first argument, but that's just traditional OO).


On Tue, May 10, 2016, 20:28 kdex <[hidden email]> wrote:
@Isiah: Comparing your syntax proposal to `Function.defineOperator`, it appears to me that
overloading an operator multiple times (e. g. unary/binary plus operator) might become painful,
assuming that the semantics follow the same variadic approach that regular functions do.

That is, of course, unless you intend to handle all operator overloads in a single `operator +(...args) {}`
definition. But then again, something like `Function.defineOperator` seems cleaner and suggests implicit
(optional?) type checks with its second argument.

On Dienstag, 10. Mai 2016 15:25:32 CEST Isiah Meadows wrote:
> Here's my thought, if we go with syntax.
>
> ```js
> class Point {
>     // constructor, etc.
>
>     operator +(other) {
>         assert(other instanceof Point)
>         return new Point(
>             this.x + other.x,
>             this.y + other.y)
>     }
>
>     operator +=(other) {
>         assert(other instanceof Point)
>         this.x += other.x
>         this.y += other.y
>     }
> }
> ```
>
> On Tue, May 10, 2016, 11:16 Brian Barnes <[hidden email]> wrote:
>
> > A note on this from somebody who's entire existence seems dedicated to
> > stopping as much stuff as possible from getting GC'd, the example below:
> >
> >  >const u = new Point(5, 10);
> >  >const v = new Point(1, -2);
> >  >
> >  >const w = u + v;  // desugars to u[Symbol.add](v)
> >  >console.log(w);   // { x: 6, y: 8 };
> >
> > Could += be a special case?  i.e.,
> >
> > u+=v;
> >
> > would call:
> >
> > Class Point { ... other stuff ...
> > [whatever the syntax is](pt)
> > {
> > this.x+=pt.x;
> > this.y+=pt.y;
> > }
> > }
> >
> > instead of desugaring to:
> >
> > u=u+v;          // which would cause the creation of an object and
> >                 // leave the other to be collected
> >
> > For all I know, += might be doing such anyway in some engines, but for
> > my stuff which is a lot of 3D math that could be a performance killer.
> > It would be nice to be able to just add points and such, as long as the
> > overhead is negligible.
> >
> > [>] Brian
> >
> > On 5/10/2016 10:52 AM, Isiah Meadows wrote:
> > > I would prefer syntax + internal slots, since you'll know at creation
> > > time whether the object has overloaded operators. It's much simpler for
> > > the engine to figure out, and it's more performant because you only need
> > > to check one thing instead of worrying about inheritance, own
> > > properties, etc.
> > >
> > > Also, it would be IMHO easier to read than a symbol (the computed
> > > property syntax is ugly IMO). Using a different concept than symbols
> > > would also fit better with value types whenever any of those proposals
> > > make it into the language (either the struct or special syntax).
> > >
> > >
> > > On Tue, May 10, 2016, 04:03 G. Kay Lee
> > > <[hidden email]
> > > <mailto:[hidden email]>> wrote:
> > >
> > >     Yes, I think exposing operators through well-known symbols is an
> > >     interesting idea worthy of more exploration because it's precisely
> > >     the purpose of well-known symbols to expose and allow manipulation
> > >     to previously inaccessible internal language behaviors.
> > >
> > >     On Tue, May 10, 2016 at 1:59 PM, Kevin Barabash
> > >     <[hidden email] <mailto:[hidden email]>> wrote:
> > >
> > >         > And remember that decorators are essentially just a syntax to
> > >         apply functions to objects/classes at design time, so what
> > >         you're proposing is essentially some new global function, which
> > >         is going against the current trend and effort to better
> > >         modularize/namespace all these utility functions/methods.
> > >
> > >         That's a really good point.
> > >
> > >         > It has been mentioned and discussed in numerous places over the
> > >         years, you can find more info on this with some casual googling.
> > >         For example:https://news.ycombinator.com/item?id=2983420
> > >
> > >         Thanks for the link.  I played around with sweet.js a bit over
> > >         the weekend.  Using macros should work if we went with Python
> > >         style operator overloading.  Instead of defining methods like
> > >         _ADD_, _SUB_ etc. we could create some well-known symbols, maybe
> > >         Symbol.plus, Symbol.times, etc.
> > >
> > >         ```
> > >         class Point {
> > >           constructor(x, y) {
> > >             Object.assign(this, {x, y});
> > >           }
> > >
> > >           [Symbol.add](other) {
> > >             return new Point(this.x + other.x, this.y + other.y);
> > >           }
> > >         }
> > >
> > >         const u = new Point(5, 10);
> > >         const v = new Point(1, -2);
> > >
> > >         const w = u + v;  // desugars to u[Symbol.add](v)
> > >         console.log(w);   // { x: 6, y: 8 };
> > >         ```
> > >
> > >         This would require default implementations to be defined on
> > >         Object.prototype for Symbol.plus, Symbol.times, etc.
> > >
> > >
> > >         On Sun, May 8, 2016 at 10:38 PM, G. Kay Lee
> > >         <[hidden email]
> > >         <mailto:[hidden email]>> wrote:
> > >
> > >             > Why not? The standard defines well-known symbols. Maybe
> > `@operator` could be a well known decorator (assuming decorators get
> > approved).
> > >
> > >             Well... you make something into the standard with proposals,
> > >             not why-nots, so in order to make that happen you need to
> > >             draft another proposal for well-known decorators. And
> > >             remember that decorators are essentially just a syntax to
> > >             apply functions to objects/classes at design time, so what
> > >             you're proposing is essentially some new global function,
> > >             which is going against the current trend and effort to
> > >             better modularize/namespace all these utility
> > >             functions/methods. And maybe a new mechanism could be
> > >             drafted for these new well-known decorators, so that we can
> > >             hide these new functions somewhere... but by now I hope it's
> > >             becoming clear that it's introducing way too much new
> > >             surface area for the language in exchange for one small
> > feature.
> > >
> > >             > I haven't seen any proposals for macros, could you post a
> > link?
> > >
> > >             It has been mentioned and discussed in numerous places over
> > >             the years, you can find more info on this with some casual
> > >             googling. For example:
> > >             https://news.ycombinator.com/item?id=2983420
> > >
> > >
> > >
> > >             On Sun, May 8, 2016 at 2:51 PM, Kevin Barabash
> > >             <[hidden email] <mailto:[hidden email]>>
> > wrote:
> > >
> > >                 I should update the demo code to show the `@operator`
> > >                 decorator in addition to `Function.defineOperator`.
> > >
> > >                 Initially I started out with just the `@operator`
> > >                 decorator, but that meant that each class would have to
> > >                 have knowledge of each of the classes it might want to
> > >                 interact with before hand.  Having a separate
> > >                 `defineOperator` function avoids this situation.
> > >
> > >                 It means that prototype style classes must be converted
> > >                 to the new class syntax before operator overloading
> > >                 could be used.  Lastly, there may be some cases where it
> > >                 makes sense to overload operators with existing 3rd
> > >                 party code or built-in classes, e.g. adding set
> > >                 operations to Set using operator overloading.
> > >
> > >                 > It's also apparent that the `@operator decorator` part
> > >                 of the proposal is an effort trying to address this
> > >                 issue, but it really is not the responsibility of the
> > >                 standard to try to define such a thing.
> > >
> > >                 Why not?  The standard defines well-known symbols.
> > >                 Maybe `@operator` could be a well known decorator
> > >                 (assuming decorators get approved).
> > >
> > >                 Slide 15
> > >                 from http://www.slideshare.net/BrendanEich/js-resp shows
> > >                 syntax for defining operators in value types which could
> > >                 be adapted as follows for regular classes:
> > >
> > >                 ```
> > >                 class Point {
> > >                    constructor(x, y) {
> > >                        this.x = +x;
> > >                        this.y = +y;
> > >                    }
> > >                    Point + Number (a, b) {
> > >                        return new Point(a.x + b, a.y + b);
> > >                    }
> > >                    Number + Point (a, b) {
> > >                        return new Point(a + b.x, a + b.y);
> > >                    }
> > >                    Point + Point (a, b) {
> > >                        return new Point(a.x + b.x, a.y + b.y);
> > >                    }
> > >                 }
> > >                 ```
> > >
> > >                 Having to define `+` twice for `Point + Number` and
> > >                 `Number + Point` seems like busy work, but maybe it's
> > >                 better to be explicit.  What are you thoughts about this
> > >                 syntax?
> > >
> > >                 > Another thing is that, IMHO, currently there are too
> > >                 much quirks/conventions in the proposal that feel
> > >                 non-evident and non-flexible which is destined to trip
> > >                 people over from time to time. It would be great to make
> > >                 a proposal that's simple and don't include too much
> > >                 assumptions.
> > >
> > >                 Could you elaborator what quirks/conventions might trip
> > >                 people up?
> > >
> > >                 > Finally, I'm not sure about the current status of
> > >                 macros, but last I heard of it, they say it's going to
> > >                 make its way into the standard pretty soon (TM), and
> > >                 macros can do much of the things overloading could, and
> > >                 much more.
> > >
> > >                 I haven't seen any proposals for macros, could you post
> > >                 a link?
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >                 On Sat, May 7, 2016 at 9:55 PM, G. Kay Lee
> > >                 <[hidden email]
> > >                 <mailto:[hidden email]>> wrote:
> > >
> > >                     I'd say it's way too early to ask for a champion on
> > >                     this because just a quick skimming revealed a lot of
> > >                     places that didn't add up. For example, the proposal
> > >                     suggested that overloading is primarily targeted at
> > >                     making it easier to work with user-defined classes,
> > >                     but curiously a `Function.defineOperator()` method
> > >                     is proposed instead of some syntax that feels more
> > >                     tightly integrated with the class definition syntax.
> > >
> > >                     ```
> > >
> > >                     class Point {
> > >                         constructor(x, y) {
> > >                             Object.assign(this, { x, y });
> > >                         }
> > >
> > >                         toString() {
> > >                             return `(${this.x}, ${this.y})`;
> > >                         }
> > >                     }
> > >
> > >                     Function.defineOperator('+', [Point, Point], (a, b)
> > => new Point(a.x + b.x, a.y + b.y));
> > >
> > >                     ```
> > >
> > >                     The demo code made this flaw evident - it looks like
> > >                     a giant step backward to define an instance method
> > >                     like this, don't you agree?
> > >
> > >                     It's also apparent that the `@operator decorator`
> > >                     part of the proposal is an effort trying to address
> > >                     this issue, but it really is not the responsibility
> > >                     of the standard to try to define such a thing.
> > >
> > >                     What I'd suggest is that perhaps you should rethink
> > >                     your proposed syntax and redesign it to become an
> > >                     extension of the ES6 class definition syntax.
> > >
> > >                     Another thing is that, IMHO, currently there are too
> > >                     much quirks/conventions in the proposal that feel
> > >                     non-evident and non-flexible which is destined to
> > >                     trip people over from time to time. It would be
> > >                     great to make a proposal that's simple and don't
> > >                     include too much assumptions.
> > >
> > >                     Finally, I'm not sure about the current status of
> > >                     macros, but last I heard of it, they say it's going
> > >                     to make its way into the standard pretty soon (TM),
> > >                     and macros can do much of the things overloading
> > >                     could, and much more.
> > >
> > >                     On Sun, May 8, 2016 at 8:51 AM, Kevin Barabash
> > >                     <[hidden email]
> > >                     <mailto:[hidden email]>> wrote:
> > >
> > >                         I forgot to mention in my last email that I'm
> > >                         looking for a champion for this proposal.
> > >
> > >                         On Sat, May 7, 2016 at 5:24 PM, Kevin Barabash
> > >                         <[hidden email]
> > >                         <mailto:[hidden email]>> wrote:
> > >
> > >                             Hi everyone,
> > >
> > >                             I've been working on implementing operator
> > >                             overloading and would like to submit a
> > proposal.
> > >
> > >                             I think operator overloading would be a
> > >                             useful addition to the language.  In
> > >                             particular I think it would be useful for
> > >                             defining operations on common mathematical
> > >                             object types such as complex numbers,
> > >                             vectors, matrices, and sets.
> > >
> > >                             I've create a working prototype that
> > >                             consists of:
> > >
> > >                               * babel plugin that rewrites operators as
> > >                                 function calls
> > >                               * a polyfill which defines these functions
> > >                                 and which call the correct
> > >                                 argument-specific function based on the
> > >                                 arguments' prototypes
> > >                               * Function.defineOperator which can be
> > >                                 used to define which function an
> > >                                 operator should use for the specified
> > types
> > >                               * "use overloading" directive which allows
> > >                                 users to opt-in
> > >
> > >                             More details can be found
> > >                             at
> > https://github.com/kevinbarabash/operator-overloading.
> > >                             The babel plugin can be found
> > >                             at
> > https://github.com/kevinbarabash/babel-plugin-operator-overloading.
> > >                             I also have a demo project at
> > >
> > https://github.com/kevinbarabash/operator-overloading-demo.
> > >
> > >                             The design was inspired by some of the
> > >                             slides from
> > >
> > http://www.slideshare.net/BrendanEich/js-resp.
> > >
> > >                             – Kevin
> > >
> > >
> > >
> > >
> > >                         _______________________________________________
> > >                         es-discuss mailing list
> > >                         [hidden email]
> > >                         <mailto:[hidden email]>
> > >                         https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >                     _______________________________________________
> > >                     es-discuss mailing list
> > >                     [hidden email] <mailto:
> > [hidden email]>
> > >                     https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >                 _______________________________________________
> > >                 es-discuss mailing list
> > >                 [hidden email] <mailto:[hidden email]>
> > >                 https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >             _______________________________________________
> > >             es-discuss mailing list
> > >             [hidden email] <mailto:[hidden email]>
> > >             https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >         _______________________________________________
> > >         es-discuss mailing list
> > >         [hidden email] <mailto:[hidden email]>
> > >         https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >     _______________________________________________
> > >     es-discuss mailing list
> > >     [hidden email] <mailto:[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
> >
>

_______________________________________________
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



_______________________________________________
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: operator overloading proposal

Kevin Barabash
@Isiah: Great points.  One potential edge case though:

```js
class A {
    operator+ (other) { }
}

class B {
    operator+ (other) { }
}

const a = new A();
const b = new B();
const c = a + b;
```

In the case where both the left and right side have `[[OpPlus]]` do we prefer the left side?

But, do we really need operator overloading? A method can be used instead, I think.

@Dawid: Suppose I create a class to represent complex numbers that looks like this:

```js
class Complex {
    constructor(re, im) {
         Object.assign({ }, { re, im });
    }
    add(other) {
        return new Complex(this.re + other.re, this.im + other.im);
    }
    ...
}
```

I might want to create instance of `Complex` with plain old numbers or I might want to use `BigNumber` instances.
Without operator overloading this means that I would have add methods to `Number.prototype` or wrap each number
in an object with methods.  Neither of which are particular appealing.



On Wed, May 11, 2016 at 1:28 AM, Isiah Meadows <[hidden email]> wrote:

That's the current state of things. I think the main issue at hand is ergonomics. Haskell, the MLs, and Swift solved it by allowing inline functions and operators as functions (that wouldn't work in a dynamic language). Scala solved it by magic methods for unary operations and the fact nearly every character is a valid identifier for binary ones (JS can't use that because of back compat issues). Lua, Ruby, Python, and Kotlin solved it by using magic methods. C++ solved it with the `operator` keyword.


On Wed, May 11, 2016, 03:26 Dawid Szlachta <[hidden email]> wrote:
But, do we really need operator overloading? A method can be used instead, I think.

2016-05-11 8:53 GMT+02:00 Isiah Meadows <[hidden email]>:

Efficiency and optimization. If you're stupid enough to want to violate those priorities in a public API, it's your own fault. But if you want to optimize updating a collection (i.e. zero allocation update for a persistent map) or increment a vector by another without having to create an intermediate vector, you'll want to implement the assignment operator as well as the standard math operator.


On Wed, May 11, 2016, 02:46 Jordan Harband <[hidden email]> wrote:
Why would you ever want to violate the algebraic properties of operators, such that `a += b` wasn't exactly equivalent to `a = a + b`, `a *= b` not equivalent to `a = a * b`, etc? I'm quite confident that any proposal that allowed for that would get tons of pushback.

On Tue, May 10, 2016 at 11:26 PM, Isiah Meadows <[hidden email]> wrote:
1. Yes, they would be inherited, but not on the prototype itself (it would technically be parasitic). It would be modeled with internal slots, so that the properties are themselves immutable and transparent, so the only way to inherit would be via the class syntax or `Reflect.construct`. Engines could model this similarly to prototypes internally, while still appearing to conform to spec, since there's no other way to access the function without explicit reference via a decorator. And if it's not decorated, you can transparently fast path the calls automatically and optimize the function at compile time for exactly the number of arguments (any different is a syntax error, like with getters and setters). 

2. I'm intentionally trying to avoid any semantics that would rely on adding more values to the global scope. First, it's harder to optimize a `hasOwnProperty` check. Second, when you allow properties to be dynamically added, you make it impossible to lower `foo + bar` to a single instruction if they're both numbers, because someone can change the Number prototype to have one of the operators on it, and now, the assumption, previously prevalent, is now invalid. Third, we shouldn't need to add 15+ new symbols to accommodate a simple operation. 

3. If it's pure syntax, you won't have the edge cases of `x += y` having to desugar to `x = x[Symbol.assignPlus](y)` and so on. You just look for an `[[OpAssignPlus]]` on `x`, and if it exists, call it as `x.[[OpAssignPlus]](y)`. Else, you check for `[[OpPlus]]`, and set `x` to `x.[[OpPlus]](y)`. If neither exists, you fall back to the old algorithm. This can be easily optimized by the fact engines only need to check this if the value is an object. Numbers and strings don't have this slot. 

Note: If the right side has an operator defined, but the left side doesn't, and if the operator checked for isn't an assignment one, the right side's operator is checked and called. Or basically, beyond assignment, the mere existence of a slot takes precedence over no slot, to make transitivity easier with primitives. To clarify, in the below case:

```js
class C {
    constructor(x) { this.x = x }
    operator +(x) {
        if (x instanceof C) {
            return this + x.x * 2
        }
        return this.x + x
    }
}

assert(new C(1) + 1 === 1 +1)
assert(1 + new C(1) === 1 + 1)
assert(new C(1) + new C(2) === 1 + 2*2)
assert(new C(2) + new C(1) === 2 + 1*2)
```

On Wed, May 11, 2016, 01:27 Kevin Barabash <[hidden email]> wrote:
I would prefer syntax + internal slots, since you'll know at creation time whether the object has overloaded 
> operators. It's much simpler for the engine to figure out, and it's more performant because you only need to 
> check one thing instead of worrying about inheritance, own properties, etc.

Will operators defined on a class work with instances of a subclass?

Could += be a special case? i.e.,

For sure.  We could define `Symbol.assignPlus`, `Symbol.assignTimes`, etc. with `u += v;` desugaring to `u = u[Symbol.assignPlus](v)`.  The reason why we can't do something do `u[Symbol.assignPlus](v)` is that there's no way to define a method on Number, String, etc. that would reassign their value.

it appears to me that overloading an operator multiple times (e. g. unary/binary plus operator) might become 
> painful, assuming that the semantics follow the same variadic approach that regular functions do.

Another pain point is handling cases where you want one class to interoperate with another.  In one of the example above methods are defined that allow `Point`s and `Number`s to be added to each other.  In order to maintain the commutativity of `+` we need to define `operator+` / `[Symbol.add]` methods on both `Point` and `Number`.  One potential solution to this problem is create `Symbol.plusRight`, `Symbol.timesRight` for all of the commutative/symmetric operators.  

I feel like this ends up making things more complex because there are more methods to implement and the methods have to be more complex b/c they have to do type checking when overloaded.

Maybe `operator+` could work like the `@operator` decorator by calling `Function.defineOperator` behind the scenes.  In this situation, instead of methods being added to classes, the `Function` object has well-defined methods that look up the correct function to call based on the argument types.  `u + v` desugars to `Function[Symbol.plus](u, v)`.  This is definitely slower than internal slots, but if we're doing runtime type checking in the method we may as well have it be automatic.  My hope is to eventually use static typing (flow b/c I'm using babel) to remove the lookup cost.
 

On Tue, May 10, 2016 at 7:07 PM, Isiah Meadows <[hidden email]> wrote:

You're correct in that the operator doesn't do any type checking (it dispatches from its first argument, but that's just traditional OO).


On Tue, May 10, 2016, 20:28 kdex <[hidden email]> wrote:
@Isiah: Comparing your syntax proposal to `Function.defineOperator`, it appears to me that
overloading an operator multiple times (e. g. unary/binary plus operator) might become painful,
assuming that the semantics follow the same variadic approach that regular functions do.

That is, of course, unless you intend to handle all operator overloads in a single `operator +(...args) {}`
definition. But then again, something like `Function.defineOperator` seems cleaner and suggests implicit
(optional?) type checks with its second argument.

On Dienstag, 10. Mai 2016 15:25:32 CEST Isiah Meadows wrote:
> Here's my thought, if we go with syntax.
>
> ```js
> class Point {
>     // constructor, etc.
>
>     operator +(other) {
>         assert(other instanceof Point)
>         return new Point(
>             this.x + other.x,
>             this.y + other.y)
>     }
>
>     operator +=(other) {
>         assert(other instanceof Point)
>         this.x += other.x
>         this.y += other.y
>     }
> }
> ```
>
> On Tue, May 10, 2016, 11:16 Brian Barnes <[hidden email]> wrote:
>
> > A note on this from somebody who's entire existence seems dedicated to
> > stopping as much stuff as possible from getting GC'd, the example below:
> >
> >  >const u = new Point(5, 10);
> >  >const v = new Point(1, -2);
> >  >
> >  >const w = u + v;  // desugars to u[Symbol.add](v)
> >  >console.log(w);   // { x: 6, y: 8 };
> >
> > Could += be a special case?  i.e.,
> >
> > u+=v;
> >
> > would call:
> >
> > Class Point { ... other stuff ...
> > [whatever the syntax is](pt)
> > {
> > this.x+=pt.x;
> > this.y+=pt.y;
> > }
> > }
> >
> > instead of desugaring to:
> >
> > u=u+v;          // which would cause the creation of an object and
> >                 // leave the other to be collected
> >
> > For all I know, += might be doing such anyway in some engines, but for
> > my stuff which is a lot of 3D math that could be a performance killer.
> > It would be nice to be able to just add points and such, as long as the
> > overhead is negligible.
> >
> > [>] Brian
> >
> > On 5/10/2016 10:52 AM, Isiah Meadows wrote:
> > > I would prefer syntax + internal slots, since you'll know at creation
> > > time whether the object has overloaded operators. It's much simpler for
> > > the engine to figure out, and it's more performant because you only need
> > > to check one thing instead of worrying about inheritance, own
> > > properties, etc.
> > >
> > > Also, it would be IMHO easier to read than a symbol (the computed
> > > property syntax is ugly IMO). Using a different concept than symbols
> > > would also fit better with value types whenever any of those proposals
> > > make it into the language (either the struct or special syntax).
> > >
> > >
> > > On Tue, May 10, 2016, 04:03 G. Kay Lee
> > > <[hidden email]
> > > <mailto:[hidden email]>> wrote:
> > >
> > >     Yes, I think exposing operators through well-known symbols is an
> > >     interesting idea worthy of more exploration because it's precisely
> > >     the purpose of well-known symbols to expose and allow manipulation
> > >     to previously inaccessible internal language behaviors.
> > >
> > >     On Tue, May 10, 2016 at 1:59 PM, Kevin Barabash
> > >     <[hidden email] <mailto:[hidden email]>> wrote:
> > >
> > >         > And remember that decorators are essentially just a syntax to
> > >         apply functions to objects/classes at design time, so what
> > >         you're proposing is essentially some new global function, which
> > >         is going against the current trend and effort to better
> > >         modularize/namespace all these utility functions/methods.
> > >
> > >         That's a really good point.
> > >
> > >         > It has been mentioned and discussed in numerous places over the
> > >         years, you can find more info on this with some casual googling.
> > >         For example:https://news.ycombinator.com/item?id=2983420
> > >
> > >         Thanks for the link.  I played around with sweet.js a bit over
> > >         the weekend.  Using macros should work if we went with Python
> > >         style operator overloading.  Instead of defining methods like
> > >         _ADD_, _SUB_ etc. we could create some well-known symbols, maybe
> > >         Symbol.plus, Symbol.times, etc.
> > >
> > >         ```
> > >         class Point {
> > >           constructor(x, y) {
> > >             Object.assign(this, {x, y});
> > >           }
> > >
> > >           [Symbol.add](other) {
> > >             return new Point(this.x + other.x, this.y + other.y);
> > >           }
> > >         }
> > >
> > >         const u = new Point(5, 10);
> > >         const v = new Point(1, -2);
> > >
> > >         const w = u + v;  // desugars to u[Symbol.add](v)
> > >         console.log(w);   // { x: 6, y: 8 };
> > >         ```
> > >
> > >         This would require default implementations to be defined on
> > >         Object.prototype for Symbol.plus, Symbol.times, etc.
> > >
> > >
> > >         On Sun, May 8, 2016 at 10:38 PM, G. Kay Lee
> > >         <[hidden email]
> > >         <mailto:[hidden email]>> wrote:
> > >
> > >             > Why not? The standard defines well-known symbols. Maybe
> > `@operator` could be a well known decorator (assuming decorators get
> > approved).
> > >
> > >             Well... you make something into the standard with proposals,
> > >             not why-nots, so in order to make that happen you need to
> > >             draft another proposal for well-known decorators. And
> > >             remember that decorators are essentially just a syntax to
> > >             apply functions to objects/classes at design time, so what
> > >             you're proposing is essentially some new global function,
> > >             which is going against the current trend and effort to
> > >             better modularize/namespace all these utility
> > >             functions/methods. And maybe a new mechanism could be
> > >             drafted for these new well-known decorators, so that we can
> > >             hide these new functions somewhere... but by now I hope it's
> > >             becoming clear that it's introducing way too much new
> > >             surface area for the language in exchange for one small
> > feature.
> > >
> > >             > I haven't seen any proposals for macros, could you post a
> > link?
> > >
> > >             It has been mentioned and discussed in numerous places over
> > >             the years, you can find more info on this with some casual
> > >             googling. For example:
> > >             https://news.ycombinator.com/item?id=2983420
> > >
> > >
> > >
> > >             On Sun, May 8, 2016 at 2:51 PM, Kevin Barabash
> > >             <[hidden email] <mailto:[hidden email]>>
> > wrote:
> > >
> > >                 I should update the demo code to show the `@operator`
> > >                 decorator in addition to `Function.defineOperator`.
> > >
> > >                 Initially I started out with just the `@operator`
> > >                 decorator, but that meant that each class would have to
> > >                 have knowledge of each of the classes it might want to
> > >                 interact with before hand.  Having a separate
> > >                 `defineOperator` function avoids this situation.
> > >
> > >                 It means that prototype style classes must be converted
> > >                 to the new class syntax before operator overloading
> > >                 could be used.  Lastly, there may be some cases where it
> > >                 makes sense to overload operators with existing 3rd
> > >                 party code or built-in classes, e.g. adding set
> > >                 operations to Set using operator overloading.
> > >
> > >                 > It's also apparent that the `@operator decorator` part
> > >                 of the proposal is an effort trying to address this
> > >                 issue, but it really is not the responsibility of the
> > >                 standard to try to define such a thing.
> > >
> > >                 Why not?  The standard defines well-known symbols.
> > >                 Maybe `@operator` could be a well known decorator
> > >                 (assuming decorators get approved).
> > >
> > >                 Slide 15
> > >                 from http://www.slideshare.net/BrendanEich/js-resp shows
> > >                 syntax for defining operators in value types which could
> > >                 be adapted as follows for regular classes:
> > >
> > >                 ```
> > >                 class Point {
> > >                    constructor(x, y) {
> > >                        this.x = +x;
> > >                        this.y = +y;
> > >                    }
> > >                    Point + Number (a, b) {
> > >                        return new Point(a.x + b, a.y + b);
> > >                    }
> > >                    Number + Point (a, b) {
> > >                        return new Point(a + b.x, a + b.y);
> > >                    }
> > >                    Point + Point (a, b) {
> > >                        return new Point(a.x + b.x, a.y + b.y);
> > >                    }
> > >                 }
> > >                 ```
> > >
> > >                 Having to define `+` twice for `Point + Number` and
> > >                 `Number + Point` seems like busy work, but maybe it's
> > >                 better to be explicit.  What are you thoughts about this
> > >                 syntax?
> > >
> > >                 > Another thing is that, IMHO, currently there are too
> > >                 much quirks/conventions in the proposal that feel
> > >                 non-evident and non-flexible which is destined to trip
> > >                 people over from time to time. It would be great to make
> > >                 a proposal that's simple and don't include too much
> > >                 assumptions.
> > >
> > >                 Could you elaborator what quirks/conventions might trip
> > >                 people up?
> > >
> > >                 > Finally, I'm not sure about the current status of
> > >                 macros, but last I heard of it, they say it's going to
> > >                 make its way into the standard pretty soon (TM), and
> > >                 macros can do much of the things overloading could, and
> > >                 much more.
> > >
> > >                 I haven't seen any proposals for macros, could you post
> > >                 a link?
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >                 On Sat, May 7, 2016 at 9:55 PM, G. Kay Lee
> > >                 <[hidden email]
> > >                 <mailto:[hidden email]>> wrote:
> > >
> > >                     I'd say it's way too early to ask for a champion on
> > >                     this because just a quick skimming revealed a lot of
> > >                     places that didn't add up. For example, the proposal
> > >                     suggested that overloading is primarily targeted at
> > >                     making it easier to work with user-defined classes,
> > >                     but curiously a `Function.defineOperator()` method
> > >                     is proposed instead of some syntax that feels more
> > >                     tightly integrated with the class definition syntax.
> > >
> > >                     ```
> > >
> > >                     class Point {
> > >                         constructor(x, y) {
> > >                             Object.assign(this, { x, y });
> > >                         }
> > >
> > >                         toString() {
> > >                             return `(${this.x}, ${this.y})`;
> > >                         }
> > >                     }
> > >
> > >                     Function.defineOperator('+', [Point, Point], (a, b)
> > => new Point(a.x + b.x, a.y + b.y));
> > >
> > >                     ```
> > >
> > >                     The demo code made this flaw evident - it looks like
> > >                     a giant step backward to define an instance method
> > >                     like this, don't you agree?
> > >
> > >                     It's also apparent that the `@operator decorator`
> > >                     part of the proposal is an effort trying to address
> > >                     this issue, but it really is not the responsibility
> > >                     of the standard to try to define such a thing.
> > >
> > >                     What I'd suggest is that perhaps you should rethink
> > >                     your proposed syntax and redesign it to become an
> > >                     extension of the ES6 class definition syntax.
> > >
> > >                     Another thing is that, IMHO, currently there are too
> > >                     much quirks/conventions in the proposal that feel
> > >                     non-evident and non-flexible which is destined to
> > >                     trip people over from time to time. It would be
> > >                     great to make a proposal that's simple and don't
> > >                     include too much assumptions.
> > >
> > >                     Finally, I'm not sure about the current status of
> > >                     macros, but last I heard of it, they say it's going
> > >                     to make its way into the standard pretty soon (TM),
> > >                     and macros can do much of the things overloading
> > >                     could, and much more.
> > >
> > >                     On Sun, May 8, 2016 at 8:51 AM, Kevin Barabash
> > >                     <[hidden email]
> > >                     <mailto:[hidden email]>> wrote:
> > >
> > >                         I forgot to mention in my last email that I'm
> > >                         looking for a champion for this proposal.
> > >
> > >                         On Sat, May 7, 2016 at 5:24 PM, Kevin Barabash
> > >                         <[hidden email]
> > >                         <mailto:[hidden email]>> wrote:
> > >
> > >                             Hi everyone,
> > >
> > >                             I've been working on implementing operator
> > >                             overloading and would like to submit a
> > proposal.
> > >
> > >                             I think operator overloading would be a
> > >                             useful addition to the language.  In
> > >                             particular I think it would be useful for
> > >                             defining operations on common mathematical
> > >                             object types such as complex numbers,
> > >                             vectors, matrices, and sets.
> > >
> > >                             I've create a working prototype that
> > >                             consists of:
> > >
> > >                               * babel plugin that rewrites operators as
> > >                                 function calls
> > >                               * a polyfill which defines these functions
> > >                                 and which call the correct
> > >                                 argument-specific function based on the
> > >                                 arguments' prototypes
> > >                               * Function.defineOperator which can be
> > >                                 used to define which function an
> > >                                 operator should use for the specified
> > types
> > >                               * "use overloading" directive which allows
> > >                                 users to opt-in
> > >
> > >                             More details can be found
> > >                             at
> > https://github.com/kevinbarabash/operator-overloading.
> > >                             The babel plugin can be found
> > >                             at
> > https://github.com/kevinbarabash/babel-plugin-operator-overloading.
> > >                             I also have a demo project at
> > >
> > https://github.com/kevinbarabash/operator-overloading-demo.
> > >
> > >                             The design was inspired by some of the
> > >                             slides from
> > >
> > http://www.slideshare.net/BrendanEich/js-resp.
> > >
> > >                             – Kevin
> > >
> > >
> > >
> > >
> > >                         _______________________________________________
> > >                         es-discuss mailing list
> > >                         [hidden email]
> > >                         <mailto:[hidden email]>
> > >                         https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >                     _______________________________________________
> > >                     es-discuss mailing list
> > >                     [hidden email] <mailto:
> > [hidden email]>
> > >                     https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >                 _______________________________________________
> > >                 es-discuss mailing list
> > >                 [hidden email] <mailto:[hidden email]>
> > >                 https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >             _______________________________________________
> > >             es-discuss mailing list
> > >             [hidden email] <mailto:[hidden email]>
> > >             https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >
> > >         _______________________________________________
> > >         es-discuss mailing list
> > >         [hidden email] <mailto:[hidden email]>
> > >         https://mail.mozilla.org/listinfo/es-discuss
> > >
> > >
> > >     _______________________________________________
> > >     es-discuss mailing list
> > >     [hidden email] <mailto:[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
> >
>

_______________________________________________
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



_______________________________________________
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: operator overloading proposal

Michael Theriot
In reply to this post by Isiah Meadows-2
What if you used a target parameter to indicate assignment?

```js
operator +(a, b, target = new obj()) {
  target.val = a.val + b.val;
  return target;
}

// or... no arrow functions...

operator +(other, target = new obj()) {
  target.val = this.val + other.val;
  return target;
}

// or... just a boolean

operator +(other, assign) {
  let target = assign ? this : new obj();
  target.val = this.val + other.val;
  return target;
}
```

And throw a TypeError if an assignment does not return the same object.

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