[Python-ideas] Using "||" (doubled pipe) as the null coalescing operator?

Steven D'Aprano steve at pearwood.info
Fri Sep 25 03:35:04 CEST 2015


On Fri, Sep 25, 2015 at 01:30:54AM +0100, Erik wrote:

> Throwing this one out there in case it inspires someone to come up with 
> a better variation (or to get it explicitly rejected):
> 
> object.(<accessor> if <condition> else <expr>)
> 
> ... where 'accessor' is anything normally allowed after 'object' ([], 
> (), attr) and 'condition' can omit the LHS of any conditional expression 
> (which is taken the associated object) or not (i.e., can be a complete 
> condition independent of the associated object):
> 
> foo = bar.((param0, param1) if not None else default())

I think that your intention is for that to be equivalent to:

if bar not None:  # missing "is" operator
    foo = bar(param0, param1)
else:
    foo = default()


I had to read your description three times before I got to the point 
where I could understand it. Some problems:

I thought `bar.(<accessor> ...)` meant attribute access, so I initially 
expected the true branch to evaluate to:

    foo = bar.(param0, param1)

which of course is a syntax error. Presumably you would write 
`bar.(attr if ...)` for attribute access and not `bar.(.attr if ...)`.

I'm still confused about the missing `is`. Maybe you meant:

if not None:  # evaluates to True
    ...


which is a problem with your suggestion that the left hand side of the 
condition is optional -- it makes it harder to catch errors in typing. 
Worse, it's actually ambiguous in some cases:

    spam = eggs.(cheese if - x else "aardvark")

can be read as:

if eggs - x:  # implied bool(eggs - x)
    spam = eggs.cheese
else:
    spam = "aardvark"


or as this:

if -x:  # implied bool(-x)
    spam = eggs.cheese
else:
    spam = "aardvark"


> foo = bar.([idx] if != sentinel else default())

I **really** hate this syntax. It almost makes me look more fondly at 
the || / !| syntax. Looking at this, I really want to interprete the 
last part as 

    foo = bar.default()

so I can see this being a really common error. "Why isn't my method 
being called?"

-1 on this.


-- 
Steve


More information about the Python-ideas mailing list