-
Notifications
You must be signed in to change notification settings - Fork 4k
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
2015-03-25 Design Discussion - Patterns and Records #1572
Comments
@MadsTorgersen You may want to link to this from today's design notes. |
So it is a class in this instance and a struct if you use |
@bbarry Yes. You can use this syntax with either the |
Great to see I still like the |
Also have a look at Nemerle for a C# like syntax for pattern matching. |
Has there been any consideration to what it means to overload the meaning of the Right now, a |
@zastrowm Yes, we've thought about it pretty deeply. Since it is an error for there to be overlaps between cases in existing There is only one catch. You can place a |
+1
+1
+1 See how it looks on Nemerle: using System.Console;
class A { public Field1 : int = 40; public Prop1 : int { get { Field1 + 2 } } }
class B { public Field : string = "OK"; public Prop1 : A { get; set; }}
module Program
{
Test(obj : object) : void
{
match (obj)
{
| A(Prop1 = 42) => WriteLine("A with Prop1 == 42");
| A() => WriteLine("A");
| B(Prop1 = null, Field = "OK") => WriteLine("B with Prop1 == null && Field == 'OK'");
| B(Prop1 = A(Field1 = 40)) => WriteLine("B with Prop1 == A(Field1 == 40)");
| B() => WriteLine("B");
| _ => WriteLine("other");
}
}
Main() : void
{
Test(A());
Test(B());
def b = B();
b.Prop1 = A();
Test(b);
_ = ReadLine();
}
}
+1
+1
It is better to implement support of IEnumerable and IList.
+1 And add support of tuple in syntax. |
Use pattern matching (PM) in switch is bad idea. PM depends on a order. match (obj)
{
is A(Prop1 is 42) => WriteLine("A with Prop1 == 42");
is A() => WriteLine("A");
is B(Prop1 is null, Field is "OK") => WriteLine("B with Prop1 == null && Field == 'OK'");
is B(Prop1 is A(Field1 is 40)) => WriteLine("B with Prop1 == A(Field1 == 40)");
is B() => WriteLine("B");
is * => WriteLine("other");
} |
A syntax suggestion: var result = match(x, y)
{
case(x == 42) => "42";
case(x == 101) { return "101"; }
case(x is Point p; p.X > 100) => "Point!";
case(x is Point p; y is long) => $"{p} and {y}";
default => string.Empty;
} |
Nice to see that you're thinking about
and for variable create this way
this code
could be written like I'm not sure if it's worth it. I just had to write similar code yesterday (make copy of class with mutable properties but with small changes) and thought about your proposed |
I think extension of the existing There is actually an example of using try-catch blocks for pattern matching (definitely NOT a good idea, but it shows to outline the fact that catch blocks really are pattern matching). Here are some ideas about different kinds of patterns and pattern matching syntax. Literal PatternA literal pattern matches a literal value known at compile time, for which the language can guarantee absolute equality. Here are some examples:
Literal patterns may take advantage of some default conversions. You can match an A literal pattern is basically equivalent to a Literal patterns can always be identified by their starting character. They cannot begin with parentheses. Variable BindingThis pattern binds a value to a name. The variable type can be Implicit conversions don't participate in variable binding patterns. The runtime type of the variable must conform to the declared type. Here are some examples:
Note that the parentheses are required. They also distinguish this pattern from active patterns and other things. It could also be viewed as a singleton tuple. Active PatternActive patterns could be objects implementing one of the interfaces:
In practice though, requiring to fully parameterize active patterns in this way is way too much typing, so I think it would be better to have a set of marker interfaces They're recommended to be struct (there is no need to box the pattern into the interface), and need to have an accessible constructor. It's important that these objects be usable in languages not supporting pattern matching, or that support different pattern matching (e.g. F#). To match against an active pattern, you write
First constructs an instance of Here is a full
Where
Active patterns don't begin with parentheses to distinguish them from simple binding patterns. Tuple PatternTuple patterns provide for a great way to match on multiple things at once. It matches both a
Pattern GuardsGuards can appear in the same way as guards for
Combining PatternsPatterns could be combined in several ways. One way is to allow patterns to be stacked, like case clauses in switch blocks can be stacked. In this case, all patterns must bind the same names to the same types of values. This is an
Another way is to use a conjunction or
|
While I appreciate the C# design team's work to avoid creating additional new keywords and constructs wherever possible, I do feel that overloading the I personally much prefer the F#/Nemerle discriminated-union-like syntax suggested by @VladD2 above. I feel it's not only more syntactically terse, it's more visually distinctive, making it easy to spot such constructs in a body of code. I also very much enjoy the F# behavior when new types are derived from the type being matched that all DI |
Design notes have been archived at https://github.com/dotnet/roslyn/blob/future/docs/designNotes/2015-03-25%20C%23%20Design%20Meeting.md but discussion can continue here. |
Discussion for pattern-matching has moved to #10153 |
These are notes that were part of a presentation on 2015-03-25 of a snapshot of our design discussions for C# 7 and VB 15. The features under discussion are described in detail in #206 and elsewhere.
Records
Changes since Semih Okur's work:
record
modifierwith
expressions (Proposal: "with" expressions for record types #5172)Working proposal resembles Scala case classes with active patterns.
readonly
propertiesUse Cases
With expressions
Illustrates an example of the value of having parameter-property association.
Given
the expression
is translated to
Open issues
Pattern Matching
Sources of Inspiration
A pattern-matching operation
Other aspects
We think we want an expression form too (no proposed syntax yet, but for inspiration):
Benefits
Use Cases
Open questions
The text was updated successfully, but these errors were encountered: