A try statement with a finally block is executed by first executing the try block. Then there is a choice: If execution of the try block completes normally, then the finally block is executed, and then there is a choice: If the finally block completes normally, then the try statement completes normally. If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S. If execution of the try block completes abruptly because of a throw of a value V, then there is a choice: If the run-time type of V is assignment compatible with a catchable exception class of any catch clause of the try statement, then the first (leftmost) such catch clause is selected. The value V is assigned to the parameter of the selected catch clause, and the block of that catch clause is executed. Then there is a choice: If the catch block completes normally, then the finally block is executed. Then there is a choice: If the finally block completes normally, then the try statement completes normally. If the finally block completes abruptly for any reason, then the try statement completes abruptly for the same reason. If the catch block completes abruptly for reason R, then the finally block is executed. Then there is a choice: If the finally block completes normally, then the try statement completes abruptly for reason R. If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded). If the run-time type of V is not assignment compatible with a catchable exception class of any catch clause of the try statement, then the finally block is executed. Then there is a choice: If the finally block completes normally, then the try statement completes abruptly because of a throw of the value V. If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and the throw of value V is discarded and forgotten). If execution of the try block completes abruptly for any other reason R, then the finally block is executed, and then there is a choice: If the finally block completes normally, then the try statement completes abruptly for reason R. If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded).Of course, each individual phrase/clause/statement is perfectly reasonable, however as a whole it is utterly incomprehensible, quite literally almost impossible to remember, and hence extremely difficult to code correctly against. Plus the whole checked vs. unchecked exceptions doobry-mah-jiig goes on top of all of that, albeit that is more at the function declaration level, it still significantly impacts on what is and is not a permitted catch clause, in java.
By adopting a simpler scheme with no finally clause and a single catch clause this becomes (for phix):
The catch clause is only entered if an exception occurs during the execution of the try block or any routines invoked from within that block. There is no special exception handling within the catch block other than any already in place before and after the try statement. You may however nest try statements to any depth, in either the try or the catch block, or both.Which certainly fits inside my little brain a bit more readily. You may also like to compare the official definition of java exception handling when there is no finally clause:
A try statement without a finally block is executed by first executing the try block. Then there is a choice: If execution of the try block completes normally, then no further action is taken and the try statement completes normally. If execution of the try block completes abruptly because of a throw of a value V, then there is a choice: If the run-time type of V is assignment compatible with a catchable exception class of any catch clause of the try statement, then the first (leftmost) such catch clause is selected. The value V is assigned to the parameter of the selected catch clause, and the block of that catch clause is executed, and then there is a choice: If that block completes normally, then the try statement completes normally. If that block completes abruptly for any reason, then the try statement completes abruptly for the same reason. If the run-time type of V is not assignment compatible with a catchable exception class of any catch clause of the try statement, then the try statement completes abruptly because of a throw of the value V. If execution of the try block completes abruptly for any other reason, then the try statement completes abruptly for the same reason.While certainly simpler than the "with finally" we just saw, it still somehow strikes me as being somehow deliberately over-egged in order to make the whole finally concept seem slightly less ridiculous (and at least in my opinion, failing badly in that attempt). FYI, I now understand why the finally clause is useful in java:
"try catch e"
has at least 3 execution paths: {completes normally,
assignment compatible with e, not assignment compatible}, and more catch clauses == more paths, so the following boolean would probably
not suffice.
At least in the much simplified phix approach, the only thing that a finally block (which this whole page is a bit of a rant against) could save is a simple boolean flag:
bool rethrow = false sequence e -- (predeclare, so it outlives the catch clause) try <try block> catch e rethrow = true -- (or some other conditional/expression) end try <finally block> if rethrow then throw(e) end ifI will concede, however, that a complex (exception-throwing) catch clause or finally block may need a nested try statement or two.
Of course you could instead factor out the cleanup code to a secondary routine that can be invoked from several places.
Should another try block exist, you might want to give the exception a different name and explicitly choose whether or not to overwrite e, effectively rethrowing the inner exception (after letting the finally block run) and discarding the outer e. Specifically, all those implicit rules for reasons S/R/V of java are replaced with explicit code fully under your control.