[Python-ideas] PEP 484 (Type Hints) -- first draft round

Cem Karan cfkaran2 at gmail.com
Mon Jan 19 02:25:52 CET 2015


On Jan 18, 2015, at 7:08 PM, Andrew Barnert <abarnert at yahoo.com> wrote:

> On Jan 18, 2015, at 14:24, Cem Karan <cfkaran2 at gmail.com> wrote:
> 
>> On Jan 18, 2015, at 9:16 AM, Chris Angelico <rosuav at gmail.com> wrote:
>> 
>>> On Mon, Jan 19, 2015 at 12:37 AM, Cem Karan <cfkaran2 at gmail.com> wrote:
>>>> There may be other uses of annotations that programmers haven't yet thought of, simply because they don't know that annotations exist.  Locking out those uses would suck.
>>> 
>>> I see a lot of vague "but what if there's something else", and not a
>>> lot of concrete "here's a use of annotations that would be locked
>>> out". Does anyone actually have another use case that would be
>>> seriously harmed by this kind of conflict? Remember, you can simply
>>> not use type hints for the function(s) that use other annotations; the
>>> conflict is only if you're trying to use both on the same function.
>> 
>> def foo(a: {Type(int), Doc("some doc")}, b):
>>   pass
>> 
>> vs.
>> 
>> def foo(a, b):
>>   """
>>   :param a: some doc
>>   :type a: int
>>   """
>>   pass
>> 
>> With annotations, the documentation lives with the argument.  If typing rules all, then you might accidentally have the following:
>> 
>> def foo(a: int, b):
>>   """
>>   :param a: some doc
>>   :type a: str <- Whoops!  Type conflict!
>>   """
>>   pass
>> 
>> Or the ugly but workable:
>> 
>> def foo(a: int, b):
>>   """
>>   :param a: some doc
>>   """
>>   pass
> 
> What's ugly about that? Besides being consistent with a wide variety of other languages, it puts signature information in the signature and documentation in the docstring, which seems like the obvious right place for everything.

Ugly in the sense that information is spread out.  That said, you are right that it is more consistent with what other languages do.

>> I'm arguing that with annotations we can put a lot more information in about a given function argument/return value than just typing.  
> 
> Denser doesn't always mean better. One piece of simple information is easy to read; a lot more information implies a lot more mental processing.

You're right about that, it can be more difficult.  However, hunting for information can also be difficult.  

> Plus, you're ignoring the fact that you're substantially increasing boilerplate, to the point where I think you're not even increasing brevity and density in the first place. For the (hopefully common) case of simple types, having to stick the type in a constructor and then stick that constructor in a set vastly increases how much space it takes to represent the type, and how much mental effort it takes to process it. Just compare:
> 
>    def foo(a: int, b):
> 
>    def foo(a: {Type(int)}, b):
> 
> That's 160% boilerplate, and it includes two levels of punctuated syntax that pushes the limits of what you can read and process without having to think it through--and that's the simplest possible case. If we did things your way, I think people would avoid annotating simple cases, and clamor for a way to hide other people's annotations when viewing help.

You're right about that.  It IS a lot uglier.  But like I said, its one saving grace is that it is clear what the annotation is; it is a type, and it is intended for type checking.  There isn't any guessing, and there is very fine-grained control over where and when type checking is done.  

As an alternative, if all basic types had equivalents in the typing library, you could skip the container above.  In short:

from typing import Int

def foo(a: Int, b):  # Simple type checking.

def foo(a: {Int, Doc("some doc")}, b):  # Something more clever.

This reduces the boilerplate while still making it possible to determine if we're looking at a type check or something else.

>> Typing and documentation are two things that I can think of off the top of my head.  I can't think of others off of the top of my head, but I suspect that is due to my lack of imagination and not the lack of potential.
> 
> Don't sell yourself short. They're the exact same two things that Collin Winter and the collective members of the python-3000 list came up with back in mid-2006 on the way to PEP 3107. And the same two things people have come up with in the nearly decade since. So either there is no obvious wider potential, or the whole Python community is short on imagination.
> 
> Obviously PEP 484's type hints are a narrower subset of all the potential kinds of typing information suggested in PEP 3107, but if the question is how to unify multiple different typing systems, I think it's pretty clear that a general "lots of separate things in parallel" solution isn't going to be the answer. (Would anyone want to see {typing.Type(int), cython.Type(cython.int32), xrpc.Type(xrpc.JSONNumber)} as an annotation?)

Only in sort of morbid fascination, kind of like the winners of the obfuscated C code contest...

Thanks,
Cem Karan


More information about the Python-ideas mailing list