-
Notifications
You must be signed in to change notification settings - Fork 13.4k
RFC: Destructuring vectors syntax #1844
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
Comments
This RFC stems from this StackOverflow question: http://stackoverflow.com/questions/9282805/rust-pattern-matching-over-a-vector Personally, I think it would be really useful if |
I kinda made up the syntax I was using, so feel free to change/modify/critique it as much as you guys want. I simply wrote it that way to express the idea. Haskell has a nice way of doing it by expressing the inverse of what you want, eg. a list is constructed from a number of cons (represented as an infix Ultimately, these are all operations that could easily be defined with a few ifs and maybe a call to find the length of the vector, but using a pattern to express the concept feels more concise. |
+1, absolutely. I was staring at the compiler trying to do similar things, only to realise that it hasn't yet been implemented! I was attempting something like this: alt xs {
[_,"foo"] {"bar"}
_ {"pub"}
} |
Something like this would be nice to have, for sure. If we had slices as @graydon recently proposed, then the |
Seems like #1799 blocks this. |
Since we have slices, this is no longer blocked. |
I've been looking at this (https://github.com/fawek/rust/commits/vector-destructuring) as a way to familiarize myself with the compiler. As the thread's been inactive for a while, I'd like to make sure that the current consensus is still that it would be good to have this. Based on the original two examples, the above branch compiles the following: fn foldl<T, U: Copy>(
values: &[T],
initial: U,
function: &fn(partial: U, element: &T) -> U
) -> U {
match values {
[head, tail...] => foldl(tail, function(initial, &head), function),
_ => copy initial
}
}
fn main() {
let x = [1, 2, 3, 4, 5];
let y = foldl(x, 1, |a, b| a * *b);
io::println(fmt!("%d", y));
} And the following: fn every_other_element<T: Copy>(
values: &[T]
) -> ~[T] {
match values {
[head, _, tail...] => ~[head] + every_other_element(tail),
[head] => ~[head],
_ => ~[]
}
}
fn main() {
let x = ["foo", "bar", "baz", "abc", "def"];
let y = every_other_element(x);
for y.each |s| {
io::println(fmt!("%s", *s));
}
} One missing bit I'm still looking at is proper detection of exhaustiveness. As it is now, the following wouldn't compile: fn every_other_element<T: Copy>(
values: &[T]
) -> ~[T] {
match values {
[head, _, tail...] => ~[head] + every_other_element(tail),
[head] => ~[head],
[] => ~[]
}
} Which might lead to confusion. I'll submit a proper PR with tests if the community still agrees on the syntax. |
Pull request 4091 seems to of landed, which implements this RFC, I think this can be closed? |
I think it can. I just realized there's no documentation for this at the moment. I'll write some. |
Currently its possible to destructure tuples, records, and enums in let's and alt patterns. It could be useful to also destructure vectors as well, plus it would feel more consistent.
The obvious goal would be to do something like this:
I am not sure of the syntax exactly but it would be useful to be able to destructure vectors at least in some way.
Another example of why this might be useful:
Could be expressed as:
In my samples I am assuming that in this expression:
[head, tail...]
;head
matches 1 element andtail
matches 0+ elements.But, the difference is just that using pattern matching makes this a lot more readable. If this should apply to lists instead of vectors, let me know, but list's are in the core:: they are in std:: so, my assumption is that it makes more sense for vec to work this way.
The text was updated successfully, but these errors were encountered: