From d966c1393d34478a45d48583a4dbfdb672097e9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Krasnoborski?= Date: Sun, 1 Jun 2014 23:49:27 +0200 Subject: [PATCH 1/2] initial commit --- active/0000-multiple-subslices.md | 89 +++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 active/0000-multiple-subslices.md diff --git a/active/0000-multiple-subslices.md b/active/0000-multiple-subslices.md new file mode 100644 index 00000000000..79cf1b86952 --- /dev/null +++ b/active/0000-multiple-subslices.md @@ -0,0 +1,89 @@ +- Start Date: 2014-06-01 +- RFC PR #: (leave this empty) +- Rust Issue #: (leave this empty) + +# Summary + +Change syntax in slice pattern matching from `..xs` to `xs..` (eg. `[head, tail..]`), +and allow multiple (fixed-size) subslices borrows in one pattern (eg. `[xs..3, ys..3]`). + +# Motivation + +(1) Current subslice matching syntax is inconsistent with constant-sized arrays types `[T, ..N]` and expressions `[e, ..N]`. +In both cases, token after `..` is a number – array size, but in current pattern matching it is a sublice's +name. Furthermore, I think that `xs..` is more intuitive (and is also similar to syntax that C++ uses in variadic templates). + +(2) Current syntax allows to make only one subslice reborrow in pattern. But now it's impossible to do following +with pattern matching: + + // slice has type &[T] + match slice { + [..firsts @ [_,_], ..rest] => { /* currently a syntax error */ } + // ... + } + +(3) Moving name binding before `..` also enables possibility to use right-hand side of `..` as subslice's size, +enabling for example simple parsing of fixed width data format: + + let line: Vec = get_a_line(); + match line.as_slice() { + [h, ..] if h == '#'.as_ascii() => (), + [record..45] => match record { + [name..20, state..10, phone..15] if valid(phone) => { /* ... */ }, + _ => fail!("Invalid phone number") + }, + _ => fail!("Invalid format") + } + +# Detailed design + +There are actually three proposals in this RFC: + +1. Change syntax from `..xs` to `xs..`. +2. Allow multiple subslices borrows in one pattern. +3. Allow `xs..N` syntax (depends on 1. and 2.). + +In this section I will describe as if all of proposals were implemented. + +Now the subslice matching is implemented as special case in the parser. What I want to have is +described in following grammar (which assumes trailing commas for simplicity) +(grammar syntax as in Rust manual): + + slice_pattern : "[" [[pattern | subslice_pattern] ","]* "]" ; + subslice_pattern : ["mut"? ident]? ".." integer? ["@" slice_pattern]? ; + +In the following example, all subslices are fixed-sized: + + [xs..5, mut ys..42, ..5, zs.. @[2,5], .. @[1, two, _]] => //... + [xs..@[ref first, ref second], ..10] => //... + +Because subslice patterns are not special cases now, there has to be additional +check that at most one non-fixed-size subslice pattern is used. + +Multiple mutable borrows of subslices should also be allowed (this is connected to +[#8636](https://github.com/mozilla/rust/issues/8636)), for example: + + let mut arr = [10, 20, 30, 40, 50]; + match arr { + [mut xs..2, 30, mut ys..] => for x in xs.mut_iter().chain(ys.mut_iter()) { *x += 1; }, + _ => () + } + +Rest of semantics and syntax should stay as it is. + +# Drawbacks + +The change is semantically backwards-compatible, so the only drawback +I can think of is that there are too little usecases to make this RFC worth implementing. + +# Alternatives + +* Do nothing, +* do only {1}, {2} or {1,2}, +* provide the same functionality with another syntax, +* provide the same/similar functionality with a macro. + +# Unresolved questions + +If 3. is implemented, should it be possible to bind subslice's length to a variable? +For example: `[_, tail..tail_len] => { /* ... */ }`. From 13be80a8fb4b39558e06fe82408dfca20e52aff6 Mon Sep 17 00:00:00 2001 From: krdln Date: Sun, 1 Jun 2014 23:57:31 +0200 Subject: [PATCH 2/2] Update 0000-multiple-subslices.md --- active/0000-multiple-subslices.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/active/0000-multiple-subslices.md b/active/0000-multiple-subslices.md index 79cf1b86952..401fe2449aa 100644 --- a/active/0000-multiple-subslices.md +++ b/active/0000-multiple-subslices.md @@ -13,7 +13,7 @@ and allow multiple (fixed-size) subslices borrows in one pattern (eg. `[xs..3, y In both cases, token after `..` is a number – array size, but in current pattern matching it is a sublice's name. Furthermore, I think that `xs..` is more intuitive (and is also similar to syntax that C++ uses in variadic templates). -(2) Current syntax allows to make only one subslice reborrow in pattern. But now it's impossible to do following +(2) Current syntax allows to make only one subslice reborrow in pattern. Now it's impossible to do following with pattern matching: // slice has type &[T]