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

Proposal: Pattern matching integral types against a range #2044

Closed
YairHalberstadt opened this issue Dec 5, 2018 · 6 comments
Closed

Proposal: Pattern matching integral types against a range #2044

YairHalberstadt opened this issue Dec 5, 2018 · 6 comments

Comments

@YairHalberstadt
Copy link
Contributor

The aim here is to provide an intuitive syntax for matching an integral type on a range of numbers.

To do this I'm abusing the current range syntax.

eg.

public bool CanBuyAlcohol(Person p) =>
    p.Age switch
    {
        case ..-1 => throw new ArgumentException("Can not have negative age");
        case 0..17 => false;
        case 18.. => true;
    }

(I'm from the UK where you can buy alcohol at 18)

Discussion: floating point types

In theory this could work with floating point types as well. However the issue is that it becomes impossible to specify that you want to match a floating point type up to, but not include a number. For example, in the above scenario let's assume Person.Age was a double not an int.

Then the compiler should warn us we haven't dealt with all scenarios - for example, what if the age is 17.5? So we would have to change the example to:

public bool CanBuyAlcohol(Person p) =>
    p.Age switch
    {
        case ..0 => throw new ArgumentException("Can not have negative age");
        case 0..18 => false;
        case 18.. => true;
    }

But then a person whose age is exactly 18 would match 0..18 and return false, even though we want it to match 18.. and return true. We would need some syntax meaning up to but not including a number.

In mathematics we use [0..18] to mean from and including 0 up to and including 18, whereas [0..18) would mean from and including 0 up to but not including 18, and (0..18] would mean from but not including 0 up to and including 18 etc.

However I feel that such syntax would only be confusing in C#, given the existence of arrays and tuples.

perhaps something like this:

public bool CanBuyAlcohol(Person p) =>
    p.Age switch
    {
        case ../0 => throw new ArgumentException("Can not have negative age");
        case 0../18 => false;
        case 18.. => true;
    }

And if we wanted to indicate from but not including 0 up to and including 18 we would do 0/..18.

@yaakov-h
Copy link
Member

yaakov-h commented Dec 5, 2018

However I feel that such syntax would only be confusing in C#, given the existence of arrays and tuples.

Well, Visual Studio extensions and NuGet already use similar syntax. It might be difficult to parse (even for humans), but it's not entirely out of place for the ecosystem.

@ufcpp
Copy link

ufcpp commented Dec 5, 2018

related to #198 (comment), dotnet/roslyn#22997

@HaloFour
Copy link
Contributor

HaloFour commented Dec 5, 2018

I believe that the details of the range syntax, including clusivity, has already been decided as the feature is slated to ship in C# 8.0. I would expect that any range pattern to use that same syntax.

@gafter
Copy link
Member

gafter commented Dec 5, 2018

I would not expect a range pattern to use the same syntax, as range patterns should generally be inclusive, not exclusive. See "Range Pattern" in #1054 and https://github.com/dotnet/csharplang/blob/master/meetings/2018/LDM-2018-04-04.md#range-pattern, where we considered expression to expression to be the most likely syntax.

@gafter
Copy link
Member

gafter commented Dec 5, 2018

See #812 for the championed issue for this.

@gafter
Copy link
Member

gafter commented Dec 5, 2018

Closing as dup of #812

@gafter gafter closed this as completed Dec 5, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants