Igor Baklan (2016-06-03T16:00:53.000Z)
Speaking about well-known symbols for operators, I would rather propose
more complex but less ambiguous solution. I think better approach is to
provide some advanced mapping object, that implements following mapping:

(operatorName, ...argumentsTypes) <==> operatorSymbol <==>
OperatorDescriptor(operatorName, ...argumentsTypes)

In code it may look like

```js
var symbol_any_plus_any = operators.symbols["_+_"]();
var symbol_point_plus_point = operators.symbols["_+_"](Point, Point);
assert(symbol_point_plus_point == operators.symbols["+"](Point, Point));
var symbol_any_plus_point = operators.symbols["_+_"]("_", Point);
var symbol_point_plus_any = operators.symbols["_+_"](Point);
assert(symbol_point_plus_any == operators.symbols["+"](Point, "_"));
var symbol_this_plus_point = operators.symbols["this+_"](Point);
var symbol_this_plus_any = operators.symbols["this+_"]("_");
assert(symbol_this_plus_any == operators.symbols["this+_"]();
// etc

var descriptor_any_plus_any = operators.descriptors[symbol_any_plus_any];
assert(descriptor_any_plus_any.shortName == "+" &&
descriptor_any_plus_any.fullName == "_+_");
// etc
```

If this (operatorSignature <==> operatorSymbol <==> operatorDescriptor)
mapping would be implemented using [WeakMap](
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/WeakMap)
then it should also allow types (and appropriate operators
signature/descriptor records) to be garbage collected when they are no
longer needed (if that situation ever happen).

Then definition of overloaded operator implementation may look like:

```js

var someObj = {
  /* ... some code ... */
  [operators.symbols["this+_"](Point)] : function(point) {
    /* ... implementation of (this+Point) should be here ... */
  }
};

const PointUtil = {
  /* ... some code ... */
  [operators.symbols["+"](Point, Point)] : function(point0, point1) {
    return new Point(point0.x + point1.x, point0.y + point1.y);
  }
};

```

And of course if we not limit our self in language syntax changes, for me
it would be more pleasant if ``operator`` keyword usage was more like
``function`` keyword usage, but with **","** symbol replaced with
underlying operation symbol.
So in code it should be something like:

```js

const PointUtil = {
  /* ... some code ... */
  operator ((p0:Point) + (p1:Point)) {
    return new Point(p0.x + p1.x, p0.y + p1.y);
  }
};

const TypelessPointUtil = {
  /* ... some code ... */
  operator (p0 + p1) {
    if ((p0 instanceof Point) && (p1 instanceof Point)) {
      return new Point(p0.x + p1.x, p0.y + p1.y);
    } else {
      // undefined can be used as a marker to delegate operation handling
to outer scope in handlers chain
      // assuming that on the "out-most" level there are always available
default JS operators implementations
      return undefined;
    };
  }
};

var someObj = {
  /* ... some code ... */
  operator ((this) + (point:Point)) {
    /* ... implementation of (this+Point) should be here ... */
  },
  operator ((num:Number) + (this)) {
    /* ... implementation of (Number+this) should be here ... */
    // for Number,Boolean,String,Function some exceptional type matching
    // should be applied - using typeof instead of instanceof operator
  }
};

```

This approach should cover more transparently left-binary and right-binary
operation (on instance level) and also easily separate ``++_`` and ``_++``
operations, like: ``operator(this + x){}`` , ``operator(x + this){}`` ,
``operator(++this){}`` , ``operator(this++){}`` , etc. (By the way, as I
remember in C++ language operators ``++_`` and ``_++`` are distinguished in
definition in some very strange way - by adding extra "dummy" boolean
parameter in signature of one of them).
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160603/fe8793ea/attachment.html>
io.baklan at gmail.com (2016-06-03T16:07:22.477Z)
Speaking about well-known symbols for operators, I would rather propose
more complex but less ambiguous solution. I think better approach is to
provide some advanced mapping object, that implements following mapping:

(operatorName, ...argumentsTypes) <==> operatorSymbol <==> OperatorDescriptor(operatorName, ...argumentsTypes)

In code it may look like

```js
var symbol_any_plus_any = operators.symbols["_+_"]();
var symbol_point_plus_point = operators.symbols["_+_"](Point, Point);
assert(symbol_point_plus_point == operators.symbols["+"](Point, Point));
var symbol_any_plus_point = operators.symbols["_+_"]("_", Point);
var symbol_point_plus_any = operators.symbols["_+_"](Point);
assert(symbol_point_plus_any == operators.symbols["+"](Point, "_"));
var symbol_this_plus_point = operators.symbols["this+_"](Point);
var symbol_this_plus_any = operators.symbols["this+_"]("_");
assert(symbol_this_plus_any == operators.symbols["this+_"]();
// etc

var descriptor_any_plus_any = operators.descriptors[symbol_any_plus_any];
assert(descriptor_any_plus_any.shortName == "+" && descriptor_any_plus_any.fullName == "_+_");
// etc
```

If this (operatorSignature <==> operatorSymbol <==> operatorDescriptor)

mapping would be implemented using [WeakMap](
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/WeakMap)
then it should also allow types (and appropriate operators
signature/descriptor records) to be garbage collected when they are no
longer needed (if that situation ever happen).

Then definition of overloaded operator implementation may look like:

```js

var someObj = {
  /* ... some code ... */
  [operators.symbols["this+_"](Point)] : function(point) {
    /* ... implementation of (this+Point) should be here ... */
  }
};

const PointUtil = {
  /* ... some code ... */
  [operators.symbols["+"](Point, Point)] : function(point0, point1) {
    return new Point(point0.x + point1.x, point0.y + point1.y);
  }
};

```

And of course if we not limit our self in language syntax changes, for me
it would be more pleasant if ``operator`` keyword usage was more like
``function`` keyword usage, but with **","** symbol replaced with
underlying operation symbol.
So in code it should be something like:

```js

const PointUtil = {
  /* ... some code ... */
  operator ((p0:Point) + (p1:Point)) {
    return new Point(p0.x + p1.x, p0.y + p1.y);
  }
};

const TypelessPointUtil = {
  /* ... some code ... */
  operator (p0 + p1) {
    if ((p0 instanceof Point) && (p1 instanceof Point)) {
      return new Point(p0.x + p1.x, p0.y + p1.y);
    } else {
      // undefined can be used as a marker to delegate operation handling to outer scope in handlers chain
      // assuming that on the "out-most" level there are always available default JS operators implementations
      return undefined;
    };
  }
};

var someObj = {
  /* ... some code ... */
  operator ((this) + (point:Point)) {
    /* ... implementation of (this+Point) should be here ... */
  },
  operator ((num:Number) + (this)) {
    /* ... implementation of (Number+this) should be here ... */
    // for Number,Boolean,String,Function some exceptional type matching
    // should be applied - using typeof instead of instanceof operator
  }
};

```

This approach should cover more transparently left-binary and right-binary
operation (on instance level) and also easily separate ``++_`` and ``_++``
operations, like: ``operator(this + x){}`` , ``operator(x + this){}`` ,
``operator(++this){}`` , ``operator(this++){}`` , etc. (By the way, as I
remember in C++ language operators ``++_`` and ``_++`` are distinguished in
definition in some very strange way - by adding extra "dummy" boolean
parameter in signature of one of them).