[Python-ideas] Null coalescing operators
Brendan Barnwell
brenbarn at brenbarn.net
Tue Sep 22 05:40:59 CEST 2015
On 2015-09-21 15:56, Carl Meyer wrote:
> My jaw dropped a bit when I saw it asserted in this thread that
> functions returning "useful value or None" is an anti-pattern. I write
> functions like that all the time, and I consider it a useful and
> necessary Python idiom. I would hate to rewrite all that code to either
> deal with exceptions or add default-value-argument boilerplate to all of
> them; when "no result" is an expected and normal possibility from a
> function, letting the calling code deal with None however it chooses is
> much nicer than either of those options.
I agree that it's a fine thing. The thing is, it's an API choice. If
your API is "return such-and-such or None", then anyone who calls your
function knows they have to check for None and do the right thing. I
think this is fine if None really does indicate something like "no
result". (The re module uses None return values this way.)
It seems to me that a lot of the "problem" that these null-coalescing
proposals are trying to solve is dealing with APIs that return None when
they really ought to be raising an exception or returning some kind of
context-appropriate empty value. If you're doing result =
someFunction() and then result.attr.upper() and it's failing because
result.attr is None, to me that's often a sign that the API is fragile,
and the result object that someFunction returns should have its attr set
to an empty string, not None.
In other words, if you really want "a null result that I can call all
kinds of string methods on and treat it like a string", you should be
returning an empty string. If you want "a null result I can subscript
and get an integer", you should be returning some kind of
defaultdict-like object that has a default zero value. Or whatever.
There isn't really such a thing as "an object to which I want to be able
to do absolutely anything and have it work", because there's no
type-general notion of what "work" means. From a duck-typing
perspective, if you expect users to try to do anything with a value you
return, what they might reasonably want to do should be a clue as to
what kind of value you should return.
That still leaves the use-case where you're trying to interoperate with
some external system that may have missing values, but I don't see that
as super compelling. Getting an exception when you do
some['big']['json']['object']['value'] and one of the intermediate ones
isn't there is a feature; the bug is the JavaScripty mentality of just
silently passing around "undefined". To my mind, Python APIs that wrap
such external data sources should ideally take the opportunity to
improve on them and make them more Pythonic, by providing sensible,
context-relevant defaults instead of propagating a generic "null" value
willy-nilly.
--
Brendan Barnwell
"Do not follow where the path may lead. Go, instead, where there is no
path, and leave a trail."
--author unknown
More information about the Python-ideas
mailing list