www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - removing default case requirement?

reply Steven Schveighoffer <schveiguy gmail.com> writes:
Imagine if every `if` statement required you to write an `else` clause, 
even if it was empty. The idea would be, that you have to affirmatively 
attest that you didn't want to have a special case for when it didn't 
match the condition.

How fast do you think that everyone would run screaming for the exits?

But we have such a thing, in the `default:` case requirement.

In my code, it happens quite a bit that I throw an exception in the 
default case, or return something, but there's still a lot of `default: 
break;` code in there.

But consider a few things here:

1. I have `final switch` at my disposal whenever I need it, which allows 
me to avoid `default:` and is really meant for "I want to make sure I 
handle everything"
2. If you forget to return something, or throw an exception, the 
compiler will still let you know (i.e. some code paths don't return a 
value). This counts for the majority of places where I have a `default` 
case that's not just `break;`.
3. I know in my experience (yours may vary) that when I forget to 
include a default, it's usually because I forgot to include `default: 
break;`. So the rule hasn't really helped me avoid bad code.
4. `switch` is already bloated enough with the requirement for `break` 
or `goto` between cases.

If we wanted to relax this requirement it's actually an easy change -- 
no currently-compiling code will break.

Why not? How much does this rule help you, vs. annoy you?

-Steve
Mar 31 2023
next sibling parent ryuukk_ <ryuukk.dev gmail.com> writes:
On Friday, 31 March 2023 at 15:20:41 UTC, Steven Schveighoffer 
wrote:
 Imagine if every `if` statement required you to write an `else` 
 clause, even if it was empty. The idea would be, that you have 
 to affirmatively attest that you didn't want to have a special 
 case for when it didn't match the condition.

 How fast do you think that everyone would run screaming for the 
 exits?

 But we have such a thing, in the `default:` case requirement.

 In my code, it happens quite a bit that I throw an exception in 
 the default case, or return something, but there's still a lot 
 of `default: break;` code in there.

 But consider a few things here:

 1. I have `final switch` at my disposal whenever I need it, 
 which allows me to avoid `default:` and is really meant for "I 
 want to make sure I handle everything"
 2. If you forget to return something, or throw an exception, 
 the compiler will still let you know (i.e. some code paths 
 don't return a value). This counts for the majority of places 
 where I have a `default` case that's not just `break;`.
 3. I know in my experience (yours may vary) that when I forget 
 to include a default, it's usually because I forgot to include 
 `default: break;`. So the rule hasn't really helped me avoid 
 bad code.
 4. `switch` is already bloated enough with the requirement for 
 `break` or `goto` between cases.

 If we wanted to relax this requirement it's actually an easy 
 change -- no currently-compiling code will break.

 Why not? How much does this rule help you, vs. annoy you?

 -Steve
Indeed, there are many rules like this one that just doesn't make sense, and just makes you type more, removing clarity from your own code Also requiring "break" is annoying, all modern languages moved away from this noisy syntax and went the pattern matching and enum as expression route, and it feels much better to use D stuck with C's enums and C's switch model
Mar 31 2023
prev sibling next sibling parent reply "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
I prefer having the current behavior, it gives good guarantees that all 
possible situations are handled, including no-operation.

Inaction is just as much an action, as any other action. Having compiler 
enforced is very reassuring that everything is handled and done so 
intentionally.
Mar 31 2023
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 3/31/23 12:28 PM, Richard (Rikki) Andrew Cattermole wrote:
 I prefer having the current behavior, it gives good guarantees that all 
 possible situations are handled, including no-operation.
 
 Inaction is just as much an action, as any other action. Having compiler 
 enforced is very reassuring that everything is handled and done so 
 intentionally.
Do you feel the same about if statements without `else`? Why is it different? -Steve
Mar 31 2023
next sibling parent "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 01/04/2023 7:30 AM, Steven Schveighoffer wrote:
 On 3/31/23 12:28 PM, Richard (Rikki) Andrew Cattermole wrote:
 I prefer having the current behavior, it gives good guarantees that 
 all possible situations are handled, including no-operation.

 Inaction is just as much an action, as any other action. Having 
 compiler enforced is very reassuring that everything is handled and 
 done so intentionally.
Do you feel the same about if statements without `else`? Why is it different? -Steve
No. Usually if statements is when you want to handle non-linear control flow. They require higher levels of scrutiny to ensure they are correct for the overall function flow to be correct. Think about it in terms of flow chart. A switch statement is just a process step, whereas an if statement would be a conditional.
Mar 31 2023
prev sibling parent reply Sebastiaan Koppe <mail skoppe.eu> writes:
On Friday, 31 March 2023 at 18:30:27 UTC, Steven Schveighoffer 
wrote:
 Do you feel the same about if statements without `else`? Why is 
 it different?

 -Steve
If statements are rather binary, and it is easy to understand the two paths. Switches often have more than 2 cases, and its easier to forget one. Also consider refactoring. With switches I might add or rename or replace one of the values, which doesn't happen with if statements.
Mar 31 2023
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 3/31/23 2:40 PM, Sebastiaan Koppe wrote:
 On Friday, 31 March 2023 at 18:30:27 UTC, Steven Schveighoffer wrote:
 Do you feel the same about if statements without `else`? Why is it 
 different?
If statements are rather binary, and it is easy to understand the two paths. Switches often have more than 2 cases, and its easier to forget one.
Complex if conditions are not "binary". I find it just as easy to forget a clause in an if statement that does the right thing.
 
 Also consider refactoring. With switches I might add or rename or 
 replace one of the values, which doesn't happen with if statements.
If you "forget a case statement", or refactor it, forcing you to write `default: break;` doesn't fix that. -Steve
Mar 31 2023
next sibling parent reply Sebastiaan Koppe <mail skoppe.eu> writes:
On Friday, 31 March 2023 at 21:24:25 UTC, Steven Schveighoffer 
wrote:
 If you "forget a case statement", or refactor it, forcing you 
 to write `default: break;` doesn't fix that.
Whenever I do write then, I do it reluctantly and mostly as a last resort. Having the default be open-endedness means I don't get reminded about that ugly detail anymore. Of the two evils, I prefer the explicit one.
Mar 31 2023
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 3/31/23 6:14 PM, Sebastiaan Koppe wrote:
 On Friday, 31 March 2023 at 21:24:25 UTC, Steven Schveighoffer wrote:
 If you "forget a case statement", or refactor it, forcing you to write 
 `default: break;` doesn't fix that.
Whenever I do write then, I do it reluctantly and mostly as a last resort.
So I do it when it makes sense that I only want to do something for the cases I specify. But that's not my point. If your code is: ```d switch(x) { case 0: doCase0; break; case 1: doCase1; break; } ``` And you forgot case 42, it doesn't say "you forgot case 42". It says "you forgot the default case". So then you add `default: break;` and case 42 is still not there -- because you forgot it. If you refactor, and `default: break;` is already there, it doesn't complain. It reminds me of an old Internet meme (maybe? This might have been before memes) which goes something like: ``` delete myfiles are you sure? yes This will remove 'myfiles', are you really sure about this? you can't get it back. YES GODDAMMIT, just delete it already!!! 'myfiles' has been deleted Ah crap... ```
 
 Having the default be open-endedness means I don't get reminded about 
 that ugly detail anymore.
 
 Of the two evils, I prefer the explicit one.
The open-endededness is not that you forgot a case, it's that you didn't care about that case, or it's not something that requires a case in that particular switch. I really am puzzled by the idea that the compiler requiring one to put `default:` is helping them remember things. To be honest, I'm OK with the requirement. I really am, I can write `default: break;` and I actually do with regularity without forgetting! But it's a hard one to explain to newcomers. It's just one of those things that I explain with "D makes you do this, get over it". I can't really explain that it's helpful with a straight face. -Steve
Mar 31 2023
next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 4/1/23 01:52, Steven Schveighoffer wrote:
 
 The open-endededness is not that you forgot a case, it's that you didn't 
 care about that case, or it's not something that requires a case in that 
 particular switch.
 ...
But which one is it? I'd like to know when I read the code.
 I really am puzzled by the idea that the compiler requiring one to put 
 `default:` is helping them remember things.
 ...
The point of `default: break;` is that it explicitly states "I am doing nothing if it's not one of the other cases". A switch can be pretty long, so it's convenient to be able to search for the default case and be confident you won't end up in an unrelated long switch.
 To be honest, I'm OK with the requirement. I really am, I can write 
 `default: break;` and I actually do with regularity without forgetting! 
 But it's a hard one to explain to newcomers. It's just one of those 
 things that I explain with "D makes you do this, get over it". I can't 
 really explain that it's helpful with a straight face.
There are multiple common ways to deal with the default: - You actually meant to use `final switch`. - Do some explicit action - assert(0); - enforce(0,"TODO: handle case") - Do nothing I seldomly want to do nothing. Why should that be the implicit default?
Mar 31 2023
prev sibling parent reply claptrap <clap trap.com> writes:
On Friday, 31 March 2023 at 23:52:29 UTC, Steven Schveighoffer 
wrote:
 On 3/31/23 6:14 PM, Sebastiaan Koppe wrote:
 On Friday, 31 March 2023 at 21:24:25 UTC, Steven Schveighoffer 
 wrote:
 If you "forget a case statement", or refactor it, forcing you 
 to write `default: break;` doesn't fix that.
Whenever I do write then, I do it reluctantly and mostly as a last resort.
So I do it when it makes sense that I only want to do something for the cases I specify. But that's not my point. If your code is: ```d switch(x) { case 0: doCase0; break; case 1: doCase1; break; } ``` And you forgot case 42, it doesn't say "you forgot case 42". It says "you forgot the default case". So then you add `default: break;` and case 42 is still not there -- because you forgot it. If you refactor, and `default: break;` is already there, it doesn't complain.
How often does anyone use "default: break"? i pretty much exclusively use "default: assert(0)" If i have cases that do nothing I still put them in, default is there to catch stuff ive forgoten.
Apr 01 2023
next sibling parent Salih Dincer <salihdb hotmail.com> writes:
On Saturday, 1 April 2023 at 07:32:28 UTC, claptrap wrote:
 How often does anyone use "default: break"?
If you are a lazy (actually talented) programmer 😀 In fact, if you use enums, the compiler will warn you with the comment in the code. But this way program produces 2 lines of output likes this:
 humid: 2
 I'm in Silifke Asthma Cave
I learned this method from Walter in Dconf'22. Remove the toggle-comment at the beginning of the final to try. ```d enum Weather { hot, humid, cold, sunny, windy, cloudy, drizzling, rainy, foggy } string shallWeGo(Weather w) { //final switch(w) {/* switch(w) { default: return home();//*/ case Weather.hot: w.writeln(": ", 1); return sea(); case Weather.humid: w.writeln(": ", 2); return cave(); case Weather.sunny: w.writeln(": ", 3); return beach(); case Weather.cloudy: w.writeln(": ", 3); return home; } } import std.stdio; void main() { auto choice = Weather.humid; choice.shallWeGo().writeln; } auto sea() => ""; auto home() => ""; auto cave() => "I'm in Silifke Asthma Cave"; auto beach() => ""; /* Without the final keyword you will get a compilation error: onlineapp.d(8): Error: missing cases for `enum` members in `final switch`: onlineapp.d(8): `cold` onlineapp.d(8): `windy` onlineapp.d(8): `drizzling` onlineapp.d(8): `rainy` onlineapp.d(8): `foggy` */ ``` SDB 79
Apr 01 2023
prev sibling parent bauss <jacobbauss gmail.com> writes:
On Saturday, 1 April 2023 at 07:32:28 UTC, claptrap wrote:
 How often does anyone use "default: break"?
I do that all the time. I don't assert the default statement, because in a lot of my projects I don't want to handle all cases always.
Apr 18 2023
prev sibling parent reply Jack Applegame <japplegame gmail.com> writes:
On Friday, 31 March 2023 at 21:24:25 UTC, Steven Schveighoffer 
wrote:
 If you "forget a case statement", or refactor it, forcing you 
 to write `default: break;` doesn't fix that.
`dafault: assert(0);` does.
Apr 02 2023
parent reply Dom Disc <dominikus scherkl.de> writes:
On Sunday, 2 April 2023 at 10:33:28 UTC, Jack Applegame wrote:
 On Friday, 31 March 2023 at 21:24:25 UTC, Steven Schveighoffer 
 wrote:
 If you "forget a case statement", or refactor it, forcing you 
 to write `default: break;` doesn't fix that.
`default: assert(0);` does.
Yup. I like that - much better default. Except for assert(0) not providing any message. So if you run into this, it's still not obvious where to find the bug.
Apr 02 2023
parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 4/2/23 07:07, Dom Disc wrote:
 On Sunday, 2 April 2023 at 10:33:28 UTC, Jack Applegame wrote:
 On Friday, 31 March 2023 at 21:24:25 UTC, Steven Schveighoffer wrote:
 If you "forget a case statement", or refactor it, forcing you to
 write `default: break;` doesn't fix that.
`default: assert(0);` does.
Yup. I like that - much better default. Except for assert(0) not providing any message. So if you run into this, it's still not obvious where to find the bug.
'final switch', which Steve included in his OP, does that. The error message points at the 'switch' line: void main(string[] args) { final switch (args.length) { // Line 1106 case 1: break; } } produces $ ./deneme my-arg core.exception.SwitchError deneme.d(1106): No appropriate switch clause found [...] Although it's good enough, it could include the value that did not match a clause like "... for '2'." However, it's always tricky to print just any value for various reasons: - A string expression may be too long to be useful; so, some trimming may have to be performed, which may trim the distinguishing parts of a string. - Sensitive data may be dumped to the user. Ali
Apr 02 2023
prev sibling next sibling parent bachmeier <no spam.net> writes:
On Friday, 31 March 2023 at 15:20:41 UTC, Steven Schveighoffer 
wrote:

 If we wanted to relax this requirement it's actually an easy 
 change -- no currently-compiling code will break.

 Why not? How much does this rule help you, vs. annoy you?
I would prefer to make the change, but it's not a major point for me, so I wouldn't fight too hard either way. Offsetting some of this is that I find the code more readable this way.
Mar 31 2023
prev sibling next sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 3/31/23 08:20, Steven Schveighoffer wrote:

 But we have such a thing, in the `default:` case requirement.
If we went with that change, I would probably feel the need to write comments like the following: // No default case ... which would defeat the purpose. Am I fooling myself here? Because I don't know why I don't feel the same need for the 'if' statement. Ali
Mar 31 2023
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 3/31/23 1:25 PM, Ali Çehreli wrote:
 On 3/31/23 08:20, Steven Schveighoffer wrote:
 
  > But we have such a thing, in the `default:` case requirement.
 
 If we went with that change, I would probably feel the need to write 
 comments like the following:
 
      // No default case
You can still write `default: break;` if you want.
 
 ... which would defeat the purpose. Am I fooling myself here? Because I 
 don't know why I don't feel the same need for the 'if' statement.
I honestly think it's just habit. And I think that habit has to do somewhat with problems that are mostly solved (from C and C++). -Steve
Mar 31 2023
prev sibling next sibling parent Max Samukha <maxsamukha gmail.com> writes:
On Friday, 31 March 2023 at 15:20:41 UTC, Steven Schveighoffer 
wrote:

 Why not? How much does this rule help you, vs. annoy you?
Annoys.
Mar 31 2023
prev sibling next sibling parent "H. S. Teoh" <hsteoh qfbox.info> writes:
On Fri, Mar 31, 2023 at 11:20:41AM -0400, Steven Schveighoffer via
Digitalmars-d wrote:
[...]
 But we have such a thing, in the `default:` case requirement.
 
 In my code, it happens quite a bit that I throw an exception in the
 default case, or return something, but there's still a lot of
 `default: break;` code in there.
[...]
 How much does this rule help you, vs. annoy you?
[...] It annoys me. It's verbose and ugly. But OTOH, I'm also thankful for it, because it has actually helped me catch bugs in my code on a few occasions -- when I forgot to write the default case. So I dunno, I'm on the fence about this. Maybe if there was a less verbose way to indicate that the missing case was intentional? T -- Written on the window of a clothing store: No shirt, no shoes, no service.
Mar 31 2023
prev sibling next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 3/31/23 17:20, Steven Schveighoffer wrote:
 Imagine if every `if` statement required you to write an `else` clause, 
 even if it was empty. The idea would be, that you have to affirmatively 
 attest that you didn't want to have a special case for when it didn't 
 match the condition.
 
 How fast do you think that everyone would run screaming for the exits?
 
 But we have such a thing, in the `default:` case requirement.
 
 In my code, it happens quite a bit that I throw an exception in the 
 default case, or return something, but there's still a lot of `default: 
 break;` code in there.
 
 But consider a few things here:
 
 1. I have `final switch` at my disposal whenever I need it, which allows 
 me to avoid `default:` and is really meant for "I want to make sure I 
 handle everything"
 2. If you forget to return something, or throw an exception, the 
 compiler will still let you know (i.e. some code paths don't return a 
 value). This counts for the majority of places where I have a `default` 
 case that's not just `break;`.
 3. I know in my experience (yours may vary) that when I forget to 
 include a default, it's usually because I forgot to include `default: 
 break;`. So the rule hasn't really helped me avoid bad code.
 4. `switch` is already bloated enough with the requirement for `break` 
 or `goto` between cases.
 
 If we wanted to relax this requirement it's actually an easy change -- 
 no currently-compiling code will break.
 
 Why not? How much does this rule help you, vs. annoy you?
 
 -Steve
I prefer the current behavior.
Mar 31 2023
parent Dom Disc <dominikus scherkl.de> writes:
On Friday, 31 March 2023 at 21:04:52 UTC, Timon Gehr wrote:
 I prefer the current behavior.
Me too. If you don't like default, use enums and final switch. If you use switch over intergers, very often some values are not covered with cases, so even if you don't expect them to occur, it can happen. Therefore having a default case (that e.g. throws) is useful most of the time.
Mar 31 2023
prev sibling next sibling parent reply Salih Dincer <salihdb hotmail.com> writes:
On Friday, 31 March 2023 at 15:20:41 UTC, Steven Schveighoffer 
wrote:
 Why not? How much does this rule help you, vs. annoy you?
If it wasn't for the final keyword (doesn't exist in many languages!), we could discuss this topic. Am I wrong, using `final` removes `default`. If there is a possibility that the `switch` value may not match any of the specified cases, you should include a `default` case. In this case, you would not use `final switch`, as the optimization relies on the assumption that the switch value will always match one of the specified cases. IMO, we should discuss "should the `break` keyword be removed" SDB 79
Mar 31 2023
parent reply Paul Backus <snarwin gmail.com> writes:
On Saturday, 1 April 2023 at 03:25:15 UTC, Salih Dincer wrote:
 IMO, we should discuss "should the `break` keyword be removed"
I believe the reason D requires you to write `break` rather than making it automatic/implicit is to avoid unexpected behavioral changes when porting C code to D. For example, if you have C code like this: ```c switch (x) { case 1: do_stuff(); /* fallthrough */ case 2: do_other_stuff(); break; } ``` ...and you try to compile it as D code, you will get a compile error, because D requires either `break`, `return`, or `goto case` at the end of each `case` block. If the D compiler inserted an implicit `break;` at the end of the first `case` block automatically, then instead of an error, you would get different behavior at runtime. This would make porting C projects to D more error prone.
Mar 31 2023
parent Salih Dincer <salihdb hotmail.com> writes:
On Saturday, 1 April 2023 at 04:51:18 UTC, Paul Backus wrote:
 If the D compiler inserted an implicit `break;` at the end of 
 the first `case` block automatically, then instead of an error, 
 you would get different behavior at runtime. This would make 
 porting C projects to D more error prone.
Paul touched on a very good sub-topic. Just as the `goto case` protects us (this was added recently)), the `default` and the `final` duo allow us to choose. Therefore, if there is a `final`, there should be no `break` and `goto case`. I think 2 modes are enough: * final and switch * switch and default SDB 79
Mar 31 2023
prev sibling next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
The design is so the user has to intentionally choose what to do with values
not 
in the cases:

1. all cases are accounted for, so "final"

2. other cases are to get default handled, so "default:"

The person reviewing the code is never left in doubt as to the intention of the 
author of the switch.

Yes, it has prevented bugs in my code.
Apr 01 2023
prev sibling next sibling parent Dukc <ajieskola gmail.com> writes:
On Friday, 31 March 2023 at 15:20:41 UTC, Steven Schveighoffer 
wrote:
 If we wanted to relax this requirement it's actually an easy 
 change -- no currently-compiling code will break.

 Why not? How much does this rule help you, vs. annoy you?

 -Steve
On the one hand, it's not nearly always that I wish to break in the default case, often I want to `assert(0)` instead. This idea would encourage not checking for erroneous states, which is worse than usual since this check is free or almost free in runtime. On the other hand, I sure like short code and it'd also be in line with what C and C++ do. On balance, I maybe prefer current behaviour. D in general places greater emphasis on hardening the code against bugs than most languages do. It's not Ada or Rust, but still. If we were talking about a typical quick-and-dirty scripting language, the change could fit it better, but it's not as good for D IMO.
Apr 01 2023
prev sibling next sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 3/31/23 11:20 AM, Steven Schveighoffer wrote:

 Why not? How much does this rule help you, vs. annoy you?
Thanks for all the replies and discussion. I have realized from all of this that there is a major difference between `if` and `switch` which justifies the requirement: `switch` can *only* do single-value comparison. I.e. it has to be the equivalent of `if(a == b)`, whereas `if` can cover any number of cases or patterns based on boolean logic and comparisons. This makes it a lot easier to cover all the cases you need in one go. `switch` on the other hand, can only cover the cases you specify. In something like an `int` or even a `byte`, that means full coverage is unwieldy or near impossible. Even with case range statements, those actually just get expanded to all the intermediate cases. So forgetting go cover cases is much more likely. So I withdraw the suggestion. It also gives me a much better response to "why does D do this?" -Steve
Apr 02 2023
prev sibling next sibling parent Ivan Kazmenko <gassa mail.ru> writes:
On Friday, 31 March 2023 at 15:20:41 UTC, Steven Schveighoffer 
wrote:
 But we have such a thing, in the `default:` case requirement.
 ...
 If we wanted to relax this requirement it's actually an easy 
 change -- no currently-compiling code will break.

 Why not? How much does this rule help you, vs. annoy you?
I rarely use switch at all. Most of the time, it's too verbose to my taste, and has little benefit compared to a chain of if-else-if. On top of that, I pause to ponder what is the Right(TM) indentation style. When I do use switch -- or a chain of if-else-if for that matter -- it often ends with a default case with assert(false) or similar. Or it should -- so, I do have a use for the default being required. That said, given the verboseness of switch, I see a valid reason to question the current state. Ivan Kazmenko.
Apr 02 2023
prev sibling next sibling parent Vladimir Panteleev <thecybershadow.lists gmail.com> writes:
On Friday, 31 March 2023 at 15:20:41 UTC, Steven Schveighoffer 
wrote:
 Imagine if every `if` statement required you to write an `else` 
 clause,
(This doesn't seem like that much of a radical idea, considering that this is the case in functional languages, right?)
 it's usually because I forgot to include `default: break;`.
One small observation, you don't need to add `break;` before `}`. (The compiler doesn't emit warnings on missing `break`, but on fall-through, and reaching `}` isn't a fall-through.) Sometimes I add a comment explaining why the default case does nothing, instead of raising an exception or something like that.
Apr 02 2023
prev sibling parent reply Quirin Schroll <qs.il.paperinik gmail.com> writes:
On Friday, 31 March 2023 at 15:20:41 UTC, Steven Schveighoffer 
wrote:
 Why not? How much does this rule help you, vs. annoy you?
[Little OT] I don’t really care. In my experience, a `switch` is one of the two cases: Every case leads to a `return` or every case leads to a `break`. Occasionally, there are cases ending in use `switch` statements, but `switch` expressions¹, where every code path necessarily must return a value. The best part about for) `break`. I consider `switch` statements like `goto`: It’s there when you need it, but it shouldn’t be your first attempt. As D implemented [DIP 1043 *Shortened Method Syntax*](https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1043.md),² it seems reasonable to also implement `switch` expressions in D much alike ¹ https://learn.microsoft.com/en-US/dotnet/csharp/language-reference/operators/switch-expression ² https://github.com/dlang/DIPs/tree/master/DIPs
Apr 04 2023
parent Salih Dincer <salihdb hotmail.com> writes:
On Tuesday, 4 April 2023 at 12:47:18 UTC, Quirin Schroll wrote:
 I don’t really care. In my experience, a switch is one of the 
 two cases: Every case leads to a return or every case leads to 
 a break. Occasionally, there are cases ending in throw. When I 

 statements, but switch
 expressions¹, where every code path necessarily must return a 

 don’t need (or even allow for) break. I consider switch 
 statements like goto: It’s there when you need it, but it 
 shouldn’t be your first attempt.
Although I like the switch, the use of a look-up table increases the assembly code when operating within a certain range (chain of possibilities). For example, the first code snippet is more efficient: ```d import core.stdc.stdio: printf; void main() { char letter = 63; while(++letter) { //* <- remove slash for toggle-snippet2 on: if(letter > 64 && letter < 91) { printf("capital: %c\n", letter); } else if(letter > 96 && letter < 123) { printf("small: %c\n", letter); }/*/ switch(letter) { case 'A': .. case 'Z': printf("capital: %c\n", letter); break; case 'a': .. case 'z': printf("small: %c\n", letter); break; default: }//*/ } } ``` I also like the second snippet, but it is necessary to use it carefully. Even if you compile with -O2, a rodata segment (.rodata) is generated unnecessarily. https://d.godbolt.org/z/1q5YoPosT Going back to our topic, don't take away the default! Because we need it in this example. SDB 79
Apr 14 2023