Earlier quoted context omitted.
> It doesn't look to be too much of a temptation to use panics as regular errors in Rust though Maybe not, but it was enough for the author to dedicate at least one whole section of the article to reasoning about this. > like when you want to show an error box to the user, instead of silently crashing, or when you want to send the crash log for later analysis As I mentioned, panics can be handled but not recovered .…
I've never heard of anyone using panic for exception-style recovery. That's anathema to the whole idea of Result . But I suppose if it's possible, it will be normal for someone.
Using unwrap() in Rust is Okay (2022)
21–30 of 54 posts
Re: Using unwrap() in Rust is Okay (2022)
#22Just don’t put unwrap in library code, please. Not if it can possibly happen, bearing in mind that you can make mistakes. I like my background threads to be infallible. If they panic, then chances are nothing will notice and the rest of the program will solely seize up. I might have agreed with more of this article if panics actually crashed the program, but in multithreaded Rust that’s rarely the case.
> I might have agreed with more of this article if panics actually crashed the program, but in multithreaded Rust that’s rarely the case. Why is that?
Re: Using unwrap() in Rust is Okay (2022)
#23The general issue, as I see it: One function is too general and handles all inputs. Some inputs are wrong and code returns error. Some languages forces you to handle that error. Another code snippet uses that function with very specific inputs which must not cause errors, but was forced to handle error, because of language rules. This error handling is essentially useless. I saw this issue with Java. There's construc…
It's a general issue with typed languages. Types are either too fine-grained or too coarse. Some more sophisticated languages can infer a whole lot but static type checking is still confusing and slows down builds. I tend to not worry much about them anymore -- about C language level types (maybe a bit more) is helpful and important for performance, but beyond that (e.g. types get dynamically instanciated from templa…
However, I think it's really easy for a statically-typed-systems user to get a bit too enamored with static types even so, and start trying to stuff too much stuff in there. Anyone who thinks that the job of static types is to make all conceivable errors impossible is invited to go learn Haskell and then spend some time trying to write a non-trivial program, like, say, a GUI that also interacts with the network somehow, using an effects system to its maximum capability to perfectly carefully constrain every single function.
It is academically impure to do things like the author mentions and have a search object that will fail if you call a certain method without having constructed it a certain way. No question. And no question, this impurity can result in bugs in real code in the real world.
On the other hand, if one takes the time to create the absolutely perfect crate for Rust that absolutely perfectly expresses all possible combinations of options and methods that such a package could have, you could conceivably end up with a package with literally 10 times or more the number of types, that requires more steps to create a search than the simpler one, that is in fact so complicated that it turns the simple task of "please look for string x in string y" into something that a new programmer can't even understand anymore, and even a senior programmer might have to fight through some docs and ultimately just copy/paste an example and hope for the best...
... and the designer must ask the question, is that actually better? In practice, and not in theory?
Bugs are not created equal.
The academic worldview implicitly accepts the premise that an infinite amount of work is worth doing to eliminate the smallest possibility of the smallest bug with the smallest consequences.
A coder who lives in the real world needs to examine that premise carefully and decide if it matches their current situation, and if as is quite likely it does not, take appropriate actions. Static type systems offer a fantastic cost/benefit tradeoff in many real-world situations, but there is a point of diminishing returns.
Re: Using unwrap() in Rust is Okay (2022)
#24> That section briefly described that, broadly speaking, using unwrap() is okay if it’s in test/example code or when panicking indicates a bug. I've come to the conclusion that even in tests unwraps look ugly. Especially in doc tests which serve as examples the code is better off using regular "?" that one would see in other parts of code. (that is: don't treat test code as a "worse" kind of code) In Signstar we're u…
Re: Using unwrap() in Rust is Okay (2022)
#25While I don't fully understand rust (not that I've really attempted to program in it much), I do really like the Result convention. Before I knew about it, I used a similar construct in a couple of places in my C# code, but I think I'll make my own version of it and try to use it more often. I don't think C# has a builtin version anyway, I know it has a builtin that does the same as Option with its nullable types, li…
int? in C# is syntactic sugar for the type Nullable. The big issue though is that Nullable only works for value types, not reference types like string (or any classes). C# added "nullable reference types" a few versions ago, but that is just static analyzers in the compiler and IDEs, it doesn't actually enforce anything at runtime. And all of the methods, etc. that are available for value types with Nullable don't work with nullable reference types.
C# has union types as a planned feature, which will also add an Option type that will make it possible to handle nullability for both value and reference types using the same type, and make it so it's actually enforced at runtime.
Re: Using unwrap() in Rust is Okay (2022)
#26Just don’t put unwrap in library code, please. Not if it can possibly happen, bearing in mind that you can make mistakes. I like my background threads to be infallible. If they panic, then chances are nothing will notice and the rest of the program will solely seize up. I might have agreed with more of this article if panics actually crashed the program, but in multithreaded Rust that’s rarely the case.
> I might have agreed with more of this article if panics actually crashed the program, but in multithreaded Rust that’s rarely the case. Why is that?
The lock case mentioned by littlestymaar is an important "program correctness" consideration, but also consider something like a instant message or chat server like Slack. You don't want the entire server with thousands of connections to crash just because one thread somewhere crashed. It's expensive to reconnect the system after that.
Also, the more threads you are running, the higher the odds get that one of them will panic somewhere, somehow. The numbers start adding up.
Each of these two effects conspire to make the other one worse as you scale up.
Re: Using unwrap() in Rust is Okay (2022)
#27I only use unwrap in tests
Re: Using unwrap() in Rust is Okay (2022)
#28Earlier quoted context omitted.
I've never heard of anyone using panic for exception-style recovery. That's anathema to the whole idea of Result . But I suppose if it's possible, it will be normal for someone.
I'm not as familiar with the Rust ecosystem, but I know it is used all the time in Go. For example, the standard http server library wraps user provided endpoint handler functions with panic handlers.
Re: Using unwrap() in Rust is Okay (2022)
#29 - The let-else syntax (Relatively new), anecdotally, removes many of my cases for unwrap. (But this may not apply to how others use it)
- Unwrap's fine if it makes the code easier-to-read and you know it won't panic for a reason the compiler doesn't know about.Re: Using unwrap() in Rust is Okay (2022)
#30Earlier quoted context omitted.
I've never heard of anyone using panic for exception-style recovery. That's anathema to the whole idea of Result . But I suppose if it's possible, it will be normal for someone.
I'm not as familiar with the Rust ecosystem, but I know it is used all the time in Go. For example, the standard http server library wraps user provided endpoint handler functions with panic handlers.