On Fri, Feb 19, 2021 at 07:35:19PM +0300, Paul Sokolovsky wrote: > People won't learn "two syntaxes for Callable". People shun using > Python's current type annotations due to their ugliness and "quick hack > without thinking of UX" feel. Only after there will be "int | str" > instead of "Union[int, str]", "(int, str) -> int" instead of > "Callable[[int, str], int]", "int & const" instead of "Annotated[int, > const]" - only then people will start learn and use them.
Pretty much all of that is either personal subjective judgement, or factually untrue. People will need to learn two syntaxes, because they will have to deal with legacy code using the old syntax. People are already learning and using annotations, and have been for years. > There can't be subclass of Callable in the same way as there can't be: > > class my_foo(type(lambda:0)): > pass We can already subclass Callable. >>> from typing import Callable >>> class X(Callable): ... pass ... >>> X[1, 2] __main__.X[1, 2] > The difference between "(int, str) -> int" and "Callable[[int, str], > int]" is the same as difference __str__ and __repr__. A better analogy is the difference between a binary operator versus a function of two arguments: a ^ b bitwise_xor(a, b) The binary operator looks nicer and is terser and more compact, but function notation is more self-documenting. > "Callable" syntax > is effectively an internal representation of the type annotation > information. I don't think so. > And currently, the people have to write that verbose, > unwieldy, ugly representation (which normally would be needed only for > debugging purposes) manually. What we need is pleasant surface syntax > for type annotations in Python. I think that's nonsense. Aside from the difference between square brackets and round brackets, `Callable[int, str]` is just a function call. If you think that's "unwieldy, ugly", wait until you try writing some actual Python code, it is full of function calls. It is reasonable to want a more terse and compact syntax for functions, but on the other hand, function parameters that take functions are definitely a relatively narrow niche. More compact syntax is a Nice To Have, not a Must Have. Paul then claims that having to write `Callable[int, str]` in an annotation is equivalent to writing AST: [added indentation to make the structure easier to see] > --- > Module( > body=[ > FunctionDef( > name='foo', > args=arguments( > posonlyargs=[], > args=[ > arg(arg='a') > ], > kwonlyargs=[], > kw_defaults=[], > defaults=[] > ), > body=[ > Expr( > value=Call( > func=Name(id='print', ctx=Load()), > args=[ > Constant(value='hello') > ], > keywords=[] > ) > ) > ], > decorator_list=[] > ) > ], > type_ignores=[] > ) > --- > > The latter is the same as the former, just in the AST form. That's what > we ask people to do with type annotations currently - write them in the > AST form. I can't take that argument seriously. How can you possibly claim that writing an annotation like `Callable[int, str]` is "the same as" writing that deeply-nested 20-line AST? -- Steve _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/WX6A5RRSHJPCSP3ZFBJQIROWCOT5I44U/ Code of Conduct: http://python.org/psf/codeofconduct/