On Thu, May 16, 2013 at 7:58 PM, Graydon Hoare <gray...@mozilla.com> wrote:
> > I'm sympathetic to the desire here, as with all attempts to "get > exceptions right". Sadly I've never really seen it; I don't think anyone > has really worked out the "right" way to work with catchable-exceptions in > a language. > > -Graydon > What's problematic about exceptions in C++, and what forces you to "worry about exceptions everywhere", is that code inside a try-block and code outside of it may share state, which the code in the try block may be in various stages of modifying (along with allocating resources) when the exception is thrown, potentially leaving an inconsistent state and/or leaked resources at the point where the exception is caught. Therefore all functions have to be very careful that any mutable state accessible to the function is in (or reverts to) a consistent state at any point where an exception might be thrown, and that resources aren't left dangling, because who knows whether that mutable state might not be on the outside of a try-block and the function on the inside of it. What if instead of that, the language enforced that code in try blocks could not share any state with code outside, only allowing for data to be transferred in at the beginning and out (whether a result or an exception) at the end, and ensured that all resources acquired inside the try block were destroyed after it exited, no matter how it did? That would free the authors of individual functions from having to care about any of it, because if an exception is passing through their code, that means that from their perspective "the world is ending", everything they have access to will be destroyed, so they can do whatever they want and it won't matter a bit. If that sounds familiar at all, it's because I just described the semantics of Rust's existing try()*. I still suspect that the best of all worlds would be something with the semantics of try(), or close, and the implementation and performance of traditional EH. Is that unrealistic? * Along with the ability to actually observe the thrown exception, but IINM that's planned. And I guess you could have multiple variations on how to handle catching-and-or-rethrowing. If the plan is to use dynamic typing for the exception object you could have something like: impl<T> Result<T, ~Typeable> { fn catch<E: Typeable>(self, hndlr: &fn(ex: ~E) -> T) -> T { match self { Ok(res) => res, Err(ex) => { match ex.cast::<E>() { Ok(casted_ex) => hndlr(casted_ex), Err(uncasted_ex) => fail!(uncasted_ex) } } } } } That doesn't really do "catch block" chaining well and I probably made 10 type errors, but oh well. -- Your ship was destroyed in a monadic eruption.
_______________________________________________ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev