- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
How about: m.values[min(3,Math.floor((d-1)/15000))]++
Admin
m.values[d > 45000 ? 3 : d / 15000]++ anyone?
Admin
That's what ternaries were created for!
Admin
Seen it before. The perpertrator's excuse was along the lines of how
switch
's lookup tables are more efficient or something. Never mind that the conditions have to evaluated first.Makes me wonder now, actually: would this typically cause all of them to be evaluated, rather than evaluating as few as possible to find the first match?
Admin
i think "could" code could run even in c
Admin
Will not work: if d < 0, d == 15000, d == 30000, d == 45000 or if d is a float, or ( I think) if d is a non-integer string.
Admin
This is actually quite useful for evaluating Radiobuttons:
switch(true) { case Radiobutton1.Selected: ... case Radiobutton2.Selected: ... }
Although doing it in languages that require an explicit break don't make it simpler than if/else.
Admin
Apart from the lack of parameter checking, I can't really see the problem.
a) The numbers are hardwired -- but then they'll also be hardwired when you're writing your if.
b) It assumes d is an integer and non-negative
Apart from that, it's obvious what it does, it's more-or-less clean, and it clearly works.
Where's the WTF?
Admin
This is the exact sort of code I routinely reject from my students. It's an abuse of switch and is much more clearly written as simple 'if' statements.
(And yes, I routinely reject it because it routinely comes up.)
Admin
I actually like your idea, especially if the tests are slightly modified so that "d" is always in the middle:
because it's quite intuitive at a glance to see exactly what gets incremented when. Of course the variable names are meaningless and the array indices should be named, but it's still easier to read than multiple "if"s.
Admin
Meh.
switch(true)
is an idiom that I've seen before; some strange people are fond of it. Not a style I like, but not a WTF.Admin
A thing about
conditions could be simplified.Addendum 2018-11-19 08:40: Oops. We need a Preview button to catch errors like this as well as a link to the markup definitions.
Admin
I used to love this construct when writing visual basic (select case true). It made perfect sense, and VB didn't require a break statement. I was initially tripped up on that when moving to other languages; you're selecting a case, you shouldn't need to break. Efficiency was the same, it read better than lengthy if else blocks, and it included an else case.
Admin
Ummm..... 15000, 30000, 45000 ???? Easily divisible to calculate which index you need to increment! No "Switch", No "If"...
(yes it's true in this case you say but then whats wrong with calling a function passing in the number and it returns the index. Hide the implementation guys!)
Admin
For obscurity bonus:
d <= 15000 && m.values[0]++; d > 15000 && d <= 30000 && m.values[1]++; d > 30000 && d <= 45000 && m.values[2]++; d > 45000 && m.values[3]++;
(clicking 'submit' and hoping the best for formatting.)
Admin
The IF solution would be nested if/else statements. For four possible paths, this would be reasonable, but the more paths, the more I would want to flatten it into the switch. Too easy to mess up the nested ifs when a later modification needs to add some other paths.
I will admit that there are languages that do "switch" for this sort of thing better than JS. And there are languages that have an "elseif" key word to do the nested if/elses more clearly.
Admin
How is this better than:
I struggle to see any cases where using the switch/case form over the if-else form saves you anything. Even in Javascript where every character counts, this is fewer characters once you include the "break;" line for each of these.
(And yes - as Wizard points out it's pretty clear here that some variation on using d/15000 as the index into the array without a set of checks at all is the better choice.)
Admin
In C/C++/C#, the expressions in case labels must be constants, so this sort of nonsense isn't possible to begin with.
Admin
Case is shorter than else if, but you don't need to repeat the lower bounds, if you use else ifs, because they'll be implied by the "else".
Admin
Am I missing something? In the original the array value is incremented:
m.values[x]++
If d == 1001 and m.values[0] == 25, after the check m.values[0] == 26.
In the revised the array value is added to d.
If d == 1001 and m.values[0] == 25, after the check m.values[0] == 1026.
Is this the same as what is intended in the original code or am I missing something?
Admin
In Swift, this is actually quite similar to the recommended style - you do use the value to be switched on (and the value can be a tulle), but the cases can handle ranges.
Admin
Bloody spelling checker: switch values can be tuples. Anyone knows what a tulles is?
Admin
Bloody spelling checker: switch values can be tuples. Anyone knows what a tulles is?
Admin
Single liner: d <= 15000 && m.values[0]++ || d <= 30000 && m.values[1]++ || d <= 45000 && m.values[2]++ || m.values[3]++;
Admin
Tulle (noun): a soft, fine silk, cotton, or nylon material like net, used for making veils and dresses.
Admin
Tulle: A lightweight, very fine netting. Not often used for calculating primes.
Admin
I've seen plenty of people advocate this style in Stack Overflow answers for both JavaScript and PHP. I personally think it's gross.
But what do I know? I also feel that many complex uses of array.reduce() to construct objects from arrays are inappropriate.
Admin
Call me crazy, but I don't see the problem. I prefer the switch syntax to the ifelse syntax, I think it's more obvious what's going on ( plus, as has been mentioned, the switch syntax could be simplified as it stops evaluating when it finds a hit ), plus as you add more conditions ( and this looks like a section which would end up having more conditions eventually ) it keeps the verbosity and the simplicity in place ( where as the ifelse could quickly become a nightmare ).
Admin
Apparently the boolean expression is evaluated as an integer in this situation, so true becomes 1 and false becomes 0. Try it in the console.
Admin
That you can write stuff like this without a syntax error is one of the reasons I don't do JavaScript.
Admin
m.values[Math.max(((int)d / 15000) - 1, 3)]++;
Admin
You are but children. Watch:
Admin
m.values[Math.max(0,Math.min(3,((d-1)/15000)|0))]++
Admin
Obviously they cleaned this up from a previous incarnation where it was switching on the value of d and had a case for every possibility in each of the ranges.
Well, probably had a case for every possibility. Usually that kind of thing ends up with some missing bits here and there that yield strange results but it can't be fixed because whoever's looking at the output would panic over the discrepancy...
Admin
The enterprisey way of doing it
m.values[d <= 15000 ? 0 : d <= 30000 ? 1 : d <= 45000 ? 2 : 3]++;
Admin
https://en.wikipedia.org/wiki/The_Elements_of_Programming_Style "5. Write clearly -- don't sacrifice clarity for efficiency."
Admin
This is a pretty standard idiom in Ruby, as well, which might well explain its presence here if the dashboard is on Rails. Case in Ruby can take no object, which makes case execute the first block with a statement that evaluates to true. Of course, Ruby case doesn't have fallthrough and the explicit ranges are bad in any language.
Admin
This is actually a common usage pattern in (surprise...) Cobol.
Languages with C-like syntax allow one to omit the braces if one has a single statement in either of the branches. When one puts an "if" in the "else" part, one is actually going one nesting level deeper using this single "if" statement. If one has three "else if" following the first "if", then the last one is three levels deep. One is (ab)using this single-statement loophole to avoid the technically correct deeper indentation on the else parts.
Cobol (and of course a few others) needs an END-IF to end an IF(*). When one needs ELSE IF parts, they actually have to have deeper and deeper indentations, or else the series of END-IF in the end, all starting on the same column, will look weird. Thus the switch-case equivalent of EVALUATE is used with TRUE.
(*) In the relatively "modern" versions of Cobol. The older Cobol IF syntax ends with a period ("."), but it ends all inner nested things too. Those issues, however, belong to another website (which should be) called thedailycobolwtf dot com (when it is born).
Admin
Worse? Have you considered the goto statement?
Admin
Admin
You are right, constants only. I have been playing in VBA/VB.Net too long. I need to get back to programming in C++ again.
Admin
Yeah, I would have written this as a if-else if-else series like that, but with the assignment clauses on new lines, rather than a funcky switch.
Admin
Really unreadable version:
Can you beat 38 bytes?
Admin
The real WTF is, as usual, Javascript. Why is there a "break" for every switch case? How often do you need the fall through compared to how often you are writing break, effectively making the entire switch construction too unwieldy to use?
Admin
Hmmm, in a vectorized language, you might get away with
m.values[ sum(d > 1.5e3*(1:3))]++
Which at least looks cool, if not a code golf winner
Admin
Going way back in my increasingly flaky memory banks ...
That style was also perfectly cromulent in DBase/FoxPro that had a switch construct (using the keyword "case" IIRC) but lacked an else if construct.
Otherwise I agree it's a mild code smell.
Admin
++m.values[(d>15000) + (d > 30000) + (d > 45000)];
Done.
Admin
It's clever, maybe a bit obscure for JS. It resembles pattern matching blocks in ML, Scala or Haskell. Pretty obscure though for JS.
Admin
In case somebody comes to read the comments in 2020 or later... This looks like output from the CoffeeScript transpiler. For more details, see https://stackoverflow.com/questions/30493275/theoretical-coffeescript-switch-statement-conundrum. As to why this is generated by CoffeeScript instead of an if-else if-else is beyond me, though.