On 4/30/07, Phillip J. Eby <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]>
Discussions-To: Python 3000 List <[email protected]>
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 [EMAIL PROTECTED] 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
_______________________________________________
Python-3000 mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-3000
Unsubscribe:
http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com