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...
For further actions, you may consider blocking this person and/or reporting abuse
That's why we never have
switch
in Python 😁And, the dictionary is always a better and cleaner alternative for the ugly switch.
Elixir :)
Pattern matching to the rescue ?
Isn't this feature called method overloading ? 🤔
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!
I quite like cond as well for certain situations as well.
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
❤ for the utmost ruining lang.
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 returnundefined
. Thoughts?That would be handy using a try except:
I added the extra
default
variable just to make the code self explanatory.EDIT: Bad solution, look at the other comments.
You can also use defaultdict in the standard library :D
This is clean :D
This is the answer to this entire thread.
@rhymes and @pedromendes96 got it better than me 😁
Really love this pattern. I have seen various approaches to the
default
case that vary across languages.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#.
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)
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:
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 (|>
).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. :)
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
overfor
loops. By usingswitch
instead ofelse 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?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 yourif
statement.The
switch
operator can be much cleaner thanif
though, notably for small return statements. For example:is much cleaner than
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.
If you're returning then you don't even need the else.
Actually looks a bit tidier to me and still very explicit.
Depends on the language, but for safety critical code, multiple function exits are typically frowned upon.
Nah. Exit early. Makes the code cleaner and clearer.
Gotta respectfully throw out a dispute. I've heard this statement used to justify multiple returns before... Looks like
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
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...
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.
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
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!
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.
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.
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-...
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:
Here, it's easier (for me, at least) to see which possible values return 1 than this:
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! :PThose 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! :)
Switch
es as well as conditionals with many branches(else if
s) are generally indicative of a different issue all together.Switch
es 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 abreak
.Switch
es also are very hard to do in a way that enables defensive programming. It's easy for aswitch
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 ofcase
s.Generally, like @rossholloway94 mentioned,
Enum
s are a much better fit. The way that @0xrumple showed in python can be done in many other languages that don't have realEnum
s, but is essentially anEnum
as well. Alternatively, in certain use cases, something like a rule matcher and handler can be a better fit.Using a
switch
can also be indicative that whatever logic you're doing in theswitch
, is really something that should be on each class to implement which can be similar to the model above. Basically the Strategy design pattern.The reason a
switch
never feels better than manyelse if
s is because they are basically the exact same thing. The kind of feel that gets hammered in a lot of beginner tutorials that explainswitch
es is something like "If you have a lot of conditions, use aswitch
!" and also the examples show how to convert a thing with a lot ofelse if
statements into aswitch
.One more time for clarity:
switch
alternative candidates are:Enum
sInterface
s in classesEnums 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:
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.
Aha... Heck yeah, this example is pretty solid 👌
Excellent point! Sometimes you may need lots of
if
statements, but more often than not, lots ofif
s 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.Personally, I oppose switch statements because they force you to opt-in to
break
rather than breaking by default (i.e. usecontinue
for fallthrough). I feel like every time I write a switch statement I forget abreak
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 withif
/else if
/else
.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.
A good optimiser will use the optimal output for the size of the operation, irrelevant of the code statement.
I'm sorry but this is a really uneducated comment.
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...
case "a", "A":
case 1..<5:
switch point: case (0, 0)
case let(x, y)
where
checksfallthrough
Granted, each of these can still be done with if-else, I like the convenience of it all.
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:
Otherwise it's main advantage is clarity for large numbers of options and optional fall through (double-edged sword that it is).
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.
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.
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
As someone who has never had the chance to jump into a compiled language, this is wonderful information! Thank you for the correction.
Of course this depends on the context of the application though. If I am checking against static values, then my previous statement is true.
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.
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
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.
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.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.
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.
I am not a big fan, it forces me to use
break
a lot... Good oldif... else
never failed me so I am being faithful 😁I like switch for when I return because you skip out on so much boilerplate over and over.
Just feels much easier to type than
You have to keep typing
something ===
over and over and I dislike that.The speed etc is not important to me.
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.
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.
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.: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.
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.
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.
In kotlin we don't have a switch, we have a
when
operator:It can take a parameter to match:
And also you can put different stuff there…
in the case of
is SubFoo
you get auto-cast. So you can usefoo
as aSubFoo
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
overelse-if
in kotlin.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.
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".
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.
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.
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 assumedbreak
and explicitfallthrough
, 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: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)
I only use
switch
statements in two scenarios:A: I'm using an Abstract Factory for something.
B: If I'm writing reducers in redux
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.A while back in college, I read somewhere that when there are a similar number of conditions in an
if-else
block and aswitch
statement, theswitch
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 oldif-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 ofswitch
statements until it's absolutely necessary. This was btw my first use ofswitch
statements in around 2 years since last I used them in college.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.
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.
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.They are different,
switch
(orcase
) is a Multi-Branch flow.Compiled languages can optimize
switch
a lot more thanif
.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.
I agree for most languages. But the pattern matching switch in ReasonML and Elixir is awesome!
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.
All redux reducers just gasped
I always favor objects over switch statements. There are only very rare occasions when an object won't work.
Just like
for
loops started to disappear after ES6 (or ES5?) brought in.map
,.reduce
,.filter
, and.forEach
, I think theswitch
statement doesn't quite fit in to modern JS.I use Switch statements a lot for mundane things, such as this:
and so on but that's about it
I'll pick if statements over switch in a heartbeat. Never missed it when I'm programming in Python daily at work.
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
Why no nested ternary love?
Why switch is better than if-else
edA‑qa mort‑ora‑y ・ Jun 29 ・ 4 min read