I too hope that we can get by with using tasks to contain failure rather than catch handlers. However, I think there will be "lighter weight" cases where a long function wants to bail out early. This is sometimes because some internal operation failed due to error or might be something like a recursive search which found a result. These cases are well-modeled with a type like either<> or std::result<>, but sometimes the syntactic burden of matching and returning failures distracts from the main line of the code. I think this is an important issue to address: a simple macro is probably enough, though.
On Nov 18, 2011, at 11:45 AM, Graydon Hoare wrote: > Woah woah, I'm arriving late here. > > We *have* exceptions. They're called 'failure'. The only point about them is > that you can't catch them. For a couple reasons: > > - We can't re-establish task typestate from unknown starting point; > memory might not be initialized, arbitrary other predicates not > hold, etc. > > - Philosophically, catching means either one of two things: > > 1. You know exactly what the failure means and an exact, transparent > recovery mode. For this we recommend simply modeling the recovery > mode you want for expected-but-rare circumstances as arguments > passed *into* the callee, and handled at the site of > circumstance. Think of how O_CREAT and O_TRUNC work in ::open. > We have these wonderful tag things for passing in such options, > they can be highly structured if necessary. > > 2. You don't or can't really understand and manage the failure, > want to wall off a whole subsystem, to contain an unknown failure > but otherwise, at best, just log it and try to reset/try again. > For this we have tasks and failure. Intentionally unrecoverable > until the task boundary, and intentionally not-very-typed. > > IOW, our approach to managing faults requires thinking a bit and classifying > them, but not much more than you'd have to classify a java exception as > checked or unchecked. And we (hopefully) don't wind up throwing or unwinding > quite as much either, as a result. > > Throwing (in terms of implementation) is actually not all that great: it's a > fair bit slower than just passing a flag, and catch paths in production code > are often bitrotted and/or untested. Flags for common/expected special > circumstances are much more likely to get tested, run quickly and correctly. > > There's a bit of fudging possible on that line because we've talked about > (and I'm still ok with) a cross-task failure notice being something that > carries an inspectable stack of "any" values (stacktrace entries, "note"s, an > original "fail" argument). But that's unimplemented and, in any case, will > never be precise: an "any" can always be some type you weren't expecting. > > -Graydon > > _______________________________________________ > Rust-dev mailing list > Rust-dev@mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > _______________________________________________ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev