
On Mon, Sep 28, 2015 at 12:47 PM, Andrew Barnert <abarnert@yahoo.com> wrote:
On Mon, Sep 28, 2015 at 10:38 AM, Carl Meyer <carl@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
On Monday, September 28, 2015 12:05 PM, Guido van Rossum <guido@python.org> wrote: 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.
Isn't the PEP author still planning to do that? But it hasn't happened yet. :-(
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))
Hm, I think the problem is that this way of representing the tree encourages thinking that each attribute (with or without ?) can be treated on its own. … 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.
To most people of course that's indecipherable mumbo-jumbo. :-)
I suppose the reference documentation wording is also important here, to explain that an uptalked attributeref or subscription short-circuits the whole primary.
Apparently clarifying that is the entire point of this thread. :-) -- --Guido van Rossum (python.org/~guido)