DEV Community

loading...
Cover image for βœ”||🀒 Commit or Vomit | Switch(true)

βœ”||🀒 Commit or Vomit | Switch(true)

jmdejager profile image 🐀πŸ₯‡ Jasper de Jager ・Updated on ・1 min read

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.


switch(true){
    case userMissedAppointment:
        return 'nope';
    case userHasAngularExperience:
    case userHasReactExperience:
    case userHasVueExperience && userCanStartInstantly:
        return 'hire';
    default:
        return 'maybe'
}
Enter fullscreen mode Exit fullscreen mode

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! 😎

Discussion (51)

pic
Editor guide
Collapse
siddharthshyniben profile image
Siddharth • Edited

This could easily have been an if/elseif/else.

You could have done:

if(someExpressionA) console.log('yes')
else if ((someExpressionB 
    && someExpressionC) || someExpressionD) console.log('nope');
else console.log('maybe');
Enter fullscreen mode Exit fullscreen mode
Collapse
basbenik profile image
Bas van Baalen

I'm not sure it's because of the editor, but I would suggest to use more lines for more readability and easier comprehension.

if(someExpressionA) 
  console.log('yes')
else if ((someExpressionB && someExpressionC) || someExpressionD) 
  console.log('nope');
else 
  console.log('maybe');
Enter fullscreen mode Exit fullscreen mode

For me this already reduces the cognitive load a lot quickly see what can happen.

Collapse
jmdejager profile image
🐀πŸ₯‡ Jasper de Jager Author

Good point for a next Commit or Vomit! What do you think about switch(true) in general?

Collapse
siddharthshyniben profile image
Siddharth

Actually I typed my comment on mobile, so I didn't format it

Collapse
jmdejager profile image
🐀πŸ₯‡ Jasper de Jager Author

true, this is a short example. Apart from this example would you never commit a switch(true)?

Collapse
siddharthshyniben profile image
Collapse
lukaszahradnik profile image
LukΓ‘Ε‘ ZahradnΓ­k

Well I wouldn't commit your code, because it had inlined blocks

Collapse
siddharthshyniben profile image
Siddharth

I'm on mobile so I didn't really format anything

Thread Thread
jmdejager profile image
🐀πŸ₯‡ Jasper de Jager Author

It was sufficient to make your point 😊 no worries.

Collapse
jmdejager profile image
🐀πŸ₯‡ Jasper de Jager Author

I'd really like the discussion to be about the switch(true) and not about the code in comments. The code posted gives a good idea about why he voted vomit. It is not the code up for discussion.

Thread Thread
siddharthshyniben profile image
Siddharth • Edited

You're right. Switching true just adds a few extra lines and makes us momentarily think "is it a typo? Why would you switch true". At least I did when I first saw a switch(true)

Thread Thread
lukaszahradnik profile image
LukΓ‘Ε‘ ZahradnΓ­k

I wanted to react to Siddhart's code and I don't see any reason why it shouldn't be up for discussion.

Thread Thread
jmdejager profile image
🐀πŸ₯‡ Jasper de Jager Author

Ok, just seamed off topic to me because of the style of the answer I guess. You said I" wouldn't commit your code" that's why.

Collapse
jmdejager profile image
🐀πŸ₯‡ Jasper de Jager Author

good to mention: the example was updated after this reply

Collapse
jackmellis profile image
Jack

Since you're returning on each case I wouldn't even bother with elses...

if (useMissedAppointment) {
  return 'nope
}
if (userHasAngularExperience || useHasReactExperience || (userHasVieExperience && userCanStartImmediately)) {
  return 'hire'
}
return 'maybe'
Enter fullscreen mode Exit fullscreen mode

Of course I'd also extract that second conditon into another method, but that's another matter.

Collapse
nefomemes profile image
Nefomemes • Edited

Um, making it a bit inline is better imo.

if (userMissedAppointment) return 'nope';

if (userHasAngularExperience || useHasReactExperience || 
(userHasVieExperience && userCanStartImmediately)) return 'hire';

return 'maybe';
Enter fullscreen mode Exit fullscreen mode

The first line for the second if statement is too long imo. Turned it into two lines.

Collapse
jmdejager profile image
🐀πŸ₯‡ Jasper de Jager Author • Edited

My preference:

if (userMissedAppointment) return 'nope';

if (
  userHasAngularExperience 
  || useHasReactExperience 
  || (userHasVueExperience && userCanStartImmediately)
) return 'hire';

return 'maybe';
Enter fullscreen mode Exit fullscreen mode
Thread Thread
nefomemes profile image
Nefomemes

Oh yeah, I didn't thought that.

Collapse
jackmellis profile image
Jack • Edited

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!

Thread Thread
jmdejager profile image
🐀πŸ₯‡ Jasper de Jager Author

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 😎

Thread Thread
edave64 profile image
edave64

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.

Collapse
asdftd profile image
Milebroke • Edited

I think the cleanest and most expressive is still this


const hasFrontendFrameworkExperience = userHasAngularExperience || userHasReactExperience || userHasVueExperience;

if(userMissedAppointment){
    return 'nope';
} else if(hasFrontendFrameworkExperience && userCanStartInstantly){
    return 'hire';
}
return 'maybe';
Enter fullscreen mode Exit fullscreen mode
Collapse
jmdejager profile image
🐀πŸ₯‡ Jasper de Jager Author

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.

Collapse
asdftd profile image
Milebroke

You are definitely right :D Well in that case I wouldn't mind the right if else combo either

Collapse
aleksandrhovhannisyan profile image
Aleksandr Hovhannisyan • Edited

Why the need for the case statement?

if (userMissedAppointment) {
  return 'nope';
}
const userMeetsTechRequirements = userHasAngularExperience || userHasReactExperience || userHasVueExperience;
if (userMeetsTechRequirements && userCanStartInstantly) {
   return 'hire';
}
return 'maybe'
Enter fullscreen mode Exit fullscreen mode

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.

Collapse
jmdejager profile image
🐀πŸ₯‡ Jasper de Jager Author

Totally agree, but would you merge it if it was in a PR for instance?

Collapse
aleksandrhovhannisyan profile image
Aleksandr Hovhannisyan

Nope, I'd request changes here.

Collapse
indoor_keith profile image
Keith Charles

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.

Collapse
jmdejager profile image
🐀πŸ₯‡ Jasper de Jager Author

Totally agree! It's a code smell.

Collapse
serializator profile image
Julian van den Berkmortel

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.

Collapse
disgustingdev profile image
disgusting-dev • Edited

How about that (pre-enterprise example :))

//allocate in one place binding of all rules with results
const conditionsEnum = {
  nope: ignoringConditions,
  hire: hiringConditions,
  maybe: mbConditions,
}

let result = '';

//find first truth in there
for (let field in conditionsEnum) {
  if (conditionsEnum[field].some(condition => !!condition())) {
    result = field;

    return result;
  }
}
Enter fullscreen mode Exit fullscreen mode

values in object are just arrays of functions:

const ignoringConditions = [
  () => false,
  () => false,
  () => false,
]

const hiringConditions = [
  () => true,
  () => false,
  () => false,
]

const mbConditions = [
  () => false,
  () => false,
  () => false,
]
Enter fullscreen mode Exit fullscreen mode

Hope my nickname speaks for itself

Collapse
jmdejager profile image
🐀πŸ₯‡ Jasper de Jager Author

Hope my nickname speaks for itself

🀣🀣

Collapse
andreidascalu profile image
Andrei Dascalu

Vomit.
Either a verbose aggregation of desired Boolean checks OR return from currying some composable functions that return a similar aggregation.
I am slightly partial to the second as I believe anyone looking for FP would be.

Collapse
sirnino profile image
Antonino Sirchia

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

Collapse
jmdejager profile image
🐀πŸ₯‡ Jasper de Jager Author

I don't expect any performance gains but I'm looking forward to your findings!

Collapse
niorad profile image
Antonio Radovcic

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.

Collapse
jmdejager profile image
🐀πŸ₯‡ Jasper de Jager Author

Yes I agree, something to take into account for the next one in the series!
Thanks for the feedback 😊

Collapse
niorad profile image
Antonio Radovcic

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

Thread Thread
jmdejager profile image
🐀πŸ₯‡ Jasper de Jager Author

More of an Angular fan myself so userHasAngularExperience is going to be added 😎 but much better example, thnx!

Thread Thread
jmdejager profile image
Collapse
juanfrank77 profile image
Juan F Gonzalez

I wouldn't personally commit a switch(true) or let anyone do it for that matter so I'll choose vomit.

Collapse
edave64 profile image
edave64

This code definitely smells. So you have multiple conditions that are all mutually exclusive, but not similar enough that you can't just use a regular switch?

In any case, that's not what switch is for. If-else that stuff. Or, even better in this case, just if's because return ends control flow anyways.

Collapse
matjones profile image
Mat Jones

switch (true) please stop making inexperienced JavaScript developers think this is a good idea 😱

Collapse
siddharthshyniben profile image
Siddharth

I can't believe some people put hearts

Collapse
jmdejager profile image
🐀πŸ₯‡ Jasper de Jager Author

That's the fun of this item 😊
It shows it's important to keep an open mind!

Collapse
stevezieglerva profile image
Steve Ziegler

You can always (and probably should) refactor long bool expressions into a functions with descriptive names.

Collapse
lucianojung profile image
Luciano Jung

πŸ¦„nice idea love it
And of course vomit 🀒

Collapse
siddharthshyniben profile image
Siddharth

Looking forward to the next one.

Collapse
mahyargp profile image
Hossen Eki

no is not readable

Collapse
jmdejager profile image
🐀πŸ₯‡ Jasper de Jager Author

This was a tough one for me, I like the style, but if/else is easier to read and comprehend. so for me it's a 🀒

Collapse
jmdejager profile image
🐀πŸ₯‡ Jasper de Jager Author

and because this is the first:
Please leave comments if you see improvements for this item 😎