tc39 / proposal-operator-overloading

MIT License
618 stars 20 forks source link

Consider some Object.defineOperator and Symbols #21

Open lifaon74 opened 4 years ago

lifaon74 commented 4 years ago

For people preferring functions over classes, or simply to overload easily the behavior of an existing object, we may consider too some kind of:

Object.defineOperator(obj, '+', () => (a, b) { return a._big.plus(b._big); });

Another point is to re-consider the usage of Symbols: obj[Symbol.plus] = () => (a, b) { return a._big.plus(b._big); }

The ES classes doesn't support multi-inheritance, only mixins. So if we have a class already extending another one (like the Custom HTMLElement for example). It's not clear how operators could be overloaded.

littledan commented 4 years ago

This proposal only permits operator overloading defined in a more static way; this means no subclassing/mixins and no definitions after things are initially set up. The suggestions made above are more dynamic and go against the goals explained in the README. Do you think these goals should be revisited?

lifaon74 commented 4 years ago

Yes, I read the readme and the FAQ part and I disagree on the "static" side of this proposal, even if I'm one of the first who wants operator overloading.

I really feel concerned about multi-inheritance/mixin limits because some projects are built around this paradigm and this proposal doesn't allow to add operator overloading on child classes nor extending already existing built-in (ex: Map, Set, etc...) or external (package) classes/object. For example, if I use an external Vector library, I wont be able to add myself operator overloading.

Moreover, if I need to add operator overloading on legacy code (ex: using function instead of class) => may append if in my company need to work on old code, or simply if I want to transpile from typescript to es5 (even if operators won't be supported by browser only supporting es5).

Another point are libraries working around mixin or even custom element.

I just point the limit of: "we want a safe environment for the developer even if it means sacrifices". Developers ARE NOT STUPID, they will know the power of such a functionality and use it with caution.

I prefer a language that does more than less, and provide more freedom (what js always did).

littledan commented 4 years ago

For external libraries, I'd suggest wrapping them in a new type that supports operator overloading. This proposal does not require ES6 class (though some suggestions in issues would). If you're transpiling, I already have an early draft Babel transform.

This proposal tries to strike a balance. I think if we ask for too much dynamism, it will be rejected by those who don't share this philosophy (and I count myself among this group). I'm not going to champion a proposal which abandons these predictability goals, but others are welcome to.

lifaon74 commented 4 years ago

Hum, maybe you could provide an example how to extends an already existing class and object ?

The following code is extremely ugly and force a monkey-patch:

function addOverloads(obj) {
  class SuperClass { constructor() { return obj; } }
  class SubClass extends SubclassOperators(SuperClass, {"+"(a, b) { /* ... */ }}) {}
  new SubClass(obj);
  return obj;
}

Javascript is based around dynamism: Reflect, Object.defineProperty, the possibility to update the prototype, etc... And since then, nobody died => JS is the most used language... so dynamism won't stop anybody...