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

Ron Adam ron3200 at gmail.com
Thu Oct 1 22:57:18 CEST 2015


On 10/01/2015 02:59 AM, Nick Coghlan wrote:

> As a result, one interesting way of looking at this problem is to
> ask: what if we *only* offered the conditional operations, *without*
> offering a binary null-coalescing operator?

How languages treat None, null, and nil, are very fundamental aspects of 
how they work.  For example I noticed that if we add an None specific 
'or' operator, we may want a None specific 'and' operator too.  And in 
order to use those in conditional statements, it makes sense to have 
None specific 'if' and 'while'.  So it may be a slippery slope.  (Or 
they may be good to have.  I'm very undecided still.)


> That is, we could allow conditional assignment:
>
> data ?= [] headers ?= {} arg ?= make_default()
>
> With the meaning:
>
> if data is None: data = [] if headers is None: headers = {} if arg is
> None: arg = make_default()

Is the above three statements, three expressions, or one long expression?

I was contemplating the possibility of having a variation of "is" as a 
way to test for not-null, but it leads down the same path.  Once you 
have one None specific bool operator, the rest are needed to make full 
use of it.



An Observation...

In many discussions here, the same shortcut problem keeps coming up when 
ever we don't want to evaluate a functions arguments too early.

So maybe what we really need is a syntax for a conditional partial where 
some arguments aren't evaluated until asked for.

The ?( is almost that, but some way to short cut the arguments would 
still be needed.  One possibility is to have them all as optional only, 
and just not ask for them.



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.

     NoneCall(these, args, are, never, evaluated)

In this case the Magic is underwhelming as it does absolutely nothing 
except return None.  I think I can live with that.

Then a special method on objects, obj __cond__call__() can return a 
NoneCall to skip the arguments on the right side of ?(, or return 
another callable to use them.

This is a bit like decorators in that to use the arguments you need to 
return a callable.  So I think maybe the @ symbol would be better.  I 
can see this being used in decorators to apply decorators conditionally.


The case of a Null default might be done by just having a conditional 
call on None, unpack the arguments. So it's __cond_call__ method if it 
had one, would be an identity function.

    value = obj@(default)   # if obj is None: value = default
                            # if obj has __cond_call__ method
                            #    it calls it with the arguments.
                            # else TypeError


So the '@(', or '?(' if preferred, may be the only one we need.  The 
rest might be implementable with it by defining __cond_call__ methods on 
the objects.


Cheers,
    Ron




















More information about the Python-ideas mailing list