[Python-ideas] In call grammar, replace primary with possible_call? (was Re: ...quote followed by a left parenthesis...?)

Andrew Barnert abarnert at yahoo.com
Fri Jul 17 03:44:26 CEST 2015


On Jul 16, 2015, at 15:27, Terry Reedy <tjreedy at udel.edu> wrote:
> 
> 'primary' is vague and to me way overly broad.

To a normal end-user, the things you syntactically call are basically all values (or, if you prefer, all expressions). Calling a value that's not callable is the same error as adding a thing that's not addable or indexing a thing that's not subscriptable, and that's a TypeError. The existing rules makes sense, and fit in with everything else in Python. For example, we don't consider {1}[1] a syntax error even though it's never valid; how is {1}(1) any different?

Even with your suggested change, you still need to teach people the same rule, because s() where s is an int or (1)() are still going to be valid syntax and still going to be guaranteed type errors. All you're doing is catching the least common cause of this type error early, and I don't see who's going to benefit from that.

If you're thinking there might be some benefit to teaching, or to self-taught novices, I don't see one; in act, I think it's slightly worse. They still have to learn the type rule to understand why x(0) raises at runtime--and that's far more common than 0(0). (And the current type error is pretty nice.) And if a novice can understand why x(0) is an error, they can understand why 0(0) is an error--and, in fact, they'll understand more easily if they're the same error than if they're different. And, the more someone looks into the current error, the more they'll understand. Why is 0(0) a TypeError? Because a call expression looks up the __call__ method on the object's type, and type(0) is int, and int doesn't have a __call__ method. Well, that makes sense--what would it mean to call an integer? But hey, does that mean I can create my own classes that act like functions? Cool!

If you're just looking to catch errors earlier, a static type checker will catch 0(0) in exactly the same way that it will catch x(0) when x has been declared or inferred to be an int.

Finally, the existing rule also has the very minor benefit that you can ast.parse 0(0) if you have a reason to do so (whether you're writing a DSL with an import hook, or writing a dev-helper tool of some kind, or even hacking up Python to add an int.__call__ method). I'm not sure why you'd want to do that (that's why it's a very minor benefit...), but I don't see any reason to make the language less consistent and stop you from doing that.

> When expanded to basic nonterminals, about half are never callable. Adding one production rule is a minor change. Leaving error detection aside, a benefit for readers would be to better define what is actually a possible callable.  

But why does a reader need to know what lexical forms are possibly callable? Again, the current rule is dead simple, and totally consistent with subscripting and so on. What's a possible callable? Any value is a possible callable, just as any value is a possible subscriptable and a possible addable and so on.

> Of course, this could be done with a new sentence in the doc without changing the grammer.  Maybe this should be the outcome of this issue.

What sentence are you envisioning here? Do we also need a sentence explaining that subscripting an int literal is always illegal despite not being a syntax error? (And that one, I can imagine a newcomer to Python actually writing, because 0[p] is valid in C...) Or that [0][0](0) is always illegal, or (0)(0)? If not, why do we need a sentence explaining that 0(0) is always illegal?



More information about the Python-ideas mailing list