[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