operator overloading proposal
I forgot to mention in my last email that I'm looking for a champion for this proposal.
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 <kevinb at khanacademy.org> 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 > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160507/350feb83/attachment.html>
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.
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 <kevinb at khanacademy.org> 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 <kevinb at khanacademy.org> > 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 > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160508/7669b3b1/attachment-0001.html>
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 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.
Could you post a link any more info? Will it be something like sweet.js?
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 < balancetraveller+es-discuss at gmail.com> 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 <kevinb at khanacademy.org> > 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 <kevinb at khanacademy.org> >> 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 >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> >> > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160507/232098a3/attachment.html>
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: news.ycombinator.com/item?id=2983420
> 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 <kevinb at khanacademy.org> 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 < > balancetraveller+es-discuss at gmail.com> 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 <kevinb at khanacademy.org> >> 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 <kevinb at khanacademy.org> >>> 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 >>> es-discuss at mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >>> >> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> >> > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160509/e4343a06/attachment-0001.html>
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: 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.
> 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 < balancetraveller+es-discuss at gmail.com> 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 <kevinb at khanacademy.org> > 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 < >> balancetraveller+es-discuss at gmail.com> 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 <kevinb at khanacademy.org> >>> 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 <kevinb at khanacademy.org> >>>> 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 >>>> es-discuss at mozilla.org >>>> https://mail.mozilla.org/listinfo/es-discuss >>>> >>>> >>> >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss at mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >>> >> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> >> > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160509/8cea0466/attachment-0001.html>
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.
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 <kevinb at khanacademy.org> 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 < > balancetraveller+es-discuss at gmail.com> 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 <kevinb at khanacademy.org> >> 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 < >>> balancetraveller+es-discuss at gmail.com> 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 <kevinb at khanacademy.org> >>>> 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 <kevinb at khanacademy.org >>>>> > 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 >>>>> es-discuss at mozilla.org >>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>> >>>>> >>>> >>>> _______________________________________________ >>>> es-discuss mailing list >>>> es-discuss at mozilla.org >>>> https://mail.mozilla.org/listinfo/es-discuss >>>> >>>> >>> >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss at mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >>> >> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> >> > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160510/402a880c/attachment-0001.html>
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).
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 < balancetraveller+es-discuss at gmail.com> 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 <kevinb at khanacademy.org> > 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 < >> balancetraveller+es-discuss at gmail.com> 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 <kevinb at khanacademy.org> >>> 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 < >>>> balancetraveller+es-discuss at gmail.com> 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 <kevinb at khanacademy.org >>>>> > 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 < >>>>>> kevinb at khanacademy.org> 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 >>>>>> es-discuss at mozilla.org >>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>> >>>>>> >>>>> >>>>> _______________________________________________ >>>>> es-discuss mailing list >>>>> es-discuss at mozilla.org >>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>> >>>>> >>>> >>>> _______________________________________________ >>>> es-discuss mailing list >>>> es-discuss at mozilla.org >>>> https://mail.mozilla.org/listinfo/es-discuss >>>> >>>> >>> >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss at mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >>> >> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> >> > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160510/4a134989/attachment-0001.html>
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 uSymbol.add 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 { 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
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 > <balancetraveller+es-discuss at gmail.com > <mailto:balancetraveller%2Bes-discuss at gmail.com>> 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 > <kevinb at khanacademy.org <mailto:kevinb at khanacademy.org>> 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 > <balancetraveller+es-discuss at gmail.com > <mailto:balancetraveller+es-discuss at gmail.com>> 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 > <kevinb at khanacademy.org <mailto:kevinb at khanacademy.org>> 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 > <balancetraveller+es-discuss at gmail.com > <mailto:balancetraveller+es-discuss at gmail.com>> 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 > <kevinb at khanacademy.org > <mailto:kevinb at khanacademy.org>> 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 > <kevinb at khanacademy.org > <mailto:kevinb at khanacademy.org>> 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 > es-discuss at mozilla.org > <mailto:es-discuss at mozilla.org> > https://mail.mozilla.org/listinfo/es-discuss > > > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> > https://mail.mozilla.org/listinfo/es-discuss > > > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> > https://mail.mozilla.org/listinfo/es-discuss > > > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> > https://mail.mozilla.org/listinfo/es-discuss > > > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> > https://mail.mozilla.org/listinfo/es-discuss > > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> > https://mail.mozilla.org/listinfo/es-discuss > > > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss >
Here's my thought, if we go with syntax.
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
}
}
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 <ggadwa at charter.net> 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 > > <balancetraveller+es-discuss at gmail.com > > <mailto:balancetraveller%2Bes-discuss at gmail.com>> 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 > > <kevinb at khanacademy.org <mailto:kevinb at khanacademy.org>> 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 > > <balancetraveller+es-discuss at gmail.com > > <mailto:balancetraveller+es-discuss at gmail.com>> 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 > > <kevinb at khanacademy.org <mailto:kevinb at khanacademy.org>> > 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 > > <balancetraveller+es-discuss at gmail.com > > <mailto:balancetraveller+es-discuss at gmail.com>> 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 > > <kevinb at khanacademy.org > > <mailto:kevinb at khanacademy.org>> 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 > > <kevinb at khanacademy.org > > <mailto:kevinb at khanacademy.org>> 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 > > es-discuss at mozilla.org > > <mailto:es-discuss at mozilla.org> > > https://mail.mozilla.org/listinfo/es-discuss > > > > > > > > _______________________________________________ > > es-discuss mailing list > > es-discuss at mozilla.org <mailto: > es-discuss at mozilla.org> > > https://mail.mozilla.org/listinfo/es-discuss > > > > > > > > _______________________________________________ > > es-discuss mailing list > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> > > https://mail.mozilla.org/listinfo/es-discuss > > > > > > > > _______________________________________________ > > es-discuss mailing list > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> > > https://mail.mozilla.org/listinfo/es-discuss > > > > > > > > _______________________________________________ > > es-discuss mailing list > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> > > https://mail.mozilla.org/listinfo/es-discuss > > > > > > _______________________________________________ > > es-discuss mailing list > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> > > https://mail.mozilla.org/listinfo/es-discuss > > > > > > > > _______________________________________________ > > es-discuss mailing list > > es-discuss at mozilla.org > > https://mail.mozilla.org/listinfo/es-discuss > > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160510/70c1971a/attachment-0001.html>
@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.
@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 <ggadwa at charter.net> 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 > > > <balancetraveller+es-discuss at gmail.com > > > <mailto:balancetraveller%2Bes-discuss at gmail.com>> 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 > > > <kevinb at khanacademy.org <mailto:kevinb at khanacademy.org>> 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 > > > <balancetraveller+es-discuss at gmail.com > > > <mailto:balancetraveller+es-discuss at gmail.com>> 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 > > > <kevinb at khanacademy.org <mailto:kevinb at khanacademy.org>> > > 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 > > > <balancetraveller+es-discuss at gmail.com > > > <mailto:balancetraveller+es-discuss at gmail.com>> 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 > > > <kevinb at khanacademy.org > > > <mailto:kevinb at khanacademy.org>> 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 > > > <kevinb at khanacademy.org > > > <mailto:kevinb at khanacademy.org>> 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 > > > es-discuss at mozilla.org > > > <mailto:es-discuss at mozilla.org> > > > https://mail.mozilla.org/listinfo/es-discuss > > > > > > > > > > > > _______________________________________________ > > > es-discuss mailing list > > > es-discuss at mozilla.org <mailto: > > es-discuss at mozilla.org> > > > https://mail.mozilla.org/listinfo/es-discuss > > > > > > > > > > > > _______________________________________________ > > > es-discuss mailing list > > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> > > > https://mail.mozilla.org/listinfo/es-discuss > > > > > > > > > > > > _______________________________________________ > > > es-discuss mailing list > > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> > > > https://mail.mozilla.org/listinfo/es-discuss > > > > > > > > > > > > _______________________________________________ > > > es-discuss mailing list > > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> > > > https://mail.mozilla.org/listinfo/es-discuss > > > > > > > > > _______________________________________________ > > > es-discuss mailing list > > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> > > > https://mail.mozilla.org/listinfo/es-discuss > > > > > > > > > > > > _______________________________________________ > > > es-discuss mailing list > > > es-discuss at mozilla.org > > > https://mail.mozilla.org/listinfo/es-discuss > > > > > _______________________________________________ > > es-discuss mailing list > > es-discuss at mozilla.org > > https://mail.mozilla.org/listinfo/es-discuss > > >
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).
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 <kdex at kdex.de> 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 <ggadwa at charter.net> 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 > > > > <balancetraveller+es-discuss at gmail.com > > > > <mailto:balancetraveller%2Bes-discuss at gmail.com>> 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 > > > > <kevinb at khanacademy.org <mailto:kevinb at khanacademy.org>> 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 > > > > <balancetraveller+es-discuss at gmail.com > > > > <mailto:balancetraveller+es-discuss at gmail.com>> 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 > > > > <kevinb at khanacademy.org <mailto:kevinb at khanacademy.org>> > > > 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 > > > > <balancetraveller+es-discuss at gmail.com > > > > <mailto:balancetraveller+es-discuss at gmail.com>> > 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 > > > > <kevinb at khanacademy.org > > > > <mailto:kevinb at khanacademy.org>> 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 > > > > <kevinb at khanacademy.org > > > > <mailto:kevinb at khanacademy.org>> 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 > > > > es-discuss at mozilla.org > > > > <mailto:es-discuss at mozilla.org> > > > > https://mail.mozilla.org/listinfo/es-discuss > > > > > > > > > > > > > > > > _______________________________________________ > > > > es-discuss mailing list > > > > es-discuss at mozilla.org <mailto: > > > es-discuss at mozilla.org> > > > > https://mail.mozilla.org/listinfo/es-discuss > > > > > > > > > > > > > > > > _______________________________________________ > > > > es-discuss mailing list > > > > es-discuss at mozilla.org <mailto: > es-discuss at mozilla.org> > > > > https://mail.mozilla.org/listinfo/es-discuss > > > > > > > > > > > > > > > > _______________________________________________ > > > > es-discuss mailing list > > > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> > > > > https://mail.mozilla.org/listinfo/es-discuss > > > > > > > > > > > > > > > > _______________________________________________ > > > > es-discuss mailing list > > > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> > > > > https://mail.mozilla.org/listinfo/es-discuss > > > > > > > > > > > > _______________________________________________ > > > > es-discuss mailing list > > > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> > > > > https://mail.mozilla.org/listinfo/es-discuss > > > > > > > > > > > > > > > > _______________________________________________ > > > > es-discuss mailing list > > > > es-discuss at mozilla.org > > > > https://mail.mozilla.org/listinfo/es-discuss > > > > > > > _______________________________________________ > > > es-discuss mailing list > > > es-discuss at mozilla.org > > > https://mail.mozilla.org/listinfo/es-discuss > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160511/54881eb2/attachment-0001.html>
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 <isiahmeadows at gmail.com>
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 <isiahmeadows at gmail.com> 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 <kdex at kdex.de> 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 <ggadwa at charter.net> 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 >> > > > <balancetraveller+es-discuss at gmail.com >> > > > <mailto:balancetraveller%2Bes-discuss at gmail.com>> 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 >> > > > <kevinb at khanacademy.org <mailto:kevinb at khanacademy.org>> 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 >> > > > <balancetraveller+es-discuss at gmail.com >> > > > <mailto:balancetraveller+es-discuss at gmail.com>> 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 >> > > > <kevinb at khanacademy.org <mailto:kevinb at khanacademy.org >> >> >> > > 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 >> > > > <balancetraveller+es-discuss at gmail.com >> > > > <mailto:balancetraveller+es-discuss at gmail.com>> >> 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 >> > > > <kevinb at khanacademy.org >> > > > <mailto:kevinb at khanacademy.org>> 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 >> > > > <kevinb at khanacademy.org >> > > > <mailto:kevinb at khanacademy.org>> 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 >> > > > es-discuss at mozilla.org >> > > > <mailto:es-discuss at mozilla.org> >> > > > >> https://mail.mozilla.org/listinfo/es-discuss >> > > > >> > > > >> > > > >> > > > _______________________________________________ >> > > > es-discuss mailing list >> > > > es-discuss at mozilla.org <mailto: >> > > es-discuss at mozilla.org> >> > > > https://mail.mozilla.org/listinfo/es-discuss >> > > > >> > > > >> > > > >> > > > _______________________________________________ >> > > > es-discuss mailing list >> > > > es-discuss at mozilla.org <mailto: >> es-discuss at mozilla.org> >> > > > https://mail.mozilla.org/listinfo/es-discuss >> > > > >> > > > >> > > > >> > > > _______________________________________________ >> > > > es-discuss mailing list >> > > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> >> > > > https://mail.mozilla.org/listinfo/es-discuss >> > > > >> > > > >> > > > >> > > > _______________________________________________ >> > > > es-discuss mailing list >> > > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> >> > > > https://mail.mozilla.org/listinfo/es-discuss >> > > > >> > > > >> > > > _______________________________________________ >> > > > es-discuss mailing list >> > > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> >> > > > https://mail.mozilla.org/listinfo/es-discuss >> > > > >> > > > >> > > > >> > > > _______________________________________________ >> > > > es-discuss mailing list >> > > > es-discuss at mozilla.org >> > > > https://mail.mozilla.org/listinfo/es-discuss >> > > > >> > > _______________________________________________ >> > > es-discuss mailing list >> > > es-discuss at mozilla.org >> > > https://mail.mozilla.org/listinfo/es-discuss >> > > >> > >> > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160510/67090d15/attachment-0001.html>
-
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). -
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 lowerfoo + 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. -
If it's pure syntax, you won't have the edge cases of
x += y
having to desugar tox = x[Symbol.assignPlus](y)
and so on. You just look for an[[OpAssignPlus]]
onx
, and if it exists, call it asx.[[OpAssignPlus]](y)
. Else, you check for[[OpPlus]]
, and setx
tox.[[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:
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)
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 <kevinb at khanacademy.org> 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 <isiahmeadows at gmail.com> > 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 <kdex at kdex.de> 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 <ggadwa at charter.net> 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 >>> > > > <balancetraveller+es-discuss at gmail.com >>> > > > <mailto:balancetraveller%2Bes-discuss at gmail.com>> 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 >>> > > > <kevinb at khanacademy.org <mailto:kevinb at khanacademy.org>> >>> 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 >>> > > > <balancetraveller+es-discuss at gmail.com >>> > > > <mailto:balancetraveller+es-discuss at gmail.com>> 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 >>> > > > <kevinb at khanacademy.org <mailto:kevinb at khanacademy.org >>> >> >>> > > 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 >>> > > > <balancetraveller+es-discuss at gmail.com >>> > > > <mailto:balancetraveller+es-discuss at gmail.com>> >>> 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 >>> > > > <kevinb at khanacademy.org >>> > > > <mailto:kevinb at khanacademy.org>> 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 >>> > > > <kevinb at khanacademy.org >>> > > > <mailto:kevinb at khanacademy.org>> 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 >>> > > > es-discuss at mozilla.org >>> > > > <mailto:es-discuss at mozilla.org> >>> > > > >>> https://mail.mozilla.org/listinfo/es-discuss >>> > > > >>> > > > >>> > > > >>> > > > _______________________________________________ >>> > > > es-discuss mailing list >>> > > > es-discuss at mozilla.org <mailto: >>> > > es-discuss at mozilla.org> >>> > > > https://mail.mozilla.org/listinfo/es-discuss >>> > > > >>> > > > >>> > > > >>> > > > _______________________________________________ >>> > > > es-discuss mailing list >>> > > > es-discuss at mozilla.org <mailto: >>> es-discuss at mozilla.org> >>> > > > https://mail.mozilla.org/listinfo/es-discuss >>> > > > >>> > > > >>> > > > >>> > > > _______________________________________________ >>> > > > es-discuss mailing list >>> > > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> >>> > > > https://mail.mozilla.org/listinfo/es-discuss >>> > > > >>> > > > >>> > > > >>> > > > _______________________________________________ >>> > > > es-discuss mailing list >>> > > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> >>> > > > https://mail.mozilla.org/listinfo/es-discuss >>> > > > >>> > > > >>> > > > _______________________________________________ >>> > > > es-discuss mailing list >>> > > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> >>> > > > https://mail.mozilla.org/listinfo/es-discuss >>> > > > >>> > > > >>> > > > >>> > > > _______________________________________________ >>> > > > es-discuss mailing list >>> > > > es-discuss at mozilla.org >>> > > > https://mail.mozilla.org/listinfo/es-discuss >>> > > > >>> > > _______________________________________________ >>> > > es-discuss mailing list >>> > > es-discuss at mozilla.org >>> > > https://mail.mozilla.org/listinfo/es-discuss >>> > > >>> > >>> >> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> >> > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160511/0308697a/attachment-0001.html>
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.
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 <isiahmeadows at gmail.com> 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 <kevinb at khanacademy.org> 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 <isiahmeadows at gmail.com> >> 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 <kdex at kdex.de> 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 <ggadwa at charter.net> 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 >>>> > > > <balancetraveller+es-discuss at gmail.com >>>> > > > <mailto:balancetraveller%2Bes-discuss at gmail.com>> 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 >>>> > > > <kevinb at khanacademy.org <mailto:kevinb at khanacademy.org>> >>>> 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 >>>> > > > <balancetraveller+es-discuss at gmail.com >>>> > > > <mailto:balancetraveller+es-discuss at gmail.com>> 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 >>>> > > > <kevinb at khanacademy.org <mailto: >>>> kevinb at khanacademy.org>> >>>> > > 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 >>>> > > > <balancetraveller+es-discuss at gmail.com >>>> > > > <mailto:balancetraveller+es-discuss at gmail.com>> >>>> 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 >>>> > > > <kevinb at khanacademy.org >>>> > > > <mailto:kevinb at khanacademy.org>> 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 >>>> > > > <kevinb at khanacademy.org >>>> > > > <mailto:kevinb at khanacademy.org>> 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 >>>> > > > es-discuss at mozilla.org >>>> > > > <mailto:es-discuss at mozilla.org> >>>> > > > >>>> https://mail.mozilla.org/listinfo/es-discuss >>>> > > > >>>> > > > >>>> > > > >>>> > > > >>>> _______________________________________________ >>>> > > > es-discuss mailing list >>>> > > > es-discuss at mozilla.org <mailto: >>>> > > es-discuss at mozilla.org> >>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>> > > > >>>> > > > >>>> > > > >>>> > > > _______________________________________________ >>>> > > > es-discuss mailing list >>>> > > > es-discuss at mozilla.org <mailto: >>>> es-discuss at mozilla.org> >>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>> > > > >>>> > > > >>>> > > > >>>> > > > _______________________________________________ >>>> > > > es-discuss mailing list >>>> > > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org >>>> > >>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>> > > > >>>> > > > >>>> > > > >>>> > > > _______________________________________________ >>>> > > > es-discuss mailing list >>>> > > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> >>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>> > > > >>>> > > > >>>> > > > _______________________________________________ >>>> > > > es-discuss mailing list >>>> > > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> >>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>> > > > >>>> > > > >>>> > > > >>>> > > > _______________________________________________ >>>> > > > es-discuss mailing list >>>> > > > es-discuss at mozilla.org >>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>> > > > >>>> > > _______________________________________________ >>>> > > es-discuss mailing list >>>> > > es-discuss at mozilla.org >>>> > > https://mail.mozilla.org/listinfo/es-discuss >>>> > > >>>> > >>>> >>> >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss at mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >>> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160510/16ff5b78/attachment-0001.html>
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.
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 <ljharb at gmail.com> 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 <isiahmeadows at gmail.com> > 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 <kevinb at khanacademy.org> >> 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 <isiahmeadows at gmail.com> >>> 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 <kdex at kdex.de> 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 <ggadwa at charter.net> 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 >>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>> > > > <mailto:balancetraveller%2Bes-discuss at gmail.com>> 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 >>>>> > > > <kevinb at khanacademy.org <mailto:kevinb at khanacademy.org>> >>>>> 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 >>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>> > > > <mailto:balancetraveller+es-discuss at gmail.com>> 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 >>>>> > > > <kevinb at khanacademy.org <mailto: >>>>> kevinb at khanacademy.org>> >>>>> > > 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 >>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>> > > > <mailto:balancetraveller+es-discuss at gmail.com>> >>>>> 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 >>>>> > > > <kevinb at khanacademy.org >>>>> > > > <mailto:kevinb at khanacademy.org>> 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 >>>>> > > > <kevinb at khanacademy.org >>>>> > > > <mailto:kevinb at khanacademy.org>> 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 >>>>> > > > es-discuss at mozilla.org >>>>> > > > <mailto:es-discuss at mozilla.org> >>>>> > > > >>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>> > > > >>>>> > > > >>>>> > > > >>>>> > > > >>>>> _______________________________________________ >>>>> > > > es-discuss mailing list >>>>> > > > es-discuss at mozilla.org <mailto: >>>>> > > es-discuss at mozilla.org> >>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>> > > > >>>>> > > > >>>>> > > > >>>>> > > > _______________________________________________ >>>>> > > > es-discuss mailing list >>>>> > > > es-discuss at mozilla.org <mailto: >>>>> es-discuss at mozilla.org> >>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>> > > > >>>>> > > > >>>>> > > > >>>>> > > > _______________________________________________ >>>>> > > > es-discuss mailing list >>>>> > > > es-discuss at mozilla.org <mailto: >>>>> es-discuss at mozilla.org> >>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>> > > > >>>>> > > > >>>>> > > > >>>>> > > > _______________________________________________ >>>>> > > > es-discuss mailing list >>>>> > > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> >>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>> > > > >>>>> > > > >>>>> > > > _______________________________________________ >>>>> > > > es-discuss mailing list >>>>> > > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> >>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>> > > > >>>>> > > > >>>>> > > > >>>>> > > > _______________________________________________ >>>>> > > > es-discuss mailing list >>>>> > > > es-discuss at mozilla.org >>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>> > > > >>>>> > > _______________________________________________ >>>>> > > es-discuss mailing list >>>>> > > es-discuss at mozilla.org >>>>> > > https://mail.mozilla.org/listinfo/es-discuss >>>>> > > >>>>> > >>>>> >>>> >>>> _______________________________________________ >>>> es-discuss mailing list >>>> es-discuss at mozilla.org >>>> https://mail.mozilla.org/listinfo/es-discuss >>>> >>>> >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss at mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160511/a09032f3/attachment-0001.html>
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 <isiahmeadows at gmail.com>:
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 <isiahmeadows at gmail.com>: > 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 <ljharb at gmail.com> 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 <isiahmeadows at gmail.com> >> 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 <kevinb at khanacademy.org> >>> 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 <isiahmeadows at gmail.com> >>>> 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 <kdex at kdex.de> 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 <ggadwa at charter.net> >>>>>> 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 >>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>> > > > <mailto:balancetraveller%2Bes-discuss at gmail.com>> 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 >>>>>> > > > <kevinb at khanacademy.org <mailto:kevinb at khanacademy.org>> >>>>>> 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 >>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>> > > > <mailto:balancetraveller+es-discuss at gmail.com>> 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 >>>>>> > > > <kevinb at khanacademy.org <mailto: >>>>>> kevinb at khanacademy.org>> >>>>>> > > 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 >>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>> > > > <mailto:balancetraveller+es-discuss at gmail.com>> >>>>>> 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 >>>>>> > > > <kevinb at khanacademy.org >>>>>> > > > <mailto:kevinb at khanacademy.org>> 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 >>>>>> > > > <kevinb at khanacademy.org >>>>>> > > > <mailto:kevinb at khanacademy.org>> 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 >>>>>> > > > es-discuss at mozilla.org >>>>>> > > > <mailto:es-discuss at mozilla.org> >>>>>> > > > >>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>> > > > >>>>>> > > > >>>>>> > > > >>>>>> > > > >>>>>> _______________________________________________ >>>>>> > > > es-discuss mailing list >>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>> > > es-discuss at mozilla.org> >>>>>> > > > >>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>> > > > >>>>>> > > > >>>>>> > > > >>>>>> > > > _______________________________________________ >>>>>> > > > es-discuss mailing list >>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>> es-discuss at mozilla.org> >>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>> > > > >>>>>> > > > >>>>>> > > > >>>>>> > > > _______________________________________________ >>>>>> > > > es-discuss mailing list >>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>> es-discuss at mozilla.org> >>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>> > > > >>>>>> > > > >>>>>> > > > >>>>>> > > > _______________________________________________ >>>>>> > > > es-discuss mailing list >>>>>> > > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> >>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>> > > > >>>>>> > > > >>>>>> > > > _______________________________________________ >>>>>> > > > es-discuss mailing list >>>>>> > > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> >>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>> > > > >>>>>> > > > >>>>>> > > > >>>>>> > > > _______________________________________________ >>>>>> > > > es-discuss mailing list >>>>>> > > > es-discuss at mozilla.org >>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>> > > > >>>>>> > > _______________________________________________ >>>>>> > > es-discuss mailing list >>>>>> > > es-discuss at mozilla.org >>>>>> > > https://mail.mozilla.org/listinfo/es-discuss >>>>>> > > >>>>>> > >>>>>> >>>>> >>>>> _______________________________________________ >>>>> es-discuss mailing list >>>>> es-discuss at mozilla.org >>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>> >>>>> >>>> _______________________________________________ >>>> es-discuss mailing list >>>> es-discuss at mozilla.org >>>> https://mail.mozilla.org/listinfo/es-discuss >>>> >>> >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss at mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >>> >> > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160511/80cff806/attachment-0001.html>
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.
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 <dawidmj.szlachta at gmail.com> 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 <isiahmeadows at gmail.com>: > >> 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 <ljharb at gmail.com> 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 <isiahmeadows at gmail.com> >>> 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 <kevinb at khanacademy.org> >>>> 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 <isiahmeadows at gmail.com >>>>> > 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 <kdex at kdex.de> 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 <ggadwa at charter.net> >>>>>>> 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 >>>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>>> > > > <mailto:balancetraveller%2Bes-discuss at gmail.com>> 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 >>>>>>> > > > <kevinb at khanacademy.org <mailto:kevinb at khanacademy.org>> >>>>>>> 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 >>>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>>> > > > <mailto:balancetraveller+es-discuss at gmail.com>> 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 >>>>>>> > > > <kevinb at khanacademy.org <mailto: >>>>>>> kevinb at khanacademy.org>> >>>>>>> > > 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 >>>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>>> > > > <mailto:balancetraveller+es-discuss at gmail.com>> >>>>>>> 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 >>>>>>> > > > <kevinb at khanacademy.org >>>>>>> > > > <mailto:kevinb at khanacademy.org>> 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 >>>>>>> > > > <kevinb at khanacademy.org >>>>>>> > > > <mailto:kevinb at khanacademy.org>> >>>>>>> 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 >>>>>>> > > > es-discuss at mozilla.org >>>>>>> > > > <mailto:es-discuss at mozilla.org> >>>>>>> > > > >>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>> > > > >>>>>>> > > > >>>>>>> > > > >>>>>>> > > > >>>>>>> _______________________________________________ >>>>>>> > > > es-discuss mailing list >>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>> > > es-discuss at mozilla.org> >>>>>>> > > > >>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>> > > > >>>>>>> > > > >>>>>>> > > > >>>>>>> > > > _______________________________________________ >>>>>>> > > > es-discuss mailing list >>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>> es-discuss at mozilla.org> >>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>> > > > >>>>>>> > > > >>>>>>> > > > >>>>>>> > > > _______________________________________________ >>>>>>> > > > es-discuss mailing list >>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>> es-discuss at mozilla.org> >>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>> > > > >>>>>>> > > > >>>>>>> > > > >>>>>>> > > > _______________________________________________ >>>>>>> > > > es-discuss mailing list >>>>>>> > > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> >>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>> > > > >>>>>>> > > > >>>>>>> > > > _______________________________________________ >>>>>>> > > > es-discuss mailing list >>>>>>> > > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> >>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>> > > > >>>>>>> > > > >>>>>>> > > > >>>>>>> > > > _______________________________________________ >>>>>>> > > > es-discuss mailing list >>>>>>> > > > es-discuss at mozilla.org >>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>> > > > >>>>>>> > > _______________________________________________ >>>>>>> > > es-discuss mailing list >>>>>>> > > es-discuss at mozilla.org >>>>>>> > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>> > > >>>>>>> > >>>>>>> >>>>>> >>>>>> _______________________________________________ >>>>>> es-discuss mailing list >>>>>> es-discuss at mozilla.org >>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>> >>>>>> >>>>> _______________________________________________ >>>>> es-discuss mailing list >>>>> es-discuss at mozilla.org >>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>> >>>> >>>> _______________________________________________ >>>> es-discuss mailing list >>>> es-discuss at mozilla.org >>>> https://mail.mozilla.org/listinfo/es-discuss >>>> >>>> >>> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160511/438b8e6d/attachment-0001.html>
@Isiah: Great points. One potential edge case though:
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:
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 <isiahmeadows at gmail.com>
wrote:
@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 <isiahmeadows at gmail.com> 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 <dawidmj.szlachta at gmail.com> > 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 <isiahmeadows at gmail.com>: >> >>> 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 <ljharb at gmail.com> 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 <isiahmeadows at gmail.com >>>> > 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 <kevinb at khanacademy.org> >>>>> 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 < >>>>>> isiahmeadows at gmail.com> 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 <kdex at kdex.de> 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 <ggadwa at charter.net> >>>>>>>> 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 >>>>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>>>> > > > <mailto:balancetraveller%2Bes-discuss at gmail.com>> 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 >>>>>>>> > > > <kevinb at khanacademy.org <mailto:kevinb at khanacademy.org>> >>>>>>>> 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 >>>>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>>>> > > > <mailto:balancetraveller+es-discuss at gmail.com>> >>>>>>>> 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 >>>>>>>> > > > <kevinb at khanacademy.org <mailto: >>>>>>>> kevinb at khanacademy.org>> >>>>>>>> > > 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 >>>>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>>>> > > > <mailto:balancetraveller+es-discuss at gmail.com>> >>>>>>>> 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 >>>>>>>> > > > <kevinb at khanacademy.org >>>>>>>> > > > <mailto:kevinb at khanacademy.org>> 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 >>>>>>>> > > > <kevinb at khanacademy.org >>>>>>>> > > > <mailto:kevinb at khanacademy.org>> >>>>>>>> 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 >>>>>>>> > > > es-discuss at mozilla.org >>>>>>>> > > > <mailto:es-discuss at mozilla.org> >>>>>>>> > > > >>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>> > > > >>>>>>>> > > > >>>>>>>> > > > >>>>>>>> > > > >>>>>>>> _______________________________________________ >>>>>>>> > > > es-discuss mailing list >>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>> > > es-discuss at mozilla.org> >>>>>>>> > > > >>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>> > > > >>>>>>>> > > > >>>>>>>> > > > >>>>>>>> > > > >>>>>>>> _______________________________________________ >>>>>>>> > > > es-discuss mailing list >>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>> es-discuss at mozilla.org> >>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>> > > > >>>>>>>> > > > >>>>>>>> > > > >>>>>>>> > > > _______________________________________________ >>>>>>>> > > > es-discuss mailing list >>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>> es-discuss at mozilla.org> >>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>> > > > >>>>>>>> > > > >>>>>>>> > > > >>>>>>>> > > > _______________________________________________ >>>>>>>> > > > es-discuss mailing list >>>>>>>> > > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org >>>>>>>> > >>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>> > > > >>>>>>>> > > > >>>>>>>> > > > _______________________________________________ >>>>>>>> > > > es-discuss mailing list >>>>>>>> > > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> >>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>> > > > >>>>>>>> > > > >>>>>>>> > > > >>>>>>>> > > > _______________________________________________ >>>>>>>> > > > es-discuss mailing list >>>>>>>> > > > es-discuss at mozilla.org >>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>> > > > >>>>>>>> > > _______________________________________________ >>>>>>>> > > es-discuss mailing list >>>>>>>> > > es-discuss at mozilla.org >>>>>>>> > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>> > > >>>>>>>> > >>>>>>>> >>>>>>> >>>>>>> _______________________________________________ >>>>>>> es-discuss mailing list >>>>>>> es-discuss at mozilla.org >>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>> >>>>>>> >>>>>> _______________________________________________ >>>>>> es-discuss mailing list >>>>>> es-discuss at mozilla.org >>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>> >>>>> >>>>> _______________________________________________ >>>>> es-discuss mailing list >>>>> es-discuss at mozilla.org >>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>> >>>>> >>>> >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss at mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >>> >> > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160511/7d3f4c3b/attachment-0001.html>
What if you used a target parameter to indicate assignment?
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.
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. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160515/051d775a/attachment.html>
If both have the operator, the left side would be used (I thought I said that, but I may have not). I'm thinking, instead, static methods should be used. It would be more versatile.
class Vec2 {
constructor(x, y) {
this.x = x
this.y = y
}
// `this` and `Vec2` are interchangeable
operator this + this(x, y) {
return new this(x.x + y.x, x.y + y.y)
}
operator this + #number(x, y) {
return new this(x.x + y, x.y + y)
}
operator this += this(x, y) {
x.x += y.x
x.y += y.y
}
operator this += #number(x, y) {
x.x += y
x.y += y
}
// #number += this -> x = x + this
operator -this(x) {
return new this(-x.x, -x.y)
}
// etc...
}
class Vec3 {
// ...
operator this + Vec2(x, y) {
return new this(x.x + y.x, x.y + y.y, x.z)
}
// etc...
}
A few notes on this:
- If an operator doesn't reference
this
or the containing class at least once, an early error is thrown. - To reference a primitive, you use the hash symbol + the typeof value.
The valid ones include
#string
,#boolean
,#number
,#symbol
,#object
,#function
, and#undefined
. If value types with customtypeof
values are introduced, you have to reference the type directly. - All type references must be either
this
, identifiers, or member expressions that do not referencethis
. It is an early error otherwise. Member expressions are evaluated at class definition time as well, so that can produce visible side effects if a proxy is referenced or a getter is called. - The operators are checked via
instanceof
. This means, for those that define operators, the behavior can become visible to previous code if the other type specified has a staticSymbol.hasInstance
method.
The reason I provided the this
alias is for anonymous classes, so you can
create anonymous objects. It's also helpful in case you have a longer class
name (possibly by convention) that you now don't have to type out.
If both have the operator, the left side would be used (I thought I said that, but I may have not). I'm thinking, instead, static methods should be used. It would be more versatile. ```js class Vec2 { constructor(x, y) { this.x = x this.y = y } // `this` and `Vec2` are interchangeable operator this + this(x, y) { return new this(x.x + y.x, x.y + y.y) } operator this + #number(x, y) { return new this(x.x + y, x.y + y) } operator this += this(x, y) { x.x += y.x x.y += y.y } operator this += #number(x, y) { x.x += y x.y += y } // #number += this -> x = x + this operator -this(x) { return new this(-x.x, -x.y) } // etc... } class Vec3 { // ... operator this + Vec2(x, y) { return new this(x.x + y.x, x.y + y.y, x.z) } // etc... } ``` A few notes on this: 1. If an operator doesn't reference `this` or the containing class at least once, an early error is thrown. 2. To reference a primitive, you use the hash symbol + the typeof value. The valid ones include `#string`, `#boolean`, `#number`, `#symbol`, `#object`, `#function`, and `#undefined`. If value types with custom `typeof` values are introduced, you have to reference the type directly. 3. All type references must be either `this`, identifiers, or member expressions that do not reference `this`. It is an early error otherwise. Member expressions are evaluated at class definition time as well, so that can produce visible side effects if a proxy is referenced or a getter is called. 4. The operators are checked via `instanceof`. This means, for those that define operators, the behavior can become visible to previous code if the other type specified has a static `Symbol.hasInstance` method. The reason I provided the `this` alias is for anonymous classes, so you can create anonymous objects. It's also helpful in case you have a longer class name (possibly by convention) that you now don't have to type out. On Thu, May 12, 2016, 01:17 Kevin Barabash <kevinb at khanacademy.org> wrote: > @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 <isiahmeadows at gmail.com> > 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 <dawidmj.szlachta at gmail.com> >> 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 <isiahmeadows at gmail.com>: >>> >>>> 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 <ljharb at gmail.com> 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 < >>>>> isiahmeadows at gmail.com> 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 <kevinb at khanacademy.org> >>>>>> 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 < >>>>>>> isiahmeadows at gmail.com> 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 <kdex at kdex.de> 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 <ggadwa at charter.net> >>>>>>>>> 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 >>>>>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>>>>> > > > <mailto:balancetraveller%2Bes-discuss at gmail.com>> 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 >>>>>>>>> > > > <kevinb at khanacademy.org <mailto:kevinb at khanacademy.org>> >>>>>>>>> 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 >>>>>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>>>>> > > > <mailto:balancetraveller+es-discuss at gmail.com>> >>>>>>>>> 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 >>>>>>>>> > > > <kevinb at khanacademy.org <mailto: >>>>>>>>> kevinb at khanacademy.org>> >>>>>>>>> > > 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 >>>>>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>>>>> > > > <mailto: >>>>>>>>> balancetraveller+es-discuss at gmail.com>> 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 >>>>>>>>> > > > <kevinb at khanacademy.org >>>>>>>>> > > > <mailto:kevinb at khanacademy.org>> 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 >>>>>>>>> > > > <kevinb at khanacademy.org >>>>>>>>> > > > <mailto:kevinb at khanacademy.org>> >>>>>>>>> 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 >>>>>>>>> > > > es-discuss at mozilla.org >>>>>>>>> > > > <mailto:es-discuss at mozilla.org> >>>>>>>>> > > > >>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>> > > > >>>>>>>>> > > > >>>>>>>>> > > > >>>>>>>>> > > > >>>>>>>>> _______________________________________________ >>>>>>>>> > > > es-discuss mailing list >>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>> > > es-discuss at mozilla.org> >>>>>>>>> > > > >>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>> > > > >>>>>>>>> > > > >>>>>>>>> > > > >>>>>>>>> > > > >>>>>>>>> _______________________________________________ >>>>>>>>> > > > es-discuss mailing list >>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>> es-discuss at mozilla.org> >>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>> > > > >>>>>>>>> > > > >>>>>>>>> > > > >>>>>>>>> > > > _______________________________________________ >>>>>>>>> > > > es-discuss mailing list >>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>> es-discuss at mozilla.org> >>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>> > > > >>>>>>>>> > > > >>>>>>>>> > > > >>>>>>>>> > > > _______________________________________________ >>>>>>>>> > > > es-discuss mailing list >>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>> es-discuss at mozilla.org> >>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>> > > > >>>>>>>>> > > > >>>>>>>>> > > > _______________________________________________ >>>>>>>>> > > > es-discuss mailing list >>>>>>>>> > > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> >>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>> > > > >>>>>>>>> > > > >>>>>>>>> > > > >>>>>>>>> > > > _______________________________________________ >>>>>>>>> > > > es-discuss mailing list >>>>>>>>> > > > es-discuss at mozilla.org >>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>> > > > >>>>>>>>> > > _______________________________________________ >>>>>>>>> > > es-discuss mailing list >>>>>>>>> > > es-discuss at mozilla.org >>>>>>>>> > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>> > > >>>>>>>>> > >>>>>>>>> >>>>>>>> >>>>>>>> _______________________________________________ >>>>>>>> es-discuss mailing list >>>>>>>> es-discuss at mozilla.org >>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>> >>>>>>>> >>>>>>> _______________________________________________ >>>>>>> es-discuss mailing list >>>>>>> es-discuss at mozilla.org >>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>> >>>>>> >>>>>> _______________________________________________ >>>>>> es-discuss mailing list >>>>>> es-discuss at mozilla.org >>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>> >>>>>> >>>>> >>>> _______________________________________________ >>>> es-discuss mailing list >>>> es-discuss at mozilla.org >>>> https://mail.mozilla.org/listinfo/es-discuss >>>> >>>> >>> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> >> > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160516/996a421b/attachment-0001.html>
@Michael Theriot:
It seems like this model can be abused in the same way that having separate
methods for assign operators can be abused. I think having separate
operators and automatically using [[plusOp]]
if [[assignPlusOp]]
doesn't exist is an easier programming model. People who need the extra
performance can go the extra mile and define both operators.
It seems like this model can be abused in the same way that having separate methods for assign operators can be abused. I think having separate operators and automatically using `[[plusOp]]` if `[[assignPlusOp]]` doesn't exist is an easier programming model. People who need the extra performance can go the extra mile and define both operators. On Sun, May 15, 2016 at 9:56 AM, Michael Theriot < michael.lee.theriot at gmail.com> wrote: > 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 > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160517/adbf78cc/attachment.html>
I'm thinking, instead, static methods should be used. It would be more versatile.
I like the idea of passing both operands as arguments (mainly from an
aesthetics/symmetry point of view), but I can't think of case where it
would be more versatile than instance methods seeing as at least one
argument has to be this
. Could you give an example of when this would be
more versatile?
Since the new syntax is describing what each type should be, maybe we could leverage existing type syntax from Flow/TypeScript.
class Vec2 {
constructor(x, y) {
this.x = x
this.y = y
}
operator+ (x: Vec2, y: Vec2) {
return new this(x.x + y.x, x.y + y.y)
}
operator+ (x: Vec2, y: number) {
return new this(x.x + y, x.y + y)
}
operator+= (x: Vec2, y: Vec2) {
x.x += y.x
x.y += y.y
}
operator+= (x: Vec2, y: number) {
x.x += y
x.y += y
}
// #number += this -> x = x + this
operator- (x: Vec2) {
return new this(-x.x, -x.y)
}
// etc...
}
class Vec3 {
// ...
operator+ (x: Vec3, y: Vec2) {
return new this(x.x + y.x, x.y + y.y, x.z)
}
// etc...
}
On Mon, May 16, 2016 at 12:33 PM, Isiah Meadows <isiahmeadows at gmail.com>
wrote:
> I'm thinking, instead, static methods should be used. It would be more versatile. I like the idea of passing both operands as arguments (mainly from an aesthetics/symmetry point of view), but I can't think of case where it would be more versatile than instance methods seeing as at least one argument has to be `this`. Could you give an example of when this would be more versatile? Since the new syntax is describing what each type should be, maybe we could leverage existing type syntax from Flow/TypeScript. ```js class Vec2 { constructor(x, y) { this.x = x this.y = y } operator+ (x: Vec2, y: Vec2) { return new this(x.x + y.x, x.y + y.y) } operator+ (x: Vec2, y: number) { return new this(x.x + y, x.y + y) } operator+= (x: Vec2, y: Vec2) { x.x += y.x x.y += y.y } operator+= (x: Vec2, y: number) { x.x += y x.y += y } // #number += this -> x = x + this operator- (x: Vec2) { return new this(-x.x, -x.y) } // etc... } class Vec3 { // ... operator+ (x: Vec3, y: Vec2) { return new this(x.x + y.x, x.y + y.y, x.z) } // etc... } ``` On Mon, May 16, 2016 at 12:33 PM, Isiah Meadows <isiahmeadows at gmail.com> wrote: > If both have the operator, the left side would be used (I thought I said > that, but I may have not). I'm thinking, instead, static methods should be > used. It would be more versatile. > > ```js > class Vec2 { > constructor(x, y) { > this.x = x > this.y = y > } > > // `this` and `Vec2` are interchangeable > operator this + this(x, y) { > return new this(x.x + y.x, x.y + y.y) > } > > operator this + #number(x, y) { > return new this(x.x + y, x.y + y) > } > > operator this += this(x, y) { > x.x += y.x > x.y += y.y > } > > operator this += #number(x, y) { > x.x += y > x.y += y > } > > // #number += this -> x = x + this > > operator -this(x) { > return new this(-x.x, -x.y) > } > > // etc... > } > > class Vec3 { > // ... > operator this + Vec2(x, y) { > return new this(x.x + y.x, x.y + y.y, x.z) > } > // etc... > } > ``` > > A few notes on this: > > 1. If an operator doesn't reference `this` or the containing class at > least once, an early error is thrown. > 2. To reference a primitive, you use the hash symbol + the typeof value. > The valid ones include `#string`, `#boolean`, `#number`, `#symbol`, > `#object`, `#function`, and `#undefined`. If value types with custom > `typeof` values are introduced, you have to reference the type directly. > 3. All type references must be either `this`, identifiers, or member > expressions that do not reference `this`. It is an early error otherwise. > Member expressions are evaluated at class definition time as well, so that > can produce visible side effects if a proxy is referenced or a getter is > called. > 4. The operators are checked via `instanceof`. This means, for those that > define operators, the behavior can become visible to previous code if the > other type specified has a static `Symbol.hasInstance` method. > > The reason I provided the `this` alias is for anonymous classes, so you > can create anonymous objects. It's also helpful in case you have a longer > class name (possibly by convention) that you now don't have to type out. > > > On Thu, May 12, 2016, 01:17 Kevin Barabash <kevinb at khanacademy.org> wrote: > >> @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 <isiahmeadows at gmail.com> >> 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 <dawidmj.szlachta at gmail.com> >>> 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 <isiahmeadows at gmail.com>: >>>> >>>>> 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 <ljharb at gmail.com> 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 < >>>>>> isiahmeadows at gmail.com> 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 <kevinb at khanacademy.org> >>>>>>> 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 < >>>>>>>> isiahmeadows at gmail.com> 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 <kdex at kdex.de> 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 <ggadwa at charter.net> >>>>>>>>>> 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 >>>>>>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>>>>>> > > > <mailto:balancetraveller%2Bes-discuss at gmail.com>> 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 >>>>>>>>>> > > > <kevinb at khanacademy.org <mailto:kevinb at khanacademy.org>> >>>>>>>>>> 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 >>>>>>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>>>>>> > > > <mailto:balancetraveller+es-discuss at gmail.com>> >>>>>>>>>> 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 >>>>>>>>>> > > > <kevinb at khanacademy.org <mailto: >>>>>>>>>> kevinb at khanacademy.org>> >>>>>>>>>> > > 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 >>>>>>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>>>>>> > > > <mailto: >>>>>>>>>> balancetraveller+es-discuss at gmail.com>> 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 >>>>>>>>>> > > > <kevinb at khanacademy.org >>>>>>>>>> > > > <mailto:kevinb at khanacademy.org>> 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 >>>>>>>>>> > > > <kevinb at khanacademy.org >>>>>>>>>> > > > <mailto:kevinb at khanacademy.org>> >>>>>>>>>> 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 >>>>>>>>>> > > > es-discuss at mozilla.org >>>>>>>>>> > > > <mailto:es-discuss at mozilla.org> >>>>>>>>>> > > > >>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>> > > > >>>>>>>>>> > > > >>>>>>>>>> > > > >>>>>>>>>> > > > >>>>>>>>>> _______________________________________________ >>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>> > > es-discuss at mozilla.org> >>>>>>>>>> > > > >>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>> > > > >>>>>>>>>> > > > >>>>>>>>>> > > > >>>>>>>>>> > > > >>>>>>>>>> _______________________________________________ >>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>> es-discuss at mozilla.org> >>>>>>>>>> > > > >>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>> > > > >>>>>>>>>> > > > >>>>>>>>>> > > > >>>>>>>>>> > > > _______________________________________________ >>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>> es-discuss at mozilla.org> >>>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>> > > > >>>>>>>>>> > > > >>>>>>>>>> > > > >>>>>>>>>> > > > _______________________________________________ >>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>> es-discuss at mozilla.org> >>>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>> > > > >>>>>>>>>> > > > >>>>>>>>>> > > > _______________________________________________ >>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>> > > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> >>>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>> > > > >>>>>>>>>> > > > >>>>>>>>>> > > > >>>>>>>>>> > > > _______________________________________________ >>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>> > > > es-discuss at mozilla.org >>>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>> > > > >>>>>>>>>> > > _______________________________________________ >>>>>>>>>> > > es-discuss mailing list >>>>>>>>>> > > es-discuss at mozilla.org >>>>>>>>>> > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>> > > >>>>>>>>>> > >>>>>>>>>> >>>>>>>>> >>>>>>>>> _______________________________________________ >>>>>>>>> es-discuss mailing list >>>>>>>>> es-discuss at mozilla.org >>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>> >>>>>>>>> >>>>>>>> _______________________________________________ >>>>>>>> es-discuss mailing list >>>>>>>> es-discuss at mozilla.org >>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>> >>>>>>> >>>>>>> _______________________________________________ >>>>>>> es-discuss mailing list >>>>>>> es-discuss at mozilla.org >>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>> >>>>>>> >>>>>> >>>>> _______________________________________________ >>>>> es-discuss mailing list >>>>> es-discuss at mozilla.org >>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>> >>>>> >>>> >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss at mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >>> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160517/b7361b3e/attachment-0001.html>
I have some concerns. With the short circuiting operators:
Commutative operators, +, *, &&, ||, &, |, ^, automatically flip the
order of operands when their types are different.
&& and || can not "flip" and routing them through a method is not compatible with short-circuiting.
Generally, there are a lot of things that can go wrong in interop with existing code: unlike some other languages in JavaScript operators are often used to coerse to a know type: "+value" to a number, "x|0" to an 32-bit integer, etc. These kinds of guarantees are what "asm.js" is based on, for example, and having to wait until type feedback is available to perform its optimizations is likely to be a non-starter.
I have some concerns. With the short circuiting operators: Commutative operators, +, *, &&, ||, &, |, ^, automatically flip the order of operands when their types are different. && and || can not "flip" and routing them through a method is not compatible with short-circuiting. Generally, there are a lot of things that can go wrong in interop with existing code: unlike some other languages in JavaScript operators are often used to coerse to a know type: "+value" to a number, "x|0" to an 32-bit integer, etc. These kinds of guarantees are what "asm.js" is based on, for example, and having to wait until type feedback is available to perform its optimizations is likely to be a non-starter. On Tue, May 17, 2016 at 10:30 PM, Kevin Barabash <kevinb at khanacademy.org> wrote: > > I'm thinking, instead, static methods should be used. It would be more > versatile. > > I like the idea of passing both operands as arguments (mainly from an > aesthetics/symmetry point of view), but I can't think of case where it > would be more versatile than instance methods seeing as at least one > argument has to be `this`. Could you give an example of when this would be > more versatile? > > Since the new syntax is describing what each type should be, maybe we > could leverage existing type syntax from Flow/TypeScript. > > ```js > class Vec2 { > constructor(x, y) { > this.x = x > this.y = y > } > > operator+ (x: Vec2, y: Vec2) { > return new this(x.x + y.x, x.y + y.y) > } > > operator+ (x: Vec2, y: number) { > return new this(x.x + y, x.y + y) > } > > operator+= (x: Vec2, y: Vec2) { > x.x += y.x > x.y += y.y > } > > operator+= (x: Vec2, y: number) { > x.x += y > x.y += y > } > > // #number += this -> x = x + this > > operator- (x: Vec2) { > return new this(-x.x, -x.y) > } > > // etc... > } > > class Vec3 { > // ... > operator+ (x: Vec3, y: Vec2) { > return new this(x.x + y.x, x.y + y.y, x.z) > } > // etc... > } > ``` > > > > On Mon, May 16, 2016 at 12:33 PM, Isiah Meadows <isiahmeadows at gmail.com> > wrote: > >> If both have the operator, the left side would be used (I thought I said >> that, but I may have not). I'm thinking, instead, static methods should be >> used. It would be more versatile. >> >> ```js >> class Vec2 { >> constructor(x, y) { >> this.x = x >> this.y = y >> } >> >> // `this` and `Vec2` are interchangeable >> operator this + this(x, y) { >> return new this(x.x + y.x, x.y + y.y) >> } >> >> operator this + #number(x, y) { >> return new this(x.x + y, x.y + y) >> } >> >> operator this += this(x, y) { >> x.x += y.x >> x.y += y.y >> } >> >> operator this += #number(x, y) { >> x.x += y >> x.y += y >> } >> >> // #number += this -> x = x + this >> >> operator -this(x) { >> return new this(-x.x, -x.y) >> } >> >> // etc... >> } >> >> class Vec3 { >> // ... >> operator this + Vec2(x, y) { >> return new this(x.x + y.x, x.y + y.y, x.z) >> } >> // etc... >> } >> ``` >> >> A few notes on this: >> >> 1. If an operator doesn't reference `this` or the containing class at >> least once, an early error is thrown. >> 2. To reference a primitive, you use the hash symbol + the typeof value. >> The valid ones include `#string`, `#boolean`, `#number`, `#symbol`, >> `#object`, `#function`, and `#undefined`. If value types with custom >> `typeof` values are introduced, you have to reference the type directly. >> 3. All type references must be either `this`, identifiers, or member >> expressions that do not reference `this`. It is an early error otherwise. >> Member expressions are evaluated at class definition time as well, so that >> can produce visible side effects if a proxy is referenced or a getter is >> called. >> 4. The operators are checked via `instanceof`. This means, for those that >> define operators, the behavior can become visible to previous code if the >> other type specified has a static `Symbol.hasInstance` method. >> >> The reason I provided the `this` alias is for anonymous classes, so you >> can create anonymous objects. It's also helpful in case you have a longer >> class name (possibly by convention) that you now don't have to type out. >> >> >> On Thu, May 12, 2016, 01:17 Kevin Barabash <kevinb at khanacademy.org> >> wrote: >> >>> @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 <isiahmeadows at gmail.com> >>> 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 <dawidmj.szlachta at gmail.com> >>>> 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 <isiahmeadows at gmail.com>: >>>>> >>>>>> 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 <ljharb at gmail.com> 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 < >>>>>>> isiahmeadows at gmail.com> 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 <kevinb at khanacademy.org> >>>>>>>> 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 < >>>>>>>>> isiahmeadows at gmail.com> 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 <kdex at kdex.de> 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 <ggadwa at charter.net> >>>>>>>>>>> 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 >>>>>>>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>>>>>>> > > > <mailto:balancetraveller%2Bes-discuss at gmail.com>> 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 >>>>>>>>>>> > > > <kevinb at khanacademy.org <mailto:kevinb at khanacademy.org>> >>>>>>>>>>> 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 >>>>>>>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>>>>>>> > > > <mailto:balancetraveller+es-discuss at gmail.com>> >>>>>>>>>>> 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 >>>>>>>>>>> > > > <kevinb at khanacademy.org <mailto: >>>>>>>>>>> kevinb at khanacademy.org>> >>>>>>>>>>> > > 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 >>>>>>>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>>>>>>> > > > <mailto: >>>>>>>>>>> balancetraveller+es-discuss at gmail.com>> 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 >>>>>>>>>>> > > > <kevinb at khanacademy.org >>>>>>>>>>> > > > <mailto:kevinb at khanacademy.org>> >>>>>>>>>>> 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 >>>>>>>>>>> > > > <kevinb at khanacademy.org >>>>>>>>>>> > > > <mailto:kevinb at khanacademy.org>> >>>>>>>>>>> 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 >>>>>>>>>>> > > > es-discuss at mozilla.org >>>>>>>>>>> > > > <mailto:es-discuss at mozilla.org> >>>>>>>>>>> > > > >>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>> > > > >>>>>>>>>>> > > > >>>>>>>>>>> > > > >>>>>>>>>>> > > > >>>>>>>>>>> _______________________________________________ >>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>>> > > es-discuss at mozilla.org> >>>>>>>>>>> > > > >>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>> > > > >>>>>>>>>>> > > > >>>>>>>>>>> > > > >>>>>>>>>>> > > > >>>>>>>>>>> _______________________________________________ >>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>>> es-discuss at mozilla.org> >>>>>>>>>>> > > > >>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>> > > > >>>>>>>>>>> > > > >>>>>>>>>>> > > > >>>>>>>>>>> > > > _______________________________________________ >>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>>> es-discuss at mozilla.org> >>>>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>> > > > >>>>>>>>>>> > > > >>>>>>>>>>> > > > >>>>>>>>>>> > > > _______________________________________________ >>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>>> es-discuss at mozilla.org> >>>>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>> > > > >>>>>>>>>>> > > > >>>>>>>>>>> > > > _______________________________________________ >>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>> > > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> >>>>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>> > > > >>>>>>>>>>> > > > >>>>>>>>>>> > > > >>>>>>>>>>> > > > _______________________________________________ >>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>> > > > es-discuss at mozilla.org >>>>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>> > > > >>>>>>>>>>> > > _______________________________________________ >>>>>>>>>>> > > es-discuss mailing list >>>>>>>>>>> > > es-discuss at mozilla.org >>>>>>>>>>> > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>> > > >>>>>>>>>>> > >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> _______________________________________________ >>>>>>>>>> es-discuss mailing list >>>>>>>>>> es-discuss at mozilla.org >>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>> >>>>>>>>>> >>>>>>>>> _______________________________________________ >>>>>>>>> es-discuss mailing list >>>>>>>>> es-discuss at mozilla.org >>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>> >>>>>>>> >>>>>>>> _______________________________________________ >>>>>>>> es-discuss mailing list >>>>>>>> es-discuss at mozilla.org >>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>> >>>>>>>> >>>>>>> >>>>>> _______________________________________________ >>>>>> es-discuss mailing list >>>>>> es-discuss at mozilla.org >>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>> >>>>>> >>>>> >>>> _______________________________________________ >>>> es-discuss mailing list >>>> es-discuss at mozilla.org >>>> https://mail.mozilla.org/listinfo/es-discuss >>>> >>>> >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss at mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >> > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160519/2edd1ccb/attachment-0001.html>
That is a valid concern. As good as having this feature might sound, could this discussion be revisited after static types are addressed and we see how WebAssembly pans out? The reason I ask the latter is because of the above concern about asm.js, which WebAssembly aims to replace in an IMHO far superior way. Depending on the uptake of WebAssembly a few years down the road, it may later become practical to break forward compatibility in that way due to lack of usage. It's not a common use case, though, to send an object of unknown type to an asm.js function, and replacing native methods fails validation, so the risk isn't as high as it might seem.
That is a valid concern. As good as having this feature might sound, could this discussion be revisited after static types are addressed and we see how WebAssembly pans out? The reason I ask the latter is because of the above concern about asm.js, which WebAssembly aims to replace in an IMHO far superior way. Depending on the uptake of WebAssembly a few years down the road, it may later become practical to break forward compatibility in that way due to lack of usage. It's not a common use case, though, to send an object of unknown type to an asm.js function, and replacing native methods fails validation, so the risk isn't as high as it might seem. On Thu, May 19, 2016, 12:36 John Lenz <concavelenz at gmail.com> wrote: > I have some concerns. With the short circuiting operators: > > Commutative operators, +, *, &&, ||, &, |, ^, automatically flip the > order of operands when their types are different. > > && and || can not "flip" and routing them through a method is not > compatible with short-circuiting. > > Generally, there are a lot of things that can go wrong in interop with > existing code: unlike some other languages in JavaScript operators are > often used to coerse to a know type: "+value" to a number, "x|0" to an > 32-bit integer, etc. These kinds of guarantees are what "asm.js" is based > on, for example, and having to wait until type feedback is available to > perform its optimizations is likely to be a non-starter. > > > > > > > > On Tue, May 17, 2016 at 10:30 PM, Kevin Barabash <kevinb at khanacademy.org> > wrote: > >> > I'm thinking, instead, static methods should be used. It would be more >> versatile. >> >> I like the idea of passing both operands as arguments (mainly from an >> aesthetics/symmetry point of view), but I can't think of case where it >> would be more versatile than instance methods seeing as at least one >> argument has to be `this`. Could you give an example of when this would be >> more versatile? >> >> Since the new syntax is describing what each type should be, maybe we >> could leverage existing type syntax from Flow/TypeScript. >> >> ```js >> class Vec2 { >> constructor(x, y) { >> this.x = x >> this.y = y >> } >> >> operator+ (x: Vec2, y: Vec2) { >> return new this(x.x + y.x, x.y + y.y) >> } >> >> operator+ (x: Vec2, y: number) { >> return new this(x.x + y, x.y + y) >> } >> >> operator+= (x: Vec2, y: Vec2) { >> x.x += y.x >> x.y += y.y >> } >> >> operator+= (x: Vec2, y: number) { >> x.x += y >> x.y += y >> } >> >> // #number += this -> x = x + this >> >> operator- (x: Vec2) { >> return new this(-x.x, -x.y) >> } >> >> // etc... >> } >> >> class Vec3 { >> // ... >> operator+ (x: Vec3, y: Vec2) { >> return new this(x.x + y.x, x.y + y.y, x.z) >> } >> // etc... >> } >> ``` >> >> >> >> On Mon, May 16, 2016 at 12:33 PM, Isiah Meadows <isiahmeadows at gmail.com> >> wrote: >> >>> If both have the operator, the left side would be used (I thought I said >>> that, but I may have not). I'm thinking, instead, static methods should be >>> used. It would be more versatile. >>> >>> ```js >>> class Vec2 { >>> constructor(x, y) { >>> this.x = x >>> this.y = y >>> } >>> >>> // `this` and `Vec2` are interchangeable >>> operator this + this(x, y) { >>> return new this(x.x + y.x, x.y + y.y) >>> } >>> >>> operator this + #number(x, y) { >>> return new this(x.x + y, x.y + y) >>> } >>> >>> operator this += this(x, y) { >>> x.x += y.x >>> x.y += y.y >>> } >>> >>> operator this += #number(x, y) { >>> x.x += y >>> x.y += y >>> } >>> >>> // #number += this -> x = x + this >>> >>> operator -this(x) { >>> return new this(-x.x, -x.y) >>> } >>> >>> // etc... >>> } >>> >>> class Vec3 { >>> // ... >>> operator this + Vec2(x, y) { >>> return new this(x.x + y.x, x.y + y.y, x.z) >>> } >>> // etc... >>> } >>> ``` >>> >>> A few notes on this: >>> >>> 1. If an operator doesn't reference `this` or the containing class at >>> least once, an early error is thrown. >>> 2. To reference a primitive, you use the hash symbol + the typeof value. >>> The valid ones include `#string`, `#boolean`, `#number`, `#symbol`, >>> `#object`, `#function`, and `#undefined`. If value types with custom >>> `typeof` values are introduced, you have to reference the type directly. >>> 3. All type references must be either `this`, identifiers, or member >>> expressions that do not reference `this`. It is an early error otherwise. >>> Member expressions are evaluated at class definition time as well, so that >>> can produce visible side effects if a proxy is referenced or a getter is >>> called. >>> 4. The operators are checked via `instanceof`. This means, for those >>> that define operators, the behavior can become visible to previous code if >>> the other type specified has a static `Symbol.hasInstance` method. >>> >>> The reason I provided the `this` alias is for anonymous classes, so you >>> can create anonymous objects. It's also helpful in case you have a longer >>> class name (possibly by convention) that you now don't have to type out. >>> >>> >>> On Thu, May 12, 2016, 01:17 Kevin Barabash <kevinb at khanacademy.org> >>> wrote: >>> >>>> @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 <isiahmeadows at gmail.com> >>>> 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 <dawidmj.szlachta at gmail.com> >>>>> 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 <isiahmeadows at gmail.com>: >>>>>> >>>>>>> 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 <ljharb at gmail.com> 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 < >>>>>>>> isiahmeadows at gmail.com> 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 <kevinb at khanacademy.org> >>>>>>>>> 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 < >>>>>>>>>> isiahmeadows at gmail.com> 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 <kdex at kdex.de> 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 <ggadwa at charter.net> >>>>>>>>>>>> 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 >>>>>>>>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>>>>>>>> > > > <mailto:balancetraveller%2Bes-discuss at gmail.com>> 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 >>>>>>>>>>>> > > > <kevinb at khanacademy.org <mailto: >>>>>>>>>>>> kevinb at khanacademy.org>> 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 >>>>>>>>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>>>>>>>> > > > <mailto:balancetraveller+es-discuss at gmail.com>> >>>>>>>>>>>> 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 >>>>>>>>>>>> > > > <kevinb at khanacademy.org <mailto: >>>>>>>>>>>> kevinb at khanacademy.org>> >>>>>>>>>>>> > > 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 >>>>>>>>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>>>>>>>> > > > <mailto: >>>>>>>>>>>> balancetraveller+es-discuss at gmail.com>> 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 >>>>>>>>>>>> > > > <kevinb at khanacademy.org >>>>>>>>>>>> > > > <mailto:kevinb at khanacademy.org>> >>>>>>>>>>>> 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 >>>>>>>>>>>> > > > <kevinb at khanacademy.org >>>>>>>>>>>> > > > <mailto:kevinb at khanacademy.org>> >>>>>>>>>>>> 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 >>>>>>>>>>>> > > > es-discuss at mozilla.org >>>>>>>>>>>> > > > <mailto:es-discuss at mozilla.org> >>>>>>>>>>>> > > > >>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>> > > > >>>>>>>>>>>> > > > >>>>>>>>>>>> > > > >>>>>>>>>>>> > > > >>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>>>> > > es-discuss at mozilla.org> >>>>>>>>>>>> > > > >>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>> > > > >>>>>>>>>>>> > > > >>>>>>>>>>>> > > > >>>>>>>>>>>> > > > >>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>>>> es-discuss at mozilla.org> >>>>>>>>>>>> > > > >>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>> > > > >>>>>>>>>>>> > > > >>>>>>>>>>>> > > > >>>>>>>>>>>> > > > >>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>>>> es-discuss at mozilla.org> >>>>>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>> > > > >>>>>>>>>>>> > > > >>>>>>>>>>>> > > > >>>>>>>>>>>> > > > _______________________________________________ >>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>>>> es-discuss at mozilla.org> >>>>>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>> > > > >>>>>>>>>>>> > > > >>>>>>>>>>>> > > > _______________________________________________ >>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>> > > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org >>>>>>>>>>>> > >>>>>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>> > > > >>>>>>>>>>>> > > > >>>>>>>>>>>> > > > >>>>>>>>>>>> > > > _______________________________________________ >>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>> > > > es-discuss at mozilla.org >>>>>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>> > > > >>>>>>>>>>>> > > _______________________________________________ >>>>>>>>>>>> > > es-discuss mailing list >>>>>>>>>>>> > > es-discuss at mozilla.org >>>>>>>>>>>> > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>> > > >>>>>>>>>>>> > >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> _______________________________________________ >>>>>>>>>>> es-discuss mailing list >>>>>>>>>>> es-discuss at mozilla.org >>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> _______________________________________________ >>>>>>>>>> es-discuss mailing list >>>>>>>>>> es-discuss at mozilla.org >>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>> >>>>>>>>> >>>>>>>>> _______________________________________________ >>>>>>>>> es-discuss mailing list >>>>>>>>> es-discuss at mozilla.org >>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>> _______________________________________________ >>>>>>> es-discuss mailing list >>>>>>> es-discuss at mozilla.org >>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>> >>>>>>> >>>>>> >>>>> _______________________________________________ >>>>> es-discuss mailing list >>>>> es-discuss at mozilla.org >>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>> >>>>> >>>> _______________________________________________ >>>> es-discuss mailing list >>>> es-discuss at mozilla.org >>>> https://mail.mozilla.org/listinfo/es-discuss >>>> >>> >> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160519/a1ba338a/attachment-0001.html>
Good point. In my original post I mentioned introducing a "use overloading"
directive. We could throw when trying to use this directive
with the "use asm"
directive.
We can definitely wait on this.
Definitely looking forward to static typing. Is sirisian/ecmascript-types the proposal to be following?
Good point. In my original post I mentioned introducing a `"use overloading"` directive. We could throw when trying to use this directive with the `"use asm"` directive. We can definitely wait on this. Definitely looking forward to static typing. Is https://github.com/sirisian/ecmascript-types the proposal to be following? On Thu, May 19, 2016 at 12:35 PM, Isiah Meadows <isiahmeadows at gmail.com> wrote: > That is a valid concern. As good as having this feature might sound, could > this discussion be revisited after static types are addressed and we see > how WebAssembly pans out? The reason I ask the latter is because of the > above concern about asm.js, which WebAssembly aims to replace in an IMHO > far superior way. Depending on the uptake of WebAssembly a few years down > the road, it may later become practical to break forward compatibility in > that way due to lack of usage. It's not a common use case, though, to send > an object of unknown type to an asm.js function, and replacing native > methods fails validation, so the risk isn't as high as it might seem. > > On Thu, May 19, 2016, 12:36 John Lenz <concavelenz at gmail.com> wrote: > >> I have some concerns. With the short circuiting operators: >> >> Commutative operators, +, *, &&, ||, &, |, ^, automatically flip >> the order of operands when their types are different. >> >> && and || can not "flip" and routing them through a method is not >> compatible with short-circuiting. >> >> Generally, there are a lot of things that can go wrong in interop with >> existing code: unlike some other languages in JavaScript operators are >> often used to coerse to a know type: "+value" to a number, "x|0" to an >> 32-bit integer, etc. These kinds of guarantees are what "asm.js" is based >> on, for example, and having to wait until type feedback is available to >> perform its optimizations is likely to be a non-starter. >> >> >> >> >> >> >> >> On Tue, May 17, 2016 at 10:30 PM, Kevin Barabash <kevinb at khanacademy.org> >> wrote: >> >>> > I'm thinking, instead, static methods should be used. It would be >>> more versatile. >>> >>> I like the idea of passing both operands as arguments (mainly from an >>> aesthetics/symmetry point of view), but I can't think of case where it >>> would be more versatile than instance methods seeing as at least one >>> argument has to be `this`. Could you give an example of when this would be >>> more versatile? >>> >>> Since the new syntax is describing what each type should be, maybe we >>> could leverage existing type syntax from Flow/TypeScript. >>> >>> ```js >>> class Vec2 { >>> constructor(x, y) { >>> this.x = x >>> this.y = y >>> } >>> >>> operator+ (x: Vec2, y: Vec2) { >>> return new this(x.x + y.x, x.y + y.y) >>> } >>> >>> operator+ (x: Vec2, y: number) { >>> return new this(x.x + y, x.y + y) >>> } >>> >>> operator+= (x: Vec2, y: Vec2) { >>> x.x += y.x >>> x.y += y.y >>> } >>> >>> operator+= (x: Vec2, y: number) { >>> x.x += y >>> x.y += y >>> } >>> >>> // #number += this -> x = x + this >>> >>> operator- (x: Vec2) { >>> return new this(-x.x, -x.y) >>> } >>> >>> // etc... >>> } >>> >>> class Vec3 { >>> // ... >>> operator+ (x: Vec3, y: Vec2) { >>> return new this(x.x + y.x, x.y + y.y, x.z) >>> } >>> // etc... >>> } >>> ``` >>> >>> >>> >>> On Mon, May 16, 2016 at 12:33 PM, Isiah Meadows <isiahmeadows at gmail.com> >>> wrote: >>> >>>> If both have the operator, the left side would be used (I thought I >>>> said that, but I may have not). I'm thinking, instead, static methods >>>> should be used. It would be more versatile. >>>> >>>> ```js >>>> class Vec2 { >>>> constructor(x, y) { >>>> this.x = x >>>> this.y = y >>>> } >>>> >>>> // `this` and `Vec2` are interchangeable >>>> operator this + this(x, y) { >>>> return new this(x.x + y.x, x.y + y.y) >>>> } >>>> >>>> operator this + #number(x, y) { >>>> return new this(x.x + y, x.y + y) >>>> } >>>> >>>> operator this += this(x, y) { >>>> x.x += y.x >>>> x.y += y.y >>>> } >>>> >>>> operator this += #number(x, y) { >>>> x.x += y >>>> x.y += y >>>> } >>>> >>>> // #number += this -> x = x + this >>>> >>>> operator -this(x) { >>>> return new this(-x.x, -x.y) >>>> } >>>> >>>> // etc... >>>> } >>>> >>>> class Vec3 { >>>> // ... >>>> operator this + Vec2(x, y) { >>>> return new this(x.x + y.x, x.y + y.y, x.z) >>>> } >>>> // etc... >>>> } >>>> ``` >>>> >>>> A few notes on this: >>>> >>>> 1. If an operator doesn't reference `this` or the containing class at >>>> least once, an early error is thrown. >>>> 2. To reference a primitive, you use the hash symbol + the typeof >>>> value. The valid ones include `#string`, `#boolean`, `#number`, `#symbol`, >>>> `#object`, `#function`, and `#undefined`. If value types with custom >>>> `typeof` values are introduced, you have to reference the type directly. >>>> 3. All type references must be either `this`, identifiers, or member >>>> expressions that do not reference `this`. It is an early error otherwise. >>>> Member expressions are evaluated at class definition time as well, so that >>>> can produce visible side effects if a proxy is referenced or a getter is >>>> called. >>>> 4. The operators are checked via `instanceof`. This means, for those >>>> that define operators, the behavior can become visible to previous code if >>>> the other type specified has a static `Symbol.hasInstance` method. >>>> >>>> The reason I provided the `this` alias is for anonymous classes, so you >>>> can create anonymous objects. It's also helpful in case you have a longer >>>> class name (possibly by convention) that you now don't have to type out. >>>> >>>> >>>> On Thu, May 12, 2016, 01:17 Kevin Barabash <kevinb at khanacademy.org> >>>> wrote: >>>> >>>>> @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 <isiahmeadows at gmail.com >>>>> > 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 < >>>>>> dawidmj.szlachta at gmail.com> 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 <isiahmeadows at gmail.com>: >>>>>>> >>>>>>>> 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 <ljharb at gmail.com> >>>>>>>> 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 < >>>>>>>>> isiahmeadows at gmail.com> 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 < >>>>>>>>>> kevinb at khanacademy.org> 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 < >>>>>>>>>>> isiahmeadows at gmail.com> 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 <kdex at kdex.de> 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 <ggadwa at charter.net> >>>>>>>>>>>>> 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 >>>>>>>>>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>>>>>>>>> > > > <mailto:balancetraveller%2Bes-discuss at gmail.com>> 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 >>>>>>>>>>>>> > > > <kevinb at khanacademy.org <mailto: >>>>>>>>>>>>> kevinb at khanacademy.org>> 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 >>>>>>>>>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>>>>>>>>> > > > <mailto:balancetraveller+es-discuss at gmail.com>> >>>>>>>>>>>>> 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 >>>>>>>>>>>>> > > > <kevinb at khanacademy.org <mailto: >>>>>>>>>>>>> kevinb at khanacademy.org>> >>>>>>>>>>>>> > > 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 >>>>>>>>>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>>>>>>>>> > > > <mailto: >>>>>>>>>>>>> balancetraveller+es-discuss at gmail.com>> 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 >>>>>>>>>>>>> > > > <kevinb at khanacademy.org >>>>>>>>>>>>> > > > <mailto:kevinb at khanacademy.org>> >>>>>>>>>>>>> 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 >>>>>>>>>>>>> > > > <kevinb at khanacademy.org >>>>>>>>>>>>> > > > <mailto:kevinb at khanacademy.org>> >>>>>>>>>>>>> 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 >>>>>>>>>>>>> > > > es-discuss at mozilla.org >>>>>>>>>>>>> > > > <mailto:es-discuss at mozilla.org> >>>>>>>>>>>>> > > > >>>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>>>>> > > es-discuss at mozilla.org> >>>>>>>>>>>>> > > > >>>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>>>>> es-discuss at mozilla.org> >>>>>>>>>>>>> > > > >>>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>>>>> es-discuss at mozilla.org> >>>>>>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > _______________________________________________ >>>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>>>>> es-discuss at mozilla.org> >>>>>>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > _______________________________________________ >>>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>>>>> es-discuss at mozilla.org> >>>>>>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > _______________________________________________ >>>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>>> > > > es-discuss at mozilla.org >>>>>>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > _______________________________________________ >>>>>>>>>>>>> > > es-discuss mailing list >>>>>>>>>>>>> > > es-discuss at mozilla.org >>>>>>>>>>>>> > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>> > > >>>>>>>>>>>>> > >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>> es-discuss mailing list >>>>>>>>>>>> es-discuss at mozilla.org >>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>> _______________________________________________ >>>>>>>>>>> es-discuss mailing list >>>>>>>>>>> es-discuss at mozilla.org >>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> _______________________________________________ >>>>>>>>>> es-discuss mailing list >>>>>>>>>> es-discuss at mozilla.org >>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>> _______________________________________________ >>>>>>>> es-discuss mailing list >>>>>>>> es-discuss at mozilla.org >>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>> >>>>>>>> >>>>>>> >>>>>> _______________________________________________ >>>>>> es-discuss mailing list >>>>>> es-discuss at mozilla.org >>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>> >>>>>> >>>>> _______________________________________________ >>>>> es-discuss mailing list >>>>> es-discuss at mozilla.org >>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>> >>>> >>> >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss at mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >>> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160520/8cd3c092/attachment-0001.html>
Maybe, maybe not - it largely depends on how TypeScript and ES end up
converging, and how the efforts for strong typing (like floats, longs,
structs, etc.) end up. Also, TypeScript has quite a few warts remaining,
including with its type system. For example, there's no way at the moment
to properly type check Function.prototype.bind
, you have to either have
variadic generics with up to two arguments or a Turing-complete type
system.
But on the other hand, -1 for a new directive, though. They're ugly, and most the community's leaders agree. And I highly doubt we will need them.
Maybe, maybe not - it largely depends on how TypeScript and ES end up converging, and how the efforts for strong typing (like floats, longs, structs, etc.) end up. Also, TypeScript has quite a few warts remaining, including with its type system. For example, there's no way at the moment to properly type check `Function.prototype.bind`, you have to either have variadic generics with up to two arguments or a Turing-complete type system. But on the other hand, -1 for a new directive, though. They're ugly, and most the community's leaders agree. And I highly doubt we will need them. On Fri, May 20, 2016, 19:34 Kevin Barabash <kevinb at khanacademy.org> wrote: > Good point. In my original post I mentioned introducing a `"use > overloading"` directive. We could throw when trying to use this directive > with the `"use asm"` directive. > > We can definitely wait on this. > > Definitely looking forward to static typing. Is > https://github.com/sirisian/ecmascript-types the proposal to be following? > > On Thu, May 19, 2016 at 12:35 PM, Isiah Meadows <isiahmeadows at gmail.com> > wrote: > >> That is a valid concern. As good as having this feature might sound, >> could this discussion be revisited after static types are addressed and we >> see how WebAssembly pans out? The reason I ask the latter is because of the >> above concern about asm.js, which WebAssembly aims to replace in an IMHO >> far superior way. Depending on the uptake of WebAssembly a few years down >> the road, it may later become practical to break forward compatibility in >> that way due to lack of usage. It's not a common use case, though, to send >> an object of unknown type to an asm.js function, and replacing native >> methods fails validation, so the risk isn't as high as it might seem. >> >> On Thu, May 19, 2016, 12:36 John Lenz <concavelenz at gmail.com> wrote: >> >>> I have some concerns. With the short circuiting operators: >>> >>> Commutative operators, +, *, &&, ||, &, |, ^, automatically flip >>> the order of operands when their types are different. >>> >>> && and || can not "flip" and routing them through a method is not >>> compatible with short-circuiting. >>> >>> Generally, there are a lot of things that can go wrong in interop with >>> existing code: unlike some other languages in JavaScript operators are >>> often used to coerse to a know type: "+value" to a number, "x|0" to an >>> 32-bit integer, etc. These kinds of guarantees are what "asm.js" is based >>> on, for example, and having to wait until type feedback is available to >>> perform its optimizations is likely to be a non-starter. >>> >>> >>> >>> >>> >>> >>> >>> On Tue, May 17, 2016 at 10:30 PM, Kevin Barabash <kevinb at khanacademy.org >>> > wrote: >>> >>>> > I'm thinking, instead, static methods should be used. It would be >>>> more versatile. >>>> >>>> I like the idea of passing both operands as arguments (mainly from an >>>> aesthetics/symmetry point of view), but I can't think of case where it >>>> would be more versatile than instance methods seeing as at least one >>>> argument has to be `this`. Could you give an example of when this would be >>>> more versatile? >>>> >>>> Since the new syntax is describing what each type should be, maybe we >>>> could leverage existing type syntax from Flow/TypeScript. >>>> >>>> ```js >>>> class Vec2 { >>>> constructor(x, y) { >>>> this.x = x >>>> this.y = y >>>> } >>>> >>>> operator+ (x: Vec2, y: Vec2) { >>>> return new this(x.x + y.x, x.y + y.y) >>>> } >>>> >>>> operator+ (x: Vec2, y: number) { >>>> return new this(x.x + y, x.y + y) >>>> } >>>> >>>> operator+= (x: Vec2, y: Vec2) { >>>> x.x += y.x >>>> x.y += y.y >>>> } >>>> >>>> operator+= (x: Vec2, y: number) { >>>> x.x += y >>>> x.y += y >>>> } >>>> >>>> // #number += this -> x = x + this >>>> >>>> operator- (x: Vec2) { >>>> return new this(-x.x, -x.y) >>>> } >>>> >>>> // etc... >>>> } >>>> >>>> class Vec3 { >>>> // ... >>>> operator+ (x: Vec3, y: Vec2) { >>>> return new this(x.x + y.x, x.y + y.y, x.z) >>>> } >>>> // etc... >>>> } >>>> ``` >>>> >>>> >>>> >>>> On Mon, May 16, 2016 at 12:33 PM, Isiah Meadows <isiahmeadows at gmail.com >>>> > wrote: >>>> >>>>> If both have the operator, the left side would be used (I thought I >>>>> said that, but I may have not). I'm thinking, instead, static methods >>>>> should be used. It would be more versatile. >>>>> >>>>> ```js >>>>> class Vec2 { >>>>> constructor(x, y) { >>>>> this.x = x >>>>> this.y = y >>>>> } >>>>> >>>>> // `this` and `Vec2` are interchangeable >>>>> operator this + this(x, y) { >>>>> return new this(x.x + y.x, x.y + y.y) >>>>> } >>>>> >>>>> operator this + #number(x, y) { >>>>> return new this(x.x + y, x.y + y) >>>>> } >>>>> >>>>> operator this += this(x, y) { >>>>> x.x += y.x >>>>> x.y += y.y >>>>> } >>>>> >>>>> operator this += #number(x, y) { >>>>> x.x += y >>>>> x.y += y >>>>> } >>>>> >>>>> // #number += this -> x = x + this >>>>> >>>>> operator -this(x) { >>>>> return new this(-x.x, -x.y) >>>>> } >>>>> >>>>> // etc... >>>>> } >>>>> >>>>> class Vec3 { >>>>> // ... >>>>> operator this + Vec2(x, y) { >>>>> return new this(x.x + y.x, x.y + y.y, x.z) >>>>> } >>>>> // etc... >>>>> } >>>>> ``` >>>>> >>>>> A few notes on this: >>>>> >>>>> 1. If an operator doesn't reference `this` or the containing class at >>>>> least once, an early error is thrown. >>>>> 2. To reference a primitive, you use the hash symbol + the typeof >>>>> value. The valid ones include `#string`, `#boolean`, `#number`, `#symbol`, >>>>> `#object`, `#function`, and `#undefined`. If value types with custom >>>>> `typeof` values are introduced, you have to reference the type directly. >>>>> 3. All type references must be either `this`, identifiers, or member >>>>> expressions that do not reference `this`. It is an early error otherwise. >>>>> Member expressions are evaluated at class definition time as well, so that >>>>> can produce visible side effects if a proxy is referenced or a getter is >>>>> called. >>>>> 4. The operators are checked via `instanceof`. This means, for those >>>>> that define operators, the behavior can become visible to previous code if >>>>> the other type specified has a static `Symbol.hasInstance` method. >>>>> >>>>> The reason I provided the `this` alias is for anonymous classes, so >>>>> you can create anonymous objects. It's also helpful in case you have a >>>>> longer class name (possibly by convention) that you now don't have to type >>>>> out. >>>>> >>>>> >>>>> On Thu, May 12, 2016, 01:17 Kevin Barabash <kevinb at khanacademy.org> >>>>> wrote: >>>>> >>>>>> @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 < >>>>>> isiahmeadows at gmail.com> 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 < >>>>>>> dawidmj.szlachta at gmail.com> 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 <isiahmeadows at gmail.com>: >>>>>>>> >>>>>>>>> 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 <ljharb at gmail.com> >>>>>>>>> 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 < >>>>>>>>>> isiahmeadows at gmail.com> 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 < >>>>>>>>>>> kevinb at khanacademy.org> 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 < >>>>>>>>>>>> isiahmeadows at gmail.com> 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 <kdex at kdex.de> 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 < >>>>>>>>>>>>>> ggadwa at charter.net> 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 >>>>>>>>>>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>>>>>>>>>> > > > <mailto:balancetraveller%2Bes-discuss at gmail.com>> >>>>>>>>>>>>>> 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 >>>>>>>>>>>>>> > > > <kevinb at khanacademy.org <mailto: >>>>>>>>>>>>>> kevinb at khanacademy.org>> 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 >>>>>>>>>>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>>>>>>>>>> > > > <mailto:balancetraveller+es-discuss at gmail.com>> >>>>>>>>>>>>>> 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 >>>>>>>>>>>>>> > > > <kevinb at khanacademy.org <mailto: >>>>>>>>>>>>>> kevinb at khanacademy.org>> >>>>>>>>>>>>>> > > 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 >>>>>>>>>>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>>>>>>>>>> > > > <mailto: >>>>>>>>>>>>>> balancetraveller+es-discuss at gmail.com>> 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 >>>>>>>>>>>>>> > > > <kevinb at khanacademy.org >>>>>>>>>>>>>> > > > <mailto:kevinb at khanacademy.org>> >>>>>>>>>>>>>> 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 >>>>>>>>>>>>>> > > > <kevinb at khanacademy.org >>>>>>>>>>>>>> > > > <mailto:kevinb at khanacademy.org>> >>>>>>>>>>>>>> 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 >>>>>>>>>>>>>> > > > es-discuss at mozilla.org >>>>>>>>>>>>>> > > > <mailto:es-discuss at mozilla.org> >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>>>>>> > > es-discuss at mozilla.org> >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>>>>>> es-discuss at mozilla.org> >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>>>>>> es-discuss at mozilla.org> >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > _______________________________________________ >>>>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>>>>>> es-discuss at mozilla.org> >>>>>>>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > _______________________________________________ >>>>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>>>>>> es-discuss at mozilla.org> >>>>>>>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > _______________________________________________ >>>>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>>>> > > > es-discuss at mozilla.org >>>>>>>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > _______________________________________________ >>>>>>>>>>>>>> > > es-discuss mailing list >>>>>>>>>>>>>> > > es-discuss at mozilla.org >>>>>>>>>>>>>> > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>> > > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>> es-discuss mailing list >>>>>>>>>>>>> es-discuss at mozilla.org >>>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>> es-discuss mailing list >>>>>>>>>>>> es-discuss at mozilla.org >>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> _______________________________________________ >>>>>>>>>>> es-discuss mailing list >>>>>>>>>>> es-discuss at mozilla.org >>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> >>>>>>>>> _______________________________________________ >>>>>>>>> es-discuss mailing list >>>>>>>>> es-discuss at mozilla.org >>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>> _______________________________________________ >>>>>>> es-discuss mailing list >>>>>>> es-discuss at mozilla.org >>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>> >>>>>>> >>>>>> _______________________________________________ >>>>>> es-discuss mailing list >>>>>> es-discuss at mozilla.org >>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>> >>>>> >>>> >>>> _______________________________________________ >>>> es-discuss mailing list >>>> es-discuss at mozilla.org >>>> https://mail.mozilla.org/listinfo/es-discuss >>>> >>>> >>> > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160521/2f515e7c/attachment-0001.html>
The Closure Compiler type checker just special cases .bind unfortunate. My experiment to make the type checker extensible to avoid special cases (the Type Transformation Language) works but is too complex for normal usage. On May 20, 2016 7:44 PM, "Isiah Meadows" <isiahmeadows at gmail.com> wrote:
Maybe, maybe not - it largely depends on how TypeScript and ES end up
converging, and how the efforts for strong typing (like floats, longs,
structs, etc.) end up. Also, TypeScript has quite a few warts remaining,
including with its type system. For example, there's no way at the moment
to properly type check Function.prototype.bind
, you have to either have
variadic generics with up to two arguments or a Turing-complete type
system.
But on the other hand, -1 for a new directive, though. They're ugly, and most the community's leaders agree. And I highly doubt we will need them.
The Closure Compiler type checker just special cases .bind unfortunate. My experiment to make the type checker extensible to avoid special cases (the Type Transformation Language) works but is too complex for normal usage. On May 20, 2016 7:44 PM, "Isiah Meadows" <isiahmeadows at gmail.com> wrote: Maybe, maybe not - it largely depends on how TypeScript and ES end up converging, and how the efforts for strong typing (like floats, longs, structs, etc.) end up. Also, TypeScript has quite a few warts remaining, including with its type system. For example, there's no way at the moment to properly type check `Function.prototype.bind`, you have to either have variadic generics with up to two arguments or a Turing-complete type system. But on the other hand, -1 for a new directive, though. They're ugly, and most the community's leaders agree. And I highly doubt we will need them. On Fri, May 20, 2016, 19:34 Kevin Barabash <kevinb at khanacademy.org> wrote: > Good point. In my original post I mentioned introducing a `"use > overloading"` directive. We could throw when trying to use this directive > with the `"use asm"` directive. > > We can definitely wait on this. > > Definitely looking forward to static typing. Is > https://github.com/sirisian/ecmascript-types the proposal to be following? > > On Thu, May 19, 2016 at 12:35 PM, Isiah Meadows <isiahmeadows at gmail.com> > wrote: > >> That is a valid concern. As good as having this feature might sound, >> could this discussion be revisited after static types are addressed and we >> see how WebAssembly pans out? The reason I ask the latter is because of the >> above concern about asm.js, which WebAssembly aims to replace in an IMHO >> far superior way. Depending on the uptake of WebAssembly a few years down >> the road, it may later become practical to break forward compatibility in >> that way due to lack of usage. It's not a common use case, though, to send >> an object of unknown type to an asm.js function, and replacing native >> methods fails validation, so the risk isn't as high as it might seem. >> >> On Thu, May 19, 2016, 12:36 John Lenz <concavelenz at gmail.com> wrote: >> >>> I have some concerns. With the short circuiting operators: >>> >>> Commutative operators, +, *, &&, ||, &, |, ^, automatically flip >>> the order of operands when their types are different. >>> >>> && and || can not "flip" and routing them through a method is not >>> compatible with short-circuiting. >>> >>> Generally, there are a lot of things that can go wrong in interop with >>> existing code: unlike some other languages in JavaScript operators are >>> often used to coerse to a know type: "+value" to a number, "x|0" to an >>> 32-bit integer, etc. These kinds of guarantees are what "asm.js" is based >>> on, for example, and having to wait until type feedback is available to >>> perform its optimizations is likely to be a non-starter. >>> >>> >>> >>> >>> >>> >>> >>> On Tue, May 17, 2016 at 10:30 PM, Kevin Barabash <kevinb at khanacademy.org >>> > wrote: >>> >>>> > I'm thinking, instead, static methods should be used. It would be >>>> more versatile. >>>> >>>> I like the idea of passing both operands as arguments (mainly from an >>>> aesthetics/symmetry point of view), but I can't think of case where it >>>> would be more versatile than instance methods seeing as at least one >>>> argument has to be `this`. Could you give an example of when this would be >>>> more versatile? >>>> >>>> Since the new syntax is describing what each type should be, maybe we >>>> could leverage existing type syntax from Flow/TypeScript. >>>> >>>> ```js >>>> class Vec2 { >>>> constructor(x, y) { >>>> this.x = x >>>> this.y = y >>>> } >>>> >>>> operator+ (x: Vec2, y: Vec2) { >>>> return new this(x.x + y.x, x.y + y.y) >>>> } >>>> >>>> operator+ (x: Vec2, y: number) { >>>> return new this(x.x + y, x.y + y) >>>> } >>>> >>>> operator+= (x: Vec2, y: Vec2) { >>>> x.x += y.x >>>> x.y += y.y >>>> } >>>> >>>> operator+= (x: Vec2, y: number) { >>>> x.x += y >>>> x.y += y >>>> } >>>> >>>> // #number += this -> x = x + this >>>> >>>> operator- (x: Vec2) { >>>> return new this(-x.x, -x.y) >>>> } >>>> >>>> // etc... >>>> } >>>> >>>> class Vec3 { >>>> // ... >>>> operator+ (x: Vec3, y: Vec2) { >>>> return new this(x.x + y.x, x.y + y.y, x.z) >>>> } >>>> // etc... >>>> } >>>> ``` >>>> >>>> >>>> >>>> On Mon, May 16, 2016 at 12:33 PM, Isiah Meadows <isiahmeadows at gmail.com >>>> > wrote: >>>> >>>>> If both have the operator, the left side would be used (I thought I >>>>> said that, but I may have not). I'm thinking, instead, static methods >>>>> should be used. It would be more versatile. >>>>> >>>>> ```js >>>>> class Vec2 { >>>>> constructor(x, y) { >>>>> this.x = x >>>>> this.y = y >>>>> } >>>>> >>>>> // `this` and `Vec2` are interchangeable >>>>> operator this + this(x, y) { >>>>> return new this(x.x + y.x, x.y + y.y) >>>>> } >>>>> >>>>> operator this + #number(x, y) { >>>>> return new this(x.x + y, x.y + y) >>>>> } >>>>> >>>>> operator this += this(x, y) { >>>>> x.x += y.x >>>>> x.y += y.y >>>>> } >>>>> >>>>> operator this += #number(x, y) { >>>>> x.x += y >>>>> x.y += y >>>>> } >>>>> >>>>> // #number += this -> x = x + this >>>>> >>>>> operator -this(x) { >>>>> return new this(-x.x, -x.y) >>>>> } >>>>> >>>>> // etc... >>>>> } >>>>> >>>>> class Vec3 { >>>>> // ... >>>>> operator this + Vec2(x, y) { >>>>> return new this(x.x + y.x, x.y + y.y, x.z) >>>>> } >>>>> // etc... >>>>> } >>>>> ``` >>>>> >>>>> A few notes on this: >>>>> >>>>> 1. If an operator doesn't reference `this` or the containing class at >>>>> least once, an early error is thrown. >>>>> 2. To reference a primitive, you use the hash symbol + the typeof >>>>> value. The valid ones include `#string`, `#boolean`, `#number`, `#symbol`, >>>>> `#object`, `#function`, and `#undefined`. If value types with custom >>>>> `typeof` values are introduced, you have to reference the type directly. >>>>> 3. All type references must be either `this`, identifiers, or member >>>>> expressions that do not reference `this`. It is an early error otherwise. >>>>> Member expressions are evaluated at class definition time as well, so that >>>>> can produce visible side effects if a proxy is referenced or a getter is >>>>> called. >>>>> 4. The operators are checked via `instanceof`. This means, for those >>>>> that define operators, the behavior can become visible to previous code if >>>>> the other type specified has a static `Symbol.hasInstance` method. >>>>> >>>>> The reason I provided the `this` alias is for anonymous classes, so >>>>> you can create anonymous objects. It's also helpful in case you have a >>>>> longer class name (possibly by convention) that you now don't have to type >>>>> out. >>>>> >>>>> >>>>> On Thu, May 12, 2016, 01:17 Kevin Barabash <kevinb at khanacademy.org> >>>>> wrote: >>>>> >>>>>> @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 < >>>>>> isiahmeadows at gmail.com> 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 < >>>>>>> dawidmj.szlachta at gmail.com> 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 <isiahmeadows at gmail.com>: >>>>>>>> >>>>>>>>> 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 <ljharb at gmail.com> >>>>>>>>> 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 < >>>>>>>>>> isiahmeadows at gmail.com> 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 < >>>>>>>>>>> kevinb at khanacademy.org> 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 < >>>>>>>>>>>> isiahmeadows at gmail.com> 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 <kdex at kdex.de> 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 < >>>>>>>>>>>>>> ggadwa at charter.net> 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 >>>>>>>>>>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>>>>>>>>>> > > > <mailto:balancetraveller%2Bes-discuss at gmail.com>> >>>>>>>>>>>>>> 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 >>>>>>>>>>>>>> > > > <kevinb at khanacademy.org <mailto: >>>>>>>>>>>>>> kevinb at khanacademy.org>> 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 >>>>>>>>>>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>>>>>>>>>> > > > <mailto:balancetraveller+es-discuss at gmail.com>> >>>>>>>>>>>>>> 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 >>>>>>>>>>>>>> > > > <kevinb at khanacademy.org <mailto: >>>>>>>>>>>>>> kevinb at khanacademy.org>> >>>>>>>>>>>>>> > > 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 >>>>>>>>>>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>>>>>>>>>> > > > <mailto: >>>>>>>>>>>>>> balancetraveller+es-discuss at gmail.com>> 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 >>>>>>>>>>>>>> > > > <kevinb at khanacademy.org >>>>>>>>>>>>>> > > > <mailto:kevinb at khanacademy.org>> >>>>>>>>>>>>>> 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 >>>>>>>>>>>>>> > > > <kevinb at khanacademy.org >>>>>>>>>>>>>> > > > <mailto:kevinb at khanacademy.org>> >>>>>>>>>>>>>> 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 >>>>>>>>>>>>>> > > > es-discuss at mozilla.org >>>>>>>>>>>>>> > > > <mailto:es-discuss at mozilla.org> >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>>>>>> > > es-discuss at mozilla.org> >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>>>>>> es-discuss at mozilla.org> >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>>>>>> es-discuss at mozilla.org> >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > _______________________________________________ >>>>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>>>>>> es-discuss at mozilla.org> >>>>>>>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > _______________________________________________ >>>>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>>>>>> es-discuss at mozilla.org> >>>>>>>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > _______________________________________________ >>>>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>>>> > > > es-discuss at mozilla.org >>>>>>>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > _______________________________________________ >>>>>>>>>>>>>> > > es-discuss mailing list >>>>>>>>>>>>>> > > es-discuss at mozilla.org >>>>>>>>>>>>>> > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>> > > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>> es-discuss mailing list >>>>>>>>>>>>> es-discuss at mozilla.org >>>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>> es-discuss mailing list >>>>>>>>>>>> es-discuss at mozilla.org >>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> _______________________________________________ >>>>>>>>>>> es-discuss mailing list >>>>>>>>>>> es-discuss at mozilla.org >>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> >>>>>>>>> _______________________________________________ >>>>>>>>> es-discuss mailing list >>>>>>>>> es-discuss at mozilla.org >>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>> _______________________________________________ >>>>>>> es-discuss mailing list >>>>>>> es-discuss at mozilla.org >>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>> >>>>>>> >>>>>> _______________________________________________ >>>>>> es-discuss mailing list >>>>>> es-discuss at mozilla.org >>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>> >>>>> >>>> >>>> _______________________________________________ >>>> es-discuss mailing list >>>> es-discuss at mozilla.org >>>> https://mail.mozilla.org/listinfo/es-discuss >>>> >>>> >>> > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160521/439736da/attachment-0001.html>
For the TypeScript end, check out Microsoft/TypeScript#5453. The aim is to produce something general purpose, because of several functional libraries and some frameworks that need this as well. Rx.js, Lodash, Underscore, and Ramda (I think) all need this.
For the TypeScript end, check out https://github.com/Microsoft/TypeScript/issues/5453. The aim is to produce something general purpose, because of several functional libraries and some frameworks that need this as well. Rx.js, Lodash, Underscore, and Ramda (I think) all need this. On Sat, May 21, 2016, 16:34 John Lenz <concavelenz at gmail.com> wrote: > The Closure Compiler type checker just special cases .bind unfortunate. > My experiment to make the type checker extensible to avoid special cases > (the Type Transformation Language) works but is too complex for normal > usage. > On May 20, 2016 7:44 PM, "Isiah Meadows" <isiahmeadows at gmail.com> wrote: > > Maybe, maybe not - it largely depends on how TypeScript and ES end up > converging, and how the efforts for strong typing (like floats, longs, > structs, etc.) end up. Also, TypeScript has quite a few warts remaining, > including with its type system. For example, there's no way at the moment > to properly type check `Function.prototype.bind`, you have to either have > variadic generics with up to two arguments or a Turing-complete type > system. > > But on the other hand, -1 for a new directive, though. They're ugly, and > most the community's leaders agree. And I highly doubt we will need them. > > On Fri, May 20, 2016, 19:34 Kevin Barabash <kevinb at khanacademy.org> wrote: > >> Good point. In my original post I mentioned introducing a `"use >> overloading"` directive. We could throw when trying to use this directive >> with the `"use asm"` directive. >> >> We can definitely wait on this. >> >> Definitely looking forward to static typing. Is >> https://github.com/sirisian/ecmascript-types the proposal to be >> following? >> >> On Thu, May 19, 2016 at 12:35 PM, Isiah Meadows <isiahmeadows at gmail.com> >> wrote: >> >>> That is a valid concern. As good as having this feature might sound, >>> could this discussion be revisited after static types are addressed and we >>> see how WebAssembly pans out? The reason I ask the latter is because of the >>> above concern about asm.js, which WebAssembly aims to replace in an IMHO >>> far superior way. Depending on the uptake of WebAssembly a few years down >>> the road, it may later become practical to break forward compatibility in >>> that way due to lack of usage. It's not a common use case, though, to send >>> an object of unknown type to an asm.js function, and replacing native >>> methods fails validation, so the risk isn't as high as it might seem. >>> >>> On Thu, May 19, 2016, 12:36 John Lenz <concavelenz at gmail.com> wrote: >>> >>>> I have some concerns. With the short circuiting operators: >>>> >>>> Commutative operators, +, *, &&, ||, &, |, ^, automatically flip >>>> the order of operands when their types are different. >>>> >>>> && and || can not "flip" and routing them through a method is not >>>> compatible with short-circuiting. >>>> >>>> Generally, there are a lot of things that can go wrong in interop with >>>> existing code: unlike some other languages in JavaScript operators are >>>> often used to coerse to a know type: "+value" to a number, "x|0" to an >>>> 32-bit integer, etc. These kinds of guarantees are what "asm.js" is based >>>> on, for example, and having to wait until type feedback is available to >>>> perform its optimizations is likely to be a non-starter. >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> On Tue, May 17, 2016 at 10:30 PM, Kevin Barabash < >>>> kevinb at khanacademy.org> wrote: >>>> >>>>> > I'm thinking, instead, static methods should be used. It would be >>>>> more versatile. >>>>> >>>>> I like the idea of passing both operands as arguments (mainly from an >>>>> aesthetics/symmetry point of view), but I can't think of case where it >>>>> would be more versatile than instance methods seeing as at least one >>>>> argument has to be `this`. Could you give an example of when this would be >>>>> more versatile? >>>>> >>>>> Since the new syntax is describing what each type should be, maybe we >>>>> could leverage existing type syntax from Flow/TypeScript. >>>>> >>>>> ```js >>>>> class Vec2 { >>>>> constructor(x, y) { >>>>> this.x = x >>>>> this.y = y >>>>> } >>>>> >>>>> operator+ (x: Vec2, y: Vec2) { >>>>> return new this(x.x + y.x, x.y + y.y) >>>>> } >>>>> >>>>> operator+ (x: Vec2, y: number) { >>>>> return new this(x.x + y, x.y + y) >>>>> } >>>>> >>>>> operator+= (x: Vec2, y: Vec2) { >>>>> x.x += y.x >>>>> x.y += y.y >>>>> } >>>>> >>>>> operator+= (x: Vec2, y: number) { >>>>> x.x += y >>>>> x.y += y >>>>> } >>>>> >>>>> // #number += this -> x = x + this >>>>> >>>>> operator- (x: Vec2) { >>>>> return new this(-x.x, -x.y) >>>>> } >>>>> >>>>> // etc... >>>>> } >>>>> >>>>> class Vec3 { >>>>> // ... >>>>> operator+ (x: Vec3, y: Vec2) { >>>>> return new this(x.x + y.x, x.y + y.y, x.z) >>>>> } >>>>> // etc... >>>>> } >>>>> ``` >>>>> >>>>> >>>>> >>>>> On Mon, May 16, 2016 at 12:33 PM, Isiah Meadows < >>>>> isiahmeadows at gmail.com> wrote: >>>>> >>>>>> If both have the operator, the left side would be used (I thought I >>>>>> said that, but I may have not). I'm thinking, instead, static methods >>>>>> should be used. It would be more versatile. >>>>>> >>>>>> ```js >>>>>> class Vec2 { >>>>>> constructor(x, y) { >>>>>> this.x = x >>>>>> this.y = y >>>>>> } >>>>>> >>>>>> // `this` and `Vec2` are interchangeable >>>>>> operator this + this(x, y) { >>>>>> return new this(x.x + y.x, x.y + y.y) >>>>>> } >>>>>> >>>>>> operator this + #number(x, y) { >>>>>> return new this(x.x + y, x.y + y) >>>>>> } >>>>>> >>>>>> operator this += this(x, y) { >>>>>> x.x += y.x >>>>>> x.y += y.y >>>>>> } >>>>>> >>>>>> operator this += #number(x, y) { >>>>>> x.x += y >>>>>> x.y += y >>>>>> } >>>>>> >>>>>> // #number += this -> x = x + this >>>>>> >>>>>> operator -this(x) { >>>>>> return new this(-x.x, -x.y) >>>>>> } >>>>>> >>>>>> // etc... >>>>>> } >>>>>> >>>>>> class Vec3 { >>>>>> // ... >>>>>> operator this + Vec2(x, y) { >>>>>> return new this(x.x + y.x, x.y + y.y, x.z) >>>>>> } >>>>>> // etc... >>>>>> } >>>>>> ``` >>>>>> >>>>>> A few notes on this: >>>>>> >>>>>> 1. If an operator doesn't reference `this` or the containing class at >>>>>> least once, an early error is thrown. >>>>>> 2. To reference a primitive, you use the hash symbol + the typeof >>>>>> value. The valid ones include `#string`, `#boolean`, `#number`, `#symbol`, >>>>>> `#object`, `#function`, and `#undefined`. If value types with custom >>>>>> `typeof` values are introduced, you have to reference the type directly. >>>>>> 3. All type references must be either `this`, identifiers, or member >>>>>> expressions that do not reference `this`. It is an early error otherwise. >>>>>> Member expressions are evaluated at class definition time as well, so that >>>>>> can produce visible side effects if a proxy is referenced or a getter is >>>>>> called. >>>>>> 4. The operators are checked via `instanceof`. This means, for those >>>>>> that define operators, the behavior can become visible to previous code if >>>>>> the other type specified has a static `Symbol.hasInstance` method. >>>>>> >>>>>> The reason I provided the `this` alias is for anonymous classes, so >>>>>> you can create anonymous objects. It's also helpful in case you have a >>>>>> longer class name (possibly by convention) that you now don't have to type >>>>>> out. >>>>>> >>>>>> >>>>>> On Thu, May 12, 2016, 01:17 Kevin Barabash <kevinb at khanacademy.org> >>>>>> wrote: >>>>>> >>>>>>> @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 < >>>>>>> isiahmeadows at gmail.com> 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 < >>>>>>>> dawidmj.szlachta at gmail.com> 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 <isiahmeadows at gmail.com>: >>>>>>>>> >>>>>>>>>> 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 <ljharb at gmail.com> >>>>>>>>>> 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 < >>>>>>>>>>> isiahmeadows at gmail.com> 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 < >>>>>>>>>>>> kevinb at khanacademy.org> 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 < >>>>>>>>>>>>> isiahmeadows at gmail.com> 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 <kdex at kdex.de> 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 < >>>>>>>>>>>>>>> ggadwa at charter.net> 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 >>>>>>>>>>>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>>>>>>>>>>> > > > <mailto:balancetraveller%2Bes-discuss at gmail.com>> >>>>>>>>>>>>>>> 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 >>>>>>>>>>>>>>> > > > <kevinb at khanacademy.org <mailto: >>>>>>>>>>>>>>> kevinb at khanacademy.org>> 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 >>>>>>>>>>>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>>>>>>>>>>> > > > <mailto:balancetraveller+es-discuss at gmail.com>> >>>>>>>>>>>>>>> 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 >>>>>>>>>>>>>>> > > > <kevinb at khanacademy.org <mailto: >>>>>>>>>>>>>>> kevinb at khanacademy.org>> >>>>>>>>>>>>>>> > > 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 >>>>>>>>>>>>>>> > > > <balancetraveller+es-discuss at gmail.com >>>>>>>>>>>>>>> > > > <mailto: >>>>>>>>>>>>>>> balancetraveller+es-discuss at gmail.com>> 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 >>>>>>>>>>>>>>> > > > <kevinb at khanacademy.org >>>>>>>>>>>>>>> > > > <mailto:kevinb at khanacademy.org>> >>>>>>>>>>>>>>> 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 >>>>>>>>>>>>>>> > > > <kevinb at khanacademy.org >>>>>>>>>>>>>>> > > > <mailto:kevinb at khanacademy.org>> >>>>>>>>>>>>>>> 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 >>>>>>>>>>>>>>> > > > es-discuss at mozilla.org >>>>>>>>>>>>>>> > > > <mailto:es-discuss at mozilla.org >>>>>>>>>>>>>>> > >>>>>>>>>>>>>>> > > > >>>>>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>>> > > > >>>>>>>>>>>>>>> > > > >>>>>>>>>>>>>>> > > > >>>>>>>>>>>>>>> > > > >>>>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>>>>>>> > > es-discuss at mozilla.org> >>>>>>>>>>>>>>> > > > >>>>>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>>> > > > >>>>>>>>>>>>>>> > > > >>>>>>>>>>>>>>> > > > >>>>>>>>>>>>>>> > > > >>>>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>>>>>>> es-discuss at mozilla.org> >>>>>>>>>>>>>>> > > > >>>>>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>>> > > > >>>>>>>>>>>>>>> > > > >>>>>>>>>>>>>>> > > > >>>>>>>>>>>>>>> > > > >>>>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>>>>>>> es-discuss at mozilla.org> >>>>>>>>>>>>>>> > > > >>>>>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>>> > > > >>>>>>>>>>>>>>> > > > >>>>>>>>>>>>>>> > > > >>>>>>>>>>>>>>> > > > _______________________________________________ >>>>>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>>>>>>> es-discuss at mozilla.org> >>>>>>>>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>>> > > > >>>>>>>>>>>>>>> > > > >>>>>>>>>>>>>>> > > > _______________________________________________ >>>>>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>>>>> > > > es-discuss at mozilla.org <mailto: >>>>>>>>>>>>>>> es-discuss at mozilla.org> >>>>>>>>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>>> > > > >>>>>>>>>>>>>>> > > > >>>>>>>>>>>>>>> > > > >>>>>>>>>>>>>>> > > > _______________________________________________ >>>>>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>>>>> > > > es-discuss at mozilla.org >>>>>>>>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>>> > > > >>>>>>>>>>>>>>> > > _______________________________________________ >>>>>>>>>>>>>>> > > es-discuss mailing list >>>>>>>>>>>>>>> > > es-discuss at mozilla.org >>>>>>>>>>>>>>> > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>>> > > >>>>>>>>>>>>>>> > >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>>> es-discuss mailing list >>>>>>>>>>>>>> es-discuss at mozilla.org >>>>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>> es-discuss mailing list >>>>>>>>>>>>> es-discuss at mozilla.org >>>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>> es-discuss mailing list >>>>>>>>>>>> es-discuss at mozilla.org >>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> _______________________________________________ >>>>>>>>>> es-discuss mailing list >>>>>>>>>> es-discuss at mozilla.org >>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>> _______________________________________________ >>>>>>>> es-discuss mailing list >>>>>>>> es-discuss at mozilla.org >>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>> >>>>>>>> >>>>>>> _______________________________________________ >>>>>>> es-discuss mailing list >>>>>>> es-discuss at mozilla.org >>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>> >>>>>> >>>>> >>>>> _______________________________________________ >>>>> es-discuss mailing list >>>>> es-discuss at mozilla.org >>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>> >>>>> >>>> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160521/bc9407d1/attachment-0001.html>
I think it would be also nice to have some "low level API" that would allow to provide some interceptor object, which will trap all operators invocations in some block of code. (at least for cases when both/some arguments of operation are not primitives). Then if this particular interceptor can't handle given arguments, it should be able to delegate execution of this operation to some "outer scope", assuming that at the out-most level is present some default handler that always executes/evaluates operations as it is specified now in JS.
So in code it may look like:
const localOperatorsInterceptor = Object.freeze({
__proto__: null, // to prevent scope pollution when using this object with ``with``-statement
[Symbol.operatorsInterceptor]: Object.freeze({
["_+_"]: function(a, b, proceed) {
console.log("operation(a+b):", a, b);
return proceed(a,b);
},
["+_"]: function(a, proceed) {
console.log("operation(+a):", a);
return proceed(a);
},
["++_"]: function(a, proceed) {
console.log("operation(++a):", a);
// returned value will be assigned back to "target" variable/expression
// and returned as result of (++_)
return proceed(a);
},
["_++"]: function(a, proceed) {
console.log("operation(a++):", a);
// returned value will be assigned back to "target" variable/expression
// former value of "target" variable/expression will become result of (_++)
return proceed(a);
}
// etc
})
});
with(localOperatorsInterceptor) {
var res = {x:"y"} + {a:"b"}; // this should log: operation(a+b): ({x:"y"}) ({a:"b"})
console.log(res); // res should become NaN since interceptor delegates execution to default operators handler
var doInc = function(x) {
return ++x;
};
res = doInc({foo: "bar"}); // this should log: operation(++a): ({foo: "bar"})
console.log(res); // res should stay equal NaN since interceptor delegates execution to default operators handler
}
It is proposed to use with
statement to localise block of code to which
this interceptor is applied. Interceptor may be organised as frozen object
with only one property which name is some "well-known symbol", for an
instance Symbol.operatorsInterceptor
. Since it is not assumed that
interceptor has "normal" (string named) properties (and has __proto__ == null
) it should generally not pollute code block scope with some extra
names, but only affect how operators are executed/evaluated inside that
block of code. Also if interceptor itself and handlers object too will be
both frozen, then it should not break engine optimisation capabilities.
Meaning that if some function expression is defined inside that
with
-statement, than all operators inside that function can be resolved
at function expression evaluation time (since all "withed" objects contents
are final). Also it can be specified that even if interceptor handler
object is not frozen, then anyway some snapshot of it state can be taken
(and actually that handler snapshot may be used as effective operators
handler for with
-ed block of code).
So if this operators interceptor feature would be available then it would be possible to implement any custom system of symbol to operation mapping in different "third-party" operators overloading libraries, which can be also good at first time - to let people do some experiments in this area.
Also for me it looks like a good thing to have possibility to control
whether some system of operators will be applied to some code or not. In
case of with
-based approach it is controlled "very" explicitly - unless
you specify some with(someOperatorsInterceptor)
no operators
overloading will be applied to your code. An if you want override some
operators in some sub-block of code, you can always span that sub-block
with some other with(anotherOperatorsInterceptor)
statement and
anotherOperatorsInterceptor
interceptor will take precedence over
previous/outer one in target sub-block of code.
Of course it would be more nice to use something like import
instead of
with
, like for example in Scala, import
may serve like more
convenient form of with
:
Scala( { import obj._; /*some code*/ }
) <==> Js( with (obj) { /*some code*/ }
)
[1], [2]
But since import
is reserved for modules I am not sure whether it can
be adapted to serve for this purposes too.
I think it would be also nice to have some "low level API" that would allow to provide some interceptor object, which will trap all operators invocations in some block of code. (at least for cases when both/some arguments of operation are not primitives). Then if this particular interceptor can't handle given arguments, it should be able to delegate execution of this operation to some "outer scope", assuming that at the out-most level is present some default handler that always executes/evaluates operations as it is specified now in JS. So in code it may look like: ```js const localOperatorsInterceptor = Object.freeze({ __proto__: null, // to prevent scope pollution when using this object with ``with``-statement [Symbol.operatorsInterceptor]: Object.freeze({ ["_+_"]: function(a, b, proceed) { console.log("operation(a+b):", a, b); return proceed(a,b); }, ["+_"]: function(a, proceed) { console.log("operation(+a):", a); return proceed(a); }, ["++_"]: function(a, proceed) { console.log("operation(++a):", a); // returned value will be assigned back to "target" variable/expression and returned as result of (++_) return proceed(a); }, ["_++"]: function(a, proceed) { console.log("operation(a++):", a); // returned value will be assigned back to "target" variable/expression // former value of "target" variable/expression will become result of (_++) return proceed(a); } // etc }) }); with(localOperatorsInterceptor) { var res = {x:"y"} + {a:"b"}; // this should log: operation(a+b): ({x:"y"}) ({a:"b"}) console.log(res); // res should become NaN since interceptor delegates execution to default operators handler var doInc = function(x) { return ++x; }; res = doInc({foo: "bar"}); // this should log: operation(++a): ({foo: "bar"}) console.log(res); // res should stay equal NaN since interceptor delegates execution to default operators handler } ``` It is proposed to use ``with`` statement to localise block of code to which this interceptor is applied. Interceptor may be organised as frozen object with only one property which name is some "well-known symbol", for an instance ``Symbol.operatorsInterceptor``. Since it is not assumed that interceptor has "normal" (string named) properties (and has ``__proto__ == null``) it should generally not pollute code block scope with some extra names, but only affect how operators are executed/evaluated inside that block of code. Also if interceptor itself and handlers object too will be both frozen, then it should not break engine optimisation capabilities. Meaning that if some function expression is defined inside that ``with``-statement, than all operators inside that function can be resolved at function expression evaluation time (since all "withed" objects contents are final). Also it can be specified that even if interceptor handler object is not frozen, then anyway some snapshot of it state can be taken (and actually that handler snapshot may be used as effective operators handler for ``with``-ed block of code). So if this operators interceptor feature would be available then it would be possible to implement any custom system of symbol to operation mapping in different "third-party" operators overloading libraries, which can be also good at first time - to let people do some experiments in this area. Also for me it looks like a good thing to have possibility to control whether some system of operators will be applied to some code or not. In case of ``with``-based approach it is controlled "very" explicitly - unless you specify some ``with(someOperatorsInterceptor)`` no operators overloading will be applied to your code. An if you want override some operators in some sub-block of code, you can always span that sub-block with some other ``with(anotherOperatorsInterceptor)`` statement and ``anotherOperatorsInterceptor`` interceptor will take precedence over previous/outer one in target sub-block of code. Of course it would be more nice to use something like ``import`` instead of ``with``, like for example in Scala, ``import`` may serve like more convenient form of ``with``: **Scala( ``{ import obj._; /*some code*/ }`` ) <==> Js( ``with (obj) { /*some code*/ }`` )** [[1]](https://en.wikibooks.org/wiki/Scala/Import) [[2]](http://www.scala-lang.org/old/node/119.html) But since ``import`` is reserved for modules I am not sure whether it can be adapted to serve for this purposes too. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160603/d0f85eb9/attachment-0001.html>
Speaking about well-known symbols for operators, I would rather propose more complex but less ambiguous solution. I think better approach is to provide some advanced mapping object, that implements following mapping:
(operatorName, ...argumentsTypes) <==> operatorSymbol <==> OperatorDescriptor(operatorName, ...argumentsTypes)
In code it may look like
var symbol_any_plus_any = operators.symbols["_+_"]();
var symbol_point_plus_point = operators.symbols["_+_"](Point, Point);
assert(symbol_point_plus_point == operators.symbols["+"](Point, Point));
var symbol_any_plus_point = operators.symbols["_+_"]("_", Point);
var symbol_point_plus_any = operators.symbols["_+_"](Point);
assert(symbol_point_plus_any == operators.symbols["+"](Point, "_"));
var symbol_this_plus_point = operators.symbols["this+_"](Point);
var symbol_this_plus_any = operators.symbols["this+_"]("_");
assert(symbol_this_plus_any == operators.symbols["this+_"]();
// etc
var descriptor_any_plus_any = operators.descriptors[symbol_any_plus_any];
assert(descriptor_any_plus_any.shortName == "+" && descriptor_any_plus_any.fullName == "_+_");
// etc
If this (operatorSignature <==> operatorSymbol <==> operatorDescriptor)
mapping would be implemented using WeakMap then it should also allow types (and appropriate operators signature/descriptor records) to be garbage collected when they are no longer needed (if that situation ever happen).
Then definition of overloaded operator implementation may look like:
var someObj = {
/* ... some code ... */
[operators.symbols["this+_"](Point)] : function(point) {
/* ... implementation of (this+Point) should be here ... */
}
};
const PointUtil = {
/* ... some code ... */
[operators.symbols["+"](Point, Point)] : function(point0, point1) {
return new Point(point0.x + point1.x, point0.y + point1.y);
}
};
And of course if we not limit our self in language syntax changes, for me
it would be more pleasant if operator
keyword usage was more like
function
keyword usage, but with "," symbol replaced with
underlying operation symbol.
So in code it should be something like:
const PointUtil = {
/* ... some code ... */
operator ((p0:Point) + (p1:Point)) {
return new Point(p0.x + p1.x, p0.y + p1.y);
}
};
const TypelessPointUtil = {
/* ... some code ... */
operator (p0 + p1) {
if ((p0 instanceof Point) && (p1 instanceof Point)) {
return new Point(p0.x + p1.x, p0.y + p1.y);
} else {
// undefined can be used as a marker to delegate operation handling to outer scope in handlers chain
// assuming that on the "out-most" level there are always available default JS operators implementations
return undefined;
};
}
};
var someObj = {
/* ... some code ... */
operator ((this) + (point:Point)) {
/* ... implementation of (this+Point) should be here ... */
},
operator ((num:Number) + (this)) {
/* ... implementation of (Number+this) should be here ... */
// for Number,Boolean,String,Function some exceptional type matching
// should be applied - using typeof instead of instanceof operator
}
};
This approach should cover more transparently left-binary and right-binary
operation (on instance level) and also easily separate ++_
and _++
operations, like: operator(this + x){}
, operator(x + this){}
,
operator(++this){}
, operator(this++){}
, etc. (By the way, as I
remember in C++ language operators ++_
and _++
are distinguished in
definition in some very strange way - by adding extra "dummy" boolean
parameter in signature of one of them).
Speaking about well-known symbols for operators, I would rather propose more complex but less ambiguous solution. I think better approach is to provide some advanced mapping object, that implements following mapping: (operatorName, ...argumentsTypes) <==> operatorSymbol <==> OperatorDescriptor(operatorName, ...argumentsTypes) In code it may look like ```js var symbol_any_plus_any = operators.symbols["_+_"](); var symbol_point_plus_point = operators.symbols["_+_"](Point, Point); assert(symbol_point_plus_point == operators.symbols["+"](Point, Point)); var symbol_any_plus_point = operators.symbols["_+_"]("_", Point); var symbol_point_plus_any = operators.symbols["_+_"](Point); assert(symbol_point_plus_any == operators.symbols["+"](Point, "_")); var symbol_this_plus_point = operators.symbols["this+_"](Point); var symbol_this_plus_any = operators.symbols["this+_"]("_"); assert(symbol_this_plus_any == operators.symbols["this+_"](); // etc var descriptor_any_plus_any = operators.descriptors[symbol_any_plus_any]; assert(descriptor_any_plus_any.shortName == "+" && descriptor_any_plus_any.fullName == "_+_"); // etc ``` If this (operatorSignature <==> operatorSymbol <==> operatorDescriptor) mapping would be implemented using [WeakMap]( https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/WeakMap) then it should also allow types (and appropriate operators signature/descriptor records) to be garbage collected when they are no longer needed (if that situation ever happen). Then definition of overloaded operator implementation may look like: ```js var someObj = { /* ... some code ... */ [operators.symbols["this+_"](Point)] : function(point) { /* ... implementation of (this+Point) should be here ... */ } }; const PointUtil = { /* ... some code ... */ [operators.symbols["+"](Point, Point)] : function(point0, point1) { return new Point(point0.x + point1.x, point0.y + point1.y); } }; ``` And of course if we not limit our self in language syntax changes, for me it would be more pleasant if ``operator`` keyword usage was more like ``function`` keyword usage, but with **","** symbol replaced with underlying operation symbol. So in code it should be something like: ```js const PointUtil = { /* ... some code ... */ operator ((p0:Point) + (p1:Point)) { return new Point(p0.x + p1.x, p0.y + p1.y); } }; const TypelessPointUtil = { /* ... some code ... */ operator (p0 + p1) { if ((p0 instanceof Point) && (p1 instanceof Point)) { return new Point(p0.x + p1.x, p0.y + p1.y); } else { // undefined can be used as a marker to delegate operation handling to outer scope in handlers chain // assuming that on the "out-most" level there are always available default JS operators implementations return undefined; }; } }; var someObj = { /* ... some code ... */ operator ((this) + (point:Point)) { /* ... implementation of (this+Point) should be here ... */ }, operator ((num:Number) + (this)) { /* ... implementation of (Number+this) should be here ... */ // for Number,Boolean,String,Function some exceptional type matching // should be applied - using typeof instead of instanceof operator } }; ``` This approach should cover more transparently left-binary and right-binary operation (on instance level) and also easily separate ``++_`` and ``_++`` operations, like: ``operator(this + x){}`` , ``operator(x + this){}`` , ``operator(++this){}`` , ``operator(this++){}`` , etc. (By the way, as I remember in C++ language operators ``++_`` and ``_++`` are distinguished in definition in some very strange way - by adding extra "dummy" boolean parameter in signature of one of them). -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160603/fe8793ea/attachment.html>
I see some discussion is happening - that's good.
As I don't want to see the tremendous amount of work people put into value types and operator overloading go to waste - let's bring Brendan and Christian into this discussion and start with a link to Brendan's 2013 slides:
www.slideshare.net/BrendanEich/value-objects
Let's consider value semantics for this.
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 kevinbarabash/operator-overloading. The
babel plugin can be found at kevinbarabash/babel-plugin-operator-overloading. I also have a demo project at kevinbarabash/operator-overloading-demo.
The design was inspired by some of the slides from www.slideshare.net/BrendanEich/js-resp.
I see some discussion is happening - that's good. As I don't want to see the tremendous amount of work people put into value types and operator overloading go to waste - let's bring Brendan and Christian into this discussion and start with a link to Brendan's 2013 slides: http://www.slideshare.net/BrendanEich/value-objects Let's consider value semantics for this. > 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 kevinbarabash/operator-overloading. The babel plugin can be found at kevinbarabash/babel-plugin-operator-overloading. I also have a demo project at kevinbarabash/operator-overloading-demo. The design was inspired by some of the slides from www.slideshare.net/BrendanEich/js-resp. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160605/246b8c39/attachment.html>
I'm not sure I'll be able to contribute much -- I've not kept up with JS since around the time of the original discussion in 2009 and the language has evolved a lot since then. But I have given the proposal some thought since so I'll put those reflections out there in case they're relevant to the discussion.
The original idea sprang from a discussion about adding a decimal type to JS. I didn't think a decimal type belonged in the core of the language and the suggestion was meant as a lesser evil. A way to support decimal -- and longer term other types -- as libraries such that there would be less pressure to put new types in the core language. (It wasn't a hidden agenda either, in context; I talk about decimal in the original email[1]) Then decimal went away which reduced that pressure. Without decimal as a greater evil I'm not sure I would have thought operator overloading was a good idea even back then.
Today I don't think the proposal is very good. For one thing it's in the flavor of 2009-era JS, and even back then it felt a little backward- looking. It also conflates two things which should probably be orthogonal: operator overloading and multiple dispatch. Operator overloading is conceptually a simple mechanism, lots of languages similar to JS has it. Multiple dispatch can be really powerful (in practice if not in theory) but also potentially incredibly complex. There are hard unsolved problems around it, particularly modularity.
If I was to put together a proposal today I would put the operator overloading aspect aside first and focus on multiple dispatch. If there is a solution, great -- but then I'd suggest providing that as a full language feature in itself instead of conflating it with a convenient operator syntax. Multiple dispatch is useful and if it can be supported cleanly there is no reason to restrict it to methods with a particular syntax -- that just creates a perverse incentive to express things in terms of operators to get the multiple dispatch behavior when the incentive should be purely that the syntax is appropriate. Or maybe no acceptable multiple dispatch mechanism can be designed, or maybe adding one isn't desirable even if there is a design. Either way the design space for operator overloading has shrunk considerably, in bother cases ideally to a thin syntactic layer on top of normal methods.
c
On Sun, Jun 5, 2016, at 03:22 PM, Benjamin Gruenbaum wrote:
I see some discussion is happening - that's good.
As I don't want to see the tremendous amount of work people put into value types and operator overloading go to waste - let's bring Brendan and Christian into this discussion and start with a link to Brendan's 2013 slides:
www.slideshare.net/BrendanEich/value-objects
Let's consider value semantics for this.
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 kevinbarabash/operator-overloading. The babel plugin can be found at kevinbarabash/babel-plugin-operator- overloading. I also have a demo project at kevinbarabash/operator-overloading- demo.
The design was inspired by some of the slides from www.slideshare.net/BrendanEich/js- resp.
es-discuss mailing list es-discuss at mozilla.org, mail.mozilla.org/listinfo/es-discuss
Links:
I'm not sure I'll be able to contribute much -- I've not kept up with JS since around the time of the original discussion in 2009 and the language has evolved a lot since then. But I have given the proposal some thought since so I'll put those reflections out there in case they're relevant to the discussion. The original idea sprang from a discussion about adding a decimal type to JS. I didn't think a decimal type belonged in the core of the language and the suggestion was meant as a lesser evil. A way to support decimal -- and longer term other types -- as libraries such that there would be less pressure to put new types in the core language. (It wasn't a hidden agenda either, in context; I talk about decimal in the original email[1]) Then decimal went away which reduced that pressure. Without decimal as a greater evil I'm not sure I would have thought operator overloading was a good idea even back then. Today I don't think the proposal is very good. For one thing it's in the flavor of 2009-era JS, and even back then it felt a little backward- looking. It also conflates two things which should probably be orthogonal: operator overloading and multiple dispatch. Operator overloading is conceptually a simple mechanism, lots of languages similar to JS has it. Multiple dispatch can be really powerful (in practice if not in theory) but also potentially incredibly complex. There are hard unsolved problems around it, particularly modularity. If I was to put together a proposal today I would put the operator overloading aspect aside first and focus on multiple dispatch. If there is a solution, great -- but then I'd suggest providing that as a full language feature in itself instead of conflating it with a convenient operator syntax. Multiple dispatch is useful and if it can be supported cleanly there is no reason to restrict it to methods with a particular syntax -- that just creates a perverse incentive to express things in terms of operators to get the multiple dispatch behavior when the incentive should be purely that the syntax is appropriate. Or maybe no acceptable multiple dispatch mechanism can be designed, or maybe adding one isn't desirable even if there is a design. Either way the design space for operator overloading has shrunk considerably, in bother cases ideally to a thin syntactic layer on top of normal methods. c On Sun, Jun 5, 2016, at 03:22 PM, Benjamin Gruenbaum wrote: > I see some discussion is happening - that's good. > > As I don't want to see the tremendous amount of work people put into > value types and operator overloading go to waste - let's bring Brendan > and Christian into this discussion and start with a link to Brendan's > 2013 slides: > > http://www.slideshare.net/BrendanEich/value-objects > > Let's consider value semantics for this. > > > 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 kevinbarabash/operator-overloading. The > > babel plugin can be found at kevinbarabash/babel-plugin-operator- > > overloading. I also have a demo project at kevinbarabash/operator-overloading- > > demo. > > The design was inspired by some of the slides from www.slideshare.net/BrendanEich/js- > resp. > > _________________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss Links: 1. https://esdiscuss.org/topic/operator-overloading-revisited -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160619/9d86a340/attachment.html>
A big +1 for moving this forwards.
I don't have any proposal to push and I don't want to add noise to the debate. Just say I would love to see this in JS, especially overloading of arithmetic operators. This is a must in domains where these operators are just "natural": decimals, complex numbers, vectors, etc.
I don't mind if the implementation or an operator is somewhat ugly/heavy. Operators will be implemented once by some clever dude but then they will be ubiquitous in the code. What matters here is the ease of use for consumers.
Bruno
A big +1 for moving this forwards. I don't have any proposal to push and I don't want to add noise to the debate. Just say I would love to see this in JS, especially overloading of arithmetic operators. This is a must in domains where these operators are just "natural": decimals, complex numbers, vectors, etc. I don't mind if the implementation or an operator is somewhat ugly/heavy. Operators will be implemented once by some clever dude but then they will be ubiquitous in the code. What matters here is the ease of use for consumers. Bruno -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160628/a85e3476/attachment.html>
What about extending proxies to have operator traps?
What about extending proxies to have operator traps? On Sun, Jun 5, 2016 at 8:22 AM, Benjamin Gruenbaum <benjamingr at gmail.com> wrote: > I see some discussion is happening - that's good. > > As I don't want to see the tremendous amount of work people put into value > types and operator overloading go to waste - let's bring Brendan and > Christian into this discussion and start with a link to Brendan's 2013 > slides: > > http://www.slideshare.net/BrendanEich/value-objects > > Let's consider value semantics for this. > > > 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 kevinbarabash/operator-overloading. The > babel plugin can be found at > kevinbarabash/babel-plugin-operator-overloading. I also have a demo project > at kevinbarabash/operator-overloading-demo. > > The design was inspired by some of the slides from > www.slideshare.net/BrendanEich/js-resp. > > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160629/7396557f/attachment.html>
Hello all!
While I am aware that previous proposals for operator overloading exist, I thought I'd attempt to write one which I consider to be simpler and more extensible - utilising Symbols.
keithamus/ecmascript-operator-overloading-proposal
It'd be great to get some feedback to this, and discuss the opportunity of getting a champion to work with me on this!
Hello all! While I am aware that previous proposals for operator overloading exist, I thought I'd attempt to write one which I consider to be simpler and more extensible - utilising Symbols. https://github.com/keithamus/ecmascript-operator-overloading-proposal It'd be great to get some feedback to this, and discuss the opportunity of getting a champion to work with me on this! -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170713/67df896c/attachment.html>
Your README.md reads:
Where an operator is used with two operands of the same type, […]
How would a binary operator work with operands of different type (by which I assume we mean its constructor)?
Your README.md reads: > Where an operator is used with two operands of the *same type*, […] How would a binary operator work with operands of *different* type (by which I assume we mean its constructor)? On Friday, July 14, 2017 12:22:25 AM CEST Keith Cirkel wrote: > Hello all! > > While I am aware that previous proposals for operator overloading exist, I > thought I'd attempt to write one which I consider to be simpler and more > extensible - utilising Symbols. > > https://github.com/keithamus/ecmascript-operator-overloading-proposal > > It'd be great to get some feedback to this, and discuss the opportunity of > getting a champion to work with me on this! -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: This is a digitally signed message part. URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170714/96824f78/attachment.sig>
Some problems I noticed at first glance:
Prefix/Postfix Unary Increment:
++
But postfix and prefix increments are supposed to return different values. How does this work if they are the same symbol?
Loose inequality Comparison:
!=
You didn't include it for consistency. Shouldn't !
also be excluded, then?
Future: Extending of operators
I don't think this can work if you don't define a way to determine the operands.
Some problems I noticed at first glance: > Prefix/Postfix Unary Increment: `++` But postfix and prefix increments are supposed to return different values. How does this work if they are the same symbol? > Loose inequality Comparison: `!=` You didn't include it for consistency. Shouldn't `!` also be excluded, then? > Future: Extending of operators I don't think this can work if you don't define a way to determine the operands. --Oriol -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170713/64c1f92d/attachment.html>
-1
javascript operator-overloading is a solution in search of a problem. there is virtually no real-world use-case where this feature would would not cause surprises and code-bloat (from bloated and unmaintainable polymorphic classes dealing with all the edge cases).
just imagine all the “fun” you would have debugging everyone else’s projects with operators your not completely confident will behave as expected.
-1 javascript operator-overloading is a solution in search of a problem. there is virtually no real-world use-case where this feature would would not cause surprises and code-bloat (from bloated and unmaintainable polymorphic classes dealing with all the edge cases). just imagine all the “fun” you would have debugging everyone else’s projects with operators your not completely confident will behave as expected. > On Jul 14, 2017, at 7:59 AM, Oriol _ <oriol-bugzilla at hotmail.com> wrote: > > Some problems I noticed at first glance: > > > Prefix/Postfix Unary Increment: `++` > > But postfix and prefix increments are supposed to return different values. How does this work if they are the same symbol? > > > Loose inequality Comparison: `!=` > > You didn't include it for consistency. Shouldn't `!` also be excluded, then? > > > Future: Extending of operators > > I don't think this can work if you don't define a way to determine the operands. > > --Oriol > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> > https://mail.mozilla.org/listinfo/es-discuss <https://mail.mozilla.org/listinfo/es-discuss> -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170714/a0f9ad70/attachment-0001.html>
javascript operator-overloading is a solution in search of a problem.
Why is JS different than languages that treat operators as methods, and make heavy use of overloading (Scala, Haskell, ...)? There seem to be lots of good use cases, same as in other languages.
> javascript operator-overloading is a solution in search of a problem. Why is JS different than languages that treat operators as methods, and make heavy use of overloading (Scala, Haskell, ...)? There seem to be lots of good use cases, same as in other languages. > On Jul 13, 2017, at 5:07 PM, es-discuss-request at mozilla.org wrote: > > Send es-discuss mailing list submissions to > es-discuss at mozilla.org > > To subscribe or unsubscribe via the World Wide Web, visit > https://mail.mozilla.org/listinfo/es-discuss > or, via email, send a message with subject or body 'help' to > es-discuss-request at mozilla.org > > You can reach the person managing the list at > es-discuss-owner at mozilla.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of es-discuss digest..." > Today's Topics: > > 1. Operator overloading proposal (Keith Cirkel) > 2. Re: Operator overloading proposal (kdex) > 3. Re: Operator overloading proposal (Oriol _) > 4. Re: Operator overloading proposal (kai zhu) > <mime-attachment> > <mime-attachment> > <mime-attachment> > <mime-attachment> > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss
javascript operator-overloading is a solution in search of a problem.
No. It is a solution to a problem I have today: arithmetic on decimal values.
> javascript operator-overloading is a solution in search of a problem. No. It is a solution to a problem I have today: arithmetic on decimal values. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170714/29a85b57/attachment.html>
No. It is a solution to a problem I have today: arithmetic on decimal values.
would you enjoy debugging someone else’s production-code with overloaded decimal operators? or would you prefer them having the courtesy to use method-calls, thus saving the headache of having to inspect every arithmetic expression?
> No. It is a solution to a problem I have today: arithmetic on decimal values. would you enjoy debugging someone else’s production-code with overloaded decimal operators? or would you prefer them having the courtesy to use method-calls, thus saving the headache of having to inspect every arithmetic expression? > On Jul 14, 2017, at 4:30 PM, Bruno Jouhier <bjouhier at gmail.com> wrote: > > > javascript operator-overloading is a solution in search of a problem. > > No. It is a solution to a problem I have today: arithmetic on decimal values. > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss
Two primary concerns:
-
JS uses proxies for a few similar hooks (like
foo["prop"]
andfoo()
) now. Python uses__getattr__
and__call__
for those, but JS doesn't use magic methods for those. -
Performance is going to be much harder to ensure, especially if you can mutate the operator methods them after creation. Scala, Haskell, C++, and the like can get away with operator functions/methods without a perf cliff, since they assume the operator to never change. You don't have that luxury with JS symbols - they can change. This is no different than in Python, and it's part of why PyPy is much slower than JS. LuaJIT only handles them well because a) Lua is very simple to begin with, and b) it does highly sophisticated analysis not seen in any other runtime, engineered by one of the top JIT and assembly experts in the field. (See Luafun for an example of its abilities, including its source code.)
Two primary concerns: 1. JS uses proxies for a few similar hooks (like `foo["prop"]` and `foo()`) now. Python uses `__getattr__` and `__call__` for those, but JS doesn't use magic methods for those. 2. Performance is going to be much harder to ensure, especially if you can mutate the operator methods them after creation. Scala, Haskell, C++, and the like can get away with operator functions/methods without a perf cliff, since they assume the operator to never change. You don't have that luxury with JS symbols - they *can* change. This is no different than in Python, and it's part of why PyPy is much slower than JS. LuaJIT only handles them well because a) Lua is very simple to begin with, and b) it does highly sophisticated analysis not seen in any other runtime, engineered by one of the top JIT and assembly experts in the field. (See Luafun for an example of its abilities, including its source code.) On Thu, Jul 13, 2017, 23:56 Boris Cherny <boris at performancejs.com> wrote: > > javascript operator-overloading is a solution in search of a problem. > > Why is JS different than languages that treat operators as methods, and > make heavy use of overloading (Scala, Haskell, ...)? There seem to be lots > of good use cases, same as in other languages. > > > On Jul 13, 2017, at 5:07 PM, es-discuss-request at mozilla.org wrote: > > > > Send es-discuss mailing list submissions to > > es-discuss at mozilla.org > > > > To subscribe or unsubscribe via the World Wide Web, visit > > https://mail.mozilla.org/listinfo/es-discuss > > or, via email, send a message with subject or body 'help' to > > es-discuss-request at mozilla.org > > > > You can reach the person managing the list at > > es-discuss-owner at mozilla.org > > > > When replying, please edit your Subject line so it is more specific > > than "Re: Contents of es-discuss digest..." > > Today's Topics: > > > > 1. Operator overloading proposal (Keith Cirkel) > > 2. Re: Operator overloading proposal (kdex) > > 3. Re: Operator overloading proposal (Oriol _) > > 4. Re: Operator overloading proposal (kai zhu) > > <mime-attachment> > > <mime-attachment> > > <mime-attachment> > > <mime-attachment> > > _______________________________________________ > > es-discuss mailing list > > es-discuss at mozilla.org > > https://mail.mozilla.org/listinfo/es-discuss > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170714/7c8a5c62/attachment.html>
It would actually be of substantial benefit to readability if you could overload operators for numeric, vector, and matrix-like types. In particular, I'd strongly prefer if SIMD types, if added, did use overloaded operators similarly to the BigInt proposal - it's honestly ridiculous why people use SIMD intrinsics for things that equate to vector addition (in the math sense).
In particular, here's a couple examples of what I mean from a math standpoint:
Vector (3D point) addition:
<a, b, c> + <x, y, z> = <a+x, b+y, c+z>
Matrix multiplication (2D):
[a, b] [x, y] [c, d] × [z, w] =
[ax+bz, ax+bw] [cx+dz, cx+dw]
Complex number division:
(a + bi) ÷ (c + di) =
(ac+bd) + i(bc - ad)
c²+d²
Set symmetric difference (i.e. exclusive or):
{1, 2, 3} ⊕ {1, 2, 4} = {3, 4}
I'd strongly prefer an operator variant over any method version, because it matches the math notation much better. You shouldn't actually need to learn some naming idiom just to add two things.
It would actually be of substantial benefit to readability if you *could* overload operators for numeric, vector, and matrix-like types. In particular, I'd strongly prefer if SIMD types, if added, *did* use overloaded operators similarly to the BigInt proposal - it's honestly ridiculous why people use SIMD intrinsics for things that equate to vector addition (in the math sense). In particular, here's a couple examples of what I mean from a math standpoint: Vector (3D point) addition: <a, b, c> + <x, y, z> = <a+x, b+y, c+z> Matrix multiplication (2D): [a, b] [x, y] [c, d] × [z, w] = [ax+bz, ax+bw] [cx+dz, cx+dw] Complex number division: (a + bi) ÷ (c + di) = (ac+bd) + i(bc - ad) -------------------------------- c²+d² Set symmetric difference (i.e. exclusive or): {1, 2, 3} ⊕ {1, 2, 4} = {3, 4} I'd strongly prefer an operator variant over any method version, because it matches the math notation much better. You shouldn't actually need to learn some naming idiom just to add two things. On Fri, Jul 14, 2017, 04:49 kai zhu <kaizhu256 at gmail.com> wrote: > > No. It is a solution to a problem I have today: arithmetic on decimal > values. > > would you enjoy debugging someone else’s production-code with overloaded > decimal operators? or would you prefer them having the courtesy to use > method-calls, thus saving the headache of having to inspect every > arithmetic expression? > > > On Jul 14, 2017, at 4:30 PM, Bruno Jouhier <bjouhier at gmail.com> wrote: > > > > > javascript operator-overloading is a solution in search of a problem. > > > > No. It is a solution to a problem I have today: arithmetic on decimal > values. > > _______________________________________________ > > es-discuss mailing list > > es-discuss at mozilla.org > > https://mail.mozilla.org/listinfo/es-discuss > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170714/e1086f5d/attachment.html>
overloaded simd-operators is again a solution in search of a problem. complex-arithmetic and matrix-operators has no significant application in the web-industry.
also, my experience with numeric javascript apps has been that generic matrix operations never quite do what i want, and the scope of handling NaN / Infinity / transpose edge-cases can be overwhelming. its more robust, efficient, and maintainable to handle these edge-cases with custom for-loop code than a mashup of matrix operations.
overloaded simd-operators is again a solution in search of a problem. complex-arithmetic and matrix-operators has no significant application in the web-industry. also, my experience with numeric javascript apps has been that generic matrix operations never quite do what i want, and the scope of handling NaN / Infinity / transpose edge-cases can be overwhelming. its more robust, efficient, and maintainable to handle these edge-cases with custom for-loop code than a mashup of matrix operations. > On Jul 14, 2017, at 6:02 PM, Isiah Meadows <isiahmeadows at gmail.com> wrote: > > It would actually be of substantial benefit to readability if you *could* overload operators for numeric, vector, and matrix-like types. In particular, I'd strongly prefer if SIMD types, if added, *did* use overloaded operators similarly to the BigInt proposal - it's honestly ridiculous why people use SIMD intrinsics for things that equate to vector addition (in the math sense). > > In particular, here's a couple examples of what I mean from a math standpoint: > > Vector (3D point) addition: > > <a, b, c> + <x, y, z> = <a+x, b+y, c+z> > > Matrix multiplication (2D): > > [a, b] [x, y] > [c, d] × [z, w] = > > [ax+bz, ax+bw] > [cx+dz, cx+dw] > > Complex number division: > > (a + bi) ÷ (c + di) = > > (ac+bd) + i(bc - ad) > -------------------------------- > c²+d² > > Set symmetric difference (i.e. exclusive or): > > {1, 2, 3} ⊕ {1, 2, 4} = {3, 4} > > I'd strongly prefer an operator variant over any method version, because it matches the math notation much better. You shouldn't actually need to learn some naming idiom just to add two things. > > On Fri, Jul 14, 2017, 04:49 kai zhu <kaizhu256 at gmail.com <mailto:kaizhu256 at gmail.com>> wrote: > > No. It is a solution to a problem I have today: arithmetic on decimal values. > > would you enjoy debugging someone else’s production-code with overloaded decimal operators? or would you prefer them having the courtesy to use method-calls, thus saving the headache of having to inspect every arithmetic expression? > > > On Jul 14, 2017, at 4:30 PM, Bruno Jouhier <bjouhier at gmail.com <mailto:bjouhier at gmail.com>> wrote: > > > > > javascript operator-overloading is a solution in search of a problem. > > > > No. It is a solution to a problem I have today: arithmetic on decimal values. > > _______________________________________________ > > es-discuss mailing list > > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> > > https://mail.mozilla.org/listinfo/es-discuss <https://mail.mozilla.org/listinfo/es-discuss> > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> > https://mail.mozilla.org/listinfo/es-discuss <https://mail.mozilla.org/listinfo/es-discuss> -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170714/dff12da5/attachment-0001.html>
No. It is a solution to a problem I have today: arithmetic on decimal values.
would you enjoy debugging someone else’s production-code with overloaded decimal operators? or would you prefer them having the courtesy to use method-calls, thus saving the headache of having to inspect every arithmetic expression?
Well, my context is business apps (accounting). Lots of developers writing lots of rules doing arithmetics on decimal quantities (JS number is not an option). Operators will keep the code concise, readable and familiar.
Code will be TypeScript so there will be typing hints everywhere (tooltips too) and debug-ability should not be an issue.
> > No. It is a solution to a problem I have today: arithmetic on decimal values. > would you enjoy debugging someone else’s production-code with overloaded decimal operators? or would you prefer them having the courtesy to use method-calls, thus saving the headache of having to inspect every arithmetic expression? Well, my context is business apps (accounting). Lots of developers writing lots of rules doing arithmetics on decimal quantities (JS number is not an option). Operators will keep the code concise, readable and familiar. Code will be TypeScript so there will be typing hints everywhere (tooltips too) and debug-ability should not be an issue. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170714/0bda714d/attachment.html>
To be honest, I recommend to abandon all ideas of operator overloading for arbitrary types - that's extremely unlikely to happen. It's heavily affects optimization possibilities, requires extensive type checks. Moreover, there is no interest from browser vendors to implement it.
However, I expect that in far future we will be able to overload operators if we get structs (having native complex numbers and matrices would be great).
To be honest, I recommend to abandon all ideas of operator overloading for arbitrary types - that's extremely unlikely to happen. It's heavily affects optimization possibilities, requires extensive type checks. Moreover, there is no interest from browser vendors to implement it. However, I expect that in far future we will be able to overload operators if we get structs (having native complex numbers and matrices would be great). On 14 Jul 2017 3:04 pm, "Bruno Jouhier" <bjouhier at gmail.com> wrote: > > > No. It is a solution to a problem I have today: arithmetic on decimal > values. > > would you enjoy debugging someone else’s production-code with overloaded > decimal operators? or would you prefer them having the courtesy to use > method-calls, thus saving the headache of having to inspect every > arithmetic expression? > > Well, my context is business apps (accounting). Lots of developers writing > lots of rules doing arithmetics on decimal quantities (JS number is not an > option). Operators will keep the code concise, readable and familiar. > > Code will be TypeScript so there will be typing hints everywhere (tooltips > too) and debug-ability should not be an issue. > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170714/6e76128d/attachment.html>
You mean this? www.slideshare.net/BrendanEich/int64 (slide 12 and following) This would be cool.
You mean this? https://www.slideshare.net/BrendanEich/int64 (slide 12 and following) This would be cool. 2017-07-14 18:03 GMT+02:00 Michał Wadas <michalwadas at gmail.com>: > To be honest, I recommend to abandon all ideas of operator overloading for > arbitrary types - that's extremely unlikely to happen. It's heavily affects > optimization possibilities, requires extensive type checks. Moreover, there > is no interest from browser vendors to implement it. > > However, I expect that in far future we will be able to overload operators > if we get structs (having native complex numbers and matrices would be > great). > > > On 14 Jul 2017 3:04 pm, "Bruno Jouhier" <bjouhier at gmail.com> wrote: > >> > > No. It is a solution to a problem I have today: arithmetic on decimal >> values. >> > would you enjoy debugging someone else’s production-code with >> overloaded decimal operators? or would you prefer them having the courtesy >> to use method-calls, thus saving the headache of having to inspect every >> arithmetic expression? >> >> Well, my context is business apps (accounting). Lots of developers >> writing lots of rules doing arithmetics on decimal quantities (JS number is >> not an option). Operators will keep the code concise, readable and familiar. >> >> Code will be TypeScript so there will be typing hints everywhere >> (tooltips too) and debug-ability should not be an issue. >> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170714/f2bd7395/attachment.html>
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:
More details can be found at kevinbarabash/operator-overloading. The babel plugin can be found at kevinbarabash/babel-plugin-operator-overloading. I also have a demo project at kevinbarabash/operator-overloading-demo.
The design was inspired by some of the slides from www.slideshare.net/BrendanEich/js-resp.
–