Functions
Pure Functions & Side Effects
Master functional programming fundamentals in JavaScript. Learn the definitions of pure functions, side effects, and state immutability.
1. Introduction
In Functional Programming (FP), function predictability is everything. A Pure Function is a function that always returns the same output for the same input and produces no Side Effects (changes to state outside of the function).
2. Why It Matters
Pure functions make code predictable and easier to test, debug, and refactor. They are also essential for state management tools (like Redux or Zustand) and React optimization strategies (like memoization).
3. Real-World Analogy
Think of a Calculator vs a Diary:
- Pure Function (Calculator): You input
5 + 5and it always outputs10. It doesn't modify the calculator casing, change other values stored in memory, or write a log file. It simply calculates and returns the result. - Function with Side Effects (Diary): You write a entry in your diary. The next time you open the diary, the overall number of pages used has changed (modified state outside the function scope).
4. Pure Function Requirements
A function is considered pure if it satisfies two main requirements:
1. Determinism: Given the same arguments, it will always return the exact same value. It cannot rely on mutable global variables or random numbers.
2. No Side Effects: It does not change state outside of its local scope.
Common Side Effects:
- Modifying global variables or outer scope variables.
- Modifying reference parameters passed to the function directly.
- Writing logs with
console.log(). - Performing network requests or I/O operations.
- Modifying the DOM.
- Querying random values with
Math.random()or current time withDate.now().
5. Practical Example
Compare these pure and impure implementations of cart operations:
6. Benefits of Pure Functions
- Testability: You only need to pass arguments and assert the output, without needing mock servers or state setups.
- Caching (Memoization): Since the output is deterministic, you can cache results based on the arguments to speed up execution.
- Concurrency: Because they don't modify shared state, pure functions can run concurrently without race conditions.
7. Common Mistakes
- Mutating objects passed as arguments: Modifying property values of objects passed as arguments causes side effects. Instead, create and return a copy of the object with the changes applied.
- Using non-deterministic utilities: Incorporating
new Date()directly inside calculations makes the function impure because its output changes depending on when it runs. Pass dates in as arguments instead.
8. Quick Quiz
Q1: Is a function that writes diagnostic messages with console.log pure?
A) Yes, because it returns the correct mathematical result
B) No, because writing output to the console is a side effect
Answer: B — Writing logs changes the state of the console window outside the function, which is technically a side effect, making the function impure.
9. Scenario-Based Challenge
The React State Updater:
A user profile updates their address: updateAddress(profile, newAddress). In React, state modifications must be immutable to trigger component re-renders. Write a pure version of this function that returns a new user profile object containing the updated address, without modifying the original object.
10. Debugging Exercise
Refactor this impure function to make it pure and deterministic:
let discountRate = 0.10; // global state
function calculateTotal(price) { // Impure: accesses global rate, and writes logs! console.log('Calculating...'); return price * (1 - discountRate); }
View Solution
Diagnosis: The function accesses a mutable global variable (discountRate) and writes to the console, which are both side effects.
Fix: Pass the discount rate as a parameter and remove the console log statement:
function calculateTotal(price, discount) {
return price * (1 - discount);
}
11. Interview Questions
🟢 Q1: Can a pure function call another function?
Answer: Yes, a pure function can call other functions, but only if the called functions are also pure. If a pure function calls an impure function, it inherits the side effects and is no longer pure itself.
12. Production Considerations
- • State Management: In modern frontends, keeping state mutations pure is critical. Always treat state variables as read-only and return new copies when updating state to avoid UI synchronization issues.