<br><br><div><span class="gmail_quote">On 4/30/07, <b class="gmail_sendername">Phillip J. Eby</b> &lt;<a href="mailto:pje@telecommunity.com">pje@telecommunity.com</a>&gt; wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
This is just the first draft (also checked into SVN), and doesn&#39;t include<br>the details of how the extension API works (so that third-party interfaces<br>and generic functions can interoperate using the same decorators,
<br>annotations, etc.).<br><br>Comments and questions appreciated, as it&#39;ll help drive better explanations<br>of both the design and rationales.&nbsp;&nbsp;I&#39;m usually not that good at guessing<br>what other people will want to know (or are likely to misunderstand) until
<br>I get actual questions.<br><br><br>PEP: 3124<br>Title: Overloading, Generic Functions, Interfaces, and Adaptation<br>Version: $Revision: 55029 $<br>Last-Modified: $Date: 2007-04-30 18:48:06 -0400 (Mon, 30 Apr 2007) $<br>
Author: Phillip J. Eby &lt;<a href="mailto:pje@telecommunity.com">pje@telecommunity.com</a>&gt;<br>Discussions-To: Python 3000 List &lt;<a href="mailto:python-3000@python.org">python-3000@python.org</a>&gt;<br>Status: Draft
<br>Type: Standards Track<br>Requires: 3107, 3115, 3119<br>Replaces: 245, 246<br>Content-Type: text/x-rst<br>Created: 28-Apr-2007<br>Post-History: 30-Apr-2007</blockquote><div><br><br>[SNIP]<br>&nbsp;</div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>The ``@overload`` decorator allows you to define alternate<br>implementations of a function, specialized by argument type(s).&nbsp;&nbsp;A<br>function with the same name must already exist in the local namespace.<br>The existing function is modified in-place by the decorator to add
<br>the new implementation, and the modified function is returned by the<br>decorator.&nbsp;&nbsp;Thus, the following code::<br><br>&nbsp;&nbsp;&nbsp;&nbsp; from overloading import overload<br>&nbsp;&nbsp;&nbsp;&nbsp; from collections import Iterable<br><br>&nbsp;&nbsp;&nbsp;&nbsp; def flatten(ob):
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;&quot;&quot;Flatten an object to its component iterables&quot;&quot;&quot;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; yield ob<br><br>&nbsp;&nbsp;&nbsp;&nbsp; @overload<br>&nbsp;&nbsp;&nbsp;&nbsp; def flatten(ob: Iterable):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for o in ob:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ob in flatten(o):
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; yield ob<br><br>&nbsp;&nbsp;&nbsp;&nbsp; @overload<br>&nbsp;&nbsp;&nbsp;&nbsp; def flatten(ob: basestring):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; yield ob</blockquote><div><br><br>Doubt there is a ton of use for it, but any way to use this for pattern matching ala Standard ML or Haskell?&nbsp; 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.&nbsp; But I don&#39;t see how that would be possible with this directly.&nbsp; I guess if a SingularSequence type was defined that overloaded __isinstance__ properly maybe?&nbsp; I have not followed the __isinstance__ discussion closely so I am not sure.
<br>&nbsp;</div>[SNIP]<br><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><br>Proceeding to the &quot;Next&quot; Method<br>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<br><br>If the first parameter of an overloaded function is named<br>``__proceed__``, it will be passed a callable representing the next<br>most-specific method.&nbsp;&nbsp;For example, this code::<br><br>&nbsp;&nbsp;&nbsp;&nbsp; def foo(bar:object, baz:object):
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print &quot;got objects!&quot;<br><br>&nbsp;&nbsp;&nbsp;&nbsp; @overload<br>&nbsp;&nbsp;&nbsp;&nbsp; def foo(__proceed__, bar:int, baz:int):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print &quot;got integers!&quot;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return __proceed__(bar, baz)<br><br>Will print &quot;got integers!&quot; followed by &quot;got objects!&quot;.
<br><br>If there is no next most-specific method, ``__proceed__`` will be<br>bound to a ``NoApplicableMethods`` instance.&nbsp;&nbsp;When called, a new<br>``NoApplicableMethods`` instance will be raised, with the arguments<br>passed to the first instance.
<br><br>Similarly, if the next most-specific methods have ambiguous precedence<br>with respect to each other, ``__proceed__`` will be bound to an<br>``AmbiguousMethods`` instance, and if called, it will raise a new<br>instance.
<br><br>Thus, a method can either check if ``__proceed__`` is an error<br>instance, or simply invoke it.&nbsp;&nbsp;The ``NoApplicableMethods`` and<br>``AmbiguousMethods`` error classes have a common ``DispatchError``<br>base class, so ``isinstance(__proceed__, 
overloading.DispatchError)``<br>is sufficient to identify whether ``__proceed__`` can be safely<br>called.<br><br>(Implementation note: using a magic argument name like ``__proceed__``<br>could potentially be replaced by a magic function that would be called
<br>to obtain the next method.&nbsp;&nbsp;A magic function, however, would degrade<br>performance and might be more difficult to implement on non-CPython<br>platforms.&nbsp;&nbsp;Method chaining via magic argument names, however, can be<br>efficiently implemented on any Python platform that supports creating
<br>bound methods from functions -- one simply recursively binds each<br>function to be chained, using the following function or error as the<br>``im_self`` of the bound method.)</blockquote><div><br><br>Could you change __proceed__ to be a keyword-only argument?&nbsp; That way it would match the precedence of class definitions and the &#39;metaclass&#39; keyword introduced by PEP 3115.&nbsp; 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&#39;s NoApplicableMethod.
<br>&nbsp;</div>-Brett</div>