Point taken. I guess there is a reason I stick with Perl: my C always did suck. | [reply] |
Not just your C; C sucks in general. As a case in
point, the C case statement is next-to-worthless,
because fallthrough is not usually what you want.
There are cases for it, but they're the exception
rather than the rule. As a result, you end up
needing to insert break statements at nearly every
case, at which point you have barely less typing to
do than with a nested if structure. Perl's elsif
is actually an improvement on this.
The case statement in Inform (and even SELECT CASE
in BASIC) is much more useful. If Perl
ever gets a case, I hope the breaks are implied;
otherwise I'll end up never using it.
Most of the cases where you want the
fallthrough, it's because what you want is actually
not a case statement, but some other structure.
This is a perfect example. What it's doing is
not really unique to each case; there are some
minor variations, but what you really want is
a loop.
Others have done efficient things (and I particularly
like the pack solution), but I'll add my own
translation, on the grounds that it is straightforward
and legible...
{ my @shiftby = (0, 8, 16, 24, 0, 8, 16, 24, 8, 16, 24);
my $l;
foreach $l (reverse 1 .. $len) {
if ($l>8) { $c += $k[$l-1]<<$shiftby[$l]; }
elsif ($l>4) { $b += $k[$l-1]<<$shiftby[$l]; }
else { $a += $k[$l-1]<<$shiftby[$l]; }
}
}
I've reduced the number of +=
operations to three,
and it is easy to see where the similarities and
the differences are. The if/elsif/else makes it
stand out when you are incrementing a different
variable. (When I first looked at the thing, I
thought the same variable was being incremented
ten times.) Even better, it is clear how @k is
being used; before, you had to look at each line
and compare the index to @k with the case number,
if you wanted to know if there were any deviations
from the pattern; here it's clear there are none;
$l-1 is always $l-1.
@shiftby could probably also be replaced with an
arithmetic expression, but I'm not sure that would
improve clarity.
--jonadab | [reply] [d/l] [select] |
"Not just your C; C sucks in general. As a case in point, the C case statement is next-to-worthless, because fallthrough is not usually what you want. There are cases for it, but they're the exception rather than the rule. "
I have to disagree here, currently I'm writing quite a bit of C(C++ really) code and I have switches all over the place. I choose the switch construct BECAUSE I can have multiple values that should map to a block of code, so the fall-through is exactly why I use the switch statement. Just because the projects you have written code that does not use a construct does not say that no one uses it. If your code calls for a if/else tree then write one, when you find someplace that could use a switch, then go ahead and use it.
If I have only a few possible values, or it makes more sense then I use a if-else ladder.
I have hit quite a few places where I wished Perl had a case/switch statement.
That all being said I believe that you have to pick a language for the situation, right now we need high performance (simulation) software so we use C/C++. When we have non-speed critical code that can be more easily written in Perl, then that is the language we use. Remember, Perl was written in C, I'm not saying that makes it better, just useful. :)
I can handle people's opinions, but coming out and saying "Language X sucks" is a little harsh.
| [reply] [d/l] |
Which is exactly why the original goto suggestion is about the only one that works and is concise enough to read. I don't see any other obvious ones. I'd often hash something like this but that wouldn't allow for easy emulation of the fall throughs in the C code.
| [reply] |