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

Conversation

Projects
None yet
@P1start
Copy link
Contributor

commented Jun 1, 2014

Rendered view

@pczarn

This comment has been minimized.

Copy link

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.

@P1start

This comment has been minimized.

Copy link
Contributor Author

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

This comment has been minimized.

Copy link
Contributor

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

This comment has been minimized.

Copy link
Contributor

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

This comment has been minimized.

Copy link
Contributor

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.

@P1start

This comment has been minimized.

Copy link
Contributor Author

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

This comment has been minimized.

Copy link
Contributor

commented Jun 3, 2014

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

This comment has been minimized.

Copy link
Contributor

commented Jun 5, 2014

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

This comment has been minimized.

Copy link
Member

commented Jun 5, 2014

Closing as explained in the previous comment.

@mdinger

This comment has been minimized.

Copy link
Contributor

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

This comment has been minimized.

Copy link
Contributor

commented Jan 10, 2016

This should be reopened.

@taralx

This comment has been minimized.

Copy link

commented Jan 22, 2016

👍

@whitequark

This comment has been minimized.

Copy link
Member

commented Sep 29, 2016

@alexcrichton Please reopen this.

@White-Oak

This comment has been minimized.

Copy link

commented Sep 29, 2016

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

@whitequark

This comment has been minimized.

Copy link
Member

commented Sep 29, 2016

@White-Oak MIR was merged though.

@Nokel81 Nokel81 referenced this pull request Sep 13, 2017

Closed

Extend Patterns #2150

@sanmai-NL

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link
Member

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link
Member

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.