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

Adam Skutt askutt at gmail.com
Thu Apr 26 07:42:36 EDT 2012


On Apr 26, 5:10 am, Steven D'Aprano <steve
+comp.lang.pyt... at pearwood.info> wrote:
> On Wed, 25 Apr 2012 20:50:21 -0700, Adam Skutt wrote:
> > On Apr 25, 8:01 pm, Steven D'Aprano <steve
> > +comp.lang.pyt... at pearwood.info> wrote:
> >> On Wed, 25 Apr 2012 13:49:24 -0700, Adam Skutt wrote:
> >> > Though, maybe it's better to use a different keyword than 'is'
> >> > though, due to the plain English
> >> > connotations of the term; I like 'sameobj' personally, for whatever
> >> > little it matters.  Really, I think taking away the 'is' operator
> >> > altogether is better, so the only way to test identity is:
> >> >     id(x) == id(y)
>
> >> Four reasons why that's a bad idea:
>
> >> 1) The "is" operator is fast, because it can be implemented directly by
> >> the interpreter as a simple pointer comparison (or equivalent). The
> >> id() idiom is slow, because it involves two global lookups and an
> >> equality comparison. Inside a tight loop, that can make a big
> >> difference in speed.
>
> > The runtime can optimize the two operations to be equivalent, since they
> > are logically equivalent operations.  If you removed 'is', there's
> > little reason to believe it would do otherwise.
>
> I'm afraid you are mistaken there. *By design*, Python allows shadowing
> and monkey-patching of built-ins. (Although not quite to the same degree
> as Ruby, and thank goodness!)
>
Yes, I understand that. You still haven't explained why this behavior
is correct in this particular situation.  Arguing from the position
of, "What Python does must be correct" isn't a valid tactic, I'm
afraid.

> It's useful for the same reason that shadowing any other builtin is
> useful. id() isn't special enough to complicate the simple, and
> effective, execution model just to satisfy philosophers.

If overriding id() is useful, then overriding 'is' must be useful
too.  Python is still broken. Unless you can prove the two operations
shouldn't be logically equivalent (and you don't), you can't
meaningfully argue for different semantics for them.  You still end up
with a broken language either way.

> They are not *logically* equivalent. First you have to define what you
> mean by identity, then you have to define what you mean by an ID, and
> then you have to decide whether or not to enforce the rule that identity
> and IDs are 1:1 or not, and if so, under what circumstances.

You're going to have to explain the value of an "ID" that's not 1:1
with an object's identity, for at least the object's lifecycle, for a
programmer.  If you can't come up with a useful case, then you haven't
said anything of merit.

Plainly, to show they're not logically equivalent, you need to explain
why the guarantee provided by id() is improper.  Then, you need to
generalize it to all programming languages.  Python's concept of
identity is not unique nor special.  It uses the exact same rules as C+
+, C#, Java, and many other languages.

> My library
> card ID may, by coincidence, match your drivers licence ID. Doesn't mean
> we're the same person.

I don't know why you even remotely think this is relevant.  All it
does is further demonstrate that you don't understand the object-
oriented concept of identity at all.  Comparing library IDs and
drivers license IDs is an improper operation.  Languages that can have
multiple IDs, possibly overlapping, /do/ disallow such idiocy.

> identities. The Borg design pattern, for example, would be an excellent
> candidate for ID:identity being treated as many-to-one.

How would inheritance work if I did that?

> Even if you decide that treating IDs as 1:1 is the only thing that makes
> sense in your philosophy, in practice that does not hold for Python. IDs
> may be reused by Python.

They may be reused in all languages I can think of.  They're only
unique for the lifetime of the object, because that's all we need as
programmers.

> There are circumstances where different objects
> get the same ID. Hence, comparing IDs is not equivalent to identity
> testing.

Two objects only get the same ID if one of the objects is dead. The
results of such an comparison are obviously meaningless.  Some
runtimes even try very hard to prevent you from doing such silly
things.

>
> But I was actually referring to something more fundamental than that. The
> statement "a is b" is a *direct* statement of identity. "John is my
> father." "id(a) == id(b)" is *indirect*: "The only child of John's
> grandfather is the parent of the mother-in-law of my sister-in-law" sort
> of thing. (Excuse me if I got the relationships mixed up.)

Again, the fact that you somehow think this absurd family tree is
relevant only shows you're fundamentally confused about what object
oriented identity means.  That's rather depressing, seeing as I've
given you a link to the definition.

In a mathematical sense, you're saying that given f(x) = x+2, using
f(x) is somehow more "direct" (whatever the hell that even means) than
using 'x+2'.  That's just not true.  We freely and openly interchange
them all the time doing mathematics.  Programming is no different.

> It is broken in the sense that "id(a) == id(b)" is to be treated as
> equivalent to "a is b". The above example demonstrates that you CANNOT
> treat them as equivalent.

They give different results, yes, and that's unfortunate.  However, my
code clearly demonstrates they are logically equivalent operations:
the temporaries have different addresses in these cases.  Both
expressions return the correct answer based on their inputs.

Since there are side-effects involved here, you cannot simply compare
the results and conclude they are different.  You must account for the
side-effects, and when you do, then we conclude they have the same
semantics.

> Solution to *what problem*?
>
This confusion that many people have over what 'is' does, including
yourself.

> > An address is an identifier: a number that I can use to access a
> > value[1].
>
> Then by your own definition, Python's id() does not return an address,
> since you cannot use it to access a value.

The fact Python lacks explicit dereferencing doesn't change the fact
that id() returns an address.  Replace 'can' with 'could' or 'could
potentially' or the whole phrase with 'represents' if you wish.  It's
a rather pointless thing to quibble over.

Would you call the result of casting a C pointer to an int an
address?  If so, you must call the result of id() an address as well--
you can't dereference either of them.  If not, then you need to
provide an alternate name for the result of casting a C pointer to an
int.

Adam



More information about the Python-list mailing list