On 30 April 2015 at 14:33, Steven D'Aprano <steve@pearwood.info> wrote:
On Thu, Apr 30, 2015 at 01:41:53PM +0200, Dima Tisnek wrote:
# Syntactic sugar "Beautiful is better than ugly, " thus nice syntax is needed. Current syntax is very mechanical. Syntactic sugar is needed on top of current PEP.
I think the annotation syntax is beautiful. It reminds me of Pascal.
Haha, good one!
# internal vs external @intify def foo() -> int: b = "42" return b # check 1 x = foo() // 2 # check 2
Does the return type apply to implementation (str) or decorated callable (int)?
I would expect that a static type checker would look at foo, and flag this as an error. The annotation says that foo returns an int, but it clearly returns a string. That's an obvious error.
Is this per PEP, or just a guess? I think PEP needs to be explicit about this. [snipped]
lambda arg: arg + 1
Obviously arg must be a Number, since it has to support addition with ints.
Well, no, it can be any custom type that implements __add__ Anyhow, the question was about non-trivial lambdas.
# local variables Not mentioned in the PEP Non-trivial code could really use these.
Normally local variables will have their type inferred from the operations done to them:
s = arg[1:] # s has the same type as arg
Good point, should be mentioned in PEP. Technically, type can be empty list, mixed list or custom return type for overloaded __getitem__ that accepts slices.
# comprehensions [3 * x.data for x in foo if "bar" in x.type] Arguable, perhaps annotation is only needed on `foo` here, but then how complex comprehensions, e.g. below, the intermediate comprehension could use an annotation [xx for y in [...] if ...]
A list comprehension is obviously of type List. If you need to give a more specific hint:
result = [expr for x in things if cond(x)] #type: List[Whatever]
See also the discussion of "cast" in the PEP.
Good point for overall comprehension type. re: cast, personally I have some reservations against placing `cast()` into runtime path. I'm sorry if I was not clear. My question was how should type of ephemeral `x` be specified. In other words, can types be specified on anything inside a comprehension?
# class attributes s = socket.socket(...) s.type, s.family, s.proto # int s.fileno # callable If annotations are only available for methods, it will lead to Java-style explicit getters and setters. Python language and data model prefers properties instead, thus annotations are needed on attributes.
class Thing: a = 42 # can be inferred b = [] # inferred as List[Any] c = [] #type: List[float]
Good point, I suppose comments + stub file may be sufficient. Stub is better (required?) because it allows to specify types of attributes that are not assigned in class scope, but that are expected to be there as result of __init__ or because it's a C extension. An example in PEP would be good.