We have a fundamental issue here:

On the one hand, we like Duck Typing, and it is baked into Python.

On the other hand, we have a "math" module, that started as a wrapper
around the C lib, and to this day is essentially a "float math" module.
Which indeed is very useful, but not compatible with duck typing.

This issue came up when we added math.isclose (
https://www.python.org/dev/peps/pep-0485/). I started out with a pure
Python implementation that would work with duck types (or, at least Decimal
and Fraction) . But when it came time for implementation, the math module
seemed to be the only logical place for it, and it's written in C, and all
(mostly?) about floats -- so we dumped the Duck Typing version.

At the time, it was proposed that we re-write the math module in Python,
calling out to C for most stuff, and then we could add to it making use of
Python features. That idea was rejected at the time, probably because it
seemed like way too much churn for the case at hand.

But maybe it's time for a "duck math" module -- one that would provide a
full set of math functions that would work on a wide range of numeric types.

isnan() would be a nice candidate to kick it off :-)

In any case, if this is too big a lift, then it would still be nice to have
an duck-typeable isnan() function -- but where to put it? MAybe the
statistics module is not such a bad place?

-CHB


On Fri, Dec 27, 2019 at 5:39 PM Guido van Rossum <gu...@python.org> wrote:

> Is duck typing float or Decimal worth the bother? Barring that it could be
> done with some isinstance() checks (in the user code, not in math.isnan()).
>
> Otherwise, your only resort is a PEP, like the final comment of that bug
> says.
>
> On Fri, Dec 27, 2019 at 18:16 David Mertz <me...@gnosis.cx> wrote:
>
>> Great work! I had not known if those corners.
>>
>> Have you tried with NumPy zero-D arrays or PyTorch Values? Both of those
>> should have sensible answers.
>>
>> On Fri, Dec 27, 2019, 7:42 PM Steven D'Aprano <st...@pearwood.info>
>> wrote:
>>
>>> By the way, it's not as easy as you might think to test whether a value
>>> is a NAN or not.
>>>
>>> There are currently three ways to test whether a value is a NAN. (Four
>>> if you include cmath.isnan.)
>>>
>>> 1. math.isnan(x) but it can fail in annoying ways.
>>>
>>>
>>>     # No int is a NAN so this should return False
>>>     py> math.isnan(10**1000)
>>>     Traceback (most recent call last):
>>>       File "<stdin>", line 1, in <module>
>>>     OverflowError: int too large to convert to float
>>>
>>>     # Decimal signalling NANs are NANs so this should return True
>>>     py> x = Decimal('snan')
>>>     py> math.isnan(x)
>>>     Traceback (most recent call last):
>>>       File "<stdin>", line 1, in <module>
>>>     ValueError: cannot convert signaling NaN to float
>>>
>>>
>>> 2. Decimal.is_nan() but it only works with decimals. However it does
>>> work with signalling NANs.
>>>
>>>
>>> 3. Back before math.isnan existed, the idiomatic way to check for NANs
>>> was to test whether they were equal to themselves. Assuming that x is a
>>> kind of numeric type, we should expect that `x == x` except for NANs.
>>> But this too fails for signalling NANs:
>>>
>>>
>>>     # Using the default Decimal context
>>>     py> x == x
>>>     Traceback (most recent call last):
>>>       File "<stdin>", line 1, in <module>
>>>     decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>]
>>>
>>>
>>> So there is no good way to check for an arbitrary NAN that duck-types
>>> floats, Decimals, ints, Fractions and other numeric types.
>>>
>>> I have come up with this:
>>>
>>>
>>>     def isnan(x, _isnan=math.isnan):
>>>         try:
>>>             return _isnan(x)
>>>         except ValueError:
>>>             # Could be a Decimal signalling NAN.
>>>             try:
>>>                 return x.is_nan()
>>>             except AttributeError:
>>>                 return x != x
>>>         except OverflowError:
>>>             return False
>>>         except TypeError:
>>>             from cmath import isnan
>>>             return isnan(x)
>>>
>>>
>>> but I fear that there could be other landmines waiting, other odd corner
>>> cases I haven't thought of.
>>>
>>> See also
>>>
>>> https://bugs.python.org/issue27975
>>>
>>>
>>>
>>> --
>>> Steven
>>> _______________________________________________
>>> 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/VHC4GO37ZT2UEW6RSRF4ASMTVK52UQ6H/
>>> Code of Conduct: http://python.org/psf/codeofconduct/
>>>
>> _______________________________________________
>> 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/AGBORBUDM2763CORRJBJPDCOJ3TSNNA5/
>> Code of Conduct: http://python.org/psf/codeofconduct/
>>
> --
> --Guido (mobile)
> _______________________________________________
> 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/OGU3QD6PEFZ3BTZYQDMC4SB6FVLRKP6B/
> Code of Conduct: http://python.org/psf/codeofconduct/
>


-- 
Christopher Barker, PhD

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython
_______________________________________________
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/IGZWMUZVB735FOGQ7O6ITVLSJMDR5IHS/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to