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. -- https://mail.python.org/mailman/listinfo/python-list