Pure Functions

February 7, 2025
javascript

A pure function is a function that, given the same inputs, will always return the same output and has no side effects. It's a fundamental concept in functional programming that makes code more predictable, testable, and easier to reason about.

Key Characteristics

  • Deterministic: Same inputs always produce same outputs
  • No side effects: Doesn't modify external state
  • No external dependencies: Only relies on its input parameters

Example

// Pure function
function add(a, b) {
  return a + b;
}

// Impure function (has side effects)
let total = 0;
function addToTotal(value) {
  total += value;  // Modifies external state
  return total;
}

// Pure function
function formatName(firstName, lastName) {
  return `${firstName} ${lastName}`;
}

// Impure function (depends on external state)
const config = { titleCase: true };
function formatNameWithConfig(firstName, lastName) {
  if (config.titleCase) {
    return `${firstName.toUpperCase()} ${lastName.toUpperCase()}`;
  }
  return `${firstName} ${lastName}`;
}

Benefits of Pure Functions

  • Easier to test: Input/output relationship is clear and consistent
  • Cacheable: Results can be memoized since outputs are predictable
  • Self-documenting: Function behavior is determined solely by its inputs
  • Concurrent code: Pure functions can safely run in parallel

Common Use Cases

Pure functions are especially useful in:

  • Data transformations
  • Mathematical computations
  • Functional programming patterns
  • Redux reducers
  • React components (ideally)

Converting Impure to Pure

// Impure function
function calculateTotal(items) {
  let total = 0;
  for(let i = 0; i < items.length; i++) {
    total += items[i].price * items[i].quantity;
  }
  items.forEach(item => item.total = item.price * item.quantity); // Side effect!
  return total;
}

// Pure version
function calculateTotal(items) {
  return items.reduce((total, item) => 
    total + (item.price * item.quantity), 0);
}

function calculateItemTotals(items) {
  return items.map(item => ({
    ...item,
    total: item.price * item.quantity
  }));
}