Repository navigation
Description
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:
fn foldr<A, B>(func: fn(A, B) -> B,
initValue: B,
vals: [A]) -> B {
alt vals {
[] { ret initValue; }
[head, tail...] { ret foldr(func, func(initValue, head), tail); }
}
}
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:
fn ever_other_element<A>(vals: [A]) -> [A] {
alt vals {
[head, _, rest...] { ret [head] + ever_other_element(rest); }
[head, _] { ret [head]; }
_ { ret []; }
}
}
Could be expressed as:
fn ever_other_element<A>(vals: [A]) -> [A] {
if vec::len(vals) > 2 {
let head = vals[0],
rest = vec::tail(vec::tail(vals));
ret [head] + ever_other_element(rest);
}
else if vect::len(vals) == 2 {
let head = vals[0];
ret [head];
}
else {
ret [];
}
}
In my samples I am assuming that in this expression: [head, tail...]; head matches 1 element and tail 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.
Activity
bstrie commentedon Feb 15, 2012
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
alts were able to reason about vectors in the manner shown in the first example here. Testing for an empty list using[] { ... }seems much more intuitive and concise thanx if x == [] { ... }, and thetail...syntax (which feels familiar to rest parameters in Harmony) seems to be somewhat analogous to the...in the macro-by-example syntax.ashgti commentedon Feb 15, 2012
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
:) with a[]at the end. So:[1, 2, 3] == 1:2:3:[]and in the pattern matching syntax you can express the inverse operations you want applied to the structure. So, sayingx:xsreally means just undo that first cons. Which is ultimately nice because the syntax you use in the pattern matching is the same syntax you use in other places, just reversed.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.
amunra commentedon Mar 17, 2012
+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:
nikomatsakis commentedon Mar 28, 2012
Something like this would be nice to have, for sure. If we had slices as @graydon recently proposed, then the
...syntax would be cheap.catamorphism commentedon Apr 12, 2012
Seems like #1799 blocks this.
catamorphism commentedon Aug 2, 2012
Since we have slices, this is no longer blocked.
ashgti commentedon Dec 28, 2012
Pull request 4091 seems to of landed, which implements this RFC, I think this can be closed?
Fix cbmc-viewer ci issues with Mac11 (rust-lang#1844)
Merge rust-lang#1844
Auto merge of rust-lang#1844 - hyd-dev:rustup, r=RalfJung