11

After using F# option type for a while, I realize that it could be used for handling exceptional cases. I can use either option or Exception in the following examples:

  1. The find functions from List/Array/Seq modules raise KeyNotFoundException in uncommon cases, while corresponding tryFind counterparts return None in those situations.
  2. When I do backtracking (in solving N-queens, Sudoku, etc), whenever a branch has no solution, I can either raise an exception and catch it later or return None to match that value to backtrack. Those cases occur quite often until we find a solution.

My impression is option is a more functional approach, while Exception is more commonly-used in the .NET platform.

What are differences between option and Exception in exception handling in terms of usability, performance, etc? In which cases using a technique is better than using the other?

dbc
  • 104,963
  • 20
  • 228
  • 340
pad
  • 41,040
  • 7
  • 92
  • 166

4 Answers4

15

The CLR makes the operation of throwing and catching an exception extremely expensive. For this reason alone, you should prefer constructs like Option for reporting expected failures. If the failure is truly exceptional and nearly unrecoverable, go ahead and throw an exception. But as you note, things like backtracking during a search are unexceptional, and you will find your performance suffers greatly if you implement them with exceptions.

Because this is a property of the CLR, it doesn't really matter whether you are in F# or not. My understanding is that other runtimes for ML-like languages, e.g. ocaml, do not have this characteristic, and so may use exceptions more often for control flow.

Sebastian Good
  • 6,310
  • 2
  • 33
  • 57
  • Indeed, I once measured this and found that C++ exceptions are 6x slower than OCaml and .NET's are 600x slower than OCaml! – J D Nov 01 '11 at 18:33
8

My question is what are differences between Option and Exception in exception handling in terms of usability, performance...?

The option type offers stronger static checking than exceptions, increasing the chances that programmer error will be caught by the compiler. Returning non-exceptionally is likely to be faster than returning Some result but returning exceptionally is hundreds of times slower than returning None.

In which cases using a technique is better than the other?

Whenever I'm writing code like servers and daemons that needs to keep running I catch as many exceptions as possible and replace them with values of union types like option. The static type system then forces me to handle both exceptional and non-exceptional returns in almost all cases, making it much easier to write code that will not die from an exception propagating unexpectedly.

J D
  • 48,105
  • 13
  • 171
  • 274
6

From the theoretical point of view. option is something that you should use in those functions which are pure from FP point of view (you can google about what are pure functions). Exceptions are more about the impure world (Like the IO world in Haskell).

Now from practicably point of view I would suggest using option as return type when the logic of you application says that the value can be there or it cannot be i.e the value not being present is a valid application rule. Exceptions are something which should be raised when something happens in the application logic which indicates the incorrect logic execution or some incorrect application state which was is not expected as par the application rules.

From performance POV throwing exception is more expensive (due to stack unwinding - looking for the appropriate exception handler - etc) as compared to returning option types.

Ankur
  • 33,367
  • 2
  • 46
  • 72
  • I don't agree with the comment about performance. Option types are more lightweight than Exception types (see @Sebastian Good's answer). – pad Oct 31 '11 at 12:24
  • My text says `exception which will bad` .. that means exceptions are not good in performance – Ankur Oct 31 '11 at 12:27
  • +1; Yet, you may want to rephrase your last sentence as I, too, had trouble interpreting it correctly. – Frank Oct 31 '11 at 15:13
  • Updated the last sentence about performance, I hope it is much clear now than the earlier one with strange recursive look :) – Ankur Oct 31 '11 at 16:45
4

In terms of usability I prefer options in F#.

  • Options encapsulate the exceptional state as well as the expected state. This allows you to deffer handling of the exceptional state until you need the expected state.
  • Option also has a number of helper functions you'd have to write yourself with exceptions.
  • Partial Active Patterns allow you to handle multiple exceptional cases very cleanly with options.
  • Optional Paramaters in F# are implemented with Options. This deferred nature I mentioned above allows you to not care what generated the exceptional case, so long as the consumer has a default value for it.

Options are a fundamentally different way of thinking about exceptional cases and I believe help to make F# special.

gradbot
  • 13,732
  • 5
  • 36
  • 69
  • +1 for a very thoughtful answer. That's what I want to know about using option in exception handling. – pad Oct 31 '11 at 22:51