Replies: 24 comments 15 replies
-
Should there be a Also, there could be a little confusion with scope here. switch (SomeMethod(out var o)) {
default: return o; // Fine
catch _: return o; // 'o' does not exist here, despite being inside the braces
} Edit: Actually, does |
Beta Was this translation helpful? Give feedback.
-
Good questions, I've added them to the list. Regarding the scope of declaration/pattern variables, I would think that those variables would be in scope but they would not be definitely assigned. Think of your statement being interpreted as follows: object o, $result;
try {
$result = SomeMethod(out o);
}
catch {
return o; // error CS0165: Use of unassigned local variable 'o'
}
return o; // fine |
Beta Was this translation helpful? Give feedback.
-
In my opinion the language doesn't need to babysit developers so it should be up to the developer much like it is today.
Could be cool to have something like this:
|
Beta Was this translation helpful? Give feedback.
-
I don't think using (var exp = SomeExpression())
{
switch (exp) {
case Result result: ...
catch Exception _: ...
}
} For expression form, you'd use the result anyway, so it has to be disposed later: using (var result = SomeExpression() match (
case Result result: ...
catch Exception _: ...
))
{
UseIt(result);
} |
Beta Was this translation helpful? Give feedback.
-
@eyalsk that's like proposing to remove safety labels off everything to ensure only smart people survive past puberty, C# has always been about "the pit of success", where the most obvious solution should be the best one. Swallowing exceptions should have always been harder or at least uglier than handling them properly. |
Beta Was this translation helpful? Give feedback.
-
I dispute your claim that "C# has always been about "the pit of success"". Being wise after the event and all that, but many C# features are the opposite. And, as the team have shown with recent new features, consistency with existing language paradigms wins out over "pit of success" even today. As such, assuming a feature similar to this one were adopted, it is likely that the syntax would favour consistency with existing catches (which makes it easier to swallow all exceptions than to handle them properly) over making exception swallowing hard. |
Beta Was this translation helpful? Give feedback.
-
The I do agree with the notion that the language should try to guide developers towards "doing the right thing" by making that "right thing" easier. Patterns which are considered abusive shouldn't be encouraged by introducing shorthand, especially if that makes it easier than following the best practices. However, those patterns/practices are always evolving and often line up with philosophical/paradigmic arguments regarding language design. Hence @DavidArno always complaining that C# isn't a pure immutable functional language. (Sorry, had to snipe back. 😉) That said, the open question here is whether or not this feature might promote abuse by those who are less likely to understand the ramifications of that abuse, and whether or not that matters. |
Beta Was this translation helpful? Give feedback.
-
The main weirdness here is that there is no That's not a huge problem. But before I read the full proposal, I wasn't sure what is in scope for exception handling. Is it:
Looks like 1 is the answer if I read the proposal correctly. But then
seems inconsistent, having a different scope than the |
Beta Was this translation helpful? Give feedback.
-
I had intended that the scope of the exception handling would only be on the As for the inclusion of a |
Beta Was this translation helpful? Give feedback.
-
Well, I don't know about always I mean it's really easy to swallow exceptions hence what you said but I really think that the "the pit of success" is more of an slogan than a reason against it.
Yes, maybe it should have been. |
Beta Was this translation helpful? Give feedback.
-
It's like saying I don't think that catching exceptions in a switch statement or match expression is necessary; try/catch is about catching exceptions whereas switch/match is about branching and the typical C# way to do either of them is not to have this feature at all but here we are. |
Beta Was this translation helpful? Give feedback.
-
Well, I'm trying to understand why a feature which is mostly syntactic sugar should prevent developers from swallowing? I mean I'm not against it, I wouldn't mind it either way but if the developer already decided about it why the language needs to stop him when he can just use another syntax and get it done? it seems like we started with C# is safe and now we're past the point where C# puts handcuffs, at least this is how it feels. |
Beta Was this translation helpful? Give feedback.
-
That's largely in comparison to the other |
Beta Was this translation helpful? Give feedback.
-
I don't think that way. Exception handling is clearly a |
Beta Was this translation helpful? Give feedback.
-
@qrli Well, sure but then I can say that finally is a different kind of branching.
Can you elaborate? how is it more (duplicated) code? I mean since when we care how much code goes into the implementation of a feature and why is it even relevant to the discussion? The only real argument against it in my opinion is "It doesn't feel right" which I can understand why it wouldn't. |
Beta Was this translation helpful? Give feedback.
-
@eyalsk As in your example code finally IDisposable d when d != null: d.Dispose(); You just implemented the part of what |
Beta Was this translation helpful? Give feedback.
-
@qrli Still can't get your point and I'm not sure why we discuss implementation details, it's just like taking the proposed example and say that this will get lowered into a try/catch block and a switch statement, great but I really don't think that this helps in the argument against it so can we please discuss actual scenarios, concerns and why people think others will abuse it? |
Beta Was this translation helpful? Give feedback.
-
My two qualms with the concept of a |
Beta Was this translation helpful? Give feedback.
-
@HaloFour Fair enough, these are good points. :) |
Beta Was this translation helpful? Give feedback.
-
I have a few observations-
Most of this glitches can be solved by returning the success value out of the try/match expression and proceed. But then, why would don't we just design the syntax that way- where only catches are handled and normal case is passed on. I think my proposal in #980 tries to do that. Regarding exception handling in general, I think pre-condition failures should not be exceptions and should have separate way of handling. That may be a |
Beta Was this translation helpful? Give feedback.
-
I'm wondering if this proposed construct would actually be widely used to simplify the kinds of code that people have to write today. I'm having a hard time finding many places in my code where I'd use this, and that makes me question its utility as a language addition. Perhaps you could point to places, e.g. in Roslyn, where this would be just what is needed. |
Beta Was this translation helpful? Give feedback.
-
Seemingly enough for @CyrusNajmabadi to originally suggest such a thing and for @jaredpar and @KrzysztofCwalina to have already prototyped out simpler I'm not entirely sold on this either, but I thought it was worth some discussion. The topic of the verbosity and limitations of |
Beta Was this translation helpful? Give feedback.
-
Looks like Java is exploring something like this: https://inside.java/2023/12/15/switch-case-effect/ |
Beta Was this translation helpful? Give feedback.
-
I would enjoy this feature, but I feel that there is definitely a need for visual indication that switch(expr)
{
case int i: ... break;
case string s: ... break;
case float f: ... break;
...
...
...
case catch Exception e: ... break;
} The information whether Luckily this is easy to fix: switch(try expr)
{
case int i: ... break;
case string s: ... break;
case float f: ... break;
case catch Exception e: ... break;
} A This being a normal pattern makes it convenient in other places too: bool IsSomethingInvalid() => try DoSomething() is catch InvalidOperationException; Perhaps in the future, there could be a concrete type or a different variety of result-like or optional-like types that you could use to materialize the result of a Result<string> result = try GetStringOrThrow();
return result.Success ? result.Value : result.Exception.Message; There are actually such types right now, Task<string> GetStringTask()
{
return try GetStringOrThrow();
} Without a There have been other proposals about lightweight exceptions/error codes, so this could really nicely prepare the ground for them too. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Based on the various proposals around expression-based exception handling and a comment made by @CyrusNajmabadi I'd like to toss
catch
patterns into the discussion. I'll only flesh them out a little bit (throwing spaghetti against the wall) and open the floor to further input.I propose the addition of
catch
patterns for pattern matching. These patterns would apply to theswitch
statement and potential futureswitch
/match
expression by using thecatch
keyword either in place of or in addition to thecase
keyword, e.g.:When a
catch
pattern is included in the list of patterns the expression used in theswitch
statement is implicitly wrapped in atry
statement. There can be any number ofcatch
patterns, each followed by a pattern that is matched against the actual exception thrown by the expression.The
catch
patterns are emitted as separatecatch
blocks that catch the appropriate exception in lexical order using exception filters to enforce additional pattern matching. That way any unmatched exceptions remain unhandled and thrown:Open Questions (non-exhaustive, will add more from comments):
try
be crammed in there somewhere?switch (try SomeExpression())
?default
orcase var _
?is
operator? I can't imagine how that would work but it would be asymmetric if it didn't.finally
"pattern" that always gets executed once execution leaves theswitch
block?out
declaration variables or pattern variables from the expression in theswitch
statement?catch
statements, however they would not be definitely assigned.Beta Was this translation helpful? Give feedback.
All reactions