[Python-ideas] Null coalescing operators

MRAB python at mrabarnett.plus.com
Sat Sep 19 01:02:42 CEST 2015


On 2015-09-18 23:37, Chris Angelico wrote:
> On Sat, Sep 19, 2015 at 3:42 AM, Mark Haase <mehaase at gmail.com> wrote:
>> StackOverflow has many questions on the topic of null coalescing operators
>> in Python, but I can't find any discussions of them on this list or in any
>> of the PEPs. Has the addition of null coalescing operators into Python ever
>> been discussed publicly?
>>
>> Python has an "or" operator that can be used to coalesce false-y values, but
>> it does not have an operator to coalesce "None" exclusively.
>
[snip]
>
> created?.isoformat() # is equivalent to
> created.isoformat() if created is not None else None
>
> but this means there needs to be some magic, because it should be
> equally possible to write:
>
> created?.year # equivalent to
> created.year if created is not None else None
>
> which means that sometimes it has to return None, and sometimes
> (lambda *a,**ka: None). Three possible solutions:
>
> 1) Make None callable. None.__call__(*a, **ka) always returns None.
> 2) Special-case the immediate call in the syntax, so the equivalencies
> are a bit different.
> 3) Add another case: func?(args) evaluates func, and if it's None,
> evaluates to None without calling anything.
>
> Option 1 would potentially mask bugs in a lot of unrelated code. I
> don't think it's a good idea, but maybe others disagree.
>
> Option 2 adds a grammatical distinction that currently doesn't exist.
> When you see a nullable attribute lookup, you have to check to see if
> it's a method call, and if it is, do things differently. That means
> there's a difference between these:
>
> func = obj?.attr; func()
> obj?.attr()
>
> Option 3 requires a bit more protection, but is completely explicit.
> It would also have use in other situations. Personally, I support that
> option; it maintains all the identities, is explicit that calling None
> will yield None, and doesn't need any magic special cases. It does add
> another marker, though:
>
> created?.isoformat?() # is equivalent to
> created.isoformat() if created is not None and created.isoformat is
> not None else None
>
> As to the syntax... IMO this needs to be compact, so ?. has my
> support. With subscripting, should it be "obj?[idx]" or "obj[?idx]" ?
> FWIW Pike uses the latter, but if C# uses the former, there's no one
> obvious choice.
>
To me, the choice _is_ obvious: "obj?[idx]". After all, that's more in
keeping with "obj?.attr" and "func?()".

If you had "obj?[idx]", then shouldn't it also be "obj.?attr" and
"func(?)"?



More information about the Python-ideas mailing list