Strange behaviour of 'is'

D

Duncan Booth

Fijoy George said:
My understanding was that every literal is a constructure of an
object. Thus, the '2.' in 'x = 2.' and the '2.' in 'x is 2.' are
different objects. Therefore, the comparison yields false.

What gave you that idea? The compiler may or may not fold together
identical immutable objects when it compiles your code. In your first
example the comparison is False because the two lines are compiled
separately. If compiled together it might have returned True:
True

However this is purely an implementation detail. The language doesn't
actually require either behaviour.
 
B

Ben C

Hi all,

I am a bit perplexed by the following behaviour of the 'is' comparator
x = 2.
x is 2. False
y = [2., 2.]
y[0] is y[1]
True

My understanding was that every literal is a constructure of an object.
Thus, the '2.' in 'x = 2.' and the '2.' in 'x is 2.' are different objects.
Therefore, the comparison yields false.

But my understanding does not explain the result of the second comparison.
According to the experiment, y[0] and y[1] are the same object!

I'm as baffled as you, even more so its implication:
True
 
F

Fijoy George

Hi all,

I am a bit perplexed by the following behaviour of the 'is' comparator
x = 2.
x is 2. False
y = [2., 2.]
y[0] is y[1]
True

My understanding was that every literal is a constructure of an object.
Thus, the '2.' in 'x = 2.' and the '2.' in 'x is 2.' are different objects.
Therefore, the comparison yields false.

But my understanding does not explain the result of the second comparison.
According to the experiment, y[0] and y[1] are the same object!

Does anyone know an explanation for this?

Thank you very much
Fijoy
 
K

Klaas

Ben said:
But my understanding does not explain the result of the second comparison.
According to the experiment, y[0] and y[1] are the same object!

I'm as baffled as you, even more so its implication:
True

It is suprising that it is easier to recognize identical constants
within the same expression?

-Mike
 
E

Erik Max Francis

Ben said:
I'm as baffled as you, even more so its implication:

There is no implication whatsoever. Whether immutable objects are
recycled by the compiler or not is totally implementation dependent, and
an irrelevant implementation detail. Since they can't be mutated,
whether their identity is shared with other objects in other contexts is
never significant.
 
B

Ben Finney

Fijoy George said:
I am a bit perplexed by the following behaviour of the 'is' comparator

In summary: you are seeing implementation details that the language
specification explicitly allows to vary by implementation.
My understanding was that every literal is a constructure of an
object. Thus, the '2.' in 'x = 2.' and the '2.' in 'x is 2.' are
different objects. Therefore, the comparison yields false.

There's no "thus" about it. Any implementation may use the same object
or different objects to represent any two values that are equal. This
allows different optimisations to be performed on different platforms,
without breaking the specified behaviour.
But my understanding does not explain the result of the second
comparison. According to the experiment, y[0] and y[1] are the same
object!

Does anyone know an explanation for this?

The explanation is:

Two objects compare *equal* if their '__eq__' method says they are. In
practice, this means their *values* are the same.

Two objects compare *identical* if the 'id()' function says they
are. In practice, this means they are the *same object*.

The relationship between "same object" and "same value" is entirely up
to the implementation to decide, by any simple or complex criteria it
chooses, and there's nothing in the specification that requires it to
be consistent at the program level. This is, among other reasons, to
allow optimisations that don't change the language specification.

No general promise is made about the relationship between those two
comparisons. Don't use them as if they were the same operation,
because the implementation isn't restricted to meet that promise.
 
S

Steve Holden

Ben said:
I am a bit perplexed by the following behaviour of the 'is' comparator


In summary: you are seeing implementation details that the language
specification explicitly allows to vary by implementation.

My understanding was that every literal is a constructure of an
object. Thus, the '2.' in 'x = 2.' and the '2.' in 'x is 2.' are
different objects. Therefore, the comparison yields false.


There's no "thus" about it. Any implementation may use the same object
or different objects to represent any two values that are equal. This
allows different optimisations to be performed on different platforms,
without breaking the specified behaviour.

But my understanding does not explain the result of the second
comparison. According to the experiment, y[0] and y[1] are the same
object!

Does anyone know an explanation for this?


The explanation is:

Two objects compare *equal* if their '__eq__' method says they are. In
practice, this means their *values* are the same.

Two objects compare *identical* if the 'id()' function says they
are. In practice, this means they are the *same object*.

The relationship between "same object" and "same value" is entirely up
to the implementation to decide, by any simple or complex criteria it
chooses, and there's nothing in the specification that requires it to
be consistent at the program level. This is, among other reasons, to
allow optimisations that don't change the language specification.

No general promise is made about the relationship between those two
comparisons. Don't use them as if they were the same operation,
because the implementation isn't restricted to meet that promise.
Absolutely correct. It would be more interesting to discuss how the
output from these statements varied between (say) CPython, Jython and
Iron Python. At the moment the discussion is indeed about insignificant
implementation trivia.

regards
Steve
 
D

Duncan Booth

Steve Holden said:
Absolutely correct. It would be more interesting to discuss how the
output from these statements varied between (say) CPython, Jython and
Iron Python. At the moment the discussion is indeed about insignificant
implementation trivia.

CPython seems to collapse identical float values if they are in the same
compilation unit:
x = 2.
y = 2.
x is y False
x = 2.; y = 2.
x is y True
y = [2., 2.]
y[0] is y[1]
True

IronPython doesn't collapse them even when they are in expression:

IronPython 1.0.60816 on .NET 2.0.50727.42
Copyright (c) Microsoft Corporation. All rights reserved.
x = 2.
y = 2.
x is y False
x = 2.; y = 2.
x is y False
y = [2., 2.]
y[0] is y[1]
False

JPython seems to behave in a similar manner to CPython:

Python command console - JPython 2.1
0
1
y = [2., 2.]
y[0] is y[1]
1

Sorry, I don't have a more recent Jython implementation to hand to complete
the comparison.
 
S

Steve Holden

Duncan said:
Absolutely correct. It would be more interesting to discuss how the
output from these statements varied between (say) CPython, Jython and
Iron Python. At the moment the discussion is indeed about insignificant
implementation trivia.


CPython seems to collapse identical float values if they are in the same
compilation unit:

x = 2.
y = 2.
x is y
False
x = 2.; y = 2.
x is y
True
y = [2., 2.]
y[0] is y[1]

True

IronPython doesn't collapse them even when they are in expression:

IronPython 1.0.60816 on .NET 2.0.50727.42
Copyright (c) Microsoft Corporation. All rights reserved.
x = 2.
y = 2.
x is y
False
x = 2.; y = 2.
x is y
False
y = [2., 2.]
y[0] is y[1]

False

JPython seems to behave in a similar manner to CPython:

Python command console - JPython 2.1

x = 2.
y = 2.
x is y
0

x = 2.; y = 2.
x is y
1

y = [2., 2.]
y[0] is y[1]

1



Sorry, I don't have a more recent Jython implementation to hand to complete
the comparison.

Perfectly all right: you make the point very well that the behavior is
an implementation artifact and not a language feature.

regards
Steve
 
B

Ben Finney

Steve Holden said:
Perfectly all right: you make the point very well that the behavior is
an implementation artifact and not a language feature.

And for those who may be thinking "oh, so I can at least depend on the
behaviour within a particular implementation", that's wrong too:
implementations are free to (and most will) change that behaviour from
one object or assignment to the next, depending on what optimisation
choices are made.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top