[Python-3000] signature annotation in the function signature or a separate line
Guido van Rossum
guido at python.org
Sun Aug 20 17:04:33 CEST 2006
On 8/19/06, Samuele Pedroni <pedronis at strakt.com> wrote:
> Given that the meaning of annotations is meant not be predefined,
Not sure what that has to do with it.
> given that people are comining with arbitrarely verbose examples
> thereof,
Which I believe are worst-case scenarios and not what we'll see in practice.
> given the precedent of type inferenced languages
> that use a separate line for optional type information
Can you show us an example or two?
> I think
> devising a way to have the annotation on a different line
> with a decorator like introduction instead of mixed with
> the function head would be saner:
>
> One possibility would be to have a syntax for signature expressions
> and then allow them as decorators with the obvious effect of attaching
> themself:
>
> @sig int,int -> int
> def f(a,b):
> return a+b
One problem with this is that for larger argument lists it's hard for the
(human) reader to match types up with arguments. In general I don't like
having two parallel lists of things that must be matched up; I'd much rather
have a single list containing all the info packed together.
> or with argument optional argument names:
>
> @sig a: int,b: int -> int
> def f(a,b):
> return a+b
This seems like it would merely move the problem to the previous line; it
doesn't solve the problem that the signature becomes unreadable when the
type expressions are long lists or dicts.
My own recommended solution for long signatures is to generously use the
Python equivalent of 'typedef'; instead of writing
def f(a: [PEAK("some peakish expression here"),
Zope("some zopeish expression here")],
b: [...more of the same...]) -> [PEAK("...", Zope("...")]:
return a+b
I think most cases can be made a lot more readable by saying
type_a = [PEAK("some peakish expression here"),
Zope("some zopeish expression here")]
type_b = [...more of the same...]) -> [PEAK("...", Zope("...")]
type_f = [PEAK("...", Zope("...")]
def f(a: type_a, b: type_b) -> type_f:
return a+b
especially since I expect that in many cases there will be typedefs that can
be shared between multiple signatures.
> sig expressions (possibly with parens) would be first class
> and be able to appear anywhere an expression is allowed,
> they would produce an object embedding the signature information.
I think it's a good idea to have a way to produce a signature object without
tying it to a function definition; but I'd rather not introduce any new
syntax for just this purpose. For purely positional signatures, this could
be done using a built-in function, e.g.
s = sig(int, int, returns=int)
I'm not sure what to do to create signatures that include the variable
names, the best I can come up with is
s = sig(('a', int), ('b', int), returns=int)
(Note that you can't use keyword parameters because that would lose the
ordering of the parameters. Possibly signatures could be limited to
describing parameters that are purely positional and parameters that are
purely keyword but no mixed-mode parameters? Nah, too restrictive.)
But I still don't want to introduce new syntax just for this. In extreme
cases you can always define a dummy function and extract its __signature__
object.
> So both of these would be possible:
>
> @typecheck
> @sig int,int -> int
> def f(a,b):
> return a+b
>
> @typecheck(sig int,int -> int)
> def f(a,b):
> return a+b
I'm not sure we need more ways to express the same thing. :-)
> For example having first-class signatures would help express nicely
> reflective queries on overloaded/generic functions, etc...
Agreed. But I think there's a way without forcing the annotations out of the
'def' line.
--
--Guido van Rossum (home page: http://www.python.org/~guido/)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.python.org/pipermail/python-3000/attachments/20060820/84237306/attachment.html
More information about the Python-3000
mailing list