Hacker News new | ask | show | jobs
by kibwen 4408 days ago

  > This seems like a step back from Exceptions to me. I 
  > want to be convinced otherwise, but I'm struggling to 
  > see how this is better than other mechanisms.
In a low-level language, guaranteeing memory safety in the face of resumable exceptions would be a nightmare. See Graydon's original post on the choice to avoid exceptions:

https://mail.mozilla.org/pipermail/rust-dev/2013-April/00381...

Selected quote:

  > In particular, to summarize for the impatient: once you get resumable 
  > exceptions, your code can only be correct if it leaves every data 
  > structure that might persist through an unwind-and-catch (that it 
  > acquired through &mut or @mut or the like, and live in an outer frame) 
  > in an internally-consistent state, at every possible exception-point.

  > I.e. you have to write in transactional/atomic-writes style in order to 
  > be correct. This is both performance-punitive and very hard to get 
  > right. Most C++ code simply isn't correct in this sense. Convince 
  > yourself via a quick read through the GotWs strcat linked to:

  > http://www.gotw.ca/gotw/059.htm
  > http://www.gotw.ca/gotw/008.htm
For more on the topic of exception-safety in C++, see the following paper by Bjarne Stroustrup:

http://www.stroustrup.com/except.pdf

I don't think that Rust's error handling solution is ideal, but I think that it might be approaching the best possible solution for its chosen context. Error handling is a hard problem!

2 comments

One last thing that deserves to be mentioned: Rust does have unwinding-on-failure, which is similar to exceptions, with the restriction that unwinding can only be caught at task boundaries. This allows failure in a single component to be isolated and contained. The pertinent distinction here is that the unwinding is not resumable in the normal sense; at best, a parent task can detect that a child task has failed and attempt to restart the task, without having the ability to persist any of the failed task's state.
> resumable exceptions

The word resumable is important to that quote, which isn't arguing against exceptions in general.

I suspect a similar analysis holds, though. After all, throw-catch style exceptions do involve resumption, just not at the point at which they're thrown. You have a similar challenge in making sure that you haven't left the world in an inconsistent state when an exception emerges from some code.

That said, i am skeptical that there is a significant safety practical difference between the use of checked exceptions, and the use of return values with a try! macro. In both cases, you are forced to acknowledge in the code that an exception can be thrown, which means that you have a chance to do the right thing about consistency.

We could imagine a version of checked exceptions where individual throw sites have to be tagged. A parallel universe version of Java [1] might look like:

  InputStream in = whatever();
  int b = in.read() throw IOException;
Wouldn't that be exactly isomorphic to Rust's use of try! ?

[1] No, not that Parallel Universe version of Java: http://blog.paralleluniverse.co/2014/05/01/modern-java/