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

Extend Patterns #2150

Closed
Nokel81 opened this issue Sep 13, 2017 · 5 comments
Closed

Extend Patterns #2150

Nokel81 opened this issue Sep 13, 2017 · 5 comments
Labels
T-lang Relevant to the language team, which will review and decide on the RFC.

Comments

@Nokel81
Copy link
Contributor

Nokel81 commented Sep 13, 2017

This is the initial issue to reopen a few of the items from #99, not all but the ones that would be the most useful.

  1. The idea of the empty pattern, ! something that will never match anything.
  2. Extend the use of the & operator to be used for pattern set intersections: 1..5 & 3..8 is the range 3..5. If the patterns do not have any intersection then you get the ! pattern.
  3. Specify in the pattern specification that pat | pat -> pat no matter the location. This basically means that the | operator is used with patterns as a pattern set union operator. The requirement is that the patterns must extend over the same type just like in match statements currently.
  4. Add pattern guards (pattern if condition) to patterns properly. Once again, this would make the pattern syntax consistent with that of match arms. It could also be useful within let bindings: let ((a, _) if a > 5) | (_, a) = (e, f); would define a as the value of e if e > 5, and otherwise bind a to the value of f.
@burdges
Copy link

burdges commented Sep 14, 2017

I think the type level ! should improve eventually, but I forget if any RFCs about ! are currently open. We maybe should've figured out the Result<T,!> story during the ergonomics imitative to improve error handling. It might overlap with using associated type constructors (ATCs/HKT) for a Result types though, so maybe ATCs need to develop first or something.

I've no idea if ! as a value is ever useful. You might match on the type level !, say only in if let but never match, as a way to run code depending upon the type parameters.

fn go<T>(foo: Foo<T>)
    match foo {
        ...
    }
    if let ! = T { ... }  // Always do this if Foo variants involving T do not exist
}

It makes no sense to use ! values in match since the variants involving ! do not exist. And maybe there is another type level formulation one should use instead. Also this complicates object safety rules.

I agree | sounds useful for if let of course. I've no strong about pat @ pat vs pat & pat as an extension for @ but one should be careful. I've suggest wait until we formulate clearer opinions about numerically constrained types, which presumably means experience with const generics.

I agree pattern guards sound useful in while let, but imho we should avoid pattern guards, and not encourage their use, until pattern soundness gets fixed rust-lang/rust#31287 I donno if the match ergonomics tweaks will improve guard soundness or make it worse.

@Nokel81
Copy link
Contributor Author

Nokel81 commented Sep 14, 2017

Sorry but I don't quite understand what you are talking about in your first paragraph. However, the reason I proposed ! as the matchless_pattern is because there has to be something that is returned when 1..5 & 3..8 is written.

Your code example doesn't make much sense since it looks like ! is acting like _ which it shouldn't.

I would prefer & since that matches with the use of |. But I disagree that we should avoid pattern guards because of a compiler edge case.

@burdges
Copy link

burdges commented Sep 14, 2017

If you write match x { 1...3 & 5...8 => .. then you'll get a dead code warning/error, not an uninhabited type, well a pattern is not a type anyways. Also, if you lack a _ => too, then you get a non-exhaustive error. Afaik, there is no ! value because that's the point of !.

go::<!> takes a Foo<!> argument. If say Foo<X> is Result<u32,X> then this is a u32 wrapped in an Ok. Try it.

@Nokel81
Copy link
Contributor Author

Nokel81 commented Sep 14, 2017

I see, so you like 3 and maybe 4. I am convinced since patterns are not a variable type so there is not much usefulness for doing intersection

@Centril Centril added the T-lang Relevant to the language team, which will review and decide on the RFC. label Dec 6, 2017
@Centril
Copy link
Contributor

Centril commented Oct 8, 2018

The 3rd point mentioned here has been RFC-accepted (#2535).
For the rest, I'm closing in favor of #263.

@Centril Centril closed this as completed Oct 8, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-lang Relevant to the language team, which will review and decide on the RFC.
Projects
None yet
Development

No branches or pull requests

3 participants