www.digitalmars.com         C & C++   DMDScript  

D - Suggestions: switch, case, also, elsif syntax

reply Mark Shackelford <mark shackelford-family.org> writes:
Hi all!

D looks like a great start for a new 'hardware' oriented language. Of
course I have a few comments:

1. A Nit to pick: The Sieve demo program on the intro page has the [] in
the wrong place for the flags array.

2. I have never liked the C switch statement and the possible ugliness
of the ensuing block statement. The structure of the statement should
reflect the semantics of the code. The way it is in C, the semantic
analyzer must check if the switch, case, and default block is structured
correctly. I would suggest something more like the following:

switchStmt ::= switch '(' expr ')' '{' caseStmtList [ defaultStmt ] '}'.

caseStmtList ::= { caseStmt [ alsoStmt ]}.
caseStmt ::= caseLabel ':' [ StmtList ].
caseLabel ::= label { ',' label }.
label ::= value [ '..' value ].
alsoStmt ::= also ':' [ StmtList ].
defaultStmt ::= default ':' [ StmtList ].

where {x} means 0 or more x, and [x] means 0 or 1 x.

The caseLabel construct allows any number of values and value ranges to
be attached to a single block of code. You can still use a list of
single value cases, if we keep the default fall-through semantics of a
case statement. Label ranges would be valid for integral types only, not

The alsoStmt contruct is a block of code that will get executed if any
of the preceding case blocks get executed.

Some of you may detect a slight Modula/Oberon influence here, but I
think this reflects more closely how a programmer thinks, as opposed to
how can he keep from shooting himself in the foot.

The upside is that the proper construction of the switch can be verified
by the syntax pass, without needing any attached semantic checking. Plus
each case block can have any number of label values, and the 'also'
block allows different case blocks to share common code.

The downside of this is not being able to use case or default labels in
nested blocks within the switch statement, which breaks C compatability.
But we don't care about that anyway, right? We should be ready to
jettison confusing and/or needlessly complex features for a reasonable
improvement in readability, and I think the C switch is one of them.

On the issue of case statement fall through behavior, we see a C
construct where the default action is not the most common usage. A break
statement after a case statement list is almost always used, and if
forgotten can cause a great deal of confusion. I would suggest that the
'break' is implied before the next label, but it can be over-ridden by
using the 'fall' keyword. And since we can use any number of labels on a
single case block with the above syntax, the default fall through does
not need to be preserved just to allow multiple case label values for
one case code block.

switch ( ch )
   case '0'..'9':
     numeric = true;
   case 'A'..'Z':
     upcase = true;
   case 'a'..'z':
      alpha = true;
       alphanumeric = true;
   case ';', ':', '.':
      punctuation = true;
     misc = true;

3. An If statement with explicit elsif parts, and also parts, as below:

ifStmt ::= if '(' expr ')' Stmt { elsif '(' expr ')' Stmt [ also Stmt ]
} [ else Stmt ].

if ( a == b )
  x = y;
elsif ( a == c )
  x = z;
  p = q;
  r = 1;
elsif ( a == d )
  x = x * 2;
  r = 2;
  r = 0;
  x = 0;

If a == b or a == c, then r gets 1. If a == d then r gets 2. Otherwise r
gets 0;

This allows multiple 'if' blocks to share a common code block (after the
'also') without 'goto' being used.

That's my two cents worth. Or maybe three.

Mark Shackelford
Aug 16 2001
parent "Walter" <walter digitalmars.com> writes:
The idea of case ranges is good. I'm less sure about the 'also' statement,
although many times I do use a goto to accomplish the same effect.
Aug 18 2001