Thread overview
break switch?
Jun 09, 2013
bearophile
Jun 09, 2013
Jonathan M Davis
Jun 09, 2013
Timon Gehr
Jun 09, 2013
Jonathan M Davis
Jun 10, 2013
bearophile
June 09, 2013
This comes from a small thread in D.announce.

Sometimes you have loops inside switch cases, maybe like this, and you want to exit the current switch case instead of just the loop (or the loops):


void main() {
    import std.stdio;
    enum Foo { foo1, foo2 }
    int[5] data;
    Foo f;

    switch (f) {
        case Foo.foo1:
            foreach (x; data)
                if (x == 10)
                    goto END;
            writeln("10 not found.");
            data[0] = 10; // Put the missing 10.
            END:
            break;

        default:
            break;
    }
}


In some of such situations sometimes I'd like a nicer way to exit the case, maybe with a "break switch":


    switch (f) {
        case Foo.foo1:
            foreach (x; data)
                if (x == 10)
                    break switch;
            writeln("10 not found.");
            data[0] = 10; // Put the missing 10.
            break;



A "break switch" is a bit like the D "break label", that allows to break an outer loop:

loop1:
foreach (x; items1)
  foreach (y; items2)
    if (foo(x, y))
      break loop1;


"break switch" in general is useful to express more clearly the programmer intentions when there are loops inside switch cases.

Do you like? :-)

Bye,
bearophile
June 09, 2013
On Monday, June 10, 2013 01:23:23 bearophile wrote:
> Do you like? :-)

Why not just use labeled breaks on switches too? Then it would be more in line with how it works with loops, _and_ it would give the capability of exiting multiple switch statements at once, which your break switch suggestion does not.

- Jonathan M Davis
June 09, 2013
On 06/10/2013 01:23 AM, bearophile wrote:
> ...
>
> Do you like? :-)
>
> Bye,
> bearophile


Are you aware that the following works?

void main(){
    import std.stdio;
    enum Foo{foo1,foo2}
    int[5] data;
    Foo f;
    Lswitch:switch(f){
    case Foo.foo1:
        foreach (x;data)
            if(x==10)
                break Lswitch;
        writeln("10 not found.");
        data[0] = 10; // Put the missing 10.
        break;

    default:
        break;
    }
}


June 09, 2013
On Monday, June 10, 2013 01:36:25 Timon Gehr wrote:
> On 06/10/2013 01:23 AM, bearophile wrote:
> > ...
> > 
> > Do you like? :-)
> > 
> > Bye,
> > bearophile
> 
> Are you aware that the following works?
> 
> void main(){
>      import std.stdio;
>      enum Foo{foo1,foo2}
>      int[5] data;
>      Foo f;
>      Lswitch:switch(f){
>      case Foo.foo1:
>          foreach (x;data)
>              if(x==10)
>                  break Lswitch;
>          writeln("10 not found.");
>          data[0] = 10; // Put the missing 10.
>          break;
> 
>      default:
>          break;
>      }
> }

Well then, there you go. Problem solved.

- Jonathan M Davis
June 10, 2013
Timon Gehr:

> Are you aware that the following works?
>
> void main(){
>     import std.stdio;
>     enum Foo{foo1,foo2}
>     int[5] data;
>     Foo f;
>     Lswitch:switch(f){
>     case Foo.foo1:
>         foreach (x;data)
>             if(x==10)
>                 break Lswitch;
>         writeln("10 not found.");
>         data[0] = 10; // Put the missing 10.
>         break;
>
>     default:
>         break;
>     }
> }

Of course I wasn't aware of that :-) I have never seen that in docs, or D code. It's an acceptable solution, better than the goto.

Thank you,
bearophile