[Python-ideas] PEP 505 [was Re: Null coalescing operators]
Steven D'Aprano
steve at pearwood.info
Wed Sep 23 18:47:00 CEST 2015
I've now read PEP 505, and I would like to comment.
Executive summary:
- I have very little interest in the ?? and ?= operators, but don't
object to them: vote +0
- I have a little more interest in ?. and ?[ provided that the
precedence allows coalescing multiple look-ups from a single
question mark: vote +1
- if it uses the (apparent?) Dart semantics, I am opposed: vote -1
- if the syntax chosen uses || or !| as per Nick's suggestion,
I feel the cryptic and ugly syntax is worse than the benefit:
vote -1
In more detail:
I'm sympathetic to the idea of reducing typing, but I think it is
critical to recognise that reducing typing is not always a good thing.
If it were, we would always name our variables "a", "b" etc, the type of
[] would be "ls", and we would say "frm col impt ODt". And if you have
no idea what that last one means, that's exactly my point.
Reducing typing is a good thing *up to a point*, at which time it
becomes excessively terse and cryptic. One of the things I like about
Python is that it is not Perl: it doesn't have an excess of punctuation
and short-cuts. Too much syntactic sugar is a bad thing.
The PEP suggests a handful of new operators:
(1) Null Coalescing Operator
spam ?? eggs
equivalent to a short-circuiting:
spam if spam is not None else eggs
I'm ambivalent about this. I don't object to it, but nor does it excite
me in the least. I don't think the abbreviated syntax gains us enough in
expressiveness to make up for the increase in terseness. In its favour,
it can reduce code duplication, and also act as a more correct
alternative to `spam or eggs`. (See the PEP for details.)
So I'm a very luke-warm +0 on this part of the PEP.
(2) None coalescing assignment
spam ?= eggs
being equivalent to:
if spam is None:
spam = eggs
For the same reasons as above, I'm luke-warm on this: +0.
(3) Null-Aware Member Access Operator
spam?.attr
being equivalent to
spam.attr if spam is not None else None
To me, this passes the test "does it add more than it costs in cryptic
punctuation?", so I'm a little more positive about this.
If my reading is correct, the PEP underspecifies the behaviour of this
when there is a chain of attribute accesses. Consider:
spam?.eggs.cheese
This can be interpreted two ways:
(a) (spam.eggs.cheese) if spam is not None else None
(b) (spam.eggs if spam is not None).cheese
but the PEP doesn't make it clear which behaviour they have in mind.
Dart appears to interpret it as (b), as the reference given in the
PEP shows this example:
[quote]
You can chain ?. calls, for example:
obj?.child?.child?.getter
[quote]
http://blog.sethladd.com/2015/07/null-aware-operators-in-dart.html
That would seem to imply that obj?.child.child.getter would end up
trying to evaluate null.child if the first ?. operator returned null.
I don't think the Dart semantics is useful, indeed it is actively
harmful in that it can hide bugs:
Suppose we have an object which may be None, but if not, it must
have an attribute spam which in turn must have an attribute eggs. This
implies that spam must not be None. We want:
obj.spam.eggs if obj is not None else None
Using the Dart semantics, we chain ?. operators and get this:
obj?.spam?.eggs
If obj is None, the expression correctly returns None. If obj is not
None, and obj.spam is not None, the expression correctly returns eggs.
But it is over-eager, and hides a bug: if obj.spam is None, you want to
get an AttributeError, but instead the error is silenced and you get
None.
So I'm -1 with the Dart semantics, and +1 otherwise.
(3) Null-Aware Index Access Operator
spam?[item]
being similar to spam.attr. Same reasoning applies to this as for
attribute access.
Nick has suggested using || instead of ??, and similar for the other
operators. I don't think this is attractive at all, but the deciding
factor which makes Nick's syntax a -1 for me is that it is inconsistent
and confusing. He has to introduce a !| variation, so the user has to
remember when to use two |s and when to use a ! instead, whether the !
goes before or after the | and that !! is never used.
--
Steve
More information about the Python-ideas
mailing list