DEV Community

I've never become overly convinced that switch statements are that much cleaner than `if else if else if else if else`

Ben Halpern on June 28, 2019

I sort of know that switch statements are typically considered a good idea when chaining together a lot of else if statements. I'm not against this...
Collapse
 
yaser profile image
Yaser Al-Najjar • Edited

That's why we never have switch in Python 😁

And, the dictionary is always a better and cleaner alternative for the ugly switch.

def my_switcher(x):
    return {
        'a': 1,
        'b': 2,
    }[x]


print(my_switcher('a'))
print(my_switcher('b'))
Enter fullscreen mode Exit fullscreen mode
Collapse
 
gidrek profile image
Giovanni Cortés • Edited

Elixir :)

def my_switcher("a"), do: 1
def my_switcher("b"), do: 2
def my_switcher(), do: 3

iex(1)> Example.my_switcher("a")
1
iex(2)> Example.my_switcher("b")
2
iex(3)> Example.my_switcher()
3
Enter fullscreen mode Exit fullscreen mode
Collapse
 
kip13 profile image
kip

Pattern matching to the rescue ?

Thread Thread
 
cescquintero profile image
Francisco Quintero 🇨🇴

Isn't this feature called method overloading ? 🤔

Thread Thread
 
gidrek profile image
Giovanni Cortés

No, because overloading is have same parameters with different types, but in patter matching you can have the same type and number of parameters but differs in the content. For example, here!

Collapse
 
seanwash profile image
Sean Washington

I quite like cond as well for certain situations as well.

Collapse
 
renegadecoder94 profile image
Jeremy Grifski

Whenever I think about why I don't like a certain way a language does something, I realize it always goes back to my love for Python. That language has ruined me. haha

Collapse
 
yaser profile image
Yaser Al-Najjar

❤ for the utmost ruining lang.

Collapse
 
lysofdev profile image
Esteban Hernández

How would you handle a default case in this?

My though is to add || defaultValue at the end since a failure to match any property will return undefined. Thoughts?

Collapse
 
yaser profile image
Yaser Al-Najjar • Edited

That would be handy using a try except:

def my_switcher(x):
    switches = {
        'a': 1,
        'b': 2,
    }
    default = 3

    try:
        result = switches[x]
    except KeyError:
        result = default

    return result



print(my_switcher('a'))
print(my_switcher('b'))
print(my_switcher('c'))

I added the extra default variable just to make the code self explanatory.

EDIT: Bad solution, look at the other comments.

Thread Thread
 
rhymes profile image
rhymes

You can also use defaultdict in the standard library :D

Thread Thread
 
pedromendes96 profile image
Pedro Mendes • Edited

This is clean :D

Thread Thread
 
lysofdev profile image
Esteban Hernández

This is the answer to this entire thread.

Thread Thread
 
yaser profile image
Yaser Al-Najjar

@rhymes and @pedromendes96 got it better than me 😁

Collapse
 
kylegalbraith profile image
Kyle Galbraith

Really love this pattern. I have seen various approaches to the default case that vary across languages.

Collapse
 
kspeakman profile image
Kasey Speakman • Edited

The main detractor with if statements is that you have to reduce your logic down to booleans, which can later be hard to trace through. But, switch statements do not go far enough to help the situation either. Reducing your logic down to integers or strings is not that much better of an abstraction. Both force you to reduce the expressiveness of your solution down to a primitive level.

This is a reason I am a big fan of Union types, which allow you to explicitly model your logically different cases along with their different related data. Combined with pattern matching, you can branch off those logical cases as-is. My favorite language which supports this is F#.

Collapse
 
cubiclebuddha profile image
Cubicle Buddha

Kasey, I have a question for you since I’m interested in F#. I use union types all of the time in TypeScript, but I often “unpack” (for a lack of a better word) the union by using an if statement. It’s really convenient since TypeScript has excellent control flow analysis and therefore discriminates the union so you know that it is only the one type.

So do you still prefer the functional approach for discriminating the union even in languages that can clarify the resulting type?

(I’m sorry if this question isn’t more clear. I suppose I’m suggesting that if statements are fine since I think the left/right monad thing very confusing)

Collapse
 
kspeakman profile image
Kasey Speakman

Typescript union types are a bit different from those in F#. There is a tradeoff made between them. Union declarations are more or less anonymous in Typescript, whereas F# requires you to create a Discriminated Union with explicit tags. So, the Typescript feels a little nicer on declaration. However, when you unpack the union type, I believe F# has the advantage. Using match you can get auto-completion of the cases and warning when all cases are not exhaustively matched. It also provides access to the value as the appropriate type.

Examples:

// TypeScript
function padLeft(value: string, padding: string | number) {
    if (typeof padding === "number") {
        return Array(padding + 1).join(" ") + value;
    }
    if (typeof padding === "string") {
        return padding + value;
    }
}

// usage
let foo = padLeft("padded", 4);
// "    padded"
let bar = padLeft("padded", "bar ");
// "bar padded"
Enter fullscreen mode Exit fullscreen mode
// F#
type Padding =
    | Text of string
    | Spaces of int

let padLeft padding str =
    match padding with
    | Text prefix ->
        prefix + str
    | Spaces count ->
        String.replicate count " " + str

// usage
let foo = padLeft (Spaces 4) "padded"
// "    padded"
let bar = padLeft (Text "bar ") "padded"
// "bar padded"
Enter fullscreen mode Exit fullscreen mode

So, I feel like the latter is a better expression of intent in the long run. Even though it requires an extra type declaration, the type declaration adds some value for readability. It is more clear what the code is going to do with "string | number" when labeled as Text and Spaces.

For F#, I also swapped the order of arguments so that padLeft would be chainable with other string functions using pipe (|>).

Thread Thread
 
cubiclebuddha profile image
Cubicle Buddha

What a wonderful response. Thank you for being generous with your time to write that thoughtful response. You should post that as it’s own article so more people can benefit from it. :)

Collapse
 
nepeckman profile image
nepeckman

For me its about using the semantics of the language to communicate as much information as possible to other developers (and my future self). Its the same reason I prefer map, filter, reduce over for loops. By using switch instead of else if, I communicate a more specific action is taking place: dispatch over a single value. It's a small thing, but its also easy to do and makes my code a little more compact, so why not?

Collapse
 
sergix profile image
Peyton McGinnis

Having the fallthrough can be nice for certain cases when you want to keep your code DRY or want to avoid a ton of || operators in your if statement.

The switch operator can be much cleaner than if though, notably for small return statements. For example:

switch (x) {
  case 'a': return 1;
  case 'b': return 2;
}
Enter fullscreen mode Exit fullscreen mode

is much cleaner than

if (x === 'a') {
  return 1;
} else if (x === 'b') {
  return 2;
}
Enter fullscreen mode Exit fullscreen mode

Of course, it does come down to personal taste, but since languages provide the operator in the first place there's obviously a reason for it.

Collapse
 
michaelbrooks profile image
Michael Brooks

If you're returning then you don't even need the else.

if (x === 'a') {
  return 1;
}

if (x === 'b') {
  return 2;
}
Enter fullscreen mode Exit fullscreen mode

Actually looks a bit tidier to me and still very explicit.

Collapse
 
andrewharpin profile image
Andrew Harpin

Depends on the language, but for safety critical code, multiple function exits are typically frowned upon.

Thread Thread
 
cheetah100 profile image
Peter Harrison

Nah. Exit early. Makes the code cleaner and clearer.

Thread Thread
 
scott_yeatts profile image
Scott Yeatts

Gotta respectfully throw out a dispute. I've heard this statement used to justify multiple returns before... Looks like

if (x) {
    return a + x
} else if (y) {
    return a + y
} else {
    return a
}
Enter fullscreen mode Exit fullscreen mode

With the justification that it avoids evaluating the additional conditionals if the first proves true.

I just don't think the performance loss is there barring some REALLY funky conditionals or some other code smell...

This is a rule that feels like it came from the old C days and just stuck around past it's expiration date, because that same logic, but expressed as

if (x) {
    a = a + x;
} else if (y) {
    a = a + y;
}

return a;
Enter fullscreen mode Exit fullscreen mode

Is so much more readable and you can look at one line to know what's going to be returned, then you only have to debug/watch one thing, and it's just SO much cleaner... If I run into a problem with evaluating conditionals to get syntax that clean, then I feel like something else is wrong in the code... It's also more bug resistant and ensures that the method is doing ONE thing. Less chance that someone can come along and decide to start returning Strings instead of ints in one of the return statements or something wacky like that...

Thread Thread
 
cheetah100 profile image
Peter Harrison

In the real situations I encounter the issue is that having early returns means being able to avoid huge indents. When reading code where the return is at the bottom of a long complex structure you are forced to parse the entire function to ensure there is no subsequent operation which influences the return value. Having one return value generally means having the return variable declaration at the highest level, and so it could potentially be modified through the function. You might intend for it not to be modified once set, but a later modification might overwrite it. A early return is syntactically a succinct expression of the intent. We are finished. Return this value now. I know that in the early days of programming there was a good reason not to return early, especially in the middle of a loop. Don't think there is any issue at all with this any more.

Thread Thread
 
scott_yeatts profile image
Scott Yeatts

I could easily see if I'm dealing with a returnable statement over 20 lines where the return value is based on multiple conditionals or is impossible to keep in your head all at once, that return early and often would be a good backstop to make sure you know what is returned and when... And I HAVE run into code like this in the wild that I couldn't refactor entirely for stability, but I could make sure it was readable, and that did involve applying Exit Early.

With new code or things I could refactor, I would have to go with Uncle Bob's rule from Clean Code

The first rule of functions is that they should be small. The second rule of functions is that they should be smaller than that. Functions should not be 100 lines long. Functions should hardly ever be 20 lines long.

If you're dealing with multiple nested conditionals or the triangle of death where nesting is making the indents move out and out until your code looks like an arrow pointing off to the right, then the function is probably just too big and needs to be broken up for maintainability...

But now we're going to get so far off the topic we'll need to write a whole new topic to keep this up hahaha!

Thread Thread
 
cheetah100 profile image
Peter Harrison

I broadly agree with the idea that functions should be small, but care should be taken not to break up logically sequential operations that really belong together just to comply with this principle.

More important to me is that a function should have one clearly defined purpose and not mash together a bunch of logically separate operations.

Switches tend to be used for doing multiple separate things based on some value. It is not always bad, but I always evaluate whether there is a better more extensible way to do it than a switch when I see it.

I'm not saying I've never used a switch, but it is generally not one I use unless there is a really good reason.

Collapse
 
sergix profile image
Peyton McGinnis

Ah, true. I'm an idiot.

But for me, I still prefer the inline look of the switch statement. Again it's up to preference though.

Collapse
 
cubiclebuddha profile image
Cubicle Buddha

I don’t think fallthrough in a switch case is ever appropriate due to the potential for buggy side effects. I describe that in this article and I’d love to hear your thoughts on if you agree: dev.to/cubiclebuddha/is-defensive-...

Collapse
 
sergix profile image
Peyton McGinnis

I absolutely agree with your point. default/else cases should be used for error handling in most instances.

However, I should have clarified, so the fault is on my behalf, but when I said "switch 'fallthrough'", I meant when you have a situation like the following:

switch (x) {
  case 'a':
  case 'b':
    return 1;
  default: throw(); break;
}
Enter fullscreen mode Exit fullscreen mode

Here, it's easier (for me, at least) to see which possible values return 1 than this:

if (x == 'a' || x == 'b') {
  return 1;
} else {
  throw();
}
Enter fullscreen mode Exit fullscreen mode

I'm probably missing another thing you can do with if statements to make it more clear. But, after all, this is #healthydebate... So tell me how I'm wrong! :P

Thread Thread
 
cubiclebuddha profile image
Cubicle Buddha

Those examples your provided look great to me. I just don’t like when code assumes that there will never be a new case. I explain that a little better in my article. But it looks like you’re covering the known cases. So great work! :)

Collapse
 
samuraiseoul profile image
Sophie The Lionhart • Edited

Switches as well as conditionals with many branches(else ifs) are generally indicative of a different issue all together.

Switches can be a good choice in the case of a clearly defined unchangeable list of things to check against, like days of the week(I pray to god there will only be seven in the future too). They are also sometimes good in the case that you actually have found a use case for the fall through effect you get when you don't use a break. Switches also are very hard to do in a way that enables defensive programming. It's easy for a switch to have 4 or 5 cases, then someone comes in and adds one, comes in and adds another, then another, until you have a giant mess of cases.

Generally, like @rossholloway94 mentioned, Enums are a much better fit. The way that @0xrumple showed in python can be done in many other languages that don't have real Enums, but is essentially an Enum as well. Alternatively, in certain use cases, something like a rule matcher and handler can be a better fit.

class Foo implements RuleHandler {
    public function canHandle(condition) : bool {
        if(condition === something) { return true; }
   }

   public function handle(thing) : Bar {
        return thing.thing() + thing.otherThing();
   }
}
Enter fullscreen mode Exit fullscreen mode

Using a switch can also be indicative that whatever logic you're doing in the switch, is really something that should be on each class to implement which can be similar to the model above. Basically the Strategy design pattern.

//instead of this
function doThingsThing(thing: Thing) : void {
  switch(thing.val) {
    case 1 { thing.a + thing.b; break; }
    case 2 {thing.a * thing.b; break; }
    // more cases
    default { //this should never happen }
    // NEVER DO THIS TO A DEFAULT IF IT SHOULDN'T HAPPEN THROW AN ERROR
  }
}

//this
function doThingsThing(thing : Thing) {
  thing.doThing();
}

abstract class Thing { abstract function doThing() : Thing; }
class Thingy extends Thing { function doThing() : Thing {this.meh = 2; return this; } }
class OtherThingy extends Thing { function doThing() : Thing { this.meh = this.meh * 2; return this; } } 
Enter fullscreen mode Exit fullscreen mode

The reason a switch never feels better than many else ifs is because they are basically the exact same thing. The kind of feel that gets hammered in a lot of beginner tutorials that explain switches is something like "If you have a lot of conditions, use a switch!" and also the examples show how to convert a thing with a lot of else if statements into a switch.

One more time for clarity:

  • Consider using an if in the case that:
    • There are a TRULY finite number of cases
    • The fall through logic will really help(though there are OOP ways of handling this too that I didn't show)
  • Some switch alternative candidates are:
    • Enums
    • Rule Handler matchers
    • Interfaces in classes
Collapse
 
yaser profile image
Yaser Al-Najjar

Enums are also good, but they might not fit in cases where there is no ordinal values.

Don't get offended, but the rule handler matcher / OOP ways to return a value reminds me of this meme:

deep-learning

Collapse
 
samuraiseoul profile image
Sophie The Lionhart • Edited

Haha no offense at all. The rule handler is overkill in A LOT if not most scenarios. That said, it's for sure one of the patterns you would use instead of a switch so I included it. For the trivial example I have though, yeah way overkill. For the slackbot I made a while back I used it and it worked well. github.com/samuraiseoul/starbot/bl... and github.com/samuraiseoul/starbot/bl... are an example where it works well.

Thread Thread
 
yaser profile image
Yaser Al-Najjar

Aha... Heck yeah, this example is pretty solid 👌

Collapse
 
eerk profile image
eerk • Edited

Excellent point! Sometimes you may need lots of if statements, but more often than not, lots of ifs are a sign that your code is just too procedural. By abstracting away code in functions or classes you can often get rid of them.

Collapse
 
renegadecoder94 profile image
Jeremy Grifski • Edited

Personally, I oppose switch statements because they force you to opt-in to break rather than breaking by default (i.e. use continue for fallthrough). I feel like every time I write a switch statement I forget a break on one of the cases. Then, I'm stuck exposing that fallthrough case during testing. In contrast, you don't really get that same ambiguity with if/else if/else.

Collapse
 
taillogs profile image
Ryland G

In terms of performance, it never practically matters. For sake of the argument, switch is much faster if you have a large number of cases and slightly slower with small number of cases. The compiler is aware of the number of cases and will convert the switch statement into a constant lookup time hash table once it exceeds a threshold. But once again, for 99.999% of code, the difference between the two will never be meaningful.

I personally think that they are used differently, and that using them both is actually the best option. If/Else can be used very broadly, but with switch it's pretty niche. It's essentially a jump table that's useful when you have a ton of outcomes given some input. When I see a switch, I immediately know the class of problem it's trying to solve. With if/else, it could be much broader.

Collapse
 
andrewharpin profile image
Andrew Harpin

A good optimiser will use the optimal output for the size of the operation, irrelevant of the code statement.

Collapse
 
taillogs profile image
Ryland G

I'm sorry but this is a really uneducated comment.

Collapse
 
val_baca profile image
Valentin Baca

Swift's switch is the only one that I think gets it right. It provides enough simplicity and usability to warrant use over if-else chains.

From docs.swift.org/swift-book/Language...

  • compund cases case "a", "A":
  • interval matching case 1..<5:
  • tuples switch point: case (0, 0)
  • value binding case let(x, y)
  • where checks
  • explicit fallthrough

Granted, each of these can still be done with if-else, I like the convenience of it all.

Collapse
 
jeikabu profile image
jeikabu • Edited

This here. switch in some languages (like F#, rust, and apparently swift- amongst others) has additional "powers".

In C# 8 you can also use it as an expression:

return x switch {
  0: something,
  // More
  _: whatever,
};

Otherwise it's main advantage is clarity for large numbers of options and optional fall through (double-edged sword that it is).

if (x == 0) {
  return something;
} else if (x == 1) {
// 10 more cases
else {
  return whatever;
}

// vs
switch (x) {
  case 0: return something;
  // 10 more
  default: return whatever;
}

Regardless what you do with your brackets/whitespace, the switch logic is clearly only about the value of x.

Also, historically compilers were more likely to turn it into a jump table rather than chain of branches.

Collapse
 
theringleman profile image
Sam Ringleman • Edited

Considering it rapidly speeds up your conditional statements, I will always use a switch statement. A switch statement acts as though you are accessing an array via an index. Whereas an elseif statement has to process each conditional statement until it passes.

Collapse
 
andrewharpin profile image
Andrew Harpin

Depends on if scripted Vs compiled.

A compiler will optimise into either the conditions or a jump table depending on the code. Usually for both switch and if else

Collapse
 
theringleman profile image
Sam Ringleman

As someone who has never had the chance to jump into a compiled language, this is wonderful information! Thank you for the correction.

Collapse
 
theringleman profile image
Sam Ringleman

Of course this depends on the context of the application though. If I am checking against static values, then my previous statement is true.

Collapse
 
alanmbarr profile image
Alan Barr

I much prefer pattern matching like in F# to switch statements. Eevee did an interesting blog on the history of the switch statement. I dislike the fallthrough behavior and find it visually displeasing in a code base.

Collapse
 
renegadecoder94 profile image
Jeremy Grifski

Thanks for the article! That was a quality read. Gave me a more clear explanation of why I don’t really like switch statements. Haha

Collapse
 
rossholloway94 profile image
Ross Holloway

I feel that with Java, if you have a switch statement, each condition can probably be modelled by an enumeration. And if that's the case, that can be refactored so that each enum type has a common abstract method to be called.

Collapse
 
nicpolhamus profile image
Nicolas Polhamus

When I'm adding some new functionality to something the main thing I'm concerned with us maintainability, and a big part of that is code readability. If statements are easier to document, at least in my opinion, and they do a better job at being representative of their purpose and the current context of the code.
Switch blocks can certainly be contextual and representative, but it takes more effort to ensure that the context and logic are properly represented. I will say, that fallthrough can be very useful in the right scenarios.

Collapse
 
andrewbrown profile image
Andrew Brown 🇨🇦

In ruby case statements feel less verbose, less prone to error since the intention is to validate a single statement against multiple outcomes and is more human readable.

With linting case statements are one way to still have compact code.

Everything has its utility.

if    status == :active     { '/active'}
elsif status == :incomplete { '/incomplete'}
elsif status == :suspended  { '/suspended'}
end

case status
when :active     then '/active'
when :incomplete then '/incomplete'
when :suspended  then '/suspended'
end
Enter fullscreen mode Exit fullscreen mode
Collapse
 
aromig profile image
Adam Romig 🇵🇭

For me it depends on the situation really. If I have a definite limited set of values I'm looking for, I may use a switch. To me, it can be easier to read the values down a column with it. If I'm looking for boolean conditions, the if will probably be the best. But just depends.

Collapse
 
anwar_nairi profile image
Anwar

I am not a big fan, it forces me to use break a lot... Good old if... else never failed me so I am being faithful 😁

Collapse
 
powerc9000 profile image
Clay Murray • Edited

I like switch for when I return because you skip out on so much boilerplate over and over.

switch(something){
case "this":
    return 1;
case "that":
    return 2;
default:
    return 0;
}
Enter fullscreen mode Exit fullscreen mode

Just feels much easier to type than

if(something === "this"){
    return 1;
} 
if (something === "that"){
    return 2;
}

return 0;
Enter fullscreen mode Exit fullscreen mode

You have to keep typing something === over and over and I dislike that.

The speed etc is not important to me.

Collapse
 
cubiclebuddha profile image
Cubicle Buddha

I often see that developers enjoy that approach until they run into a nasty bug down the line. I describe a bug like that here and I’d love to get your perspective on if my defensive coding approach I describe would be beneficial to you.

Collapse
 
jckuhl profile image
Jonathan Kuhl

I hate switch. And I hate that most languages make fallthrough the default behavior for switch. I love that Swift decided to instead implement a "fallthrough" keyword, because I find that fallthrough is the cause of 99% of most switch problems.

In JavaScript, I find using objects is a good alternative most the time.

const days {
  monday: "Monday";
  tuesday: "Tuesday";
  // . . . etc
}

const today = days[monday];
Enter fullscreen mode Exit fullscreen mode
Collapse
 
gabrielweidmann profile image
Gabriel Weidmann

In C# I mostly use switches together with enums. Why?

First because if you use the switch code snippet it will generate you a switch-case with all enum parameters, e.g.:

public enum Values
{
    A,
    B,
    C
}

static void Switch(Values value)
{
    switch (value)
    {
        case Values.A:
            break;
        case Values.B:
            break;
        case Values.C:
            break;
        default:
            break;
    }
}
Enter fullscreen mode Exit fullscreen mode

Second if you add a new case it will automatically suggest to use a value of the enum and typecheck the cases, e.g. you couldn't use a string.

Collapse
 
gklijs profile image
Gerard Klijs

Since Java 8 I don't use switch case anymore for Java. I find it much more readable to create a functional interface, and add it to the enum. For example if you have an enum with different types of messages, and you want to correct topic for that type depending on some TopicConfiguration class. You can add a lambda config -> config.emailTopic to all the enums. Reducing it to just a single function call on the enum when needed.
In Rust there not even is enum, there is match which is more powerful. And you can use traits to get the same kind of construction as described for Java.

Collapse
 
cheetah100 profile image
Peter Harrison

The main danger is the need to place a break; inline to prevent execution flowing through to the next block. Never found this very consistent with other conditional structures. Basically just an opportunity for a bug. It is also often abused, in that we don't want large conditional blocks of code. Usually there are better ways.

Collapse
 
sierisimo profile image
Sinuhe Jaime Valencia

In kotlin we don't have a switch, we have a when operator:

fun doSomething(x: Int){
    when {
        x == 1 -> 
        x == 2 -> 
        else -> 
    }
}

It can take a parameter to match:

fun doSomething(x: Int){
    when(x) {
        1 -> 
        2 -> 
        else -> 
    }
}

And also you can put different stuff there…

fun doSomethingWithAFoo(foo: Foo){
    when(foo){
        is SubFoo -> {
          //…
        }
        foo.someProperty == someValue -> 
        else -> 
    }
}

in the case of is SubFoo you get auto-cast. So you can use foo as a SubFoo


For me more than 3 else-if will complicate the reading of the code and in some languages will get you a wrong scenario…

Like the kotlin syntax that actually doesn't have an else-if expression (yes, in kotlin is an expression) so you can end in weird places:

github.com/angryziber/kotlin-puzzl...

In kotlin else if(…) is actually: else { if() }

So that's one reason at least to prefer when over else-if in kotlin.

Collapse
 
mnivoliez profile image
mnivoliez • Edited

Syntactically, a switch statement express that you work with a limited set of option and only those.

For example, let say you have a mammal and you need to make a specific treatment depending if it's a cat, dog or a bird person (yes bird person are mammal laying eggs, just like the platypus).

As you got a limited set of supported mammals, I'll go for the switch as it is the syntax to express that you handle only that set.

match mammal {
  "dog" => pet_dog(),
  "cat" => judge_cat(),
  "bird_person" => make_dick_move()
}

In comparison, the "trick" with dictionary is making a structure wearing the meaning of a syntax element. I will not advocate against it nor will I support it. It may have some use but bear in mind the "semantic" trade off you are making.

It could be interesting to see if the switch statement is more efficient than a if else (and honestly it depends on so many option that I'm not even sure it will be relevant) but at the very least it tells other programmers "here we work only with those possibilities and only them".

Collapse
 
jessekphillips profile image
Jesse Phillips

Yeah while I reach for them often I usually only see benefits in a few cases

final switch(some enum)

This means all enum values must have a case, no default.

switch (arg) {
static foreach(...) 
Case t....

Now I can build my cases at Compile time and don't need to hand the first if or start with else.

But these are only things you find in D.

Collapse
 
kunde21 profile image
Chad Kunde

This entirely depends upon the language in which I'm working.

I'm pretty gun-shy about switches in C, especially when they are interacting with macros. Pre-processing magic is a nightmare to debug, especially when a typo accidentally eats the break.

Python I don't mind the ifelse design as much That's usually for data science-y code, so readability is rarely a high priority.

Go I'll use switch quite often. Between the assumed break and explicit fallthrough, it's just easier to read than the sibling in C. There's a few ways to make things easier and easily identified patterns. One of my favorite is a simple string check:

func something(multiple, required, variables string) error {
    switch ""{
        case multiple, required, variables:
            return errors.Errorf("all variables required %q %q %q", multiple, required, variables)
    }
    // brilliant logic here
}

I think Swift has a similar style switch statement, too, that is more useful that the default C switch design. (Could be wrong, I don't write Swift)

Collapse
 
stemmlerjs profile image
Khalil Stemmler

I only use switch statements in two scenarios:

A: I'm using an Abstract Factory for something.

public class PokemonFactory {
  public static createPokemon (type: PokemonType): Pokemon {
    switch (type) {
       case 'pikachu':
         return new Pikachu();
       case 'charizard':
         return new Charizard();
       case 'squirtle':
         return new Squirtle();
       default:
         return null;
    }
  } 
}

B: If I'm writing reducers in redux

   switch (action) {
     case actions.FETCHING_PROFILE:
     case actions.FETCHING_PROFILE_SUCCESS:
     case actions.FETCHING_PROFILE_FAILURE:
     case actions.SUBMITTING_PROFILE:
     case actions.SUBMITTING_PROFILE_SUCCESS:
     case actions.SUBMITTING_PROFILE_FAILURE:
        return { ...state, profile: profileReducer(state.profile, action);
     default:
        return state;
  }

Imagine the OR pipes if that last one was made using if statements. Being able to match many cases at one time saves so much typing.

Collapse
 
napoleon039 profile image
Nihar Raote

A while back in college, I read somewhere that when there are a similar number of conditions in an if-else block and a switch statement, the switch statement is faster.

Recently, during a FreeCodeCamp JavaScript section project, I had to use a bunch of conditions (I know it could have been done in a better way) in multiple functions. I decided to try using switch statements since that would apparently be faster. But as soon as I wrote the first function, I realized that although it would be faster, it looked ugly. I used good old if-else blocks in the other functions.

And although I had to think quite a bit about the order of the conditions, it looked a bit cleaner than the former.

For me, I would use if-else blocks instead of switch statements until it's absolutely necessary. This was btw my first use of switch statements in around 2 years since last I used them in college.

Collapse
 
johnfound profile image
johnfound • Edited

It depends on the language syntax where switch is used.

For example, the "case" operator in Pascal does not fall-through (which is a serious problem in C-kind of languages).

In addition, the switch can be internally implemented in different way than a chain of ifs. For example with hash table, which can be much faster in the cases when you want to compare big amount of strings.

Collapse
 
gazzonyx profile image
Scott Lovenberg

Switch statement runtime : O(1)
If/Else : O(n)

If your operating system drivers used if/else for polling/events, your network card would be running at a fraction of the speed it does. Sometimes performance matters. The original Linux scheduler was O(log n) which was replaced with two linked lists for a O(1) runtime since the log n scheduler was deemed too slow for process scheduling.

Collapse
 
wincentbalin profile image
Wincent Balin

AFAIK the compilers for embedded systems translate the switch-statements to jump tables, hence we might perceive this construct as an abstraction for a certain low-level structure(s).

Of course, looking from the developer's perspective only it is just an oversized if..else if..else-statement with indentation problems.

Collapse
 
juancarlospaco profile image
Juan Carlos

They are different, switch (or case) is a Multi-Branch flow.
Compiled languages can optimize switch a lot more than if.

Collapse
 
foresthoffman profile image
Forest Hoffman

Dos Equis Man

But in all seriousness, I do really only use switches to save typing. It just feels cleaner to me for handling lots of really simple comparisons.

Collapse
 
johnpaulada profile image
John Paul Ada

I agree for most languages. But the pattern matching switch in ReasonML and Elixir is awesome!

Collapse
 
jrop profile image
Jonathan Apodaca

Pattern matching for the win! That aside, switch statements are more easily readable than long if-else-chains when comparing against constants. As always, readability is subjective.

Collapse
 
bvmcode profile image
bvmcode

All redux reducers just gasped

Collapse
 
cristinasolana profile image
Cristina Solana

I always favor objects over switch statements. There are only very rare occasions when an object won't work.

Collapse
 
lysofdev profile image
Esteban Hernández

Just like for loops started to disappear after ES6 (or ES5?) brought in .map, .reduce, .filter, and .forEach, I think the switch statement doesn't quite fit in to modern JS.

Collapse
 
brandonskerritt profile image
Autumn

I use Switch statements a lot for mundane things, such as this:

a: 1
b: 2
c: 3
d: 5
e: 8

and so on but that's about it

Collapse
 
steelwolf180 profile image
Max Ong Zong Bao

I'll pick if statements over switch in a heartbeat. Never missed it when I'm programming in Python daily at work.

Collapse
 
nektro profile image
Meghan (she/her)

I think the formatting typically used for both if else and switch statements doesn’t do either of them justice so I’ll make another comment once I’m back at my computer

Collapse
 
wolverineks profile image
Kevin Sullivan

Why no nested ternary love?

Collapse
 
mortoray profile image
edA‑qa mort‑ora‑y