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

Terry Reedy tjreedy at udel.edu
Sun Apr 22 21:22:10 EDT 2012


On 4/22/2012 3:43 PM, John Nagle wrote:
> On 4/20/2012 9:34 PM, john.tantalo at gmail.com wrote:
>> On Friday, April 20, 2012 12:34:46 PM UTC-7, Rotwang wrote:
>>
>>> I believe it says somewhere in the Python docs that it's undefined and
>>> implementation-dependent whether two identical expressions have the same
>>> identity when the result of each is immutable
>
> Bad design. Where "is" is ill-defined, it should raise ValueError.

There is no ambiguity about the meaning of 'is' in Python. It is always 
well-defined. So the suggestion is a nullity. The equivalent function 
form in Python is

def is(a, b):
   return id(a) == id(b)

It is important here that the expressions corresponding to both a and b 
are evaluated and the resulting objects bound to names a and b first and 
that they are not unbound and possibly destroyed until after the return 
is computed.

The inline form of the function call is

__tem1__ = a
__tem2__ = b
result = id(a) == id(b)
del __tem1__, __tem2__

Leaving out the temporaries is a (common) mistake, but it changes the 
meaning.

The id(object) function is also well-defined: it is the immutable 
internal integer id assigned to the object upon creation by the 
interpreter. The interpreter may use that internal number to associate 
names with object and to find objects given a name, but how it does do 
is up to the interpreter. In any case, the return value is always the 
same for a given object. That is the meaning of 'well-defined'.

Python is an object-based language. Its objects have identity, class, 
and value. Most functions in Python are *value* functions. The result is 
independent of object id. However, id is an *object* function. It is, in 
fact, the basic object function. Class and value can change for some 
objects, but identity never does. Identity is independent of class and 
value and not predictable from them.

I believe you are confusing 'unpredictable from other, uncorrelated 
object attributes' with 'ill-defined'.

If you want 'ill-defined', consider the other comparison operators, 
which can be redefined in user subclasses. For such comparisons, a op b 
may not be the same as b op a. The use of 'is' in production code is to 
be a predictable comparison operator. That way, we can write 'if a is 
None:' rather than having to write 'if None is a:' to ensure getting the 
expected and desired result.

>  >>> a = 256
>  >>> b = 256
>  >>> a is b
> True # this is an expected result

'Expected' is in the mind of the designer or beholder.

>  >>> a = 257
>  >>> b = 257
>  >>> a is b
> False

The other use of 'is' and 'id' is to reveal and test implementation details.

> Operator "is" should be be an error between immutables
> unless one is a built-in constant.

The CPython-specific part of the Python test suite has test like the 
above to test such implementation details. Do you really want to disable 
that and make it impossible ;-?

> "True" and "False"  should be made hard constants, like "None".

The developers agree, and did exactly this about 3 years ago.

> You can't assign to None, but you can assign to True, usually with
> unwanted results.

Not any more, except in 2.x, for back compatibility.

> It's not clear

It is completely clear and has been discussed here many times.

> why True and False weren't locked down when None was.

Are you really unaware that before False and True were added officially, 
many people routinely wrote in their code:
False, True = 0, 1
and that locking the names, when it was done in 3.0, broke such code?
And that is was not done earlier to avoid breaking code earlier, in 
accordance with the general policy to mostly avoid such breakage?

-- 
Terry Jan Reedy




More information about the Python-list mailing list