Exception vs Result
An exception happens after the violation of a precondition in our code. For example, in the code below y ≠ 0
is a precondition:
let x = stdin.ReadLine() |> int
let y = stdin.ReadLine() |> int
let r = x / y
printfn $"{x} / {y} = {r}"
We also know that in some situations it is better to treat the error as any other value than to throw an exception. So the question is, do we represent an error as a value or do we throw an exception?
My way of answering such dilemma is: can the abnormal situation be followed by operations in the same domain where it occurred or do we have to leave it?
In the example above after y = 0
there is no calculation allowing us to continue, it's the user who should know that y = 0
is not part of the domain of the operation. So it makes sense to catch the exception or if possible to never let such value enter that scope.
Sometimes we discover that our domain can be enriched with values representing abnormal situations, and that way we can continue operating within it. However, in some cases, adding a Result
type doesn't change the fact the only thing we can do is leaving one or more scopes.
In those instances an exception is more appropriate because adding Result
is only making more cumbersome our way out.
Originally posted on 2023/10/21 on Twitter
val int: value: 'T -> int (requires member op_Explicit)
--------------------
type int = int32
--------------------
type int<'Measure> = int