Invoking return through a function?
Steve D'Aprano
steve+python at pearwood.info
Sun Oct 29 20:42:31 EDT 2017
On Mon, 30 Oct 2017 03:35 am, Alberto Riva wrote:
> On 10/29/2017 10:35 AM, Steve D'Aprano wrote:
[...]
>> You mean *less* explicit. "checkKey" gives absolutely no hint that it
>> causes the current function to return.
>
> That's just because I used a name that was too generic in my example. I
> can call it "returnIfKeyMissing", and then it would be clear.
No it wouldn't. That sounds like it is the "returnIfKeyMissing" function that
returns if the key is missing, and presumably pauses forever, never
returning, if the key exists.
Of course we can *learn* that this is not the case, by reading the docs (if it
has any) or the source code (if it is available). But what of every other
function, any one of which might have been named like your first example:
checkKey
We cannot rely on naming conventions, because people won't always follow it.
*Any* function could potentially return early from the caller.
But honestly, if you're prepared to write:
returnIfKeyMissing(dict, key)
that's LONGER than:
if key not in dict: return
Since your motive appears to be the wish to save typing at the expense of
readability and maintainability, then I expect that *in practice* you
wouldn't use "returnIfKeyMissing" but would prefer a less explicit, shorter
name like "checkKey".
[...]
>> You really should re-think your strategy. Your suggestion, if possible,
>> would lead to difficult to maintain code where you couldn't easily tell
>> where the exit points of a function where.
>
> But again, it's just a naming problem.
It *really isn't* a naming problem. Being able to force the caller to return
is a kind of GOTO, and it violates both the letter and the spirit of the
principle that functions should have "one entry, one exit".
Of course we already violate the second part of that, by allowing multiple
returns. But that doesn't mean that any other violation should be acceptable.
Allowing functions to force their caller to exit allows them to violate the
caller's post-condition contracts.
But even if it were just a naming problem, you under-estimate its magnitude.
The word "just" is not justified here: even treated as a naming problem, it
is a big problem. Not an end-of-the-world problem, but still big enough.
> Something like returnIfKeyMissing
> would make it easy to tell where the exit points are.
No it wouldn't, because not everyone is going to use such a clumsy, long
naming convention, either out of ignorance or for some other reason. Maybe
you're using a library where everything is named in Dutch, or Russian. Maybe
the function was named "foo()" long ago, and has only subsequently gained the
ability to force the caller to return but the name was never changed.
> And as Bartc
> pointed out, we already have this situation with exceptions, so it would
> be nothing new.
Pardon me, but it was *me* who pointed out the analogy with exceptions, not
Bart. But this is different from an exception.
The similarity is quite weak:
- any function can raise an exception;
- your hoped for feature would allow any function to cause the
caller to return;
But the differences are profound:
- exceptions are an alternative to normal execution flow, they don't
silently continue unless explicitly caught and silenced;
- if you don't explicitly catch the exception, it is obvious when
one occurs, because your program halts and you get an obvious
stacktrace;
- your suggested force-caller-to-return would silently alter the
control flow of the caller, without warning or signal that it
had happened.
That's a very significant difference.
> Indeed, what I'm asking for could be accomplished by
> wrapping the body of each function in a try/catch block for an ad-hoc
> exception type.
A terrible idea. Why not just write a "validate input" function that checks
your input and returns True for valid and False for invalid, then:
if not valid(args):
return
That's little harder to type than
returnIfNotValid(args)
and much more comprehensible.
> But again, since the language doesn't have macros
And this is the sort of misfeature why Guido is dead-set against Python ever
getting them.
Yes, we get it that Lisp macros are really, really powerful. But there are two
bottle-necks in coding:
- writing the code in the first place;
- maintaining the code afterwards.
Macros are aimed at simplifying the first, at the cost of the second. That's
not a strategy Python follows.
--
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.
More information about the Python-list
mailing list