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 <isiahmead...@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 <kev...@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 <isiahmead...@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 <k...@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 <gga...@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-disc...@gmail.com >>>> > > > <mailto:balancetraveller%2bes-disc...@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 >>>> > > > <kev...@khanacademy.org <mailto:kev...@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-disc...@gmail.com >>>> > > > <mailto:balancetraveller+es-disc...@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 >>>> > > > <kev...@khanacademy.org <mailto: >>>> kev...@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-disc...@gmail.com >>>> > > > <mailto:balancetraveller+es-disc...@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 >>>> > > > <kev...@khanacademy.org >>>> > > > <mailto:kev...@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 >>>> > > > <kev...@khanacademy.org >>>> > > > <mailto:kev...@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@mozilla.org >>>> > > > <mailto:es-discuss@mozilla.org> >>>> > > > >>>> https://mail.mozilla.org/listinfo/es-discuss >>>> > > > >>>> > > > >>>> > > > >>>> > > > >>>> _______________________________________________ >>>> > > > es-discuss mailing list >>>> > > > es-discuss@mozilla.org <mailto: >>>> > > es-discuss@mozilla.org> >>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>> > > > >>>> > > > >>>> > > > >>>> > > > _______________________________________________ >>>> > > > es-discuss mailing list >>>> > > > es-discuss@mozilla.org <mailto: >>>> es-discuss@mozilla.org> >>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>> > > > >>>> > > > >>>> > > > >>>> > > > _______________________________________________ >>>> > > > es-discuss mailing list >>>> > > > es-discuss@mozilla.org <mailto:es-discuss@mozilla.org >>>> > >>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>> > > > >>>> > > > >>>> > > > >>>> > > > _______________________________________________ >>>> > > > es-discuss mailing list >>>> > > > es-discuss@mozilla.org <mailto:es-discuss@mozilla.org> >>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>> > > > >>>> > > > >>>> > > > _______________________________________________ >>>> > > > es-discuss mailing list >>>> > > > es-discuss@mozilla.org <mailto:es-discuss@mozilla.org> >>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>> > > > >>>> > > > >>>> > > > >>>> > > > _______________________________________________ >>>> > > > es-discuss mailing list >>>> > > > es-discuss@mozilla.org >>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>> > > > >>>> > > _______________________________________________ >>>> > > es-discuss mailing list >>>> > > es-discuss@mozilla.org >>>> > > https://mail.mozilla.org/listinfo/es-discuss >>>> > > >>>> > >>>> >>> >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss@mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >>> >> _______________________________________________ >> es-discuss mailing list >> es-discuss@mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> > > _______________________________________________ > es-discuss mailing list > es-discuss@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > >
_______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss