Operator overloading revisited

Brendan Eich brendan at mozilla.com
Tue Jun 30 11:06:27 PDT 2009


On Jun 30, 2009, at 10:35 AM, Allen Wirfs-Brock wrote:

> Pulling back from Mark's and Brendan's programming language  
> metaphysics discussion (which I think is interesting and useful) I  
> just wanted to say that I find Christian's proposal quite  
> interesting. It feels like a natural fit to the language as it  
> exists today and doesn't require any new abstraction concepts such  
> as classes, nominal type, value types, etc. although it could be  
> made compatible with any of them. It has a simple conceptual  
> explanation: an operator works with two object if they both  
> associate the same function with that operator.
>
> It may or may not be the ultimate solution, but I think it deserves  
> serious consideration.

We can entertain strawman UI but I hope to focus on substance not  
surface.

Costs that seem to leap out from Christian's mutual-asymmetric  
multimethod proposal:

1. Two lookups, "this+" and "+this", required.
2. Intersection.

(2) looks like a transformation or simplification of standard  
multimethod Class Precedence List usage to find the most specific  
method. Any system allowing multiple methods for a given operator will  
have something like it.

(1) seems avoidable, though -- *assuming* it is not a phantom cost. We  
have to deal with the symmetric vs. encapsulated issue, though. But  
notice that Christian's proposal does not use "this" in the method  
bodies!

   function pointPlusNumber(a, b) {
     return new Point(a.x + b, a.y + b);
   }
   function numberPlusPoint(a, b) {
     return new Point(a + b.x, a + b.y);
   }
   function addPoints(a, b) {
     return new Point(a.x + b.x, a.y + b.y);
   }

These are nice generic functions. With type annotations or guards, you  
could imagine them as adding to generic function "+":

   generic function "+"(a :Point, b :Point) {
     return new Point(a.x + b.x, a.y + b.y);
   }

Syntax is not the point, please hold fire and spare the bikeshed --  
the unencapsulated (no |this| or |self|) nature of these functions is  
what I'm stressing.

So why require "this+" and "+this" lookups?

If the reason is to assign responsibility to the different  
constructors [*], then how can you tell who is responsible?

Function.defineOperator in the proposal binds both "this+" and  
"+this". I agree these should not be plain old properties. But then  
why spec them as named internal properties of any kind?

Suppose we had a generic function "+" (syntax TBD) to which methods  
could be added for particular non-conflicting pairs of operand types.  
Then the lookup would be for two types A and B, but this can be  
optimized under the hood. See, e.g.,

http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.35.4799

Seems worth allowing this kind of optimization. Whether and how users  
add multimethods we can debate at greater length. But can we agree  
that the "this+" and "+this" properties are not necessary?

/be

[*] or constructor.prototypes in your reply, but I don't see why we  
would require noisy ".prototype" suffixing -- instanceof does not!


More information about the es-discuss mailing list