@@jackthereaper9379 The simplest is to look at docs for std::thread::Result, there's an example. In short, when you spawn a thread, you get a handle and when you join that handle, it'll return Err if the spawned thread has panicked. It'll return Ok if the thread finished without panicking.
Weird, I'm pretty sure I replied, maybe it'll appear twice. The simplest is to look at docs for std thread Result, there's an example. After spawning a child thread, you wait for its completion by calling join. Join will return that Result and if it's an Err, the child thread has panicked. Edit: it the result is Ok, it's the value that the function executed in the child thread returned.
I think proper use of panics still has its place in applications, specifically if the error is unrecoverable and expected to never happen. Leaving the app running while the state of the application reached to a point where it should never reach is more problematic, and halting the whole program is the best option.
I would also say its application dependent. For example, you wouldnt want a server just crashing out of nowhere, however a client app could deal with a crash. I just dont like to use panics personally lol 😅
Yes! There are certainly use cases for panic but they are typically infrequent. The problem is developer use panic outside of the specific circumstances you've mentioned.
Just want to say how very very nice it is to see the five patterns in the title immediately listed when the video starts. Really helps me orient myself and understand what you're communicating!
Sometimes (like 1 out of 10 situations), it's more ergonomic to use panic! rather than introduce bespoke error type. Also, quite a few crates will use panic! internally, so there is not much you can do about it (apart from catch_unwind), even though your crate handles all errors in a clean way.
Yes I agree with that when it comes to your own codebase. In terms of libraries, panicking should not be done unless there's a VERY good reason. I'm curious which crates you are referring to.
Oh you don't want to clone and instead use a reference? Just re-architect the entire codebase... Nah I'm gonna keep cloning. 'Life is too short for lifetimes
If you have only one reader and one writer on different threads, you may want to use Arc instead of Arc. Further for that case of a single reader and writer, if your type is integral or boolean, then you don't even need the Mutex (data that is 64 bits or less can already be read and written atomically via the Arc).
Be careful when sharing writable data between threads. It can lead to false sharing, which is a degradation of performance when two threads constantly write to data contained in the same cache lane at the same time. In this case, making copies then reconciling them after the fact is better
Using unwrap/expect in production code is not an antipattern. Sometimes you know statically that something cannot be None/Err, but getting the type system to help is impractical or impossible. There are also functions with preconditions, and panicking when these aren't upheld to provide a nicer API is fair.
Unwrap and expect should be avoided except as a last resort and it's better if the function preconditions can be expressed in the input types so that the function can't even be called with invalid inputs.
@@ortervesoften it cannot be expressed in the parameter types. eg. a parameter for an index in a slice. it could also js be incredibly unnecessary to create a custom type just to ensure some invariant. eg. a non empty vec
@@Nesdac-k1lfunnily enough `NonEmptyVec` is actually a thing. I was in a situation where I actually needed that, and found out that there's a crate for that™
Do you have recommendations for how to handle a result in a function that can't return a result? (E.g. closures or implementing trait methods of library crates, that you do not own, which have a overly simply return type like String) Having to discard the entire error stack up to that point always feels so wrong.
Also using Box without any good reason. Most of the time it is better to use impl Trait in function properties for static dispatch. Or even better fn() pointers for your own code.
I miss the mentioning of the `Arc` anti-pattern, but maybe that's too complex for this kind of video and needs its own instead to explain why it's problematic.
Just so it's clear, points 1 and 3 are entirely allowed in Leetcode, Project Euler, Advent of Code, and similar settings. Unwrap and clone everything. Just make it run and get your answer.
Man I love how Rust is just becoming C++. You have a problem ? don't worry we have syntax to solve it. Kidding love rust :) (still plz don't become C++)
Get your *FREE Rust training* :
letsgetrusty.com/training
Nitpick: `panic!()` doesn't terminate the program, it terminates the current thread only. Another thread can then observe the panic.
Nice catch 👍
can you tell me atleast briefly how any other thread can observe the panic? I wanna know, it might be useful for a project of mine.
@@jackthereaper9379 The simplest is to look at docs for std::thread::Result, there's an example. In short, when you spawn a thread, you get a handle and when you join that handle, it'll return Err if the spawned thread has panicked. It'll return Ok if the thread finished without panicking.
I would be interested to know as well
Weird, I'm pretty sure I replied, maybe it'll appear twice. The simplest is to look at docs for std thread Result, there's an example. After spawning a child thread, you wait for its completion by calling join. Join will return that Result and if it's an Err, the child thread has panicked. Edit: it the result is Ok, it's the value that the function executed in the child thread returned.
I think proper use of panics still has its place in applications, specifically if the error is unrecoverable and expected to never happen. Leaving the app running while the state of the application reached to a point where it should never reach is more problematic, and halting the whole program is the best option.
I would also say its application dependent. For example, you wouldnt want a server just crashing out of nowhere, however a client app could deal with a crash. I just dont like to use panics personally lol 😅
@@rustisbae But you WOULD want to use it if say, an API key gets unauthorized or a wrongly formatted environment variable is detected.
@@u-k Right, that would be a reasonable to panic. But that's something that happens at startup, not while the server is up and running :p
Yes! There are certainly use cases for panic but they are typically infrequent. The problem is developer use panic outside of the specific circumstances you've mentioned.
Just want to say how very very nice it is to see the five patterns in the title immediately listed when the video starts. Really helps me orient myself and understand what you're communicating!
if the data is small cloning is faster than arc most of the time
And clone uses less RAM than Java or JS. RAM is expensive while CPU is often not the bottleneck. And lifetimes can get annoying at times. YMMV
Performant but more memory usage.
Yes good point but then you run into the issue of having multiple sources of truth
@letsgetrusty the data is immutable
Sometimes (like 1 out of 10 situations), it's more ergonomic to use panic! rather than introduce bespoke error type. Also, quite a few crates will use panic! internally, so there is not much you can do about it (apart from catch_unwind), even though your crate handles all errors in a clean way.
Yes I agree with that when it comes to your own codebase. In terms of libraries, panicking should not be done unless there's a VERY good reason. I'm curious which crates you are referring to.
I will keep cloning
Oh you don't want to clone and instead use a reference? Just re-architect the entire codebase... Nah I'm gonna keep cloning. 'Life is too short for lifetimes
@@sutsuj6437 i love rust untill i meet lifetimes
If you have only one reader and one writer on different threads, you may want to use Arc instead of Arc. Further for that case of a single reader and writer, if your type is integral or boolean, then you don't even need the Mutex (data that is 64 bits or less can already be read and written atomically via the Arc).
5:26 Think you need to put `&self.settings` even when self is a reference.
Yes! Good catch!
You can put if statements in matches?!?
It’s the beeessssst
the perfect question for claude/chatgpt
Yup, they're called guard cases!
I was genuinely confused by that. 7:55 for reference.
Looks awesome.
Be careful when sharing writable data between threads. It can lead to false sharing, which is a degradation of performance when two threads constantly write to data contained in the same cache lane at the same time. In this case, making copies then reconciling them after the fact is better
can you explain?
Using unwrap/expect in production code is not an antipattern. Sometimes you know statically that something cannot be None/Err, but getting the type system to help is impractical or impossible. There are also functions with preconditions, and panicking when these aren't upheld to provide a nicer API is fair.
Unwrap and expect should be avoided except as a last resort and it's better if the function preconditions can be expressed in the input types so that the function can't even be called with invalid inputs.
yes, but avoid `unwrap` especially since it cannot be given a message. and prefer `assert` where possible.
@@ortervesoften it cannot be expressed in the parameter types. eg. a parameter for an index in a slice. it could also js be incredibly unnecessary to create a custom type just to ensure some invariant. eg. a non empty vec
@@Nesdac-k1lfunnily enough `NonEmptyVec` is actually a thing. I was in a situation where I actually needed that, and found out that there's a crate for that™
"the variable cannot have this value" is better expressed with `unreachable!`
Is panic! okay to use if there's no recovery possible?
yes, it is usually recommended if unrecoverable.
New pattern matching syntax that I didn't know about.
Do you have recommendations for how to handle a result in a function that can't return a result? (E.g. closures or implementing trait methods of library crates, that you do not own, which have a overly simply return type like String)
Having to discard the entire error stack up to that point always feels so wrong.
Also using Box without any good reason. Most of the time it is better to use impl Trait in function properties for static dispatch. Or even better fn() pointers for your own code.
I thought in Lazy-man error handling you will talk about mindless usage of `?` with anyhow lib
Very informative stuff, thank you as always
explain please how to create custom error types and what are the best practices there
check out `thiserror` crate for a simple/easy solution.
I miss the mentioning of the `Arc` anti-pattern, but maybe that's too complex for this kind of video and needs its own instead to explain why it's problematic.
Just so it's clear, points 1 and 3 are entirely allowed in Leetcode, Project Euler, Advent of Code, and similar settings. Unwrap and clone everything. Just make it run and get your answer.
The German translation is really awful.
5:28 I think you need `&self.settings` instead.
Yes! Good catch!
At 9:07 you switched place on number 2, 3 and 4.
Good catch, editing mistake :)
The biggest rust sin is not using Rust
Please don't use auto-translate for your titles, the translation is unbearable.
Didn't see an auto translated title, but I definitely still agree.
Fixed! YT started doing this automatically -_-
How is it possible? I thought, if it compiles, then it is good. /s
very interesting even for a beginner like me.
but youtube enabled the audio translation. what a pain in the a** !
This missing enum variant problem can be huge problem
la voix française est insupportable et on peut pas la changer sur browser de téléphone. Mais sinon good content
Man I love how Rust is just becoming C++. You have a problem ? don't worry we have syntax to solve it. Kidding love rust :) (still plz don't become C++)
I am `unwrap_or` user 😂😂😂
Rust propagandist try not to say "powerful" challenge (impossible)
I really dislike the black background in this video