On Dec 29, 2019, at 04:34, Steven D'Aprano <st...@pearwood.info> wrote: > > On Sat, Dec 28, 2019 at 11:58:35PM -0800, Andrew Barnert via Python-ideas > wrote: > >> No it won’t, unless you assume here that no possible non-numeric types >> could ever have non-self-equal values. Which isn’t true. > > Reflexivity of equality (namely, that any value should be equal to > itself) is such a fundamental property that I would assume that NANs are > the only exception, until such time as somebody points out an > uncontrived real-world example.
It may be a fundamental property in math, and in many other programming languages, but not in Python (and many other programming languages). Numpy arrays: a==a is neither true nor false, but a bool array the same shape as a (which will raise if used in an if statement or otherwise converted to bool). sNaN: Adding special handling for Decimal won’t help any third-party libs that also do sNaN properly and raise instead of returning false from a==a. ORMs: a==a is neither true nor false, it’s a where clause that, when used to form a query, compared column a to itself, but it has no bool value. SymPy: a==a is neither true nor false, it’s the equation a==a. Other libraries that build other things out of expressions are similar to the ORM and SymPy cases. Not-a-Time values from various date time libraries: a==a is false, but the type is not a numeric type in the first place. Meanwhile, are there any non-contrived types for which the equals test does the right thing? Sure. Quiet NaN-like values from third-party number libraries. But does using == to get the right answer for qNaN from those types, even though it means we get the wrong answer for sNaN from those same types, not to mention all kinds of other types, actually make the function more generic, or more useful than one that just raised for types it wasn’t prepared to deal with? Certainly not in general. Maybe for some specific use it does, but without knowing what the intended use of a “generic isnan” function is (which I’ve asked for three times now—the statistics module doesn’t seem to need one given that it’s intentionally not generic), all you have is that it might be useful in some use that nobody’s come up with where you want to duck-type NaN-ness and don’t care that it often does the wrong thing but do care that it does the right thing for some particular case that wouldn’t otherwise be handled. > A bigger concern is the question of what should isnan do for non-numeric > types? > > isnan(None) > # raise or return False? > > Clearly None is not a NAN, so it shouldn't return True. Should it return > False because its not a NAN, or raise because it's not a numeric type at > all? I think it should raise an exception, just as I said a paragraph later for strings. Returning true implies that it’s a NaN, returning false implies that it’s not not a number, and both are wrong. Consider this: what should isfinite or isinfinite or ispositive do for None or a string? If they should raise, why should isnan be different? A better question is, what should a numpy array do? Numpy’s own isnan returns a bool array of the same shape, just like comparisons do. But is that what we want? Or do we want to treat scalars (0D arrays) special? Or do we want to ask numpy to try to convert to a scalar (in which case it’ll treat all 1-element arrays of any dimension special)? Or …? Similarly, should an expression library be able to capture the isnan test and turn it into part of the query or equation or whatever it is that it’s building, or should it raise? The advantage of using an isnan method or an __isnan__ protocol, and then raising for anything else (maybe with special exceptions for the builtin number types), instead of trying to come up with something that sort of works for all types, is that numpy and expression libraries and so on get to make that decision, instead of the statistics module or the math module or wherever this is intended to go. _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/RPS3AF3Q7XCC2HSIFFM3UI6PEMCCI6N7/ Code of Conduct: http://python.org/psf/codeofconduct/