Paradigm Deep Dive · 03 of 04

Functional Programming

Programs are built from pure functions — predictable mathematical mappings of input to output. No hidden state, no surprises.

← Back to Foundations
Foundations

What Is Functional Programming?

If procedural says "do this then that" and OOP says "ask this object to do that," functional says "this is a transformation of input into output."

Basic Concepts

  • Pure Function: same input always produces the same output, with no side effects.
  • Immutability: data never changes; you create new versions instead.
  • First-Class Functions: functions are values you can pass around, return, store.
  • Higher-Order Functions: functions that take or return other functions (map, filter, reduce).
  • Recursion often replaces loops.
Pillars

The Five Pillars of FP

1
Pure Functions

No side effects. Easy to test, cache, parallelize, and reason about.

2
Immutability

Once created, values don't change. Eliminates whole classes of bugs.

3
Function Composition

Build big behaviors by chaining small functions: f(g(x)).

4
Declarative Style

Say what you want, not how to compute it. map over for.

5
Referential Transparency

An expression can be replaced with its value without changing program meaning.

Building Blocks

FP Mechanics

Higher-Order Functions: map, filter, reduce
// JavaScript — sum of squares of even numbers
const result = [1, 2, 3, 4, 5, 6]
    .filter(n => n % 2 === 0)   // [2, 4, 6]
    .map(n => n * n)            // [4, 16, 36]
    .reduce((a, b) => a + b, 0); // 56

Same logic in procedural style would need a loop, a temp variable, and three if/accumulator steps.

Currying & Partial Application
const add = a => b => a + b;     // curried
const add5 = add(5);             // partial application
add5(3); // 8

Building specialized functions from general ones, by fixing some arguments up front.

Recursion & Tail Calls
-- Haskell: factorial
factorial :: Int -> Int
factorial 0 = 1
factorial n = n * factorial (n - 1)

FP languages often optimize tail recursion into loops, so you don't blow the stack.

Algebraic Data Types & Pattern Matching
-- Haskell: define an algebraic type, match on its shape
data Shape = Circle Double | Square Double | Rectangle Double Double

area :: Shape -> Double
area (Circle r)         = pi * r * r
area (Square s)         = s * s
area (Rectangle w h)    = w * h

Algebraic data types + pattern matching = a uniquely powerful way to model data.

Monads (the Friendly Tour)

A monad is a wrapper around a value with a standard way to chain operations. Examples:

  • Maybe / Option — value or nothing (no nulls).
  • Either / Result — success or error (no exceptions).
  • Promise / Future — async value.
  • IO — controlled side effects.

If you've used .then() on JavaScript Promises, you've used a monad — without the scary name.

Lazy Evaluation

Don't compute a value until it's actually needed. Enables infinite data structures (like an infinite list of primes) and big performance wins.

Languages

FP Languages

LanguageStyleNotes
Lisp / Scheme / ClojurePure-ish, dynamicCode is data; macros are unmatched.
HaskellPure, lazy, typedThe textbook FP language. Pure functions enforced by the type system.
F#Pragmatic, .NETOCaml-derived; runs on .NET; great interop with C#.
OCamlPragmaticPowers Jane Street, parts of Facebook, Coq.
Erlang / ElixirConcurrentMassive concurrency on the BEAM VM. Powers WhatsApp, Discord.
ScalaHybridOOP + FP on the JVM.
JavaScript / PythonMulti-paradigmEmbrace many FP idioms — map, filter, lambdas.
Trade-offs

Strengths & Weaknesses

Strengths
  • Pure functions are trivially testable and parallelizable.
  • Immutability eliminates many concurrency bugs.
  • Concise — small code that says a lot.
  • Strong types catch entire categories of bugs at compile time.
Weaknesses
  • Steeper learning curve, esp. monads & type theory.
  • Performance can suffer if immutability isn't optimized.
  • Hiring is harder — fewer FP-fluent developers.
  • Real-world side effects (I/O, DBs) require extra ceremony.
When to Use

Sweet Spots

Data Pipelines

ETL, analytics, transforming streams of records.

Concurrency-Heavy Systems

Erlang/Elixir for chat, telecom, real-time messaging.

Finance & Quant

Trading rules, pricing models — math maps cleanly to functions.

Compilers & DSLs

OCaml, Haskell shine when transforming trees of code.

Frontend State

React + Redux is FP-flavored — pure reducers, immutable state.

Distributed Systems

Immutability + message passing make consensus easier.

Continue

Other Paradigm Deep Dives