> Date: Thu, 16 May 2013 10:58:28 -0700
> From: [email protected]
> To: [email protected]
> CC: [email protected]
> Subject: Re: [rust-dev] Adding exception handling as syntax sugar with
> declared exceptions
>
> On 12/05/2013 8:00 PM, Bill Myers wrote:
> > This is a suggestion for adding an exception system to Rust that
> > satisfies these requirements:
> > 1. Unwinding does NOT pass through code that is not either in a function
> > that declares throwing exceptions or in a try block (instead, that
> > triggers task failure)
> > 2. Callers can ignore the fact that a function throws an exception,
> > resulting in task failure
> > 3. Callers can handle exceptions if desired, with the same syntax of
> > C++, Java and C#
> >
> > (1) avoids the issue with C++ exception handling forcing to think about
> > exception safety everywhere
> > (2) avoids the issue with Java's checked exceptions forcing to
> > explicitly handle or redeclare them
> > (3) provides an easy-to-use exception mechanism
>
> Hi, sorry, I did mean to get back to this.
>
> I think this is ... unlikely to work out, or be something we incorporate
> into our repo. For a few reasons:
>
> - It's very late in the design cycle to be making changes of
> this scope. We're trying to stabilize.
>
> - It'll be a big performance hit on code paths that want to use
> such exceptions. Things that look like "just function calls"
> turn into quite extensive operations. We're already struggling
> with the costs of a return-bool solution for unwinding on
> platforms that have difficult "normal" EH (#4342).
>
> - Most seriously: it doesn't actually resolve (1) or (2), imo.
>
> (1) You'd still have to declare checked exceptions everywhere. But
> worse than in java, if you failed to declare them _anywhere_
> you wouldn't get a compilation error, but a runtime failure.
> This is like making C++ default to 'throw ()', which tends
> to surprise everyone.
Well, the idea is that exception would generally either be caught in the
immediate caller or let go to task failure, with rare cases of propagation.
The target use case are things like "str_to_int" functions that would throw
format exceptions that would be caught by the immediate caller in case they
want to handle it.
> (2) You still have to write in "worry about exceptions everywhere"
> style inside a try-block or function-that-rethrows. Only
> get to avoid it when you're insulating yourself by the implicit
> "throw ()" declaration.
Yes, but you can't always avoid this anyway, since in some cases operations are
truly irreversible.
For instance, if you want to make three HTTP POST requests and the second
fails, then the first will have gone through and cannot be reverted
automatically in any way, so the logic to handle "we did something and then
failed, leaving us in a half-done way" is fundamentally necessary in some case
regardless of language design.
A limited version of this might be implementable by macros that could
automatically generate a "try_" version of a function with Result<> return type
along with a version that fails.
The only other approach that can improve on this is to have support for
reversible execution.
Basically, one would compile everything in two versions, where one of the
versions keeps an undo log of memory writes. When a try block is entered, the
compiler switches to the undo-log-enabled code, and when an exception is
thrown, the log is played to undo everything. Hardware transactional memory
like Haswell TSX can also be tried first if available.
Of course, this wouldn't be able to handle external function calls and
modifications of shared memory via unsafe pointers: this could be handled by
having a special "unsafe" construct that passes a closure to unwind the changes.
Calling irreversible functions like I/O would need to cause a transaction
abort/throw an exception. Also, some things like RWARC modifications would be
impossible to handle without a full STM implementation (with MVCC and so on).
The biggest drawback of this is that it will double code size and compilation
time.
I'm not sure if it's worthwhile since it cannot work in general due to I/O, and
simple cases can be handled with the syntax sugar proposed or doing the same by
hand with Result return types and so on.
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev