Operator overloading for non-value objects

Domenic Denicola domenic at domenicdenicola.com
Mon Jan 13 12:09:24 PST 2014

(Warning: this reply somehow got rather rambly. Sigh.)

From: Brendan Eich <brendan at mozilla.com>

> I know, other languages allow this. The experience in those languages seems mixed to bad. Anyway, that's my view. What do others think?

Having used operator overloading in C#, I found it quite useful, even for mutable objects. Overloading `==` was by far the most common.

In domain-driven design terms, it comes down to the appropriate notion of equality for value objects (should be immutable) vs. entities (often mutable). Conceptually, value objects equal if all their composite parts are equal, whereas entity equality is determined by identity (e.g. same value for their ID properties). Allowing `==` to be useful for both value objects and entities was, in my experience, a crucial part of making equality comparison a useful part of the language.

The situation is somewhat different in C# than in JavaScript, though. For example, in C#, overloading `==` would always be accompanied by implementing the appropriate `IEquatable` stuff, in concordance with your `==` implementation. This would have ramifications for the various standard library data structures: for example, a set data structure would use the `IEquatable` implementation to determine uniqueness, or a dictionary would use it for key equality.

In JavaScript, our data structures are specified to use SameValue (or SameValueZero, or Strict Equality Comparison); none of them use a user-overridable hook. Furthermore, years of best-practice advice have made a lot of programmers prefer using `===` exclusively, ignoring `==` altogether. I for one would find it uncomfortable to start switching to `==` on the hope that it does something useful, in case the left-hand side is a value object with a proper overload implementation. (I would of course want to *avoid* it for the primitives, since its coercion behavior there is rarely desired.)

So ... I guess I am saying, I am not sure that making `==` work for mutable objects is salvagable. It can be made to work for immutable objects, maybe, assuming that their immutability is also used to modify SameValue et al. and thus allow a consistent behavior between `==` and e.g. `map.has`. (I suppose I am asking for invariants `x == y && Type(x) is Object && Type(y) is Object` implies `map.has(x) === map.has(y)`.) But unless we are prepared to allow the overloaded `==` to propagate throughout the language, which seems unlikely since the language rarely uses Abstract Equality Comparison, then I can't really see a place for `==` overloading on mutable objects.

More information about the es-discuss mailing list