[Python-Dev] type categories

David Abrahams David Abrahams" <dave@boost-consulting.com
Sat, 24 Aug 2002 07:33:41 -0400

From: "Guido van Rossum" <guido@python.org>

> > If we don't have the separate interface concept, the language just
> > isn't as expressive.  We would have to establish a convention to
> > sacrifice one of -- a) being able to inherit from a class just for
> > implementation purposes or b) being able to reason about interfaces
> > using isinstance().  a) is error prone, because the language
> > wouldn't prevent anyone from making the mistake.  b) is unfortunate,
> > because we'd have interfaces but no formal way to reason about them.
> So the point is that it's possible to have a class D that picks up
> interface I somewhere in its inheritance chain, by inheriting from a
> class C that implements I, where D doesn't actually satisfy the
> invariants of I (or of C, probably).


>     def foo(a: classA, b: classB):
>         ...body...
> It would be convenient if this could be *defined* as
>     assert isinstance(a, classA) and isinstance(b, classB)
> so that programs that have a simple class hierarchy can use their
> classes directly as argument types, without having to go through the
> trouble of declaring a parallel set of interfaces.
> I also think that it should be possible to come up with a set of
> standard "abstract" classes representing concepts like number,
> sequence, etc., in which the standard built-in types are nicely
> embedded.

Ah, but not all numbers are created equal! Can I write:

    x << 1

? Not if x is a float. Somebody will eventually want to categorize numeric
types more-finely, e.g. Monoid, Euclidean Ring, ...

It sounds to my C++ ear like you're trying to make this analogous to
runtime polymorphism in C++. I think Python's polymorphism is a lot closer
to what we do at compile-time in C++, and it should stay that way: no
inheritance relationship needed... at least, not on the surface. Here's
why: people inevitably discover new type categories in the objects and
types they're already using. In C++ this happened when Stepanov et al
discovered that built-in pointers matched his mental model of random-access
iterators. A similar thing will happen in Python when you make all numbers
inherit from Number but someone wants to impose the real mathematical
categories (or heck: Integer vs. Fractional) on them.

What Stepanov's crew did did was to invent iterator traits, which decouple
the type's category from the type itself. Each category is represented by a
class, and those classes do have an inherticance relationship (i.e. every
random_access_iterator IS-A bidirectional_iterator). Actually, I have no
problem with collecting type category info from an object's MRO: as Guido
implies, that will often be the simplest way to do it. However, I think
there ought to be a parallel mechanism which allows additional
categorization non-intrusively, and it was my understanding that the PEP
Alex has been promoting does that.


           David Abrahams * Boost Consulting
dave@boost-consulting.com * http://www.boost-consulting.com