Implement try/fault expressions
I would like F# to have try/fault expressions. It would work along the same lines as the current try/with syntax, although the 'fault' block would be constrained to a return type of 'unit'. I don't expect the usage of this to be terribly common, but it would be very handy to have for logging purposes.
To answer the inevitable question, "Why not just use try/with and reraise()?" -- with try/with you're actually catching the exception; unless you remember to call reraise() to terminate all paths in the control flow within the 'with' block, you'll end up swallowing the exception and not getting the expected behavior. Similarly, if an inexperienced (or perhaps just inattentive) developer re-raises the exception with 'raise' instead of 'reraise', the stack trace information will be lost.
With try/fault, it'd be easy to log relevant information (e.g., variable values) from functions when unwinding the stack due to an exception being thrown, without the downside of being able to affect the control flow.
Don Syme commented
One approach to this would be to add an OnException combinatory accepting a pair of functions. Likewise an Async.OnException.
Don Syme commented
My inclination is that we won't do this in F#. I can see the use cases though - are there really no other ways to achieve this in .NET, e.g. by calling a library function with two lambdas?
Jack Pappas commented
Jon -- With try/finally, the code in the finally block is always executed, whether an exception is raised within the protected (try) block or not. With try/fault, the code in the fault block is executed *only* when an exception has been raised in the try block.
It would be possible to emulate try/fault behavior with try/finally by writing something like this:
let mutable error = true
// code which may or may not raise an exception
error <- false
if error then ... // execute the "fault" handler
but it's hacky and I'd prefer just to use a true 'fault' block (which is already a feature supported by the CLR). In addition, the code to implement try/finally in the compiler is basically identical to what's needed for try/fault, so it should be fairly straightforward to implement this. If this language feature were accepted, I'd be happy to contribute an implementation (or attempt to).
Jon Harrop commented
Why not use try..finally?