On Mar 27, 2012, at 12:03 PM, Brendan Eich wrote:

> What Tab said about having "right" versions for the binary operators. 
> Otherwise you can't properly handle number + decimal or number + complex, e.g.

yes you can:

Number.prototype.@operatorMinus = function(rval) {return 
rval.@subFromNumber(this)};
Complex.prototype.@operatorMinus = function(rval) {return 
rval.@subFromComplex(this)};
Decimal.@operatorMinus = function(rval) {return rval.@subFromDecimal(this)};

Complex.prototype.@subFromNumber = Complex.prototype.@subFromDecimal = 
function(minuend) {return new Complex(nimuend,0)-this};
Complex.prototype.@subFromComplex = function(minuend) {return new 
Complex(minuend.real-this.real,minuend-imag-this.imag)};
Decimal.prototype.@subFromNumber = function(minuend) {return 
Decimal.forNumber(nimuend)-this};
Decimal.prototype.@subFromDecimal = function(minuend) {return 
primitiveDecimalSub(nimuend,this)};
Decimal.prototype.@subFromComplex = function(minuend) {return minuend-new 
Complex(this,0};
Number.prototype.@subFromComplex  = function(minuend) {return minuend-new 
Complex(this,0};
Number.prototype.@subFromDecimal = function(minuend) {return 
minuend-Decimal.forNumber(this)};

I probably should have provided the above definition of 
Number.prototype.@operatorMinus as part of the srtrawman proposal as that is 
really the definition you always want to use.  The job of all @operatorX 
methods is simply to pass the type of the lval and the specific operator to the 
rval.  These are both encoded in the method name. To add a new type you just 
have to define a single method for each operator cross each type that the rval 
can be combined with.  See [2] for a more detailed discussion on building a 
complex numeric hierarchy using double dispatch.

If we assume this standard definition for Number.prototype.@operatorMinus then 

lines 5-7 of my overloadable subtract operator algorithm, which the wiki shows 
as:

5.   If Type(lval) is Number and Type(rval) is Number, then
I  Return the result of applying the subtraction operation to lval and rval. 
See the note below 11.6.3.
6.   Let dispatchable be the result of calling the [[Get]] internal methods of 
lval with the private name @operatorMinus as argument.
7.   If IsCallable(dispatchable) is true, then
I  Return the result of calling the [[Call]] internal method of dispatchable 
with providing lval as the this value and rval as the argument.

could be expand like:

5.   If Type(lval) is Number, then and Type(rval) is Number, then
II  If Type(rval) is Number, then
a Return the result of applying the subtraction operation to lval and rval. See 
the note below 11.6.3.
Else, 
a Let dispatchable be the result of calling the [[Get]] internal methods of 
rval with the private name @subFromNumber as argument.
b If IsCallable(dispatchable) is true, then
1.  Return the result of calling the [[Call]] internal method of dispatchable 
with providing rval as the this value and lval as the argument.
6.   Let dispatchable be the result of calling the [[Get]] internal methods of 
lval with the private name @operatorMinus as argument.
7.   If IsCallable(dispatchable) is true, then
I  Return the result of calling the [[Call]] internal method of dispatchable 
with providing lval as the this value and rval as the argument.

This is essentially an inlining of the standard definition of 
Number.prototype.@operatorMinus given above.  It is conceptually similar to 
right operator methods in the value proxy paper, expect that it is essential to 
double dispatch that the type of one of the operands is encoded in the second 
(or in my above restatement inlined) method call.  The value proxy strawman 
apparently depends upon a separate mechanism that apparently does some sort of 
table lookup in the proxy hander to  do type base dispatch. I suspect that, it 
reduces to a double type based look, that ultimately is logically equivalent to 
the the selection done using double dispatch.  It isn't clear (to me) how it 
actually works but it certainly appears more opaque and possible less (or 
harder) extensible.

One of the challenges with double dispatch, is that it is so brain dead simple 
and efficient (if you have a high perf method dispatch) that sometimes people 
have a hard time believing that it actually works.

> 
> The right and left methods proposed in 
> http://wiki.ecmascript.org/doku.php?id=strawman:value_proxies seems worth a 
> look, as well as the OOPSLA paper linked at the bottom.

[3] is really nice survey of known techniques for do multi-dispatch within a 
single dispatch language (and isn't everything ultimately built on single 
dispatch)

> 
> /be
> 
> Allen Wirfs-Brock wrote:
>> As a followup, I've written a strawman[1] that explains how we could specify 
>> and implement operator overloading that supports an open-ended set of value 
>> types.  I look at this as an adjunct to Dave's proposal that suggests that 
>> the coercion/promotion rules  should be pushed out of the actual operator 
>> semantics and placed into an extensible set of methods.
>> 
>> [1] 
>> http://wiki.ecmascript.org/doku.php?id=strawman:operator_overloading_with_double_dispatch
>>  
  
      [2]  
https://wiki.engr.illinois.edu/download/attachments/186744921/double-dispatch.pdf
 
      [3]  www.laputan.org/reflection/Foote-Johnson-Noble-ECOOP-2005.pd

>> 
>> Allen
>> _______________________________________________
>> es-discuss mailing list
>> [email protected]
>> https://mail.mozilla.org/listinfo/es-discuss
> 

_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to