The proposal for operator overload was withdrawn:
I wanted to share yet again a proposal for adding an operator overload but for Proxy. It will be only one change and allow full operator overload and implementation of something like Matrix class, Pandas Data Frame or numpy from Python.
It can be just one hook/handler in Proxy. No new syntax is required.
Here is an example of how I would implement the Matrix class . Note that the core is of the proposal is an instance of a Proxy. This may not work if the feature were implemented, since I was unable to run it and see if it actually works and fix any bugs.
class Matrix {
constructor(rows, cols) {
if (Array.isArray(rows)) {
this._data = rows;
} else {
this._data = this.init(rows, cols, 0);
}
return this._wrap(this);
}
add(arg) {
if (arg instanceof Matrix) {
// Multiply the matrix when possible
// write the result into result variable
return this._wrap(result);
}
}
identity() {
return this.map((_, i, j) => i === j ? 1 : 0);
}
_wrap(arg) {
const matrix = arg instanceof Matrix ? new Matrix(arg) : arg;
return new Proxy(matrix, {
operation(target, operation, operand) {
if (operand instanceof Matrix) {
switch(operation) {
case '+':
return target.add(operand);
case '-':
case '*':
case '/':
case '**':
case '%':
throw new Error('Not Yet Implemented');
}
}
throw new Error('Invalid operand');
}
});
}
map(callback) {
return this._wrap(this._data.map((row, i) => row.map((cell, j) => callback(cell, i, j))));
}
fill(value) {
return this._wrap(this._data.map(() => row.fill(value)));
}
_init(row, col, callback) {
return Array.from({ length: row }, (_, i) => Array.from({ length: col }, (_, j) => callback(i, j)))
}
}
const a = new Matrix(3, 3);
const b = a.fill(1);
const c = a.identity();
const result = a * b;
console.log(result);
// Proxy of Matrix([[2, 1, 1], [1, 2, 1], [1, 1, 2]])
This will work since the class can return an object that can be the result of new operator. So you can wrap the object with a Proxy.
This will only require adding operation handler in Proxy object.
This can work left to right. Like a function call.
x + y
Will check if x is a Proxy then check if it has operation handler. Or there can be default one that work like it work right now. So there will be no need for check if handler exists.
Additionally if it will be required to allow something like 10 * MyString there can be 2 different handlers.
There are 3 cases actually:
- Proxy + non proxy
- Proxy + Proxy
- non_proxy + Proxy
Each can be a different handler in Proxy or just one, that prefer left operand or right if left is non-proxy. This will allow to create any combination of operations in a custom object like Pandas Data Frame.
The checking for Proxy exisistance can happen before coercion. That will not be used when one of the object is a Proxy. The default coercion can happen in Proxy.prototype default handler for operation.