Silly idea: range constructors

Just a silly[1] idea that came up my head:

What if we changed the range operators (.. and friends) into proper constructors[2] so they can be used in patterns like this:

fn fun(some_range: Range<i32>) -> &'static str {
    match some_range {
        1.._ => "starts in 1",
        _..10 => "ends in 10",
        (..43)..(43..) => "contains the answer",  // yeah, the +1 here is kinda ugly ...
        (..7)..(4..) => "overlaps with 4..7",
        // the following one may be ambiguous, but ranges are not literals and they are not comparable, so it should be fine
        (11..13)..(15..17) => "a funny one",
        _ => "something weird",
    }
}

What do you think?


  1. is there any 'fun' category here? ↩︎

  2. like struct and variant names ↩︎

I guess it could be done by requiring parentheses to distinguish between existing integer range patterns and range destructuring patterns, but it would likely still be too confusing for humans to read to be seriously considered. I've had situations though where I've wanted to write let a..b = some_range rather than the much more cumbersome let Range { start: a, end: b } = some_range. It definitely feels like it should work, given that all the other type constructor operators have their dual destructuring patterns.

TBH, everywhere other than indexing I'd be happy with just normal functions to make a range.

x = range(a + b, k - j); is fine, and helps avoid the precedence uncertainty in a + b..k - j.

What is the actual problem this is solving? As in, what is an actual use case for this?