Hacker News new | ask | show | jobs
by gergo_barany 739 days ago
> Yes, you will be able to get the compile-time safety by immediately using switch on the return value, but what if you don't?

Then you switch on the value at some other point in time. It's still AsyncReturn<V>. Why do you think safety would get lost?

> Exceptions are a completely sound solution, failures as return values can easily escape detection.

How so?

2 comments

Rust has lints for unused result types, but I've still seen new coders unintentionally write

  let _ = failable_call();
Which suppresses the error entirely.

I wouldn't say it's "easy", and it hasn't really been a problem in production. But maybe this is where the parent post is going.

I see. Yes, deliberately ignoring the result and error might be a problem. Of course the same novice programmers could write:

    try {
        failableCall();
    } catch (Throwable t) {
        /* Ignore. Stupid Java, always forcing me to handle checked exceptions that won't happen in practice. */
    }
In general, I'd say the choice between exceptions and a result-or-error return type should be driven by how likely the user of the method is interested in the return value. In the specific context of this discussion, there is no reason to call a future's get method unless you're really very interested in what it returns. So in this case I'd think the result type would be a good choice. For other APIs the trade-off is different.
I'd say between a stupid result out of ignorance or risky defaults, vs a stupid result out of explicitly being stupid and overriding sane defaults, the latter is probably safer.

Also, exceptions (particularly checked ones) are not a simple matter of optional checks; they form an explicit contract forcing you to deal with exceptions (and having to be explicitly stupid to make them useless via an empty try/catch block). Compare to type-contracts where you'd need to go out of your way to make the "Null" part of the union type "useful" in the first place, for example.

Well you can ignore return values (Rust & Golang force handling them) in Java, exceptions are „unstoppable“ by default.