Re: [Python-ideas] PEP 505 -- None-aware operators
On Oct 14, 2016 9:14 AM, "Gustavo Carneiro"
Sorry if I missed the boat, but only just now saw this PEP.
Glancing through the PEP, I don't see mentioned anywhere the SQL
alternative of having a coalesce() function: https://www.postgresql.org/docs/9.6/static/functions-conditional.html#FUNCTI...
In Python, something like this:
def coalesce(*args): for arg in args: if arg is not None: return arg return None
Just drop it into builtins, and voila. No need for lengthy discussions
about which operator to use because IMHO it needs no operator.
Sure, it's not as sexy as a fancy new operator, nor as headline grabbing,
but it is pretty useful. That function is for a different purpose. It selects the first non-null value from a flat collection. The coalesce operators are for traveling down a reference tree, and shortcutting out without an exception if the path ends. For example: return x?.a?.b?.c instead of: if x is None: return None if x.a is None: return None if x.a.b is None: return None return x.a.b.c You can use try-catch, but you might catch an irrelevant exception. try: return x.a.b.c except AttributeError: return None If `x` is an int, `x.a` will throw an AttributeError even though `x` is not None. A function for the above case is: def coalesce(obj, *names): for name in names: if obj is None: return None obj = getattr(obj, name) return obj return coalesce(x, 'a', 'b', 'c') See this section for some examples: https://www.python.org/dev/peps/pep-0505/#behavior-in-other-languages (The PEP might need more simple examples. The Motivating Examples are full chunks of code from real libraries, so they're full of distractions.)
My mistake. You're talking about the ?? operator, and I'm thinking about
the null-aware operators.
You say short-circuiting would be nice to have, but short-circuiting is
what people want it for. As for using `if-else`, that's listed as an
alternative here:
https://www.python.org/dev/peps/pep-0505/#ternary-operator
The coalesce operator has the semantic advantage ("expressiveness"?): you
are saying what you want to do, rather than how you do it. Making a
function is one way to get semantic advantage, but you can't do that if you
want short-circuiting.
The question on the table is whether the semantic advantage is worth the
cost of a new operator. That's a value question, so it's not gonna be easy
to answer it with objective observations.
(Not that I'm suggesting anything, but some languages have custom
short-circuiting, via macros or lazy arg evalation. That's be using a
missile to hammer in a nail.)
On Oct 14, 2016 9:46 AM, "Franklin? Lee"
On Oct 14, 2016 9:14 AM, "Gustavo Carneiro"
wrote: Sorry if I missed the boat, but only just now saw this PEP.
Glancing through the PEP, I don't see mentioned anywhere the SQL
alternative of having a coalesce() function: https://www.postgresql.org/docs/9.6/static/functions-conditional.html#FUNCTI...
In Python, something like this:
def coalesce(*args): for arg in args: if arg is not None: return arg return None
Just drop it into builtins, and voila. No need for lengthy
discussions about which operator to use because IMHO it needs no operator.
Sure, it's not as sexy as a fancy new operator, nor as headline
grabbing, but it is pretty useful.
That function is for a different purpose. It selects the first non-null value from a flat collection. The coalesce operators are for traveling down a reference tree, and shortcutting out without an exception if the path ends.
For example: return x?.a?.b?.c instead of: if x is None: return None if x.a is None: return None if x.a.b is None: return None return x.a.b.c
You can use try-catch, but you might catch an irrelevant exception. try: return x.a.b.c except AttributeError: return None If `x` is an int, `x.a` will throw an AttributeError even though `x` is not None.
A function for the above case is: def coalesce(obj, *names): for name in names: if obj is None: return None obj = getattr(obj, name) return obj
return coalesce(x, 'a', 'b', 'c')
See this section for some examples: https://www.python.org/dev/peps/pep-0505/#behavior-in-other-languages
(The PEP might need more simple examples. The Motivating Examples are full chunks of code from real libraries, so they're full of distractions.)
On 14 October 2016 at 14:46, Franklin? Lee
On Oct 14, 2016 9:14 AM, "Gustavo Carneiro"
wrote: Sorry if I missed the boat, but only just now saw this PEP.
Glancing through the PEP, I don't see mentioned anywhere the SQL
alternative of having a coalesce() function: https://www. postgresql.org/docs/9.6/static/functions-conditional. html#FUNCTIONS-COALESCE-NVL-IFNULL
In Python, something like this:
def coalesce(*args): for arg in args: if arg is not None: return arg return None
Just drop it into builtins, and voila. No need for lengthy discussions
about which operator to use because IMHO it needs no operator.
Sure, it's not as sexy as a fancy new operator, nor as headline
grabbing, but it is pretty useful.
That function is for a different purpose. It selects the first non-null value from a flat collection. The coalesce operators are for traveling down a reference tree, and shortcutting out without an exception if the path ends.
For example: return x?.a?.b?.c
From what I can read in the PEP, it attacks 3 different problems at once:
1. The " null -coalescing" operator is a binary operator that returns its
left operand if it is not null . Otherwise it returns its right operand. 2. The " null -aware member access" operator accesses an instance member only if that instance is non- null . Otherwise it returns null . (This is also called a "safe navigation" operator.) 3. The " null -aware index access" operator accesses an element of a collection only if that collection is non- null . Otherwise it returns null . (This is another type of "safe navigation" operator.)
I am proposing a coalesce() function as alternative for (solely) problem 1, while you are talking about problem 2. I do believe problems 2 and 3 are interesting too, and of course coalesce() does not work for them, they do need their own operators. Sorry, I was a bit confused by the PEP attacking 3 (related) problems at once. Thanks. -- Gustavo J. A. M. Carneiro Gambit Research "The universe is always one step beyond logic." -- Frank Herbert
participants (2)
-
Franklin? Lee
-
Gustavo Carneiro