Programming · paradigms · concepts
What is functional programming?
You've probably heard the term thrown around — "FP", "pure functions", "no side effects", "Haskell". Functional programming (FP) is a way of writing software that builds programs out of functions applied to values, rather than sequences of statements that change shared state. This guide explains what FP really is, its core ideas, how it differs from the imperative and object-oriented styles, the honest trade-offs, and where a language like Haskell fits in.
The short definition
Functional programming is a style of building programs by composing pure functions and avoiding shared, mutable state. You describe what you want computed as transformations of values, rather than spelling out how to mutate variables step by step. The same inputs always produce the same outputs, which makes code easier to reason about and test.
The core ideas
Pure functions. A pure function depends only on its inputs and produces only a return value — no reading or writing of outside state, no surprises. Call it with the same arguments and you always get the same result.
Immutability. Instead of changing data in place, you create new values. A "modified" list is actually a new list; the original is untouched. This removes a whole category of bugs caused by something changing data you didn't expect.
Functions as first-class values. Functions can be passed as arguments, returned from other functions, and stored in variables — so you build behaviour by combining small functions (map, filter, reduce are the everyday examples).
Declarative over imperative. You say what the result should be, not the exact loop-and-mutate steps to get there.
A quick contrast
Imperative code often loops and mutates a running total:
total = 0
for n in numbers:
total = total + n # mutating 'total' each step Functional code expresses the same idea as a transformation of values, with no mutation:
total = sum(map(double, numbers)) # describe the result, not the steps Both compute a number; the functional version has no changing state to track, which is easier to test and parallelise.
How it differs from OOP
Object-oriented programming organises code around objects that bundle data with methods that often mutate that data. Functional programming keeps data and behaviour separate: data is immutable values, behaviour is pure functions that transform them. The two aren't enemies — many modern languages (Python, JavaScript, Kotlin, Scala) mix both — but the mindset differs: minimise state and side effects rather than encapsulate and mutate them.
Where Haskell fits
Most mainstream languages are multi-paradigm and let you write in a functional style. A few are purely functional, and Haskell is the best-known: purity and immutability aren't optional conveniences but enforced by the language and its type system, and side effects (like input/output) are made explicit — which is exactly what monads are for. Learning FP in a language that enforces it tends to make the ideas click faster.
The honest trade-offs
FP isn't a silver bullet. The strengths: code that's easier to reason about, test and run in parallel, with fewer state-related bugs. The costs: a learning curve (recursion and higher-order functions instead of loops), and some problems (heavy in-place mutation, certain performance-critical paths) map less naturally to a pure style. In practice most teams adopt functional habits — pure functions, immutability where it helps — without going fully pure.
FAQ
What is functional programming in simple terms? A style of building programs from pure functions that transform values, while avoiding shared, mutable state — so the same inputs always give the same outputs.
What is a pure function? A function whose result depends only on its inputs and that has no side effects (it doesn't read or change outside state). It's the building block of FP.
Is functional programming better than OOP? Neither is universally better. FP excels at predictability, testing and parallelism; OOP at modelling stateful entities. Many languages let you combine both.
Which languages are functional? Haskell is purely functional. Many others support the style well — Scala, Elixir, Clojure, F#, and even Python and JavaScript via first-class functions.
Functional code is still made of step-by-step logic underneath — see what an algorithm is — and the purest place to learn the style is Haskell. Browse more clear explainers in our guides index.