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

Reply via email to