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

Tuple issue #41081

Closed
wind2412 opened this issue Apr 5, 2017 · 10 comments
Closed

Tuple issue #41081

wind2412 opened this issue Apr 5, 2017 · 10 comments

Comments

@wind2412
Copy link

wind2412 commented Apr 5, 2017

I defined a tuple: let tuple: ((u8, u32),(u8, u32)) = ((1, 45), (2, 100));
And I have a tool to look up its type:

#![feature(core_intrinsics)]

fn type_of<T>(_: T) {
	println!("{}", unsafe { std::intrinsics::type_name::<T>() });
}
//p.s. from stack overflow

So I can get the type of the tuple: type_of(tuple.0); and it turns out to be (u8, u32).Right.
According to convention, I can use tuple.0.0 to get the first u8 value. Because type_of(tuple.0) is (u8, u32). But when I use tuple.0, I get:

error: unexpected token: `0.0`
  --> test_tuple.rs:38:16
   |
38 | 	type_of(tuple.0.0);		
   | 	              ^^^
   |
help: try parenthesizing the first index
   | 	type_of(tuple.(tuple.0).0);	 

error[E0061]: this function takes 1 parameter but 0 parameters were supplied
  --> test_tuple.rs:38:2
   |
3  |   fn type_of<T>(_: T) {
   |  _- starting here...
4  | | 	println!("{}", unsafe { std::intrinsics::type_name::<T>() });
5  | | }
   | |_- ...ending here: defined here
...
38 |   	type_of(tuple.0.0);		
   |    ^^^^^^^^^^^^^^^^^^ expected 1 parameter

error: aborting due to previous error

A little weird of this wrong message... It tells us Rust recognized it as tuple.(0.0)...
And I do as the "help"'s advice, type_of(tuple.(tuple.0).3) and then get another wrong msg...

error: unexpected token: `(`
  --> test_tuple.rs:39:16
   |
39 | 	type_of(tuple.(tuple.0).3);		
   | 	              ^

error: aborting due to 2 previous errors

But I use (tuple.0).0 is okay...

If it's not made deliberately, hope you can fix this syntax instead of (tuple.0).0 and make the help message better~;)

Besides,

>rustc --version
rustc 1.18.0-nightly (2564711e8 2017-04-04)
@leonardo-m
Copy link

leonardo-m commented Apr 5, 2017

You can also add a space:

#![allow(unused_variables)]
fn main() {
    let tt = ((1, 2), (10, 20));
    let x = tt.0 .0;
}

I think the tuple access syntax is one of the few design mistakes of Rust. A array-indexing-like syntax like in D/Python language avoids that problem altogether:

let x = tt[0][0];

And it can be used in static for loops as in D language:

void main() {
    import std.stdio, std.meta, std.typecons;
    immutable tup = tuple(10, 20, 30);
    foreach (immutable i; AliasSeq!(0, 1, 2)) {
        writeln(tup[i]);
    }
}

But perhaps now it's too much late to fix the tuple indexing syntax even in epoch.

@estebank
Copy link
Contributor

estebank commented Apr 5, 2017

This bug in particular was an incorrect span being used for the suggestion and a unittest not actually checking the output. Thanks for the bug report!

@steveklabnik
Copy link
Member

I think the tuple access syntax is one of the few design mistakes of Rust. A array-indexing-like syntax like in D/Python language avoids that problem altogether:

For some history here: https://github.com/rust-lang/rfcs/blob/master/text/0184-tuple-accessors.md

@leonardo-m
Copy link

For some history here: https://github.com/rust-lang/rfcs/blob/master/text/0184-tuple-accessors.md

Thank you for the link. Unfortunately the drawbacks of the t.0.0 syntax was ignored in that RFC, the "Unresolved questions" is empty, and the "Alternatives" lacks a discussion of the [] syntax. In the implementation thread they say:

Indexing syntax was already commented upon, and rejected, because it's actually a really bad fit. Notably, indexing syntax everywhere else has a consistent type, but a tuple is heterogenous so a[0] and a[1] would have different types.

This sounds silly, and ignores both the D language and Python, and the possible usage in static for loops as in D language... So it's a Rust wart for me.

@durka
Copy link
Contributor

durka commented Apr 6, 2017

FWIW I think the tuple syntax in general is fine, but the error with nested indexing that's highlighted here is one of those annoying "I know what you meant, but I'll make you rephrase it anyway" errors that we could consider simply removing in the name of usability.

@leonardo-m
Copy link

FWIW I think the tuple syntax in general is fine,

You can't use it to index statically.

@arielb1
Copy link
Contributor

arielb1 commented Apr 6, 2017

@leonardo-m

Rust is a statically-typed language, so you can't index tuples dynamically anyway.

@leonardo-m
Copy link

Rust is a statically-typed language, so you can't index tuples dynamically anyway.

That's the point of a static loop, take a look at the D code above. There's no dynamic tuple indexing in it.

@durka
Copy link
Contributor

durka commented Apr 6, 2017

I don't read D fluently, but that D code seems to have a tuple with three items of the same type, which is weird -- in Rust you'd just use an array. Actually, in Rust you'd use a macro to get the same effect, right? Like this:

macro_rules! tuploop {
    (foreach |$tup:expr, $i:ident: [$($idx:tt),*]| $code:expr) => {
        $(
            let $i = $tup.$idx;
            $code;
        )*
    }
}

fn main() {
    let tup = (1, "hi");
    tuploop! {
        foreach |tup, i: [0, 1]| {
            println!("{}", i);
        }
    }
}

@leonardo-m
Copy link

that D code seems to have a tuple with three items of the same type, which is weird -- in Rust you'd just use an array.

That D code isn't weird, it's just an example. If you want an example tuple with different types here it is:

void main() {
    import std.stdio, std.meta, std.typecons;
    immutable tup = tuple(10, 20.5, "hello");
    foreach (immutable i; AliasSeq!(0, 1, 2)) {
        writeln(tup[i]);
    }
}

Actually, in Rust you'd use a macro to get the same effect, right?

Thank you for your macro. I think the current Rust tuple indexing syntax isn't good enough, it wasn't discussed enough during the language design phase. Probably it's too much late now to fix it even in a Rust Epoch.

TimNN added a commit to TimNN/rust that referenced this issue Apr 12, 2017
Use proper span for tuple index parsed as float

Fix diagnostic suggestion from:

```rust
help: try parenthesizing the first index
  |     (1, (2, 3)).((1, (2, 3)).1).1;
```

to the correct:

```rust
help: try parenthesizing the first index
  |     ((1, (2, 3)).1).1;
```

Fix rust-lang#41081.
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

6 participants