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

Chris Angelico rosuav at gmail.com
Thu Jul 16 13:28:30 CEST 2015


On Thu, Jul 16, 2015 at 7:00 PM, Paul Moore <p.f.moore at gmail.com> wrote:
> On 16 July 2015 at 05:18, Steven D'Aprano <steve at pearwood.info> wrote:
>> On Wed, Jul 15, 2015 at 07:03:50PM -0400, Terry Reedy wrote:
>>
>>> So here is the proposal: in the call definition, change primary to
>>>   possible_call ::= identifier | parenth_form | yield_atom
>>>                     | attributeref | subscription | slicing | call
>>>
>>> As for error messages, there is another thread suggesting that the
>>> messages for SyntexError might be vastly improved.
>>
>>
>> This sounds like a good proposal. +1
>
> Note that the proposal should also include a change to "call":
>
> call ::= possible_call '(' args ')'
>
> replacing
>
> call  ::= primary '(' args ')'

I presume that was the intent :)

> (I was initially confused by the fact that possible_call included call
> as an option, until I remembered how it fitted into the larger
> picture).

Calling the result of a call is the easiest way to demonstrate nested
functions, closures, etc:

def adder(x):
    def add(y):
        return x + y
    return add

adder(5)(7) # == 12

Even if this is never used in real-world code, permitting it is a
great way to show that a thing is a thing, no matter how you obtain it
- you can use "adder(5).__name__" for attribute lookup on function
return values, "lst[4][7]" to subscript a list item (very common!),
"(yield 5)()" to call whatever function someone send()s you... worth
keeping! (Also, I have unpleasant memories of PHP functions that
return arrays - assigning the return value to a name and subscripting
the name works, but subscripting the function return directly didn't
work at the time. It has subsequently been fixed, but while I was
doing that particular work, the restriction was there.)

> This seems to me like more complexity than is warranted, particularly
> as the error message quality drops dramatically (unless we improve the
> syntax error message at the same time).
>
> So I'm -0 on this.

There's another thread around the place for improving the error
messages. But the message is unlikely to be accurate to the real
problem anyway, as most people do not consciously seek to call string
literals. It's like getting told "NoneType object has no attribute X"
- the problem isn't that None lacks attributes, the problem is "why is
my thing None instead of the object I thought it was". And hey. If
anyone *really* wants to try to call a string lit, they can always
write it thus:

# Call me!
response = ("0406 650 430")()

That said, though, there is a backward-compatibility problem. Code
which would have blown up at run-time will now fail at compile-time.
It's still broken code, but people will need to check before running
stuff in production.

+1 on the proposal. Catching errors earlier is a good thing if it
doesn't make things too complicated.

ChrisA


More information about the Python-ideas mailing list