
On Sat, Nov 28, 2020 at 10:02 AM Abdulla Al Kathiri < alkathiri.abdulla@gmail.com> wrote:
Initially, when I wrote this, I had a similar syntax to what you wrote. I like it, I changed it to brackets so we could contain Callable that has multiple arguments or return value as Callables themselves.
E.g., function that has two Callables as arguments and a Callable return looks like this..
f: ((int, str) -> int, (…) -> str) -> (str) -> int
The arguments are clear to me but the callable return confuses me a little (the last two ->’s). However, the return value does’t have parenthesis, I still could see the consistency (arguments) -> return. But my mind is focusing on the last item, int, instead of the whole (str) -> int for some reason.
You could parenthesize the return value if you think it's not clear. (IIRC some functional languages like Haskell use the ... -> ... -> ... notation to indicate functions of multiple arguments, so it's probably good to avoid looking like that -- even if it'sconsistent it would mislead people into thinking that Python uses a similar idiom.
[[int, str -> int], [… -> str] -> [str -> int]] looks uglier but the one before last “->" clearly communicates that the return value is callable.
Regardless of how it’s done, the less we depend on the typing module for annotations, the better I think because it encourages python users to annotate their functions.
Indeed. Shantanu did some quick counting and found that after 'Any' and the types covered by PEP 585, Callable is by far the most used: https://bugs.python.org/issue42102#msg381155