JavaScript Functional Programming: Pure Functions, Currying & Memoization

Functional Programming (FP) is a declarative programming paradigm where software is built by composing pure functions, avoiding shared mutable state, and eliminating side-effects.

1. Pure Functions vs. Impure Functions

// IMPURE FUNCTION (Depends on external mutable state & produces side-effects)
let taxRate = 0.18;
function calculateImpureTax(amount) {
    taxRate = 0.20; // SIDE-EFFECT: Mutates outer state!
    return amount * taxRate;
}

// PURE FUNCTION (Deterministic & Zero Side-Effects)
function calculatePureTax(amount, rate) {
    return amount * rate; // Always returns same output for same inputs!
}

2. Function Currying

Currying converts a multi-argument function into a chain of single-argument functions using closures:

// Standard multi-arg function:
const add = (a, b, c) => a + b + c;

// Curried Version:
const curriedAdd = a => b => c => a + b + c;

console.log(curriedAdd(10)(20)(30)); // 60

// Practical Use: Specialized reusable discount calculator
const applyDiscount = discountPercent => price => price * (1 - discountPercent / 100);

const studentDiscount = applyDiscount(25); // Specialized function
console.log(studentDiscount(1000)); // 750
console.log(studentDiscount(2000)); // 1500

3. Memoization (Caching Function Results)

function memoize(fn) {
    const cache = new Map();
    return function(...args) {
        const key = JSON.stringify(args);
        if (cache.has(key)) {
            console.log("Serving from Memoization Cache!");
            return cache.get(key);
        }
        const result = fn(...args);
        cache.set(key, result);
        return result;
    };
}

const expensiveFibonacci = memoize((n) => {
    if (n <= 1) return n;
    return expensiveFibonacci(n - 1) + expensiveFibonacci(n - 2);
});

console.log(expensiveFibonacci(40)); // Fast calculation with cache!

University Exam Corner (BCA Examination Notes)

Exam Question: "What are the benefits of Functional Programming in modern JavaScript?"

  • Predictability: Pure functions are trivially easy to test and reason about in isolation.
  • Concurrency Safety: Immutability guarantees that multiple async tasks cannot corrupt shared data simultaneously.
  • Reusability: Function composition allows constructing complex workflows from tiny, reusable building blocks.

Next Step

How do you optimize runtime performance, prevent memory leaks, and debounce heavy events? Proceed to: JavaScript Performance Optimization & Memory Leaks →

Share Share on Facebook Share on Twitter Share on LinkedIn Pin on Pinterest Share on Stumbleupon Share on Tumblr Share on Reddit Share on Diggit

You may also like this!