Functional Programming
📖 Concept
Functional Programming (FP) is a paradigm that treats computation as evaluating mathematical functions, avoiding state mutation and side effects.
Core Principles:
- Pure Functions — Same inputs always produce same outputs; no side effects
- Immutability — Data is never modified; new copies are created
- First-Class Functions — Functions are values (passed, returned, stored)
- Composition — Build complex functions from simple ones
- Declarative — Describe WHAT, not HOW
🏠 Real-world analogy: FP is like a mathematical equation. f(x) = x + 1 — it always returns the same result for the same input, never changes x itself, and has no hidden side effects. Imperative programming is like a recipe with mutable ingredients.
💻 Code Example
1// Pure function — no side effects, deterministic2const add = (a, b) => a + b; // Pure ✅3// let total = 0; const addImpure = (x) => total += x; // Impure ❌45// Immutability6const original = [1, 2, 3];7const withFour = [...original, 4]; // New array, original unchanged8const user = { name: "Alice", age: 25 };9const older = { ...user, age: 26 }; // New object1011// Function composition12const pipe = (...fns) => (x) => fns.reduce((v, f) => f(v), x);13const compose = (...fns) => (x) => fns.reduceRight((v, f) => f(v), x);1415const processUser = pipe(16 (name) => name.trim(),17 (name) => name.toLowerCase(),18 (name) => `user_${name}`19);20console.log(processUser(" ALICE ")); // "user_alice"2122// Functors (mappable containers)23const Maybe = (value) => ({24 map: (fn) => value == null ? Maybe(null) : Maybe(fn(value)),25 getOrElse: (defaultVal) => value ?? defaultVal,26 value27});28const result = Maybe("hello")29 .map(s => s.toUpperCase())30 .map(s => s + "!")31 .getOrElse("default");32console.log(result); // "HELLO!"3334// Pipe operator equivalent35const transform = pipe(36 (arr) => arr.filter(x => x > 0),37 (arr) => arr.map(x => x * 2),38 (arr) => arr.reduce((sum, x) => sum + x, 0)39);40console.log(transform([-1, 2, 3, -4, 5])); // 204142// Immutable updates with reduce43const addItem = (list, item) => [...list, item];44const removeItem = (list, index) => list.filter((_, i) => i !== index);45const updateItem = (list, index, fn) =>46 list.map((item, i) => i === index ? fn(item) : item);
🏋️ Practice Exercise
Mini Exercise:
- Refactor imperative code to use pure functions and immutability
- Build a
pipefunction and use it to transform data step by step - Implement a Maybe monad for null-safe chaining
- Write a point-free style solution for a data transformation pipeline
⚠️ Common Mistakes
Going 100% pure is impractical — I/O, DOM, network are inherently impure; isolate them at boundaries
Excessive immutability with deep nesting — use
structuredCloneor libraries like Immer for deeply nested updatesOver-composing simple operations — sometimes a loop is more readable than 5 composed functions
Confusing FP concepts from Haskell/ML with JavaScript's pragmatic FP — JS is multi-paradigm
Not understanding that
.map,.filter,.reduceARE functional programming — you're likely already using FP
💼 Interview Questions
🎤 Mock Interview
Mock interview is powered by AI for Functional Programming. Login to unlock this feature.