Death to tuples!

Mike Meyer mwm at mired.org
Mon Nov 28 15:53:38 EST 2005


Peter Hansen <peter at engcorp.com> writes:
> Mike Meyer wrote:
>> It seems that the distinction between tuples and lists has slowly been
>> fading away. What we call "tuple unpacking" works fine with lists on
>> either side of the assignment, and iterators on the values side. IIRC,
>> "apply" used to require that the second argument be a tuple; it now
>> accepts sequences, and has been depreciated in favor of *args, which
>> accepts not only sequences but iterators.
>> Is there any place in the language that still requires tuples instead
>> of sequences, except for use as dictionary keys?
> Would it be possible to optimize your "frozenlist" so that the objects
> would be created during compilation time and rather than only during
> runtime?  If not then tuples() have a distinct performance advantage
> in code like the following where they are used as local constants:

No, because I want to change the definition.

Tuples have the problem that they are immutable, except when they're
not (or for proper values of immutable, your choice). They're
hashable, except when they're not. Or equivalently, they can be used
as dictionary keys - or set elements - except when they can't.

I want frozenlists to *not* be that way. A frozenlist should *always*
be valid as a dictionary key. This changes the semantics significantly
- and means that creating a frozenlist from a list could be very
expensive.

Doing this requires extending the "frozen" concept, adding two new
types, a new magic method, and maybe a new builtin function.

Right now, a "frozenset" is always valid as a dictionary key. The concept
extension is to provide facilities to freeze nearly everything.

New types:
    frozenlist: a tuple with count/index methods, and the constraint
                that all the elements are frozen.
    frozendict: A dictionary without __setitem__, and with the constraint
                that all values stored in it are frozen.

New magic method: __freeze__(self): returns a frozen version of self.

Possibe new builtin:
        freeze(obj) - returns the frozen form of obj. For lists, it
        returns the equivalent frozenlist; for a set, it returns the
        equivalent frozenset. For dicts, it returns the equivalent
        frozendict. For other built-ins, it returns the original object.
        For classes written in Python, if the instance has __freeze__, it
        returns the result of calling that. Otherwise, if the instance
        has __hash__, or does not have __cmp__ and __eq__ (i.e. - if
        the class is hashable as is), it returns the instance. If all
        of that fails, it throws an exception. While not strictly
        required, it appears to be handy, and it makes thinking about
        the new types much less simler.

You can't always create a frozenlist (or frozendict) at compile time. I.e.:

a = []
foo(a)
fa = frozenlist([a])

You don't know at compile time what a is going to be. Since you can't
change the frozenlist after creation, you have to wait until you know
the value of a to create fa.

This version is *not* suitable as an alias for tuple. It might work as
a replacement for tuple in Py3K, but a number of issues have to be
worked out - most notable tuple packing. % on strings is easy - you
make it accept either a list or a frozenlist (or, if we're going to
change it, maybe an arbitary sequence). But tuple unpacking would need
some real work. Do we blow off the comma syntax for creating tuples,
and force peole to write real lists? Doesn't seem like  a good idea to
me.

        <mike
-- 
Mike Meyer <mwm at mired.org>			http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.



More information about the Python-list mailing list