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...@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!) Given the language semantics of Python, "id(a) == id(b)" is NOT equivalent to "a is b" since the built-in id() function can be shadowed by some other function at runtime, but the "is" operator cannot be. An extremely clever optimizing implementation like PyPy may be able to recognise at runtime that the built-in id() is being called, but that doesn't change the fact that PyPy MUST support this code in order to claim to be a Python compiler: id = lambda x: 999 id(None) == id("spam") # returns True If your runtime doesn't allow that, it isn't Python. >> 2) The "is" operator always has the exact same semantics and cannot be >> overridden. The id() function can be monkey-patched. >> >> > I can't see how that's useful at all. Identity is a fundamental > property of an object; hence retrieval of it must be a language > operation. The fact Python chooses to do otherwise is unfortunate, but > also irrelevant to my position. 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. >> 3) The "is" idiom semantics is direct: "a is b" directly tests the >> thing you want to test, namely whether a is b. The id() idiom is >> indirect: "id(a) == id(b)" only indirectly tests whether a is b. > > The two expressions are logically equivalent, so I don't see how this > matters, nor how it is true. 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. My library card ID may, by coincidence, match your drivers licence ID. Doesn't mean we're the same person. Entities may share identities, or may have many identities. The Borg design pattern, for example, would be an excellent candidate for ID:identity being treated as many-to-one. 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. There are circumstances where different objects get the same ID. Hence, comparing IDs is not equivalent to identity testing. 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.) >> 4) The id() idiom already breaks if you replace names a, b with >> expressions: >> >> >>> id([1,2]) == id([3,4]) >> True > > It's not broken at all. 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. [...] > The other solution is to do what Java and C# do: banish id() entirely Solution to *what problem*? I do not believe that there is a problem here that needs to be solved. Both id() and "is" are perfectly fine for what they do. >> But that's absolutely wrong. id(x) returns an ID, not an address. It >> just >> happens that, as an accident of implementation, the CPython interpreter >> uses the object address as an ID, because objects can't move. That's >> not the case for all implementations. In Jython, objects can move and >> the address is not static, and so IDs are assigned on demand starting >> with 1: >> >> steve@runes:~$ jython >> Jython 2.5.1+ (Release_2_5_1, Aug 4 2010, 07:18:19) [OpenJDK Client VM >> (Sun Microsystems Inc.)] on java1.6.0_18 Type "help", "copyright", >> "credits" or "license" for more information.>>> id(42) 1 >> >>> id("Hello World!") >> 2 >> >>> id(None) >> >> 3 >> >> > 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. -- Steven -- http://mail.python.org/mailman/listinfo/python-list