-
Notifications
You must be signed in to change notification settings - Fork 22
Operator overloading class syntax using TS-like method overloading and "extension" classes #29
Comments
I like the idea of making more ergonomic syntax for classes with operator overloading. Do you have an idea of the algorithm you'd use for determining which overload to select? Do you like the one described in this proposal, or do you prefer another one? |
What about decorators? Could a built-in decorator be used, similar to what AssemblyScript does? class Vector {
@operator("*")
static mul(left: Vector, right: Vector): Vector { ... }
@operator("*")
mul(right: Vector): Vector { ... }
} As a side-effect, you can also use the method directly:
|
I too dislike that we need to make two parallel |
I proposed decorators in a previous draft that you can see in the git log, but removed them due to both negative feedback about the syntax and uncertainty about how decorators will go exactly. |
I would propose to extend mixins with operators for that usecase. https://github.com/justinfagnani/proposal-mixins Example using parts of your code: mixin Matrix4x4Mixin {
constructor(...m) {
super(16);
this.set(m);
}
operator+(m) {
return new this.constructor(...this.map((value, index) => value + m[index]));
}
clone() {
return new this.constructor(...this);
}
static Identity() {
return new this(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
}
}
class Matrix4x4 extends Array with Matrix4x4Mixin {
}
class Matrix4x4Int8 extends Int8Array with Matrix4x4Mixin {
} |
Instead of using Instead of class Point {
operator+(rhs) {}
operator==(rhs) {}
operator!=(rhs) {}
} We could use class Point {
[Symbol.operator["+"]](rhs) {}
[Symbol.operator["=="]](rhs) {}
[Symbol.operator["!="]](rhs) {}
} |
I like this one the most out of all suggestions I have read. The only problem with this approach is that unary Perhaps we can over-specify things a bit, like this? class Point {
[Symbol.operator.unary['+']]() {}
[Symbol.operator.unary['++']]() {}
[Symbol.operator.binary['+']](rightOperand) {}
[Symbol.operator.binary['??']](rightOperand) {}
[Symbol.operator.assignment['+=']](value) {}
// or Symbol.operator.assignment['+'](value) {}
[Symbol.operator.comparison['==']](other) {}
/*** And probably (or probably not)... ***/
// Interchangeable with handler.deleteProperty()
[Symbol.operator.keywords['delete']](property) {}
// Interchangeable with handler.has()
[Symbol.operator.keywords['in']](property) {}
// Interchangeable with handler.construct()
[Symbol.operator.keywords['new']](property) {}
// await seeking for equity.
[Symbol.operator.keywords['await']](property) {}
} Some already has their own well-known Not to mention, class C {
[Symbol.toPrimitive](hint) {
switch (hint) {
case 'number':
return 42;
case 'string':
return 'Hello';
default:
// or case 'default':
return null;
}
}
};
console.log(+new C()); // 42
console.log(`${new C()} world!`); // 'Hello world!'
console.log(new C() + 'ish?'); // 'nullish?' |
This would keep all the current static behavior with the goal of using a more future-proof (for types) syntax choice.
Syntax for each operator:
This would use a fake method overloading syntax to specialize for each right hand side type.
Ad-hoc examples:
The second new feature would be the ability to define extension classes. Currently declaring a class with the same name causes a redeclaration SyntaxError. I'd propose that if the class only has, for now, operators that it's treated as an extension and would simply act like a partial class merging into any previously declared class as long as there are no signature conflicts in the operator overloads.
There is a caveat here with the extension syntax. It's elegant for user made classes and extending them in compartmentalized ways, but this syntax doesn't work for intrinsic objects. Things like Boolean, Number, BigInt, String, etc. You can't just write:
You'd need to use the function syntax, like the spec proposal has, to declare them. Maybe I'm thinking about this part wrong, but it makes my suggestion awkward as ideally you'd want a single elegant syntax throughout a codebase without having to use two separate systems. If there was a way to refer to the intrinsic objects and use an extension syntax that would be awesome, but it's not clear to me if that's possible. (In an elegant and consistent way within JS).
The text was updated successfully, but these errors were encountered: