- Pure Functions — output depends only on input; no hidden state or side effects.
- Immutability — data never changes; create new values instead of mutating existing ones.
- Referential Transparency — any expression can be replaced with its evaluated result without changing program behavior.
- Higher-Order Functions — either takes function(s) as argument(s) or returns a function(s) as its result.
- Function Composition — build complex transformations by composing small functions in chains.
- Point-Free Style — define transformations by combining functions, not naming intermediate data.
- Currying — transform a function of many arguments into a chain of single-argument functions.
- Partial Application — pre-fill some arguments to produce specialized functions.
- Algebraic Data Types (ADTs) — is a composite data (type combining other types).
- Total Functions — function must return a valid result for every valid input in its type.
- No Hidden State — avoid local mutation and invisible transitions; state is always explicit.
- Explicit Effects — model I/O, randomness, time, async, or errors using types (Option, Either, Result, IO, Task).
- Lazy Evaluation — defer computation until needed; represent infinite sequences naturally.
- Idempotence — repeated evaluation yields the same result without accumulating side effects.
- Declarative Style — describe "what" to compute, not "how" to compute it step-by-step.
- Pipeline Processing — linear data flow; avoid branching when possible by chaining operations.
- Stateless Concurrency — parallelize pure computations without synchronization.
- Determinism — same inputs always produce the same outputs; easy reproducibility.
- Abstraction — hide internal representation via functions instead of classes.
- Separation of Concerns — isolate independent transformations, modules, and pipelines.
- Tell, Don’t Ask (in FP terms) — push data into transformations rather than pulling fields for manual operations.
- Information Hiding — control visibility via module boundaries, closure scope, or type privacy.
- Law of Demeter — avoid deep object paths; use direct parameters and simple shapes.
- Composition over Inheritance — FP is fundamentally compositional; small functions compose into larger ones.
- Generics / Parametric Polymorphism — type-safe reuse of functions across many data types.
