Skip to content

In the Guide, the example of extracting a value from a newtype is confusing #20471

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

Closed
camjackson opened this issue Jan 3, 2015 · 4 comments · Fixed by #21038
Closed

In the Guide, the example of extracting a value from a newtype is confusing #20471

camjackson opened this issue Jan 3, 2015 · 4 comments · Fixed by #21038

Comments

@camjackson
Copy link
Contributor

In this section of the guide, this example is given:

struct Inches(int);

let length = Inches(10);

let Inches(integer_length) = length;
println!("length is {} inches", integer_length);

As a newcomer to Rust, I found this example quite confusing, specifically the line declaring the integer_length binding. Until this point in the Guide, all bindings are declared like let var_name = "some_value"; or let var_name: VarType;. All of a sudden, we have let SomeType(var_name) = instance_of_SomeType;, and the only explanation is "you can extract the inner integer type through a destructuring let".

It's clear enough from the context what the line is doing (extracting the inner value), but I don't really get how the code works, or why the syntax looks that way, rather than let integer_length = some_expression_involving_length;.

Also, and perhaps this should be a separate issue, I personally feel like mentioning tuple structs is unnecessary at this point in the guide? They are brought up, and then immediately dismissed in favour of proper structs, which leaves the reader (or me, at least) wondering why they exist in the language at all... Perhaps tuple structs are only explained as a precursor to showing off newtypes (which do seem useful), but I still feel like newtypes could be explained well enough without going into tuple structs, or perhaps with just a passing mention that a newtype is a special case of a thing called a tuple struct, which will be covered later.

@steveklabnik
Copy link
Member

It's mostly there to just introduce the concept. They're only really useful in specific circumstances.

That said, yes, explaining that this is a pattern could maybe use more explanation.

@ninjabear
Copy link

+1 I found this confusing also, unless you've programmed prolog or something its an unusual construct.

As for patterns in general, the one that made it click for me was fizzbuzz;

  for x in range(0i, 101i) {

    match (x % 3, x % 5) {
      (0, 0) => println!("fizzbuzz"),
      (0, _) => println!("fizz"),
      (_, 0) => println!("buzz"),
           _ => println!("{}", x),
    }

  }

mind=blown.

just my 2 cents.

@camjackson
Copy link
Contributor Author

I think the destructuring let feels quite natural for tuples:

let (x, y) = (1i, 2i);

It's when its used on a struct that it feels weird at first:

let MyStruct(new_int_binding) = instance_of_MyStruct

Having spent most of my time in Ruby/Python/Java/C, when I see Type(var) it immediately looks to me like var is an existing variable being passed as a parameter to create a new instance of Type, rather than the name of a new variable pulling something out of an instance of Type.

I think the comparison to tuple destructuring really helps a lot though. It makes it clearer that what you're doing is writing a binding declaration on the left that kind of 'lines up with' the value on the right. Would something like this be an OK addition?

As you can see here, you can extract the inner integer type through a destructuring let. This is equivalent to how you would extract values from a tuple, with the bindings on the left wrapped in a type matching that of the value on the right: let (x, y) = (1i, 2i);.

If the inline code example isn't OK, you could probably even just drop it and still gain a lot from the comparison, in my opinion.

steveklabnik added a commit to steveklabnik/rust that referenced this issue Jan 12, 2015
alexcrichton added a commit to alexcrichton/rust that referenced this issue Jan 15, 2015
@FranklinChen
Copy link
Contributor

Would it be useful to point out briefly in the documentation that tuple syntax is just syntactic sugar for a struct, e.g.,

(a, b)
(a, b, c)

are basically special macros for

Pair2(a, b)
Pair3(a, b, c)

so that pattern matching is presented pedagogically as operating on structs in general in a regular, consistent way?

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

Successfully merging a pull request may close this issue.

4 participants