Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #86958 > unrolled thread
| Started by | random832@fastmail.us |
|---|---|
| First post | 2015-03-05 17:26 -0500 |
| Last post | 2015-03-06 18:37 -0800 |
| Articles | 20 on this page of 29 — 9 participants |
Back to article view | Back to comp.lang.python
Is nan in (nan,) correct? random832@fastmail.us - 2015-03-05 17:26 -0500
Re: Is nan in (nan,) correct? sohcahtoa82@gmail.com - 2015-03-05 15:11 -0800
Re: Is nan in (nan,) correct? Ben Finney <ben+python@benfinney.id.au> - 2015-03-06 10:20 +1100
Re: Is nan in (nan,) correct? sohcahtoa82@gmail.com - 2015-03-05 15:27 -0800
Re: Is nan in (nan,) correct? Ben Finney <ben+python@benfinney.id.au> - 2015-03-06 10:39 +1100
Re: Is nan in (nan,) correct? Chris Angelico <rosuav@gmail.com> - 2015-03-06 10:40 +1100
Re: Is nan in (nan,) correct? Chris Angelico <rosuav@gmail.com> - 2015-03-06 10:25 +1100
Re: Is nan in (nan,) correct? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-03-06 13:09 +1100
Re: Is nan in (nan,) correct? Ben Finney <ben+python@benfinney.id.au> - 2015-03-06 13:55 +1100
Re: Is nan in (nan,) correct? Ethan Furman <ethan@stoneleaf.us> - 2015-03-05 19:18 -0800
Re: Is nan in (nan,) correct? Ben Finney <ben+python@benfinney.id.au> - 2015-03-06 14:26 +1100
Re: Is nan in (nan,) correct? Ethan Furman <ethan@stoneleaf.us> - 2015-03-05 19:44 -0800
Re: Is nan in (nan,) correct? Chris Angelico <rosuav@gmail.com> - 2015-03-06 14:49 +1100
Re: Is nan in (nan,) correct? random832@fastmail.us - 2015-03-05 23:37 -0500
Re: Is nan in (nan,) correct? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-03-07 04:07 +1100
Re: Is nan in (nan,) correct? Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-03-06 04:46 +0000
Re: Is nan in (nan,) correct? Rustom Mody <rustompmody@gmail.com> - 2015-03-06 01:50 -0800
Re: Is nan in (nan,) correct? Chris Angelico <rosuav@gmail.com> - 2015-03-06 21:01 +1100
Re: Is nan in (nan,) correct? Rustom Mody <rustompmody@gmail.com> - 2015-03-06 02:22 -0800
Re: Is nan in (nan,) correct? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-03-07 03:59 +1100
Re: Is nan in (nan,) correct? Rustom Mody <rustompmody@gmail.com> - 2015-03-06 10:04 -0800
Re: Is nan in (nan,) correct? Ethan Furman <ethan@stoneleaf.us> - 2015-03-06 10:16 -0800
Re: Is nan in (nan,) correct? Grant Edwards <invalid@invalid.invalid> - 2015-03-06 15:34 +0000
Re: Is nan in (nan,) correct? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-03-07 03:43 +1100
Re: Is nan in (nan,) correct? Rustom Mody <rustompmody@gmail.com> - 2015-03-06 09:04 -0800
Re: Is nan in (nan,) correct? Chris Angelico <rosuav@gmail.com> - 2015-03-07 04:16 +1100
Re: Is nan in (nan,) correct? Rustom Mody <rustompmody@gmail.com> - 2015-03-06 09:36 -0800
Re: Is nan in (nan,) correct? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-03-07 10:33 +1100
Re: Is nan in (nan,) correct? Rustom Mody <rustompmody@gmail.com> - 2015-03-06 18:37 -0800
Page 1 of 2 [1] 2 Next page →
| From | random832@fastmail.us |
|---|---|
| Date | 2015-03-05 17:26 -0500 |
| Subject | Is nan in (nan,) correct? |
| Message-ID | <mailman.67.1425594415.21433.python-list@python.org> |
It's been brought up on Stack Overflow that the "in" operator (on tuples, and by my testing on dict and list, as well as dict lookup) uses object identity as a shortcut, and returns true immediately if the object being tested *is* an element of the container. However, the contains operation does not specify whether object identity or equality is to be used. In effect, the built-in container types use a hybrid test: "a is b or a == b". My question is, is this a *correct* implementation of the operator, or are objects "supposed to" use a basis of equality for these tests?
[toc] | [next] | [standalone]
| From | sohcahtoa82@gmail.com |
|---|---|
| Date | 2015-03-05 15:11 -0800 |
| Message-ID | <eb903edb-6400-4a61-8d79-e8a8535443e7@googlegroups.com> |
| In reply to | #86958 |
On Thursday, March 5, 2015 at 2:27:12 PM UTC-8, rand...@fastmail.us wrote: > It's been brought up on Stack Overflow that the "in" operator (on > tuples, and by my testing on dict and list, as well as dict lookup) uses > object identity as a shortcut, and returns true immediately if the > object being tested *is* an element of the container. However, the > contains operation does not specify whether object identity or equality > is to be used. In effect, the built-in container types use a hybrid > test: "a is b or a == b". > > My question is, is this a *correct* implementation of the operator, or > are objects "supposed to" use a basis of equality for these tests? I would argue that if `a is b` then it is obvious that `a == b`, so if all you care about is whether or not `a == b`, then it shouldn't matter if `a is b` is checked first. It could greatly speed up comparisons for objects that are expensive to compare. I would also argue that the "in" operator *SHOULD* be using equality of value. Otherwise, if it only used equality of identity, testing if user input is valid by seeing if it is "in" a list of valid inputs wouldn't work. Testing identity in this case would *never* be true unless you were dealing with a select number of integers. >>> i = input() 5 >>> i is 5 True >>> i = intput() 999999 >>> i is 999999 False >>> i in [1, 2, 3, 999999] True
[toc] | [prev] | [next] | [standalone]
| From | Ben Finney <ben+python@benfinney.id.au> |
|---|---|
| Date | 2015-03-06 10:20 +1100 |
| Message-ID | <mailman.70.1425597600.21433.python-list@python.org> |
| In reply to | #86963 |
sohcahtoa82@gmail.com writes: > I would argue that if `a is b` then it is obvious that `a == b` It may be obvious, but it's not necessarily true. Some commonly-used values – for example, an “null” – are not equal to themselves, by definition. It is fine to define such a type in Python, because ‘is’ does not necessarily imply ‘==’. > I would also argue that the "in" operator *SHOULD* be using equality > of value. Hopefully you can see how that argument is incorrect. -- \ “Yesterday I told a chicken to cross the road. It said, ‘What | `\ for?’” —Steven Wright | _o__) | Ben Finney
[toc] | [prev] | [next] | [standalone]
| From | sohcahtoa82@gmail.com |
|---|---|
| Date | 2015-03-05 15:27 -0800 |
| Message-ID | <5cfab73a-ec0b-488b-8787-72e7640dc352@googlegroups.com> |
| In reply to | #86964 |
On Thursday, March 5, 2015 at 3:20:16 PM UTC-8, Ben Finney wrote: > sohcahtoa82@gmail.com writes: > > > I would argue that if `a is b` then it is obvious that `a == b` > > It may be obvious, but it's not necessarily true. Some commonly-used > values - for example, an "null" - are not equal to themselves, by > definition. > > It is fine to define such a type in Python, because 'is' does not > necessarily imply '=='. > > > I would also argue that the "in" operator *SHOULD* be using equality > > of value. > > Hopefully you can see how that argument is incorrect. > > -- > \ "Yesterday I told a chicken to cross the road. It said, 'What | > `\ for?'" --Steven Wright | > _o__) | > Ben Finney Do you have an example of where `a is b` but `a != b` in Python? `None == None` is True.
[toc] | [prev] | [next] | [standalone]
| From | Ben Finney <ben+python@benfinney.id.au> |
|---|---|
| Date | 2015-03-06 10:39 +1100 |
| Message-ID | <mailman.72.1425598789.21433.python-list@python.org> |
| In reply to | #86966 |
sohcahtoa82@gmail.com writes:
> On Thursday, March 5, 2015 at 3:20:16 PM UTC-8, Ben Finney wrote:
> > It is fine to define such a type in Python, because 'is' does not
> > necessarily imply '=='.
>
> Do you have an example of where `a is b` but `a != b` in Python?
Maybe I misunderstand your question, but you've already been discussing
such an example. Here it is for clarity::
>>> nan = float("NaN")
>>> (nan is nan) == (nan == nan)
False
>>> nan is nan
True
>>> nan == nan
False
> `None == None` is True.
Right, the Python `None` is not the null I was describing. Python does
allow for a null with the semantics I described, because ‘is’ does not
imply ‘==’.
--
\ “We suffer primarily not from our vices or our weaknesses, but |
`\ from our illusions.” —Daniel J. Boorstin, historian, 1914–2004 |
_o__) |
Ben Finney
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-03-06 10:40 +1100 |
| Message-ID | <mailman.73.1425598822.21433.python-list@python.org> |
| In reply to | #86966 |
On Fri, Mar 6, 2015 at 10:27 AM, <sohcahtoa82@gmail.com> wrote:
> Do you have an example of where `a is b` but `a != b` in Python? `None == None` is True.
Check out the subject line.
>>> nan = float("nan")
>>> nan is nan # obviously
True
>>> nan != nan # IEEE 754 mandates
True
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-03-06 10:25 +1100 |
| Message-ID | <mailman.71.1425597914.21433.python-list@python.org> |
| In reply to | #86963 |
On Fri, Mar 6, 2015 at 10:11 AM, <sohcahtoa82@gmail.com> wrote:
> I would argue that if `a is b` then it is obvious that `a == b`
This is not true for float("nan"), though. The question is, is your
above statement a valid optimization for the 'in' operator, or not?
And no, it isn't, because it's not perfectly safe. However, there are
other invariants that mean that 'in' has to allow object identity to
count; for instance:
for elem in collection:
assert elem in collection
should never assert-fail.
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2015-03-06 13:09 +1100 |
| Message-ID | <54f90c53$0$12994$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #86958 |
random832@fastmail.us wrote: > It's been brought up on Stack Overflow that the "in" operator (on > tuples, and by my testing on dict and list, as well as dict lookup) uses > object identity as a shortcut, and returns true immediately if the > object being tested *is* an element of the container. However, the > contains operation does not specify whether object identity or equality > is to be used. In effect, the built-in container types use a hybrid > test: "a is b or a == b". > > My question is, is this a *correct* implementation of the operator, or > are objects "supposed to" use a basis of equality for these tests? This has been discussed multiple times on the python-dev mailing list, and each time the conclusion is the same: Using `is` to optimize the `in` operator is perfectly acceptable for the vast bulk of values in Python. There are only a few, like floating point NANs, where `a is b` does not imply `a == b`, and it is acceptable for container-types like tuple and list to assume reflexivity (that x == x). Since reflexivity is *almost* universal, and using object identity permits very substantial optimizations, the core developers agreed that built-in contain types may assume that `x is y` implies `x == y`. Users of NANs and other non-reflexive types can subclass or define their own membership function. -- Steven
[toc] | [prev] | [next] | [standalone]
| From | Ben Finney <ben+python@benfinney.id.au> |
|---|---|
| Date | 2015-03-06 13:55 +1100 |
| Message-ID | <mailman.77.1425610573.21433.python-list@python.org> |
| In reply to | #86973 |
Steven D'Aprano <steve+comp.lang.python@pearwood.info> writes:
> Since reflexivity is *almost* universal, and using object identity
> permits very substantial optimizations, the core developers agreed
> that built-in contain types may assume that `x is y` implies `x == y`.
> Users of NANs and other non-reflexive types can subclass or define
> their own membership function.
On a type (such as a hypothetical SQL NULL type) which does not have
reflexivity – i.e. that ‘(x is x) == (x == x)’ may be False – which
method needs to be implemented so items *containing* values of that type
will have the expected semantics?
I can only think of ‘footype.__contains__’, but that's a method of the
*container* type, and the ‘in’ operator doesn't consult that method of
the items themselves.
So, given the hypothetical NullType::
class NullType(object):
""" A type whose value never equals any other.
This type's values will behave correctly when tested for
membership in a collection::
>>> foo = NullType()
>>> bar = NullType()
>>> foo is foo
True
>>> foo is bar
False
>>> foo == foo
False
>>> foo == bar
False
>>> quux = [foo, "spam"]
>>> "spam" in quux
True
>>> foo in quux
True
>>> bar in quux
False
"""
def __eq__(self, value):
return False
def __method_which_the_in_operator_interrogates__(self, collection):
""" Method which the ‘is’ operator interrogates for membership. """
return is_a_member_of(container, self)
What method of NullType replaces the hypothetical
‘__method_which_the_in_operator_interrogates__’, which I've implemented
to as you describe “define their own membership function”, in order to
get the correct behaviour in the doctest above?
--
\ “Why am I an atheist? I ask you: Why is anybody not an atheist? |
`\ Everyone starts out being an atheist.” —Andy Rooney, _Boston |
_o__) Globe_ 1982-05-30 |
Ben Finney
[toc] | [prev] | [next] | [standalone]
| From | Ethan Furman <ethan@stoneleaf.us> |
|---|---|
| Date | 2015-03-05 19:18 -0800 |
| Message-ID | <mailman.78.1425611901.21433.python-list@python.org> |
| In reply to | #86973 |
[Multipart message — attachments visible in raw view] — view raw
On 03/05/2015 06:55 PM, Ben Finney wrote: > class NullType(object): > """ A type whose value never equals any other. > > This type's values will behave correctly when tested for > membership in a collection:: > > >>> foo = NullType() > >>> bar = NullType() > >>> foo is foo > True > >>> foo is bar > False > >>> foo == foo > False > >>> foo == bar > False > >>> quux = [foo, "spam"] > >>> "spam" in quux > True > >>> foo in quux > True Did you mean False here? Because True is current behavior. -- ~Ethan~
[toc] | [prev] | [next] | [standalone]
| From | Ben Finney <ben+python@benfinney.id.au> |
|---|---|
| Date | 2015-03-06 14:26 +1100 |
| Message-ID | <mailman.80.1425612620.21433.python-list@python.org> |
| In reply to | #86973 |
Ethan Furman <ethan@stoneleaf.us> writes: > On 03/05/2015 06:55 PM, Ben Finney wrote: > > > class NullType(object): > > """ A type whose value never equals any other. > > > > This type's values will behave correctly when tested for > > membership in a collection:: > > > > >>> foo = NullType() > > >>> bar = NullType() > > >>> foo is foo > > True > > >>> foo is bar > > False > > >>> foo == foo > > False > > >>> foo == bar > > False > > >>> quux = [foo, "spam"] > > >>> "spam" in quux > > True > > >>> foo in quux > > True > > Did you mean False here? Because True is current behavior. Isn't the point at issue that the Python interpreter *may* optimise by assuming ‘is implies equality’, so the ‘in’ operator can fail if that assumption is false? I thought the problem was that types with custom behaviour, as with the ‘NullType’ example, needed to deal specially with the ‘is implies equality’ optimisation Steven explained. If that's the correct behaviour, and we can *depend* on it being correct, then I don't see what the problem is. -- \ “What I have to do is see, at any rate, that I do not lend | `\ myself to the wrong which I condemn.” —Henry Thoreau, _Civil | _o__) Disobedience_ | Ben Finney
[toc] | [prev] | [next] | [standalone]
| From | Ethan Furman <ethan@stoneleaf.us> |
|---|---|
| Date | 2015-03-05 19:44 -0800 |
| Message-ID | <mailman.82.1425613536.21433.python-list@python.org> |
| In reply to | #86973 |
[Multipart message — attachments visible in raw view] — view raw
On 03/05/2015 07:26 PM, Ben Finney wrote: > Ethan Furman <ethan@stoneleaf.us> writes: > >> On 03/05/2015 06:55 PM, Ben Finney wrote: >> >>> class NullType(object): >>> """ A type whose value never equals any other. >>> >>> This type's values will behave correctly when tested for >>> membership in a collection:: >>> >>> >>> foo = NullType() >>> >>> bar = NullType() >>> >>> foo is foo >>> True >>> >>> foo is bar >>> False >>> >>> foo == foo >>> False >>> >>> foo == bar >>> False >>> >>> quux = [foo, "spam"] >>> >>> "spam" in quux >>> True >>> >>> foo in quux >>> True >> >> Did you mean False here? Because True is current behavior. > > Isn't the point at issue that the Python interpreter *may* optimise by > assuming ‘is implies equality’, so the ‘in’ operator can fail if that > assumption is false? No, it's not a /may/, it's a /does/, and that it can be optimized is a bonus. > I thought the problem was that types with custom behaviour, as with the > ‘NullType’ example, needed to deal specially with the ‘is implies > equality’ optimisation Steven explained. The NaN-type objects cannot deal with it directly, as that behavior is in the container. > If that's the correct behaviour, and we can *depend* on it being > correct, then I don't see what the problem is. Well, we can depend on it for native Python types -- but if you write your own container, along with your own __contains__, then you might unwittingly do `for item in self.container: if item == target: return True` and then NaN (or NullType, or what-have-you) would not work "correctly" [1] for your container. -- ~Ethan~ [1] Otherwise known as: how Python does it.
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-03-06 14:49 +1100 |
| Message-ID | <mailman.83.1425613750.21433.python-list@python.org> |
| In reply to | #86973 |
On Fri, Mar 6, 2015 at 2:26 PM, Ben Finney <ben+python@benfinney.id.au> wrote: > Isn't the point at issue that the Python interpreter *may* optimise by > assuming ‘is implies equality’, so the ‘in’ operator can fail if that > assumption is false? > > I thought the problem was that types with custom behaviour, as with the > ‘NullType’ example, needed to deal specially with the ‘is implies > equality’ optimisation Steven explained. > > If that's the correct behaviour, and we can *depend* on it being > correct, then I don't see what the problem is. I'm not sure it's just an optimization. Compare this post from python-dev, where Nick Coghlan discusses the same topic: https://mail.python.org/pipermail/python-dev/2014-July/135476.html ChrisA
[toc] | [prev] | [next] | [standalone]
| From | random832@fastmail.us |
|---|---|
| Date | 2015-03-05 23:37 -0500 |
| Message-ID | <mailman.86.1425616629.21433.python-list@python.org> |
| In reply to | #86973 |
On Thu, Mar 5, 2015, at 22:49, Chris Angelico wrote: > I'm not sure it's just an optimization. Compare this post from > python-dev, where Nick Coghlan discusses the same topic: > > https://mail.python.org/pipermail/python-dev/2014-July/135476.html If it is a bug for NaN to "infect" containers' behavior, we need to take a serious look at sort().
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2015-03-07 04:07 +1100 |
| Message-ID | <54f9decd$0$12987$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #86984 |
random832@fastmail.us wrote:
> On Thu, Mar 5, 2015, at 22:49, Chris Angelico wrote:
>> I'm not sure it's just an optimization. Compare this post from
>> python-dev, where Nick Coghlan discusses the same topic:
>>
>> https://mail.python.org/pipermail/python-dev/2014-July/135476.html
>
> If it is a bug for NaN to "infect" containers' behavior, we need to take
> a serious look at sort().
Hmmm. No, I don't think so. I think that NANs are just weird and you either
accept that they do weird things or you don't use them.
Real numbers have a total ordering, so sorting a list of real numbers (or
their closest equivalent in computer implementations) makes sense, and sure
enough we can meaningfully sort a list of finite floats.
Complex numbers do not define an ordering at all: given a complex number w,
and another complex number z, asking whether w < z is meaningless. Ordering
comparisons simply aren't defined for complex numbers at all, and trying to
sort a list with more than one complex number will raise an exception.
But NANs are weird. NANs are unordered like complex, but unlike complex the
order comparisons are defined. They just always return False (except for
not-equal, which always returns True):
NAN < x returns False, for every x
NAN > x also returns False, for every x
If you think of NANs as members of a set with total ordering, like the real
number line, then this doesn't make sense. But floats (as opposed to the
Real Numbers) don't have total order. If you think of NANs as members of
unorderable values like the complex plane, then you should get an
exception, but they aren't members of an unorderable set, they're merely
not ordered. There's nothing wrong with doing:
if x < 1.2345: ...
just because x happens to be a NAN. One shouldn't raise an exception (even
though this is an exceptional case), because < and > operators are
perfectly well-defined for NANs, unlike the case for complex values.
But the consequence of this is that sort misbehaves. Sort algorithms depend
on the values being sorted having a total order. If you sort a list
containing objects with a partial order (like sets, or NANs), then the sort
result is dependent on the initial order of the elements.
If we really wanted to solve this problem, we could re-define sorting to use
a separate method instead of __lt__, let's call it __sort_lt__. If
__sort_lt__ doesn't exist, sorting will fall back on __lt__. That will
allow sets to distinguish between the use of < for subset testing and the
use of < for the purposes of sorting, and raise an exception or a warning.
Likewise floats could define the method:
def __sort_lt__(self, other):
if isnan(self) or isnan(other):
raise SomeException
return type(self).__lt__(other)
Another option would be to have a context manager which disables order
comparisons for NANs:
def sorted(it):
L = list(it)
with disabled_nan_comparisons():
L.sort() # raise if L contains a NAN
return L
sort of thing.
But either solution is a pretty big change for a pretty rare issue.
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | Mark Lawrence <breamoreboy@yahoo.co.uk> |
|---|---|
| Date | 2015-03-06 04:46 +0000 |
| Message-ID | <mailman.87.1425617174.21433.python-list@python.org> |
| In reply to | #86973 |
On 06/03/2015 04:37, random832@fastmail.us wrote: > On Thu, Mar 5, 2015, at 22:49, Chris Angelico wrote: >> I'm not sure it's just an optimization. Compare this post from >> python-dev, where Nick Coghlan discusses the same topic: >> >> https://mail.python.org/pipermail/python-dev/2014-July/135476.html > > If it is a bug for NaN to "infect" containers' behavior, we need to take > a serious look at sort(). > I entirely agree. With the extremely serious bug that was reported (and fixed) just a few days ago in the Python sorting algorithm and/or code, it is quite clear to me that it probably needs a major rethink. After you :) -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence
[toc] | [prev] | [next] | [standalone]
| From | Rustom Mody <rustompmody@gmail.com> |
|---|---|
| Date | 2015-03-06 01:50 -0800 |
| Message-ID | <dd9a23e8-39fc-4a1f-87f1-d2edbcc3e0e6@googlegroups.com> |
| In reply to | #86958 |
On Friday, March 6, 2015 at 3:57:12 AM UTC+5:30, rand...@fastmail.us wrote: > It's been brought up on Stack Overflow that the "in" operator (on > tuples, and by my testing on dict and list, as well as dict lookup) uses > object identity as a shortcut, and returns true immediately if the > object being tested *is* an element of the container. However, the > contains operation does not specify whether object identity or equality > is to be used. In effect, the built-in container types use a hybrid > test: "a is b or a == b". > > My question is, is this a *correct* implementation of the operator, or > are objects "supposed to" use a basis of equality for these tests? nan is an illegal or bogus value. As usual legalizing the illegal is always fraught with increasing conundrums. The most (to me) classic instance of this is denotational semantics. In DS one tries to give semantics to programs by mapping programs to math-functions across some domains However some programs crash. What should be the semantics of such a program. We say its a partial function – undefined at the crash-points. But partial functions are not nearly as tractable (to mathematicians!) as total functions. So we invent a bogus value ⊥ (called bottom) and totalize all functions by mapping to this. Very nice… So nice in fact that we wish to add ⊥ to our programming language And now all hell breaks loose because the question x == ⊥ is the halting problem. And people love this problem so much they keep replicating it: - C and null (or Pascal/Lisp and Nil) [Hoare's billion dollar mistake https://en.wikipedia.org/wiki/Tony_Hoare#Apologies_and_retractions ] - nul in SQL – Should two nuls compare as same or different? There are good (and different!) reasons for both answers - Python and None - Floats and nans My own thoughts on this (not very well thought out, I admit) The letter of the IEEE standard talks of nans and their details The spirit of the standard is that nans capture exception-al computations ie nan represents an exception In a language like python with decent exceptions we do not need nans. Of course there are all sorts of corner cases eg data source is something outside python etc
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-03-06 21:01 +1100 |
| Message-ID | <mailman.101.1425636069.21433.python-list@python.org> |
| In reply to | #87003 |
On Fri, Mar 6, 2015 at 8:50 PM, Rustom Mody <rustompmody@gmail.com> wrote: > In a language like python with decent exceptions we do not need nans. Not so. I could perhaps accept that we don't need signalling NaNs, as they can be replaced with exceptions, but quiet NaNs are by definition _not_ exceptions. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Rustom Mody <rustompmody@gmail.com> |
|---|---|
| Date | 2015-03-06 02:22 -0800 |
| Message-ID | <87443f8f-3bd8-4b88-84c1-d20a2fc8cc19@googlegroups.com> |
| In reply to | #87006 |
On Friday, March 6, 2015 at 3:31:58 PM UTC+5:30, Chris Angelico wrote: > On Fri, Mar 6, 2015 at 8:50 PM, Rustom Mody wrote: > > In a language like python with decent exceptions we do not need nans. > > Not so. I could perhaps accept that we don't need signalling NaNs, as > they can be replaced with exceptions, but quiet NaNs are by definition > _not_ exceptions. My impression (maybe I am wrong): "Catch an exception and ignore it" is a way of converting signalling to quiet With the added advantage of being able to tweak the specs of what happens when nan op normal to one's taste
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2015-03-07 03:59 +1100 |
| Message-ID | <54f9dcdc$0$12987$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #87011 |
Rustom Mody wrote:
> On Friday, March 6, 2015 at 3:31:58 PM UTC+5:30, Chris Angelico wrote:
>> On Fri, Mar 6, 2015 at 8:50 PM, Rustom Mody wrote:
>> > In a language like python with decent exceptions we do not need nans.
>>
>> Not so. I could perhaps accept that we don't need signalling NaNs, as
>> they can be replaced with exceptions, but quiet NaNs are by definition
>> _not_ exceptions.
>
> My impression (maybe I am wrong):
> "Catch an exception and ignore it" is a way of converting signalling to
> quiet With the added advantage of being able to tweak the specs of what
> happens when nan op normal to one's taste
I don't understand what you are trying to say.
Let's take a dirt-simple example:
def inverse(x):
return 1.0/x
There's an exception there, waiting to bite. If I include inverse() in some
complex calculation:
def function(x, y):
return atan2(inverse(3*x*y)+1, inverse(1 - x**2 + 3*x - 0.2)**3)
values = [function(1.5*x, y+2) for x, y in zip(xx, yy)]
and I just wish to skip over the failed calculations, I can't just "ignore"
exceptions:
# This doesn't work!
def inverse(x):
try:
return 1.0/x
except ZeroDivisionError:
pass
I have to return something that acts like a number but isn't a number.
Something which, once it enters a calculation, should propagate through it.
But not necessarily something which once it enters can never be removed! It
may be that some calculations can "cancel out" these "errors" (indeed, the
atan2 function is one of those -- it can return non-NANs from at least some
NAN arguments). So what should I return? It cannot be a number, but it has
to act like a number. Ideally, it should carry diagnostic information so I
can see what the failure was, for debugging, although I may not bother to
do so that information should at least be available for use.
I have just re-invented NANs.
--
Steven
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.python
csiph-web