Author Topic: Switch statement  (Read 4981 times)

bas

  • Full Member
  • ***
  • Posts: 205
    • View Profile
Switch statement
« on: March 27, 2014, 09:11:44 AM »
Some new languages like C# changed the default behavior of a case statement so that it breaks by default.
I wonder if this would be an good for C2 as well. It would make writing case statements for concise, but we'd
need a keyword to specify fallthrough (fallthrough, next, ?). I currently lean to the default-break, unless there
are good arguments for default-fallthrough.

DerSaidin

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: Switch statement
« Reply #1 on: April 11, 2014, 04:05:09 PM »
I'd suggest a third option: the user MUST terminate each case with a break or fallthrough (whatever keyword that may use) or return. Then there is no default, it is always explicit.

bas

  • Full Member
  • ***
  • Posts: 205
    • View Profile
Re: Switch statement
« Reply #2 on: April 14, 2014, 09:28:11 AM »
Nice one.
The choice would then be between more compact cases and more explicit code..

I also found another choice: In languages like Ada, there is a default break, but you
can specify more matches in single case. Something like:

switch (x) {
case 1|2: ..
case 3|4 ..
}
« Last Edit: April 14, 2014, 09:37:52 AM by bas »

kyle

  • Newbie
  • *
  • Posts: 48
    • View Profile
Re: Switch statement
« Reply #3 on: June 20, 2014, 11:07:17 PM »
I like having multiple cases combined.  It is a fairly common thing in protocols to see several values that do the same thing (often for support of older versions of a protocol, for instance).

Best,
Kyle

chqrlie

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Switch statement
« Reply #4 on: August 29, 2015, 11:50:08 PM »
Following the principle of least surprise, DerSaidin's proposal makes a lot of sense.

The question is do we really want a new keyword such as fallthrough or fallthru?  As an alternative to a new keyword, we could use the goto keyword with new semantics:

    goto next;      /* fall thru to the code below */
    goto default;   /* to branch to the default case */
    goto case 'a';  /* to branch to the handler for 'a' */

Regarding combining multiple cases, it would be preferable to allow multiple case statements to follow one another without any intervening statement as this is the common idiom for C and it is widely used and poses no real problem.  We could also extend the syntax for the case clause, but with operators that do not clash with current use:  commas could be used to enumerate values, and a range operator could be introduced for to specify inclusive value ranges (.. seems an obvious choice for this).

DerSaidin

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: Switch statement
« Reply #5 on: August 30, 2015, 03:12:25 PM »
switch (x) {
case 1|2: ..
case 3|4 ..
}

I agree with chqrlie that this would be better achieved by multiple case statements.

Code: [Select]
switch (x) {
case 1:
case 2:
  ...
  break;
case 3:
case 4:
  ..
  break;
}

(Note: imo, case 1 wouldn't require any explicit fallthrough because there is no code there to fallthrough from.)

I also agree that for the other option , would be a better separator than |.

lerno

  • Full Member
  • ***
  • Posts: 211
    • View Profile
Re: Switch statement
« Reply #6 on: October 26, 2018, 11:34:34 PM »
Let me go a bit further:

There is no real reason why switch can't have more extended functionality:

1. Allow "case" to be followed by any expression
2. Allow switch to be without value
3. Compile "expression"-case to nested ifs, and regular values to normal switch/case.

E.g.

Code: [Select]
// (1) Compiles to if/else
switch
{
  case (x > 0): do_something(); break;
  case (y < 10): do_something_else(); break;
  case (x + y < 1): foo(); break;
}

// (2) Compiles to if/else
switch (x)
{
  case 0: zero_handle(); break;
  case x > 0: do_something(); break;
  case y < 10: do_something_else(); break;
  case x + y < 1: foo(); break;
}

// (3) This compiles to switch/case
switch (x)
{
   case 0: ...  break;
   case 1: ... break;
   default: ... break;
}

To simplify, type (2) can be eliminated entirely. That also makes it clearer when we have possible jump tables and when not.

Compare case (1) with if/else:
Code: [Select]
switch
{
  case (x > 0):
     do_something();
     break;
  case (y < 10):
     do_something_else();
     break;
  case (x + y < 1):
     foo();
     break;
}

if (x > 0) {
  do_something();
} else if (y < 10) {
  do_something_else();
} else of (x + y < 1) {
  foo();
}

However, the "break" statement makes is a little less useful. In languages where "fallthrough" is required, this can be shortened further:

Code: [Select]
switch
{
  case (x > 0):
     do_something();
  case (y < 10):
     do_something_else();
  case (x + y < 1):
     foo();
}

A "break"-less switch would also allow for automatic scopes with each case. But that idea has to be refined a bit.

Anyway, just posting this as food for thought.

lerno

  • Full Member
  • ***
  • Posts: 211
    • View Profile
Re: Switch statement
« Reply #7 on: October 29, 2018, 01:45:02 AM »
Also, it could be possible to provide both switch-with-fallthrough and switch-with-break by having two different syntax constructs, one with a new name, like "select (foo)" "match (foo)"

acbaile

  • Jr. Member
  • **
  • Posts: 89
    • View Profile
Re: Switch statement
« Reply #8 on: October 29, 2018, 05:46:11 AM »
Some new languages like C# changed the default behavior of a case statement so that it breaks by default.
I wonder if this would be an good for C2 as well. It would make writing case statements for concise

Bas, i agree with you that "break" keyword in each "case" statement is cumbersome. But. (i tried to convey this idea already). It's difficult to explain. I will try again.

When human reads/thinks programming constructions in С language, it influences on his style of thinking and behavior. It programs not computer only, but human brain too.

This switch construction programs following: when you go to some office and ask about some service, servant will offer to you possibilities one by one infinitely - until you will say to him: "break" :) . It is very good, friendly style of behavior.

If you introduce implicit "break" - you will not receive a lot of good things that servant has for you. It's like style "shut up after each sentence" - we see it when servant is our enemy.

It is better TO HAVE this cumbersome in "switch" statement.
« Last Edit: October 29, 2018, 05:49:04 AM by acbaile »

lerno

  • Full Member
  • ***
  • Posts: 211
    • View Profile
Re: Switch statement
« Reply #9 on: October 29, 2018, 08:38:47 AM »
I thought of yet another way to do this:

- Introduce auto break like before create a ”fallthrough, empty case”

Maybe it could look like this:

Code: [Select]
switch (a) {
  case 1 |
  case 2 |
  case 3:
     foo();
  case 4 |
  case 5:
     bar();
     fallthrough;
  case 6:
     baz();
}

lerno

  • Full Member
  • ***
  • Posts: 211
    • View Profile
Re: Switch statement
« Reply #10 on: November 01, 2018, 01:51:14 AM »
If there are first class strings, then switch on strings are is an awesome feature (likely implemented using a hash)

bas

  • Full Member
  • ***
  • Posts: 205
    • View Profile
Re: Switch statement
« Reply #11 on: November 08, 2018, 11:07:13 AM »
I think it's good to have a language as simple as possible. Especially to read. Having (the option) to specify whether
a switch statement is auto-break or auto-fallthrough is nasty when you are only seeing the case part on your screen.
You think it's auto-break, but it might be auto-fallthrough. All code/switch statements should just look alike.

Fallthrough (by forgetting a break) in C has been a common cause for bugs, so I think it should be addressed somehow.
My proposal would be to force either a break or fallthrough statement. But mapping this to generated C code might
not be trivial..

lerno

  • Full Member
  • ***
  • Posts: 211
    • View Profile
Re: Switch statement
« Reply #12 on: November 08, 2018, 05:06:52 PM »
What did you think of

case 1 | case 2: foo(); above?

To clarify:

Code: [Select]
switch (a) {
  case 1 |  // Using : instead of | is syntax sugar for case 1: fallthrough;
  case 2 |
  case 3:
    foo();  // With : we get a break;
  case 4 |
  case 5:
    bar();
    fallthrough; // If we want to execute a statement then pass to next.
  case 6:
    baz();
}

// The above in C:
switch (a) {
  case 1:
  case 2:
  case 3:
    foo();
    break;
  case 4:
  case 5:
    bar();
  case 6:
    baz();
    break;
}

Another possibility is |: or :|

Code: [Select]
switch (foo) {
  case 1|:
  case 2|:
  case 3:
     do_something();

Using | means a that some care must be taken if there is an expression of type:

case 1|2: (This is is compiled to case 3: or course, but I think it's reasonable to require ( ) on any constant expression that isn't a literal.

So case 1+2: would not be allowed, but case (1+2): is ok.

acbaile

  • Jr. Member
  • **
  • Posts: 89
    • View Profile
Re: Switch statement
« Reply #13 on: November 12, 2018, 09:39:51 PM »
fallthrough

    If you plan to use word fallthrough as keyword, i prevent it by claim: "This word has bad sound!" :) Not-friendly. Maybe, i explain it later, when i understood.

    Maybe, keyword continue will be good for this purpose? Or you don't want to mix areas of applying? But you already mixed them with keyword local... Yes, if you want to continue cycle from switch statement, it will be more complicated in this case. Sometimes, i think: "Why there is no possibility in C to continue cycle from nested cycle"... Needs to continue cycle from switch statement in my practice is rare. Cycles - all time, switches - rare, continue cycle from switch - never or quase never.

    I like this idea of simplicity too. With auto-break it will be easier. In practice, you need this break in most of cases, so, writing it each time is cumbersome. And it is so easy to forget it.

    With keyword continue it will have good higher-meaning. If you need to continue interconnecting with servant, you simply say to him: "Please, continue".

    Or you want to introduce another keyword?

    It is better for this purpose to choose word with meaning: "continue, more, another". My english does not allow me to make good selection - because of poor vocabulary. Maybe, you can offer.
« Last Edit: November 18, 2018, 02:49:23 AM by acbaile »

lerno

  • Full Member
  • ***
  • Posts: 211
    • View Profile
Re: Switch statement
« Reply #14 on: November 12, 2018, 10:25:39 PM »
I rather think that fallthrough is bad because it's so long to type :P