4 ms·
I lost the line of reasoning (or perhaps the author did) at the second example. If I have 2 InputStream objects, nevermind equality. It just doesn't apply here
by rzwitserloot 6y ago
I lost the line of reasoning (or perhaps the author did) at the second example.
If I have 2 InputStream objects, nevermind equality. It just doesn't apply here. I don't even want `a.Equals(b)` to be considered valid code in the first place. Having __any__ default behaviour here is a lot like the permissiveness that is bashed in example 1 (a trifecta of unexpected variable scoping rules, the ability to re-type variables merely by assigning an object of a different type to them, and the idea that a boolean will silently convert itself to a numeric value): There are a billion situations where you'd want to e.g. treat a boolean as a number, and in the vast majority of them, '0' is a fine value, but nevertheless, it leads to unpredictable code so let's not default. Let's require an explicit interaction from the code author to indicate they really want to do that, and, hopefully, we can make that 'explicit interaction' simple.
Apply the same logic to example 2 and the author draws the wrong conclusion.
- Smaug123 6y agoNote that F# has the `[<NoEquality>]` attribute for exactly that sort of case.
- masklinn 6y agoThat's the wrong default though. There is no reason to assume equality is a sensible concept, so objects should not even be equatable by default, and you could have an attribute which gives them structural equality (with a third option of a full-blown custom equality if necessary) as e.g. Haskell or Rust handle it.
- joshsyn 6y agoAlzabraic types and records have strutural equality while classes don't have it I believe.
- tome 6y agoI don't understand how you concluded that Example 2 implies that the author thinks that `a.Equals(b)` should work on InputStream objects.
- mrkeen 6y agoI'm not sure you're contradicting the author as much as taking his argument a step further. His second example is arguing for value-equality instead of reference-equality as a saner default. He created two "value-ish" Customer objects and used them to motivate his argument. So when he writes: >> Why not make the objects equal by default, and make reference equality testing the special case? this refers in particular to these value objects. I completely agree with you that InputStream should not have equals defined. A sane language would not conflate values with classes, and InputStream is not a value. So perhaps it could be better-written as: If defined, equality should test by value, rather than by reference.
- isaacabraham79 6y ago'0' is a string (or char), not a number. Just saying.
- elihu 6y agoA couple other counterexamples to > "Records with the same internal data ARE equal by default" Floats: floating point equality tests between two floats of the same value or testing equality with itself is generally "true" with the exception of NaN (i.e. "not a number") values. Testing if NaN == Nan is "false" according to the IEEE [1]. (Probably not all languages follow IEEE's recommendation.) Functions: some functions are trivially the same, and some functions are trivially different, but deciding whether arbitrary functions (for instance, f(x) { x + x } and f(x) { 2*x } return the same values and have the same side-effects for all possible inputs is generally not something a compiler should be expected to do. So any record with a function as a field can't really be tested for equality. [1] https://stackoverflow.com/questions/38798791/nan-comparison-rule-in-c-c https://stackoverflow.com/questions/38798791/nan-comparison-...