The second case, if there is an exception, it would be handled as such by simply switching the order of the `if` in the extension method. None of this seems confusing nor onerous in day-to-day use.
The second case, if there is an exception, it would be handled as such by simply switching the order of the `if` in the extension method. None of this seems confusing nor onerous in day-to-day use.
The issue is not that they cannot be handled, it's that they can be. You included an entire extra branch and check for something that will never occur because they're legal values for your tuple type. I assume it'll be optimized out of this trivial example, but imagine writing a function to receive your tuple type in a codebase where you didn't create the tuple. ADTs prevent this entire worry because there is no way to represent illegal states.
What does it mean to receive both value and error in the context of division? What about neither?
It's only "invalid" if you define it as such. We can state "if we receive neither, then this is the same as an error state". And "if we receive both, than an exception occurred and should be handled".I don't see the issue?
The issue is not one of usability or (direct) understandability, it’s an issue of correctness. Something like “well it works fine for me if I just remember to check if I receive both” or “everyone on my team understands that receiving both means an error occurred” just isn’t a valid response, it doesn’t address the problem.
(null, new DivideByZeroException())
(null, null)
(result, new DivideByZeroException())
One of which does not actually use our custom error type, and one of which contains a value for some reason. Our function is simple division! Are there really 3 different ways division can fail?This isn't a showstopper, it's just more stuff you have to keep in your head.
> if we receive both, than an exception occurred and should be handled
P(decimal ∩ DivideByZeroException) = 0 , therefore we only need 2 states, not 4.