why () is () and [] is [] work in other way?

Tim Delaney timothy.c.delaney at gmail.com
Mon Apr 23 20:03:18 EDT 2012


On 24 April 2012 09:08, Devin Jeanpierre <jeanpierreda at gmail.com> wrote:

> On Mon, Apr 23, 2012 at 6:26 PM, Tim Delaney
> <timothy.c.delaney at gmail.com> wrote:
> > And doing that would make zero sense, because it directly contradicts the
> > whole *point* of "is". The point of "is" is to tell you whether or not
> two
> > references are to the same object. This is a *useful* property.
>
> It's useful for mutable objects, yes. How is it useful for immmutable
> things? They behave identically everywhere where you don't directly
> ask the question of "a is b" or "id(a) == id(b)".


Not always. NaNs are an exception - they don't even compare equal to
themselves. And hence a very good reason why "is" and == are separate
operations.


> Therefore it shouldn't make any difference if we make equality
> _always_ imply "is", since that was always on the table as an
> implementation detail.
>

See above. Identity does not necessarily imply equality.


> I think the real breakage is that now "a is b" is not equivalent to
> "id(a) == id(b)" (unless you try to hack that as well.)


The operations are indeed equivalent if the lifetimes of both objects cover
the entire computation. Since you are not rebinding names here, there is no
way that the operations could not be equivalent (unless multithreading is
involved and the name bindings change underneath you, but I think we can
discount that for the purposes of this discussion).

There is no breakage here - just (I'm suspecting willful) lack of
understanding.

>>> a = "a"
>>> b = a
>>> a is b
True
>>> id(a) == id(b)
True
>>> a = "a"
>>> b = "b"
>>> a is b
False
>>> id(a) == id(b)
False

Absolutely consistent results. The fact that a Python implementation is
free to reuse IDs once that ID is no longer in use (the behaviour prompting
this thread in the first place) is irrelevant here. At no time will "a is
b" and "id(a) == id(b)" give inconsistent results when the names "a" and
"b" remain bound to the same objects across the comparisons.

> remove the opportunity for various programming techniques, such as
> > interning. Of course, you could say that all immutable objects should be
> > interned automatically. There are a couple problems with this that I can
> > think of off the top of my head.
>
> Hold up, why do we give up interning? As you mention later, interning
> only involves hashing and equality comparisons, not id() or is. (e.g.
> we can intern `y` just fine with `y = cache.setdefault(y, y)`)


I should now conclude that you have no interest in actually discussing this
but just want to take an obstinate position and never consider moving from
it.

But I'll give one last chance. What is the whole point of interning? It's
to get a canonical object to reference:

>>> a = "a " + "b"
>>> b = "a b"
>>> a is b
False
>>> a = intern(a)
>>> b = intern(b)
>>> a is b
True

For (most*) immutable objects, if there is only ever a single canonical
instance with that value, == and "is" are effectively the same operation
(what you seem to want). Python's types are implemented this way - they do
an "is" check before moving onto the more expensive equality check (except
where overridden*). That's the benefit. But as you will see if you go back
and read my message, there is a tradeoff in memory and/or performance
involved in the canonicalising. Somewhere between no canonicalising and
canonicalising everything (inclusive) is a sweet spot in terms of this
tradeoff, and it varies depending on other decisions that have been made
for the language and (of course) the actual program being run.

* NaNs again.

Tim Delaney
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20120424/39e29c72/attachment-0001.html>


More information about the Python-list mailing list