Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #86958 > unrolled thread

Is nan in (nan,) correct?

Started byrandom832@fastmail.us
First post2015-03-05 17:26 -0500
Last post2015-03-06 18:37 -0800
Articles 20 on this page of 29 — 9 participants

Back to article view | Back to comp.lang.python


Contents

  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 →


#86958 — Is nan in (nan,) correct?

Fromrandom832@fastmail.us
Date2015-03-05 17:26 -0500
SubjectIs 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]


#86963

Fromsohcahtoa82@gmail.com
Date2015-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]


#86964

FromBen Finney <ben+python@benfinney.id.au>
Date2015-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]


#86966

Fromsohcahtoa82@gmail.com
Date2015-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]


#86967

FromBen Finney <ben+python@benfinney.id.au>
Date2015-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]


#86968

FromChris Angelico <rosuav@gmail.com>
Date2015-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]


#86965

FromChris Angelico <rosuav@gmail.com>
Date2015-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]


#86973

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2015-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]


#86975

FromBen Finney <ben+python@benfinney.id.au>
Date2015-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]


#86976

FromEthan Furman <ethan@stoneleaf.us>
Date2015-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]


#86978

FromBen Finney <ben+python@benfinney.id.au>
Date2015-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]


#86980

FromEthan Furman <ethan@stoneleaf.us>
Date2015-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]


#86981

FromChris Angelico <rosuav@gmail.com>
Date2015-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]


#86984

Fromrandom832@fastmail.us
Date2015-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]


#87046

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2015-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]


#86985

FromMark Lawrence <breamoreboy@yahoo.co.uk>
Date2015-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]


#87003

FromRustom Mody <rustompmody@gmail.com>
Date2015-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]


#87006

FromChris Angelico <rosuav@gmail.com>
Date2015-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]


#87011

FromRustom Mody <rustompmody@gmail.com>
Date2015-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]


#87043

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2015-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