Proposal for syntactic sugar for match with some pattern + guards


#1

Hi,

I asked a question on stackoverflow about some special case of matches where I would end up with a code like this:

let value = 111;

match pair {
    _ if value > 1000 => println!("more than thousand"),
    _ if value > 100 => println!("more than hundred"),
    _ if value > 10 => println!("more than then"),
    _ => println!("Not matched"),
}

So actually, the only thing I am trying to do is match against greater than instead of equality. But I think it is quite redundant to write _ if value in every pattern.

So what about a bit of syntactic sugar:

let value = 111;

match pair {
    > 1000 => println!("more than thousand"),
    > 100 => println!("more than hundred"),
    > 10 => println!("more than then"),
    _ => println!("Not matched"),
}

This would be equal to the what I wrote above but removes the extra _ if value ...

Of course this would work only in this special case and with any comparative operator (> < >= >=)

I know it’s not a very important feature, everybody can live without it. But it would be nice and saves some repetition. So what are your opinions? :blush:

Does it make sense? Are there any reasons not to implement this?


#2

[quote=“Azerupi, post:1, topic:1636”]
_ if value > 1000
[/quote]Consider writing it like x if x > 1000 – it doesn’t depend on the context (the value name) and is rather short.


#3

Eventually, we’ll probably allow infinite range patterns:

match value {
    1000.. => println!("more than thousand"),
    100.. => println!("more than hundred"),
    10.. => println!("more than then"),
    _ => println!("Not matched"),
}

edit: I think… (but I’m not a dev)


#4

Can you explain why this works?


#5

Thats nice :slight_smile:
I guess the only difference between the two notations is just a matter of taste. Or is there something more that justifies choosing one over the other?


#6

We already have range patterns so it makes sense to extend them. However, using comparison operators directly will be more flexible unless we start allowing non-constants in range patterns.


#7

Good point.
But you can already do this with the slightly longer notation. _ if x > a So it doesn’t really matter what they choose to implement.

I just wanted to propose a handy shortcut to avoid redundancy in certain case and see what others thought about it :blush:


#8

[quote=“Azerupi, post:4, topic:1636, full:true”]
Can you explain why this works?
[/quote]Patterns let you bind values to names and these names are usable in the match guard.


#9

Ok, but what value do you bind to x in this case ?

match a {
    x if x > 5 => ...,
    _  => ...,
}

Btw, how do you color rust code?


#10

The value of a. This example might make it more obvious:

fn main() {
    match (1, 2) {
        (x, y) if x > 0 => println!("{}, {}", x, y),
        _ => (),
    }
}
```rust

#11

Ow yes, now it’s obvious! I feel so stupid right now :smile:


#12

[quote=“Azerupi, post:1, topic:1636”]```rust
match pair {
> 1000 => println!(“more than thousand”),
> 100 => println!(“more than hundred”),
> 10 => println!(“more than then”),
_ => println!(“Not matched”),
}

This doesn't seem a pattern, since it's not destructing something. You can use guards (as well as you were doing), or you could just use ranges (like the examples above).

[quote="stebalien, post:3, topic:1636"]```rust
match value {
    1000.. => println!("more than thousand"),
    100.. => println!("more than hundred"),
    10.. => println!("more than then"),
    _ => println!("Not matched"),
}
```[/quote]

This indeed seems to be a pattern. But, in most of cases, guards are there, and they do the job as well. :blush:

#13

Of course, I never implied otherwise :wink: I was merely suggesting an alternate syntax (that is not supported at the moment) for some edge cases where you could save some extra keystrokes and in my opinion gain a little in clarity in your code.