Igor Baklan (2016-06-03T16:00:53.000Z)
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).