4 ms·
> Most of my code is error checking and handling. > Plenty of noob code ignores errors. You can encode errors into the return type of the function to force pe
by rovolo 6y ago
> Most of my code is error checking and handling.
> Plenty of noob code ignores errors.
You can encode errors into the return type of the function to force people to deal with errors. Here's a good example:
byte[] read() throws IOException
// vs
Optional<byte[]> read()
Both cases force the user to consider failure cases.
Checked exceptions are essentially modifying the return type already, just in a different syntax. It's inconvenient because the nonstandard syntax for the type doesn't work well with all the other return types. It's still a bit inconvenient to use the other option in Java though because there's no language level support for real tagged unions (sum type) (union type). https://en.wikipedia.org/wiki/Tagged_union https://en.wikipedia.org/wiki/Tagged_union
The other class of not handling errors takes a bigger conceptual leap:
void write(byte[]) throws IOException
// vs
Optional<Void> write(byte[])
The caller could just ignore the value in Java, so your criticism is still valid. However, you can force the caller to never implicitly ignore return values. If the function 'throws' by returning a value, you have to explicitly ignore it:
val _ = write(bytes);
If the function can't throw (i.e. the return type is strictly 'void'), then you don't have to do anything:
write(bytes);
- jayd16 6y agoOptional<T> isn't a replacement for typed exceptions as you can't pass or inspect the error details.
- rovolo 6y agoThat's correct. I used Optional because it's included in Java and it's simpler. With Optional I could explain handling the presence of errors, but not the inspection of errors. A full replacement is the Result type (a specialized 'Either'): https://doc.rust-lang.org/std/result/ https://doc.rust-lang.org/std/result/
- jayd16 6y agoYeah. Although, that has an explicit error type which is good and bad. The errors are consistent and known but you're restricted to throwing them together into a single type. I kind of like C#'s Task type where you can still use the catch block pattern matching if you want to. Maybe dropping the catch syntax is better though.
- specialist 6y agoInteresting. I'd love to see more of these kinds of alternatives. I don't have experience with monads, union types, and the like for network programming. I dimly recall some nodejs stuff which moved the err and result values from the callback to the method's return, which I also found appealing. (Or maybe that was golang. Sorry, am replying on phone.)
- Nursie 6y ago> Both cases force the user to consider failure cases But only one allows you to pass back information about the source of the failure rather than just the existence of the failure.