[Python-3000] Abilities / Interfaces
Dave Anderson
python3000 at davious.org
Thu Nov 23 13:14:59 CET 2006
Proposal Summary
================
Add 2 new keywords: implements, implement
(alternatively, implements and implement can be implemented as object
level functions)
Add new built-in function: interface
Add new object level function: does_implement
Interfaces
==========
There is a fight between using classes/types for dispatch verses class
methods for dispatch. There is a fight between declaring class
compatibility and declaring method compatibility.
We see this explicit declaration in Phillip's
defop iter(self):
versus method checking
We should unify these concepts by allowing them to mix in an interface
definition:
Interfaces, here, are a set of class types, class methods/attributes,
and strings
* Class/Type: Can be built-in or user-defined
when Class2 declares it implements Class1, we will presume
the class will support anything Class1 will support, but will only
crash on a call to a method Class1 has, but Class2 does not
* Class Method/Attribute: Can be from a built-in object or be
user-defined class
when Class2 declares it implements a Class1.amethod, we will
presume the class as a method amethod, but will only crash on a call
to Class2.amethod if Class2.amethod is not defined.
* String: Indicates a method or attribute with that name, introspection
is used to see if a Class implements this
iter_interface = interface(iter) # class-based interface
file_open_close_inter = interface(file.open, file.close) # method interface
# here is an interface looking for both a class and some methods to be
'implemented'
iter_file_open_close_inter = interface(iter, file.open, file.close)
Implementation of Interfaces (Implements and Implement)
=======================================================
In the common case, a class already implements another class behavior
and we just need to say that.
Other times, we want to adapt or use a special method in a certain context.
Implement and Implement:
* Implements: Declares pre-existing computability
It is a list of classes/types and class methods/attributes
when Class2 declares it implements Class1, we will presume
the class will support anything Class1 will support, but will
only crash on a call to a method Class1 has, but Class2 does not
* Implement: Indicates special method-help via adaptation or a different
method.
The keyword is used to define a function that acts as a class/type
adapter or special function.
when Class2 declares it implements a Class1.amethod, we will
presume the class as a method amethod, but will only crash
on a call to Class2.amethod if Class2.amethod is not defined.
Class's declared to be implemented are presumed to have the full method
set of the class, those reducing the need for extensive method checking
at the adult-allowable risk of someone not completely implementing the
classes methods. (Of course, we now have implementation declaration
inspection of a sort.)
Dispatching by Interface and Declared Implementation
=====================================================
the example Bar class (following these dispatching examples) should be
able to be dispatched by
* methods looking for a iter, Foo, SomeOtherClass, YetAnotherClass instances
example: def funct(iter_var: iter):
* methods looking for a method of those classes
example: def funct(var_that_implements_foo_or_declares_a_foo_method:
Foo.method):
* methods looking for methods file.open, file.close, AnotherClass.close
example: def funct(var_with_a_method_like_file_open: file.open):
* methods looking for just method of with a particular name
example: def funct(var_with_a_method_called_open: "open"):
the dispatch need not be based on a singular type or method
(see below for those multi-condition interface examples)
also, these dispatch functions can be class functions
example def funct(self, var_with_a_file_open_meth: file.open):
Example of Using Implements and Implement
=========================================
class Bar(Foo):
"""based on the declarations that follow class is taken as iter, Foo,
and SomeOtherClass without method introspection (return of self for
these is implicit) methods open and close are understood to be file like
methods. An adaption functionality is available in the declaration
implement AnotherClass and special method as a particular class is
available in the declaration implement
YetAnotherClass.method."""
# new keyword implements
implements iter, SomeOtherClass, file.open, file.close
# new keyword implement: for class adaptation
implement AnotherClass(self):
return transform_to_yac(self)
implement YetAnotherClass.open(self, var):
return different_open_function(self, var)
# presumed for file.open
def open(self):
# presumed for file.close
def close(self):
[implementing iter functions not shown]
Interface objects, including multiple object apis
===================================================
* use of new standard interface function
* allows multiple interface apis to be combined
foo_interface = interface(Foo)
iter_interface = interface(iter)
file_open_close_interface = interface(file.open, file.close)
any_open_close_interface = interface("open", "close")
iter_file_open_close_inter = interface(iter, file_open_close_interface)
def funct(foo_var: Foo):
.. equivalent to ..
def funct(foo_var: foo_interface):
def funct(iter_var: iter):
.. equivalent to ..
def funct(iter_var: iter_interface):
def funct(file_like_var: file.open, file.close):
.. equivalent to ..
def funct(file_like_var: file_open_close_interface):
def funct(method_abilities_var: "open", "close"):
.. equivalent to ..
def funct(method_abilities_var: just_open_close_methods_interface):
def funct(method_abilities_var: iter, file.open, file.close):
.. equivalent to ..
def funct(method_abilities_var: iter_file_open_close_inter):
does_implement
==============
* does_implement: a boolean function that at the object level that
returns true if the object has declared that it implements an
interface object
if obj.does_implement(iter):
if obj.does_implement(Class1):
if obj.does_implement(interface_obj):
Implementing Interfaces without the keywords Implements, Implement
==================================================================
Class2.implements(iter)
Class2.implements(Class1)
Class2.implements(interface_obj)
Class2.implements(file.open)
Class2.implements(iter, Class1, interface_obj, file.open)
Class2.implement(Class1, transform_function_def)
Class2.implement(Class1.method, function_def)
Dispatching Issues
==================
There will have to be some way to decide which declarations are chosen
ahead of others, but I haven't thought about that too much.. we'd
probably look at the order of the objects in the implements statement.
The last issue I have in my head is Guido's issue
> This doesn't do anything for other generic functions that might also
> conceivably work with C. Phillip addresses that by proposing help
> functions that do a bunch of these bindings at once, and by noticing
> that if you just use the standard library and generic functions, the
> default implementation might just work.
But, it think those bindings could be generated with some *implements*
declarations inside of standard objects like Iterable - Collection -
Sequence - MutableSequence - list to each other. These declarations
will be inherited by those object which declare they implement them.
With this syntax, dispatch functions would seamlessly integrate with the
current python language, the absence of any interface in a function def
would be the python language as it works now, by defaulting to the
lowest and most-likely only "dispatching" function.
More information about the Python-3000
mailing list