Glossary / Pure functions
Pure functions
A pure function’s result depends only on its explicit inputs, and calling it causes no observable side effects. With the same inputs it returns the same output, making it easier to test, cache, reorder, and reason about. Purity is a behavioral property, not a special JavaScript declaration syntax; a function can be pure for one contract and impure for another if hidden dependencies are introduced.
Pure transformations and effect boundaries
function subtotal(items) {
return items.reduce((sum, item) => sum + item.price * item.quantity, 0);
}
This is pure only if reading the items is stable and no getter or proxy produces effects. A function that reads Date.now(), Math.random(), mutable global state, the DOM, or network data has an implicit input and is not pure. Mutating an argument is an effect visible to the caller. Logging is also observable, even if the return value remains deterministic.
A practical architecture keeps deterministic decision logic in pure functions and places I/O at boundaries. For example, pass the current time into an eligibility function rather than having it read the clock itself; an outer service obtains the time and calls the pure core. This improves testability without pretending the whole application has no effects.
Purity supports memoization only when inputs and outputs are handled correctly. Object identity, mutation, expensive keys, and cache invalidation still matter. Pure functions are not automatically faster, and floating-point computations can still have precision behavior.
Interview questions
- What makes a function pure? Same explicit inputs yield the same result and there are no observable effects.
- Is
Date.now()pure? No, because time is an implicit changing input. - Is mutating an argument pure? No, callers can observe the mutation.
- How apply purity in an I/O-heavy service? Keep the decision/transformation core pure and inject time, data, and effect adapters at the edges.