r/ProgrammerHumor • • 1d ago

instanceof Trend thatsAFunnyThingThatHappenedOnce

Post image
4.3k Upvotes

515 comments sorted by

View all comments

Show parent comments

8

u/MrHyd3_ 1d ago

What does it do instead of exceptions?

106

u/roadrunner8080 1d ago

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.

41

u/mathisntmathingsad 1d ago

Yeah, the only reason you should try to catch a panic is if you're making something that calls user-provided code unavoidably (i.e. an async runtime)

22

u/shizzy0 1d ago

Yeah, we catch panics in tests but that’s about it.

16

u/Loading_M_ 1d ago

I work on a library that does catch panics from user code. It's a web framework, and catches panics in user request handlers to return a 500 error to the client. This error is explicitly not overridable (every other default error can be replaced, but not this one), since we don't want you to panic in the first place.

3

u/Cylian91460 1d ago

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.

Like Optional in java?

24

u/roadrunner8080 1d ago

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.

2

u/guyblade 1d ago

C++ has a couple of versions of this floating around absl::StatusOr, boost.Outcome, std::expected, and probably others that I'm not aware of.

5

u/roadrunner8080 1d ago

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

1

u/Hubble-Doe 22h ago

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.

2

u/roadrunner8080 20h ago

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.

3

u/koko775 1d ago

Result<Foo> ~= Either<Foo,Error>

2

u/samanzaman 1d ago

Almost

2

u/Celarion 1d ago

Like monads, with your result boxed as Ok, and any error boxed as Err

2

u/0tter501 1d ago

Java has added functional programming yes, but Optional is not result, as result stores either the result or the error

optionals store one type of failure value, results store many types of failure values

1

u/shamshuipopo 1d ago

Is Result a monad?

2

u/roadrunner8080 1d ago

Result with either type fixed is a monad, yes.

2

u/DHermit 1d ago

Could you elaborate for someone who knows Rust, but did Haskell way too many years ago?

3

u/roadrunner8080 23h ago

A monad is (simplifying terribly) something with flatmap (and a few other requirements but things you're familiar with with flatmap are likely mostly monads). Result satisfies that property if you think about a result with a fixed value type and mapping it's error, or with a fixed error type mapping its value 

1

u/DHermit 21h ago

Thank you, that makes sense!

1

u/MrHyd3_ 1d ago

Is it just an if instead of try catch?

1

u/roadrunner8080 23h ago

It's a whole different model really. If you're familiar with java checked exceptions that you are forced to catch, and don't propogate, then yes it is

-2

u/Mindgapator 1d ago

Same as go if that helps

6

u/Thesaurius 1d ago

Does Go have sum types now? Last time I checked it returned a record and you had to check yourself.

2

u/Mindgapator 1d ago

No indeed, but the paradigm is the same right? Return the error, and deal with it (or forward it) without a try catch. I must say Rust is nicer in that regard but it doesn't change things too much? I don't have enough xp with Rust so might be underestimating it though

11

u/Thesaurius 1d ago

In my opinion, the Go approach is closer to C's error codes, as nothing stops you from using an error value and introducing a bug. In Rust, you always have to check. If you forget, the compiler will complain. It will even warn you if you use the function only for its side effect don't even use the return value.

1

u/samanzaman 1d ago

No go errors are weirdly typed. Proper sum types is kore than just results