The Codex / JavaScript / Functional Programming

Functional Programming

Pure functions, immutability, composition, currying, and higher-order functions — the functional style in JavaScript.

What it is, in plain English: Functional programming (FP) is a style where you build programs by composing pure functions — functions that always return the same output for the same input and cause no side effects. JavaScript is a multi-paradigm language that supports FP natively: functions are first-class values, arrays have map/filter/reduce, and the spread operator enables immutable updates. FP principles make code more predictable, testable, and easier to reason about.

The functional style — build programs from small, reliable pieces

Functional programming is a way of writing code where every function is a pure calculation: same input always gives the same output, and nothing is modified. JavaScript isn't a purely functional language, but applying FP ideas makes code much easier to test and reason about.

Pure functions — predictable and testable

// Impure — depends on external state, unpredictable:
let tax = 0.18;
function calculateTotal(price) {
  return price + price * tax;   // depends on external 'tax' variable
}
// If tax changes, the function gives different results for the same price!

// Pure — all inputs are parameters, no external dependencies:
function calculateTotalPure(price, taxRate) {
  return price + price * taxRate;
}
console.log(calculateTotalPure(100, 0.18));  // always 118
console.log(calculateTotalPure(100, 0.18));  // still 118

// Pure functions are trivial to test:
// test("100 at 18% = 118", () => assert(calculateTotalPure(100, 0.18) === 118))

Immutability — never mutate, always return new

// Mutable (bad for FP):
function addItemMutable(cart, item) {
  cart.push(item);   // modifies the original — side effect!
  return cart;
}

// Immutable (FP style):
function addItem(cart, item) {
  return [...cart, item];   // returns a NEW array, original unchanged
}

const cart1 = ["apple", "banana"];
const cart2 = addItem(cart1, "cherry");

console.log(cart1);  // ["apple", "banana"] — unchanged
console.log(cart2);  // ["apple", "banana", "cherry"] — new array

// Same for objects:
const user = { name: "Alice", score: 90 };
const updated = { ...user, score: 95 };   // new object
console.log(user.score);    // 90 — original safe
console.log(updated.score); // 95

map / filter / reduce — the FP trinity

const products = [
  { name: "Laptop",  price: 60000, inStock: true  },
  { name: "Phone",   price: 25000, inStock: false },
  { name: "Tablet",  price: 30000, inStock: true  },
  { name: "Monitor", price: 15000, inStock: true  },
];

// filter — keep items matching a condition:
const available = products.filter(p => p.inStock);

// map — transform each item:
const discounted = available.map(p => ({
  ...p,
  price:     Math.round(p.price * 0.9),
  discount:  "10% off"
}));

// reduce — fold into a single value:
const total = discounted.reduce((sum, p) => sum + p.price, 0);

console.log(`${discounted.length} items available`);
console.log(`Total: ₹${total.toLocaleString("en-IN")}`);

// Chain them:
const totalDiscount = products
  .filter(p => p.inStock)
  .map(p => p.price * 0.1)
  .reduce((sum, d) => sum + d, 0);
console.log(`Total savings: ₹${totalDiscount.toLocaleString("en-IN")}`);

Higher-order functions — functions that work with functions

// A function that returns another function:
function multiplier(factor) {
  return (n) => n * factor;
}

const double = multiplier(2);
const triple = multiplier(3);
const halve  = multiplier(0.5);

console.log(double(10));  // 20
console.log(triple(10));  // 30
console.log(halve(10));   // 5

// A function that takes another function:
function applyTwice(fn, value) {
  return fn(fn(value));
}
console.log(applyTwice(double, 3));   // 12 (doubled twice)
Try It Yourself

Official Sources

The Codex links only to official documentation and the ECMAScript specification. No third-party tutorials.