Core FP Concepts
Functional programming treats functions as values and emphasizes pure functions and immutability. JavaScript supports FP natively alongside OOP — use both where they fit.
// Pure functions: same input, always same output, no side effects:
const add = (a, b) => a + b; // pure
let total = 0;
function addToTotal(n) { total += n; } // impure — modifies external state
// Immutability — create new instead of mutating:
const arr = [1, 2, 3];
const newArr = [...arr, 4]; // new array
const obj = { a: 1 };
const newObj = { ...obj, b: 2 }; // new object
// Array methods are functional:
const result = [1,2,3,4,5]
.filter(n => n % 2 === 0) // [2,4]
.map(n => n ** 2) // [4,16]
.reduce((sum, n) => sum + n, 0); // 20
Currying & Composition
// Curry — one arg at a time:
const multiply = a => b => a * b;
const double = multiply(2);
const triple = multiply(3);
[1,2,3].map(double); // [2,4,6]
[1,2,3].map(triple); // [3,6,9]
// Partial application:
const add = a => b => a + b;
const add10 = add(10);
[1,2,3].map(add10); // [11,12,13]
// Pipe — left to right composition:
const pipe = (...fns) => x => fns.reduce((v, f) => f(v), x);
const processName = pipe(
s => s.trim(),
s => s.toLowerCase(),
s => s.replace(/ /g, "-")
);
processName(" Hello World "); // "hello-world"
// Compose — right to left:
const compose = (...fns) => x => fns.reduceRight((v, f) => f(v), x);
// Point-free style:
const isEven = n => n % 2 === 0;
const negate = fn => (...args) => !fn(...args);
const isOdd = negate(isEven);
[1,2,3,4,5].filter(isOdd); // [1,3,5]
⚡ Key Takeaways
- Pure functions: deterministic, no side effects — easy to test
- Immutability prevents accidental shared state bugs
- Curry: multi-arg to chain of single-arg — enables partial application
- Pipe: compose functions left-to-right — readable data transforms
- FP and OOP are complementary — use each where it shines
🎯 Practice Exercises
EXERCISE 1
Build a data pipeline with pipe(): validate → normalize → transform → format a list of user objects. Each step is a pure function.