I certainly see where you’re coming from, but I think the designers of C# have done fairly good job evolving the language to balance backwards compatibility, simplicity (in terms of having “only one way” to do things), and the ergonomics expected of modern languages. I think C++ and JS are great comparisons because C++ has at this point added everything and the kitchen sink to it’s language and standard library, whereas C# has gone much more like JS introducing features that evolve the best practices for writing but still feel and read like essentially the same language. For example, primary constructors still look just like regular C#, it’s just a nicer way to define simple POCOs when desired.
As far as important language features, I think it’s easy to pick on discriminated unions because it seems like C#’s users unanimously want that. However, if you read through proposals and discussions, it’s obvious that there’s a lot of nuance and trade offs in deciding how and what form of discriminated unions should exist in C# (and the designers are very active in working through that nuance and trade off - they said they have a working group that meets weekly to discuss it I believe*). And to be fair, they have introduced a LOT of other important features (like records and the vastly improved pattern matching) in just the last few years. Without those features, discriminated unions wouldn’t be nearly as appealing, and those features are great for the language even without DUs.
*Edit: Source for my claim is the recent Languages & Runtime Community Standup on the official dotnet YouTube channel. Mads talks about the working group at 21:05, but the discussion of discriminated unions begins at 7:09.
the ergonomics expected of modern languages.
As someone learning c# right now, can we get some of those "modern ergonomics" for switch statements 💀
I cant believe it works the way it does. "Fallthrough logic is a dumb footgun, so those have to be explicit rather than the default. But C programmers might get confused somehow, so break has to be explicit too"
I miss fallthrough logic in languages that dont have it, and the "goto case" feature is really sick but like... Cmon, there's clearly a correct way here and it isnt "there is no default behavior"
I’m not sure I understand your point about fall through having to be explicit, but I agree that switch statements are lacking ergonomics - which makes some sense considering they were added a looooong time ago. Luckily, they added recently the switch expression, which uses pattern matching and behaves more like Rust’s Match expression. It’s still lacking proper exhuastiveness checks for now, but that’s a problem with the core design of composition in C#’s type model and one they are looking to solve (alongside Discriminate Unions in all likelihood).
I’m not sure I understand your point about fall through having to be explicit
As far as i understand it, every switch statement requires a break otherwise it's a compiler error - which makes sense from the "fallthrough is a footgun" C perspective. But fallthrough isnt the implicit behavior in C# like it is in C - the absence of a break wouldnt fall through, even if it wasnt a compiler error. Fallthrough only happens when you explicitly use goto.
But break is what you want 99% of the time, and fallthrough is explicit. So why does break also need to be explicit? Why isnt it just the default behavior when there's nothing at the end of the case?
It's like saying "my hammer that's on fire isnt safe, so you're required to wear oven mitts when hammering" instead of just... producing a hammer that's not on fire.
From what i saw on the internet, the justification (from MS) was literally "c programmers will be confused if they dont have to put breaks at the end".
Ah ok I think I get you now. To be clear, fall through is implicit - when the case being fallen through is empty. I forgot that, if you want to execute some statements in one case, and then go to another case, you need gotos. To be fair, I’ve never needed that behavior before.
I absolutely see your point on break not being the default. It is sad, although I will say I don’t mind a little extra explicitness in code I’m sharing with a large team.
I certainly see where you’re coming from, but I think the designers of C# have done fairly good job evolving the language to balance backwards compatibility, simplicity (in terms of having “only one way” to do things), and the ergonomics expected of modern languages. I think C++ and JS are great comparisons because C++ has at this point added everything and the kitchen sink to it’s language and standard library, whereas C# has gone much more like JS introducing features that evolve the best practices for writing but still feel and read like essentially the same language. For example, primary constructors still look just like regular C#, it’s just a nicer way to define simple POCOs when desired.
As far as important language features, I think it’s easy to pick on discriminated unions because it seems like C#’s users unanimously want that. However, if you read through proposals and discussions, it’s obvious that there’s a lot of nuance and trade offs in deciding how and what form of discriminated unions should exist in C# (and the designers are very active in working through that nuance and trade off - they said they have a working group that meets weekly to discuss it I believe*). And to be fair, they have introduced a LOT of other important features (like records and the vastly improved pattern matching) in just the last few years. Without those features, discriminated unions wouldn’t be nearly as appealing, and those features are great for the language even without DUs.
*Edit: Source for my claim is the recent Languages & Runtime Community Standup on the official dotnet YouTube channel. Mads talks about the working group at 21:05, but the discussion of discriminated unions begins at 7:09.
As someone learning c# right now, can we get some of those "modern ergonomics" for switch statements 💀
I cant believe it works the way it does. "Fallthrough logic is a dumb footgun, so those have to be explicit rather than the default. But C programmers might get confused somehow, so break has to be explicit too"
I miss fallthrough logic in languages that dont have it, and the "goto case" feature is really sick but like... Cmon, there's clearly a correct way here and it isnt "there is no default behavior"
I’m not sure I understand your point about fall through having to be explicit, but I agree that switch statements are lacking ergonomics - which makes some sense considering they were added a looooong time ago. Luckily, they added recently the switch expression, which uses pattern matching and behaves more like Rust’s Match expression. It’s still lacking proper exhuastiveness checks for now, but that’s a problem with the core design of composition in C#’s type model and one they are looking to solve (alongside Discriminate Unions in all likelihood).
As far as i understand it, every switch statement requires a
break
otherwise it's a compiler error - which makes sense from the "fallthrough is a footgun" C perspective. But fallthrough isnt the implicit behavior in C# like it is in C - the absence of abreak
wouldnt fall through, even if it wasnt a compiler error. Fallthrough only happens when you explicitly usegoto
.But
break
is what you want 99% of the time, and fallthrough is explicit. So why doesbreak
also need to be explicit? Why isnt it just the default behavior when there's nothing at the end of the case?It's like saying "my hammer that's on fire isnt safe, so you're required to wear oven mitts when hammering" instead of just... producing a hammer that's not on fire.
From what i saw on the internet, the justification (from MS) was literally "c programmers will be confused if they dont have to put breaks at the end".
Ah ok I think I get you now. To be clear, fall through is implicit - when the case being fallen through is empty. I forgot that, if you want to execute some statements in one case, and then go to another case, you need gotos. To be fair, I’ve never needed that behavior before.
I absolutely see your point on break not being the default. It is sad, although I will say I don’t mind a little extra explicitness in code I’m sharing with a large team.