Functional Programming Concepts
Functional Programming Concepts in JavaScript
Pure functions, immutability, referential transparency, and declarative data pipelines.
The Pure Mathematics Calculator
Functional Programming (FP) treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data. It makes applications predictable, testable, and free of race conditions.
Pure Functions
A pure function has two traits: 1) Deterministic (always returns the same output for the same inputs), 2) Zero Side Effects (does not alter external variables, DOM, or database).
Referential Transparency
An expression or function call can be replaced with its evaluated result without changing the program behavior.
Immutability and Persistent Data
Data structures are never modified in place. Transformations return new objects or arrays, preventing race conditions.
Higher-Order Functions and Pipelines
Functions are combined using `map`, `filter`, `reduce`, `compose`, and `curry` to build declarative, point-free pipelines.
Refactoring mutable imperative code into an immutable, pure functional pipeline:
const transactions = [
{ id: 1, type: "income", amount: 1200 },
{ id: 2, type: "expense", amount: 200 },
{ id: 3, type: "income", amount: 450 },
{ id: 4, type: "expense", amount: 150 }
];
// Pure transformation pipeline (zero mutations of original data)
const calculateTotalIncome = (items) =>
items
.filter(t => t.type === "income")
.map(t => t.amount)
.reduce((acc, amount) => acc + amount, 0);
console.log("Total Income:", calculateTotalIncome(transactions));
console.log("Original data untouched:", transactions.length);
Total Income: 1650
Original data untouched: 4
Hidden Side Effects in Impure Helpers
The Risk: Functions that read `Date.now()`, `Math.random()`, or mutate global state are impure, making unit tests flaky and non-deterministic.
The Fix: Pass current time or random seeds as explicit arguments into functions rather than reading them internally.
- ✓ Pure Functions = Deterministic output + Zero side effects.
- ✓ Immutability: Always return new data instances instead of mutating existing objects.
- ✓ Referential Transparency: Calls can be substituted with their values.
- ✓ High reusability through function composition (`compose`, `pipe`).
- ✓ Eliminates whole classes of concurrency bugs and simplifies testing.