There are remarkably few situations involving recoverable errors, though, and they almost all look like "not found"--which includes your parse integer example--and, even then, most of the time you will want a forceful automatic exception variant and not a "recoverable" error value as there is almost never anything to do instead: try-parse is so rare of a thing that is correct to do it warrants having a quick "try" attached to the expression.
In contrast, there are a billion ways in which almost every line of code can fail--even stuff people are super sure could never fail is still usually at least subject to stack exhaustion--and almost none of these failures are things you should locally "handle"; and yet in many--even most--cases these are situations you can still recover from at a higher level if you don't screw up your own logic (which is not the point of these errors).
A parser failing is something I'd expect to be recoverable. And I'd expect it to return where it failed and why. You can do that without throwing exceptions at all, and instead encode it in the type. Like returning a result<parsedObject,failureReason>. (Can be further refined, like adding the already parsed/yet to be parsed string to the failurereason as a value) I WANT to be forced to handle it right there and then rather than potentially forgetting a try catch, or checking the boolean returned if it was successful or checking the out parameter if it is not null (boolean tryparse(out parsedObject) is something I see commonly)
For me it is much more ergonomic to use a
match tryparse somestring with
| Ok obj -> proceedFurther obj
| Error reasons -> handleerror reasons
For truly exceptional cases you don't expect to be recoverable? Yeah, throw an exception.
In contrast, there are a billion ways in which almost every line of code can fail--even stuff people are super sure could never fail is still usually at least subject to stack exhaustion--and almost none of these failures are things you should locally "handle"; and yet in many--even most--cases these are situations you can still recover from at a higher level if you don't screw up your own logic (which is not the point of these errors).