In computer programming, a pure function is a function that has the following properties:[1][2]

1. the function return values are identical for identical arguments (no variation with local static variables, non-local variables, mutable reference arguments or input streams), and
2. the function has no side effects (no mutation of local static variables, non-local variables, mutable reference arguments or input/output streams).

Thus a pure function is a computational analogue of a mathematical function. Some authors, particularly from the imperative language community, use the term "pure" for all functions that just have the above property 2[3][4] (discussed below).

## Examples

### Pure functions

The following examples of C++ functions are pure:

• `floor`, returning the floor of a number;
• `max`, returning the maximum of two values.
• the function f, defined as
```void f() {
static std::atomic<unsigned int> x = 0;
++x;
}
```
The value of `x` can be only observed inside other invocations of `f()`, and as `f()` does not communicate the value of `x` to its environment, it is indistinguishable from function `void f() {}` that does nothing. Note that `x` is `std::atomic` so that modifications from multiple threads executing `f()` concurrently do not result in a data race, which has undefined behavior in C and C++.

### Impure functions

The following C++ functions are impure as they lack the above property 1:

• because of return value variation with a static variable
```int f() {
static int x = 0;
++x;
return x;
}
```
• because of return value variation with a non-local variable
```int f() {
return x;
}
```
For the same reason, e.g. the C++ library function `sin()` is not pure, since its result depends on the IEEE rounding mode which can be changed at runtime.
• because of return value variation with a mutable reference argument
```int f(int* x) {
return *x;
}
```
• because of return value variation with an input stream
```int f() {
int x = 0;
std::cin >> x;
return x;
}
```

The following C++ functions are impure as they lack the above property 2:

• because of mutation of a local static variable
```void f() {
static int x = 0;
++x;
}
```
• because of mutation of a non-local variable
```void f() {
++x;
}
```
• because of mutation of a mutable reference argument
```void f(int* x) {
++*x;
}
```
• because of mutation of an output stream
```void f() {
std::cout << "Hello, world!" << std::endl;
}
```

The following C++ functions are impure as they lack both the above properties 1 and 2:

• because of return value variation with a local static variable and mutation of a local static variable
```int f() {
static int x = 0;
++x;
return x;
}
```
• because of return value variation with an input stream and mutation of an input stream
```int f() {
int x = 0;
std::cin >> x;
return x;
}
```

## I/O in pure functions

I/O is inherently impure: input operations undermine referential transparency, and output operations create side effects. Nevertheless, there is a sense in which a function can perform input or output and still be pure, if the sequence of operations on the relevant I/O devices is modeled explicitly as both an argument and a result, and I/O operations are taken to fail when the input sequence does not describe the operations actually taken since the program began execution.[clarification needed]

The second point ensures that the only sequence usable as an argument must change with each I/O action; the first allows different calls to an I/O-performing function to return different results on account of the sequence arguments having changed.[5][6]

The I/O monad is a programming idiom typically used to perform I/O in pure functional languages.

## Compiler optimizations

Functions that have just the above property 2 allow for compiler optimization techniques such as common subexpression elimination and loop optimization similar to arithmetic operators.[7] A C++ example is the `length` method, returning the size of a string, which depends on the memory contents where the string points to, therefore lacking the above property 1. Nevertheless, in a single-threaded environment, the following C++ code

```std::string s = "Hello, world!";
int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int l = 0;

for (int i = 0; i < 10; ++i) {
l += s.length() + a[i];
}
```

can be optimized such that the value of `s.length()` is computed only once, before the loop.

Some programming languages allow for declaring a pure property to a function:

• In Fortran and D, the `pure` keyword can be used to declare a function to be just side-effect free (i.e. have just the above property 2).[8] The compiler may be able to deduce property 1 on top of the declaration.[9]
• In the GCC, the `pure` attribute specifies property 2, while the `const` attribute specifies a truly pure function with both properties.[10]
• Languages offering compile-time function execution may require functions to be pure, sometimes with the addition of some other constraints. Examples include `constexpr` of C++ (both properties).[11]

## Unit testing

Since pure functions have identical return values for identical arguments, they are well suited to unit testing.

## References

1. ^ Bartosz Milewski (2013). "Basics of Haskell". School of Haskell. FP Complete. Archived from the original on 2016-10-27. Retrieved 2018-07-13. Here are the fundamental properties of a pure function: 1. A function returns exactly the same result every time it's called with the same set of arguments. In other words a function has no state, nor can it access any external state. Every time you call it, it behaves like a newborn baby with blank memory and no knowledge of the external world. 2. A function has no side effects. Calling a function once is the same as calling it twice and discarding the result of the first call.
2. ^ Brian Lonsdorf (2015). "Professor Frisby's Mostly Adequate Guide to Functional Programming". GitHub. Retrieved 2020-03-20. A pure function is a function that, given the same input, will always return the same output and does not have any observable side effect.
3. ^ "Common Function Attributes - Using the GNU Compiler Collection (GCC)". gcc.gnu.org, the GNU Compiler Collection. Free Software Foundation, Inc. Retrieved 2018-06-28.
4. ^ Fortran 95 language features#Pure Procedures
5. ^ Peyton Jones, Simon L. (2003). Haskell 98 Language and Libraries: The Revised Report (PDF). Cambridge, United Kingdom: Cambridge University Press. p. 95. ISBN 0-521 826144. Retrieved 17 July 2014.
6. ^ Hanus, Michael. "Curry: An Integrated Functional Logic Language" (PDF). www-ps.informatik.uni-kiel.de. Institut für Informatik, Christian-Albrechts-Universität zu Kiel. p. 33. Archived from the original (PDF) on 25 July 2014. Retrieved 17 July 2014.
7. ^ "Common Function Attributes - Using the GNU Compiler Collection (GCC)". gcc.gnu.org, the GNU Compiler Collection. Free Software Foundation, Inc. Retrieved 2018-06-28.
8. ^ Pure attribute in Fortran
9. ^ Pure attribute in D language
10. ^ "Common Function Attributes". Using the GNU Compiler Collection (GCC. Retrieved 22 July 2021.
11. ^ constexpr attribute in C++