Example: for (...) sum += i;
Procedural programming — organizes code into reusable procedures (e.g., C, Pascal).
Object-oriented programming (OOP) — organizes code around mutable objects that have state and behavior (e.g., Java, C++, Python).
Example: sum = range(1,6).reduce((a,b)->a+b);
Declarative styles include functional, logic, and SQL programming — where you describe relationships or transformations instead of procedures.
It is a programming paradigm where computation is treated as evaluation of mathematical functions, avoiding changing state and mutable data.
Pure functions
A function’s output depends only on its input.
It does not change anything outside itself (no side effects).
Example in pseudo-code:
f(x) = x * 2
f(3) = 6
Every time you call f(3), you get 6. No surprises.
Immutability
Data cannot be changed after creation.
Instead of modifying data, you create new data structures.
First-class and higher-order functions
Functions can be passed around as values.
Functions can return other functions.
applyTwice(f, x) = f(f(x))
No side effects
Side effects are things like changing a global variable, writing to a file, or modifying an object. FP minimizes or isolates these.
Predictable and easy to test
Pure functions are deterministic: same input → same output.
Testing and debugging become simpler.
Easier concurrency and parallelism
No shared state → no race conditions.
Ideal for multi-core and distributed systems.
Composability
Functions can be combined like building blocks.
Encourages small, reusable pieces of code.
Clearer reasoning
Functional code often expresses what to do rather than how to do it.
This aligns more closely with math reasoning.
Less bugs due to immutable state
Since data isn’t modified, you avoid side-effect-related bugs.
Immutable data can mean more memory allocations and copying. Modern FP languages (like Haskell, Scala, or functional features in Java, Python, or Rust) have optimizations like lazy evaluation, persistent data structures, and tail-call optimization to mitigate this.