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

Carl Meyer carl at oddbird.net
Mon Sep 28 21:43:24 CEST 2015

On 09/28/2015 12:38 PM, Guido van Rossum wrote:
> On Mon, Sep 28, 2015 at 10:38 AM, Carl Meyer <carl at oddbird.net

>     "Propagating" refers to the proposed behavior where use of ?. or ?[
>     "propagates" through the following chain of operations. For example:
>         x = foo?.bar.spam.eggs
>     Where both `.spam` and `.eggs` would behave like `?.spam` and `?.eggs`
>     (propagating None rather than raising AttributeError), simply because a
>     `.?` had occurred earlier in the chain. So the above behaves differently
>     from:
>         temp = foo?.bar
>         x = temp.spam.eggs
>     Which raises questions about whether the propagation escapes
>     parentheses, too:
>         x = (foo?.bar).spam.eggs
> Oh, I see. That's evil.
> The correct behavior here is that "foo?.bar.spam.eggs" should mean the
> same as
>     (None if foo is None else foo.bar.spam.eggs)
> (Stop until you understand that is *not* the same as either of the
> alternatives you describe.)

I see that. The distinction is "short-circuit" vs "propagate."
Short-circuit is definitely more comprehensible and palatable.

> It should not escape parentheses.

Good. I assume that the short-circuiting would follow the precedence
order; that is, nothing with looser precedence than member and index
access would be short-circuited. So, for example,


would short-circuit the indexing and the final member access, translating to

    foo.bar['baz'].spam if foo is not None else None


    foo?.bar or 'baz'

would mean

    (foo.bar if foo is not None else None) or 'baz'

and would never evaluate to None. Similarly for any operator that binds
less tightly than member/index access (which is basically all Python

AFAICS, under your proposed semantics what I said above is still true, that

    x = foo?.bar.baz

would necessarily have a different meaning than

    temp = foo?.bar
    x = temp.baz

Or put differently, that whereas these two are trivially equivalent (the
definition of left-to-right binding within a precedence class):


these two are not equivalent:


I'm having trouble coming up with a parallel example where the existing
short-circuit operators break "extractibility" of a sub-expression like

I guess this is because the proposed short-circuiting still "breaks out
of the precedence order" in a way that the existing short-circuiting
operators don't. Both member access and indexing are within the same
left-to-right binding precedence class, but the new operators would have
a short-circuit effect that swallows operations beyond where normal
left-to-right binding would suggest their effect should reach.

Are there existing examples of behavior like this in Python that I'm


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: OpenPGP digital signature
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20150928/d60767df/attachment.sig>

More information about the Python-ideas mailing list