[Python-3000] Abilities / Interfaces

Phillip J. Eby pje at telecommunity.com
Wed Nov 22 20:32:58 CET 2006


At 10:31 AM 11/22/2006 -0800, Guido van Rossum wrote:
>In *my* notion of abilities, this part being inspired by Zope
>interfaces, you can state after the fact that a particular class
>(which you didn't write) provides a given ability (which you didn't
>write either). I think it would also be great if we had "ability
>algebra" whereby you could state that a given ability A is composed of
>existing abilities A1 and A2, and every object or class that already
>has A1 and A2 will automatically be considered to have A.
>
>However, I do *not* want to go the way of duck typing here -- if an
>ability A claims that it is implemented by method foo(), and an object
>x has a foo() method but doesn't explicitly claim to have ability A
>(and neither does its class), then testing x for A should return
>false. I think this deviates from Haskell, which seems to be big on
>structural type equivalence (?).
>
>So I think Python needs to do its own thing here, to some extent.

Actually, you just described Haskell typeclasses.  :)  That is, they are:

1. Able to be specified after the fact
2. Are algebraically defined as sets of operations
3. Strongly typed based on functions

With respect to #3, I think you are confusing Haskell function names with 
Python method names.  Typeclasses also have one more ability that you 
didn't include above:

4. Able to provide implementations after the fact, not merely declarations

This is basically the same concept as adaptation and generic functions, so 
that you can not only *declare* that a type meets an interface, but also 
provide a way to make it work.

So, we are in agreement on some basics, I think.  I am mainly concerned 
that we do not treat interfaces as collections of method names, rather than 
collections of operations.  (Attributes can be considered operations to 
read, write, or delete them, and in many cases you will want to specify 
those operations individually in an interface/typeclass).

In Haskell, however, it is not that common for ordinary code to define or 
use typeclasses, since direct use of the operations (e.g. len()/iter() 
equivalents) normally suffices to imply the typeclass(es) involved.  Also, 
like Java, Haskell selects overloaded implementations based on their 
argument type, so you don't write "if isinstance" tests either.

Generics reduce the need for type testing and explicit interfaces, since 
you can just use an operation rather than needing a method (as in Haskell) 
or you can define overloads to select an implementation (as in Java).

In Python, however, interface libraries have historically treated their 
operations as simply a bag of method names and call signatures, which 
doesn't allow algebraic operations and introduces the need for explicit 
adapter types.  In contrast, an operation-based approach (where interfaces 
are collections of first-class "operations" of some kind, that can be 
recombined to create new interfaces) allows both interface algebra and 
*automatic* adapter generation (as described in my "monkey typing" proposal 
early last year).



More information about the Python-3000 mailing list