operator overloading proposal

Kevin Barabash kevinb at khanacademy.org
Wed May 11 05:27:37 UTC 2016


> 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>


More information about the es-discuss mailing list