Hello, On Sat, 20 Feb 2021 00:23:13 +0900 "Stephen J. Turnbull" <turnbull.stephen...@u.tsukuba.ac.jp> wrote:
> Abdulla Al Kathiri writes: > > Condensing to the parts which are in question, > > > def test(self, func: t.Callable[..., bool], *args, **kwargs) -> > > Predicate: return self._build_predicate( > > lambda lhs, value: func(lhs, *args, **kwargs), > > Operation.TEST, > > (self._path, func, args, freeze(kwargs)) > > ) > > > def test(self, func: (...) -> bool, *args, **kwargs) -> Predicate: > > return self._build_predicate( > > (lhs, value) => func(lhs, *args, **kwargs), > > Operation.TEST, > > (self._path, func, args, freeze(kwargs)) > > ) > > Yes, it's nicer, but I don't see a win big enough to be worth forcing > people who read code to learn two syntaxes for lambda, and two > syntaxes for Callable (one of which isn't even syntax). 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. > Also, "->" > can't be just syntax, if I understand type annotations correctly. It > would need to become an object constructor. It depends on how "->" in that role will be implemented. It would be nice to not just hardcode it to "Callable[lhs, rhs]", but at the same time, I'd personally hope we'll avoid yet another dunder either. > Then the question would > be "are there cases where 'Callable' is not what you want there?", > i.e., you want a subclass of Callable. There can't be subclass of Callable in the same way as there can't be: class my_foo(type(lambda:0)): pass > In that case you'd have to use > the old syntax anyway. (I don't have an answer to that, but you would > need one.) > > I don't make the rules, but to me if this is the best you can do, you > would have to provide evidence that quite a lot of code would benefit > from this. The difference between "(int, str) -> int" and "Callable[[int, str], int]" is the same as difference __str__ and __repr__. "Callable" syntax is effectively an internal representation of the type annotation information. 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. So no, __str__ vs __repr__ comparison doesn't do fairness to it. The difference is the same as between: --- def foo(a): print("hello") --- and --- 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. > > Steve -- Best regards, Paul mailto:pmis...@gmail.com _______________________________________________ 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/TC4CM3R6HKSIOOF2FNQANVLXFBOU2OZJ/ Code of Conduct: http://python.org/psf/codeofconduct/