On Sat, Sep 19, 2015 at 9:21 AM, Guido van Rossum firstname.lastname@example.org wrote:
I forgot to think about the scope of the uptalk operator (i.e. what is skipped when it finds a None). There are some clear cases (the actual implementation should avoid double evaluation of the tested expression, of course):
a.b?.c.d[x, y](p, q) === None if a.b is None else a.b.c.d[x, y](p, q) a.b?[x, y].c.d(p, q) === None if a.b is None else a.b[x, y].c.d(p, q) a.b?(p, q).c.d[x, y] === None if a.b is None else a.b(p, q).c.d[x, y]
This makes sense to me.
But what about its effect on other operators in the same expression? I think this is reasonable:
a?.b + c.d === None if a is None else a.b + c.d
This is a bit weird to me. Essentially ?. takes precedence over a following +. But would you also expect it to take precedence over a preceding one as well? That's inconsistent.
c.d + a?.b === None if a is None else c.d + a.b or c.d + a?.b === c.d + None if a is None else c.d + a.b
I think that ?. ? and ?() should affect other operators at the same precedence level only, i.e., each other and .  and (). This seems the most logical to me. And I just looked up the C# documentation on MSDN and it does the same thing: https://msdn.microsoft.com/en-us/library/dn986595.aspx
It also shouldn't escape out of comma-separated lists, argument lists, etc.:
(a?.b, x) === ((None if a is None else a.b), x) f(a?.b) === f((None if a is None else a.b))
Agree. It also should not escape grouping parenthesis even though that might not be useful. It would be very weird if a parenthesized expression did something other than evaluate the expression inside it, period.
(a?.b).c === None.c if a is None else (a.b).c === temp = a?.b; temp.c (x or a?.b).c === (x or (None if a is none else a.b)).c
Yes, None.c is going to raise an exception. That's better than just getting None IMHO.