Hacker News new | ask | show | jobs
by CharlieDigital 684 days ago
I don't see those as necessarily illegal states, but even so, it's not hard to handle by adding a third `Action` for it (I kept the example short and left the first `if` condition empty).

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.

1 comments

What does it mean to receive both value and error in the context of division? What about neither?

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 return type of a function is an assertion. You’re saying that values of the type exist. The return value is an assertion about the arguments. You’re saying that they imply the result. The issue is that your code is incorrect, in a logic sense, if it states that for some given value the mathematical operation of division results in both an error and a number.

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.

Now you have 3 different states that all represent an error:

    (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.

> I don't see the issue?

> if we receive both, than an exception occurred and should be handled

P(decimal ∩ DivideByZeroException) = 0 , therefore we only need 2 states, not 4.