Computation does not always provide a result, for various reason. In our case, a frequent case is lexer and parser which can fail to process an ill-formed string.
The traditional way in ES to handle these situations is to throw exceptions and catch them later. This presents two major problems:
- There is no type safety built in exception. Anything can be thrown. Which does make exception handling tricky at best.
- The control flow becomes difficult to follow for humans since a thrown exception might be caught much later in the code. This makes debugging and maintaining high quality code difficult.
We will implement a Result<T, E>
type to model a computation that can either produce a "good" value of type T
or an erroneous one of type E
.
The Result<T, E>
type will be monadic to allow easy chaining of operations that may create errors, or transformations of the result while keeping any error that may have occurred on the way.
The Result<T, E>
type will also be used to model values that, without really being erroneous, can nonetheless be grouped into "good" and "bad" cases; for example a rule expectation that may pass ("good") or fail ("bad").
Accepted.
The Result<T, E>
provides type safety in error handling, and easy to follow control flow.
The resulting code style is closer to Functional Programming languages, which may be unsettling for developers not used to them; but may also ease entry cost for developers used to them…
See more discussion about this choice in "The great refactoring" pull request.