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

codeTap to expand ⛶
1// Pure function — no side effects, deterministic
2const add = (a, b) => a + b; // Pure ✅
3// let total = 0; const addImpure = (x) => total += x; // Impure ❌
4
5// Immutability
6const original = [1, 2, 3];
7const withFour = [...original, 4]; // New array, original unchanged
8const user = { name: "Alice", age: 25 };
9const older = { ...user, age: 26 }; // New object
10
11// Function composition
12const pipe = (...fns) => (x) => fns.reduce((v, f) => f(v), x);
13const compose = (...fns) => (x) => fns.reduceRight((v, f) => f(v), x);
14
15const processUser = pipe(
16 (name) => name.trim(),
17 (name) => name.toLowerCase(),
18 (name) => `user_${name}`
19);
20console.log(processUser(" ALICE ")); // "user_alice"
21
22// Functors (mappable containers)
23const Maybe = (value) => ({
24 map: (fn) => value == null ? Maybe(null) : Maybe(fn(value)),
25 getOrElse: (defaultVal) => value ?? defaultVal,
26 value
27});
28const result = Maybe("hello")
29 .map(s => s.toUpperCase())
30 .map(s => s + "!")
31 .getOrElse("default");
32console.log(result); // "HELLO!"
33
34// Pipe operator equivalent
35const 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])); // 20
41
42// Immutable updates with reduce
43const 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:

  1. Refactor imperative code to use pure functions and immutability
  2. Build a pipe function and use it to transform data step by step
  3. Implement a Maybe monad for null-safe chaining
  4. 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 structuredClone or libraries like Immer for deeply nested updates

  • Over-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, .reduce ARE 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.