|
Size: 630
Comment:
|
Size: 2376
Comment:
|
| Deletions are marked like this. | Additions are marked like this. |
| Line 1: | Line 1: |
| Equality and Coercion could be harmful ====================================== |
{{{#!rst |
| Line 4: | Line 3: |
| The goal of this page is to gather all problems due to equality accepting coercion in borderline cases | Equality using Coercion considered harmful? =========================================== |
| Line 6: | Line 6: |
| {{{ sage: bool(pi == 3.14159265358979323) True sage: hash(pi) 2943215493 sage: hash(3.14159265358979323) 1826823505 sage: dd {3.1415926535897932: 'approx', pi: 'exact'} sage: {0:"exact", 0.0000000000000000000:"approx"} {0: 'approx'} }}} as a consequence {{{ sage: pii = 3.14159265358979323 sage: bool(pii == pi) True sage: dd = {pi: "exact"} sage: pi in dd True sage: pii in dd False sage: pii in dd.keys() True }}} |
Currently, Sage specifies that, upon comparing with ``a==b`` two objects `a` and `b` that do not have the same parent, a coercion is attempted to put them in the same parent. To prepare a discussion on whether that specification is viable in the long run, we are gathering here (borderline?) use cases where this behaviour is harmful. :: sage: bool(pi == 3.14159265358979323) True sage: hash(pi) 2943215493 sage: hash(3.14159265358979323) 1826823505 However Python 2.7 documentation specifies:: object.__hash__(self) Called by built-in function hash() and for operations on members of hashed collections including set, frozenset, and dict. __hash__() should return an integer. The only required property is that objects which compare equal have the same hash value; As a first consequence of the above behavior:: sage: {3.1415926535897932: 'approx', pi: 'exact'} {3.1415926535897932: 'approx', pi: 'exact'} sage: {0:"exact", 0.0000000000000000000:"approx"} {0: 'approx'} And also:: sage: pii = 3.14159265358979323 sage: bool(pii == pi) True sage: dd = {pi: "exact"} sage: pi in dd True sage: pii in dd False sage: pii in dd.keys() True More strange consequences when using UniqueRepresentation --------------------------------------------------------- :: sage: F1 = FiniteEnumeratedSet([0.000000]) sage: F2 = FiniteEnumeratedSet([0]) sage: F1 is F2 True sage: F2.list() [0.000000000000000] sage: An example showing that Sage's specifications clashes with Python's specifications ------------------------================------------------------------------------ :: sage: S = SymmetricFunctions(QQ) sage: x = S.s()[5] sage: y = S.p()(x) sage: x == y True sage: hash(x), hash(y) (-1840429907820881728, 5178019317311573726) It's surely syntactically nice to have x == y evaluate True after a coercion. However enforcing that the two hash functions be the same would be simply impossible: this would force to systematically coerce any symmetric function to some fixed base for computing the hash function, and we just can't afford that. |
