On 02/16/2014 04:42 PM, Manu wrote:
So D offers great improvements to switch(), but there are a few small
things I wonder about.

1.
case fall-through is not supported; explicit 'goto case n;' is required.

Yes it is supported. Use 'goto case;'.

With this in mind, 'break' is unnecessary.

Sure.

Why is it required?

Backwards compatibility.

It could be implicit upon reaching the next case label, or a scope could be used
(with support for omitting the scope for single statements as with if).
It's really noisy, and annoying to write everywhere.
...

Like this: http://ceylon-lang.org/documentation/reference/statement/switch/ ?


2.
'case 1, 3, 7, 8:' is awesome! ...but ranged cases have a totally
different syntax: 'case 1: .. case 3:'

Why settle on that syntax? The inconsistency looks kinda silly when they
appear together in code.
Surely it's possible to find a syntax that works without repeating case
and ':'?
...

AFAIK it is to emphasize that the range is inclusive, as opposed to:

case 1..3:

IIRC Walter's intention was to format it as follows:

switch(x){
    case 1:
    ..
    case 3:
}


It's also weird, because it seems that 'case n: .. case m:' is inclusive
of m. This may be unexpected.
I'm not sure it's reasonable to use the '..' syntax in this case for
that reason. '..' is an [) range, case ranges must be [] so that it
makes sense when dealing with enum key ranges.
...

Sure, mixing case lists and ranges in a single statement would be neat, but what would be your preferred syntax?

3.
Why is 'default' necessary? If I'm not switching on an enumerated type,
then many values are meaningless. requiring an empty 'default: break;'
line at the end is annoying and noisy.
...

There is more than one sensible default, so being explicit about the default makes sense.


I often find myself tempted to rewrite blocks of successive if() logic
comparing integers against values/ranges, but it looks silly since the
scope rules are not explicit, and 'default: break;' always wastes an
extra line.
I like to reduce noise in my code, and these switch semantics threaten
to simplify a lot of code, if not for these strange decisions (purely
for legacy compliance?).


Let's consider an example:

Code like this:

int difficulty = -1;
if(e.note.note >= 60 && e.note.note < 72)
    difficulty = 0;
else if(e.note.note >= 72 && e.note.note < 84)
    difficulty = 1;
else if(e.note.note >= 84 && e.note.note < 96)
    difficulty = 2;
else if(e.note.note >= 96 && e.note.note < 108)
    difficulty = 3;

The repetition of e.note.note is annoying, and particular choice of
comparisons are liable to result in out-by-ones. It's not nice code to read.


Rewrites like this:

int difficulty;
switch(e.note.note)
{
    case 60: .. case 71:
        difficulty = 0;
    break;
    case 72: .. case 83:
        difficulty = 1;
    break;
    case 84: .. case 95:
        difficulty = 2;
    break;
    case 96: .. case 107:
        difficulty = 3;
    break;
    default:
        difficulty = -1;
    break;
}

That's horrid, it's much longer! And there are pointless wasted lines
everywhere.

The wasted lines are due to your formatting.

int difficulty=-1;
switch(e.note.note){
    case 60: .. case 71:  difficulty = 0; break;
    case 72: .. case 83:  difficulty = 1; break;
    case 84: .. case 95:  difficulty = 2; break;
    case 96: .. case 107: difficulty = 3; break;
    default: break;
}

Of course, I'd just write the above as:

int difficulty = e.note.note.between(60,108) ? (e.note.note-60)/12 : -1;

The default case is a total waste, since -1 should just be assigned when
initialising the variable above.
...

How is the compiler supposed to know? It might be a logic error for e.note.note to be out of range.

...

Ideally:

int difficulty = -1;
switch(e.note.note)
{
    case 60 .. 72:
        difficulty = 0;
    case 72 .. 84:
        difficulty = 1;
    case 84 .. 96:
        difficulty = 2;
    case 96 .. 108:
        difficulty = 3;
}
...

Ideally closer to:

int difficulty =
  switch(e.note.note){
      60 .. 72  =>  0;
      73 .. 84  =>  1;
      84 .. 96  =>  2;
      96 .. 108 =>  3;
      _         => -1;
  };



Reply via email to