> Objects containing the same values should be equal by default.
I strongly disagree with this. I’d take it one step further and say that there should be no equality operator or default equals function for non-primitive data types. Some specific type of records/tuples could use a default equality, but it should be opt-in or follow from using metadata like an attribute (e.g Rust derive) or only for those specific types (e.g C# ValueTuple) . Not even strings should have a default equality (ie it shouldn’t be possible to create a map/dictionary with string keys without explicitly also saying how keys are compared. That’s right: It shouldn’t even be an optional argument so the default string equality/hash is used unless specified. It should be explicitly passed. This isn’t “boilerplate” it’s avoiding subtle bugs.
As for the rest of the arguments, some are downright crazy. You cannot program without mutation in the general case. You simply don’t always have the performance/power budget for it. Obviously mutation should be avoided, but dogmatically using all-immutable data is just not possible.
No automatic casts would be high on my list too. I don’t ever want to accidentally treat things like “falsy” or convert between types based on usage. I’d rather litter my programs with type names and explicit conversions.
I strongly disagree with this. I’d take it one step further and say that there should be no equality operator or default equals function for non-primitive data types. Some specific type of records/tuples could use a default equality, but it should be opt-in or follow from using metadata like an attribute (e.g Rust derive) or only for those specific types (e.g C# ValueTuple) . Not even strings should have a default equality (ie it shouldn’t be possible to create a map/dictionary with string keys without explicitly also saying how keys are compared. That’s right: It shouldn’t even be an optional argument so the default string equality/hash is used unless specified. It should be explicitly passed. This isn’t “boilerplate” it’s avoiding subtle bugs.
As for the rest of the arguments, some are downright crazy. You cannot program without mutation in the general case. You simply don’t always have the performance/power budget for it. Obviously mutation should be avoided, but dogmatically using all-immutable data is just not possible.
No automatic casts would be high on my list too. I don’t ever want to accidentally treat things like “falsy” or convert between types based on usage. I’d rather litter my programs with type names and explicit conversions.