-
Notifications
You must be signed in to change notification settings - Fork 543
parallel-letter-frequency: Use &str with lifetime, not String #239
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
The previous version had a comment that explained a need for copying the `&str` into `Strings`, but this can be avoided. The disadvantage is now that this function can *only* be invoked with `&'static str`, which means that it can't (for example) accept arbitrary user input as part of a command-line program. So it works for our style of testing (all our tests do indeed use `&'static str`) but is unrealistic code.
I think I'm fine with this. Declaring static lifetimes is a good thing to see, assuming anyone looks at the examples. |
I don't like this. Who will look at examples? I guess some people who want to simply "cheat" and those who are stuck and want to peek at a solution. It may look like a function accepting only If we merge this at least put a warning comment before the function... and by doing that we are back to the original problem with the comment explaining things. |
@ijanos Do you have more details on why it's not a good pattern? I would like to know more! From my experience, I use the examples a lot when learning a new language. I usually know how to solve the problem, but I don't know the language's syntax or idioms. So I'll look at the example code to figure out what I need to use. I don't know if that's common, but this use case is one of the reasons we settled on the goal of having our example solutions be, well, exemplary. We want them to use reasonably idiomatic, well-written Rust. |
The problem is explained shortly with: It is now impossible for this function to take a I can try to come up with example code soon, but not now. |
No intent to merge - better close now to avoid any mistakes. I do still plan to get back to you with a reason why it's not going to get merged. |
@IanWhitney Accepting a static string slice basically means accepting only strings available at compile time. Imagine using a library that has a restriction like that, you cannot call it on anything you don't know during compile, like data from a file, data downloaded from somewhere or user input. |
Reopening to show Travis. Please do not merge. |
This is meant to demonstrate why `&'static str` of #239 is very restrictive.
The commit 8fe6c5b should show the restrictiveness of Failure reproduced here for posterity:
|
Ok, I think I see what's going on here now. My understanding was that all So, based on that belief, I thought these two lines are identical
But the non-lifetime version is allowing Rust to do some implicit conversion of let hi = format!("Hello, {}!", "world");
&[&hi] into something it can think of as a str. Right? But one you say "I only accept static str" then the compiler can't do the conversion since it can't satisfy the lifetime requirements. 🦆 |
I believe that's a good summary. My understanding of the full story is below, if it is unclear to anyone. Please correct if I made any errors.
The version without lifetime annotations follows the rules of lifetime elision which should mean that it is equivalent to: pub fn frequency<'a, 'b>(texts: &'a [&'b str], num_workers: usize) -> HashMap<char, usize> The only requirement on At this point, let's see why we have to do The strings in However, if Aside: If we wanted to have the type system prove that the threads terminate before their spawner, that seems a bit tricky! But it's been done! I have not investigated this crate to see what it is doing. What happens in this PR? If I understand lifetime elision properly, what I wrote should be equivalent to: pub fn frequency<'a>(texts: &'a [&'static str], num_workers: usize) -> HashMap<char, usize> For the But imposing the requirement on the callers leads to unrealistic code, and would not make a good example for our students. As I showed, references of arbitrary |
The previous version had a comment that explained a need for copying the
&str
intoString
s, but this can be avoided.The disadvantage is now that this function can only be invoked with
&'static str
, which means that it can't (for example) accept arbitraryuser input as part of a command-line program. So it works for our style
of testing (all our tests do indeed use
&'static str
) but isunrealistic code.
Reviewers should consider the disadvantage carefully before deciding whether to merge. Of course, this is only the example and doesn't affect the test code. On the other hand, it could be better to keep the example code realistic.
In the extreme case, we might even choose to add a test that creates non-
'static
strings, so that using&'static str
is not possible (I do not advocate for this, but y'all can if you like)