[Python-3000] Abilities / Interfaces

Guido van Rossum guido at python.org
Thu Nov 23 18:00:54 CET 2006


Smells a bit like the rejected PEP 245 doesn't it? You should at least
explain how it differs in a summary or rationale.

Anyway, it's Thanksgiving day here, and I'm unlikely to be able to
spend much time on this collection of threads until Monday or so...
And even then I'll have other work to do -- it was a rare opportunity
that I could spend pretty much the entire day reading, thinking and
writing about one topic (if perhaps a little too quick of the
trigger). If you want to save me time, a personal email from Phillip,
Fredrik, Bill or Andrew with a pointer to a proto-PEP that summarizes
a spec that might emerge from the discussion would carry a lot of
weight in my inbox (even if there were 4 competing proto-PEPs :-).
(I'm not suggesting they are the only ones who can write the PEP, but
without an endorsement from a heavyweight I would treat it as just
another post.)

--Guido

On 11/23/06, Dave Anderson <python3000 at davious.org> wrote:
> 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.
> _______________________________________________
> Python-3000 mailing list
> Python-3000 at python.org
> http://mail.python.org/mailman/listinfo/python-3000
> Unsubscribe: http://mail.python.org/mailman/options/python-3000/guido%40python.org
>


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


More information about the Python-3000 mailing list