[Python-3000] PEP 3124 - more commentary (original) (raw)
Guido van Rossum guido at python.org
Tue May 15 06:37:27 CEST 2007
- Previous message: [Python-3000] PEP 3124 - more commentary
- Next message: [Python-3000] PEP 3124 - more commentary
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
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/)
- Previous message: [Python-3000] PEP 3124 - more commentary
- Next message: [Python-3000] PEP 3124 - more commentary
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]