8 ms·
IMO, any language with a type system should enforce comparisons only between those types (or derived types) unless a developer explicitly overrides an operator-
by nathanaldensr 5y ago
IMO, any language with a type system should enforce comparisons only between those types (or derived types) unless a developer explicitly overrides an operator--and even then, overriding operators is sometimes considered bad practice due to violating the principle of least astonishment. The types of a comparison operator's operands matter because the type system exists. Allowing things like "5" == 5 suddenly introduces human expectations of logical equality--"they're both '5', therefore they're equal." Programming languages shouldn't codify these human interpretations.
My favorite language, C#, has some unfortunate history. The == operator when dealing with references indicates reference equality (Object.ReferenceEquals), but can be overridden to indicate value equality (Object.Equals) even with reference types. Then, when dealing with value types, == suddenly means value equality. It would've been better to define two separate operators for reference and value equality. This would've helped make usages self-documenting.
- egeozcan 5y agoThat historical... erm... glitch... in C# is very unfortunate and burned us many times back when I was working in a .NET shop (people getting creative was usually the culprit). I've even seen some codebases where people decided to implement their own equality operators (lesson through experience: don't do this).
- coding123 5y agoThey picked that up from C++
- int_19h 5y agoThey picked it up from Java, which also used == to mean both reference equality and value equality. But C# also tried to improve on Java. One of the things that the latter was commonly criticized for, was the need to use .equals() for strings for value comparisons - which is almost always what you want - and avoiding the more obvious ==. So they overloaded == for strings to mean value equality, while retaining them as reference types. IMO, the bigger mistake here was to keep strings as reference types - they really ought to be value types (the implementation can still wrap a reference to the actual string data internally, and share it between copies, but the client shouldn't be able to observe that).
- MarkSweep 5y agoAt least more recent versions of Visual Studio highlight the == differently so you know it is overridden.
- zajio1am 5y ago> IMO, any language with a type system should enforce comparisons only between those types (or derived types) There are languages with a type system that have universal type (and all types are derived from it), in these languages it make sense that "5" == 5 is defined and false.
- int_19h 5y agoA universal type doesn't necessarily have to be arbitrarily comparable between instances. The strictly correct response to "5"==5 really is "not comparable"; it's just a question of how you choose to surface it. One popular choice is to define the equality operator as returning false if the operands aren't comparable - but then you have to do the reverse for inequality, which is far less obvious.
- int_19h 5y agoYou can already kinda sorta do that if you consistently use == assuming value equality, and use ReferenceEquals() - which doesn't need to be qualified, since everything inherits from Object - for reference equality. You still have == working on all references in this case, but this can be interpreted as reference types having the default value semantics of "every instance is logically different", so referenced values are only equal to themselves. The annoying part of this approach is that ReferenceEquals() is the one that ends up being used way more often than == in practice for reference types, but it's also much longer to type, and more awkward to use being a function. Python and VB, with their "is" operator for reference equality, handled this one best. Unfortunately, C# wasted "is" as a keyword for something far less common - a type check (and now also pattern matching).