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