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


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

'is not' or '!='

Started by"ElChino" <elchino@cnn.cn>
First post2014-08-18 22:35 +0200
Last post2014-08-21 21:42 +0200
Articles 20 on this page of 44 — 20 participants

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


Contents

  'is not' or '!=' "ElChino" <elchino@cnn.cn> - 2014-08-18 22:35 +0200
    Re: 'is not' or '!=' MRAB <python@mrabarnett.plus.com> - 2014-08-18 21:53 +0100
    Re: 'is not' or '!=' Marko Rauhamaa <marko@pacujo.net> - 2014-08-18 23:53 +0300
      Re: 'is not' or '!=' "ElChino" <elchino@cnn.cn> - 2014-08-18 22:58 +0200
        Re: 'is not' or '!=' Ethan Furman <ethan@stoneleaf.us> - 2014-08-18 14:42 -0700
        Re: 'is not' or '!=' Ethan Furman <ethan@stoneleaf.us> - 2014-08-18 15:19 -0700
        Re: 'is not' or '!=' Chris Kaynor <ckaynor@zindagigames.com> - 2014-08-18 15:04 -0700
          Re: 'is not' or '!=' Thomas Rachel <nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de> - 2014-08-19 11:49 +0200
        Re: 'is not' or '!=' Martin S <shieldfire@gmail.com> - 2014-08-19 14:42 +0200
        Re: 'is not' or '!=' Skip Montanaro <skip@pobox.com> - 2014-08-19 08:12 -0500
          Re: 'is not' or '!=' Marko Rauhamaa <marko@pacujo.net> - 2014-08-19 20:29 +0300
            Re: 'is not' or '!=' Tim Chase <python.list@tim.thechases.com> - 2014-08-19 12:34 -0500
              Re: 'is not' or '!=' Marko Rauhamaa <marko@pacujo.net> - 2014-08-19 21:18 +0300
            Re: 'is not' or '!=' Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-08-20 04:26 +1000
              Re: 'is not' or '!=' Marko Rauhamaa <marko@pacujo.net> - 2014-08-19 21:52 +0300
                Re: 'is not' or '!=' Marko Rauhamaa <marko@pacujo.net> - 2014-08-20 00:00 +0300
                  Re: 'is not' or '!=' Ian Kelly <ian.g.kelly@gmail.com> - 2014-08-19 16:21 -0600
                    Re: 'is not' or '!=' Marko Rauhamaa <marko@pacujo.net> - 2014-08-20 02:02 +0300
                  Re: 'is not' or '!=' Rustom Mody <rustompmody@gmail.com> - 2014-08-20 22:03 -0700
                    Re: 'is not' or '!=' Marko Rauhamaa <marko@pacujo.net> - 2014-08-21 08:56 +0300
              Re: 'is not' or '!=' Mark Lawrence <breamoreboy@yahoo.co.uk> - 2014-08-19 20:05 +0100
              Re: 'is not' or '!=' Terry Reedy <tjreedy@udel.edu> - 2014-08-19 18:23 -0400
        Re: 'is not' or '!=' Ian Kelly <ian.g.kelly@gmail.com> - 2014-08-19 10:42 -0600
          Re: 'is not' or '!=' Marko Rauhamaa <marko@pacujo.net> - 2014-08-19 20:36 +0300
        Re: 'is not' or '!=' Skip Montanaro <skip@pobox.com> - 2014-08-19 13:44 -0500
      Re: 'is not' or '!=' alister <alister.nospam.ware@ntlworld.com> - 2014-08-19 09:35 +0000
      Re: 'is not' or '!=' Thomas Rachel <nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de> - 2014-08-19 11:53 +0200
    Re: 'is not' or '!=' Rustom Mody <rustompmody@gmail.com> - 2014-08-18 19:29 -0700
      Re: 'is not' or '!=' Steven D'Aprano <steve@pearwood.info> - 2014-08-19 08:36 +0000
        Re: 'is not' or '!=' Chris Angelico <rosuav@gmail.com> - 2014-08-19 18:47 +1000
        Re: 'is not' or '!=' Tim Chase <python.list@tim.thechases.com> - 2014-08-19 05:36 -0500
        Re: 'is not' or '!=' Ben Finney <ben+python@benfinney.id.au> - 2014-08-20 09:24 +1000
          Re: 'is not' or '!=' Rustom Mody <rustompmody@gmail.com> - 2014-08-19 21:01 -0700
            Re: 'is not' or '!=' Steven D'Aprano <steve@pearwood.info> - 2014-08-20 04:59 +0000
              Re: 'is not' or '!=' Rustom Mody <rustompmody@gmail.com> - 2014-08-19 22:25 -0700
                Re: 'is not' or '!=' Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-08-20 21:05 +1000
                  Re: 'is not' or '!=' Chris Angelico <rosuav@gmail.com> - 2014-08-20 21:17 +1000
                    Re: 'is not' or '!=' Thomas Rachel <nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de> - 2014-08-21 20:31 +0200
                  Re: 'is not' or '!=' Tim Chase <python.list@tim.thechases.com> - 2014-08-20 06:26 -0500
                  Re: 'is not' or '!=' Chris Angelico <rosuav@gmail.com> - 2014-08-20 21:33 +1000
                  Re: 'is not' or '!=' Robert Kern <robert.kern@gmail.com> - 2014-08-20 12:40 +0100
                  Re: 'is not' or '!=' Rustom Mody <rustompmody@gmail.com> - 2014-08-20 05:01 -0700
    Re: 'is not' or '!=' Dan Stromberg <drsalists@gmail.com> - 2014-08-21 12:24 -0700
      Re: 'is not' or '!=' "ElChino" <elchino@cnn.cn> - 2014-08-21 21:42 +0200

Page 1 of 3  [1] 2 3  Next page →


#76510 — 'is not' or '!='

From"ElChino" <elchino@cnn.cn>
Date2014-08-18 22:35 +0200
Subject'is not' or '!='
Message-ID<lsto1s$6gk$1@dont-email.me>
A newbie question to you; what is the difference between statements 
like:
  if x is not None:
and
 if x != None:

Without any context, which one should be preferred?
IMHO, the latter is more readable.

[toc] | [next] | [standalone]


#76511

FromMRAB <python@mrabarnett.plus.com>
Date2014-08-18 21:53 +0100
Message-ID<mailman.13114.1408395209.18130.python-list@python.org>
In reply to#76510
On 2014-08-18 21:35, ElChino wrote:
> A newbie question to you; what is the difference between statements
> like:
>    if x is not None:
> and
>   if x != None:
>
> Without any context, which one should be preferred?
> IMHO, the latter is more readable.
>
"x == y" tells you whether x and y refer to objects that are equal.

"x is y" tells you whether x and y actually refer to the same object.

In the case of singletons like None (there's only one None object),
it's better to use "is".

[toc] | [prev] | [next] | [standalone]


#76512

FromMarko Rauhamaa <marko@pacujo.net>
Date2014-08-18 23:53 +0300
Message-ID<87fvgt7c4i.fsf@elektro.pacujo.net>
In reply to#76510
"ElChino" <elchino@cnn.cn>:

> A newbie question to you; what is the difference between statements
> like:
>  if x is not None:
> and
> if x != None:

Do the following: take two $10 bills. Hold one bill in the left hand,
hold the other bill in the right hand.

Now, the bill in the left hand "is not" the bill in the right hand.
However, the bill in the left hand "==" the bill in the right hand.

> Without any context, which one should be preferred?
> IMHO, the latter is more readable.

In almost all cases, both tests would result in the same behavior.
However, the "is not" test is conceptually the correct one since you
want to know if x is the one and only None object. You don't want to be
fooled by an imposter object that simply looks like the None object.
Frankly, I don't know of any other object that is "==" to the None
object except None itself, but such objects could possible exist.


Marko

[toc] | [prev] | [next] | [standalone]


#76513

From"ElChino" <elchino@cnn.cn>
Date2014-08-18 22:58 +0200
Message-ID<lstpe1$gbn$1@dont-email.me>
In reply to#76512
"Marko Rauhamaa" <marko@pacujo.net> wrote:
 
> In almost all cases, both tests would result in the same behavior.
> However, the "is not" test is conceptually the correct one since you
> want to know if x is the one and only None object. You don't want to be
> fooled by an imposter object that simply looks like the None object.

Thanks for this excellent answer. "Terve, terve".

[toc] | [prev] | [next] | [standalone]


#76517

FromEthan Furman <ethan@stoneleaf.us>
Date2014-08-18 14:42 -0700
Message-ID<mailman.13115.1408398146.18130.python-list@python.org>
In reply to#76513
On 08/18/2014 01:58 PM, ElChino wrote:
> "Marko Rauhamaa" <marko@pacujo.net> wrote:
>
>> In almost all cases, both tests would result in the same behavior.
>> However, the "is not" test is conceptually the correct one since you
>> want to know if x is the one and only None object. You don't want to be
>> fooled by an imposter object that simply looks like the None object.
>
> Thanks for this excellent answer. "Terve, terve".

I don't know what "terve, terve" means, but the "in almost all cases" is only true when talking about singletons such as 
None.

If you are not dealing with singletons (which is most cases), such as numbers, strings, lists, and most other arbitrary 
objects, you will need to use "!=" or anytime the two objects you are comparing are not the exact same object, you can 
easily get the wrong answer.

--
~Ethan~

[toc] | [prev] | [next] | [standalone]


#76520

FromEthan Furman <ethan@stoneleaf.us>
Date2014-08-18 15:19 -0700
Message-ID<mailman.13118.1408400381.18130.python-list@python.org>
In reply to#76513
On 08/18/2014 03:04 PM, Chris Kaynor wrote:
> On Mon, Aug 18, 2014 at 2:42 PM, Ethan Furman wrote:
>>
>> If you are not dealing with singletons (which is most cases), such as numbers, strings, lists, and most other
>> arbitrary objects, you will need to use "!=" or anytime the two objects you are comparing are not the exact same
>> object, you can easily get the wrong answer.
>
> For example, in CPython 3.4.1:
>>>> (254 + 3) is 257
> False
>>>> (254 + 3) == 257
> True
>>>> ('asd' + '@sd') is 'asd@sd'
> False
>>>> ('asd' + '@sd') == 'asd@sd'
> True
>
> However, when testing these cases, you need to be careful due to optimizations like smaller integer interning and string
> interning:
>
>>>> (254 + 2) == 256
> True
>>>> (254 + 2) is 256
> True
>>>> ('asd' + 'sd') == 'asdsd'
> True
>>>> ('asd' + 'sd') is 'asdsd'
> True
>
> In each of these cases, the behavior may be different in other implementations or versions of Python.

But the point to remember is that, for equal objects, '==' will work, 'is' may or may not.

--
~Ethan~

[toc] | [prev] | [next] | [standalone]


#76522

FromChris Kaynor <ckaynor@zindagigames.com>
Date2014-08-18 15:04 -0700
Message-ID<mailman.13120.1408401295.18130.python-list@python.org>
In reply to#76513

[Multipart message — attachments visible in raw view] — view raw

On Mon, Aug 18, 2014 at 2:42 PM, Ethan Furman <ethan@stoneleaf.us> wrote:

> If you are not dealing with singletons (which is most cases), such as
> numbers, strings, lists, and most other arbitrary objects, you will need to
> use "!=" or anytime the two objects you are comparing are not the exact
> same object, you can easily get the wrong answer.


For example, in CPython 3.4.1:
>>> (254 + 3) is 257
False
>>> (254 + 3) == 257
True
>>> ('asd' + '@sd') is 'asd@sd'
False
>>> ('asd' + '@sd') == 'asd@sd'
True

However, when testing these cases, you need to be careful due to
optimizations like smaller integer interning and string interning:

>>> (254 + 2) == 256
True
>>> (254 + 2) is 256
True
>>> ('asd' + 'sd') == 'asdsd'
True
>>> ('asd' + 'sd') is 'asdsd'
True

In each of these cases, the behavior may be different in other
implementations or versions of Python.

Chris

[toc] | [prev] | [next] | [standalone]


#76552

FromThomas Rachel <nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de>
Date2014-08-19 11:49 +0200
Message-ID<lsv6ju$v7q$1@r01.glglgl.de>
In reply to#76522
Am 19.08.2014 00:04 schrieb Chris Kaynor:

> In each of these cases, the behavior may be different in other
> implementations or versions of Python.

And, the most important thing, in each of these cases, using "is" is 
semantically wrong, so no matter how different versions behave.

If you ask the wrong question, you might get a wrong answer.


Thomas

[toc] | [prev] | [next] | [standalone]


#76559

FromMartin S <shieldfire@gmail.com>
Date2014-08-19 14:42 +0200
Message-ID<mailman.13144.1408452497.18130.python-list@python.org>
In reply to#76513
2014-08-19 0:04 GMT+02:00 Chris Kaynor <ckaynor@zindagigames.com>:
>
> On Mon, Aug 18, 2014 at 2:42 PM, Ethan Furman <ethan@stoneleaf.us> wrote:
>>
>> If you are not dealing with singletons (which is most cases), such as
>> numbers, strings, lists, and most other arbitrary objects, you will need to
>> use "!=" or anytime the two objects you are comparing are not the exact same
>> object, you can easily get the wrong answer.
>
>
> For example, in CPython 3.4.1:
>>>> (254 + 3) is 257
> False
>>>> (254 + 3) == 257
> True
>>>> ('asd' + '@sd') is 'asd@sd'
> False
>>>> ('asd' + '@sd') == 'asd@sd'
> True

Now you have managed to confuse this newbie: What would a valid
"is-example" look like?


Regards,

Martin S

[toc] | [prev] | [next] | [standalone]


#76564

FromSkip Montanaro <skip@pobox.com>
Date2014-08-19 08:12 -0500
Message-ID<mailman.13148.1408453963.18130.python-list@python.org>
In reply to#76513
On Tue, Aug 19, 2014 at 7:42 AM, Martin S <shieldfire@gmail.com> wrote:
>> For example, in CPython 3.4.1:
>>>>> (254 + 3) is 257
>> False
>>>>> (254 + 3) == 257
>> True
>>>>> ('asd' + '@sd') is 'asd@sd'
>> False
>>>>> ('asd' + '@sd') == 'asd@sd'
>> True
>
> Now you have managed to confuse this newbie: What would a valid
> "is-example" look like?

Perhaps adding to the confusion:

>>> (4 + 3) is 7
True

The use of "is" or "is not" is the right thing to do when the object
of the comparison is known to be a singleton. That is true for None.
(I suspect it's true for True and False as well, though for historical
and idiomatic reasons "x is True" is never used.) It would also be
true if you created a sentinel object like this:

SENTINEL = []

then used it to represent "no valid value" in situations where you
can't otherwise assume some value like None is outside the domain of
values:

if mything is not SENTINEL:
    # do whatever is necessary to initialize mything
    ...

The case of "(4 + 3) is 7" simply exposes an optimization in the
implementation of integers in CPython (the small integer cache), and
*must not be relied on*.

Note that

SENTINEL = ()

would be a mistake if () is in the domain of your data, since the
empty tuple is itself a singleton. That is a CPython implementation
detail you shouldn't rely on:

>>> x = ()
>>>
>>> y = (1,2,3)
>>>
>>> z = y[0:0]
>>> z
()
>>> x
()
>>> x == z
True
>>> x is z
True

That's why the first definition of SENTINEL uses the empty list. I can
guarantee that there is no other object in the system which "is" that
particular object.

(Strings which look like identifiers are also "interned" so there is
only one copy in memory. I suspect that's why Chris's string example
included an "@" - to defeat that optimization.)

The CPython runtime is under no obligation to retain these
optimizations. Relying on them is a bug. OTOH, CPython guarantees
there is only one None object in the system.

Skip

[toc] | [prev] | [next] | [standalone]


#76580

FromMarko Rauhamaa <marko@pacujo.net>
Date2014-08-19 20:29 +0300
Message-ID<8761ho75gv.fsf@elektro.pacujo.net>
In reply to#76564
Skip Montanaro <skip@pobox.com>:

> The use of "is" or "is not" is the right thing to do when the object
> of the comparison is known to be a singleton.

Object identity stirs a lot of passions on this forum. I'm guessing the
reason is that it is not defined very clearly (<URL:
https://docs.python.org/3/library/functions.html#id>):

   id(object)

       Return the “identity” of an object. This is an integer which is
       guaranteed to be unique and constant for this object during its
       lifetime. Two objects with non-overlapping lifetimes may have the
       same id() value.

       CPython implementation detail: This is the address of the object
       in memory.


The "is" relation can be defined trivially through the id() function:

   X is Y iff id(X) == id(Y)

What remains is the characterization of the (total) id() function. For
example, we can stipulate that:

   X = Y
   assert(id(X) == id(Y))
   # assignment preserves identity

(assuming X and Y are not modified in other threads or signal handlers).

We know further that:

   i = id(X)
   time.sleep(T)
   assert(i == id(X))
   # the identity does not change over time

   def f(x, y):
       return id(x) == id(y)
   assert(f(X, X))
   # parameter passing preserves the identity

   def f(x):
       return x
   assert(id(f(X) == id(X)))
   # the return statement preserves the identity

   assert(id((X0, X1, ..., X)[k]) == id(Xk))
   # tuple composition and projection preserve the identity

   i = id(X)
   X.Y
   assert(i == id(X))
   # reference does not change the identity

and so on. The nice thing about these kinds of formal definitions is
that they make no metaphysical reference to "objects" or "lifetime" (or
the CPython implementation). They can also be converted into
implementation conformance statements and test cases.

A much tougher task is to define when id(X) != id(Y). After all, all of
the above would be satisfied by this implementation of id():

   def id(x):
       return 0

The nonidentity will probably have to be defined separately for each
builtin datatype. For example, for integers and strings we know only
that:

   assert(X == Y or id(X) != id(Y))
   # inequality implies nonidentity


Marko

[toc] | [prev] | [next] | [standalone]


#76582

FromTim Chase <python.list@tim.thechases.com>
Date2014-08-19 12:34 -0500
Message-ID<mailman.13155.1408469734.18130.python-list@python.org>
In reply to#76580
On 2014-08-19 20:29, Marko Rauhamaa wrote:
> The "is" relation can be defined trivially through the id()
> function:
> 
>    X is Y iff id(X) == id(Y)
> 
> What remains is the characterization of the (total) id() function.
> For example, we can stipulate that:
> 
>    X = Y
>    assert(id(X) == id(Y))

Note that a lifetime can be less than a statement:

$ python
Python 2.7.3 (default, Mar 13 2014, 11:03:55) 
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> id([1,2,3]) == id([4,5,6])
True


-tkc

[toc] | [prev] | [next] | [standalone]


#76591

FromMarko Rauhamaa <marko@pacujo.net>
Date2014-08-19 21:18 +0300
Message-ID<87siks5oo0.fsf@elektro.pacujo.net>
In reply to#76582
Tim Chase <python.list@tim.thechases.com>:

> Note that a lifetime can be less than a statement:
>
>>>> id([1,2,3]) == id([4,5,6])
> True

Duly noted.


Marko

[toc] | [prev] | [next] | [standalone]


#76592

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2014-08-20 04:26 +1000
Message-ID<53f396eb$0$29993$c3e8da3$5496439d@news.astraweb.com>
In reply to#76580
Marko Rauhamaa wrote:

> Skip Montanaro <skip@pobox.com>:
> 
>> The use of "is" or "is not" is the right thing to do when the object
>> of the comparison is known to be a singleton.
> 
> Object identity stirs a lot of passions on this forum. I'm guessing the
> reason is that it is not defined very clearly (<URL:
> https://docs.python.org/3/library/functions.html#id>):

Identity is defined very clearly. As you just quoted:

>    id(object)
> 
>        Return the “identity” of an object. This is an integer which is
>        guaranteed to be unique and constant for this object during its
>        lifetime. Two objects with non-overlapping lifetimes may have the
>        same id() value.

Python identity is represented by an integer, and it is guaranteed to be
unique and constant for the lifetime of the object. It may or may not be
reused once the object no longer exists. That's all you need to know about
identity; that's *all there is to know* about identity in Python.

[Actually, to be pedantic, one also needs to state that the objects have to
be part of a single Python process. Object X in one process, and object Y
in another process, may have the same id() but still be considered
distinct.]


>        CPython implementation detail: This is the address of the object
>        in memory.

I really wish CPython didn't do that, or at least not admit to it. It does
nothing but confuse people.


> The "is" relation can be defined trivially through the id() function:
> 
>    X is Y iff id(X) == id(Y)

Except that id() is a built-in function and can be shadowed or
monkey-patched, while the `is` operator is a keyword and cannot be. But
apart from that minor point, I agree.

 
> What remains is the characterization of the (total) id() function. For
> example, we can stipulate that:
> 
>    X = Y
>    assert(id(X) == id(Y))
>    # assignment preserves identity

That's not a property of identity. That's a property of *assignment*. So you
cannot use that fact to define identity in Python, since there could be
another language with the *exact* same definition of identity but that does
copy-on-assignment instead.


> (assuming X and Y are not modified in other threads or signal handlers).
> 
> We know further that:
> 
>    i = id(X)
>    time.sleep(T)
>    assert(i == id(X))
>    # the identity does not change over time

That would be the part of the definition that says the identity is constant.

 
>    def f(x, y):
>        return id(x) == id(y)
>    assert(f(X, X))
>    # parameter passing preserves the identity

Again, that's not a property of identity. There could be a language just
like Python in all respects, including identity, except that parameters are
passed by value.


[snip more examples of things which tell us nothing about identity]


> The nice thing about these kinds of formal definitions is 
> that they make no metaphysical reference to "objects" or "lifetime" (or
> the CPython implementation).

They are not metaphysical. They are concrete. You cannot understand the
semantics of identity in Python without understanding Python's execution
model. Python's execution model contains objects (which are not
metaphysical woo, but a concrete computer science data structure), and
identity in Python is defined in terms of objects. Not values, or names, or
namespaces, but objects.


> They can also be converted into
> implementation conformance statements and test cases.

True, but in most of the examples you show, they will be tests of some other
aspect of Python, e.g. that assignment (name binding) preserves identity.
They don't help us understand identity, because there are other models for
assignment, and there are an infinite number of things which could also be
preserved by assignment but aren't identity.

E.g. "the number of zero bits in the object struct".


> A much tougher task is to define when id(X) != id(Y). After all, all of
> the above would be satisfied by this implementation of id():
> 
>    def id(x):
>        return 0

That fails the definition given, that identities are *unique*.

Defining non-identity for objects that exist simultaneously is simple:

id(X) != id(Y) iff not (X is Y)

We don't have good notation for discussing objects which exist at different
times, but we can fake it with the rule:

"if either X or Y or both raise NameError, then we deem `X is Y` to be
false"

 
> The nonidentity will probably have to be defined separately for each
> builtin datatype. 

That is incorrect. See below.

> For example, for integers and strings we know only  
> that:
> 
>    assert(X == Y or id(X) != id(Y))
>    # inequality implies nonidentity

That tells us something about string equality. It tells us nothing about
identity.

Python's concept of identity applies equally to all types. Read the
definition again: it refers to objects, but without caring about the type
of objects. Let's just consider two types:

str:
    assert (X == Y or id(X) != id(Y)) always passes

float:
    assert (X == Y or id(X) != id(Y)) sometimes fails

Proof of the second case:

py> X = Y = float('nan')
py> assert (X == Y or id(X) != id(Y))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError

This demonstrates that the condition

    (X == Y or id(X) != id(Y))

fails to tell us anything useful about identity, since it is sometimes true
and sometimes false.

You cannot understand identity from first principles, precisely because it
is not a metaphysical concept in Python. In Python it is defined by and in
terms of the concrete programming model of the language.



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#76597

FromMarko Rauhamaa <marko@pacujo.net>
Date2014-08-19 21:52 +0300
Message-ID<87ha185n34.fsf@elektro.pacujo.net>
In reply to#76592
Steven D'Aprano <steve+comp.lang.python@pearwood.info>:

> Python identity is represented by an integer, and it is guaranteed to
> be unique and constant for the lifetime of the object. It may or may
> not be reused once the object no longer exists. That's all you need to
> know about identity; that's *all there is to know* about identity in
> Python.
>
> [...]
>
> They are not metaphysical. They are concrete. You cannot understand the
> semantics of identity in Python without understanding Python's execution
> model.

That's circular reasoning. When you are defining Python's execution
model, you can't refer back to Python's execution model.

For a good example of what I'm after, take a look how Java specifies its
crucial happens-before relation:

   <URL:
   http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4.5>


Marko

[toc] | [prev] | [next] | [standalone]


#76604

FromMarko Rauhamaa <marko@pacujo.net>
Date2014-08-20 00:00 +0300
Message-ID<87bnrg5h5l.fsf@elektro.pacujo.net>
In reply to#76597
Marko Rauhamaa <marko@pacujo.net>:

> That's circular reasoning. When you are defining Python's execution
> model, you can't refer back to Python's execution model.
>
> For a good example of what I'm after, take a look how Java specifies its
> crucial happens-before relation:
>
>    <URL:
>    http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4.5>

However, Java does *not* do a particularly good job defining object
identity (<URL:
http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.21.3>):

   At run time, the result of == is true if the operand values are both
   null or both refer to the same object or array; otherwise, the result
   is false.

   The result of != is false if the operand values are both null or both
   refer to the same object or array; otherwise, the result is true.

For a more worthy attempt, we'll have to take a look at Scheme (<URL:
http://www.scheme.com/tspl2d/objects.html>):

   * Two objects of different types (booleans, the empty list, pairs,
     numbers, characters, strings, vectors, symbols, and procedures) are
     distinct. The Revised4 Report (but not the ANSI/IEEE standard)
     permits one exception to this rule: the empty list and the boolean
     #f may be identical.

   * Two objects of the same type with different contents or values are
     distinct.

   * The boolean object #t is identical to itself wherever it appears,
     and #f is identical to itself wherever it appears, but #t and #f
     are distinct.

   * The empty list () is identical to itself wherever it appears.

   * Two symbols (created by read or by string->symbol) are identical if
     and only if they have the same name (by string=?).

   * A quoted pair, vector, or string is identical to itself, as is a
     pair, vector, or string created by an application of cons, vector,
     string, etc. Two pairs, vectors, or strings created by different
     applications of cons, vector, string, etc., are distinct. One
     consequence is that cons, for example, may be used to create a
     unique object distinct from all other objects.

   * Two procedures that may behave differently are distinct. A
     procedure created by an evaluation of a lambda expression is
     identical to itself. Two procedures created by the same lambda
     expression at different times, or by similar lambda expressions,
     may or may not be identical.


Marko

[toc] | [prev] | [next] | [standalone]


#76612

FromIan Kelly <ian.g.kelly@gmail.com>
Date2014-08-19 16:21 -0600
Message-ID<mailman.13170.1408486944.18130.python-list@python.org>
In reply to#76604
On Tue, Aug 19, 2014 at 3:00 PM, Marko Rauhamaa <marko@pacujo.net> wrote:
> For a more worthy attempt, we'll have to take a look at Scheme (<URL:
> http://www.scheme.com/tspl2d/objects.html>):

Those are invariants, not a definition.  The actual definition is
found in the paragraph above:

"In most Scheme systems, two objects are considered identical if they
are represented internally by the same pointer value and distinct (not
identical) if they are represented internally by different pointer
values, although other criteria, such as time-stamping, are possible."

In other words, object identity in Scheme is also established by an
integer that may or may not correspond to a memory address. How is
this any different from Python's definition?

[toc] | [prev] | [next] | [standalone]


#76617

FromMarko Rauhamaa <marko@pacujo.net>
Date2014-08-20 02:02 +0300
Message-ID<877g245bhy.fsf@elektro.pacujo.net>
In reply to#76612
Ian Kelly <ian.g.kelly@gmail.com>:

> On Tue, Aug 19, 2014 at 3:00 PM, Marko Rauhamaa <marko@pacujo.net> wrote:
>> For a more worthy attempt, we'll have to take a look at Scheme (<URL:
>> http://www.scheme.com/tspl2d/objects.html>):
>
> Those are invariants, not a definition.  The actual definition is
> found in the paragraph above:
>
> "In most Scheme systems, two objects are considered identical if they
> are represented internally by the same pointer value and distinct (not
> identical) if they are represented internally by different pointer
> values, although other criteria, such as time-stamping, are possible."
>
> In other words, object identity in Scheme is also established by an
> integer that may or may not correspond to a memory address. How is
> this any different from Python's definition?

"In most Scheme systems" is similar to the CPython sidenote. The
"invariants" might not form a complete axiom system but are a step in
that direction.

When Peano Arithmetic posits (<URL:
http://en.wikipedia.org/wiki/Peano_axioms#Addition>):
   
   a + 0 = a
   a + b' = (a + b)'

we usually take that to be the definition of addition in the system.

The true Scheme standard appeals to the "invariants" (<URL:
http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.ht
ml#%_sec_6.1>):

    The eqv? procedure defines a useful equivalence relation on objects.
    Briefly, it returns #t if obj1 and obj2 should normally be regarded
    as the same object. This relation is left slightly open to
    interpretation, but the following partial specification of eqv?
    holds for all implementations of Scheme.

    The eqv? procedure returns #t if:

       obj1 and obj2 are both #t or both #f.

       obj1 and obj2 are both symbols and

       (string=? (symbol->string obj1)
                 (symbol->string obj2))
                   ===>  #t

    [...]


Marko

[toc] | [prev] | [next] | [standalone]


#76698

FromRustom Mody <rustompmody@gmail.com>
Date2014-08-20 22:03 -0700
Message-ID<b84df5e4-53ca-4c7f-a817-de9d224908d4@googlegroups.com>
In reply to#76604
On Wednesday, August 20, 2014 2:30:22 AM UTC+5:30, Marko Rauhamaa wrote:

> For a more worthy attempt, we'll have to take a look at Scheme (<URL:
> http://www.scheme.com/tspl2d/objects.html>):

Since you brought up scheme, here is a discussion going on right now
on the Haskell list:

http://www.haskell.org/pipermail/haskell-cafe/2014-August/115659.html
[The lingo is of course different]

In summary it runs thus:
OP asks for 'is' (Haskell has no equivalent of 'is')

Almost all the answers explain why its a bad idea

[toc] | [prev] | [next] | [standalone]


#76704

FromMarko Rauhamaa <marko@pacujo.net>
Date2014-08-21 08:56 +0300
Message-ID<87bnrecrnr.fsf@elektro.pacujo.net>
In reply to#76698
Rustom Mody <rustompmody@gmail.com>:

> OP asks for 'is' (Haskell has no equivalent of 'is')
>
> Almost all the answers explain why its a bad idea

Well, I don't think it is a bad idea in and of itself, but if you don't
have it, you don't have to define it.

Object identity does make you look under the skin. In Python, it is
necessary even without id() or *is* since you have to understand why

   >>> a = []
   >>> b = a
   >>> b.append(0)
   >>> a
   [0]

Exposing object identity is a consequence of allowing mutable objects.


Marko

[toc] | [prev] | [next] | [standalone]


Page 1 of 3  [1] 2 3  Next page →

Back to top | Article view | comp.lang.python


csiph-web