* Errors must be explicitly listed as part of the function signature. Checked exceptions and the equivalent for exceptions but they are rarely used in practice. I think Android uses them, but they were so unpopular in C++ that they removed them from the language!
* The syntax to catch and handle errors is very different and more more verbose for exceptions. It can also make flow control a real pain in some languages where you can't declare a variable outside the try body (e.g. references in C++).
* Result errors need to be explicitly handled whereas exceptions are silently propagated by default.
Even though they're similar enough that you could translate one to the other in most cases, they're different enough that saying one is "an emulation" of the other is just stupid.
In my experience Result-based handling is far superior with two exceptions:
1. In functional code like map & filter where it can become quite awkward to explicitly deal with returning errors.
2. It's hard to get a stack trace from where the Err was created rather than from where it was unwrapped. Less of a problem with exceptions which record a stack trace from where they were thrown (in most languages anyway - C++ is an annoying exception).
I did say that indeed. Am I to conclude doing so was stupid? If so I would find that very rude.
(For what it's worth I was trying to understand what astrange meant by "it has exceptions which are a bad language feature, and typed throws which are a worse one" and offering that characterization as a way of trying to tease out exactly what he/she meant. Your response contains many interesting points and I would otherwise be interested in discussing with you further, but I'm not too inclined to now that you have suggested you might think I'm stupid.)
In principle, static analysis could identify unhandled exceptions, then trace the exception, then make that information available to the top-level "Err returned from main" handler. In practice, that's never going to happen in Rust.