Avoid side effects

Improve code reliability by avoiding side effects. Minimize hidden consequences, enhance predictability, and simplify testing.


Usage

πŸ“ Guideline

Avoid Side Effects: Minimize or eliminate code that modifies state or produces non-obvious consequences.

Code that produces unexpected changes to the system's state or has hidden consequences can be difficult to reason about and debug. By avoiding side effects, you can create code that is more predictable, easier to test, and less prone to bugs.

πŸ› οΈ How to Apply

  • Immutability: Favor immutability whenever possible to prevent accidental modifications of shared data. 🚫
  • Pure Functions: Write pure functions that only depend on their input and produce consistent output, without modifying external state. πŸ§ͺ
  • Avoid Global State: Minimize the use of global variables or shared state, as they can lead to hidden dependencies and unintended side effects. 🌍

Pros and Cons

πŸ‘ Pros

  • Predictability: Code without side effects is easier to understand and predict because its behavior is more explicit and deterministic. 🎯
  • Testability: Side-effect-free code is easier to test, as it can be isolated and its behavior can be verified without the need for complex setup or mocking. πŸ§ͺ
  • Concurrency: Code with fewer side effects is generally more amenable to concurrent or parallel execution, as it avoids shared mutable state and potential race conditions. πŸƒβ€β™‚οΈ

πŸ‘Ž Cons

  • Performance impact: Avoiding side effects may introduce additional data copies or indirection, impacting performance slightly. However, improved maintainability and reliability often outweigh this trade-off. 🐒
  • Integration challenges: When working with legacy codebases or third-party libraries that heavily rely on side effects, adopting a side effect free approach can be challenging. 🚧

Examples

❌ Bad

// Bad example: Function with side effects
let counter = 0;
 
function incrementCounter() {
  counter++;
}
 
incrementCounter();
console.log(counter); // Output: 1

βœ… Good

// Good example: Pure function without side effects
function incrementCounter(counter: number): number {
  return counter + 1;
}
 
let counter = 0;
counter = incrementCounter(counter);
console.log(counter); // Output: 1

References

  • Separation of Concerns: Avoiding side effects is closely related to the principle of separation of concerns, as it promotes modular and decoupled code by isolating state manipulation. 🧩
  • Immutable Data: The concept of immutability complements side effect prevention by emphasizing the use of unmodifiable data structures to prevent unintended changes. πŸ”’
  • Pure Functions: Side effect avoidance aligns with the use of pure functions, which have no side effects and produce consistent results based solely on their input. πŸ§ͺ
  • Functional Composition: Pure functions without side effects can be easily composed together to create larger and more complex functions. This encourages modular and reusable code. πŸ”€