[Python-3000] Implementations: A syntax for extending method dispatching beyond type/class inheritance
Hasan Diwan
hasan.diwan at gmail.com
Thu Dec 7 16:06:29 CET 2006
The parametrized version of the pass keyword could be used to indicate a
formal interface.
On 07/12/06, Dave Anderson <python3000 at davious.org> wrote:
>
>
> Has-Method Contracts
> --------------------
>
> The first thing I loved about python (coming from java), was this
> realization that I was no longer need be caught up in the inheritance
> game. If I wanted to use an unspoken convention that I could get a
> special string from every object just by defining name() in each of
> those objects, that's all I had to do. It didn't matter which class
> tree it came from.
>
> Looking at the syntax sketch, this can be formalized; but, its a low
> level of formality that fits the context.
>
> # (I used Generic.name in my original post, but that was a mistake.
> # Sorry for my confusion, Phillip)
>
> def get_name(arg: AnyClass.name): # AnyClass will magically have
> return arg.name() # a reference to any method name
> # somehow
>
> further refinement of this would be:
>
> class HasName:
> def name(self):
> ...
>
> def get_name(arg: HasName):
> return arg.name()
>
> but this refinement (in the syntax sketch), would force implementers to
> declare the following implementation:
>
> class X:
> implements HasName
>
> def name(self):
I may be missing something here, but we already have a mechanism for
defining that a object defines certain methods. Could we not keep it
orthogonal and have, e. g.:
class super():
def __init__(self): pass
def typeOfSuper(self): pass(subclass)
The way pass is defined now would remain the default. A new builtin pass()
would be added to support your notion of interfaces.
Has Class-specific Method Contracts
> -----------------------------------
>
> Similar to Has-Method Contracts are class-specific method contracts.
> This is when you use a well-defined class as a way to indicate the
> context of a method and separate it from homonyms.
>
> def add_key_value_pair(arg: MutableContainer.add, key, value):
> arg[key] = value
def __add__(self, onemore):
MutableContainer.add (self, onemore.key, onemore.value):
If you need more than one function to implement '+', you can use two
classes.
> Implement (As a) vs Inherit (Is a)
> ----------------------------------
>
> This is nuanced.
> Basically, if I have some object Car and I want to be able to use it
> like a dict, I don't necessarily consider it inheriting from dict (or
> even UserDict). That is, I don't think a Car is a dict.
>
> To me, even if Car happens to represent a dict by being able to be used
> as a dict, the expression of this fact feels better expressed as merely
> implementing dict.
>
> compare:
>
> class Car(dict): # car... is a dict? hmm, a bad ring to it
> ...
>
> class Car:
> implements dict # oh, Cars can be used like a dict, got it
> ...
>
> In addition to that subjective differentiation, there is a technical
> argument. Without something like an implements declaration, if I ever
> want to express a relationship to another class, but with different
> internals, I am forced to first define an abstract class and then
> inherit from that. With an implements declaration, I can say implements
> dict and be free of inheriting any of its internal implementation.
>
> (I concede here that I could, in fact, inherit UserDict, override all
> the methods, and just not call super in my init.)
>
> Even with the nicely done ABCs, is there an easy way for a class to
> declare that it can be used like a dict with its own implementation of
> dict methods? With this syntax sketch, UserDict would remain the same
> except:
>
> class UserDict:
> implements dict # dispatch can rely on this declaration
> ... # rather than method-checking
>
>
> The Consequences of Going Outside of the Hierarchy
> --------------------------------------------------
>
> For all the above reasons, I want to see python support something more
> flexible than type-based dispatching. We can look at the method-scoped
> units of Implementations as a limited version of Guido's Abilities, and
> we can look at the class-scoped implementations as types, or classes, or
> also as abstract interfaces from concrete classes.
>
> Unfortunately, I am now outside of the hierarchy tree; an implementation
> tree would be a superset of a class's hierarchy tree. I suppose that
> using dispatch this way is more complex compared to a strict class-based
> set of relationships (because I am asking for checks not just on the
> class-tree, but also on the implementations off that class-tree); but,
> I'd rather fold current python usage into a future of type /
> protocol-aware methods than force current pythonists into choosing
> between class or no class, to type or not to type.
>
>
> (Small Caveat:) Using Implementations as a Development Tool
> ------------------------------------------------------------
>
> Btw, if we formally differentiate that I'm declaring an implementation
> (versus inherit and override), I could programatically double-check my
> implementation with tools...
>
> class A:
> implements Container
>
> def len(self)
> ...
>
> >>> interface_compliance(A)
This would just scan for a parametrised "pass" keyword and check that all
subclasses inheriting from it implemented that method.
(If I missed the gist of these questions. Please forgive me and clarify
> them for me.)
>
Ditto for me.
--
Cheers,
Hasan Diwan <hasan.diwan at gmail.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.python.org/pipermail/python-3000/attachments/20061207/e0f01890/attachment.html
More information about the Python-3000
mailing list