Hacker News new | ask | show | jobs
by tialaramex 1720 days ago
The crucial difference with Rust's Result (I don't know Zig well enough) is that Result isn't about control flow.

Exceptions unavoidably and deliberately change control flow.

Suppose you're in a loop twiddling zarks. In Rust, twiddling a zark gives you a Result and if the Result isn't Ok then that's an error. But Rust doesn't care what - if anything - you do with the error, it just won't allow you to pretend the error was Ok (because it isn't). You can count up all your Results and consider what fraction were Ok. You can filter out any that weren't Ok. You can ignore the Result altogether. Or, if you find one that isn't Ok you could give up twiddling zarks immediately. Rust doesn't mind, Results are just data, do whatever you want with it.

But in a language with exceptions, checked or not, each time there's a problem twiddling a zark the exception jumps the program to somewhere else to "handle" the exception - and it's on you, the programmer, to manage that, by e.g. wrapping the zark twiddling in a try-catch block.

2 comments

Error returns and checked exceptions are isomorphic. There's nothing you can do with one that you can't do with the other.

But I agree with the underlying point you're making. The error mechanism that a language provides determines how a programmer will think about handling errors. Exceptions make you think about error handling as control flow. Error returns make you think about error handling as unwrapping data.

Which is the imo correct approach. Instead of unwrapping and rewrapping the exception at the closest level, I want to handle most exceptions in a common place. Eg, in case of a web server that place would give a proper error page to the user whenever an unhandled exception happened in his/her request.

Also, Java’s exceptions are pretty much the exact same sum type as in Rust, just with added syntactic sugar. A method with a throws SomeException signature will have a type of Result<Something> | Error<SomeException>, that gets autounwrapped for you, with the added benefit of giving you a stacktrace by default.

> Java’s exceptions are pretty much the exact same sum type as in Rust, just with added syntactic sugar.

Except Java doesn’t actually return a result object that can be assigned to a variable by default.

And in case of exceptions, why would that be useful?

(For other things, I agree that sum types are cool, and fortunately are supported in Java through sealed classes)

I don’t think sealed classes offer exhaustive pattern matching. Instead you have an if-else ladder of instanceof checks. This is not the same as most union type implementations.
They do with switch expressions. It is only type based for now, but deconstructs are coming with full blown pattern matching a la Haskell.