On Tue, Feb 6, 2024 at 7:14 PM Larry Garfield <la...@garfieldtech.com> wrote:
> These two samples *are logically identical*, and even have mostly the same > performance characteristics, and both expose useful data to static > analyzers. They're just spelled differently. The advantage of the second > is that it could be implemented without generics. (ADTs would be an > optional nice-to-have.) And if the caller doesn't handle DivByZero, it > would try to pass it up to its caller, but being checked it would require > the caller to also declare that it can raise DivByZero. > Let's assume that the developer knows the divisor isn't 0 - through an assertion or an `if` clause above the call to `divide(5, $divisor)`. In this case, DivByZero error cannot ever be thrown (or risen), but the developer would still have to either handle the error (which will never happen) or declare it as raisable, which in turn may require also marking 10+ function/method calls as "raises DivByZero". Both options aren't great. And even if there was no assertion about the divisor, maybe the developer's intent is exactly to ignore that case as an "implicit assertion" - meaning instead of explicitly asserting the divisor value themselves (through `assert($divisor !== 0)`), they rely on `divide(5, $divisor)` doing that implicitly for them. If the `assert()` fails, then nobody is expected to really handle that assertion error; it usually bubbles up to the global exception handler which takes care of it. If the `divide()` fails on the other hand, checked exceptions would require all the callers to actually "check" it by catching or declaring the caller function as `raises DivByZero`, but this doesn't bring any benefit to the developer in this case. So I assume this is why Java developers hate checked exceptions and why Kotlin doesn't have them. I'm not aware of other implementations of checked exceptions; there may be other, better versions of them. If you have any in mind that overcome the issues above, I'd be interested to look into them :)