On 8/19/06, Samuele Pedroni <[EMAIL PROTECTED]> 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/)
_______________________________________________
Python-3000 mailing list
Python-3000@python.org
http://mail.python.org/mailman/listinfo/python-3000
Unsubscribe: 
http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com

Reply via email to