Alternative notation for Callable
PEP 604 introduced a new notation for specifying Unions, with `X | Y` being an alias for `typing.Union[X, Y]`. While thinking about other notations that could be useful, I would like to suggest also having `[ArgType1, ArgType2, ArgType3] -> ReturnType` as an alternative for `typing.Callable[[ArgType1, ArgType2, ArgType3], ReturnType]` This would then mean that, for example, we could annotate the `map` function as: `def map(func: [X] -> Y, items: Iterable[X]) -> Iterable[Y]:` Which would make this very similar to the annotation used to define a function that can be passed into `map`: ` def f(x: X) -> Y:` What do people think of this proposal? (I originally submitted this https://discuss.python.org/t/additional-type-annotation-for-callable/6800 here but was told that this mailing list may be more appropriate, please let me know if there is somewhere more appropriate to ask this)
I like the idea of a less-cumbersome way to annotate callables. Did you consider using parentheses (i.e. tuple notation) rather than square brackets? Parentheses would more closely mirror the punctuation of a function declaration, so it might be more natural to most Python developers. ```python (ParamType1, ParamType2, ParamType3) -> ReturnType ``` TypeScript uses a similar notation for callable types, except that it replaces `->` with `=>`, and it requires the names of parameters to be specified as well, as in `(a: ParamType1, b: ParamType2) => ReturnType`. Including the names of parameters would allow for variadic parameters and keyword-only separators, as in `(a: int, *args: Any, *, b: str, **kwargs: Any) -> float`. One thing to consider is how to express `Callable[..., ReturnType]`. Would that be `(...) -> ReturnType`? Another consideration is that the combination of this proposal and PEP 604 would produce ambiguities. For example, what type is `(int) -> str | float`? Is that a union of a callable and a float, or is it a callable that returns a union? We'd need to decide on relative precedence of the `|` and `->` operators. (I'd recommend that `->` bind more tightly than `|`). We'd also need to add support for parentheses in type expressions to override the default precedence: `((int) -> str) | float` vs `(int -> str) -> (str | float)`. -- Eric Traut Contributor to pyright and pylance Microsoft Corp.
Eric Traut wrote:
I like the idea of a less-cumbersome way to annotate callables. Did you consider using parentheses (i.e. tuple notation) rather than square brackets? Parentheses would more closely mirror the punctuation of a function declaration, so it might be more natural to most Python developers. (ParamType1, ParamType2, ParamType3) -> ReturnType
I am very encouraged by the trend set in motion by PEP 604 of simpler annotation syntax; the benefit of having readers intuit an an annotation at a glance is enormous. This proposal feels like another step in that direction. Two others that crop up a lot are Sequence (for lists + tuples + ...) and Iterable, but I guess we are running out of syntax—with `{ ... }` , and maybe `[ ... ]`, as a few of the "containers" left. Here's an example Dave Beazley posted to Twitter: ``` def read_csv_as_dicts( lines: Iterable[str], *, types: Sequence[Callable[[str],Any]]=None, headers: Sequence[str]=None ) -> List[Dict[str,Any]]: ``` Imagining `[ ]` for sequences, `iter` for Iterable, and the above function syntax, that could become: ``` def read_csv_as_dicts( lines: iter(str), *, types: [(str) -> Any, ...]=None, headers: [str, ...]=None ) -> list[dict[str, Any]]: ``` which to my eye, ignoring the feasibility of the exact form, becomes eminently more readable and helpful. Thanks to everyone who is working hard to think through and sort out this syntax. Stéfan
here's a similar request I made on the mypy github https://github.com/python/mypy/issues/10156 Needs a PEP to change overload new operators at the type level, or introduce new syntax, so issue was closed I was also directed here
On 3/5/21 4:42 AM, Joel Berkeley via Typing-sig wrote:
here's a similar request I made on the mypy github https://github.com/python/mypy/issues/10156 Needs a PEP to change overload new operators at the type level, or introduce new syntax, so issue was closed I was also directed here
Yep, I'd say there's definitely interest in considering shorthand notation for Callable. :) Right now contributors are tied up working on a couple of other PEPs for Python 3.10, so my guess is that we'll be looking at potential alternative syntax for Callable for Python 3.11, presuming an acceptable design can be found. -- David Foster | Seattle, WA, USA Contributor to TypedDict support for mypy
participants (5)
-
David Foster
-
Eric Traut
-
Joel Berkeley
-
mark00bell@gmail.com
-
stefanv@berkeley.edu