# Pure function

A pure function is a function that only performs a calculation: it does not change any object or variable that existed before it was called, and given the same inputs it always returns the same result.<sup>[1](https://react.dev/learn/keeping-components-pure)</sup> The concept comes from functional programming, where it is the standard against which side effects, testing, caching, and compiler optimization are measured.<sup>[2](https://learn.saylor.org/mod/book/view.php?chapterid=96129&id=101735)</sup>

| Key fact | Detail |
|---|---|
| Definition | Minds its own business (changes nothing that existed before the call) and returns the same output for the same inputs, always<sup>[1](https://react.dev/learn/keeping-components-pure)</sup> |
| Side effects | No modification of external state, no I/O, no reading of time or randomness; impure functions often mutate globals, change their arguments, or depend on external factors<sup>[3](https://tu-delft-dcc.github.io/docs/software/code_quality/code_smells/side_effects.html)</sup> |
| Local mutation | Changing variables created inside the function body does not break purity; the criterion is what is observable from outside<sup>[4](https://academia.sh/en/courses/paradigms/pure-functions)</sup> |
| Optimization | Unused pure expressions can be deleted, repeated calls can be memoized, and independent pure expressions can be reordered or run in parallel safely<sup>[2](https://learn.saylor.org/mod/book/view.php?chapterid=96129&id=101735)</sup> |
| Language support | Haskell enforces purity with the IO monad; D has a `pure` keyword with memoization guarantees; gcc, Fortran 95, and C++11 (`constexpr`) let programmers mark functions pure<sup>[5](https://www.haskell.org/tutorial/io.html)</sup><sup> • </sup><sup>[6](https://dlang.org/spec/function.html)</sup><sup> • </sup><sup>[2](https://learn.saylor.org/mod/book/view.php?chapterid=96129&id=101735)</sup> |
| Framework use | React assumes every component is a pure function of its props, state, and context<sup>[1](https://react.dev/learn/keeping-components-pure)</sup> |

## Definition and side effects

The two defining characteristics are usually stated together. A pure function minds its own business: it does not change any objects or variables that existed before it was called. And it satisfies same inputs, same output: given the same inputs, it always returns the same result. React's documentation compares this to a mathematical formula such as \( y = 2 \cdot x \); solving it twice does not change what \( y \) is, and calling a pure `double` function with 3 returns 6 every time.<sup>[1](https://react.dev/learn/keeping-components-pure)</sup>

A side effect is anything a function does beyond returning a value: modifying external state or interacting with the outside world. Typical impure behaviors include modifying global variables or shared state, mutating function arguments, performing I/O with files, databases, or APIs, generating random numbers, and depending on external state so that results change between calls.<sup>[3](https://tu-delft-dcc.github.io/docs/software/code_quality/code_smells/side_effects.html)</sup> Time and randomness are described as the natural enemies of purity: a call to `Date.now` inside the function body breaks the same-input-same-output condition. The usual fix is not to forbid such values but to produce them outside the function and pass them in as parameters.<sup>[4](https://academia.sh/en/courses/paradigms/pure-functions)</sup>

**What counts as an effect is a design choice.** The OCaml documentation notes that any computation has effects, and deciding which are relevant is an engineering decision. System I/O is normally treated as an effect; the heat emitted by the processor is not usually considered a relevant side effect, except in energy-efficient design. Functions returning random numbers or the current time are impure because their results are influenced by external factors.<sup>[7](https://ocaml.org/docs/values-and-functions)</sup>

## Local mutation

Purity does not mean that nothing inside the function changes. The criterion is observability: a function stays pure as long as changes to variables it created are not seen from outside. A loop that accumulates into a local `total` variable is pure, because the accumulator is invisible to the caller.<sup>[4](https://academia.sh/en/courses/paradigms/pure-functions)</sup> React's tutorial makes the same point with a component that creates an empty array and pushes twelve items into it during rendering; this "local mutation" is fine because the array was created during the same render, but pushing into an array created outside the component would be a serious purity violation.<sup>[1](https://react.dev/learn/keeping-components-pure)</sup>

One boundary remains: a pure function must not change an object it receives as a parameter, because the caller would see the change.<sup>[4](https://academia.sh/en/courses/paradigms/pure-functions)</sup>

## Why purity pays

Purity gives compilers, caches, and programmers guarantees that impure code cannot offer. The Saylor functional programming text lists the practical consequences:<sup>[2](https://learn.saylor.org/mod/book/view.php?chapterid=96129&id=101735)</sup>

- If the result of a pure expression is unused, it can be removed without affecting anything else.
- Calling a pure function again with the same arguments returns the same result, which enables caching optimizations such as memoization.
- Pure expressions with no data dependency between them can be reordered, run in parallel, and cannot interfere with one another; evaluation of a pure expression is thread-safe.
- In a language that allows no side effects at all, the compiler can choose any evaluation strategy and freely reorder or combine expression evaluation.

[Referential transparency](https://www.edgepedia.org/referential-transparency), the property that an expression can be replaced by its value, is described in a 2015 review in *National Science Review* as the basis of the properties that let programmers reason about, test, optimize, and derive programs; pure functional languages encode side effects with a programming pattern known as monads.<sup>[8](https://academic.oup.com/nsr/article/2/3/349/1427872?login=false)</sup> In day-to-day practice, the TU Delft software guide recommends keeping computational logic in pure functions and isolating side-effecting operations such as file writes from them.<sup>[3](https://tu-delft-dcc.github.io/docs/software/code_quality/code_smells/side_effects.html)</sup>

## Purity in language design

Languages differ in how much purity they enforce. Haskell is defined as a general-purpose, purely functional programming language, and its I/O system is purely functional: I/O actions are values in the IO monad, cleanly separated from the purely functional core, so equational reasoning is not compromised even though the I/O component of a program can look like ordinary imperative code.<sup>[9](https://www.haskell.org/onlinereport/intro.html)</sup><sup> • </sup><sup>[5](https://www.haskell.org/tutorial/io.html)</sup> GHC's Safe Haskell documentation describes the separation as functions in the safe language being deterministic and free of side effects.<sup>[10](https://downloads.haskell.org/~ghc/7.8.3/docs/html/users_guide/safe-haskell.html)</sup>

D takes a different approach: purity is defined as not accessing mutable global or `static` state, and the compiler checks it. A strongly pure function has no parameters with mutable indirections and cannot modify program state external to the function; the implementation may assume that a strongly pure function called with immutable-only arguments that returns a result without mutable indirections has the same effect for equivalent arguments, and it is allowed to memoize the result on that assumption.<sup>[6](https://dlang.org/spec/function.html)</sup> D also permits impure operations inside `debug` statements to make debugging easier, and allows a pure function to read and write floating-point exception and mode flags provided the flags are restored to their initial state.<sup>[6](https://dlang.org/spec/function.html)</sup>

In languages without a purity type, programmers can still mark functions. Most compilers for imperative languages detect pure functions and perform common-subexpression elimination on them, but pre-compiled libraries generally do not expose purity information, so gcc adds keywords for explicitly marking external functions pure, Fortran 95 lets functions be designated pure, and C++11 added `constexpr` with similar semantics.<sup>[2](https://learn.saylor.org/mod/book/view.php?chapterid=96129&id=101735)</sup>

## Pure functions in React

React is designed around purity: it assumes every component is a pure function that returns the same JSX given the same inputs. Components must not mutate their inputs, which include props, state, and context; to update the screen, code sets state instead of changing preexisting objects. Changes belong in event handlers, with `useEffect` as a last resort.<sup>[1](https://react.dev/learn/keeping-components-pure)</sup>

The framework exploits purity directly. Because pure components return the same result for the same inputs, they can run in a different environment such as the server, rendering can be skipped for components whose inputs have not changed, and React can safely restart rendering a deep component tree if data changes mid-render. React's Strict Mode double-invokes components to surface impure code, and has no effect in production.<sup>[1](https://react.dev/learn/keeping-components-pure)</sup> Memoization APIs build on the same contract: the `cache` function memoizes per component render, `useMemo` caches an expensive computation across renders within a component, and `memo` (the function-component successor to class-based `PureComponent`) skips re-renders when props are unchanged.<sup>[11](https://react.dev/reference/react/cache)</sup><sup> • </sup><sup>[12](https://react.dev/reference/react/PureComponent)</sup>

## References

1. [Keeping Components Pure, React documentation](https://react.dev/learn/keeping-components-pure)
2. [Functional Programming: 3.2 Pure Functions, Saylor University](https://learn.saylor.org/mod/book/view.php?chapterid=96129&id=101735)
3. [Side Effects and External State, TU Delft Digital Competence Center](https://tu-delft-dcc.github.io/docs/software/code_quality/code_smells/side_effects.html)
4. [Pure Functions, Programming Paradigms, Academia.sh](https://academia.sh/en/courses/paradigms/pure-functions)
5. [A Gentle Introduction to Haskell: Input/Output, haskell.org](https://www.haskell.org/tutorial/io.html)
6. [Functions, D Programming Language specification](https://dlang.org/spec/function.html)
7. [Values and Functions, OCaml documentation](https://ocaml.org/docs/values-and-functions)
8. [How Functional Programming Mattered, National Science Review 2(3), 2015](https://academic.oup.com/nsr/article/2/3/349/1427872?login=false)
9. [The Haskell 98 Report: Introduction](https://www.haskell.org/onlinereport/intro.html)
10. [Safe Haskell, GHC 7.8.3 User's Guide](https://downloads.haskell.org/~ghc/7.8.3/docs/html/users_guide/safe-haskell.html)
11. [cache, React documentation](https://react.dev/reference/react/cache)
12. [PureComponent, React documentation](https://react.dev/reference/react/PureComponent)

---
*Topic: Encyclopedia › Technology and the built world › Computing and digital systems › Software and programming › Programming languages › Programming language concepts*

*Initially written Sep 17, 2026 · Reviewed: Sep 30, 2026; Oct 15, 2026 · Edited: Oct 15, 2026 · Last review: Oct 15, 2026*

*Copyright 2026 EdgeChat AI, a subsidiary of Biostate AI.*

License: Edgepedia Community License 1.0, https://www.edgepedia.org/edgepedia/license
