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

Ron Adam ron3200 at gmail.com
Fri Oct 2 19:47:53 CEST 2015


On 10/02/2015 07:54 AM, Random832 wrote:
> On Fri, Oct 2, 2015, at 06:01, Ron Adam 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.
>
> Does lambda calculus really have a notion of two types of function that
> are called with the same syntax but one receives the values as they have
> been evaluated and the other receives some abstract representation of
> how to get them if it needs them? That doesn't even make any sense. Does
> it even have a notion of side effects and therefore when/whether things
> are evaluated if they are not needed?
>
> Not everything in Lisp is in lambda calculus.

I wasn't really comparing it to lisp, but I understood your reference to 
it.  The comparison to lambda calculus is very loose also.

BTW, in lisp (and scheme) there are a handful of special functions.  One 
of those is the if function which avoids early evaluation of the 
expressions till after the condition is evaluated.  It can be 
implemented as a normal lisp expression but not without quoting the 
arguments.

>> 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.
>>
>> If you look at byte code generated for a function call...
>>
>> You will notice the function is loaded on the stack *before* the
>> argument expressions are evaluated.
>>
>> It won't require generating lamba expressions, just a conditional jump
>> where '?(' is used.  So no, it won't be required at every call site.
>
> What does this have to do with the idea of a magic callable?

As I said above it doesn't need to magic after all.

> If this is
> implemented with a magic callable then A) *any* callable might be a
> magic callable and B) the idea original idea strongly implied a
> generalized notion of magic callables, of which NoneCall would be only
> one example. How do you pass the arguments to the *other* magic
> callables that *do* [maybe] evaluate them?
>
> You've basically just explained how the bytecode works for ?( if it is
> *not* implemented with a magic callable. So how does making it NoneCall
> instead of just None improve anything?

It's not quite the same.  The proposed ?( skips the arguments if the 
right hand side is None.

          None?(...)   ---> None

So you can't use that to supply a default directly.

         value = None?(default)    # returns None (not useful here)



To make that work, think of applying None to the arguments.  Which in 
turn does nothing to them, they just get returned.

         value = None?(default)   --> default

But to get the inverse of that which is the original preposed ?( 
behavior, you need a different way to trigger that.  We could use False 
I suppose.

        value = False?(default)   --> None

And of course....

        value = other?(default)   -->  other(default)



This is just based on the thought that a conditional ?( calling syntax 
could be useful in a broader scope and not just used as a None 
coalescing operator.

So in the above, None, False, and other can be replaced by expressions.

      def when(x):
          return None if x else False

      value = when(cond)?(expr)       # expr or None



With the original proposed ?( operator the set default example is still 
doable, but it needs a helper function.

        None?(expr) --> None

        other?(expr) --> other(expr)    # The True case


      def is_none(cond):
          return None if cond is None else lambda x:x

      value = is_none(value)?(default_value)


Compared to

      value = default_value if expr is None else None



I was trying to shorten it to..

     value = expr?(default)

But maybe that just won't work in a nice enough way.

Well it's just a thought/suggestion.  (shrug)


Cheers,
    Ron





















More information about the Python-ideas mailing list