Python 3.0, rich comparisons and sorting order

Alex Martelli aleaxit at yahoo.com
Wed Sep 22 09:10:55 CEST 2004


Andrew Dalke <adalke at mindspring.com> wrote:

> Phil Frost wrote:
> > The right question here is, "is there a reason for mappings with
> > heterogeneous key types?" It's not something that I do often, but it's
> > something that's important to have. Dynamic typing is a good thing.
> 
> Though it's a different question.  mapping keys only
> need to define __hash__ and __eq__.  That's easier than
> defining an ordering.

A dict is just one specific kind of mapping, one IMPLEMENTATION of the
mapping interface.  Currently the only built-in one, but definitely not
the only one that can be useful.  A BTree and other order-based
mechanisms might well provide implementations of the mapping interface
that are preferable in some circumstances (e.g., frequent need to access
the sequence of keys in a predictable order).

((Performance may be better with a comparison-based implementation of a
mapping, for example when comparisons may typically be performed WAY
faster than computations of hash values.  Say that the keys are tuples
that tend to be extremely long AND tend to differ within the first few
items.  When such a tuple computes its hash value, it nevertheless needs
to step through all items.  But comparisons between such tuples
typically get solved within the first few items, as soon as
corresponding items that differ are met -- which saves the computational
cost of continuing to step through tuples to the bitter end.))

Prohibiting ordering comparisons between heterogenous types can make
sense only if mappings which have keys of both types are a bad thing,
just like Phil says.  The fact that other implementations of mappings
might still be possible (e.g., a dict) does not per se justify the
prohibition of implementations such as BTrees, which have their own
advantages.

One example I have used are tuples representing expressions.  One such
tuple might be, say:

('+', 'foo', 'bar')

and another might be:

('+', ('*', 'foo', 2), 'bar', 'baz')

I guess these tuples, and their items, would be seen as being
'heterogeneous' by any language mechanism -- they are 'homogeneous' only
at a somewhat abstract level.  Sure, I could wrap such tuples and each
of their 'nodes' (items) into an instance of some darned class which
internally holds an operator and a tuple of operands which can be
numbers, strings (names of free variables), other such nodes.  But one
of Python's advantages used to be the ability to avoid such gyrations in
term of language requirements -- the ability to use direct concrete
representations when appropriate, without the language twisting your arm
to make you wrap them up in order to be able to pass them uniformly as
arguments, use them as keys in a dict OR BTree, etc, etc.  You only did
the wrapping up into abstractions if and when you WANTED to (much like,
say, in Lisp or Scheme -- you start with plain lists, then at some point
you decide that (car expression) is not a good way to access the
operator so you switch to a more abstract (operator-of expression), &c).

Exactly what's gained by forbidding this kind of nice optional usage is
very murky indeed to me.  Why is the "burden of proof" that it IS nice
to have the option of representing expressions this way, for example,
being suddenly placed on the shoulders of those who have long been doing
so, and want to keep that option even when order comparisons are wanted
between such representations?!  Let those who argue it's dangerous and
bad for us, to use concrete representations whenever you may need
comparisons, prove to us why our years-long habit was insane, please...!


Alex



More information about the Python-list mailing list