[Python-3000] PEP 3124 - Overloading, Generic Functions, Interfaces, etc.

Steven Bethard steven.bethard at gmail.com
Wed May 9 22:41:14 CEST 2007


On 4/30/07, Phillip J. Eby <pje at telecommunity.com> wrote:
> PEP: 3124
> Title: Overloading, Generic Functions, Interfaces, and Adaptation
[snip]
>      from overloading import overload
>      from collections import Iterable
>
>      def flatten(ob):
>          """Flatten an object to its component iterables"""
>          yield ob
>
>      @overload
>      def flatten(ob: Iterable):
>          for o in ob:
>              for ob in flatten(o):
>                  yield ob
>
>      @overload
>      def flatten(ob: basestring):
>          yield ob
[snip]
> ``@overload`` vs. ``@when``
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> The ``@overload`` decorator is a common-case shorthand for the more
> general ``@when`` decorator.  It allows you to leave out the name of
> the function you are overloading, at the expense of requiring the
> target function to be in the local namespace.  It also doesn't support
> adding additional criteria besides the ones specified via argument
> annotations.  The following function definitions have identical
> effects, except for name binding side-effects (which will be described
> below)::
>
>      @overload
>      def flatten(ob: basestring):
>          yield ob
>
>      @when(flatten)
>      def flatten(ob: basestring):
>          yield ob
>
>      @when(flatten)
>      def flatten_basestring(ob: basestring):
>          yield ob
>
>      @when(flatten, (basestring,))
>      def flatten_basestring(ob):
>          yield ob
[snip]

+1 on @overload and @when.


> Proceeding to the "Next" Method
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[snip]
> "Before" and "After" Methods
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[snip]
> "Around" Methods
> ~~~~~~~~~~~~~~~~
[snip]
> Custom Combinations
> ~~~~~~~~~~~~~~~~~~~

I'd rather see all this left as a third-party library to start with.
(Yes, even including __proceed__.)  It shouldn't be a problem to
supply these things separately, right?


> Interfaces and Adaptation
> -------------------------
>
> The ``overloading`` module provides a simple implementation of
> interfaces and adaptation.  The following example defines an
> ``IStack`` interface, and declares that ``list`` objects support it::
>
>      from overloading import abstract, Interface
>
>      class IStack(Interface):
>          @abstract
>          def push(self, ob)
>              """Push 'ob' onto the stack"""
>
>          @abstract
>          def pop(self):
>              """Pop a value and return it"""
>
>
>      when(IStack.push, (list, object))(list.append)
>      when(IStack.pop, (list,))(list.pop)
>
>      mylist = []
>      mystack = IStack(mylist)
>      mystack.push(42)
>      assert mystack.pop()==42
>
> The ``Interface`` class is a kind of "universal adapter".  It accepts
> a single argument: an object to adapt.  It then binds all its methods
> to the target object, in place of itself.  Thus, calling
> ``mystack.push(42``) is the same as calling
> ``IStack.push(mylist, 42)``.

+1 on adapters like this.

> Interfaces as Type Specifiers
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> ``Interface`` subclasses can be used as argument annotations to
> indicate what type of objects are acceptable to an overload, e.g.::
>
>      @overload
>      def traverse(g: IGraph, s: IStack):
>          g = IGraph(g)
>          s = IStack(s)
>          # etc....

and +1 on being able to specify Interfaces as "types".

> Aspects
> -------
[snip]
>      from overloading import Aspect
>
>      class Count(Aspect):
>          count = 0
>
>      @after(Target.some_method)
>      def count_after_call(self, *args, **kw):
>          Count(self).count += 1

Again, I'd rather see this kind of thing in a third-party library.


Summary of my PEP thoughts:
* Keep things simple: just @overload, @when, @abstract and Interface.
* More complex things like __proceed__, @before, @after, Aspects, etc.
should be added by third-party modules

As others have mentioned, the current PEP is overwhelming. I'd rather
see Py3K start with just the basics. When people are comfortable with
the core, we can look into introducing the extras.

STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


More information about the Python-3000 mailing list