In my recent post I questioned the use of a switch instead of an if else statement. This gave me the idea of an recurring item for dev.to: Commit or Vomit! Would you commit this code or not.
It's going to be code snippets that are going to be evaluated here. Not posts because I don't want people to feel/be judged by this, only code!
So this first ✔||🤢 is from the post that started it all.
If (all) else is complicated, switch to switch?
🐤🥇 Jasper de Jager ・ Apr 1 '21
switch(true){
case userMissedAppointment:
return 'nope';
case userHasAngularExperience:
case userHasReactExperience:
case userHasVueExperience && userCanStartInstantly:
return 'hire';
default:
return 'maybe'
}
This is just an example but the question is about the switch(true). What do you think? ✔||🤢
❤: Commit
🏷: Vomit (we all know unicorns don't vomit)
🦄: Like your post please continue this series!
Looking forward to your reactions! 😎
Top comments (50)
This could easily have been an if/elseif/else.
You could have done:
I'm not sure it's because of the editor, but I would suggest to use more lines for more readability and easier comprehension.
For me this already reduces the cognitive load a lot quickly see what can happen.
Actually I typed my comment on mobile, so I didn't format it
Good point for a next Commit or Vomit! What do you think about switch(true) in general?
true, this is a short example. Apart from this example would you never commit a switch(true)?
Nope 🤢
good to mention: the example was updated after this reply
Since you're returning on each case I wouldn't even bother with elses...
Of course I'd also extract that second conditon into another method, but that's another matter.
Um, making it a bit inline is better imo.
The first line for the second if statement is too long imo. Turned it into two lines.
My preference:
Oh yeah, I didn't thought that.
Personally I prefer all-or-nothing for braces, I really don't like mixing styles. If any of my code has braces, I'd prefer all of my code to have braces. But this is totally off topic and probably a topic for another C/V poll!
I'll save it for another ✔️||🤢 good idea.
Just have to come up with a good example 😊 and not posting a new one every day is hard but I think this is going to be a weekly recurring item from now on 😎
I personally like to drop the braces IF the condition is small and the statement ends control flow and logically can't have anything after, like return, throw, continue, break, etc.
I think the cleanest and most expressive is still this
Your function behaves slightly different than the example, bit this just might prove your point of the switch not being readable enough 😅
The difference is that in the switch an angular experienced used doesn't have to start immediately.
You are definitely right :D Well in that case I wouldn't mind the right if else combo either
Why the need for the case statement?
Also, imo, there's no need to repeat "user" in these flags. You could just say
canStartInstantly
, for example. There's no ambiguity regarding who this refers to.Totally agree, but would you merge it if it was in a PR for instance?
Nope, I'd request changes here.
While the code is valid, I think the real issue here is just the amount of conditions you're trying to parse through. Using switch (true) feels more like a band-aid than a solution I would accept say in a PR.
I'm a fan for using switches when we're actually comparing the value in switch(value). Someone mentioned checking for a match in the zodiac. Perfect use case for a switch statement.
When you have to resort to a hacky solution, chances are the problem lies more with the code leading up to this decision than the decision itself.
Totally agree! It's a code smell.
I think this is a misuse of the switch statement and its purpose.
If there is a need for this kind of hackery witchery I believe there are other design flaws which makes this code "necessary" and should be refactored to make this kind of code avoidable.
When an if statement gets so complex that you start to search for more readable ways of writing it there will most likely also be alternative ways to take it apart into smaller parts and make it more comprehensible (and maintainable) that way.
I'd say probably vomit, but I'm sure there are cases where this way is just easier to read than if/else/return early/etc. Hard to say with placeholder-var-names.
Yes I agree, something to take into account for the next one in the series!
Thanks for the feedback 😊
switch(true){
case userDoesntHaveWorkPermit:
console.log('nope');
break;
case userHasReactExperience:
console.log('Hire!');
break;
case userHasVueExperience
&& userCanStartInstantly:
console.log("Hire, if they can start instantly");
break;
default:
console.log('maybe');
}
More of an Angular fan myself so userHasAngularExperience is going to be added 😎 but much better example, thnx!
Snippet was updated!
Honestly you made me really curious about the performance... The switch normally are the first choice to avoid writing long if-else chains because the code "jumps" directly to the right place without evaluating all the other conditions... I'm curious to understand if also in this case these considerations are valid or not... I'll try and, if so, it will be an heart
I don't expect any performance gains but I'm looking forward to your findings!
👎
With that out of the way I do think it's worth hypothesising how code like this may have come in to being.
But even before that I'm surprised nobody claimed primitive obsession given that there are five distinct boolean values on the "loose".
Seems the more likely scenario should be something like:
With that reorganization my next guess should make more sense. I suspect the
switch(true)
is a degenerate form of some copy-pasted code that was trying to approximate pattern matching.While a number of languages support pattern matching, JavaScript only supports destructuring assignment — not pattern matching:
There is a TC 39 proposal to add pattern matching to JavaScript (which hasn't moved beyond stage 1 since 2018). Meanwhile there are some third party libraries available that approximate some pattern matching functionality.
Using Pattern Matching:
The actual proposal has much richer functionality that would allow for the aggregation of all the "accept" patterns. But if you squint, that
when
(ormatch
) is reminiscent of aswitch
.There is another way to represent boolean values - as bit flags.
Using bit flags/field operators:
Again
interviewStatus()
is somewhat reminiscent of aswitch
statement wrangled to behave like an expression.One final point: readability.
It's kind of interesting how many comments claim that
if
based solutions are more readable. Personally I find that most of theif
based proposals require a prolonged mental parse to just get the gist of the code. Obviously readability is a lot more subjective than most people are willing to admit.Using the nullish coalscing operator:
In my view:
Now I'm certain there already is a queue of people forming getting ready to drop a ton of bricks on me, how they don't find the above code readable at all.
That's not surprising — something is only judged as "readable" if it is already familiar. Anything unfamilar to an individual is also not as readable because of the additional cognitive effort that is required to read it.
In natural langauge there is the notion that
However
Going further
So just because something isn't deemed "readable" by a certain group of people doesn't necessarily imply that it is unreasonable.
From that point of view it's important to get exposure to a broad spectrum of programming styles (preferably across languages from different programming paradigms) — with that exposure a lot more code becomes "readable".
I can't believe some people put hearts
I liked this post, not because I think
switch (true)
is a good paradigm (it isn't), but because the post itself is interesting.The author isn't saying "you should use
switch (true)
in your code", they're saying "let's have a discussion about whetherswitch (true)
is acceptable". IMO, that's a useful discussion!That's the fun of this item 😊
It shows it's important to keep an open mind!