6 ms·
Say you have library that takes a filename and returns the contents after some kind of decoding. If the file is inaccessible (doesn't exist, in use, user doesn'
by rcfox 8y ago
Say you have library that takes a filename and returns the contents after some kind of decoding. If the file is inaccessible (doesn't exist, in use, user doesn't have permission), you don't want the library to take any real action on that. It shouldn't display a message, attempt to correct the filename or retry the same file. It should just let the caller know that an error occurred, and ideally what that error was.
Okay, so we'll return early with an error code and probably some kind of nil result. (Because we're not using a system that's so archaic that it can only return one value!)
But the caller of the library was some middleware that also can't be expected to handle the error usefully. It returns the same error and result to its own caller. And let's say there are a few layers like this until we finally get to the top layer where we can translate that error code into a big, red message for the user saying "file not found".
Now how is that any different from raising an exception? (Other than the extra 'if error: return error, result' lines you need.)
- wyldfire 8y ago> Now how is that any different from raising an exception? (Other than the extra 'if error: return error, result' lines you need.) I think exceptions can be used well in some contexts but I will completely concede the point that they're super complicated. "How is that any different?" Well -- we unwound the stack automagically and that's not trivial. Every intervening piece of code should know that a call they make could transitively make lots of interesting calls and they might cause this function we're writing to exit early.
- kaoD 8y ago> Now how is that any different from raising an exception? Exception bubbling is implicit. There's no way to know which exceptions can be thrown from a function just by looking at its code, nor looking at the called-functions code. You have to keep in your head all the call chain up to the first function that does not call any other function (good luck with that). Even worse: we don't even know _where_ the function can stop running and start unwinding. This leads to defensive programming. Hello try-catch soup! It's a slippery slope that gets worse and worse with each abstraction layer. Languages with typed errors have been nothing but a joy for me.
- rcfox 8y ago> There's no way to know which exceptions can be thrown from a function just by looking at its code, nor looking at the called-functions code. But is this different from error codes? Does seeing a file open tell you every error that might occur from that? If you're arguing that you could just look at the file-open code to see the errors it returns, couldn't the same apply for seeing which exceptions are thrown?
- kaoD 8y ago> If you're arguing that you could just look at the file-open code to see the errors it returns, couldn't the same apply for seeing which exceptions are thrown? No, because then you have to look at every function inside there. And there every function inside those functions. And then... With typed error handling they're only one-level of abstraction deep. Actually zero-levels, since your function won't typecheck unless you handle the errors.
- wvenable 8y agoSo if you have a potential call chain of dozens of methods, your error return includes every single possibility? That's pretty doubtful. What happens is the same thing that happens with checked exceptions; the errors are massaged or placed untyped in properties and while you're handling all the errors you're doing it in a sloppier way.
- 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).