www.digitalmars.com         C & C++   DMDScript  

D - so what about switch()

reply "Pavel Minayev" <evilone omen.ru> writes:
Yeah, once again back to the old topic... Walter, are you going
to provide some neater, more powerful, and less error-prone
alternative to this #&!% C switch()? It's one of the most frequent
sources of bugs, IMO, and the way it works is not intuitive
and absolutely anti-C(D), in general.

My suggestion of syntax:

    select (n)
    {
        case (0)
            foo();
        case (1, 3, 7)
        {
            int m = foo(n);
            bar(n);
        }
        case (2, 4 .. 6, 9)
            bar(n);
        default
            throw new Error;
    }

This should deal with most switch() problems:

    - no more break; only one case-block gets executed. Block statement
      is required if there are more then one statement in case (just
      like all other D constructs)
    - easy to check for several possible values and/or ranges

What do you think of this?
Feb 12 2002
next sibling parent reply "Sean L. Palmer" <spalmer iname.com> writes:
Once break is no longer *required* in a switch, we can actually use break to
break out of an enclosing loop, something I've wished for many times in the
past.

Sean

"Pavel Minayev" <evilone omen.ru> wrote in message
news:a4ap6u$teg$1 digitaldaemon.com...
 Yeah, once again back to the old topic... Walter, are you going
 to provide some neater, more powerful, and less error-prone
 alternative to this #&!% C switch()? It's one of the most frequent
 sources of bugs, IMO, and the way it works is not intuitive
 and absolutely anti-C(D), in general.

 My suggestion of syntax:

     select (n)
     {
         case (0)
             foo();
         case (1, 3, 7)
         {
             int m = foo(n);
             bar(n);
         }
         case (2, 4 .. 6, 9)
             bar(n);
         default
             throw new Error;
     }

 This should deal with most switch() problems:

     - no more break; only one case-block gets executed. Block statement
       is required if there are more then one statement in case (just
       like all other D constructs)
     - easy to check for several possible values and/or ranges

 What do you think of this?

Feb 12 2002
next sibling parent reply "Walter" <walter digitalmars.com> writes:
"Sean L. Palmer" <spalmer iname.com> wrote in message
news:a4arei$ude$1 digitaldaemon.com...
 Once break is no longer *required* in a switch, we can actually use break

 break out of an enclosing loop, something I've wished for many times in

 past.

 Sean

There is, in D, a break label construct enabling breaking out of any lexically enclosing loop.
Feb 12 2002
parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Walter" <walter digitalmars.com> wrote in message
news:a4arl2$ueu$1 digitaldaemon.com...

 There is, in D, a break label construct enabling breaking out of any
 lexically enclosing loop.

True. But labels and goto (or break & continue w/label) make code somewhat harder to read - because you have to find that label to follow the execution flow of the program. If you're lucky enough to mess with the code written by one of those holy guys that use strict formatting rules (like me =)), you have a chance to see it easily: while(true) { switch() { ... break Out; .. } } Out: ... However, it's so easy to write this code in such a way you'll spend several minutes trying to find that damn Out in a 10-screen function listing. Not the most productive way to spend your time, it is. =)
Feb 12 2002
parent "Walter" <walter digitalmars.com> writes:
"Pavel Minayev" <evilone omen.ru> wrote in message
news:a4b19l$10s8$1 digitaldaemon.com...
 "Walter" <walter digitalmars.com> wrote in message
 news:a4arl2$ueu$1 digitaldaemon.com...

 There is, in D, a break label construct enabling breaking out of any
 lexically enclosing loop.

True. But labels and goto (or break & continue w/label) make code somewhat harder to read - because you have to find that label to follow the execution flow of the program. If you're lucky enough to mess with the code written by one of those holy guys that use strict formatting rules (like me =)), you have a chance to see it easily: while(true) { switch() { ... break Out; .. } } Out: ... However, it's so easy to write this code in such a way you'll spend several minutes trying to find that damn Out in a 10-screen function listing. Not the most productive way to spend your time, it is. =)

The label applies to the loop, your example should be: Out: while (true) { switch () .... break Out; .... Complex control flow spanning many screens is always going to be complex, I don't think there's much hope for that.
Feb 12 2002
prev sibling next sibling parent "Pavel Minayev" <evilone omen.ru> writes:
"Sean L. Palmer" <spalmer iname.com> wrote in message
news:a4arei$ude$1 digitaldaemon.com...
 Once break is no longer *required* in a switch, we can actually use break

 break out of an enclosing loop, something I've wished for many times in

 past.

Yes, I also had it in mind when proposing this idea.
Feb 12 2002
prev sibling parent reply Jon Allen <jallen minotstateu.edu> writes:
My suggestion of syntax:

    select (n)
    {
        case (0)
            foo();
        case (1, 3, 7)
        {
            int m = foo(n);
            bar(n);
        }
        case (2, 4 .. 6, 9)
            bar(n);
        default
            throw new Error;
    }

This should deal with most switch() problems:

    - no more break; only one case-block gets executed. Block statement
      is required if there are more then one statement in case (just
      like all other D constructs)
    - easy to check for several possible values and/or range


I don't personally mind the c-style switch statement. The fall through behavior can be extremely handy at times, and i haven't personally had much problem with forgetting the break when it's necessary. If something has to be changed though, why not leave case and default as they are and add something like and "else:" switch(x) { case 1: ..... //no break case 2: ..... //no break default: ..... else: ..... } Here the default block would always be called and the else block would only be called if (x != 1) && (x != 2). This would retain the C-flavored syntax of D, give C guys what they are used to, and give BASIC guys an alternative to the "fall through" behavior (the compiler could even eliminate the fall through for real if the default code block was absent). P.S. I wouldn't be opposed to enumerations (case 1,2,3:) but ranges (case 1..3:)? There is a reason for the if statement. Part of the beauty of D is that everything is simple and straightforward. I vote for leaving it that way.
Feb 21 2002
parent reply "Sean L. Palmer" <spalmer iname.com> writes:
Try rewriting this as a switch statement (without ranges) sometime:

char c;
if (c >= 'A' && c <= 'Z')
{
  printf("uppercase");
}
else if (c >= 'a' && c <= 'z')
{
  printf("lowercase");
}

Fingers tired yet?

Even though in this case a 256-byte table wouldn't be that bad of a way to
generate the code, if you're only interested in speed.

Sometimes ranges can be a big time saver for the programmer.  Also easier to
maintain if used properly.

Sean


"Jon Allen" <jallen minotstateu.edu> wrote in message
news:3C758B5B.8020307 minotstateu.edu...
My suggestion of syntax:

    select (n)
    {
        case (0)
            foo();
        case (1, 3, 7)
        {
            int m = foo(n);
            bar(n);
        }
        case (2, 4 .. 6, 9)
            bar(n);
        default
            throw new Error;
    }

This should deal with most switch() problems:

    - no more break; only one case-block gets executed. Block statement
      is required if there are more then one statement in case (just
      like all other D constructs)
    - easy to check for several possible values and/or range


I don't personally mind the c-style switch statement. The fall through behavior can be extremely handy at times, and i haven't personally had much problem with forgetting the break when it's necessary. If something has to be changed though, why not leave case and default as they are and add something like and "else:" switch(x) { case 1: ..... //no break case 2: ..... //no break default: ..... else: ..... } Here the default block would always be called and the else block would

 be called if (x != 1) && (x != 2).  This would retain the C-flavored
 syntax of D, give C guys what they are used to, and give BASIC guys an
 alternative to the "fall through" behavior (the compiler could even
 eliminate the fall through for real if the default code block was absent).

 P.S.  I wouldn't be opposed to enumerations (case 1,2,3:) but ranges
 (case 1..3:)?  There is a reason for the if statement.  Part of the
 beauty of D is that everything is simple and straightforward.  I vote
 for leaving it that way.

Feb 22 2002
parent reply Karl Bochert <kbochert ix.netcom.com> writes:
On Fri, 22 Feb 2002 01:36:02 -0800, "Sean L. Palmer" <spalmer iname.com> wrote:
 Try rewriting this as a switch statement (without ranges) sometime:
 
 char c;
 if (c >= 'A' && c <= 'Z')
 {
   printf("uppercase");
 }
 else if (c >= 'a' && c <= 'z')
 {
   printf("lowercase");
 }
 
 Fingers tired yet?
 
 Even though in this case a 256-byte table wouldn't be that bad of a way to
 generate the code, if you're only interested in speed.
 
 Sometimes ranges can be a big time saver for the programmer.  Also easier to
 maintain if used properly.
 
 Sean
 

Why one would ever do this as: if (c>='A' && c < '[' ) { ... is beyond me. Karl
Feb 22 2002
parent "Sean L. Palmer" <spalmer iname.com> writes:
"Karl Bochert" <kbochert ix.netcom.com> wrote in message
news:1103_1014441037 bose...
 On Fri, 22 Feb 2002 01:36:02 -0800, "Sean L. Palmer" <spalmer iname.com>

 Try rewriting this as a switch statement (without ranges) sometime:

 char c;
 if (c >= 'A' && c <= 'Z')
 {
   printf("uppercase");
 }
 else if (c >= 'a' && c <= 'z')
 {
   printf("lowercase");
 }

 Fingers tired yet?

 Even though in this case a 256-byte table wouldn't be that bad of a way


 generate the code, if you're only interested in speed.

 Sometimes ranges can be a big time saver for the programmer.  Also


 maintain if used properly.

 Sean

Why one would ever do this as: if (c>='A' && c < '[' ) { ... is beyond me. Karl

Yeah... I despise end-exclusive syntax. It Just Ain't Natural. I've gotten used to it in for loops but that's a special case. Sean
Feb 23 2002
prev sibling next sibling parent reply "Walter" <walter digitalmars.com> writes:
The difficulty I have is I haven't had problems with switch in my own code.
I do like the idea of having multiple case values, though. The case range is
a good idea, too. I don't want to change the fall through behavior, though.
Is it really such a problem?

"Pavel Minayev" <evilone omen.ru> wrote in message
news:a4ap6u$teg$1 digitaldaemon.com...
 Yeah, once again back to the old topic... Walter, are you going
 to provide some neater, more powerful, and less error-prone
 alternative to this #&!% C switch()? It's one of the most frequent
 sources of bugs, IMO, and the way it works is not intuitive
 and absolutely anti-C(D), in general.

 My suggestion of syntax:

     select (n)
     {
         case (0)
             foo();
         case (1, 3, 7)
         {
             int m = foo(n);
             bar(n);
         }
         case (2, 4 .. 6, 9)
             bar(n);
         default
             throw new Error;
     }

 This should deal with most switch() problems:

     - no more break; only one case-block gets executed. Block statement
       is required if there are more then one statement in case (just
       like all other D constructs)
     - easy to check for several possible values and/or ranges

 What do you think of this?

Feb 12 2002
next sibling parent "D" <s_nudds hotmail.com> writes:
Language behaviour should default to the behaviour that is most commonly
used and expected.  Hence there
should be an implicit break before each new case statement.  The fall
through behaviour of case can be omitted
entirely with the logical justification being that the fall through is not
part of the current case.

Fall though should also be avoided in my view because doing so would
facilitate converting the case statemement
from a standard branch around block type of code, to a more efficient
dispatch table type of code.

In the syntax above, bracketing is redundant.  The following syntax is
superior

selectcase (a)
    case 1,2,3
    ...
    case 4,5,6
    ...
    case 7,8,9
    ...
    default
    ...
end select

Typically a compiler will comple the above code to.

_case1:   mov eax,a
              cmp eax,1
              je l1a
              cmp eax,2
               je l1a
               cmp eax,3
               jne l1
l1a:          <block1>
               jmp exit
l1:           cmp ax,4
               je l2a
               cmp  eax,5
               je l2a
               cmp  eax,6
               jne l2
l2a:          <block2>
               jmp exit
l2:            cmp eax,7
               je l3a
               cmp eax,8
               je l3a
               cmp eax,9
               jne dflt
l3a:          <block3>
               jmp exit
dflt:         <block4>
exit:         *

Without fallthrough the following code could be substituted....
This code will provide higher speed where the cases span a simple integer
sequence by
computing the jump address rather than performing multiple tests and jumps.

In the pervious example the worst case execution hits the default block
after 9 tests,
3 taken jumps and 6 aborted jumps.  In the code below,  it takes 2
unparallelable instructions
and one jump.  Other optimizations are possible.

case1:      mov  ebx,a
               sub   ebx,1
               cmp  ebx,9
               jae     dflt
               shl     ebx,2
               call    [dispatch + bx]
dflt:         <block4>
 exit:        *

diapatch:  &<block1>
                &<block2>
                &<block3>

l1:             <block1>
                 ret

l2:             <block2>
                 ret

l3:             <block3>
                 ret

I am not saying that D should provide this optimization.   But D should be
thoughtful that such an optimization can be performed.

Mozilla contains a 10 page neted case statement in it's gif image
compression parser.

Madness.

Walter <walter digitalmars.com> wrote in message
news:a4aril$ue9$1 digitaldaemon.com...
 The difficulty I have is I haven't had problems with switch in my own

 I do like the idea of having multiple case values, though. The case range

 a good idea, too. I don't want to change the fall through behavior,

 Is it really such a problem?

Feb 12 2002
prev sibling next sibling parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Walter" <walter digitalmars.com> wrote in message
news:a4aril$ue9$1 digitaldaemon.com...

 The difficulty I have is I haven't had problems with switch in my own

It's the matter of experience, I believe. All amateur C programmers, especially those who came from other languages like BASIC or Pascal, with strict select-case statement, tend to forget to add the break at the end of case blocks. This is much like missing semicolons, but the latter is detected at compile-time, while one occasionaly missed break very often compiles silently and is then a source of hard-to- catch bugs. After some practice, though, you get used to break out of the cases - it took me about a month to polish my practical C skills (including switch-breaks) when I moved to C from Pascal.
 I do like the idea of having multiple case values, though. The case range

 a good idea, too. I don't want to change the fall through behavior,

 Is it really such a problem?

First of all, I suggest to leave the switch() construct untouched (note that I proposed another keyword, select()), for some compatibility with C, and for those [really rare] cases when you really need the fall-through behaviour, like one in this piece of code (from WinD): case WM_LBUTTONDOWN: if (handleClicks) clicking = true; case WM_RBUTTONDOWN: case WM_MBUTTONDOWN: mouseDown(new MouseEvent(this, wParam, lParam)); break; However, such code is typically hard to read, because you might assume there's a break statement where there isn't, or you might miss one that is really there... so the _recommended_ way would be to use select(), which is less prone for such errors.
Feb 12 2002
parent "Sean L. Palmer" <spalmer iname.com> writes:
You can always use goto if you want to jump into another case.  Fallthru is
not necessary once you can supply multiple arguments to each case.

Sean

"Pavel Minayev" <evilone omen.ru> wrote in message
news:a4b10u$10li$1 digitaldaemon.com...
 "Walter" <walter digitalmars.com> wrote in message
 news:a4aril$ue9$1 digitaldaemon.com...

 The difficulty I have is I haven't had problems with switch in my own

It's the matter of experience, I believe. All amateur C programmers, especially those who came from other languages like BASIC or Pascal, with strict select-case statement, tend to forget to add the break at the end of case blocks. This is much like missing semicolons, but the latter is detected at compile-time, while one occasionaly missed break very often compiles silently and is then a source of hard-to- catch bugs. After some practice, though, you get used to break out of the cases - it took me about a month to polish my practical C skills (including switch-breaks) when I moved to C from Pascal.
 I do like the idea of having multiple case values, though. The case


 is
 a good idea, too. I don't want to change the fall through behavior,

 Is it really such a problem?

First of all, I suggest to leave the switch() construct untouched (note that I proposed another keyword, select()), for some compatibility with C, and for those [really rare] cases when you really need the fall-through behaviour, like one in this piece of code (from WinD): case WM_LBUTTONDOWN: if (handleClicks) clicking = true; case WM_RBUTTONDOWN: case WM_MBUTTONDOWN: mouseDown(new MouseEvent(this, wParam, lParam)); break; However, such code is typically hard to read, because you might assume there's a break statement where there isn't, or you might miss one that is really there... so the _recommended_ way would be to use select(), which is less prone for such errors.

Feb 12 2002
prev sibling next sibling parent reply "Richard Krehbiel" <rich kastle.com> writes:
"Walter" <walter digitalmars.com> wrote in message
news:a4aril$ue9$1 digitaldaemon.com...
 The difficulty I have is I haven't had problems with switch in my own

Well, I have. But more importantly, I've had difficulty with switch in *other* people's code. How much of other people's code have you looked at, or had to debug? I've given this some thought, and IMHO, fallthrough behavior of switch is more dangerous than useful. Sure, I've personally used it to good effect (in fact, just today), and without case enumerations and ranges it's essential. But if it were me, I would provide one switch() syntax (not two), I'd make all cases exclusive (each case breaks at the end), and I'd provide case ranges (1 ... 3) and enumerations (1, 2, 3). If I really wanted to code a fallthrough, I'd do it the ugly way: switch(a) { case 1, 2, 3: // do stuff for these cases goto do_other_case; case 4 ... 10: do_other_case: // It was ugly but I decided it was worth it.
 I do like the idea of having multiple case values, though. The case range

 a good idea, too. I don't want to change the fall through behavior,

 Is it really such a problem?

 "Pavel Minayev" <evilone omen.ru> wrote in message
 news:a4ap6u$teg$1 digitaldaemon.com...
 Yeah, once again back to the old topic... Walter, are you going
 to provide some neater, more powerful, and less error-prone
 alternative to this #&!% C switch()? It's one of the most frequent
 sources of bugs, IMO, and the way it works is not intuitive
 and absolutely anti-C(D), in general.

 My suggestion of syntax:

     select (n)
     {
         case (0)
             foo();
         case (1, 3, 7)
         {
             int m = foo(n);
             bar(n);
         }
         case (2, 4 .. 6, 9)
             bar(n);
         default
             throw new Error;
     }

 This should deal with most switch() problems:

     - no more break; only one case-block gets executed. Block statement
       is required if there are more then one statement in case (just
       like all other D constructs)
     - easy to check for several possible values and/or ranges

 What do you think of this?


-- Richard Krehbiel, Arlington, VA, USA rich kastle.com (work) or krehbiel3 comcast.net (personal)
Feb 12 2002
next sibling parent "Walter" <walter digitalmars.com> writes:
"Richard Krehbiel" <rich kastle.com> wrote in message
news:a4bk4v$1918$1 digitaldaemon.com...
 "Walter" <walter digitalmars.com> wrote in message
 news:a4aril$ue9$1 digitaldaemon.com...
 The difficulty I have is I haven't had problems with switch in my own

Well, I have. But more importantly, I've had difficulty with switch in *other* people's code. How much of other people's code have you looked

 or had to debug?

Well, I do get emailed a lot of code I have to sort through looking for problems <g>.
Feb 12 2002
prev sibling parent "Sean L. Palmer" <spalmer iname.com> writes:
I have at least 5 or 6 extremely hard to track down subtle bugs a year due
to missing a break statement in a switch.  Doesn't matter who writes it, it
is a major source of bugs.

Even experienced C coders sometimes forget it.

Sean

"Richard Krehbiel" <rich kastle.com> wrote in message
news:a4bk4v$1918$1 digitaldaemon.com...
 "Walter" <walter digitalmars.com> wrote in message
 news:a4aril$ue9$1 digitaldaemon.com...
 The difficulty I have is I haven't had problems with switch in my own

Well, I have. But more importantly, I've had difficulty with switch in *other* people's code. How much of other people's code have you looked

 or had to debug?

 I've given this some thought, and IMHO, fallthrough behavior of switch is
 more dangerous than useful.  Sure, I've personally used it to good effect
 (in fact, just today), and without case enumerations and ranges it's
 essential.  But if it were me, I would provide one switch() syntax (not
 two), I'd make all cases exclusive (each case breaks at the end), and I'd
 provide case ranges (1 ... 3) and enumerations (1, 2, 3).

 I do like the idea of having multiple case values, though. The case


 is
 a good idea, too. I don't want to change the fall through behavior,

 Is it really such a problem?


YES.
Feb 12 2002
prev sibling parent reply DrWhat? <DrWhat nospam.madscientist.co.uk> writes:
Walter wrote:

 The difficulty I have is I haven't had problems with switch in my own
 code. I do like the idea of having multiple case values, though. The case
 range is a good idea, too. I don't want to change the fall through
 behavior, though. Is it really such a problem?
 

I agree - if we are aiming for ex C programmers to migrate to D then we really need the old syntax to either look the same and act the same or look different and act in a new way. How about a varient of Pavel's otherwise good suggestion switch ( variable ) { case ( 1,2,3 ): doCode(); case ( 4,5..8 ): /* fall through */ doMoreCode(); when ( 12..17 ): /* auto break - like Ada/VHDL */ doOtherCode(); when others: /* or case others for fall through */ throw new Error; } these ideas are mosly from VHDL which does not support fall though, but mixed with C syntax to give a more consistant feel. (and C default is just plain nasty, while 'when others' / 'case others' is both clearer in meaning and plainer in use). The colons could be optional as they do not really appear to fit with the rest of C / D, or could be interchangable with semi-colon. The brackets probably should also be optional (but then a terminator ':' or ';' would be needed) PS: does '12..17' mean '12 <= x <= 17' or '12 <= x < 17' ? whould '17..12' produce an error or become '17 >= x >= 12' or '17 >= x > 12' ?
 "Pavel Minayev" <evilone omen.ru> wrote in message
 news:a4ap6u$teg$1 digitaldaemon.com...
 Yeah, once again back to the old topic... Walter, are you going
 to provide some neater, more powerful, and less error-prone
 alternative to this #&!% C switch()? It's one of the most frequent
 sources of bugs, IMO, and the way it works is not intuitive
 and absolutely anti-C(D), in general.

 My suggestion of syntax:

     select (n)
     {
         case (0)
             foo();
         case (1, 3, 7)
         {
             int m = foo(n);
             bar(n);
         }
         case (2, 4 .. 6, 9)
             bar(n);
         default
             throw new Error;
     }

 This should deal with most switch() problems:

     - no more break; only one case-block gets executed. Block statement
       is required if there are more then one statement in case (just
       like all other D constructs)
     - easy to check for several possible values and/or ranges

 What do you think of this?


Feb 14 2002
parent reply "Pavel Minayev" <evilone omen.ru> writes:
"DrWhat?" <DrWhat nospam.madscientist.co.uk> wrote in message
news:a4hp3c$10tt$1 digitaldaemon.com...

 switch ( variable )
 {       case ( 1,2,3 ):
                 doCode();
         case ( 4,5..8 ):                /* fall through */
                 doMoreCode();
         when ( 12..17 ):                /* auto break - like Ada/VHDL */
                 doOtherCode();
         when others:            /* or case others for fall through */
                 throw new Error;
 }

 these ideas are mosly from VHDL which does not support fall though,
 but mixed with C syntax to give a more consistant feel.
 (and C default is just plain nasty,  while 'when others' / 'case others'

 both clearer in meaning and plainer in use).

I suggested something like this, mixed old/new style, before (only I proposed the "on" keyword, not "when"). Seems fine as well.
 The colons could be optional as they do not really appear to fit with
 the rest of C / D,  or could be interchangable with semi-colon.
 The brackets probably should also be optional (but then a terminator
 ':' or ';' would be needed)

A colon after the case is unneeded if you have the brackets. We don't have it after if(), right? And the brackets are better be there - for consistency with all other constructs.
 PS: does '12..17' mean '12 <= x <= 17' or '12 <= x < 17' ?

I guess it should follow the syntax for array slices, to prevent confusion. So 12 <= x < 17.
 whould '17..12' produce an error or become
 '17 >= x >= 12' or '17 >= x > 12' ?

I vote for error. Once again, an array slice like 17..12 is illegal in D. So making it illegal for switch() as well is a good idea, IMO.
Feb 14 2002
parent reply "Sean L. Palmer" <spalmer iname.com> writes:
 PS: does '12..17' mean '12 <= x <= 17' or '12 <= x < 17' ?

I guess it should follow the syntax for array slices, to prevent confusion. So 12 <= x < 17.

You seriously think that this: char c; switch (c) { case ('a'..'{') { printf("lowercase\n"); } case ('A'..'[') { printf("uppercase\n"); } case ('0'..':') { printf("digit\n"); } } is better than this? char c; switch (c) { case ('a'..'z') { printf("lowercase\n"); } case ('A'..'Z') { printf("uppercase\n"); } case ('0'..'9') { printf("digit\n"); } } P.S. I had to load up Character Map just to figure out what symbols to put in the first example, if that clues you in at all. I suppose however that it could be written like so, but still doesn't appear very clear: char c; switch (c) { case ('a'..'z'+1) { printf("lowercase\n"); } case ('A'..'Z'+1) { printf("uppercase\n"); } case ('0'..'9'+1) { printf("digit\n"); } }
Feb 15 2002
parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Sean L. Palmer" <spalmer iname.com> wrote in message
news:a4kuvk$2fo2$1 digitaldaemon.com...

 You seriously think that this:

 char c;
 switch (c)
 {
   case ('a'..'{') { printf("lowercase\n"); }
   case ('A'..'[') { printf("uppercase\n"); }
   case ('0'..':') { printf("digit\n"); }
 }

 is better than this?

 char c;
 switch (c)
 {
   case ('a'..'z') { printf("lowercase\n"); }
   case ('A'..'Z') { printf("uppercase\n"); }
   case ('0'..'9') { printf("digit\n"); }
 }

No, I don't...
 I suppose however that it could be written like so, but still doesn't

 very clear:

 char c;
 switch (c)
 {
   case ('a'..'z'+1) { printf("lowercase\n"); }
   case ('A'..'Z'+1) { printf("uppercase\n"); }
   case ('0'..'9'+1) { printf("digit\n"); }
 }

This is what I think it should look like. Yes, it might look somewhat strange, but at least a D newbie won't get a headache trying to understand why case(1 .. 5) works for all 1 <= n <= 5, while array[1 .. 5] turns out to have length of 4 elements... ...but _personally_, I wouldn't mind if there was such syntax. Simply because I will be aware of it either way. =)
Feb 16 2002
parent reply Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
Pavel Minayev wrote:

 This is what I think it should look like. Yes, it might look somewhat
 strange, but at least a D newbie won't get a headache trying to
 understand why case(1 .. 5) works for all 1 <= n <= 5, while
 array[1 .. 5] turns out to have length of 4 elements...

 ...but _personally_, I wouldn't mind if there was such syntax.
 Simply because I will be aware of it either way. =)

(twitch) You just made the best argument yet for end-INclusive array slicing syntax. -- The Villagers are Online! http://villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Feb 16 2002
next sibling parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message
news:3C6EAF3B.9741F1C3 deming-os.org...

 You just made the best argument yet for end-INclusive array slicing

Forget it, I didn't say that... =) Another idea is to use different syntax: case (1, 3 to 5, 7) ... This way, it differentiates from array slicing op .. enough to avoid confusion, IMO.
Feb 16 2002
next sibling parent reply "Roberto Mariottini" <rmariottini lycosmail.com> writes:
"Pavel Minayev" <evilone omen.ru> ha scritto nel messaggio
news:a4mbd5$63s$1 digitaldaemon.com...
 "Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message
 news:3C6EAF3B.9741F1C3 deming-os.org...

 You just made the best argument yet for end-INclusive array slicing

Forget it, I didn't say that... =)

No, he's right. v1[] = v2['A'..'Z'+1] Looks weird. Looks wrong. What a mess... Ciao
Feb 18 2002
parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Roberto Mariottini" <rmariottini lycosmail.com> wrote in message
news:a4qetl$1nbv$1 digitaldaemon.com...

 No, he's right.

 v1[] = v2['A'..'Z'+1]

 Looks weird. Looks wrong. What a mess...

Just how frequently you index array with chars? Also v2[0 .. v2.length] looks nice and suites for(int i = 0; i < v2.length; i++) syntax.
Feb 18 2002
parent "OddesE" <OddesE_XYZ hotmail.com> writes:
"Pavel Minayev" <evilone omen.ru> wrote in message
news:a4r4bf$2072$1 digitaldaemon.com...
 "Roberto Mariottini" <rmariottini lycosmail.com> wrote in message
 news:a4qetl$1nbv$1 digitaldaemon.com...

 No, he's right.

 v1[] = v2['A'..'Z'+1]

 Looks weird. Looks wrong. What a mess...

Just how frequently you index array with chars? Also v2[0 .. v2.length] looks nice and suites for(int i = 0; i < v2.length; i++) syntax.

Clearly both ways have some advantages and disadvantages. The end-inclusive way works more natural for arrays and ranges of fixed sizes. [0,10] looks like 10 is included. But when size variables are used [0, array.size] end-exclusive looks more natural than having to subtract one element manually. I still agree with the notation suggested in another thread, where the programmer can choose: [0,9] [0,10) (-1,0] (-1,10) Would all denote elements 0 up to and including 9, but not 10. The last two would probably hardly be used, but the whole idea has a very nice feeling of consistency around it. Especially the fact that [0,10) uses two different characters to denote that it uses two different ways of 'inclusiveness' to me looks very natural and I think that notation is also used in math. There is something about this consistency that makes it very powerfull, even when at first sight it might look 'funny'. I would vote for this option, also because you are never forced to add or subtract one manually to correct for the inclusiveness, which is going to end up wrong for some situations whichever one you choose. These two examples both look unnatural, when in fact, depending on the inclusiveness, one might be forced to write that way: [0, array.size-1] ['A', 'Z' + 1] A good idea, but unfortunately not mine. It was somewehere back in the newsgroup, but I can't remember who posted it. -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net __________________________________________ Remove _XYZ from my address when replying by mail
Feb 18 2002
prev sibling parent reply Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
Pavel Minayev wrote:

 Another idea is to use different syntax:

     case (1, 3 to 5, 7) ...

Personal opinion: To my eye, the comma has "higher precedence" than "to". That is, when I looked at it, my eyes saw it as case ((1,3) to (5,7)) ... which was confusing to say the least. I'm not (very much) opposed to forking off a new syntax, I just would opine that that syntax isn't the one. :) -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Feb 18 2002
parent reply "Sean L. Palmer" <spalmer iname.com> writes:
Comma doesn't do a good job of denoting a range... that's what dotdot is
for.

Damn... no I just fell into the same trap as you did.  <grin>

Anyway if this route ends up being taken I think "thru" would be a better
keyword than "to" (maybe)

case (1, 3 thru 5, 7)

Yeah... still looks funny, would take some getting used to.

Sean



"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message
news:3C711D06.A4EABA23 deming-os.org...
 Pavel Minayev wrote:

 Another idea is to use different syntax:

     case (1, 3 to 5, 7) ...

Personal opinion: To my eye, the comma has "higher precedence" than "to". That is, when I looked at it, my eyes saw it as case ((1,3) to (5,7)) ... which was confusing to say the least. I'm not (very much) opposed to forking off a new syntax, I just would opine that that syntax isn't the one. :)

Feb 19 2002
parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Sean L. Palmer" <spalmer iname.com> wrote in message
news:a4tcpn$2vn3$1 digitaldaemon.com...
 Comma doesn't do a good job of denoting a range... that's what dotdot is
 for.

 Damn... no I just fell into the same trap as you did.  <grin>

 Anyway if this route ends up being taken I think "thru" would be a better
 keyword than "to" (maybe)

 case (1, 3 thru 5, 7)

 Yeah... still looks funny, would take some getting used to.

Just a thought... I wonder how loudly Walter does laugh while he reads all this... =)
Feb 19 2002
next sibling parent "Sean L. Palmer" <spalmer iname.com> writes:
"Pavel Minayev" <evilone omen.ru> wrote in message
news:a4u1f8$8p1$1 digitaldaemon.com...
 Just a thought...
 I wonder how loudly Walter does laugh while he reads all this... =)

If anyone can find the humor in all this, I hope it's Walter. ;)
Feb 20 2002
prev sibling parent "OddesE" <OddesE_XYZ hotmail.com> writes:
"Pavel Minayev" <evilone omen.ru> wrote in message
news:a4u1f8$8p1$1 digitaldaemon.com...
 "Sean L. Palmer" <spalmer iname.com> wrote in message
 news:a4tcpn$2vn3$1 digitaldaemon.com...
 Comma doesn't do a good job of denoting a range... that's what dotdot is
 for.

 Damn... no I just fell into the same trap as you did.  <grin>

 Anyway if this route ends up being taken I think "thru" would be a


 keyword than "to" (maybe)

 case (1, 3 thru 5, 7)

 Yeah... still looks funny, would take some getting used to.

Just a thought... I wonder how loudly Walter does laugh while he reads all this... =)

:) -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net __________________________________________ Remove _XYZ from my address when replying by mail
Feb 20 2002
prev sibling parent reply Karl Bochert <kbochert ix.netcom.com> writes:
On Sat, 16 Feb 2002 12:12:59 -0700, Russ Lewis
<spamhole-2001-07-16 deming-os.org> wrote:
 Pavel Minayev wrote:
 
 This is what I think it should look like. Yes, it might look somewhat
 strange, but at least a D newbie won't get a headache trying to
 understand why case(1 .. 5) works for all 1 <= n <= 5, while
 array[1 .. 5] turns out to have length of 4 elements...

 ...but _personally_, I wouldn't mind if there was such syntax.
 Simply because I will be aware of it either way. =)

(twitch) You just made the best argument yet for end-INclusive array slicing syntax. --

that an array (of objects or case values) is an ordered set which is therefore naturally denoted with ordinals. Karl Bochert
Feb 20 2002
parent reply Russell Borogove <kaleja estarcion.com> writes:
Karl Bochert wrote:
  It's such a shame.  All these problems disappear once you realize
 that an array (of objects or case values) is an ordered set
 which is therefore  naturally denoted with ordinals.

Thus, arrays should be 1-based? -RB
Feb 20 2002
parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Russell Borogove" <kaleja estarcion.com> wrote in message
news:3C747A1C.5090300 estarcion.com...

 Thus, arrays should be 1-based?

So what? I don't see how it'd affect slicing syntax.
Feb 20 2002
parent reply Russell Borogove <kaleja estarcion.com> writes:
Pavel Minayev wrote:
 "Russell Borogove" <kaleja estarcion.com> wrote in message
 news:3C747A1C.5090300 estarcion.com...
 
 
Thus, arrays should be 1-based?

So what? I don't see how it'd affect slicing syntax.

Well, if you were 1-based, it would be natural to be both-ends-inclusive in all cases, because array.length would be the index of the last element as well as its size. I am not sure if this was what Mr. Bochert was getting at or not. You'd have to get used to starting from one, and you'd want to use <= instead of < in the idiomatic for-loop: for (i = 1; i <= array.length; i++) { ... } -RB
Feb 20 2002
next sibling parent reply "Sean L. Palmer" <spalmer iname.com> writes:
This would be bad from a performance standpoint, as the compiler would have
to sneak in a hidden "minus one" when indexing into an array.  Admittedly
sometimes it could do this offset at compile time, if the array address is
known at compile time.  Or the BASIC approach could be used, and the
language allocate one extra entry in each array to humor those careless C
programmers who think 0 is a valid index.  ;)

Sean

"Russell Borogove" <kaleja estarcion.com> wrote in message
news:3C747CC4.1020100 estarcion.com...
 Pavel Minayev wrote:
 "Russell Borogove" <kaleja estarcion.com> wrote in message
 news:3C747A1C.5090300 estarcion.com...


Thus, arrays should be 1-based?

So what? I don't see how it'd affect slicing syntax.

Well, if you were 1-based, it would be natural to be both-ends-inclusive in all cases, because array.length would be the index of the last element as well as its size. I am not sure if this was what Mr. Bochert was getting at or not. You'd have to get used to starting from one, and you'd want to use <= instead of < in the idiomatic for-loop: for (i = 1; i <= array.length; i++) { ... }

Feb 21 2002
parent reply Karl Bochert <kbochert ix.netcom.com> writes:
On Thu, 21 Feb 2002 00:36:41 -0800, "Sean L. Palmer" <spalmer iname.com> wrote:
 This would be bad from a performance standpoint, as the compiler would have
 to sneak in a hidden "minus one" when indexing into an array.
 sometimes it could do this offset at compile time, if the array address is
 known at compile time.

the 'offset' would already be built into the variable. In cases where the index is computed, there is usually a place to modify a constant as opposed to doing an add.
 Or the BASIC approach could be used, and the
 language allocate one extra entry in each array to humor those careless C
 programmers who think 0 is a valid index.  ;)
 

Could a 'zero'th element' hold something else of interest? The type? The size of the elements? Karl Bochert
Feb 21 2002
parent "Pavel Minayev" <evilone omen.ru> writes:
"Karl Bochert" <kbochert ix.netcom.com> wrote in message
news:1104_1014316439 bose...

 This is a very small performance hit. In most cases of indexing from a

 the 'offset' would already be built into the variable. In cases where the

 is computed,  there is usually a place to modify a constant as opposed to
 doing an add.

I don't see what you can do when index is a variable, like in foo[i]. Either way you have to increase it by the array base - which is not only slower, but requires a place for temporary, probably a register... After all you can always do foo[base+i] if it's really needed.
 Probably not a good idea, given that the array elements could be very

 Could a 'zero'th element' hold something else of interest?
 The type?

Type of what?
 The size of the elements?

It's (*foo).size
Feb 21 2002
prev sibling parent reply Karl Bochert <kbochert ix.netcom.com> writes:
On Wed, 20 Feb 2002 20:51:16 -0800, Russell Borogove <kaleja estarcion.com>
wrote:
 Well, if you were 1-based, it would be natural to be
 both-ends-inclusive in all cases, because array.length
 would be the index of the last element as well as its
 size. I am not sure if this was what Mr. Bochert was
 getting at or not.
 

array[2..4] // second, third, and fourth elements case [2..4] // cases 2,3,4 Both 'array' and 'case' include the end elements as the text would indicate. (The syntax includes the ends ---- so should the semantics.)
 You'd have to get used to starting from one,

C programmer, was extremely suspicious to say the least. One day's use convinced me.
 and you'd
 want to use <= instead of < in the idiomatic for-loop:
 
 for (i = 1; i <= array.length; i++)
 {
     ...
 }
 

one equal to the array length. It just looks more like the lfirst and ast elements are included in the loop. Karl Bochert
Feb 21 2002
parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Karl Bochert" <kbochert ix.netcom.com> wrote in message
news:1103_1014316261 bose...

 Array slicing is the same as case ranges:
 array[2..4]   // second, third, and fourth elements

Arrays are _zero-based_. a[2] is actually the _third_ element. Slicing should be no different! As for the end-inclusive thing... this is a matter of personal taste, I believe. I like it as it is implemented now by Walter. Most people here seem to dislike it though (but have you _tried_ it?)...
 case [2..4]  // cases 2,3,4

Could be. Just don't use .. to avoid confusion, some keyword would be better.
 When I first ran into 1-based arrays (in Euphoria)  I, a life-long
 C programmer, was extremely suspicious to say the least.
 One day's use convinced me.

When I (3-year BASIC user, then 1-year Pascal user) ran into 0-based arrays in C++, I found out that they are actually easier to use. Even now, in my BASIC programs, I declare arrays zero-based. BTW remember that VB.NET does so as well? Also, Euphoria is an interpreter - so that impact on perfomance isn't really important there.
 Makes more sense doesn't it -- the last element done is the
 one equal to the array length. It just looks more like the
 lfirst and ast elements are included in the loop.

I don't see much difference, really. The most important thing is that you can tell the number of iterations easily: for (int i = 0; i < 10; i++) for (int i = 1; i <= 10; i++) Only the first syntax reminds us that arrays are actually 0-based (when used to iterate through an array), while the second would remind of 1-based arrays if they were there...
Feb 21 2002
parent reply "OddesE" <OddesE_XYZ hotmail.com> writes:
"Pavel Minayev" <evilone omen.ru> wrote in message
news:a53n18$2fuj$1 digitaldaemon.com...
 "Karl Bochert" <kbochert ix.netcom.com> wrote in message
 news:1103_1014316261 bose...

 Array slicing is the same as case ranges:
 array[2..4]   // second, third, and fourth elements

Arrays are _zero-based_. a[2] is actually the _third_ element. Slicing should be no different!

I think he was talking about the hypothetical case of 1-based arrays. Ofcourse in Pascal you can choose the range of your arrays freely, but it seems people have already chosen. 0-based has also become the standard there (in the VCL at least).
 As for the end-inclusive thing... this is a matter of personal taste,
 I believe. I like it as it is implemented now by Walter. Most people
 here seem to dislike it though (but have you _tried_ it?)...

 case [2..4]  // cases 2,3,4

Could be. Just don't use .. to avoid confusion, some keyword would be better.

I still like: case [2..4) // end-exclusive case [2..3] // end-inclusive. <SNIP> -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net __________________________________________ Remove _XYZ from my address when replying by mail
Feb 22 2002
parent reply "Pavel Minayev" <evilone omen.ru> writes:
"OddesE" <OddesE_XYZ hotmail.com> wrote in message
news:a561fa$2vmo$1 digitaldaemon.com...

 arrays. Ofcourse in Pascal you can choose the range of your
 arrays freely, but it seems people have already chosen. 0-based
 has also become the standard there (in the VCL at least).

Yes, also in VB (remember that Collections are indexed starting from 0?), and VB.NET arrays are similar to C ones by default... Funny isn't it? This means that most VB.NET and Delphi programmers will get used to 0-based arrays as well - and then D would be a small island in a large sea...
 I still like:
 case [2..4)  // end-exclusive
 case [2..3]  // end-inclusive.

Me too. The same for slices etc, and everybody's happy. A common math notation, easy to learn and use.
Feb 22 2002
parent reply Russell Borogove <kaleja estarcion.com> writes:
Pavel Minayev wrote:
 "OddesE" <OddesE_XYZ hotmail.com> wrote in message
 news:a561fa$2vmo$1 digitaldaemon.com...

I still like:
case [2..4)  // end-exclusive
case [2..3]  // end-inclusive.

Me too. The same for slices etc, and everybody's happy. A common math notation, easy to learn and use.

Not everybody's happy with it, though. I could live with it, but I don't like it -- too hard to see the difference in a small font. -RB
Feb 22 2002
parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Russell Borogove" <kaleja estarcion.com> wrote in message
news:3C768FF8.4030708 estarcion.com...

 Not everybody's happy with it, though. I could live
 with it, but I don't like it -- too hard to see the
 difference in a small font.

...but still better than "always end-exclusive"? =)
Feb 22 2002
parent Russell Borogove <kaleja estarcion.com> writes:
Pavel Minayev wrote:
 "Russell Borogove" <kaleja estarcion.com> wrote in message
 news:3C768FF8.4030708 estarcion.com...
 
 
Not everybody's happy with it, though. I could live
with it, but I don't like it -- too hard to see the
difference in a small font.

...but still better than "always end-exclusive"? =)

Tough call. I could handle "always end-exclusive" if the array slice documentation were changed to SCREEAAAAAM about it so that those who don't intuitively assume end-exclusive have a fighting chance of learning the rule, and if all examples of array slice in the documentation have a comment saying "// remember: end-exclusive, see array slice docs" :) -RB
Feb 22 2002
prev sibling next sibling parent Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
I really think that this is a Good Idea...but that we do need a
continuation block of some sort.  My favorite (of what's been proposed
here) was "goto case":

select(n)
{
    case(0)
        foo();
    case(1,3,7)
    {
        int m = foo(n);
        goto case(2);
    }
    case(2,4..6,9)
        bar(n);
    default
        throw new Error;
}

--
The Villagers are Online! http://villagersonline.com

.[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ]
.[ (a version.of(English).(precise.more)) is(possible) ]
?[ you want.to(help(develop(it))) ]
Feb 12 2002
prev sibling next sibling parent reply Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
People have also talked about switches on strings or other types.  Frankly,
I think that switches on arbitrary types is good, but switches on strings
(i.e. arrays of chars and wchars) is almost "absolutely necessary".
Trouble is, if you select() on an array, it's kind of ambiguous whether
your're comparing the arrays (do the point to the same region and have the
same length) or are you comparing the strings (would strcmp() return 0).  I
think that the default behavior should be the latter...but that there
should be a language construct for the former.  Maybe, like in setting
arrays, we use the [] to tell the difference:

char string[] = ...;
select(string)
{
   ...   // compares arrays
}

select(string[])
{
    ... // compares array contents (i.e. the string value)
}

--
The Villagers are Online! http://villagersonline.com

.[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ]
.[ (a version.of(English).(precise.more)) is(possible) ]
?[ you want.to(help(develop(it))) ]
Feb 12 2002
parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message
news:3C691185.6B118CF deming-os.org...

 People have also talked about switches on strings or other types.

 I think that switches on arbitrary types is good, but switches on strings
 (i.e. arrays of chars and wchars) is almost "absolutely necessary".
 Trouble is, if you select() on an array, it's kind of ambiguous whether
 your're comparing the arrays (do the point to the same region and have the
 same length) or are you comparing the strings (would strcmp() return 0).

Just to remind, switch() in D already works with string. select() should, too, in the same way.
Feb 12 2002
parent Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
Pavel Minayev wrote:

 "Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message
 news:3C691185.6B118CF deming-os.org...

 People have also talked about switches on strings or other types.

 I think that switches on arbitrary types is good, but switches on strings
 (i.e. arrays of chars and wchars) is almost "absolutely necessary".
 Trouble is, if you select() on an array, it's kind of ambiguous whether
 your're comparing the arrays (do the point to the same region and have the
 same length) or are you comparing the strings (would strcmp() return 0).

Just to remind, switch() in D already works with string. select() should, too, in the same way.

Sorry, I forgot. :( As much as I wanted to be a cutting-edge D developer, I haven't had the time to even try. I love the language, and plan to move my personal pet project to it as soon as a good cross platform UNIX/Windows compiler (or dfront) stabilizes. I'd do it right now, but I don't want to have to fork my UNIX and Windows code. :( -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Feb 12 2002
prev sibling next sibling parent reply Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
I would also like to see regexp matching...this could be done, perhaps with
a regexp keyword in the select() block:

char[] string = ...;
select(string)
{
    regexp("^asdf$")
        foo(string);
    retexp("^asdf")
        bar(string);
    regexp("asdf$")
        baz(string);
    default
        fred(string);
}

--
The Villagers are Online! http://villagersonline.com

.[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ]
.[ (a version.of(English).(precise.more)) is(possible) ]
?[ you want.to(help(develop(it))) ]
Feb 12 2002
parent reply "Walter" <walter digitalmars.com> writes:
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message
news:3C69122D.BE5F2EAE deming-os.org...
 I would also like to see regexp matching...this could be done, perhaps

 a regexp keyword in the select() block:

 char[] string = ...;
 select(string)
 {
     regexp("^asdf$")
         foo(string);
     retexp("^asdf")
         bar(string);
     regexp("asdf$")
         baz(string);
     default
         fred(string);
 }

Oh, man, I do strings and he raises the bar wanting regexp <g>.
Feb 12 2002
next sibling parent "Pavel Minayev" <evilone omen.ru> writes:
"Walter" <walter digitalmars.com> wrote in message
news:a4bm6k$1a5o$4 digitaldaemon.com...

 Oh, man, I do strings and he raises the bar wanting regexp <g>.

Yeah, a bit too much =)
Feb 12 2002
prev sibling parent Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
LOL

Hey Walter, thanks for the work so far. :)

--
The Villagers are Online! villagersonline.com

.[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ]
.[ (a version.of(English).(precise.more)) is(possible) ]
?[ you want.to(help(develop(it))) ]
Feb 12 2002
prev sibling parent reply Juarez Rudsatz <juarez correio.com> writes:
"Pavel Minayev" <evilone omen.ru> wrote in 
news:a4ap6u$teg$1 digitaldaemon.com:

 Yeah, once again back to the old topic... Walter, are you going
 to provide some neater, more powerful, and less error-prone
 alternative to this #&!% C switch()? 

The most practical and flexible loop of all programming languages is the "C++" for loop. None laguage has its power and simplicity. But the switch statement is not so good. Bellow some suggestion (or resume of someone) to improve the "multiple case statement" giving for it more power. 1. As commented in anothers messages in this thread, the "break" fallthrough is error prone and is not the default option for average cases in code. Stripping it brings some advantages IMHO: o The typing is reduced o The reading is improved mainly in large quantity of cases o The break could be used in loops without problems. o Many novice and some "hard to debug" errors could be prevented. o The syntax will follow anothers D statements syntax. The fallthrough case could be emulated, as Russ Lewis suggests, with the goto, without problem. The sintax will change something: for(;;) { ... switch(x){ case 1: break; case 2: { doSomething(); goto case_3; } case 3: { doAnotherthing() } default: RaiseMyException(); } } 2. There are three keywords for switch statement: "switch", "case" and "default". Once the break is out, there are no need of case keyword. And the default keyword could be replaced by another keyword in language: switch(x){ 1, 2, 3 : sigle_line_statement(); 4 : { multi_line_statement_1(); multi_line_statement_2(); multi_line_statement_3(); } else : another_statement(); } With this the keywords case and default dont are needed. I know some redundancy is good but I think the parser (yacc) dont will find problem because al identifiers have keywords delimitanting. Some persons dont like the keyword switch too and prefer "case" or "select" or "option". They have a more significant meaning !? 3. In some languages, the diferent cases must be only integral types. The D already allow using string as case for use. But you need use only constant types. This is made thus because choosed implementation is a jump table or some similar. But this is very restricting. Theare no reason for a modern compiler dont allow variables, expression, function calls or ranges to be a case option. Consider the following: o Many times the programmer will write nesteds if statements because they could not use expressions as "switch cases": if (x = a) { ... } else if ((x = b) or (x = c*3)) { ... } else if (x = get_old_x()) { ... } else if ((x >= 10) and (x =< 20)){ ... } this could be better writed as: switch(x){ a: { ... } b, c * 3 : { ... } get_old_x(): { ... } 10..20 : { ... } } Simpler and clearer IMHO. o The limitation is not give by sintax or semantic but by the compiler implementation. Generally the limitations of switch, case, select are decisions made in language definion because simplify something the implementation. But I think this will not add considerable bloat to a language. o For tradicional switch statement generally are a simple optimization like a jump table, or a hash table in case of strings. But nothing prevents the compiler of making this optimizations when possible. And there are a new door open for new optimizations discovered. The compiler also can mix the optimizations, when are not only same type constants involved. 4. The order of comparation must not follow the topbottom order necessarily: switch(y){ slow_function(): { ... } 1, 3, 4 : { ... } } If is needed precedence, the programmer could use the default argument : switch(y){ slow_function(): { ... } 1, 3, 4 : { ... } else: switch(y){ another_func() :{ ... } } } With this the compiler could use optimize the comparisons choose the best order in compile time. Until the optimization is not implemented or when is not possible to guess the best order, the compiler will follow the topbottom rule. IMHO, this solution will improved the switch statement and allow for the compiler have more power when optimizing the code. Comments, sugestion, Yes, No ?
Feb 14 2002
next sibling parent reply DrWhat? <DrWhat nospam.madscientist.co.uk> writes:
Juarez Rudsatz wrote:

 "Pavel Minayev" <evilone omen.ru> wrote in
 news:a4ap6u$teg$1 digitaldaemon.com:
 
 Yeah, once again back to the old topic... Walter, are you going
 to provide some neater, more powerful, and less error-prone
 alternative to this #&!% C switch()?

The most practical and flexible loop of all programming languages is the "C++" for loop. None laguage has its power and simplicity. But the switch statement is not so good. Bellow some suggestion (or resume of someone) to improve the "multiple case statement" giving for it more power. 1. As commented in anothers messages in this thread, the "break" fallthrough is error prone and is not the default option for average cases in code. Stripping it brings some advantages IMHO: o The typing is reduced o The reading is improved mainly in large quantity of cases o The break could be used in loops without problems. o Many novice and some "hard to debug" errors could be prevented. o The syntax will follow anothers D statements syntax.

I would advocate using a new keyword 'when' to effectively alias to 'break; case ' (I do this using '#define when break; case' if using C, though I admit to getting the idea from Ada/VHDL - and it does give some problems (ie. have to use case at start, default falls though), still it is better than missing a break; especially with the C I write!) Maybe 'else' could be used as 'default' without fallthrough?
 The fallthrough case could be emulated, as Russ Lewis suggests, with the
 goto, without problem. The sintax will change something:
 
 for(;;) {
     ...
     switch(x){
     case 1: break;
     case 2: {
     doSomething();
     goto case_3;
     }
     case 3: {
     doAnotherthing()
     }
     default:
     RaiseMyException();
     }
 }

goto case_3: this is not good what if 'case "hello world":' is supported continue (as suggested earlier) would be better if you are going to run with this option <NITPICK> besides if this code is entered with x=1 it does an infinate loop </NITPICK>
 2. There are three keywords for switch statement: "switch", "case" and
 "default". Once the break is out, there are no need of case keyword. And
 the default keyword could be replaced by another keyword in language:
 
 switch(x){
     1, 2, 3 : sigle_line_statement();
     4 : {
     multi_line_statement_1();
     multi_line_statement_2();
     multi_line_statement_3();
     }
     else : another_statement();
 }

yes - getting rid of 'default' is a good idea.
 With this the keywords case and default dont are needed. I know some
 redundancy is good but I think the parser (yacc) dont will find problem
 because al identifiers have keywords delimitanting.
 Some persons dont like the keyword switch too and prefer "case" or
 "select" or "option". They have a more significant meaning !?

yes - though it does not really matter, keeping switch will be just as good
 3. In some languages, the diferent cases must be only integral types. The
 D already allow using string as case for use. But you need use only
 constant types. This is made thus because choosed implementation is a jump
 table or some similar. But this is very restricting. Theare no reason for
 a modern compiler dont allow variables, expression, function calls or
 ranges to be a case option. Consider the following:
 o     Many times the programmer will write nesteds if statements because
 they could not use expressions as "switch cases":
 if (x = a) {
     ...
 }
 else
     if ((x = b) or (x = c*3)) {
     ...
     }
     else
     if (x = get_old_x()) {
     ...
     }
     else
     if ((x >= 10) and (x =< 20)){
     ...
     }

 this could be better writed as:
 
 switch(x){
     a: {
     ...
     }
     b, c * 3 : {
     ...
     }
     get_old_x(): {
     ...
     }
     10..20 : {
     ...
     }
 }
 
 Simpler and clearer IMHO.

I think ELSIF would be better ie. (using your style) if (x = a) { ... } elsif ((x = b) or (x = c*3)) { ... } elsif(x = get_old_x()) { ... } elsif ((x >= 10) and (x =< 20)){ ... }
 o   The limitation is not give by sintax or semantic but by the compiler
 implementation. Generally the limitations of switch, case, select are
 decisions made in language definion because simplify something the
 implementation. But I think this will not add considerable bloat to a
 language.

I would advise using switch to compare against constants and if / elsif / else for more complex expressions. This should both make the language less complex, simplify implementation and not loose and functionality (compared to your suggestion). [Walter - are we going to get an ELSIF construct in D - it does not appear to be in the specifications, though I think it would be fairly easy to add]
 o     For tradicional switch statement generally are a simple optimization
 like a jump table, or a hash table in case of strings. But nothing
 prevents the compiler of making this optimizations when possible. And
 there are a new door open for new optimizations discovered. The compiler
 also can mix the optimizations, when are not only same type constants
 involved.

That adds otherwise unnecessary complexity to the compiler.
 4.    The order of comparation must not follow the topbottom order
 necessarily:
 
 switch(y){
     slow_function(): {
     ...
     }
     1, 3, 4 : {
     ...
     }
 }
 
 If is needed precedence, the programmer could use the default argument :
 
 switch(y){
     slow_function(): {
     ...
     }
     1, 3, 4 : {
     ...
     }
     else:
     switch(y){
     another_func() :{
     ...
     }
     }
 }

What is slow_function() has side effects (ie. setting a global variable) - then we are left with an implementation specific quection ie. does it execute? (assuming you have to check y == slow_function()). And also what would happen if say y = 3 and slow_function() returned 3 ? Seems a lot to remember for little real gain over the more common solution of ELSIF.
 With this the compiler could use optimize the comparisons choose the best
 order in compile time. Until the optimization is not implemented or when
 is not possible to guess the best order, the compiler will follow the
 topbottom rule.
 
 IMHO, this solution will improved the switch statement and allow for the
 compiler have more power when optimizing the code.
 
 Comments, sugestion, Yes, No ?
 

Sorry, NO! ELSIF, although slightly more limited is far better for this less common construct, and also far easier to bolt onto an existing compiler (though I have not seen the D compiler source, so that may not be the case here). Otherwise a sequence of IF statements would do just as well, the only reason for having a specific ELSIF is for greater syntactic clarity.
Feb 14 2002
parent reply "Pavel Minayev" <evilone omen.ru> writes:
"DrWhat?" <DrWhat nospam.madscientist.co.uk> wrote in message
news:a4hs5m$11vo$1 digitaldaemon.com...

 [Walter - are we going to get an ELSIF construct in D - it does not
  appear to be in the specifications,  though I think it would be fairly
 easy to add]

Is it really needed? You can always use else if: if (a) ... else if (b) ... else if (c) ... I think it's just enough?
Feb 14 2002
parent DrWhat? <DrWhat nospam.madscientist.co.uk> writes:
Pavel Minayev wrote:

 "DrWhat?" <DrWhat nospam.madscientist.co.uk> wrote in message
 news:a4hs5m$11vo$1 digitaldaemon.com...
 
 [Walter - are we going to get an ELSIF construct in D - it does not
  appear to be in the specifications,  though I think it would be fairly
 easy to add]

Is it really needed? You can always use else if: if (a) ... else if (b) ... else if (c) ... I think it's just enough?

Ok, you have convinced me, I though about this in the context of a different language which enforces { ... } after a block statement, though I say it should still be easy to implement using up another keyword (to save two keypresses) on this less common construct does not seem worth the effort. Point conceeded. C 2002/2/15
Feb 15 2002
prev sibling parent reply "d" <s_nudds hotmail.com> writes:
Using a goto to emulate a fall though is a bad idea.  First it begs abuse
where programmers will use goto to jump around multiple times within a case
statement.  The result will be more difficult to manage than having a
fallthrough as default.

If fallthrough is needed (and I am not convinced that it is),  it would be
better to end the case block with a Fallthrough keyword.  This way the
programmer is constrained

In fact allowing GOTO within a case statement is just a generally all round
bad idea.  Partucularly if the GOTO is allowed to jump out of the current
case.

As to optimizations, supporting GOTO's is also an inpediment. whereas a
fallthrough is simply a secondary entry point to a comon function shared
between the various cases.

Juarez Rudsatz <juarez correio.com> wrote in message
news:Xns9115A04D7A983juarezcorreio 63.105.9.61...
 o    For tradicional switch statement generally are a simple optimization
 like a jump table, or a hash table in case of strings. But nothing

 the compiler of making this optimizations when possible. And there are a
 new door open for new optimizations discovered. The compiler also can mix
 the optimizations, when are not only same type constants involved.

Feb 15 2002
next sibling parent reply "Walter" <walter digitalmars.com> writes:
"d" <s_nudds hotmail.com> wrote in message
news:a4jde2$1q97$1 digitaldaemon.com...
 As to optimizations, supporting GOTO's is also an inpediment.

Not the way I do it. Internally, all control structures are translated to goto's before optimization anyway. All the optimizations work on a graph of basic blocks connected by edges (goto's).
Feb 15 2002
parent "Sean L. Palmer" <spalmer iname.com> writes:
That's good... goto is the most basic control flow instruction in all
processors I know of anyway.  At the assembly level you usually have call,
goto, and goto-if-condition-holds.  Makes sense for the compiler to work in
those terms... it all works out to a graph anyway.  I think most optimizing
compilers these days don't have any problem with goto statements.

Sean

"Walter" <walter digitalmars.com> wrote in message
news:a4jfd5$1rar$3 digitaldaemon.com...
 "d" <s_nudds hotmail.com> wrote in message
 news:a4jde2$1q97$1 digitaldaemon.com...
 As to optimizations, supporting GOTO's is also an inpediment.

Not the way I do it. Internally, all control structures are translated to goto's before optimization anyway. All the optimizations work on a graph

 basic blocks connected by edges (goto's).

Feb 15 2002
prev sibling parent reply "OddesE" <OddesE_XYZ hotmail.com> writes:
"d" <s_nudds hotmail.com> wrote in message
news:a4jde2$1q97$1 digitaldaemon.com...
 Using a goto to emulate a fall though is a bad idea.  First it begs abuse
 where programmers will use goto to jump around multiple times within a

 statement.  The result will be more difficult to manage than having a
 fallthrough as default.

 If fallthrough is needed (and I am not convinced that it is),  it would be
 better to end the case block with a Fallthrough keyword.  This way the
 programmer is constrained

Agreed. You only seem to need fallthrough on a very few occasions. Mostly you just need to break the case. But couldn't continue be used as the keyword? -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net __________________________________________ Remove _XYZ from my address when replying by mail
Feb 16 2002
parent reply "Sean L. Palmer" <spalmer iname.com> writes:
Please, no!!  Let's use break and continue just for loops.  Otherwise it
gets confusing.  I'd rather just use goto to implement fallthrough.  Or goto
case.  A new "fallthru" keyword would work as well... so long as Walter
doesn't mind cluttering up the language with lots of keywords.  ;)

Sean

"OddesE" <OddesE_XYZ hotmail.com> wrote in message
news:a4mveb$dh4$1 digitaldaemon.com...
 "d" <s_nudds hotmail.com> wrote in message
 news:a4jde2$1q97$1 digitaldaemon.com...
 Using a goto to emulate a fall though is a bad idea.  First it begs


 where programmers will use goto to jump around multiple times within a

 statement.  The result will be more difficult to manage than having a
 fallthrough as default.

 If fallthrough is needed (and I am not convinced that it is),  it would


 better to end the case block with a Fallthrough keyword.  This way the
 programmer is constrained

Agreed. You only seem to need fallthrough on a very few occasions. Mostly you just need to break the case. But couldn't continue be used as the keyword? -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net __________________________________________ Remove _XYZ from my address when replying by mail

Feb 17 2002
next sibling parent "OddesE" <OddesE_XYZ hotmail.com> writes:
 "OddesE" <OddesE_XYZ hotmail.com> wrote in message
 news:a4mveb$dh4$1 digitaldaemon.com...
 "d" <s_nudds hotmail.com> wrote in message
 news:a4jde2$1q97$1 digitaldaemon.com...
 Using a goto to emulate a fall though is a bad idea.  First it begs


 where programmers will use goto to jump around multiple times within a

 statement.  The result will be more difficult to manage than having a
 fallthrough as default.

 If fallthrough is needed (and I am not convinced that it is),  it



 be
 better to end the case block with a Fallthrough keyword.  This way the
 programmer is constrained

Agreed. You only seem to need fallthrough on a very few occasions. Mostly you just need to break the case. But couldn't continue be used as the keyword? -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net __________________________________________ Remove _XYZ from my address when replying by mail


"Sean L. Palmer" <spalmer iname.com> wrote in message news:a4o7vb$sam$1 digitaldaemon.com...
 Please, no!!  Let's use break and continue just for loops.  Otherwise it
 gets confusing.  I'd rather just use goto to implement fallthrough.  Or

 case.  A new "fallthru" keyword would work as well... so long as Walter
 doesn't mind cluttering up the language with lots of keywords.  ;)

 Sean

"Juarez Rudsatz" wrote in another message in this thread:
 2. There are three keywords for switch statement: "switch", "case" and
 "default". Once the break is out, there are no need of case keyword. And
 the default keyword could be replaced by another keyword in language:

 switch(x){
     1, 2, 3 : sigle_line_statement();
     4 : {
     multi_line_statement_1();
     multi_line_statement_2();
     multi_line_statement_3();
     }
     else : another_statement();
 }

I think this is a good idea. Leave the switch keyword or change it to select. Either way you keep the same amount of keywords. I would recommend select since it clearly signifies the change in the construct. Ditch default, else works just as well. Now we have saved one keyword. The case keyword really isn't necessary if you make the statements blocks behave like all other statement blocks in C/C++/D, where you can write one statement delimited by a semicolon, or a block of multiple statements enclosed in curly braces. Now we have saved two keywords. If continue or goto were used to signfy a jump to another case then we would be at a 'profit' of two keywords, but even if we added a fallthrough keyword we still would save keywords, not clutter the language with them. If you allowed for more than one case on a line, like in the example above, the fallthrough/continue construct could be ditched altogether for a more natural looking way of handling multiple cases, while goto would remain where it is, since it is already available? Code could look like this: char c = 'a'; select (c) { 'a'..'z': printf ("This is a: Lowercase character.\n"); 'A'..'Z': { printf ("This is a: "); printf ("Uppercase character.\n"); } '0'..'9': { printf ("This is a: "); printf ("Decimal digit.\n"); } ';', ',', ':', '.': printf ("This is a: Punctuation character.\n"); else: printf ("This is a: Weird character :)\n"); } I think this is natural looking, easy to understand and fits in with the D filosophy. Any suggestions? -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net __________________________________________ Remove _XYZ from my address when replying by mail
Feb 18 2002
prev sibling parent reply "d" <s_nudds hotmail.com> writes:
Goto should not be used for fallthroughs.  It is too general a construct and
will result in spaghetti like references in larger case statements.

Further, as I said earlier, goto limits the ability of the compiler to
perform optimizations.  Typically case
statements are implmented as a series of nested conditional jumps.  This is
highly inefficient both in terms of execution and code size.  Often it is
possible to replace these nested tests and jumps with a more compact and
efficient loop and table structure.

When defined in a manner similar to that below, one dispatch function can be
used to dispatch for
all such optimizations.

       omov esi,jtab
        mov cx,[esi-2]
 foo: cmp eax,[esi]
        je     foo1
        add  esi,8
        dec  cx
        jne   foo
        ret

foo1: jmp [esi+4]

         dw  5
jtab:  ddq val1,addr1
         ddq val2,addr2
         ddq val3,addr3
         ddq val4,addr4
         ddq val5,addr5


Sean L. Palmer <spalmer iname.com> wrote in message
news:a4o7vb$sam$1 digitaldaemon.com...
 Please, no!!  Let's use break and continue just for loops.  Otherwise it
 gets confusing.  I'd rather just use goto to implement fallthrough.  Or

 case.  A new "fallthru" keyword would work as well... so long as Walter
 doesn't mind cluttering up the language with lots of keywords.  ;)

Feb 21 2002
next sibling parent reply "Sean L. Palmer" <spalmer iname.com> writes:
The code generator can easily tell that the only exit from a block is to
another block, and move that block's code just before the one it goto's to,
and eliminate the goto completely.  This doesn't go away if you hide it
behind voodoo "break" syntax either... you still can get cases where more
than one case wants to fallthrough to another case.  C doesn't handle that
any better.  To someone unfamiliar with C, the lexical adjacency doesn't
help them understand what's going on any better.  At least the goto is
fairly obvious to a newbie.  Any modern optimizing compiler won't have much
trouble with it, although a homegrown compiler may generate suboptimal code
for it (it's gonna have worse problems than this though)

You're making the mistaken assumption that the "normal" thing people do with
switch is fallthrough, while in fact quite the opposite is true.  Making
fallthrough easier at the expense of "normal" code is bad.  Therefore "no
fallthrough" should be the default and some other method should be used for
fallthrough.

Someone already suggested "goto case" and "fallthrough".  Either one is
fine.  Just don't use continue or break.

Sean

"d" <s_nudds hotmail.com> wrote in message
news:a53ql5$2hk1$1 digitaldaemon.com...
 Goto should not be used for fallthroughs.  It is too general a construct

 will result in spaghetti like references in larger case statements.

 Further, as I said earlier, goto limits the ability of the compiler to
 perform optimizations.  Typically case
 statements are implmented as a series of nested conditional jumps.  This

 highly inefficient both in terms of execution and code size.  Often it is
 possible to replace these nested tests and jumps with a more compact and
 efficient loop and table structure.

 When defined in a manner similar to that below, one dispatch function can

 used to dispatch for
 all such optimizations.

        omov esi,jtab
         mov cx,[esi-2]
  foo: cmp eax,[esi]
         je     foo1
         add  esi,8
         dec  cx
         jne   foo
         ret

 foo1: jmp [esi+4]

          dw  5
 jtab:  ddq val1,addr1
          ddq val2,addr2
          ddq val3,addr3
          ddq val4,addr4
          ddq val5,addr5


 Sean L. Palmer <spalmer iname.com> wrote in message
 news:a4o7vb$sam$1 digitaldaemon.com...
 Please, no!!  Let's use break and continue just for loops.  Otherwise it
 gets confusing.  I'd rather just use goto to implement fallthrough.  Or

 case.  A new "fallthru" keyword would work as well... so long as Walter
 doesn't mind cluttering up the language with lots of keywords.  ;)


Feb 22 2002
next sibling parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Sean L. Palmer" <spalmer iname.com> wrote in message
news:a552t1$1g0$1 digitaldaemon.com...

 Someone already suggested "goto case" and "fallthrough".  Either one is
 fine.  Just don't use continue or break.

What about "next"? select (foo) { case (1) { ... next; // fallthru } case (2) { ... next; // fallthru } case (3) { ... // NO fallthru } }
Feb 22 2002
parent reply "Martin York" <Martin.York veritas.com> writes:
Extending the next idea.

how about

switch(foo)
{
    case 1:
    {//  Some stuff
        next;                    // With just a next fall through to the
next case
    }
    case 2:
    {// Case 2 code
        next 4;                // With an argument goto the specified case.
NB argument must be same type as foo.
    }
    case 3:
    {// Case 3 stuff
        next 4;
    }
    case 4:
    {// Case 4 stuff.
    }// implied break
}


"Pavel Minayev" <evilone omen.ru> wrote in message
news:a55g80$7fq$1 digitaldaemon.com...
 "Sean L. Palmer" <spalmer iname.com> wrote in message
 news:a552t1$1g0$1 digitaldaemon.com...

 Someone already suggested "goto case" and "fallthrough".  Either one is
 fine.  Just don't use continue or break.

What about "next"? select (foo) { case (1) { ... next; // fallthru } case (2) { ... next; // fallthru } case (3) { ... // NO fallthru } }

Feb 22 2002
next sibling parent "Pavel Minayev" <evilone omen.ru> writes:
"Martin York" <Martin.York veritas.com> wrote in message
news:a55o6t$bjh$1 digitaldaemon.com...
 Extending the next idea.

 how about

 switch(foo)
 {
     case 1:
     {//  Some stuff
         next;                    // With just a next fall through to the
 next case
     }
     case 2:
     {// Case 2 code
         next 4;                // With an argument goto the specified

 NB argument must be same type as foo.

Probably a good idea. The same could be achieved with goto case, but if introduce the new keyword, let's use it to its full. =)
Feb 22 2002
prev sibling parent "d" <s_nudds hotmail.com> writes:
Cases aren't enumerated.  Would you also use next "a".  If the param after
the next isn't a constant
then the compiler can not make the choice until runtime.

In that case, goto <anything> must necessarily cause a jump to the beginning
of the case statement.

Not Good

Martin York <Martin.York veritas.com> wrote in message
news:a55o6t$bjh$1 digitaldaemon.com...
 Extending the next idea.

 how about

 switch(foo)
 {
     case 1:
     {//  Some stuff
         next;                    // With just a next fall through to the
 next case
     }
     case 2:
     {// Case 2 code
         next 4;                // With an argument goto the specified

 NB argument must be same type as foo.
     }
     case 3:
     {// Case 3 stuff
         next 4;
     }
     case 4:
     {// Case 4 stuff.
     }// implied break
 }


 "Pavel Minayev" <evilone omen.ru> wrote in message
 news:a55g80$7fq$1 digitaldaemon.com...
 "Sean L. Palmer" <spalmer iname.com> wrote in message
 news:a552t1$1g0$1 digitaldaemon.com...

 Someone already suggested "goto case" and "fallthrough".  Either one



 fine.  Just don't use continue or break.

What about "next"? select (foo) { case (1) { ... next; // fallthru } case (2) { ... next; // fallthru } case (3) { ... // NO fallthru } }


Mar 04 2002
prev sibling next sibling parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Sean L. Palmer" <spalmer iname.com> wrote in message
news:a552t1$1g0$1 digitaldaemon.com...

 Someone already suggested "goto case" and "fallthrough".  Either one is
 fine.  Just don't use continue or break.

What about "next"? select (foo) { case (1) { ... next; // fallthru } case (2) { ... next; // fallthru } case (3) { ... // NO fallthru } }
Feb 22 2002
parent "d" <s_nudds hotmail.com> writes:
The Keyword "next" if not used to end the "for" statement would be a good
keyword to use to fall through.

Block typing requires that for be ended with a keyword that is unique to the
for/next construct

Pavel Minayev <evilone omen.ru> wrote in message
news:a55g9r$7g8$1 digitaldaemon.com...
 "Sean L. Palmer" <spalmer iname.com> wrote in message
 news:a552t1$1g0$1 digitaldaemon.com...

 Someone already suggested "goto case" and "fallthrough".  Either one is
 fine.  Just don't use continue or break.

What about "next"?

Mar 04 2002
prev sibling parent reply "Walter" <walter digitalmars.com> writes:
"Sean L. Palmer" <spalmer iname.com> wrote in message
news:a552t1$1g0$1 digitaldaemon.com...
 The code generator can easily tell that the only exit from a block is to
 another block, and move that block's code just before the one it goto's

 and eliminate the goto completely.  This doesn't go away if you hide it
 behind voodoo "break" syntax either... you still can get cases where more
 than one case wants to fallthrough to another case.  C doesn't handle that
 any better.  To someone unfamiliar with C, the lexical adjacency doesn't
 help them understand what's going on any better.  At least the goto is
 fairly obvious to a newbie.  Any modern optimizing compiler won't have

 trouble with it, although a homegrown compiler may generate suboptimal

 for it (it's gonna have worse problems than this though)

I just want to emphasize again that the D optimizer converts everything into goto's, and then analyzes the code as a graph of basic blocks connected by edges (goto's). You can create a nightmarish rat's nest of goto's and the optimizer will work just fine on it. All the obvious optimizations like eliminating fallthrough goto's, goto's to goto's, at nauseum, are done. In other words, the use of goto's is not an issue for code optimization and generation with this compiler.
Feb 22 2002
parent "d" <s_nudds hotmail.com> writes:
Conceptually the language should be designed so that the compiler may
convert a series of case statements to a standard dispatch table.

In cases where the argument is a numeric progression a long series of nested
jumps can be replaced with one subtraction followed by a single indexed jump
or call.

Vastly superior.

Walter <walter digitalmars.com> wrote in message
news:a56tc5$1534$3 digitaldaemon.com...
 I just want to emphasize again that the D optimizer converts everything

 goto's, and then analyzes the code as a graph of basic blocks connected by
 edges (goto's). You can create a nightmarish rat's nest of goto's and the
 optimizer will work just fine on it. All the obvious optimizations like
 eliminating fallthrough goto's, goto's to goto's, at nauseum, are done.

 In other words, the use of goto's is not an issue for code optimization

 generation with this compiler.

Mar 04 2002
prev sibling parent reply "Richard Krehbiel" <rich kastle.com> writes:
"d" <s_nudds hotmail.com> wrote in message
news:a53ql5$2hk1$1 digitaldaemon.com...
 Goto should not be used for fallthroughs.

Once case enumerations and ranges are supported, the motivation for fallthrough mostly disappears. So, don't worry about it. There won't be any fallthroughs. Visual Basic "select case" semantics imply a break after each case; and yet, in all the Visual Basic code I've read or written (okay, maybe not that much, but still), I've never seen nor coded a fallthrough. I would personally bundle the rest of the reasons for fallthrough behavior under the category of "clever hacks." (Do a web search for "Duff's device", and be prepared to retch uncontrollably.) "Goto" exists in the language to support clever hacks. -- Richard Krehbiel, Arlington, VA, USA rich kastle.com (work) or krehbiel3 comcast.net (personal)
Feb 22 2002
parent reply "OddesE" <OddesE_XYZ hotmail.com> writes:
"Richard Krehbiel" <rich kastle.com> wrote in message
news:a55gn1$7nk$1 digitaldaemon.com...
 "d" <s_nudds hotmail.com> wrote in message
 news:a53ql5$2hk1$1 digitaldaemon.com...
 Goto should not be used for fallthroughs.

Once case enumerations and ranges are supported, the motivation for fallthrough mostly disappears. So, don't worry about it. There won't be any fallthroughs.

Yes! Agreed!
 Visual Basic "select case" semantics imply a break after each case; and

 in all the Visual Basic code I've read or written (okay, maybe not that
 much, but still), I've never seen nor coded a fallthrough.

Pascal also implies a break after each case and it works like a charm. Are there any languages that don't imply a break after a case except for C/C++? What about Java?
 I would personally bundle the rest of the reasons for fallthrough behavior
 under the category of "clever hacks."  (Do a web search for "Duff's

 and be prepared to retch uncontrollably.)  "Goto" exists in the language

 support clever hacks.

 --
 Richard Krehbiel, Arlington, VA, USA
 rich kastle.com (work) or krehbiel3 comcast.net  (personal)

-- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net __________________________________________ Remove _XYZ from my address when replying by mail
Feb 22 2002
next sibling parent "Pavel Minayev" <evilone omen.ru> writes:
"OddesE" <OddesE_XYZ hotmail.com> wrote in message
news:a562qp$5nj$1 digitaldaemon.com...

 Once case enumerations and ranges are supported, the motivation for
 fallthrough mostly disappears.  So, don't worry about it.  There won't


 any fallthroughs.

Yes! Agreed!

Me too. Frankly, fallthrough is used so rarely, it won't be hard to mimic it with goto when _really_ needed (and it's even rarer).
 Pascal also implies a break after each case and it works
 like a charm. Are there any languages that don't imply a
 break after a case except for C/C++? What about Java?

Java works in the same manner, AFAIK. C# requires break or return at the end of each case but doesn't insert it automatically (which is stupidity, IMO). However, if case has no body, this requirement doesn't apply and fallthrough happens - this is to support one handler for multiple cases.
Feb 22 2002
prev sibling parent Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
OddesE wrote:

 Pascal also implies a break after each case and it works
 like a charm. Are there any languages that don't imply a
 break after a case except for C/C++? What about Java?

Korn shell scripting uses fallthrough...I don't know about Bash. -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Feb 22 2002