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 refactor in any big way, but I've also never found it overly important.
I tend to find the behavior and syntax of if
and else
to be pretty consistent regardless of language compared with switch statements so reaching for if
is easier, but even when chained doesn't seem that much less clean than switches.
I definitely agree that getting rid of if
..else
..else
chains are worth refactoring away, but I haven't found that a switch statement actually improves the quality meaningfully.
Thoughts?
Oldest comments (81)
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.
Of course this depends on the context of the application though. If I am checking against static values, then my previous statement is true.
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.
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.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.
That's why we never have
switch
in Python 😁And, the dictionary is always a better and cleaner alternative for the ugly switch.
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.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.
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. :)
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 😁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?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
.I'll pick if statements over switch in a heartbeat. Never missed it when I'm programming in Python daily at work.
All redux reducers just gasped