Strange behaviour of 'is'

Discussion in 'Python' started by Duncan Booth, Sep 21, 2006.

1. Duncan BoothGuest

"Fijoy George" <> wrote:

> 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
example the comparison is False because the two lines are compiled
separately. If compiled together it might have returned True:

>>> x = 2.; x is 2.

True

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

Duncan Booth, Sep 21, 2006

2. Ben CGuest

On 2006-09-21, Fijoy George <> wrote:
> 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:

>>> a = 2.
>>> b = 2.

>>> a is b

False

>>> a, b = 2., 2.
>>> a is b

True

Ben C, Sep 21, 2006

3. Fijoy GeorgeGuest

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

Fijoy George, Sep 21, 2006
4. KlaasGuest

Ben C wrote:
> On 2006-09-21, Fijoy George <> wrote:

> > 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:

> >>> a = 2.
> >>> b = 2.

>
> >>> a is b

> False
>
> >>> a, b = 2., 2.
> >>> a is b

> True

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

-Mike

Klaas, Sep 21, 2006
5. Erik Max FrancisGuest

Ben C wrote:

> 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.

--
Erik Max Francis && && http://www.alcyone.com/max/
San Jose, CA, USA && 37 20 N 121 53 W && AIM, Y!M erikmaxfrancis
Little things / Cut like knives / Hurt and sting
-- Anggun

Erik Max Francis, Sep 21, 2006
6. Ben FinneyGuest

"Fijoy George" <> writes:

> 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.

comparisons. Don't use them as if they were the same operation,
because the implementation isn't restricted to meet that promise.

--
\ "You know what I hate? Indian givers... no, I take that back." |
`\ -- Emo Philips |
_o__) |
Ben Finney

Ben Finney, Sep 22, 2006
7. Steve HoldenGuest

Ben Finney wrote:
> "Fijoy George" <> writes:
>
>
>>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
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://holdenweb.blogspot.com
Recent Ramblings http://del.icio.us/steve.holden

Steve Holden, Sep 22, 2006
8. Duncan BoothGuest

Steve Holden <> wrote:

> 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
>>> 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.

Duncan Booth, Sep 22, 2006
9. Steve HoldenGuest

Duncan Booth wrote:
> Steve Holden <> wrote:
>
>
>>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
>
>>>>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
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://holdenweb.blogspot.com
Recent Ramblings http://del.icio.us/steve.holden

Steve Holden, Sep 22, 2006
10. Ben FinneyGuest

Steve Holden <> writes:

> 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

--
\ "He who allows oppression, shares the crime." -- Erasmus |
`\ Darwin, grandfather of Charles Darwin |
_o__) |
Ben Finney

Ben Finney, Sep 23, 2006