1. non-local control flow can make it difficult to read
2. it also makes it difficult to handle nested errors (eg the catch() itself throws)
3. unchecked exceptions (and implicit propagation) means any function can throw something, at any time -- it's not defined in the API contract -- so if you really wanted to be safe and general, every function needs have exception checking. This is the same problem that null has
4. It also means it can change "under your feet" -- a library can add new exceptions to functions with no indication; this is also possible in rust, but its requires much more finagling by the author.
5. Checked exceptions like in Java are basically the same as rust's error-as-enum, but feature the other points.
6. At least in Java, not all exceptions are checked, but of course that doesn't need to be true.
7. Through developer ergonomics, Exceptions leads the natural strategy of try it, and rollback on failure. Rust Result<> leads the natural strategy of validate, then continue. The latter, IMO, is significantly easier/general/more sane.
8. Through developer ergonomics (avoiding a try-catch every statement), multiple statements are naturally rolled into a single try-catch -- undone when this turns out not to be the case. In the worst case, if you try-catch every statement in a function, its completely unreadable. It's also difficult to know which function throws which error, if you have them rolled up in a single try-catch, with multiple catches.
9. Exception's main job is to put errors in the background; Rust has the philosophy of putting errors in the foreground
10. The main benefit they have over return codes is that return codes are utterly arbitrary, and even less defined in the API contract, or the language itself, than exceptions. They lose out on the other points -- namely that they're significantly more complex. Result<> grants the natural ergonomics of return codes, with a higher level of definition than exceptions.
11. Try-And-Rollback is a generally valid strategy for single-threaded code; less so for parallel code (eg fork-and-join). Result<> fits that model more cleanly.
12. My personally most important point: exceptions are ugly and anyone who likes them is ugly too
That's whatever I could think of off the top of my head.
2. it also makes it difficult to handle nested errors (eg the catch() itself throws)
3. unchecked exceptions (and implicit propagation) means any function can throw something, at any time -- it's not defined in the API contract -- so if you really wanted to be safe and general, every function needs have exception checking. This is the same problem that null has
4. It also means it can change "under your feet" -- a library can add new exceptions to functions with no indication; this is also possible in rust, but its requires much more finagling by the author.
5. Checked exceptions like in Java are basically the same as rust's error-as-enum, but feature the other points.
6. At least in Java, not all exceptions are checked, but of course that doesn't need to be true.
7. Through developer ergonomics, Exceptions leads the natural strategy of try it, and rollback on failure. Rust Result<> leads the natural strategy of validate, then continue. The latter, IMO, is significantly easier/general/more sane.
8. Through developer ergonomics (avoiding a try-catch every statement), multiple statements are naturally rolled into a single try-catch -- undone when this turns out not to be the case. In the worst case, if you try-catch every statement in a function, its completely unreadable. It's also difficult to know which function throws which error, if you have them rolled up in a single try-catch, with multiple catches.
9. Exception's main job is to put errors in the background; Rust has the philosophy of putting errors in the foreground
10. The main benefit they have over return codes is that return codes are utterly arbitrary, and even less defined in the API contract, or the language itself, than exceptions. They lose out on the other points -- namely that they're significantly more complex. Result<> grants the natural ergonomics of return codes, with a higher level of definition than exceptions.
11. Try-And-Rollback is a generally valid strategy for single-threaded code; less so for parallel code (eg fork-and-join). Result<> fits that model more cleanly.
12. My personally most important point: exceptions are ugly and anyone who likes them is ugly too
That's whatever I could think of off the top of my head.