I think the issue with that is that it's a little bit of a solution in search of a problem. Your example of:
fn do_stuff() -> Result<...> {
if condition {
return Error(...)
}
return Ok(...)
} out (r) {
if r.is_err() {
// special cleanup (maybe has access to fn scope vars)
}
}
isn't really superior in any meaningful way (and is arguably worse in some ways) to:
fn do_stuff() -> Result<...> {
if condition {
// special cleanup (maybe has access to fn scope vars)
return Error(...)
}
return Ok(...)
}
For more complicated error handling the various functions on Result probably have all the bases covered.
For what it's worth a lot of my day to day professional work is actually in Java and our code base has adopted various practices inspired by Rust and Haskell. We completely eliminated null from our code and use Optional everywhere and use a compile time static analysis tool to validate that. As for exception handling, we're using the Reactor framework which provides a type very similar to Result, and we essentially never directly throw or catch exceptions any more, it's all handled with the functions Reactor provides for error handling.
I just don't think the potential footguns introduced by null
and exception
s are worth it, the safer type level abstractions of Option
and Result
are essentially superior to them in every way.