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

RFC: Extend pattern syntax #99

Closed
wants to merge 1 commit into from
Closed

Conversation

ftxqxd
Copy link
Contributor

@ftxqxd ftxqxd commented Jun 1, 2014

@pczarn
Copy link

pczarn commented Jun 1, 2014

The guard syntax could be modeled after Python's if expressions, for example: ((a, _) if a > 5 else (_, a)).

A sugar for _ if cond => is another minor thing to consider. Anyway, I don't see anything in this RFC that could be so easily implemented with a procedural macro.

@ftxqxd
Copy link
Contributor Author

ftxqxd commented Jun 2, 2014

One thing I’d like to remark on that I didn’t mention in the RFC is that this could potentially make pattern macros a lot more useful. As a (relatively) useless example, a vec_pat! procedural macro could probably be made that uses guards to match against a Vec<T>. I could imagine this being used for more complex data structures like {Tree, Hash}{Map, Set}.

(Should I mention this within the RFC itself?)

@bstrie
Copy link
Contributor

bstrie commented Jun 2, 2014

Prior to submission, there was extensive discussion of this RFC on reddit: http://www.reddit.com/r/rust/comments/270b6y/idea_for_extending_the_patternmatching_syntax/

@bstrie
Copy link
Contributor

bstrie commented Jun 2, 2014

To summarize my personal opinions, unchanged since that reddit thread:

Change @-patterns to allow a pattern on either side.

Shrug. No other language with as-patterns does this, but I don't see a reason why we couldn't if we wanted to.

Add alternation (|) to patterns properly.

I think that static typing and the requirement of irrefutability will make this unusable in practice.

Add pattern guards (pattern if condition) to patterns properly.

Vehemently against allowing this in function arguments. Our function signatures are already gnarly enough.

Treat repeated variables as implicit guards for equality.

Seems magical and makes patterns susceptible to typos, but could be useful if there's demand for it.

@bstrie
Copy link
Contributor

bstrie commented Jun 2, 2014

It's also worth noting that the last enhancement (repeated variables as equality) is the only part of this RFC that could not be added post-1.0 without breaking backcompat.

@ftxqxd
Copy link
Contributor Author

ftxqxd commented Jun 3, 2014

I just ran into a use case for alternation in regular patterns—I was using a tree type where each node also stored its weight (enum Tree<T> { Branch(uint, Box<Tree<T>>, Box<Tree<T>>), Leaf(uint, T) }). I needed to extract the weight of an instance of Tree, and so I had to construct an entire match statement where, with this proposal, I could have instead used let Branch(weight, _, _) | Leaf(weight, _) = tree;.

@bstrie Repeated variables as equality is technically backwards-incompatible, but repeated variables right now are completely useless (& should probably warn/error (rust-lang/rust#14581)), so in practice it’s not really backwards-incompatible.

@glaebhoerl
Copy link
Contributor

I really like the thing with alternation (|) and binding (@) and the analogy with boolean operators.

Indifferent about guards.

As I already wrote on reddit, I'm wary about repeated variables implying an equality guard, because I don't want seemingly innocuous patterns calling out to user code (via Eq), nor do I want to have a wired-in primitive notion of equality distinct from Eq. If you want to invoke an == operator overload, be explicit about it and use a guard.

@nikomatsakis
Copy link
Contributor

After some discussion, we decided to postpone decisions here until after 1.0. However, we like some of the ideas here, and hence we will raise priority of rust-lang/rust#14581, which makes multiple variable bindings an error.

@alexcrichton
Copy link
Member

Closing as explained in the previous comment.

@mdinger
Copy link
Contributor

mdinger commented May 28, 2015

Another use case for extending the pattern matching which is slightly similar to #673:

use E::*;

enum E {
    A(i32, i32),
    B(i32, i32),
}

fn main() {
    let a = A(6, 9);
    let b = B(3, 8);

    // Destructure numbers out of structures regardless of which type they are.
    // Covering all cases becomes a nuisance. Don't try triples or quads...
    match (a, b) {
        (A(x, y), B(z, t)) |
        (B(x, y), A(z, t)) |
        (A(x, y), A(z, t)) |
        (B(x, y), B(z, t)) => println!("x: {}, y: {}, z: {}, t: {}", x, y, z, t),
    }

    // One possible solution. Both `_` are ignored but can be either `A` or `B`.
    match (a, b) {
        (_(x, y), _(z, t)) @_ A | B => {},
    }

    // It uses `@T` to specify a specific variable.
    match a {
        A(x, y) @x 3 => {}, // bind x to 3
    }
}

I'm not thrilled with @T but it does seem clear to me and I don't see any obviously better syntax ideas for this.

@ticki
Copy link
Contributor

ticki commented Jan 10, 2016

This should be reopened.

@taralx
Copy link

taralx commented Jan 22, 2016

👍

@whitequark
Copy link
Member

@alexcrichton Please reopen this.

@White-Oak
Copy link

@whitequark there was a subset of this: #1500 which gor postponed as well, so I guess, not yet.

@whitequark
Copy link
Member

@White-Oak MIR was merged though.

@Nokel81 Nokel81 mentioned this pull request Sep 13, 2017
@sanmai-NL
Copy link

sanmai-NL commented Jan 1, 2018

@nikomatsakis, @alexcrichton: You can quickly conclude from the above comments, that this PR ought to be reopened now. Could you please take this action (right away) or let everyone involved know why, in case you disagree somehow? This topic has led to multiple issue/PR filings (e.g., #929, #2150, #551). Could someone with responsibility step in and reorganize the discussion (e.g. close duplicate issues and refer to this PR or so), to start with?

@aidanhs
Copy link
Member

aidanhs commented Jan 1, 2018

@aturon made a comment in the RFC @White-Oak linked:

In a future incarnation of this RFC, we'd like to see more detailed motivation with real-world use-cases where the feature makes a significant impact.

Which seems to indicate a new RFC that includes this additional detail would be more appropriate than reopening this one (otherwise the lang team would presumably just reach a similar conclusion). I also don't see the need to 'reorganise' the discussion when it's not clear what form extending pattern matching would take (incrementally, with if let && and others as separate RFCs each with their own motivational use-cases, or as one overhaul).

(personally I would love this RFC, but I guess a new one with the bits I mentioned above would be more appropriate)

@sanmai-NL
Copy link

sanmai-NL commented Jan 1, 2018

@aidanhs: If @aturon’s comment in that other thread is conclusive, then I’d expect the persons responsible (him? the people I pinged?) to address the outstanding issue threads, some of which I mentioned (i.e., close them), and to respond to the calls for reopening this PR here with a clear statement. That is what I mean with reorganizing the discussion.

Enhancement of the pattern syntax in if let vs. match seems to get ‘a lot’ of attention from Rust people here on GitHub, so it isn’t so obvious such an enhancement is little desired. I’m not too familiar with RFC procedures but if just the motivation section of an RFC could still be improved, I don’t see why the whole RFC should be started over. Esp. if the motivation is apparent from community response but just not laid out well enough in the RFC.

@Centril
Copy link
Contributor

Centril commented Jan 1, 2018

Parts of this RFC has already been lifted in #2175 . I suspect more of it will be lifted later in other RFCs as well.

@Centril Centril added A-syntax Syntax related proposals & ideas A-patterns Pattern matching related proposals & ideas A-control-flow Proposals relating to control flow. labels Nov 26, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-control-flow Proposals relating to control flow. A-patterns Pattern matching related proposals & ideas A-syntax Syntax related proposals & ideas postponed RFCs that have been postponed and may be revisited at a later time.
Projects
None yet
Development

Successfully merging this pull request may close these issues.