If you're a software developer, chances are you'll use the switch stament at some point. This operator allows you to evaluate the expression and ex...
For further actions, you may consider blocking this person and/or reporting abuse
Imho this article is just creating a problem out of absolute nothing.
A switch statement is totally fine to use until it reaches a distinct amount of switch cases.
After that a refactoring would be necessary to maintain readability.
This would also be the case whe using if statements.
So just clickbait?
Here the original article source:
dev.to/tauantcamargo/replace-your-...
The decision to use or avoid switch statements depends on the specific situation and the developer's preferences and coding standards.Thanks for sharing
Totally agree, sometimes we just need guard clauses to make the code more readable.
In my personal opinion, the switch-case block in the first code block is perfectly fine and in my opinion also better than the presented alternatives. It is much more readable due to less code and probably also faster and more efficient than the other solutions.
The if-else option has to evaluate the condition three times in the worst case, instead of once. Not a big deal, to be honest, but if we are discussing such a topic, it needs to be mentioned.
The key-value option (object or map) contains much more boilerplate code, which makes it harder to read, understand, and maintain. It also causes memory overhead due to additional objects (map, functions, etc.).
That being said, I would extract the three notification functions into three separate functions and call them from either the switch block or the if block. No need for overengineering.
It certainly makes sense to avoid switch blocks in certain cases, especially if they span long lines of code. However, this is not such a case. And if the post title has such a strong opinion about switch-blocks, it should also present a strong use case against them.
But there is a tipping point. The example code is short for article readability. If there were 20, 200 or 2000 notifications the switch pattern is unmanageable (and untestable). However if you start with the switch pattern, the cost to refactor can be too great to fit into a development sprint and you end up with tech debt
Please, think about it. That's nonsens. I don't believe, you had such this situation in any of your sources. Not to manags and no way to test it? What? I use switch-blocks since over 40 years. And i would never use an if-then-else-basic-shit. Sorry. This article is redudant.
canonical example. medical SNOMED/HL7 codes. There are literally thousands of them... It is likely that a solution starts out for one particular medical diclipline and as the software expands, you need to do different things. In the end you need to be able to map an enumerated value to an action. Whether you do this with SWITCH, IF-ELSE, object keys or a database is an implementation detail.
You wouldn't be calling a different action for those codes, you'd be calling the same action with different parameters.
A more realistic case would be a device controller in which what you do depends on how the device answers back. Even then usually it's enough for a switch statement but some devices can be hella complex in their interfaces.
How would the condition to check which type of notification to send be any different? The notification type will be determined by either a) switch-statement, b) an if-statement or c) the key-value-map.
In all three cases you should most likely extract the actual notification logic into its separate function, depending on the length and complexity. But that has nothing to do with switch-statement in particular. It equally applies to all three use cases.
If you use TypeScript, you don't need to refactor your Switch statements. You can make them safer with this trick:
When you use type
never
TypeScript explicitly checks thatdefault
case is unreachable and shows you an error if it isn't.mejor usar un enum
Strongly disagree.
1) I don't think switches are less readable when you are used to them. They don't come up very often in code because they are only useful in specific cases so they might look "odd" to the inexperienced eye.
2) You haven't mentioned that switches are powerful when mutliple cases lead to the same branch.
3) Switch cases are NOT tested sequentially like a chain of if {} else if {}. Try to write a little piece of C code with a switch, compile it, look at the generated Assembly result and it might surprise you how good compilers are at optimising switches.
4) When it comes to performance, using a string as a case value is already a bad idea. A properly designed software should use enums for that anyway (in JS too). Besides, hashmaps are dynamic runtime structures, so they are not as predictable and therefore not as optimisable as the code branches of a switch, and that's true for any language.
The only thing I would agree on is that switches are often used to patch bad design, which might also be why they have a bad reputation. If I have a lot of branches in a switch, I would try to refactor the code using polymorphism.
Switches in JS are indeed sequential tests. Unless there are some JIT optimizations I'm not aware of, each case of a switch is tested in order until one matches.
I just had a quick look at the V8 source and it turns out that some switches are already optimisable by the JIT compiler before any heavy optimization work by TurboFan.
Specifically, any switch that meets the following conditions will get optimised with a jump table:
Here's the source code for that:
src/interpreter/bytecode-generator.cc
src/flags/flag-definitions.h
Note that the jump table will be tested first. If the switch has any non Smi cases, they will be tested AFTER any case available in the jump table, even if they appear before some of these cases in the code.
Also note that this is just a basic compilation optimisation. When the function becomes "hot" it will be picked up by the optimiser (TurboFan in V8). And the optimisation performed will be much more important than a simple jump table. Some of function calls inside the cases may even be inlined inside the parent function. It's much harder (though not impossible) for the optimiser to optimise if you use a hashmap because a hashmap is dynamic so the optimiser has to make assumption before inlining and verify that these assumptions are still true when calling the function.
I literally created an account with the sole intention of asking you how the **** did you come up with this code? Like, really, how do you know your way around this repo so good to find this? Or if not how did you manage to do it anyway? This is an invaluable skill imo
Thanks asaf!
I'm not familiar with the v8 source code but I could navigate it rather easily because:
Beyond that, it's a matter of opening and checking folders/files and guessing if you're on the right track. Also I have only dug into the interpreter code, which is the easy part I suppose.
All JS JIT compilers come with optimisers that will sort this out (e.g. V8's TurboFan).
Partially agree with you, although unsure about the proposed solution... In most cases I would just encourage people to use guard clauses, with clear descriptions like:
The use of
Objects
orMapping Functions
depends on the context of what is being integrated. It is up to the developer if it is useful or not. Thank you very much for your comment. π€I would take a switch statement over the provided alternatives any day. We need to keep readability in mind. When you return to that specific section in three years, you want to see at first glance what's happening.
In react I using switch-return for useReducer, I think that way much simplier, than create lot of extra function.
for example:
You don't need a switch at all for such a reducer, this is plenty:
that is only complicated the whole reducer, because in this case - real exmaple - you can call this "simpleReducer" from each line.
Switch version do not need to create 14 different reducer function call - one calls level less solution. Check this solution, in each case you declare which state property chagened. Plus as you saw this gameReducer have return type definition ( at once ), that guard each of them.
Nope, no need to declare separate functions
You only need advanced reducers if you have to manage arrays, like adding, updating or deleting items to/from array.
Have a look at immer. It might help you here
All this hassle can be avoided just by adding a "default:" with an error throw. If you forget to add the new fruit to the switch, it will throw an error exactly the same as your object solution.
Also, if the input comes from "outside" (not fully under your control), your object solution is bugged. Use "toString" as the notification name and see. Trying to find a safer solution you just created an unsafer one. Sometimes overengineering is a problem more than a solution.
And a default case is not even needed, check this example:
they kinda seem harder to read
I agree. I've used this pattern before, but with some refactoring.
I find this helps to keep everything in one place while separating them too.
What? How is one of these things easier than the other?
Congratulations you just replaced performant code for code that YOU subjectively think looks better with a GC overhead. Sure you can do it but none of the so called benefits hold true.
You may think that a hash map is O(1) but it's not it comes with a huge overhead even if you ignore the fact that you just created VM functions.
Unless your use case involves hundreds of return paths linear search will ALWAYS be faster. In both cases you can optimize based on code execution rank but switch case may or may not be optimized for by JIT depending on implemention.
So please stop posting about micro-optimizations.
Agree with the article unless you can guarantee a finite number of cases over time.
In almost all other cases a map keyed to your execution function is more readable, scalable, testable and importantly most people forget, much more commit friendly. I've had plenty of collisions on active teams with switch statements that never happened (or are much simpler to resolve) when simply populating a map.
Can you give a specific real or hypothetical example of the same collision with each?
Apologies for the previous use of the word "switch." I'll avoid using that term moving forward. If you have any specific requests of Facebook owner game or questions, please let me know, and I'll be happy to assist you.
This is terrible advice.
If you have known and few cases, keep using Switch. It's the easiest and most readable, and the way it's implemented is usually very fast.
If you have many and unknown-at-release-time (i.e. you're shipping something that supports plugins) then use polymorphism -- that is, you pass an object of the base type and call an abstract/virtual function and you let the derived types define that function. This is also fast as heck as it's a vtable lookup, it's understandable, it's maintainable and expandable.
The mapping function is what you do if you need to expand the functionality AT RUNTIME ONLY. It's much harder to read and maintain otherwise.
Stop posting clickbait titles.
Yeah sometimes it would be nicer to extract an object with the operations. But one of the problems that I have faced is that you no longer can use a closure to access the data where the original switch was. I can't think of a way to achieve the same result when the switch was inside a class, accessing private members to carry out the result.
This is to be honest a very complicated solution for a made up problem. If your switch case, or in newly Java Versions your switch expression is getting too big, then you might think of using maps, lambdas or if else constructs.
The switch is far more preferable to endless if else if else chained statement s . Yes it is preferable to do a mapping for a large number of branches but that happens extremely rarely. There's no point in doing mappings or derived classes if you can solve that with a 5 branch switch. But that is the core of being a good programmer: choose the appropriate tool for the appropriate situation. And not typing 100 classes per minute. Think strategically and act carefully.
That's gonna be a "no" from me, dawg. Switch isn't the best for everything, but it's the most appropriate option virtually anywhere you have more than one mutually exclusive branch.
Switch statements absolutely have great usecases
Objects with functions as propvalues are much less readable.
I am sorry but the switch statement has the opportunity to be in the stack and to still return early and now we want to use heap allocated memory for the hash map to get the same result⦠over engineering at best to not solve a real problem
Well, if you need to modify 2 code blocks that always comes with some dangers. It is not a switch statement problem, but a more underlying issue.
It is rare when developers can put their fingers on problems like this and they'll go on and blame a certain pattern, paradigm, technology or in this case, a statement.
I found modeling diagrams can help alot to find out the ways a particular piece of code can change. The understanding of clients and development roadmaps define how it is most likely to change.
I think there is no problem using switch or match when the number of cases are not many. If they are growing so much then it'll be necessary to refactor.
I had some similar feelings about switch in the past.
I ended up making this
github.com/kristoferjoseph/hash-sw...
Or if it hits the default case just throw an exception?
Safer? Lol, what safe?
Let me introduce you, the "default" argument for switch statement.
Stop using switch?
No. I don't think I will.
Wow, you just leaned into an antipattern. Im amazed
With the multiple if statements I think the switch(true){
case notification === Notification.emailConfirmed:
// do something
Break;
}
Can also be used.