6 ms·
if you make it easy to be lazy and panic vs properly handling the error, you've designed a poor language
by arccy 11mo ago
if you make it easy to be lazy and panic vs properly handling the error, you've designed a poor language
- yoyohello13 11mo agoSo… basically every language ever? Except maybe Haskell.
- dkersten 11mo agoAnd Gleam
- yakshaving_jgt 11mo agoIt's easy to cause this kind of failure in Haskell also.
- otterley 11mo agohttps://en.wikipedia.org/wiki/Crash-only_software https://en.wikipedia.org/wiki/Crash-only_software
- nine_k 11mo agoWorks when you have the Erlang system that does graceful handing for you: reporting, restarting.
- SchwKatze 11mo agoUnwrap isn't a synonym for laziness, it's just like an assertion, when you do unwrap() you're saying the Result should NEVER fail, and if does, it should abort the whole process. What was wrong was the developer assumption, not the use of unwrap.
- dietr1ch 11mo ago> What was wrong was the developer assumption, not the use of unwrap. How many times can you truly prove that an `unwrap()` is correct and that you also need that performance edge? Ignoring the performance aspect that often comes from a hat-trick, to prove such a thing you need to be wary of the inner workings of a call giving you a `Return`. That knowledge is only valid at the time of writing your `unwrap()`, but won't necessarily hold later. Also, aren't you implicitly forcing whoever changes the function to check for every smartass dev that decided to `unwrap` at their callsite? That's bonkers.
- JuniperMesos 11mo agoI doubt that this unwrap was added for performance reasons; I suspect it was rather added because the developer temporarily didn't want to deal with what they thought was an unlikely error case while they were working on something else; and no other system recognized that the unwrap was left in and flagged it before it was deployed on production servers. If I were Cloudflare I would immediately audit the codebase for all uses of unwrap (or similar rust panic idioms like expect), ensure that they are either removed or clearly documented as to why it's worth crashing the program there, and then add a linter to their CI system that will fire if anyone tries to check in a new commit with unwrap in it.
- duped 11mo agoPanics are for unexpected error conditions, like your caller passed you garbage. Results are for expected errors, like your caller passed you something but it's your job to tell if it's garbage. So the point of unwrap() is not to prove anything. Like an assertion it indicates a precondition of the function that the implementer cannot uphold. That's not to say unwrap() can't be used incorrectly. Just that it's a valid thing to do in your code. Note that none of this is about performance.
- SchemaLoad 11mo agoIt also makes it very obvious in the code, something very dangerous is happening here. As a code reviewer you should see an unwrap() and have alarm bells going off. While in other languages, critical errors are a lot more hidden.
- Rohansi 11mo ago> when you do unwrap() you're saying the Result should NEVER fail Returning a Result by definition means the method can fail.
- Dylan16807 11mo ago> Returning a Result by definition means the method can fail. No more than returning an int by definition means the method can return -2.
- yoyohello13 11mo agoWhat? Results have a limited number of possible error states that are well defined.
- Dylan16807 11mo agoSome call points to a function that returns a Result will never return an Error. Some call points to a function that returns an int will never return -2. Sometimes you know things the type system does not know.
- Rohansi 11mo agoThe difference is functions which return Result have explicitly chosen to return a Result because they can fail. Sure, it might not fail in the current implementation and/or configuration, but that could change later and you might not know until it causes problems. The type system is there to help you - why ignore it?
- Dylan16807 11mo agoBecause it would be a huge hassle to go into that library and write an alternate version that doesn't return a Result. So you're stuck with the type system being wrong in some way. You can add error-handling code upfront but it will be dead code at that point in time, which is also not good.
- JuniperMesos 11mo agoIt's a little subtler than this. You want it to be easy to not handle an error while developing, so you can focus on getting the core logic correct before error-handling; but you want it to be hard to deploy or release the software without fully handling these checks. Some kind of debug vs release mode with different lints seems like a reasonable approach.
- leshenka 11mo agoAll languages with few exceptions have these kinds of escape hatches like unwrap
- nine_k 11mo agoAt Facebook they name certain "escape hatch" functions in a way that inescapably make them look like a GIANT EYESORE. Stuff like DANGEROUSLY_CAST_THIS_TO_THAT, or INVOKE_SUPER_EXPENSIVE_ACTION_SEE_YOU_ON_CODE_REVIEW. This really drives home the point that such things must not be used except in rare extraordinary cases. If unwrap() were named UNWRAP_OR_PANIC(), it would be used much less glibly. Even more, I wish there existed a super strict mode when all places that can panic are treated as compile-time errors, except those specifically wrapped in some may_panic_intentionally!() or similar.
- Nathanba 11mo agoright and if the language designers named it UNWRAP_OR_PANIC() then people would rightfully be asking why on earth we can't just use a try-catch around code and have an easier life
- yoyohello13 11mo agoProbably not, since errors as values are way better than exceptions.
- nomel 11mo agoHow so? An exception is a value that's given the closest, conceptually appropriate, point that was decided to handle the value, allowing you to keep your "happy path" as clean code, and your "exceptional circumstances" path at the level of abstraction that makes sense. It's way less book-keeping with exceptions, since you, intentionally, don't have to write code for that exceptional behavior, except where it makes sense to. The return by value method, necessarily, implements the same behavior, where handling is bubbled up to the conceptually appropriate place, through returns, but with much more typing involved. Care is required for either, since not properly bubbling up an exception can happen in either case (no re-raise for exceptions, no return after handling for return).
- pyrolistical 11mo ago
- kibwen 11mo agoIn Rust, `.unwrap()` is nine characters, whereas propagating the Result via `?` is one.
- selfmodruntime 11mo agoThis is untrue. A `?` operator would have done just fine here. I agree with you though that it should be possible to explicitely forbid unwraps.