Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign upAllow use of pipe operator in patterns. #1882
Conversation
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
|
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
petrochenkov
Feb 3, 2017
Contributor
I think you also have to introduce pattern grouping with parens () to disambiguate something like a @ PAT1 | PAT2.
|
I think you also have to introduce pattern grouping with parens |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Nemo157
Feb 3, 2017
Contributor
As an example this currently works:
match a {
f @ 'b' | f @ 'c' => foo(f),
_ => (),
}and this currently fails because of f not being bound in the second pattern:
match a {
f @ 'b' | 'c' => foo(f),
_ => (),
}but if 'b' | 'c' was itself a pattern then it could be possible to do something like
match a {
f @ ('b' | 'c') => foo(f),
_ => (),
}to bind f to whatever matched the pattern 'b' | 'c' without having to bind in each sub-pattern individually
|
As an example this currently works: match a {
f @ 'b' | f @ 'c' => foo(f),
_ => (),
}and this currently fails because of match a {
f @ 'b' | 'c' => foo(f),
_ => (),
}but if match a {
f @ ('b' | 'c') => foo(f),
_ => (),
}to bind |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
mbrubeck
Feb 3, 2017
Contributor
I think a better way to modify the grammar might look something like this:
Remove the pats_or nonterminal, and replace it with pat in the match expression grammar:
nonblock_match_clause
: maybe_outer_attrs pat maybe_guard FAT_ARROW nonblock_expr
| maybe_outer_attrs pat maybe_guard FAT_ARROW full_block_expr;
block_match_clause
: maybe_outer_attrs pat maybe_guard FAT_ARROW block;Change the top-level pat grammar to allow one or more patterns separated by |:
pat
: single_pat
| pat '|' single_pat;And add a new single_pat rule that matches the old pat rule, with the possible addition of an alternation enclosed in parentheses:
single_pat
: UNDERSCORE
| '&' pat
| '&' MUT pat
// ...
| '(' pat '|' single_pat ')'
;(There might be some ambiguity to resolve between that last rule and tuple patterns.)
|
I think a better way to modify the grammar might look something like this: Remove the nonblock_match_clause
: maybe_outer_attrs pat maybe_guard FAT_ARROW nonblock_expr
| maybe_outer_attrs pat maybe_guard FAT_ARROW full_block_expr;
block_match_clause
: maybe_outer_attrs pat maybe_guard FAT_ARROW block;Change the top-level pat
: single_pat
| pat '|' single_pat;And add a new single_pat
: UNDERSCORE
| '&' pat
| '&' MUT pat
// ...
| '(' pat '|' single_pat ')'
;(There might be some ambiguity to resolve between that last rule and tuple patterns.) |
Aaronepower
changed the title from
Allow use of pipe operator in sub expressions.
to
Allow use of pipe operator in patterns.
Feb 3, 2017
aturon
added
the
T-lang
label
Feb 3, 2017
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
sgrif
Feb 8, 2017
Contributor
I am in favor of this, but this was also proposed last year. Have the reasons that was postponed changed/been addressed?
(Note: WRT real world impact, I don't have links off-hand but I have run into wanting this 3-4 times in Diesel in the past 3 months or so. I'm sure I can dig up where I wanted this if needed)
|
I am in favor of this, but this was also proposed last year. Have the reasons that was postponed changed/been addressed? (Note: WRT real world impact, I don't have links off-hand but I have run into wanting this 3-4 times in Diesel in the past 3 months or so. I'm sure I can dig up where I wanted this if needed) |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Ericson2314
Feb 9, 2017
Contributor
Well, for one, the MIR is done now.
The Haskell community is discussing this right now, btw: ghc-proposals/ghc-proposals#43 (comment). http://gallium.inria.fr/%7Escherer/research/ambiguous_pattern_variables/ml_workshop_2016.abstract.pdf was especially useful and cited in that thread.
|
Well, for one, the MIR is done now. The Haskell community is discussing this right now, btw: ghc-proposals/ghc-proposals#43 (comment). http://gallium.inria.fr/%7Escherer/research/ambiguous_pattern_variables/ml_workshop_2016.abstract.pdf was especially useful and cited in that thread. |
aturon
assigned
nrc
Feb 9, 2017
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Aaronepower
Feb 10, 2017
@petrochenkov @Nemo157 Why would the () be necessary? Wouldn't foo @ '\n' | '\r' => {} be ideal syntax?
@sgrif Well with the Rust roadmap, and I think this would fit well into lowering the learning curve for Rust, as it provides a much more intuitive syntax for pattern matching.
Aaronepower
commented
Feb 10, 2017
|
@petrochenkov @Nemo157 Why would the @sgrif Well with the Rust roadmap, and I think this would fit well into lowering the learning curve for Rust, as it provides a much more intuitive syntax for pattern matching. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
petrochenkov
Feb 10, 2017
Contributor
@Aaronepower
@Nemo157 gave an example of why introducing | as a high priority operator is a breaking change.
f @ 'b' | f @ 'c'
is currently a valid match arm and it's grouped as (f @ 'b') | (f @ 'c').
If | has high priority, then the example is parsed as an invalid pattern f @ ('b' | f @ 'c').
I've just grepped rustc and found a few examples in real code:
ref t @ TyUint(_) | ref t @ TyInt(_)
def @ None | def @ Some(Def::Local(_))
seq @ TokenTree::Delimited(..) | seq @ TokenTree::Token(_, DocComment(..))
// etc
&PAT | &PAT has this problem as well.
In general, it would be natural for | to have low priority, both for compatibility, and because binary/sequence operators have lower priority than unary operators in both expression and type grammars.
However, if | has low priority, then we cannot express foo @ ('\n' | '\r'), which can be useful. This can be fixed in the same way as it's fixed in expression and type grammars - with parens.
|
@Aaronepower
is currently a valid match arm and it's grouped as I've just grepped rustc and found a few examples in real code:
In general, it would be natural for However, if |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
aturon
Apr 29, 2017
Member
This RFC is missing its motivation section, which is probably the most important section of an RFC!
While this feature seems potentially nice, there is often a lot of unanticipated detail work necessary to push changes like this through (e.g, @petrochenkov is already turning up some interesting issues). Before we spend time hashing out all those details, there needs to be a clear case for why this is important to prioritize right now.
|
This RFC is missing its motivation section, which is probably the most important section of an RFC! While this feature seems potentially nice, there is often a lot of unanticipated detail work necessary to push changes like this through (e.g, @petrochenkov is already turning up some interesting issues). Before we spend time hashing out all those details, there needs to be a clear case for why this is important to prioritize right now. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
joshtriplett
May 11, 2017
Member
One corner case in treating this as pure syntactic sugar: what if I write this:
match a_big_tuple {
(0|1, 0|1, 0|1, 0|1, 0|1, 0|1, ...) => ...(Or anything else where you embed multiple alternations inside a pattern.) The obvious syntactic-sugar expansion would turn that into 2^n patterns. (The compiler ought to be able to optimize that in cases like this, but it could result in a large intermediate state if not handled specially.)
Does this seem like a problem?
|
One corner case in treating this as pure syntactic sugar: what if I write this: match a_big_tuple {
(0|1, 0|1, 0|1, 0|1, 0|1, 0|1, ...) => ...(Or anything else where you embed multiple alternations inside a pattern.) The obvious syntactic-sugar expansion would turn that into 2^n patterns. (The compiler ought to be able to optimize that in cases like this, but it could result in a large intermediate state if not handled specially.) Does this seem like a problem? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
mglagla
May 22, 2017
Small data point: i am making a small tetris clone using the sdl2-crate. In my code i have a match expression which looks like this, if i understand it right:
for event in event_pump.poll_iter() {
use sdl2::event::Event;
use sdl2::keyboard::Keycode::{Escape, Q};
match event {
Event::KeyDown {
keycode: Some(Escape),
..
}
| Event::KeyDown {
keycode: Some(Q),
..
} => break 'game,
_ => {},
}
With this RFC i would be able to express more concisely like this:
for event in event_pump.poll_iter() {
use sdl2::event::Event;
use sdl2::keyboard::Keycode::{Escape, Q};
match event {
Event::KeyDown {
keycode: Some(Escape | Q),
..
} => break 'game,
_ => {},
}
In my opinion, this is more clear and thus less error-prone.
mglagla
commented
May 22, 2017
•
|
Small data point: i am making a small tetris clone using the sdl2-crate. In my code i have a match expression which looks like this, if i understand it right: for event in event_pump.poll_iter() {
use sdl2::event::Event;
use sdl2::keyboard::Keycode::{Escape, Q};
match event {
Event::KeyDown {
keycode: Some(Escape),
..
}
| Event::KeyDown {
keycode: Some(Q),
..
} => break 'game,
_ => {},
}
With this RFC i would be able to express more concisely like this: for event in event_pump.poll_iter() {
use sdl2::event::Event;
use sdl2::keyboard::Keycode::{Escape, Q};
match event {
Event::KeyDown {
keycode: Some(Escape | Q),
..
} => break 'game,
_ => {},
}
In my opinion, this is more clear and thus less error-prone. |
petrochenkov
referenced this pull request
May 31, 2017
Merged
Match Ergonomics Using Default Binding Modes #2005
petrochenkov
referenced this pull request
Jun 16, 2017
Merged
Allow an optional vert at the beginning of a match branch #1925
mbrubeck
referenced this pull request
Jul 8, 2017
Closed
Allow alternation within sub-patterns #17180
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
rfcbot
Jul 25, 2017
Team member @aturon has proposed to close this. The next step is review by the rest of the tagged teams:
No concerns currently listed.
Once these reviewers reach consensus, this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!
See this document for info about what commands tagged team members can give me.
rfcbot
commented
Jul 25, 2017
•
|
Team member @aturon has proposed to close this. The next step is review by the rest of the tagged teams: No concerns currently listed. Once these reviewers reach consensus, this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
rfcbot
added
the
proposed-final-comment-period
label
Jul 25, 2017
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
joshtriplett
Jul 26, 2017
Member
@Aaronepower To further clarify: if you're interested in seeing this go into Rust, that's still possible; it just needs further expansion into a full RFC that addresses all the issues raised in this thread.
I'm personally interested in seeing this.
|
@Aaronepower To further clarify: if you're interested in seeing this go into Rust, that's still possible; it just needs further expansion into a full RFC that addresses all the issues raised in this thread. I'm personally interested in seeing this. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
liigo
Jul 28, 2017
Contributor
I'm confused. What's the type of expression a | b? and what is its value?
|
I'm confused. What's the type of expression |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
eddyb
Jul 28, 2017
Member
@liigo It's not an expression, it's a pattern for "try pattern a and if that doesn't match try b".
|
@liigo It's not an expression, it's a pattern for "try pattern |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
nrc
Jul 31, 2017
Member
Agree we should close. Although I do think it would be a good feature to have, I don't think it should be high priority right now.
|
Agree we should close. Although I do think it would be a good feature to have, I don't think it should be high priority right now. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
(Checking off for @pnkfelix, who is away) |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
rfcbot
commented
Aug 9, 2017
|
|
rfcbot
added
final-comment-period
and removed
proposed-final-comment-period
labels
Aug 9, 2017
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
rfcbot
commented
Aug 19, 2017
|
The final comment period is now complete. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
liigo
Aug 22, 2017
Contributor
It's not an expression, it's a pattern for "try pattern a and if that doesn't match try b".
According to the refference:
The type of the patterns must equal the type of the head expression.
the pattern Some('a' | 'b')'s type must be Option(char). so the type of 'a' | 'b' should be char?
According to the refference:
the pattern |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Centril
Aug 24, 2017
Contributor
@nrc I disagree - it helps ergonomics a lot and should fit in well with the 2017 ergonomics initiative.
|
@nrc I disagree - it helps ergonomics a lot and should fit in well with the 2017 ergonomics initiative. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
I agree it helps ergonomics, but a little. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
Closing, as per FCP. Thanks @Aaronepower for the RFC! |
aturon
closed this
Aug 26, 2017
petrochenkov
referenced this pull request
Oct 16, 2017
Merged
RFC: or-patterns in let and if / while let expressions #2175
petrochenkov
referenced this pull request
Jan 29, 2018
Open
Variable labeling of complex match arms should be able to label the whole arm #673
petrochenkov
referenced this pull request
Apr 7, 2018
Open
Tracking issue for RFC #2175: or-patterns in if / while let expressions #48215
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
New RFC for this feature: #2535. |
Aaronepower commentedFeb 3, 2017
•
edited
rendered