From: Marcin 'Qrczak' Kowalczyk Date: 2002-10-01T00:05:23+09:00 Subject: Re: Where Is Method Call Precedence? Mon, 30 Sep 2002 22:16:37 +0900, William Djaja Tjokroaminata pisze: > Everything below is "obvious" and natural, isn't it? That's why > I don't understand why Python does not allow mutable object to be > used as a hash/dictionary key in the first place. It's not obvious that a Ruby hash doesn't put given objects as keys but their duplicates. In Python it puts the keys as given (strings and tuples are immutable so it would be a waste of time and memory to make duplicates). I think the difference between Python and Ruby is more philosophical than technical, i.e. there mutable and immutable objects are technically about the same. Technically "immutable" means that there is no operation provided which changes the state of the object. Philosophically it means that the object's identity is an artifact of the implementation and shouldn't be taken into account, only the value matters. It implies that passing them by reference and by value is the same. All immutable objects of some kind with the given value are equivalent. The implementation is free to merge or disjoin representations of immutable objects when it wants. In Ruby any object can be frozen. In Python immutable and mutable types are usually separate: mutability is not an attribute of an object but a property of its type. (User-defined classes are not formally classified, only intentionally.) Python doesn't enforce the consistency of treatment of these kinds of objects: it allows to compare identity of immutable objects like numbers (with unspecified results when objects are equal) and it allows to use user-defined objects as keys of hashes, hoping that their hash and equality relations won't change over time. Python tuples are different from lists (i.e. really arrays but python calls them lists) also in this respects: tuples are usually heterogeneous and of a fixed length, i.e. the length is usually statically known in places they are used; lists are usually homogeneous and of variable length. Tuples are represented more efficiently than lists: #define PyObject_HEAD \ int ob_refcnt; \ struct _typeobject *ob_type; #define PyObject_VAR_HEAD \ PyObject_HEAD \ int ob_size; /* Number of items in variable part */ typedef struct { PyObject_VAR_HEAD PyObject *ob_item[1]; } PyTupleObject; // Allocated with the additional space for elements. typedef struct { PyObject_VAR_HEAD PyObject **ob_item; } PyListObject; // Capacity is implied by rounded size. -- __("< Marcin Kowalczyk \__/ qrczak@knm.org.pl ^^ http://qrnik.knm.org.pl/~qrczak/