match fallible_function() {
Err(e) => // handle error
Ok(val) => // do something with val
}
In this case, you of course don't need to annotate the outer function's type with its possibility of failure. In the case where you use ?, you of course do have to annotate the possibility of failure. However, I think trying to argue that this is more painful as syntactic ceremony than constant nil checks is a non-starter.
2. You can create custom errors for a specific function, and put any data that you would have passed to Errorf inside. This way you get the ability to introspect errors to see what went wrong programmatically, and all that data is available for later inspection. Note that we could also have returned a formatted string on error instead of FallibleError exactly like in Go if we wanted to.
Of course, the way you'd write fallible_function if you weren't going out of your way to be verbose would be like this:
Separately, the point of all this is to be able to statically know whether a function can fail or not. We know for a fact that fallible_function can fail. If we write a function
We know for a fact it won't fail (unless it panics, but well behaved code should never panic). We don't even have to worry about the possibility of nils getting in there and screwing us up.