5 ms·
This PEP is a footgun. Remember that exceptions are GOTO. If your exception-handling code is complex enough to be at all tricky you have a state machine and i
by carapace 5y ago
This PEP is a footgun. Remember that exceptions are GOTO.
If your exception-handling code is complex enough to be at all tricky you have a state machine and it behooves you to make that ad hoc machine explicit.
Do not implement a multiplexing GOTO.
- kdmccormick 5y agoI see this sentiment a lot in language discussions; I really think the exceptions==goto parallel is overstated. Exceptions are a recognition of and abstraction over a common pattern from exception-less languages: "if <error state>, return early with a special value and some info on the error". Client functions follow a pattern of "if <error returned>, then handle the error or propogate it upwards". If you factor out that chain of early returns, you get "throw"/"raise". If you factor out the error handling, you get "catch"/"except". And if you turn that error info into an object/ADT, then you get the "Exception" class. Exceptions are not adding anything new; it's syntactic sugar over a more verbose pattern you'd probably be using anyway. You could totally implement a clunky but logically equivalent version of exceptions yourself in any language. Now, that being said, there's definitely a case to be made for avoiding over-abstracting and preferring explicitness to implicit magic. But that's much different than saying that exceptions are a under-abstraction like GOTO.
- deleted 5y ago[deleted]
- R0b0t1 5y agoI routinely encounter places where I am forced to use try..except where it would be better and more easily understood if I did not have to work around the fact I am forced to goto out of the current scope.
- guenthert 5y agoI didn't downvote you, but I suspect you have been because you're mistaken. try...except doesn't force you to go out of scope, it keeps you in it. raising an exception leaves the scope, but nobody forces you to use it.
- R0b0t1 5y agoNot mistaken. The try..except creates a scope. It is not always, but often, that I need to address this new nested scope when structuring exception handling when I could simply not if exceptions were not used.
- formerly_proven 5y agoYou are mistaken. try...except does not introduce a scope in Python. Only "def" and "class" do.
- kdmccormick 5y agoYup. try: x = uncertain_op() except ...: x = 'fallback' do_something(x) is a common Python idiom; no initial definition required. Although this isn't true in every language.
- R0b0t1 5y agoHm, I suppose you're right. I just tested it. I can't for the life of me remember what I was thinking of then.
- formerly_proven 5y agoIn many (most?) other languages compounds / blocks always introduce a scope. E.g. in C++ (or Java) try { /* new scope */ } catch (FooException &foo) { /* another scope */ } Python is probably one of not that many languages where this is not the case.
- wvenable 5y ago> Remember that exceptions are GOTO. This is not true and I wish people would stop repeating this falsehood. If you had multi-valued returns and propagated every single error at every call site you will have implemented exceptions exactly.
- jcelerier 5y ago> If your exception-handling code is complex enough to be at all tricky you have a state machine and it behooves you to make that ad hoc machine explicit. 1980: "that error handling code is a tedious and repetitive state machine, how could we abstract it ? ... let's create exceptions !" 2020: "exceptions implement a state machine, that state machine should be visible error-handling code ! let's remove exceptions and make error handling explicit" 2060: "that error handling code is a tedious and repetitive state machine, how could we abstract it ? "
- BiteCode_dev 5y agoExceptions are not a GOTO: - they cannot make you end up any place in the code, only up the stack. - going up in the stack, it leads to the destruction of any frame in the way. - the exception object carries metadata about the origin and propagation. - calling code can subscribe to the event and act on it. Handling is decoupled from raising. - calling code can interrupt (in multiple spots) or stop the propagation.
- aranchelk 5y agoMany excellent points. I had never encountered the idea of exception=goto. My initial thoughts: 1) In the case of goto, behavior is determined in the invocation. Conversely, when throwing an exception, the behavior is determined by the surrounding try block, which very is often well outside the scope of that throw. In this sense they seem like polar opposites. 2) You can model exceptions as monads: create a wrapper type that can either hold a regular value or a failure. Then create a helper function that processes these wrapped values. When encountering a wrapped regular value, the helper unwraps it and runs the next computation; on encountering a failure the helper skips the next computation and passes on the failure. The computations take unwrapped regular values as input, but they return the wrapped type. Not only is this how exceptions are done in pure functional languages, to my mind it’s the most implementation-independent way to think about what they actually are. This description bears no resemblance to goto.
- tsimionescu 5y agoExceptions are just as much goto as return is. They are just a jump up the stack.