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

Luciano Ramalho luciano at ramalho.org
Mon Sep 28 23:48:49 CEST 2015


Glyph tweeted yesterday that everyone should watch the "Nothing is
Something" 35' talk by Sandi Metz at RailsConf 2015. It's great and,
in a way, relevant to this discussion.

https://www.youtube.com/watch?v=29MAL8pJImQ

BTW, so far, `or?` is the least horrible token suggested, IMHO. I like
the basic semantics, though.

Cheers,

Luciano


On Mon, Sep 28, 2015 at 4:47 PM, Andrew Barnert via Python-ideas
<python-ideas at python.org> wrote:
> On Monday, September 28, 2015 12:05 PM, Guido van Rossum <guido at python.org> wrote:
>>On Mon, Sep 28, 2015 at 10:38 AM, Carl Meyer <carl at oddbird.net> wrote:
>>>"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 can see the confusion that led to the idea of "propagation" -- it probably comes from an attempt to define "foo?.bar" without reference to the context (in this case the relevant context is that it's followed by ".spam.eggs").
>
>
> It would really help to have a complete spec, or at least a quick workthrough of how an expression gets parsed and compiled.
>
> I assume it's something like this:
>
> spam?.eggs.cheese becomes this pseudo-AST (I've skipped the loads and maybe some other stuff):
>
>     Expr(
>         value=Attribute(
>             value=Attribute(
>                 value=Name(id='spam'), attr='eggs', uptalk=True),
>             attr='cheese', uptalk=False))
>
>
> … which is then compiled as this pseudo-bytecode:
>
>     LOAD_NAME 'spam'
>     DUP_TOP
>     POP_JUMP_IF_NONE :label
>     LOAD_ATTR 'eggs'
>     LOAD_ATTR 'cheese'
>     :label
>
>
> I've invented a new opcode POP_JUMP_IF_NONE, but it should be clear what it does. I think it's clear how replacing spam with any other expression works, and how subscripting works. So the only question is whether understanding how .eggs.cheese becomes a pair of LOAD_ATTRs is sufficient to understand how ?.eggs.cheese becomes a JUMP_IF_NONE followed by the same pair of LOAD_ATTRs through the same two steps.
>
> I suppose the reference documentation wording is also important here, to explain that an uptalked attributeref or subscription short-circuits the whole primary.
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/



-- 
Luciano Ramalho
|  Author of Fluent Python (O'Reilly, 2015)
|     http://shop.oreilly.com/product/0636920032519.do
|  Professor em: http://python.pro.br
|  Twitter: @ramalhoorg


More information about the Python-ideas mailing list