[Python-3000] PEP 3124 - more commentary

Phillip J. Eby pje at telecommunity.com
Tue May 15 03:45:25 CEST 2007


At 05:51 PM 5/14/2007 -0700, Guido van Rossum wrote:
>On 5/14/07, Phillip J. Eby <pje at telecommunity.com> wrote:
>>At 05:17 PM 5/14/2007 -0700, Guido van Rossum wrote:
>> >Other use cases that come to mind are e.g. APIs that you can pass
>> >either a Point object or two (or three!) floats. This is not a natural
>> >use case for argument default values, and it's not always convenient
>> >to require the user to pass a tuple of floats (perhaps the
>> >three-floats API already existed and its signature cannot be changed
>> >for compatibility reasons). Or think of a networking function that
>> >takes either a "host:port" string or a host and port pair; thinking of
>> >this as having a default port is also slightly awkward, as you don't
>> >know what to do when passed a "host:port" string and a port.
>>
>>How do people handle these in Python now?  ISTM that idiomatic Python
>>for these cases would either use tuples, or else different method names.
>
>Both of which are sub-optimal compared to the C++ and Java solutions.

C++ and Java don't have tuples, do they?

The open(filename="...") example you gave doesn't bother me in the 
least, but when I see range()-style APIs, I cringe.  However, since 
this is a matter of taste, I yield to the BDFL.


>>That having been said, if you want it, there's probably a way to make
>>it work.  I just think we should try to preserve the "nameness" of
>>arguments in the process -- and consider whether the use cases you've
>>listed here actually improve the code clarity any.
>
>There seems to be a stalemate. It seems I cannot convince you that
>this type of overloading is useful. And it seems you cannot explain to
>me why I need a framework for method combining.

And yet, the difference is that I'm not ruling your proposal out; I'm 
merely suggesting that we work a bit more on defining what the best 
way to implement your proposal would be, in order to avoid collateral damage.

I also wanted to know more about your use cases; it's now clear that 
my previous thinking in terms of range() and named arguments as a 
typical use case is wrong; the things I'd want to do to handle that 
set of signatures are totally different from the thing you really 
want, which is to have truly positional arguments.

Perhaps the best thing would be to first define a syntactic notion of 
purely-positional arguments?  Then it would merely be a concept that 
overloading could respect, rather than being something that applies 
only to generic functions.

Or perhaps we could just say that if the main function is defined 
with *args, we treat those arguments as positional?  i.e.:

     @abstract
     def range(*args):
         """This just defines the signature; no implementation here"""

     @range.overload
     def range(stop):
         ...

     @range.overload
     def range(start, stop, step=None):
         ...

or:

     @abstract
     def draw(*coords):
         """This just defines the signature; no implementation here"""

     @draw.overload
     def draw(x:float, y:float, z:float):
         draw(Point(x,y,z))

     @draw.overload
     def draw(point:Point):
         ...



More information about the Python-3000 mailing list