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

Brett Cannon brett at python.org
Tue May 1 01:19:06 CEST 2007


On 4/30/07, Phillip J. Eby <pje at telecommunity.com> wrote:
>
> This is just the first draft (also checked into SVN), and doesn't include
> the details of how the extension API works (so that third-party interfaces
> and generic functions can interoperate using the same decorators,
> annotations, etc.).
>
> Comments and questions appreciated, as it'll help drive better
> explanations
> of both the design and rationales.  I'm usually not that good at guessing
> what other people will want to know (or are likely to misunderstand) until
> I get actual questions.
>
>
> PEP: 3124
> Title: Overloading, Generic Functions, Interfaces, and Adaptation
> Version: $Revision: 55029 $
> Last-Modified: $Date: 2007-04-30 18:48:06 -0400 (Mon, 30 Apr 2007) $
> Author: Phillip J. Eby <pje at telecommunity.com>
> Discussions-To: Python 3000 List <python-3000 at python.org>
> Status: Draft
> Type: Standards Track
> Requires: 3107, 3115, 3119
> Replaces: 245, 246
> Content-Type: text/x-rst
> Created: 28-Apr-2007
> Post-History: 30-Apr-2007



[SNIP]



> The ``@overload`` decorator allows you to define alternate
> implementations of a function, specialized by argument type(s).  A
> function with the same name must already exist in the local namespace.
> The existing function is modified in-place by the decorator to add
> the new implementation, and the modified function is returned by the
> decorator.  Thus, the following code::
>
>      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



Doubt there is a ton of use for it, but any way to use this for pattern
matching ala Standard ML or Haskell?  Would be kind of neat to be able to do
recursive function definitions and choose which specific function
implementation based on the length of an argument.  But I don't see how that
would be possible with this directly.  I guess if a SingularSequence type
was defined that overloaded __isinstance__ properly maybe?  I have not
followed the __isinstance__ discussion closely so I am not sure.

[SNIP]


> Proceeding to the "Next" Method
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> If the first parameter of an overloaded function is named
> ``__proceed__``, it will be passed a callable representing the next
> most-specific method.  For example, this code::
>
>      def foo(bar:object, baz:object):
>          print "got objects!"
>
>      @overload
>      def foo(__proceed__, bar:int, baz:int):
>          print "got integers!"
>          return __proceed__(bar, baz)
>
> Will print "got integers!" followed by "got objects!".
>
> If there is no next most-specific method, ``__proceed__`` will be
> bound to a ``NoApplicableMethods`` instance.  When called, a new
> ``NoApplicableMethods`` instance will be raised, with the arguments
> passed to the first instance.
>
> Similarly, if the next most-specific methods have ambiguous precedence
> with respect to each other, ``__proceed__`` will be bound to an
> ``AmbiguousMethods`` instance, and if called, it will raise a new
> instance.
>
> Thus, a method can either check if ``__proceed__`` is an error
> instance, or simply invoke it.  The ``NoApplicableMethods`` and
> ``AmbiguousMethods`` error classes have a common ``DispatchError``
> base class, so ``isinstance(__proceed__, overloading.DispatchError)``
> is sufficient to identify whether ``__proceed__`` can be safely
> called.
>
> (Implementation note: using a magic argument name like ``__proceed__``
> could potentially be replaced by a magic function that would be called
> to obtain the next method.  A magic function, however, would degrade
> performance and might be more difficult to implement on non-CPython
> platforms.  Method chaining via magic argument names, however, can be
> efficiently implemented on any Python platform that supports creating
> bound methods from functions -- one simply recursively binds each
> function to be chained, using the following function or error as the
> ``im_self`` of the bound method.)



Could you change __proceed__ to be a keyword-only argument?  That way it
would match the precedence of class definitions and the 'metaclass' keyword
introduced by PEP 3115.  I personally would prefer to control what the
default is if __proceed__ is not passed in at the parameter level then have
to do a check if it's NoApplicableMethod.

-Brett
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.python.org/pipermail/python-3000/attachments/20070430/9ba16dd0/attachment.htm 


More information about the Python-3000 mailing list