Pure function

Pure function #

Functional languages like Haskell favor pure functions, which behave like mathematical functions.

In imperative code, their adoption varies by language and community. For instance, pure functions are not idiomatic in C, but common in languages like Java, JavaScript, Python or Rust.

Side effect #

Definition. A method/function has a side effect if it modifies a resource (variable, object, array, etc.) that is defined outside of its scope.

Purity #

A method/function is pure if it:

  1. has no side-effect, and
  2. returns the same value when called twice with the same argument(s).

Counterexample #

Example. Consider the following two Java methods:

public class MyClass {

    int x = 0;

    ...

    boolean inc() {
        x++;
        return true;
    }

    boolean isEqual(int y) {
        return x == y;
    }
}
  • inc is not pure, because it violates Condition 1 (side effect).
  • isEqual is not pure either, because it violates Condition 2. For instance, if:
    • x has value 0,
    • then isEqual(0) is executed,
    • then inc() is executed,
    • then isEqual(0) is executed again.

Benefits #

Readability #

The behavior of a pure function is fully specified by its arguments.

Easier debugging #

Because it has no side effect, a pure function may cause a bug only if it returns an incorrect value.

Opportunities for static analysis (comparing programs, simplifying a program, etc.) #

Examples. If f and g are pure functions, then for two variables x and y:

  • f(x) == f(x) can be replaced with true,
  • f(x) || g(y) can be replaced with g(y) || f(x).

Parallelization #

Example. If f and g are pure functions, then for some values a,b, we can evaluate

$\qquad$ f(a) + g(b)

by evaluating f(a) and g(b) in parallel.

Caching #

Example. If f is a pure function, then for a value a, we can evaluate

$\qquad$ f(a) + f(a)

by evaluating f(a) once (and caching the result).