[Python-3000] Draft pre-PEP: function annotations
Phillip J. Eby
pje at telecommunity.com
Sat Aug 12 23:10:17 CEST 2006
At 12:38 PM 8/12/2006 -0700, Paul Prescod wrote:
>Phillip. I'm having trouble following the discussion. I briefly caught up
>when Talin got very concrete with syntax and I would appreciate if you
>could offer some correspondingly remedial training.
>
>Talin's example is that metadata inventor A documents that his/her users
>should use this syntax for parameter docstrings:
>
>def myfunc( x : "The x coordinate", y : "The y coordinate" )
> ...
>
>Then metadata inventor B documents this his/her users should use this
>syntax for getopt strings:
>
>class MyHandler( CommandLineHandler ):
>
> @getopt
> def list( infile:"i" = sys.stdin, outfile:"o" = sys.stdout ):
>
>Now the user is faced with the challenge of making these two work together
>in order to get the best of both worlds. What does the user type?
As long as both inventors used overloadable functions, the user can type
almost *anything they want to*, as long as:
1. It's consistent,
2. It's unambiguous, and
3. They've defined the appropriate overloads.
For example, they might use a 'docopt' class that allows both to be
specified, or a pair of 'doc' and 'opt' objects in a list.
>The mechanism of overloading, function dispatching etc. is uninteresting
>to me until I understand what goes in the user's Python file. Syntax is
>important.
Indeed it is. Hence the importance of not forcing some particular
semantics, so as to allow the user to use the types and semantics of their
choosing.
By the way, it should be understood that when I say "overloadable
function", I simply mean some type-extensible dispatching mechanism. If
you exclude built-in types from consideration, and simply have special
attribute or method names, then duck typing works just as well. You can
have decorators that use hasattr() and such to do their dirty work.
It's only if you want to have sensible meaning for built-in types that
there even begins to be an illusion that conflicts are an issue. However,
the only built-in types likely to even be used in such a way are lists,
dictionaries, tuples, and strings. If there's more than one way to
interpret them, depending on the operation, their use is inherently
ambiguous, and it's up to the person combining them to supply the
differentiation.
However, if you have:
def myfunc( x : doc("The x coordinate"), y : doc("The y coordinate") )
There is no ambiguity. Likewise:
def cat( infile:opt("i") = sys.stdin, outfile:opt("o") = sys.stdout ):
is unambiguous. And the interpetation of:
def cat(infile: [doc("input stream"), opt("i")] = sys.stdin,
outfile: [doc("output stream"), opt("o")] = sys.stdout
):
is likewise unambiguous, unless the creator of the documentation or option
features has defined some other interpretation for a list than "recursively
apply to contained items". In which case, you need only do something like:
def cat(infile: docopt("input stream", "i") = sys.stdin,
outfile: docopt("output stream", "o") = sys.stdout
):
with an appropriate definition of methods for the 'docopt' type.
Since many people seem to be unfamiliar with overloaded functions, I would
just like to take this opportunity to remind you that the actual overload
mechanism is irrelevant. If you gave 'doc' objects a 'printDocString()'
method and 'opt' objects a 'setOptionName()' method, the exact same logic
regarding extensibility applies. The 'docopt' type would simply implement
both methods.
This is normal, simple standard Python stuff; nothing at all fancy. The
only thing that overloaded functions add to this is that they allow you to
(in effect) add methods to existing types without monkeypatching. Thus,
you can define overloads for built-in types, and types you didn't implement
yourself. Even if overloaded functions didn't exist, it wouldn't be
necessary to invent them just to allow arbitrary annotation semantics! It
simply requires that operations that *use* annotations always follow the
"tell, don't ask" pattern, whether it's done by duck typing, EAFP, or
overloaded functions.
More information about the Python-3000
mailing list