`results.Result[T, E]` is a type for representing the outcome of some
computation or an error - what `E` is depends on the desired granularity of
error information: depending on requirements, it can be a simple type like an
`enum` or a `string`, or a dynamic type like a `ref object` that gives it the
same expressivity as exceptions in general.
Sometimes there is no meaningful error information at all - an operation either
succeeds or fails, the result of such an operation being an optional value. In
Nim, we use `options.Option` for representing such optional values.
With `results`, the way to represent such a case would be `Result[T, void]`,
and `results` now conveniently exposes an alias `Opt[T] = Result[T, void]` and
functions for working with such values:
let v = Opt.some(42)
if v.isSome():
echo v.get()
var x: Opt[int]
doAssert x.isNone()
x = v
doAsert x.isSome()
Run
We've been using these facilities in several projects and it turns out that
it's pretty convenient to be able to switch between `Opt` and `Result`, as well
as using the typical `results` utilities like `?`:
func f(): Opt[int] = Opt.some(42)
func r(): Result[int, cstring] = discard
func f2(): Opt[int] =
let v = f().valueOr:
10+32 # Use a lazy-computed default
let v2 = ? f() # Return early if `f` fails
let rv = ? r().mapErr(proc (_: auto) = discard) # drop rich error
information
...
Run
Incidentally, this solves the same problem as
<https://github.com/nim-lang/Nim/pull/18401> and
<https://github.com/nim-lang/Nim/pull/19828> set out to solve - allowing `null`
in `Option` for pointers.
Enjoy!