-
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
Reconcile syntax of "match" expression based on LDM feedback #8818
Comments
@MadsTorgersen Can we meet sometime this week to make some tentative calls for the prototype? |
Not sure if you really want the opinions on non-LDM members here, but I'll offer them anyway (I assume it can be deleted if this is an unhelpful comment):
If
Please, please, please don't use |
Another peanut-gallery opinion, feel free to forward to I think I might prefer I prefer Does it make sense for an incomplete match in an expression to result in anything other than an exception? I'm not sure that it does. As such I think that the compiler should try to enforce that the match is complete and silently emit a wildcard pattern that throws unless one is already defined. |
I think I'd prefer |
The main reason that I resist I think we're likely to change the keyword from |
If it's likely to change the keyword to Just a quick question, ordering problem doesn't apply to switch statement already? I mean the following would be useless, because switch(...) {
default:
case Student(var name):
break;
} Why it cannot be applied to match expressions as well? |
This surely has to apply to a match statement too? If the |
@DavidArno No, we're not going to change the fact that a
I have no idea what this means. What syntax are you imagining? |
// as originally proposed
var result = t match(case P1: e1 case P2: e2); // no comma
var result = t match P : e;
// instead of
var result = t case P : e;
Becomes,
|
So, taking the example from xxx: switch (e) {
case Mult(Const(0), *): return Const(0);
case Mult(*, Const(0)): return Const(0);
case Mult(Const(1), var x): return Simplify(x);
case Mult(var x, Const(1)): return Simplify(x);
case Mult(Const(var l), Const(var r)): return Const(l*r);
case Add(Const(0), var x): return Simplify(x);
case Add(var x, Const(0)): return Simplify(x);
case Add(Const(var l), Const(var r)): return Const(l+r);
case Neg(Const(var k)): return Const(-k);
default: return e;
} I could change that to: switch (e) {
case Mult(Const(0), *): return Const(0);
default: return e;
case Mult(*, Const(0)): return Const(0);
case Mult(Const(1), var x): return Simplify(x);
case Mult(var x, Const(1)): return Simplify(x);
case Mult(Const(var l), Const(var r)): return Const(l*r);
case Add(Const(0), var x): return Simplify(x);
case Add(var x, Const(0)): return Simplify(x);
case Add(Const(var l), Const(var r)): return Const(l+r);
case Neg(Const(var k)): return Const(-k);
} and it will not affect the functionality? Will |
@DavidArno That's the baggage inherited from |
Yes, that's exactly what I'd like to see. The current switch statement is a wholly different thing to a match statement. So don't try and merge the two into some amorphous mess: make them two distinct things. Further I'm sure that any breaking change concerns around using the match keyword will prove easier to solve than trying to make pattern matching work fully with goto and the like. |
@DavidArno Those are already the semantics of the existing |
Would I don't think I care for |
@bondsbw That is precisely the question asked in this issue (fifth question in the list). |
match ( e )
{
|: Mult(Const(0), *),
Mult(*, Const(0)) => Const(0);
|: Mult(Const(1), var x),
Mult(var x, Const(1)) => Simplify(x);
|: Mult(Const(var l), Const(var r)) => Const(l*r);
|: Add(Const(0), var x),
Add(var x, Const(0)) => Simplify(x);
|: Add(Const(var l), Const(var r)) => Const(l+r);
|: Neg(Const(var k)) => Const(-k);
default:
return e;
} 'default: |
@gafter Sorry I realized later that's what you meant by "complete", but I did want to throw my (perhaps unsolicited and humble) opinion in that non-exhaustive/incomplete matching isn't worth locking down a new keyword. |
I vote for 'switch' because it is an already used construct in c#. |
My concerns with using |
@AdamSpeight2008 We will not change the meaning of existing code. This issue is about a new syntactic form for an expression. |
@gafter Say if I have pre-existing code using |
Trailing comma is an embarrassingly bad design decision. Noted. |
The final trailing comma shouldn't be needed. |
You guys know that it's optional right? And I'm not proposing it, it is from spec draft. |
I'm aware it's optional; that's it's problem. When looking at a piece of code with a trailing comma, one must ask: is it there because the author likes to use them, because they forgot to refactor, or because something has been missed and thus it could be a bug. They create a serious hindrance to readability just to pander to developers who want their lives made fractionally easier when writing the code. |
@orthoxerox Do I need a sarcasm sign? 😄 @DavidArno Perhaps you should research why it is useful in the first place and why do we care about it (or not). This is nothing new in C# or programming language design overall. I don't think that I need to explain the basics. Again, I'm not proposing it and my suggestion is based on the current design (of C# not just |
@alrz Mornings are never kind to me 😪 I like both trailing commas and curlies. |
You may rest assured that I have researched it. There are three main use cases:
The first two are only of use to developers who value making their lives easier when writing code over making the lives of readers of their code, easier. The third doesn't really apply to 99.9%of C# developers. Mistakes will always be made in designing languages and decisions taken 10-15 years ago will often be viewed as wrong with the benefit of hindsight. C# is a conservative language and avoids breaking changes. So we are stuck with trailing commas being supported for some existing features. That doesn't mean they should be used though. And "we have always done it like that" is a very silly reason to repeat those mistakes with new features. Ergo, what C# currently does isn't important; doing |
@DavidArno Being internally consistent is even more important. The syntax doesn't affect the behavior of |
Consistency is important, so use |
@DavidArno without comma it will be ambiguous with case expressions. There is a reason for every bit of the syntax. You should try to understand this. |
How would a trailing comma remove ambiguity? |
@DavidArno That works for me. I'm kind of on the fence about the whole brace v. parenthesis bit. I think parenthesis looks fine for a handful of patterns but beyond that I think braces would look nicer. It's like how a method with a huge number of arguments can look awkward. But it's really a minor concern. I'm much more concerned about the behavior and features of the expression than it's specific syntax. I'd be thrilled with guillemets and poop emojis if they delivered active patterns and proper AND/OR patterns. |
@DavidArno Oh you are talking about just the trailing comma. Well, that doesn't seem to be up for discussion here, it is about using commas or not at all. And if they prefer to not use it, perhaps they should redesign case expressions to be distinguishable from case labels. case_expression
- : shift_expression 'case' pattern ':' shift_expression
+ : relational_expression 'match' pattern ':' shift_expression
; |
Braces are used in C# when the contents are typically expected to be provided on multiple lines. Parentheses are used otherwise. And I believe that most code formatters make the assumption that parentheses are intended to span one line (assuming it's not too long). I made a fluent syntax for an area of my project that creates a hierarchical outline: TableOfContents._
(
BeforeYouBegin,
Introduction,
CompilerConcepts._
(
Lexer,
Parser,
Checker,
Emitter
),
CreatingYourOwnLanguage._
(
Design,
Optimization,
Tooling
)
); One annoyance is that Resharper wants to reformat the parentheses every time I edit anything, because in most other cases that's the expectation. I suspect other tooling would be similar. So for match expressions, I feel braces are definitely more consistent than parentheses. |
Didn't you say the comma was optional? Hence no abiquity. -------- Original Message --------
|
The phrase "hijacking the meaning of the return statement" is forever etched into my brain. I will never live it down 😝 If possible I would prefer that there be no delimiting Additionally, I don't think Resharper's, or any tool's, code formatting behavior should impact this proposal. |
Issue moved to dotnet/csharplang #487 via ZenHub |
We need the LDM (C# language design meeting attendees) to decide what the syntax of a "match expression" should be, and then we need to implement that.
Are we using
switch
ormatch
?default:
orcase *:
or both?commas between cases?
Curly braces or parens?
Must a match expression be complete? If not, what happens when it isn't?
What about a single-case (irrefutable) match expression?
The text was updated successfully, but these errors were encountered: