Jump to page: 1 2
Thread overview
Suggestion: new switch statement
Aug 21, 2006
Kristian
Aug 21, 2006
Jeff
Aug 21, 2006
Kristian
Aug 21, 2006
mike
Aug 25, 2006
Stewart Gordon
Aug 21, 2006
nobody
Aug 24, 2006
Stewart Gordon
Aug 24, 2006
Kristian
Aug 21, 2006
BCS
Aug 22, 2006
Chad J
Aug 22, 2006
Rioshin an'Harthen
Aug 22, 2006
Kristian
Aug 22, 2006
mike
Aug 23, 2006
Kristian
Aug 23, 2006
mike
August 21, 2006
It would be nice if there was a new statement that acts like 'switch' except that 'break' will be automatically added at the end of the case statements. (We don't want to change the behavior of 'switch' because it'll break old code and confuse people familiar with C/C++.)

Let call this new statement 'jump' (or something), for example:

void func(int val) {
    jump(val) {
        case 1:
            doX();
        case 2, 3:
            doY();
        default:
            doZ();
    }
}

Using 'switch', 'func()' would look, of course, as follows:

void func(int val) {
    switch(val) {
        case 1:
            doX();
            break;
        case 2, 3:
            doY();
            break;
        default:
            doZ();
            break;
    }
}

You could use a 'unbreak' (or something) to allow execution to fall through to the next case statement.

In addition, falling through should be allowed in the following case:

    case 1:
    case 2:

which is a longer way to write "case 1, 2:", of course.


I think breaking after a case is (a lot) more common than falling through. So this will reduce bugs (a programmer can easily forget to put the break statement at the end of a case). Also, it'll make code shorter and easier to read.
August 21, 2006
How about allowing:

switch (val) {
    case (1) {
	doX();
    } case (2, 3) {
        doY();
    } default {
        doZ();
    }
)

Or would this create some horrible syntactic ambiguities? Or, on the other hand, it could just be too damn ugly. ;)
August 21, 2006
On Mon, 21 Aug 2006 13:06:49 +0300, Jeff <psychobrat@gmail.com> wrote:

> How about allowing:
>
> switch (val) {
>      case (1) {
> 	doX();
>      } case (2, 3) {
>          doY();
>      } default {
>          doZ();
>      }
> )
>
> Or would this create some horrible syntactic ambiguities? Or, on the other hand, it could just be too damn ugly. ;)

Actually I also thought about that very syntax. :) However, I guess that there are people out there that are not so fond of having more curly brackets... In a way it'd fit the structure of the language, though.

But, as you mentioned, it could confuse people and generate more bugs. Also note that this is ok in D:

void func(int val) {
    switch(val) {
        case 1:
            doX();
            break;

        case 2:
            {
            int b = 2;  //a local variable inside a block
            doY(b);
            }
            break;
    }
}

So, I think it would be better just use different statement. (And for a compiler, it'd be simple to implement.)


Heheh, I just tested the switch statement, and guess what? I forgot to put the break statements at the end of cases...!!
August 21, 2006
Hi!

If I may comment on that - I think that fits perfectly into the syntax. Think of that:

' class foo
' {
'     // you can write public in 3 different ways
'     public int x;
'     public
'     {
'         int y;
'     }
'     public:
'         int z;
' }

Why not something similar with switch?

' switch (i)
' {
'     // you could write case in 3 different ways too
'     case 1 writefln("case 1");
'     case 2
'     {
'         writefln("case 2");
'     }
'     case 3:
'         writefln("case 3");
'         break;
' }

That would be really nice of one has lots of 1-line switch cases. I'd like that very much.

-Mike

Am 21.08.2006, 13:05 Uhr, schrieb Kristian <kjkilpi@gmail.com>:

> On Mon, 21 Aug 2006 13:06:49 +0300, Jeff <psychobrat@gmail.com> wrote:
>
>> How about allowing:
>>
>> switch (val) {
>>      case (1) {
>> 	doX();
>>      } case (2, 3) {
>>          doY();
>>      } default {
>>          doZ();
>>      }
>> )
>>
>> Or would this create some horrible syntactic ambiguities? Or, on the other hand, it could just be too damn ugly. ;)
>
> Actually I also thought about that very syntax. :) However, I guess that there are people out there that are not so fond of having more curly brackets... In a way it'd fit the structure of the language, though.
>
> But, as you mentioned, it could confuse people and generate more bugs. Also note that this is ok in D:
>
> void func(int val) {
>      switch(val) {
>          case 1:
>              doX();
>              break;
>
>          case 2:
>              {
>              int b = 2;  //a local variable inside a block
>              doY(b);
>              }
>              break;
>      }
> }
>
> So, I think it would be better just use different statement. (And for a compiler, it'd be simple to implement.)
>
>
> Heheh, I just tested the switch statement, and guess what? I forgot to put the break statements at the end of cases...!!



-- 
Erstellt mit Operas revolutionärem E-Mail-Modul: http://www.opera.com/mail/
August 21, 2006
Jeff wrote:
> How about allowing:
> 
> switch (val) {
>     case (1) {
>     doX();
>     } case (2, 3) {
>         doY();
>     } default {
>         doZ();
>     }
> )
> 
> Or would this create some horrible syntactic ambiguities? Or, on the other hand, it could just be too damn ugly. ;)

The answer is that you can do interesting things in switch statements. Probably the most famous example is Duff's Device which you can see an example of in the Mixin section of the D docs:

http://www.digitalmars.com/d/mixin.html



template duffs_device(alias id1, alias id2, alias s)
{
    void duff_loop()
    {
	if (id1 < id2)
	{
	    typeof(id1) n = (id2 - id1 + 7) / 8;
	    switch ((id2 - id1) % 8)
	    {
		case 0:        do {  s();
		case 7:              s();
		case 6:              s();
		case 5:              s();
		case 4:              s();
		case 3:              s();
		case 2:              s();
		case 1:              s();
				  } while (--n > 0);
	    }
	}
    }
}
August 21, 2006
On Mon, 21 Aug 2006 12:00:47 +0300, Kristian wrote:

> It would be nice if there was a new statement that acts like 'switch' except that 'break' will be automatically added at the end of the case statements. (We don't want to change the behavior of 'switch' because it'll break old code and confuse people familiar with C/C++.)
> 
> Let call this new statement 'jump' (or something), for example:
> 
> void func(int val) {
>      jump(val) {
>          case 1:
>              doX();
>          case 2, 3:
>              doY();
>          default:
>              doZ();
>      }
> }

I think the non-curly bracket version is nicer, as it shows how closely it is linked to the switch statement, and you don't have to put all those useless symbols in. I find it very annoying to type curly brackets with if/else/elseif statements, and I think many azerty-users do. We have to press altgr-9 to get one, which is a long way for fingers to stretch.

Curly brackets or not, I think this jump thing would make a great addition to the language, and I completely agree with you on the break thing: falling through is something that I rarely use, and I've forgotten more than enough break; statements for one lifetime.


-Wim
August 21, 2006
Kristian wrote:
> It would be nice if there was a new statement that acts like 'switch'  except that 'break' will be automatically added at the end of the case  statements. 
[...]
> 
> You could use a 'unbreak' (or something) to allow execution to fall  through to the next case statement.
> 

no need for a unbreak, use:

goto case;

http://www.digitalmars.com/d/statement.html#goto
August 22, 2006
Kristian wrote:
> It would be nice if there was a new statement that acts like 'switch'  except that 'break' will be automatically added at the end of the case  statements. (We don't want to change the behavior of 'switch' because  it'll break old code and confuse people familiar with C/C++.)
> 
> Let call this new statement 'jump' (or something), for example:
> 
> void func(int val) {
>     jump(val) {
>         case 1:
>             doX();
>         case 2, 3:
>             doY();
>         default:
>             doZ();
>     }
> }
> 
> Using 'switch', 'func()' would look, of course, as follows:
> 
> void func(int val) {
>     switch(val) {
>         case 1:
>             doX();
>             break;
>         case 2, 3:
>             doY();
>             break;
>         default:
>             doZ();
>             break;
>     }
> }
> 
> You could use a 'unbreak' (or something) to allow execution to fall  through to the next case statement.
> 
> In addition, falling through should be allowed in the following case:
> 
>     case 1:
>     case 2:
> 
> which is a longer way to write "case 1, 2:", of course.
> 
> 
> I think breaking after a case is (a lot) more common than falling through.  So this will reduce bugs (a programmer can easily forget to put the break  statement at the end of a case). Also, it'll make code shorter and easier  to read.

Creating a new type of switch statement just to change some default
behavior seems a bit excessive.

At the same time, I can't stand the fall-through default behavior!  It
is a source of bugs, and I've already been hit by it a few times in D
and spent hours trying to find the bug in a switch statement that
behaves subtly different than what I expected.

I've read that this is maintained in D to keep it easy to port C code
over to D.  That's understandable, especially if you want to make break
the default, which would change the meaning of code without any warning.

I'd suggest though, that you don't allow a default ending for case
blocks at all.  Mandate that each case block be followed by an escape
like 'break', 'return', 'goto', 'throw', etc.  That way, the compiler
would throw an error when C code that uses fallthroughs is inadvertently
used as D code.  Also, this is one of those things from C/C++ that is
bad.  D is supposed to get rid of those bad things even if it means
losing backwards compatibility, so please get rid of this bad thing that
comes from C.

I also like Mike's suggestion on this thread a lot.  It could even be combined with my suggestion.  I'd say use Mike's suggestion, and only apply my suggestion to the colon blocks.  Since the brackets and one-liners are not valid C syntax AFAIK, the compiler won't need to mandate anything about them to flush out bugs from incoming C code.  On the developer side, this trades nasty runtime bugs for some small amount of hunting down compiler errors and fixing them.  A good trade IMO.  Not sure what the cost would be to compiler writers like Walter, but please at least implement the mandatory ending on the current case blocks, or something just as good.
August 22, 2006
"Chad J" <gamerChad@_spamIsBad_gmail.com> wrote:
> At the same time, I can't stand the fall-through default behavior!  It is a source of bugs, and I've already been hit by it a few times in D and spent hours trying to find the bug in a switch statement that behaves subtly different than what I expected.
>
> I've read that this is maintained in D to keep it easy to port C code over to D.  That's understandable, especially if you want to make break the default, which would change the meaning of code without any warning.
>
> I'd suggest though, that you don't allow a default ending for case blocks at all.  Mandate that each case block be followed by an escape like 'break', 'return', 'goto', 'throw', etc.  That way, the compiler would throw an error when C code that uses fallthroughs is inadvertently used as D code.  Also, this is one of those things from C/C++ that is bad.  D is supposed to get rid of those bad things even if it means losing backwards compatibility, so please get rid of this bad thing that comes from C.
>
> I also like Mike's suggestion on this thread a lot.  It could even be combined with my suggestion.  I'd say use Mike's suggestion, and only apply my suggestion to the colon blocks.  Since the brackets and one-liners are not valid C syntax AFAIK, the compiler won't need to mandate anything about them to flush out bugs from incoming C code.  On the developer side, this trades nasty runtime bugs for some small amount of hunting down compiler errors and fixing them.  A good trade IMO.  Not sure what the cost would be to compiler writers like Walter, but please at least implement the mandatory ending on the current case blocks, or something just as good.

Me, too.

I hate forgetting to type a break statement at the end of a case. It's usually a pain in the *** to find. Enforcing the break, continue, etc. at the end of a case is a good way to remove unnecessary bugs.

Thus, votes++


August 22, 2006
I too think that curly brackets in switch fits nively to the syntax of the language, as Mike here demostrated. And I also understand, as Chad said, why a new switch statement is a bit too extreme.

Well now, currently there are four solutions:

1) A new switch statement (e.g. jump or branch).
2) The switch statement using different notation (curly brackets).
3) The compiler forces to use breaks etc at the end of cases.
4) A combination of the solutions 2 and 3.

Solution 1:
Pros:
- No breaking through bugs.
- Does not break old code.
- Does not require breaks etc at the end of cases.
- You'll instantly know that breaking always happen at the end of cases (if not defined otherwise) when looking at code.
- Does not require brackets (some people don't like them).
- Allows doing complex case structures easily (usually a bad thing, but sometimes necessary, maybe).
Cons:
- Two statements that do similar tasks yet differently. (Personally I don't think this is a problem though.)
- Allows doing complex case structures easily (sometimes a good thing, maybe).

Solution 2:
Pros:
- Does not break old code.
- Fits to the language syntax nicely.
- Only one statement doing switching/jumping/branching.
- Allows doing complex case structures easily (usually a bad thing, but sometimes necessary, maybe).
Cons:
- You have to be a little more careful when using it. You may end up allowing a break through when not wanted. Will people accustomed to old switch syntax adapt to use the new one?
- Uses brackets (some people don't like them). (Personally I don't mind using them.)
- Allows doing complex case structures easily (sometimes a good thing, maybe).

Solution 3:
Pros:
- No breaking through bugs.
- Does not break old code as _itself_ (see the cons).
- You know instantly that breaking etc always happen at the end of cases when looking at code.
- Complex case structures are somewhat harder to do (sometimes a bad thing, maybe).
Cons:
- In old code, where breaking through is required, you have to modify the code to keep it compiling. This can be considered as "breaking old code". And changing old code may introduce new bugs.
- Takes more typing. If you forget a break statement, then you have to edit the code and recompile.
- Complex case structures are somewhat harder to do (usually a good thing, though).


The simplest and safest solution seems to be 1. The solution 2 is more 'beautiful' syntaxically (well, at least people who don't like curly brackets may disagree with this). However, it's not so safe to use than the solution 1, I think. Solution 3 is also safe. However, it requires more typing and it may 'break' old code.

Maybe we could have both the solutions 1 and 2? (Or not...) ;)
I think solutions 3 and 2+3 are not accepted (by public) because of this old code breaking issue... but maybe it's not an issue at all in practice.


Btw, it's quite funny/sad that (quite) many seem to hate curly brackets. C/C++, D, etc, are so called curly brackets languages after all.

Well, I am not fond of them either, pressing AltGr + 7 and AltGr + 0 is not so fast/easy as it should be (usually pressing AltGr + 7 requires two hands). Fortunately my text editor's macro will add { and } to a statement by pressing Ctrl + Enter. Usually it works fine, even.


On Tue, 22 Aug 2006 04:56:40 +0300, Chad J <gamerChad@_spamIsBad_gmail.com> wrote:
> Kristian wrote:
>> It would be nice if there was a new statement that acts like 'switch'  except that 'break' will be automatically added at the end of the case  statements. (We don't want to change the behavior of 'switch' because  it'll break old code and confuse people familiar with C/C++.)
>>  Let call this new statement 'jump' (or something), for example:
>>  void func(int val) {
>>     jump(val) {
>>         case 1:
>>             doX();
>>         case 2, 3:
>>             doY();
>>         default:
>>             doZ();
>>     }
>> }
>>  Using 'switch', 'func()' would look, of course, as follows:
>>  void func(int val) {
>>     switch(val) {
>>         case 1:
>>             doX();
>>             break;
>>         case 2, 3:
>>             doY();
>>             break;
>>         default:
>>             doZ();
>>             break;
>>     }
>> }
>>  You could use a 'unbreak' (or something) to allow execution to fall  through to the next case statement.
>>  In addition, falling through should be allowed in the following case:
>>      case 1:
>>     case 2:
>>  which is a longer way to write "case 1, 2:", of course.
>>   I think breaking after a case is (a lot) more common than falling through.  So this will reduce bugs (a programmer can easily forget to put the break  statement at the end of a case). Also, it'll make code shorter and easier  to read.
>
> Creating a new type of switch statement just to change some default
> behavior seems a bit excessive.
>
> At the same time, I can't stand the fall-through default behavior!  It
> is a source of bugs, and I've already been hit by it a few times in D
> and spent hours trying to find the bug in a switch statement that
> behaves subtly different than what I expected.
>
> I've read that this is maintained in D to keep it easy to port C code
> over to D.  That's understandable, especially if you want to make break
> the default, which would change the meaning of code without any warning.
>
> I'd suggest though, that you don't allow a default ending for case
> blocks at all.  Mandate that each case block be followed by an escape
> like 'break', 'return', 'goto', 'throw', etc.  That way, the compiler
> would throw an error when C code that uses fallthroughs is inadvertently
> used as D code.  Also, this is one of those things from C/C++ that is
> bad.  D is supposed to get rid of those bad things even if it means
> losing backwards compatibility, so please get rid of this bad thing that
> comes from C.
>
> I also like Mike's suggestion on this thread a lot.  It could even be combined with my suggestion.  I'd say use Mike's suggestion, and only apply my suggestion to the colon blocks.  Since the brackets and one-liners are not valid C syntax AFAIK, the compiler won't need to mandate anything about them to flush out bugs from incoming C code.  On the developer side, this trades nasty runtime bugs for some small amount of hunting down compiler errors and fixing them.  A good trade IMO.  Not sure what the cost would be to compiler writers like Walter, but please at least implement the mandatory ending on the current case blocks, or something just as good.

« First   ‹ Prev
1 2