Operator overloading revisited

Christian Plesner Hansen christian.plesner.hansen at gmail.com
Wed Jul 1 01:33:29 PDT 2009


> Almost. It's actually a bit worse than that, since presumaby, Points want to
> be addable with Numbers:
>
> Point.prototype['+'] = function (that) {
>   if (that instanceof Point) {
>    return new Point(this.x + that.x, this.y + that.y);
>  } else if (that instanceof Number) {
>    // again ignoring the difference between numbers and Numbers
>    return new Point(this.x + that, this.y + that);
>  } else {
>    return that['reverse+'](this);
>  }
> };

I find the use of instanceof problematic for several reasons.

The connection between constructor functions and instances is fragile.
 Once you've created an instance you're free to change the constructor
without those changes being reflected in the instance.  What it means
to be a Point can change throughout the lifetime of a program.

Furthermore, instanceof is an implementation type query, not an
interface or behavior type query.  The limitations of implementation
types compared with interface types are well understood.

> Perhaps Complex(3, 5) === Complex(3, 5) is a better example?

I really don't see it.  What is the problem with two complex numbers
being distinct object instances and strict equals reflecting that
fact?  If you want structural equality use ==, that's what it's there
for.

> Ignoring Operable, in your proposal, how would you handle the need to
> preserve the legacy + behavior on legacy kinds of objects? The only other
> possibility I foresee is duck typing on the presence of the 'this+' and/or
> '+this' property names. That would work.

Duck typing is built into the proposal already.  It is folded into
step 2 and 4 as a special case of bailing out if looking up the
properties doesn't yield lists.  If an internal property were used
instead it would have to have a state that reflected "no operators are
present", maybe the absence of the internal property, which would
serve the same purpose.  Instead of giving an error in step 2 and 4
you would fall through to the legacy behavior if either side didn't
respond to operators.


More information about the es-discuss mailing list