<div dir="ltr">Steven, thanks for the reply. Just to clarify: the current PEP draft was not meant to be read -- it was just a placeholder to get a PEP # assigned. I didn't realize that new PEPs are published in an RSS feed!<div><br></div><div>I do appreciate your detailed feedback, though. Your interpretation of Dart's semantics is correct, and I agree that's absolutely the wrong way to do it. C# does have the short-circuit semantics that you're looking for.</div><div><br></div><div>To you, and to everybody else in this thread: I am reading every single message, and I'm working on a draft worthy of your time and attention that incorporates all of these viewpoints and offers several, competing alternatives. I will announce the draft on this list when I'm further along.</div><div><br></div><div>Proposing a new operator is tremendously difficult in Python, because this community doesn't like complex or ugly punctuation. (And adding a new keyword won't happen any time soon.) A similar debate surrounded the ternary operator PEP[1]. That PEP's author eventually held a vote on the competing alternatives, including an option for "don't do anything". I'm hoping to hold a similar referendum on this PEP once I've had time to work on it a bit more.</div><div><br></div><div>[1] <a href="https://www.python.org/dev/peps/pep-0308/">https://www.python.org/dev/peps/pep-0308/</a><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Sep 23, 2015 at 12:47 PM, Steven D'Aprano <span dir="ltr"><<a href="mailto:steve@pearwood.info" target="_blank">steve@pearwood.info</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I've now read PEP 505, and I would like to comment.<br>
<br>
Executive summary:<br>
<br>
- I have very little interest in the ?? and ?= operators, but don't<br>
  object to them: vote +0<br>
<br>
- I have a little more interest in ?. and ?[ provided that the<br>
  precedence allows coalescing multiple look-ups from a single<br>
  question mark: vote +1<br>
<br>
- if it uses the (apparent?) Dart semantics, I am opposed: vote -1<br>
<br>
- if the syntax chosen uses || or !| as per Nick's suggestion,<br>
  I feel the cryptic and ugly syntax is worse than the benefit:<br>
  vote -1<br>
<br>
<br>
In more detail:<br>
<br>
I'm sympathetic to the idea of reducing typing, but I think it is<br>
critical to recognise that reducing typing is not always a good thing.<br>
If it were, we would always name our variables "a", "b" etc, the type of<br>
[] would be "ls", and we would say "frm col impt ODt". And if you have<br>
no idea what that last one means, that's exactly my point.<br>
<br>
Reducing typing is a good thing *up to a point*, at which time it<br>
becomes excessively terse and cryptic. One of the things I like about<br>
Python is that it is not Perl: it doesn't have an excess of punctuation<br>
and short-cuts. Too much syntactic sugar is a bad thing.<br>
<br>
The PEP suggests a handful of new operators:<br>
<br>
(1) Null Coalescing Operator<br>
<br>
    spam ?? eggs<br>
<br>
equivalent to a short-circuiting:<br>
<br>
    spam if spam is not None else eggs<br>
<br>
I'm ambivalent about this. I don't object to it, but nor does it excite<br>
me in the least. I don't think the abbreviated syntax gains us enough in<br>
expressiveness to make up for the increase in terseness. In its favour,<br>
it can reduce code duplication, and also act as a more correct<br>
alternative to `spam or eggs`. (See the PEP for details.)<br>
<br>
So I'm a very luke-warm +0 on this part of the PEP.<br>
<br>
<br>
<br>
(2) None coalescing assignment<br>
<br>
    spam ?= eggs<br>
<br>
being equivalent to:<br>
<br>
    if spam is None:<br>
        spam = eggs<br>
<br>
For the same reasons as above, I'm luke-warm on this: +0.<br>
<br>
<br>
<br>
(3) Null-Aware Member Access Operator<br>
<br>
    spam?.attr<br>
<br>
being equivalent to<br>
<br>
    spam.attr if spam is not None else None<br>
<br>
To me, this passes the test "does it add more than it costs in cryptic<br>
punctuation?", so I'm a little more positive about this.<br>
<br>
If my reading is correct, the PEP underspecifies the behaviour of this<br>
when there is a chain of attribute accesses. Consider:<br>
<br>
    spam?.eggs.cheese<br>
<br>
This can be interpreted two ways:<br>
<br>
    (a)  (spam.eggs.cheese) if spam is not None else None<br>
<br>
    (b)  (spam.eggs if spam is not None).cheese<br>
<br>
but the PEP doesn't make it clear which behaviour they have in mind.<br>
Dart appears to interpret it as (b), as the reference given in the<br>
PEP shows this example:<br>
<br>
    [quote]<br>
    You can chain ?. calls, for example:<br>
    obj?.child?.child?.getter<br>
    [quote]<br>
<br>
<a href="http://blog.sethladd.com/2015/07/null-aware-operators-in-dart.html" rel="noreferrer" target="_blank">http://blog.sethladd.com/2015/07/null-aware-operators-in-dart.html</a><br>
<br>
That would seem to imply that obj?.child.child.getter would end up<br>
trying to evaluate null.child if the first ?. operator returned null.<br>
<br>
I don't think the Dart semantics is useful, indeed it is actively<br>
harmful in that it can hide bugs:<br>
<br>
Suppose we have an object which may be None, but if not, it must<br>
have an attribute spam which in turn must have an attribute eggs. This<br>
implies that spam must not be None. We want:<br>
<br>
    obj.spam.eggs if obj is not None else None<br>
<br>
Using the Dart semantics, we chain ?. operators and get this:<br>
<br>
    obj?.spam?.eggs<br>
<br>
If obj is None, the expression correctly returns None. If obj is not<br>
None, and obj.spam is not None, the expression correctly returns eggs.<br>
But it is over-eager, and hides a bug: if obj.spam is None, you want to<br>
get an AttributeError, but instead the error is silenced and you get<br>
None.<br>
<br>
So I'm -1 with the Dart semantics, and +1 otherwise.<br>
<br>
<br>
<br>
(3) Null-Aware Index Access Operator<br>
<br>
    spam?[item]<br>
<br>
being similar to spam.attr. Same reasoning applies to this as for<br>
attribute access.<br>
<br>
<br>
<br>
Nick has suggested using || instead of ??, and similar for the other<br>
operators. I don't think this is attractive at all, but the deciding<br>
factor which makes Nick's syntax a -1 for me is that it is inconsistent<br>
and confusing. He has to introduce a !| variation, so the user has to<br>
remember when to use two |s and when to use a ! instead, whether the !<br>
goes before or after the | and that !! is never used.<br>
<span class="HOEnZb"><font color="#888888"><br>
<br>
<br>
--<br>
Steve<br>
_______________________________________________<br>
Python-ideas mailing list<br>
<a href="mailto:Python-ideas@python.org">Python-ideas@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-ideas" rel="noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/python-ideas</a><br>
Code of Conduct: <a href="http://python.org/psf/codeofconduct/" rel="noreferrer" target="_blank">http://python.org/psf/codeofconduct/</a><br>
</font></span></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr">Mark E. Haase<br><a style="color:rgb(17,85,204)">202-815-0201</a><br></div></div>
</div>