On Tue, Feb 4, 2020 at 1:08 PM Steven D'Aprano firstname.lastname@example.org wrote:
On Tue, Feb 04, 2020 at 12:33:44PM +1100, Chris Angelico wrote:
But if `PyObject_RichCompareBool(..., Py_EQ)` is such a fundamental operation (and in a sense it seems to me that it is), is there a point in explicitly defining it?
That would mean adding `operator.equivalent(a, b) -> bool` which would allow float to override the result and let `operator.equivalent_value(float("NaN"), float("NaN))` return True; luckily very few types would actually override the operation.
The implication here is that there would be a corresponding dunder method, yes? If it's possible for a type to override it, that would need a dunder.
I think the whole point of this is that it *cannot* be overridden.
Yes, I agree.
Can we summarise this issue like this?
[quote] Containers or other compound objects are permitted to use identity testing to shortcut what would otherwise be an equality test (e.g. in list equality tests, and containment tests), even if that would change the behaviour of unusual values, such as floating point NANs which compare unequal to themselves, or objects where `__eq__` have side effects.
Such containers are permitted to assume that their contents all obey the reflexivity of equality (each value is equal to itself) and so avoid calling `__eq__` or `__ne__`.
This is an implementation-specific detail which may differ across different container types and interpreters. [end quote]
I'd actually rather see it codified as a specific form of comparison and made a guarantee, upon which other guarantees and invariants can be based. It's not an optimization (although it can have the effect of improving performance), it's a codification of the expectations of containers. As such, this comparison would be defined by language rules as the way that built-in containers behave, and would also be the recommended and normal obvious way to build other container types.
Can the word "equivalent" be used for this, perhaps?
We don't need and shouldn't have a dunder for this, but the word "equivalent" would be wrong in any case. Two objects may be equivalent but not equal, for example, when it comes to iteration, the string "abc" is equivalent to the list ['a', 'b', 'c'].
Hmm, true, although that's equivalent only in one specific situation. In mathematics, "congruent" means that two things are functionally equivalent (eg triangles with the same length sides; in programming terms we'd probably say that two such triangles would be "equal" but not identical), even if there's a specific context for such equivalence, such as stating that 12,345 is congruent to 11 modulo 7, because the remainders 12345%7 and 11%7 are both 4. So maybe "congruent" could be used for this concept?