[Python-ideas] PEP 505 (None coalescing operators) thoughts

Andrew Barnert abarnert at yahoo.com
Fri Oct 2 12:21:43 CEST 2015


On Oct 2, 2015, at 03:01, Ron Adam <ron3200 at gmail.com> wrote:
> 
>> On 10/01/2015 04:12 PM, Random832 wrote:
>>> On Thu, Oct 1, 2015, at 16:57, Ron Adam wrote:
>>> >And to go out on a limb...;-)
>>> >
>>> >Another possibility is to have a*special magic callable*  that when
>>> >called skips the argument evaluation and returns None.
> 
>> That's dangerous talk indeed. Special magic callables are Lisp
>> territory.;)
> 
> It's also lambda calculus territory.
> 
>> And I don't even know how you'd implement it efficiently without them
>> being known at compile-time.
> 
>> I guess at*every*  callsite you could test if the callable is magic, and
>> if it is evaluate the arguments, and if it's not just pass in a lambda
>> that will return the arguments. But you've got to generate those lambdas
>> for*all*  callsites, even the vast majority that will never be a magic
>> callable.
> 
> I realized this evening the parser doesn't need to know at parse time, and the object doesn't need to be special.  It's the syntax that gives it the specialness, not the object.  So what I was thinking is still possible, but it would work more like the other suggestions.

But if you've already got special handling for ?(), you don't need this NoCall object at all. If bar is None, ?() just skips the call. Compare the bytecode for your version:
> 
> 2  0  LOAD_GLOBAL 0 (bar)
> 
>   #-- inserted only if '?(' is used --------------
>      POP_JUMP_IF_NOT_NOCALL 3
>      LOAD_CONST 0 (None)
>      JUMP_FORWARD  8 (to 20)
>   #-----------------------------------------------

... to the simple ?() check version:

    2  0  LOAD_GLOBAL 0 (bar)
    #-- inserted only if '?(' is used
    JUMP_IF_NONE 8 (to 20)
    #--------------------------------

That's it. (And if you don't want to add a JUMP_IF_NONE opcode, you just DUP, compare to None, and POP_JUMP_IF_TRUE.) Just like ?. and ?[], the LOAD_* is followed by a JUMP_IF_NONE to the end of the first call (or the end of the entire primary if there is no call, but that case can't come up for ?() because it is a call), and nothing else has to be done.

> The case of unpacking the args if the object is None would require an additional check for None and to load an identity function in it's place or could be done by adding a __cond_call__ method (if that is how ?( will work) to None that is an identity function.

Why do you want to do this? And what does it even mean to "unpack the args" here? Does the identity function return a tuple and a dict for the positional and keyword functions respectively? When would you ever want that?

Also, to call the identity function (or anything else) on the args requires evaluating them, which defeats the entire purpose of short-circuiting evaluation of the args.

And, even if the idea of a universal identity function made sense here, why even call it instead of just not calling anything? What's the benefit from that extra work?

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20151002/18db6486/attachment.html>


More information about the Python-ideas mailing list