[Python-3000] Type parameterization (was: Re: Type annotations: annotating generators)

Guido van Rossum guido at python.org
Fri May 19 18:48:39 CEST 2006


On 5/19/06, Collin Winter <collinw at gmail.com> wrote:
> On 5/19/06, Guido van Rossum <guido at python.org> wrote:
> > That's not quite how I did it. list[int] should return another type,
> > not a list instance. Here's a minimal example of what I'm after (truly
> > minimal because it only allows a single parameter named T):
>
> [snip]
>
> I agree that the act of parameterizing dict, list, tuple, set, etc
> will end up returning instances of other types, but I'd like to save
> that particular discussion for later. For now, what do you think of
> the underlying idea of having bracket-based parameterization be
> redirected a call to some double-underscore method (as I outlined
> earlier)?

It feels a little too general for my taste. Have you written a bunch
of those __parameterize__ functions yet? I somehow feel that the
metaclass might want to work a little harder so that the
parameterizable class only has to specify what's unique to it. For
example (not sure this is the right API) I could imagine that a
parameterizable class should only have to do the following:

  class List(list):
      __metaclass__ = ParameterizableClass
      __parameters__ = ["T"]

List[X] would then return a new class C for which C.T is X.

(This is vaguely analogous to __slots__ -- but only vaguely because
it's about the class and not about the instances.)

> I'm trying to give as much flexibility as possible to the annotation
> classes. While simply assigning the parameter to an attribute of the
> new annotation object (here, "newcls.T = arg") works for simple
> examples, I can easily think of cases where the annotation class
> (here, "List") would want to do its own processing:
>
> 1. Classes implementing boolean type expressions (Or, And, Not, Xor,
> etc) might want to try and simplify the expression: Or(int, Or(int,
> float)) simplifies to Or(int, float); And(Not(int), Not(float))
> becomes Not(Or(int, float)); etc.

I'm confused. Are you proposing that Or etc. are classses? How would this work?

I think this may be odd enough that subclassing the metaclass would be
more appropriate. But yo have to explain more what this would do --
I'm not grasping the specifics from your brief examples, to me they
feel like functions, not classes.

> 2. Similarly, annotation classes might want to do more complex
> parameter validation. Or(), for instance, might want to assert that it
> needs at least two distinct parameters (that is, Or(int, int, int)
> simplifies to Or(int), which makes no sense and is an error).

So that's really the same example.

> The reason for putting parameterization into its own double-underscore
> method is to make it easier to for people to incorporate their own
> classes into the type system. Rather than playing metaclass tricks or
> writing a separate class to handle parameterized typechecking, you can
> use the same class name in type expressions as you do in "real" code:
> constructing a BinaryTree instance might look like BinaryTree(5, 6) in
> code, and asserting that it contains only ints would look like
> BinaryTree[int]. To add parameterizability to BinaryTree, all you'd
> have to do is define an appropriate __parameterize__ method.
>
> Not being able to reuse the BinaryTree class like this leads to things
> like CheckBinaryTree(int) or something equally unpleasant.

Agreed. But we need code before we can continue this discussion; I
don't immediately how you get from this argument to making each class
implement its own __parameterize__() method.

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)


More information about the Python-3000 mailing list