Skip to content
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

Question on patterns section shadowing example (existing book) #316

Closed
JamieMason opened this issue Nov 1, 2016 · 5 comments
Closed

Question on patterns section shadowing example (existing book) #316

JamieMason opened this issue Nov 1, 2016 · 5 comments

Comments

@JamieMason
Copy link

Hi,
I'm confused by the following example in the existing book and was hoping someone might be able to help me. I've sought help via an issue incase it's found that other beginners could draw the same conclusions I have and the book might be updated to help them.

There’s one pitfall with patterns: like anything that introduces a new binding, they introduce shadowing. For example:

let x = 1;
let c = 'c';

match c {
    x => println!("x: {} c: {}", x, c),
}

println!("x: {}", x)

This prints:

x: c c: c
x: 1

https://doc.rust-lang.org/book/patterns.html

My understanding is that x is 1 and c is 'c', so println!("x: {} c: {}", x, c) should not run because 'c' != 1, but this is not the case. I'd also expect a complaint that _ is not set to catch cases where x => is not met.

Out of curiosity I also tried;

let x = 1;
let c = 'c';

match c {
    y => println!("y: {} c: {}", y, c),
}

println!("x: {}", x)

Which prints:

y: c c: c
x: 1

But again, y shouldn't match as far as I understand, but does.

Grateful for any help, thanks for your time.

@steveklabnik
Copy link
Member

Some quick comments, sorry if this isn't super clear

should not run because 'c' != 1, but this is not the case

Remember, pattern matching matches on the type and structure, not on the value.

I'd also expect a complaint that _ is not set to catch cases where x => is not met.

x and _ will both match anything. The only difference is if you give that matched value a name or not.

@carols10cents
Copy link
Member

Thank you for the feedback! We haven't gotten to the Patterns chapter in the new version of the book yet, and it will likely be significantly different when we do get there. So I'm going to close this issue, but we will keep it in mind.

We are happy to help with issues on here-- some other places you might also want to try if you need help are:

Thanks!!! 🌻

@btipling
Copy link

btipling commented Jan 15, 2017

@carols10cents I think updating the pattern page should be a huge priority because as it's written it's one of hardest to understand page as it is, even for someone with previous rust experience. It's so hard because it introduces an entirely new language feature without explaining. Someone could update it within the span of a few minutes by just explaining the newly introduced feature.

match c {
    x => println!("x: {} c: {}", x, c),
}

No where in the book up to this point has it explained that identifiers match patterns with just a name create an irrefutable pattern. The page uses this feature without explanation, it just assumes that readers would immediately understand it. To confuse the issue even further the topic uses this feature to explain shadowing, placing two x's from different scopes and different meanings without ever explaining why there is shadowing.

What follows comes across as utterly nonsensical given everything the reader would know about Rust about this point:

the result:
x: c c: c
x: x

x is c? What? Yes even if you understand that x here is not the x in the previous scope why would x equal 'c' here? What previous chapter explained this? The previous chapter on 'matching' only mentions the catch all '_' and never in any shape or form mentioned that a name here creates an irrefutable pattern and binds a value.

There are numerous examples of people not understanding this section, not finding answers and looking for them online about x: c c: c:

https://stackoverflow.com/questions/35563141/match-shadowing-example-in-the-patterns-section-of-the-rust-book-is-very-perplex

https://users.rust-lang.org/t/confusion-about-match-and-patterns/3937

https://www.bountysource.com/issues/38852461-question-on-patterns-section-shadowing-example-existing-book

And a google search for rust x: c c: c finds many more people being tripped up, including people who speak a language other than English. I am confident that this page has resulted in questions on the irc channel more than once. Given rust already has a pretty big learning curve I recommend this issue being reopened and someone best suited to write docs, just spend 15 minutes, just like 15 minutes of their time right now and just explain what is happening here. I get it you're rewriting this page, but in the meantime don't throw this problem over the fence because every day someone is coming to this badly written page and probably some of them just give up and move on to learn some other language.

This issue was closed nearly three months ago and yet this page is still as bad as it was when the issue was originally opened, and it could have just taken a few minutes to fix. Just explain why a variable is bound here before you talk about shadowing.

@carols10cents
Copy link
Member

@btipling Please send a pull request, since it will only take a few minutes! Thanks!

@btipling
Copy link

@carols10cents I didn't realize this repository was a separate project from the currently published version, having said that I have an attempt here:

rust-lang/rust#39084

GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this issue Jan 16, 2017
…eklabnik

An update to patterns documentation

As it is written the current pattern page creates a lot of confusion, even for someone with previous rust experience. It's so hard because it introduces an entirely new language feature without explaining. Someone could update it within the span of a few minutes by just explaining the newly introduced feature.

```rust
match c {
    x => println!("x: {} c: {}", x, c),
}
```
No where in the book up to this point has it explained that identifiers match patterns with just a name create an irrefutable pattern. The page uses this feature without explanation, it just assumes that readers would immediately understand it. To confuse the issue even further the topic uses this feature to explain shadowing, placing two x's from different scopes and different meanings without ever explaining why there is shadowing.

What follows comes across as utterly nonsensical given everything the reader would know about Rust about this point:

```rust
the result:
x: c c: c
x: x
```

x is c? What? Yes even if you understand that x here is not the x in the previous scope why would x equal 'c' here? What previous chapter explained this? The previous chapter on 'matching' only mentions the catch all '_' and never in any shape or form mentioned that a name here creates an irrefutable pattern and binds a value.

There are numerous examples of people not understanding this section, not finding answers and looking for them online about `x: c c: c`:

rust-lang/book#316

https://stackoverflow.com/questions/35563141/match-shadowing-example-in-the-patterns-section-of-the-rust-book-is-very-perplex

https://users.rust-lang.org/t/confusion-about-match-and-patterns/3937

https://www.bountysource.com/issues/38852461-question-on-patterns-section-shadowing-example-existing-book

And a [google search for `rust x: c c: c`](https://www.google.com/search?q=rust+%22x:+c+c:+c%22) finds many more people being tripped up, including people who speak a language other than English. I am confident that this page has resulted in questions on the irc channel more than once. Given rust already has a pretty big learning curve I recommend this be fixed.

I was asked to create PR from where I made this same case in the [rust book repository issue](rust-lang/book#316) (I didn't realize this was a separate project).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants