[Python-ideas] Fwd: Null coalescing operator
Guido van Rossum
guido at python.org
Sun Sep 11 20:26:53 EDT 2016
On Sun, Sep 11, 2016 at 12:44 PM, Daniel Moisset
<dmoisset at machinalis.com> wrote:
> Both this discussion, PEP 505, and the one a year ago, tend to mix up 2
> related but separate proposals:
I don't think there's that much of a mix-up. PEP 505 clearly describes
each proposal separately and even gives a choice to accept or reject
each one separately.
> (A) Add a None-coalescing operator (like C# a ?? b, what you would write in
> Python as "a or b" if it didn't have the falsy gotcha)
https://www.python.org/dev/peps/pep-0505/#none-coalescing-operator
> (B) Add some None-aware navigation operators ( The "?.", "?()", "?[]", or
> what you would write in python as "a and a.attribute" if it didn't have the
> falsy gotcha)
https://www.python.org/dev/peps/pep-0505/#none-aware-attribute-access-operator
> Both are things that can be already done in python, so the purpose here is
> to add some convenience (aka "syntax sugar"). IMO, this kind of syntax sugar
> proposals should be weighed with the frequency of the coding pattern where
> the sugar can be applied. And from the stats presented in PEP-505 (B) is one
> order of magnitude less usual than (A); that matches most of the examples I
> see in the threads and FWIW my personal experience.
I can't argue here yet. Honestly I looked at some examples; for those
where it wasn't instantly clear that a None-coalescing operator would
*not* help, I found it hard to figure out how to rewrite it. E.g. this
one -- quick, is there a better way?
return "Illegal Argument" + (self.message is not None and (": " +
self.message) or "")
I think the answer is, if we had both None-coalescing (??) and
None-severing (!!) it could be written as follows:
return "Illegal Argument" + ((self.message !! (": " + self.message)) ?? "")
but it took me way too long to prove that to myself.
> So, as a counterproposal I would like to suggest:
>
> * Add an "a ?? b" operator which is equivalent to "a if a is None else b"
> (but evaluating a once)
> * Do not add none-aware navigation; in the less usual scenario where you
> need to do it AND ALSO the "and" operator is not usable (it frequently is,
> given that by default classes are truish), well, you can use a ternary
> operator
Honestly the one thing that makes `?.` attractive is that it's easier
than the None-coalescing and -severing operators to grasp at an
intuitive level. If "foo.bar" raises "AttributeError: 'NoneType'
object has no attribute 'foo'" then try again with "foo?.bar". It's
surprising how often that will work!
> * I don't care if it's an alternate syntax (I'm surprised nobody suggested
> "||" which is also used in other languages for similar purpose)
Interestingly, after analyzing the above example I desperately want to
write it as
return "Illegal Argument" + (self.message && (": " + self.message) || "")
Note that I already know the relative priorities of && and ||, so I
can drop a set of parentheses.
> Would this satisfy most of the people requesting this? (and, would it
> satisfy the people making the decision?)
Personally, after the above example, I'm less excited about ??/!! or
||/&&, and more excited about `?.` -- so it doesn't satisfy me.
--
--Guido van Rossum (python.org/~guido)
More information about the Python-ideas
mailing list