Are Side Effects Bad?
Side effects get a bad rap—we actually need them in computer systems. We want side effects.
A useful program causes side effects. Imagine an application that never made changes to a database, never wrote to a file or recorded the result of a calculation. Such a side-effect-free system would only be able to work with the same data, never changing anything. You would not be able to shop online – items in your shopping cart would not persist. Your online payment would not go through to the payment provider – another side effect.
So, why are side effects considered bad?
They are not bad per se. Side effects in our programs can be problematic when we don’t manage them carefully:
Side effects make code harder to reason about. Imagine we have two classes. One is a container for internal state that frequently changes. The other one is also stateful but once instantiated, its state is immutable. If Which of these would you rather debug? The first class is a slippery character constantly changing—we’ll need to be attentive and careful in tracking down when and how it changes. We’ll have no such headaches from the immutable class. It’s harder for human minds to reason about code that has many side effects.
Side effects make unit testing more difficult. We’ll need to account for the side effects in our unit testing. Considerable setting up may be required before we can unit test a stateful module. Classes without side effects, we can unit test by varying the values plugged into parameter lists. Mocking and stubbing may be required when testing the correct writing of data to external data sinks. Even though these techniques are useful and needed, it is worth keeping in mind that they make unit tests harder to understand.
Side effects require sequential execution. When we have no side effects, we can break up and run the code concurrently. On the other hand, when we have to account for side effects, this is no longer true—now, the code must execute in a particular order. Say data is coming into our system, and we need to validate it before writing it out to a database. We cannot reverse the order of operations: The validation must occur before the database write. On the other hand, the validation checks can occur in any order—it does not matter if we were to validate a surname data item before, after or concurrently to a first name one.
To conclude today’s tip, side effects are not bad or evil—they are a system requirement. However, side effects make programs harder to understand and unit test. Besides, they restrict opportunities for parallel execution.