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: Lambda Patterns #8990

Closed
alrz opened this issue Feb 21, 2016 · 6 comments
Closed

Proposal: Lambda Patterns #8990

alrz opened this issue Feb 21, 2016 · 6 comments

Comments

@alrz
Copy link
Contributor

alrz commented Feb 21, 2016

Currently C# has a nice homoiconicity between expressions and delegates (aka expression trees). I want to suggest to bring that to patterns as well via lambdas.

Expression<Func<string, int>> expr = x => x.Length;

switch(expr) {
  case x => x.Length: break;
  case x => x.(string member): break;
}

// roughly translates to
switch(expr) {
  case LambdaExpression { Body is MemberExpression { Member is MemberInfo {
    Name is "Length" } } }: break;
  case LambdaExpression { Body is MemberExpression { Member is MemberInfo {
    Name is string member } } }: break;
}

Expression<Func<string, int>> expr = x => x.IndexOf("foo");

switch(expr) {
  case x => x.IndexOf("foo"): break;
  case x => x.IndexOf(string param): break;
}

// roughly translates to
switch(expr) {
  case LambdaExpression { Body is MethodCallExpression { Method is MethodInfo {
    Name is "IndexOf" }, Arguments is { ConstantExpression { Value is "foo" } } } }:
    break;
  case LambdaExpression { Body is MethodCallExpression { Method is MethodInfo {
    Name is "IndexOf" }, Arguments is { ConstantExpression { Value is string param } } } }:
    break;
}
  • For Arguments I'm using list patterns, proposed in Proposal: List, Indexer (Dictionary) and String Patterns #5811.
  • Type of the parameter x is inferred from the target expr.
  • Pattern compatibility would be defined as matching lambda signatures and the target expression.
  • All the additions in #2060 can be used in lambda patterns.
  • The proposed translations are incomplete because the generated pattern should also check that the member comes form the first parameter i.e. Expression property must be a ParameterExpression.
  • Parameter names are insignificant and they just matched by type and position.
@orthoxerox
Copy link
Contributor

What would lamba patters be used for?

@alrz
Copy link
Contributor Author

alrz commented Feb 21, 2016

@orthoxerox Instead of any expression tree inspection that you currently need to write by hand or perhaps more verbosely with property patterns, as the final translation suggests.

@pawchen
Copy link
Contributor

pawchen commented Feb 23, 2016

I like the idea, inspecting expression trees in API codes can be painful in both writing and reading. Maybe the title should be expression trees instead of lambda?

@alrz
Copy link
Contributor Author

alrz commented Feb 23, 2016

@DiryBoy Had the same thought. I don't mind the title but it seems a lambda that is a pattern, right? Because expression tree pattern could be confusing as the hypothetical translation suggests, you still can match expression tree types via property patterns.

@pawchen
Copy link
Contributor

pawchen commented Feb 23, 2016

Right, so please forget about the title change:)

@svick
Copy link
Contributor

svick commented Feb 24, 2016

What I don't like about this is that it introduces quite a heavy new syntax, but that syntax is useful only in pretty niche situations.

I think that pattern matching expression trees could work pretty well using some well-written is operators. Using the examples from above:

switch (expr.Body) {
  case Member(*, "Length"): break;
  case Member(*, string member): break;
}

switch (expr.Body) {
  case MethodCall(*, "IndexOf", { Constant("foo") }): break;
  case MethodCall(*, "IndexOf", { Constant(string param) }): break;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants