[Python-3000] PEP 3124 - more commentary

Guido van Rossum guido at python.org
Tue May 15 06:37:27 CEST 2007


On 5/14/07, Talin <talin at acm.org> wrote:
> Guido van Rossum wrote:
> > Also, can we overload different-length signatures (like in C++ or
> > Java)? This is very common in those languages; while Python typically
> > uses default argument values, there are use cases that don't easily
> > fit in that pattern (e.g. the signature of range()).
>
> Well, from an algorithmic purity standpoint, I know exactly how it would
> work: You put all of the overloads, regardless of number of arguments,
> keywords, defaults, and everything else into a single bin. When you call
> that function, you search through ever entry in that bin and throw out
> all the ones that don't fit, then sort the remaining ones by specificity.
>
> The problem of course is that I don't know how to build an efficient
> dispatch table to do that, and I'm not even sure that it's possible.

Have a look at sandbox/abc/abc.py, class overloadable (if you don't
want to set up a svn workspace, see
http://svn.python.org/view/sandbox/trunk/abc/abc.py). It doesn't
handle keyword args or defaults, but it does handle positional
argument lists of different sizes efficiently, by using a cache
indexed with a tuple of the argument types. The first time a
particular combination of argument types is seen it does an exhaustive
search; the result is then cached. Performance is good assuming there
are many calls but few distinct call signatures, per overloaded
function. (At least, I think it's efficient; I once timed an earlier
implementation of the same idea, and it wasn't too bad. That code is
still in sandbox/overload/.)

Argument default values could be added relatively easily by treating a
function with a default argument value as multiple signatures; e.g.

  @foo.overload
  def _(a:str, b:int=1, c:Point=None): ...

would register these three signatures:

  (str,)
  (str, int)
  (str, int, Point)

Phillip suggested a clever idea to deal with keyword arguments, by
compieing a synthesized function that has the expected signature and
calls the dispatch machinery. I think it would need some adjustment to
deal with variable-length signatures too, but I think it could be made
to work as long as the problem isn't fundamentally ambiguous (which it
may be when you combine different-sides positional signatures with
defaults *and* keywords). The synthetic fuction is just a speed hack;
the same thing can be done without synthesizing code, at the cost
(considerable, and repeated per call) of decoding *args and **kwds
explicitly.

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


More information about the Python-3000 mailing list