Hacker News new | ask | show | jobs
by AlotOfReading 4 days ago
Not the person you're asking, but result types pessimize code more, add register pressure, use more icache for largely dead code, etc. They're arguably noisier at the source level too.

That said, I've spent too much of my life chasing implicit control flow to accept exceptions. Heck, C++'s "noexcept" is a strong argument against exceptions all by itself.

4 comments

> That said, I've spent too much of my life chasing implicit control flow to accept exceptions.

Yes. This is why unchecked exceptions are annoying. Checked exceptions are a „failed experiment“ anyway.

A result type (or even Go‘s err) with forced error handling meaningfully increases the robustness of a program in my experience.

My view is that Java's checked exceptions failed in big part because Java didn't have type variables back then; after all, polymorphic Result types are not that much different from checked exceptions.

I haven't written any Java since it has gained those, so I suspect there might be other aspects making it awkward. And it still would lack exhaustiveness checking that e.g. Rust has.

Checked exceptions were actually the "right way" to do exceptions (if there is such a thing), the problem was just that developers hated them, but I think that draws the wrong conclusion. That tells me their syntax/usage was seen as too much forced boiler plate making code unwieldy, not that they didn't have benefits for correctness (something often not appreciated until years later).

Unchecked exceptions lead to unhandled exceptions at runtime. We've all seen screens with Java programs running with tons of exceptions in the log, or worse, that crash with unhandled exceptions. This is the result of the unchecked exceptions mess, which is why I won't use languages that use them for routine error handling for anything more than trivial programs.

> developers hated them, but I think that draws the wrong conclusion

Exception handling is just annoying from a syntax perspective. Also checked Exceptions have the problem that they bubble up types that a different layer shouldn’t even be aware of due to exception chaining (cause of a cause etc), unless you carefully re-throw them, which nobody did.

Lower ceremony errors are just better to deal with.

Agreed, I really like Rust's Result type. Go's idea is okay, but they should force you to handle the error.

    > result types pessimize code more
What does it mean?

    > They're arguably noisier at the source level too.
But they are more explicit, which means there will be fewer bugs in your code.
C++ noexcept exists because the way C++ evolved, it is no argument against exceptions.

Exceptions came to be during the 1990's, as the C++ARM to C++98 standardisation process was taking place.

Naturally during the early days C++ compilers lacked exceptions, as CFront was introduced without them.

Then we had the C folks that were migrating to C++.

When C++ compilers finally supported exception, compilers vendors introduced the non standard switch to disable them, so that existing code could still compile with the expected behaviour.

The standard itself does not acknowledge this as allowed.

This feature was naturally misused by the anti-exception folks, same applies to how RTTI came to be.

So noexcept is a way to be able to write code to appease both camps, while surfacing what variant was chosen by the programmer.

From my point of view allowing disabling exceptions in first place was a mistake, those folks should have moved back to C, or fixed their code.

I don't understand why Result type is necessarily slower. Result that simply bubbles up is basically an exception, no?
You need instructions to check the result type, and a bit somewhere to store whether it's valid. Most exceptions only add extra instructions during throws/unwinding. There may or may not be an overall reduction in code size, depending on how many checks you have vs table entries.
In theory, a compiler can figure out that you don't need that in some cases.