I suggest we ...

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.

5 votes
Vote
Sign in
(thinking…)
Sign in with: facebook google
Signed in as (Sign out)
You have left! (?) (thinking…)
Jack Pappas shared this idea  ·   ·  Flag idea as inappropriate…  ·  Admin →

4 comments

Sign in
(thinking…)
Sign in with: facebook google
Signed in as (Sign out)
Submitting...
  • Don Syme commented  ·   ·  Flag as inappropriate

    One approach to this would be to add an OnException combinatory accepting a pair of functions. Likewise an Async.OnException.

  • Don Syme commented  ·   ·  Flag as inappropriate

    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  ·   ·  Flag as inappropriate

    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
    try
    // code which may or may not raise an exception
    error <- false
    finally
    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).

F# Language

Feedback and Knowledge Base