
On Fri, 8 Oct 2021 at 03:45, S Pradeep Kumar <gohanpra@gmail.com> wrote:
Typing-sig has been discussing user-friendly syntax for the type used to represent callables. [1] Since this affects the Python language syntax, we wanted to get some high-level feedback from you before putting up a detailed PEP.
Disclaimer: I personally find that use of complex type annotations like Callable make code unreadable for the *human* reader, as compared to out of line information like a clearly-written comment or documentation. Therefore I'd probably be extremely reluctant to use this new syntax in real-life projects, regardless of the form that it takes. However, I do have some experience working on projects that use type annotations like this for callbacks, so I will answer in spite of my personal reservations.
**Question 1**: Are there concerns we should keep in mind about such a syntax proposal?
In my experience, a common pattern for functions that take non-trivial callbacks is to call them with named arguments rather than positional, in order to preserve future compatibility. So I would like callback annotations to be able to express the type "a function returning X, taking arguments `arg1` of type Y and `arg2` of type Z". The lack of keyword argument support in this proposal makes it unusable for APIs like this. Conversely, for callbacks with single arguments like f(cb: int->int) -> int, in my experience a lot of uses are lambda expressions, so something like f(lambda x: x+1). I would be a strong -1 on having to add types to lambda expressions (they are ugly enough already) so how does this interact with the annotation? Are type checkers able to correctly infer the type of lambda x: x+1, or would the whole expression end up being untyped? Similarly with functools.partial - would that correctly match the type? If common uses of callbacks end up being untyped in practice, that drastically reduces the value of the new syntax. (Note that this point is equally applicable to Callable - so I guess it's not so much about the new syntax as it is about whether annotating callbacks is sufficiently useful to be *worth* improving). Also, note that I automatically used a type of int->int up there. As someone else asked, is that form allowed, or is it required to be (int)->int? In my view, if we require the latter, I expect there will be a *lot* of people making that mistake and having to correct it.
**Question 2**: Do you have preferences either way? Do we propose (1) alone or (1) + (2)?
See above. My experience is that using named arguments for callbacks is a useful approach, and should probably be encouraged rather than made difficult, so I'd say that named argument support is important. Having said that, I think that making simple types like int->int or (int, int)->int more awkward to write would be a disadvantage - they are used a *lot* in things like the `key` argument of `sort`. So I'm -1 on things like (for example) requiring a colon as in (:int, :int) -> int. But to reiterate, I'm probably not likely to ever be a significant consumer of this feature, so consider the above with that in mind ;-) Paul