3 ms·
Porting to a language supporting exceptions would be a huge simplification. But then maybe it would stop being a space shuttle ...
by chvid 8y ago
Porting to a language supporting exceptions would be a huge simplification. But then maybe it would stop being a space shuttle ...
- almost_usual 8y agoBetter to make blindly throwing exceptions impossible.
- geofft 8y agoA good alternative is language-level support for returning early from a function with an error. Off the top of my head, both Rust and Haskell have good support for this. (I'm sure there are others, these are just the ones I know.) Rust has a macro try!(x) that takes a Result<T, E> - a two-variant type, either a successful result of type T or an error of type E - and translates it to, if x is the first variant, evaluate the output of try! to the value of type T inside, otherwise return an error with the value of type E (on the assumption the calling function returns a Result<something, E>, too). So you can do things like `let file = try!(open(...));` and operate on the file. People liked it so much that a couple years back Rust added the question-mark operator, so you can just do `let file = open(...)?`, and chain it to `let data = open(...)?.read(...)?`. It's still visible that this is how you're handling errors, and you can always leave off the question mark and write out `match open(...) { Ok(file) => ..., Err(error) => ... }` instead, if you'd like. Haskell has its monads, which for the present purpose can be interpreted as just a wrapper type. Given a wrapped object of type T, you can give it a function that takes a T and returns a similarly-wrapped object of type U, and have it apply the function to the data. If the wrapped object is in a failure state, it can choose to "apply" the function by just not calling it at all and instead returning the same failure state. Haskell has special notation with the "do" keyword for calling several monadic functions repeatedly, where it looks like you're writing regular, imperative code and assuming errors don't happen. But again it's obvious when you're using it and you can always handle the exceptional case specially as soon as you want.
- steveklabnik 8y agoYou missed the E in Result<T, E>, by the way.
- geofft 8y agoThanks, fixed - I was trying to gloss over it for the sake of readers for whom X<Y> itself isn't familiar syntax but I think it makes more sense this way. (I'm also glossing over the fact that try! will convert error types, I think?) Or pretend I meant io::Result :)