Jan Wieck wrote:
There is no "try" in Tcl.
The syntax is
catch { block-of-commands } [variable-name]
Catch returns a numeric result, which is 0 if there was no exception thrown inside of the block-of-commands. The interpreter result, which would be the exceptions error message in cleartext, is assigned to the optional variable specified. Thus, your code usually looks like this:
if {[catch {statements-that-might-fail} err]} { on-error-action } else { on-success-action }
Ok, I wasn't trying to write tcl ;-) just pseudo code proving a point. This particular point is only valid until you expose the savepoint API's (as you now suggest) though, so no disagreement there.
Your example shows where leaving the burdon on the programmer can improve performance. But change it to this:
foo {} { spi-calls;
if {[catch {spi-call} err]} { return "boo: $err" } return "hooray" }
This function never throws any exception. And any normal Tcl programmer would expect that the spi-calls done before the catch will either abort the function on exception, or if they succeed, they get committed. What you mean with "normal" savepoint handling in fact means that we don't change catch at all but just expose the savepoint feature on the Tcl level.
Maybe Tcl programmers use catch very differently from what I'm used to with try/catch in C++, C#, and Java. There, it's very common that you use a catch to make sure that resources that you've utilized are freed up, to do error logging, and to deal with errors that are recoverable.
If a catch containing an spi-function automatically implies a subtransaction, then it might affect how people design their code since the subtransaction is much more expensive then a mere catch.
Ideally, in a scenario where the caller of foo also calls other functions and want to treat the whole call chain as a atomic, he would start a subtransaction and do all of those calls within one catch where an error condition would yield a rollback. Within each function he still might want to catch code that eventually contains spi-calls but not for the purpose of rolling back. The error condition is perhaps not even caused by the spi-call but by something else that happened within the same block of code. If it's unrecoverable, then he re-throws the error of course.
The catch functionality is likely to be lean and mean. Implied subtransactions will make it slower and thus not as suitable for control flow as it normally would be. Where I come from, frequent use of try/catch is encouraged since it results in good program design. I'm concerned that what you are suggesting will make developers think twice before they use a catch since they know what's implied.
I still believe that both catch (with try or no try) and savepoints are simple and well known concepts that will benefit from being kept separate.
Regards, Thomas Hallgren
---------------------------(end of broadcast)--------------------------- TIP 8: explain analyze is your friend