Hacker News new | ask | show | jobs
by ameliaquining 20 days ago
The problem with checked exceptions is that they don't compose with the rest of the type system. Hence the infamous problems with things like Streams. Result types have basically all the virtues of checked exceptions without the problems.
1 comments

Result types do have one problem that checked exceptions don’t. Checked exceptions automatically combine into union types in a throws or catch clause. I haven’t seen a language that lets you be generic like that.

    T fn() throws E, F, G
vs

    Result<T, E | F | G> // not even Rust lets you do this.
That's more a consequence of Rust needing its tagged unions declared up front so it can lay them out consistently in memory without runtime type information. Python and TypeScript have untagged unions (that are discriminated at runtime by the RTTI attached to all objects in the underlying dynamic language); they don't happen to have an equivalent of Rust's ? operator, but if they did it'd work like you're describing.
"untagged union" usually means "no discriminant" not "runtime discriminant."

(Rust has both tagged (enum) and untagged (union) unions, but untagged ones are unsafe and therefore mostly used for C interop and similar cases.)

People often call Python/TypeScript unions "untagged unions" even though they're a very different creature from C/Rust unions. Ideally there'd be a term specifically for them but I'm not aware of one.
The E | F | G could be two different features, "anonymous sum types" or "union types".

TypeScript is an example of a language with union types: https://www.typescriptlang.org/docs/handbook/unions-and-inte...