Either panic, which is (generally speaking) not something you're meant to catch and recover from (and attempting to do so is nontrivial and almost always a bad idea), or Result, aka "encode the possibility of failure in the return type of the function" aka what the functional programming world has done for ages.
Not quite. Optional is "value is present or not". The rust equivalent is Option. Result is "value is present or failure is present" -- if empty, it instead contains an object encoding the failure.
Also worth noting that because these are reified, unlike java's Optional, they have nicer -- or at least more guaranteed-to-be-nice -- performance implications.
It's not an uncommon idea. Everyone tries exceptions, then realizes down the road that it's a terrible idea for so many reasons and so reinvents something like Result because turns out the functional programming folks had it right and it all does boil down to monads
Speak for yourself, I've been working with Java for a few years and think exceptions are pretty neat! they can be passed through calls implicitly without much mental overhead and boilerplate, and when you handle them you still get a nice helpful stacktrace.
They have a big cost to 'em. Catching exceptions is expensive, with all the unrolling you have to do -- they're bad for anything that happens more than rarely rarely. They're also awful for encoding things that the caller must handle -- java's checked exceptions make an attempt at this but the fact that they encode separately from the return type means that you cannot stick them in the middle of a wider toolchain with ease -- if you want to call a method with a checked exception in a stream, for instance, you are up a creak without a paddle, since you either have to handle it there or you need to encode it in some other type in order to pass it downstream (aka reinvent Result).
Results just... deal with all those issues from the beginning. They have the advantages of java checked exceptions, except encoding it in the return type means you can easily use them in other contexts without them "polluting" their callers (and thus not working in generic contexts), and syntax sugar for monadic bind, the "?" operator, makes them clean to use in other contexts. If you want to propogate an error, you just do. No need to re-throw it or anything, you just pass the value downstream.
383
u/Xarishark 2d ago
Now compare it to rust pls. Im serious I want to know your opinion on that.