On Sunday, 16 February 2014 at 15:43:31 UTC, 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.
With this in mind, 'break' is unnecessary. Why is it required?
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.
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
':'?
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.
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.
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 default case is a total waste, since -1 should just be
assigned when
initialising the variable above.
We can compact it a bit 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;
}
But that's horrible too. It's not clear what vertical offset
the 'break'
statements shoudl appear at (I hate stacking up multiple
statements across
the same line!).
The the default case is still a waste.
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;
}
'break's are unnecessary since fallthrough isn't allowed.
Proper numeric range could be supported (assuming [) intervals).
'default' case is unnecessary, and removed.
The switch and braces results in 3 extra lines, but I still
feel this level
of simplification results in code that is MUCH more readable
than the
sequence of if's I started with. It's super obvious what's
going on.
I have quite many blocks like this.
A great man once (actually, frequently) said "If it doesn't
look right, it
probably isn't".
Having also wrote a lot of switch statements in D I do mostly
agree on these points. I think this example 'case 1: .. case 3:'
is obvious. but I like 'case 1..3, 5, 6, 8, 9..10:' syntax better
(Pascal) see how much typing I save.
Break inside a switch should be rid of (Again Pascal) it's bloat.
Having a default does get a bit annoying I see a lot of these..
That being said it's nice having that extra safety.