4 ms·
> So if you have a potential call chain of dozens of methods, your error return includes every single possibility? Mostly yes, usually as a sum type. Pattern
by kaoD 8y ago
> So if you have a potential call chain of dozens of methods, your error return includes every single possibility?
Mostly yes, usually as a sum type.
Pattern matching is your friend.
> the errors are massaged
Why would I take the extra effort?
Unless it's my responsibility to handle it (i.e. it's part of the function's logic) I will just return it untouched and let the consumer decide what to do (if anything at all).
> or placed untyped
That's not possible (at least in the typed languages I tried).
- wvenable 8y agoJava has checked exceptions (which honestly is more like error-return) and the innerException property is used extensively to hold the "real" exception and, of course, it's type is just "Exception". Making the real error types part of the signature of the method means that implementation changes require changing the signature, completely breaking encapsulation. In fact, I'd argue it makes polymorphism completely impossible.
- kaoD 8y ago> Java has checked exceptions (which honestly is more like error-return) and the innerException property is used extensively to hold the "real" exception and, of course, it's type is just "Exception". Yeah, well, Java's semantics and programer laziness make a mess. News at 11. > I'd argue it makes polymorphism completely impossible. Oh, so two birds with one stone!
- wvenable 8y agoIt's like it's 1992 all over again. Every change requires changing every caller everywhere. Yes, it's an improvement now that the typechecker will tell us all the places we need to change but it still doesn't sound enjoyable or useful.
- kaoD 8y ago> Every change requires changing every caller everywhere I don't see why.
- wvenable 8y agoNon-trivial changes to functions typically change what errors they will trigger. Thus changing what errors their callers will trigger. And so on. Putting error conditions in the function signature means that the signature reflects the implementation details of the function. Change those implementation details and the signature changes, affecting the callers and their signatures. Unless you abstract the error and then you lose the only advantage of passing the errors around rather than using exceptions.
- kaoD 8y agoI still don't see why. https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=c65c3161570329fb22907620f4f09692 https://play.rust-lang.org/?version=stable&mode=debug&editio... Let's add a new error condition: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=841a3bb4ff75c10752f9cfd1ace3bdd5 https://play.rust-lang.org/?version=stable&mode=debug&editio... Only the function raising the error, and the consumer, had to change (and the consumer only changed because it _cared_ about the error type!) If you want an example with nested errors I can do it, you'll see it's mostly the same.
- wvenable 8y agoIf you had an external compiled library the consumed MyError or called caller, you just broke it, becuase you changed the type. This isn't a realistic example at all because your MyError is simple enum that you changed to make it work. If you add another error, or have more than one level, or call it multiple locations, and don't eat the error then now you're changing many more functions, just as I said.
- kaoD 8y ago> This isn't a realistic example at all because your MyError is simple enum that you changed to make it work. Well, that's what an error is. A simple enum of the error cases and maybe some metadata. EDIT: e.g. IO errors in Rust's std: https://doc.rust-lang.org/src/std/io/error.rs.html#91-174 https://doc.rust-lang.org/src/std/io/error.rs.html#91-174 If your first guess is this isn't realistic because it's "too simple" then maybe you've never been exposed to this kind of error handling? It's so simple it's unbelievable? > If you add another error That's what I did, I added a new error. > or have more than one level and don't eat the error now you're changing more methods, just as I said. As I said, if you want an example with nested error types I can do it: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=c4a81faf48266658f569c2a00ae10d02 https://play.rust-lang.org/?version=stable&mode=debug&editio... As you can see, caller() (which would be our "middleman" here, the one that neither produces nor uses the error) didn't change at all. > If you had an external compiled library the consumed MyError or called caller, you just broke it, becuase you changed the type. You mean a dynamically-linked library? Yep, completely broken, but that's not the only problem with DLLs. Static linking is fine. Anyways, the contract changed, so it's a breaking change, so that's good in my book. The contract changed in the case of exceptions too, you just hand-waved over the issue and called it a day. Wouldn't it be the same with exceptions across library boundaries?