loading...
Cover image for Switch is ok

Switch is ok

macsikora profile image Maciej Sikora ・4 min read

It is ok (2 Part Series)

1) Tuples are ok 2) Switch is ok

Switch statement had lately some bad fame, some developers avoid it as possible, and others advocate to deprecate it. Almost as if it would be some anti-pattern to use it. To make you an example of the attitude, here are few articles:

This article will try to fight with common statements against switch. So here they go!

Switch is old and clunky

Yes Switch statement is old, if statement also is old, for loop is old too, but so what? Really what a strange argument it is. New and shiny doesn't mean better.

We're forced to manually add break

That's a kinda interesting take, as in all examples criticizing switch, the switch is shown with a break keyword. It is so by purpose, to make the counterexample looking better. So no, we don't need to use break, we can use switch with return only.

switch (x) {
  case "DC":
    return "Batman";
  case "Marvel":
    return "Wolverine";
  default:
    return "Spiderman"
}

Where is the break now?

Its not an expression

Yes, it's not. But wrapping it in a function will give us expression:

function hero(x) {
  switch (x) {
    case "DC":
      return "Batman";
    case "Marvel":
      return "Wolverine";
    default:
      return "Spiderman"
  }
}
const myHero = hero("DC");

It is emphasizing impure and procedural programming

You work with multi-paradigm language, where you can mutate everything, you can make any side effect whenever you want, and still make such argument? Purity in such language like JS is a coding practice only. If you want to write pure code, switch will not be any blocker, believe me.

It is error prone and likely to make some mistake

Really stop using Notepad. Please.

And update your Windows 8.

Use object literals instead of switch

Yes you can, I will not say that using literal is a bad idea. But saying that switch is much worse, is still overstatement. Consider both examples:

// switch
function hero(x) {
  switch (x) {
    case "DC":
      return "Batman";
    case "Marvel":
      return "Wolverine";
    default:
      return "Spiderman"
  }
}
// literal
function hero(x = "default") {
  const herosMap = {
    "DC": "Batman",
    "Marvel" : "Wolverine",
    "default": "Spiderman"
  }
  return herosMap[x];
}

Yes yes, I see how you look at the second, it is smaller, and there is this nice trick with default value, what a sexy thing. But, sexy should be your girlfriend/boyfriend, and not exactly your code. Smaller doesn't mean better 😂, when you look at both for sure you need a little more time for the second. Admit it!

These examples are isomorphic, there is no winner here. I don't see any issue in using one or another.

Switch statements are bad in OOP code

Yes, probably better will be your StrategyFactoryProducerPattern. But to be serious, there can be issues with OOP principles about polymorphism and switch. However do you write OOP code? If not those arguments are not a thing.

We can make some FP wrapper to never look at switch again

Why to use switch if you can function? Below example from the Eliminate the switch statement for better code article. You can make such:

const switchcase = cases => defaultCase => key =>
  cases.hasOwnProperty(key) ? cases[key] : defaultCase

const counter = (state = 0, action) =>
  switchcaseF({
    'INCREMENT': () => state + 1,
    'DECREMENT': () => state -1
  })(state)(action.type)

than simple

const counter = (state = 0, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return state + 1
    case 'DECREMENT':
      return state - 1
    default:
      return state
  }
}

Yes but first has no {, no explicit return and there is some partial application, notice how sexy this function is called twice at the end (state)(action.type). If this argument works for you, go sleep and read this code again, and I've already said who should be sexy 😉

Switch statement is ok

There is nothing wrong with switch statement, we can use it without the break keyword, it's very explicit and clean to see all possible branches inside the switch. If you think it's not functional programming if we use switch, then look at pure functional languages which have pattern matching. Take a look at below Elm code example:

hero x = case x of
  DC -> "Batman"
  Marvel -> "Wolverine"
  _ -> "Spiderman"

Yes, it is functional programming, and yes case of is expression, but it doesn't mean you should deprecate switch, use it, make it return in every case. Don't complicate things which should be simple.

Thank you.

Photo by Nick Nice on Unsplash

It is ok (2 Part Series)

1) Tuples are ok 2) Switch is ok

Posted on Apr 25 by:

macsikora profile

Maciej Sikora

@macsikora

I am Software Developer, currently interested in static type languages (TypeScript, Elm, Reason) mostly in the frontend land

Discussion

markdown guide
 

The best thing about switch statements is that you're not limited to strings.

function fun(data) {
  switch(data.constructor) {
    case Symbol:
      return 'You gave me a symbol';
    case String:
      return 'No strings attached';
    case Array:
      return 'To map or not to map';
    case Number:
      return 'something something 42';
    case Boolean:
      return 'is it true?';
    case Promise:
      return 'maybe, maybe not';
    case Function:
      return "Don't call us, we'll call you";
    case (async () => {}).constructor:
      return 'Ooh, fancy stuff';
    default:
      return 'what?'
  }
}

const some_fun = function() {};
const async_fun = async function() {};

fun(['hello']);
fun(74);
fun('this');
fun(Symbol('What?'));
fun(true);
fun(some_fun);
fun(async_fun);
 

Nice. Thanks for sharing

 

I am in the bandwagon of object literals over switches, I know it doesn't have a tremendous impact but combining it with some ES8 features like optional chaining and nil colascing makes it even better IMO:

const counter = (initialState = 0) => (action) => {
  const nextState = {
    'INCREMENT': () => initialState + 1,
    'DECREMENT': () => initialState -1
  }[action.type]?.() ?? initialState

return nextState
}
 

It goes to the point that switch is not expression. Don't get we wrong optional chaining and nulish colascing are great feature, but I don't believe using them as you have shown is a good example. It's just not needed here.

 

Hahaha I agree completely, specially nil colascing which would easily be replaced with a logical or instead, it’s just a personal preference

 

I've been in both camps before. I think I went at least 10 years without writing a switch/case anywhere. But in the last several years, I've actually come back to switch statements. It's not like I use them everywhere - or even, often. But I do use them. IMHO, the "proper" use-case for switches is whenever you are checking one variable against a set of known values. I do not like any use of a switch where people are trying to embed logic that goes beyond the basic idea of a switch.

Also, although I'm, admittedly, a Certified Redux Hater, it's hard for anyone to love Redux and hate switches. I've even seen Redux fanboys grumble about switches that are written outside of their reducers - but they're perfectly fine using a ton of switches inside their reducers. Such pedantic distinctions make little sense.

Railing against the use of switch makes no more sense than railing against a while loop. Are while loops usually the "right" choice?? No. But there are absolutely times when a while loop is the right choice.

 

Your example with the object literal is overly long:

const hero = (x = "default") => ({
    "DC": "Batman",
    "Marvel" : "Wolverine",
    "default": "Spiderman"
}[x])
 

I have waited for that 😉

 

New and shiny doesn't mean better.

Smaller doesn't mean better 😂, when you look at both for sure you need a little more time for the second.

I'm constantly telling those phrases to Kotlin fans :)

 

My favourite Javascript switch feature is the ability to use switch(true) followed by cases with with comparison operations.

Looks much cleaner compared to a lot of if/else.

 

Thanks for sharing, I really hate how some developers try convencing others to stop using something just because they don't like it (for some reason)

I love this series, keep going!!

 

Hi, cool article.

What do you mean by "It is not pure, and emphasize procedural programming". I don't see any way how switch itself (or the one in example above) is not pure.

 

Yes you are right, I have wrongly made a title of this paragraph. Changed already

 

Lodash _.cond with lodash/fp version for the win!