On 17 February 2014 03:14, Timon Gehr <timon.gehr@gmx.ch> wrote:
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;'.

That's still entirely explicit. It's not fallthrough.


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/ ?

Yes. That's just common sense, right?


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:
}

Right. Inclusive ranges are intended for enum ranges though. Integer ranges are just fine in the usual way.
I'd support both...


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?

case 1, 2, 5..10, 20:

But that's not what I actually meant. I was actually talking about the case when 'case 1,2,5:' appears in the same switch() block as 'case 10: .. case 19:', when they appear next to eachother, it just looks awkward; like they don't belong together.


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.

Don't agree. Most of my cases are such that no default action is required. It's just noise in my code.
If I fail to handle default when I probably should have, then that's clearly my mistake.


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;
}

I hate this. It violates the formatting conventions used EVERYWHERE else.
In terms of formatting, it doesn't even look like the same language.


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

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

Yes yes, very clever. Obviously it's an example and could come in any shape or form.
Personally, I also wouldn't do that anyway; basic readability has definitely been lost.


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.

Then I should have used an invariant or something actually designed for catching values out of range.
It's not the compilers fault I made a logic error. I could make a logic error literally anywhere in my code. Why force an annoying rule to maybe sometimes catch exactly one case (while making other competing cases where a logic error isn't present more annoying).