What is a pure function and why is it desirable?
Show answer — try answering out loud first
A pure function is one that, given the same inputs, always returns the same output and produces no side effects (it doesn't modify anything outside itself). They are desirable because they are predictable, easy to test, and easy to reuse.
A function is pure if it follows two rules:
- Deterministic: with the same arguments, it always returns the same result.
- No side effects: it doesn't modify external variables, doesn't change its arguments, doesn't print to the console, doesn't write to disk, and doesn't make requests.
The opposite is an impure function: it depends on something external or changes something external.
Pure functions are easier to test (you just check the input and the output) and easier to reason about (you don't have to worry about what they touch outside).
// PURE: same input, same output, no side effects
function sumar(a, b) {
return a + b;
}
console.log(sumar(2, 3)); // always 5
// IMPURE: depends on an external variable
let impuesto = 0.16;
function precioConImpuesto(precio) {
return precio * (1 + impuesto); // if impuesto changes, the result changes
}
// IMPURE: modifies its argument (side effect)
function agregarItem(carrito, item) {
carrito.push(item); // mutates the original array
return carrito;
}
// PURE version: creates a copy instead of mutating
function agregarItemPura(carrito, item) {
return [...carrito, item]; // returns a new array
}
const original = ["a"];
const actualizado = agregarItemPura(original, "b");
console.log(original); // ["a"] (untouched)
console.log(actualizado); // ["a", "b"]
Thinking a function is pure just because it has a return. If inside it modifies an array it received as a parameter, or depends on an external variable that can change, it's already impure. Mutating the arguments is the most common and hardest-to-detect side effect.
"A pure function always returns the same result for the same inputs and has no side effects: it doesn't modify external variables or its own arguments. They are desirable because they are predictable and very easy to test, since I only have to check the input and the output. Whenever I can, I avoid mutating the arguments and instead return new copies, for example using the spread operator."
Turn this impure function into a pure one:
let total = 0;
function acumular(n) {
total += n;
return total;
}
See answer
// Pure: receives the accumulated total and returns the new one, no external state
function acumular(total, n) {
return total + n;
}
console.log(acumular(0, 5)); // 5
console.log(acumular(5, 3)); // 8