Suggest an editImprove this articleRefine the answer for “What is a pure Function?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**A pure function** always returns the same output for the same input and produces no side effects. ```javascript const add = (a, b) => a + b; add(2, 3); // 5, always Date.now(); // different every call - impure ``` **Key:** React's `useMemo` and `React.memo` only skip re-renders correctly when your function is pure.Shown above the full answer for quick recall.Answer (EN)Image**A pure function** always returns the same output for the same input and produces no side effects outside its own scope. ## Theory ### TL;DR - A pure function is like a vending machine: same coins in, same snack out, no mess left behind - Two rules: same input always gives the same output, and no side effects (no mutations, no logs, no API calls) - Output depends only on arguments, never on global state, DOM, or values like `Date.now()` - React's `useMemo` and `React.memo` rely on purity to skip re-renders safely ### Quick example ```javascript // Pure: depends only on arguments const add = (a, b) => a + b; add(2, 3); // 5, always // Impure: reads external state const now = () => Date.now(); // different result each call // Impure: mutates external variable let count = 0; const increment = () => count++; // side effect ``` `add` only touches its arguments. `Date.now()` reads from the clock, external state it doesn't control. `increment` modifies `count` outside its own body. Those last two are impure. ### Key difference Pure functions depend only on the arguments passed in. They don't read global variables, touch the DOM, or access anything that lives outside their own body. That makes the output predictable: call `add(2, 3)` a thousand times and you always get `5`. Impure functions break that contract the moment they read or write something external. ### When to use - Math or logic over props/state (calculate a cart total, filter a list): pure function - Wrapping in `useMemo` or `React.memo` to avoid unnecessary re-renders: pure function required - API calls, DOM mutations, timers: impure by nature, isolate them in `useEffect` - Shared utility helpers used across components: pure, because they are easy to test and reuse ### How the engine handles this V8 doesn't check purity explicitly. It infers predictability from the absence of external mutations during JIT compilation, which opens the door to optimizations like inline caching. React does something similar at a higher level: it compares props shallowly and skips re-renders when inputs haven't changed. That mechanism only works correctly if your function is actually pure and returns the same output for the same props. ### Common mistakes **Mutating the argument** ```javascript // Looks harmless, breaks React state const badSum = (numbers) => { numbers.push(0); // mutates the original array! return numbers.reduce((a, b) => a + b, 0); }; // Fixed const goodSum = (numbers) => { return [...numbers].reduce((a, b) => a + b, 0); }; ``` React expects immutability. Mutating an array that came in as a prop produces stale state bugs that are hard to trace. In code reviews, this pattern shows up more often than you'd expect, usually hidden inside a function that looks completely harmless. **Reading global state** ```javascript let counter = 0; const getNextId = () => counter++; // different result every call // Fixed: pass it as an argument const getNextId = (counter) => counter + 1; ``` Redux forbids this pattern in reducers for exactly this reason. **`console.log` inside a "pure" function** ```javascript const multiply = (a, b) => { console.log('computing'); // side effect return a * b; }; ``` The log doesn't change the return value, but it changes observable program behavior. React can't safely memoize this. ### Real-world usage - **React useMemo**: wrap expensive pure computations (filtering large lists) so React skips re-running them on every render - **Redux reducers**: must be pure, take state and action, return new state without mutations (Redux Toolkit uses Immer under the hood) - **Lodash FP / Ramda**: all functions pure by design, safe to compose into pipelines ### Follow-up questions **Q:** What is referential transparency? **A:** A function call can be replaced with its return value without changing program behavior. `add(2, 3)` and `5` are interchangeable anywhere in the code. **Q:** Why does React care whether a function is pure? **A:** `React.memo` and `useMemo` rely on the assumption that the same input produces the same output. If a function is impure, caching its result leads to wrong UI state. **Q:** Does `useCallback` make a callback pure? **A:** No. `useCallback` memoizes the function reference so it doesn't change between renders. But if the callback reads or mutates external state, it's still impure. Reference stability and purity are separate things. **Q:** Can a function that mutates its argument ever be pure? **A:** No. Mutation is a side effect by definition. Even if the return value looks correct, the function changed something outside its own body. ## Examples ### Basic: tax calculator ```javascript // Pure - safe to wrap in useMemo const calculateTax = (amount, rate) => amount * (1 + rate); calculateTax(100, 0.08); // 108 calculateTax(100, 0.08); // 108, every time ``` Same inputs, same output, no external reads. React can cache this result and skip recalculation until `amount` or `rate` actually changes. ### Intermediate: filtering todos in a component ```javascript // Pure filter function const filterTodos = (todos, filter) => { return todos.filter(todo => { if (filter === 'active') return !todo.completed; if (filter === 'completed') return todo.completed; return true; }); }; // In component const visibleTodos = useMemo( () => filterTodos(todos, filter), [todos, filter] ); ``` `filterTodos` only reads its arguments. Wrapping it in `useMemo` means React re-runs the filter only when `todos` or `filter` actually changes, not on every render. This is the pattern from React's own docs for expensive list operations.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.