Functional-programming Patterns Reference

Patterns based on composition, immutability, and explicit effects.

Functional-programming Patterns Reference

Intent, fit, trade-offs, and relationships for reusable functional techniques.

Updated 2026-07-22

Pure Function

Return a result determined only by inputs without observable side effects.

AspectGuidance
Use whenLogic should be predictable, testable, cacheable, and safely composable.
Trade-offsReal programs still need effects, so boundaries and effect descriptions must be explicit.
RelatedImmutability, Memoization

Immutability

Represent a change by producing a new value rather than modifying an existing one.

AspectGuidance
Use whenValues are shared, compared, replayed, or processed concurrently.
Trade-offsNaive copying costs memory; APIs and data structures must support efficient updates.
RelatedPersistent Data Structure, Lens

Higher-order Function

Accept functions as inputs or return functions as results.

AspectGuidance
Use whenBehavior should be abstracted from traversal, timing, policy, or data shape.
Trade-offsDeep callback layers and abstract signatures can reduce readability.
RelatedFunction Composition, Closure

Function Composition

Create a transformation by feeding each function’s result to the next.

AspectGuidance
Use whenA workflow can be expressed as small compatible transformations.
Trade-offsTypes, error channels, and asynchronous boundaries must align.
RelatedPipeline, Higher-order Function

Pipeline

Pass a value through a readable ordered sequence of transformations.

AspectGuidance
Use whenData processing is naturally staged from input to output.
Trade-offsBranching, shared context, and mixed sync/async steps weaken a simple pipeline.
RelatedFunction Composition, Pipes and Filters

Currying

Transform a multi-argument function into a series of one-argument functions.

AspectGuidance
Use whenFunctions should be specialized incrementally or composed in unary APIs.
Trade-offsCalling conventions become unfamiliar and language support varies.
RelatedPartial Application, Closure

Partial Application

Create a new function by fixing some arguments of an existing function.

AspectGuidance
Use whenRepeated calls share configuration or dependencies.
Trade-offsHidden bound values can make behavior and signatures less obvious.
RelatedCurrying, Dependency Injection

Closure

Combine a function with values captured from its lexical environment.

AspectGuidance
Use whenBehavior needs private state or configuration without a class.
Trade-offsCaptured mutable state, memory retention, and stale values can surprise callers.
RelatedHigher-order Function, Partial Application

Memoization

Cache function results by input so repeated calls reuse prior work.

AspectGuidance
Use whenA pure computation is expensive and inputs repeat.
Trade-offsKey equality, memory growth, invalidation, and sensitive inputs require policy.
RelatedPure Function, Lazy Evaluation

Map

Apply a function to each contained value while preserving structure.

AspectGuidance
Use whenEvery element needs the same independent transformation.
Trade-offsSide effects inside mapping obscure evaluation order and intent.
RelatedFunctor, Filter, Fold

Filter

Retain elements that satisfy a predicate.

AspectGuidance
Use whenSelection should be expressed independently of traversal.
Trade-offsMultiple filter passes may be less efficient than one composed fold.
RelatedMap, Fold

Fold

Collapse a structure into a result using a combining function and accumulator.

AspectGuidance
Use whenAggregation or traversal can be defined from one composable primitive.
Trade-offsDirection, associativity, initial values, and short-circuit behavior matter.
RelatedMap, Recursion

Persistent Data Structure

Preserve previous versions while sharing unchanged structure with new versions.

AspectGuidance
Use whenImmutable updates need practical memory and time costs.
Trade-offsConstants, cache locality, and interoperability may differ from mutable structures.
RelatedImmutability, Lens

Lens

Compose a focused getter with an immutable updater for nested data.

AspectGuidance
Use whenDeep immutable structures require reusable, type-safe access and updates.
Trade-offsOptics terminology and abstractions can outweigh benefits for shallow models.
RelatedImmutability, Function Composition

Algebraic Data Type

Model data using explicit product and alternative cases.

AspectGuidance
Use whenA finite set of valid states should be represented and checked exhaustively.
Trade-offsChanging cases affects consumers and some languages emulate the feature awkwardly.
RelatedPattern Matching, Option, Result

Pattern Matching

Select and bind behavior by the structural form of data.

AspectGuidance
Use whenCode handles explicit variants or recursively shaped values.
Trade-offsNon-exhaustive matches fail and large matches can centralize too much behavior.
RelatedAlgebraic Data Type, Visitor

Option

Represent either a present value or explicit absence.

AspectGuidance
Use whenMissing data is expected and should not use null or exceptions.
Trade-offsCallers must unwrap or transform the context and nested options can become noisy.
RelatedResult, Functor

Result

Represent either a success value or a structured failure value.

AspectGuidance
Use whenFailure is expected, recoverable, and part of a function contract.
Trade-offsError types and combination rules require design; unexpected defects still need another path.
RelatedOption, Monad

Functor

Apply an ordinary function to values inside a context while preserving that context.

AspectGuidance
Use whenMany structures need a common map-like transformation.
Trade-offsThe abstraction helps only when laws and context behavior are understood.
RelatedMap, Applicative

Applicative

Combine independent computations that each occur inside a context.

AspectGuidance
Use whenThe structure of a computation is known without depending on earlier values.
Trade-offsLess flexible than monadic sequencing and syntax support varies.
RelatedFunctor, Monad

Monad

Sequence contextual computations where each next step depends on the prior result.

AspectGuidance
Use whenErrors, state, async work, parsing, or effects need composable chaining.
Trade-offsAbstraction, nested contexts, and language-specific notation raise the learning cost.
RelatedApplicative, Result

Recursion

Solve a problem by defining base cases and combining smaller instances.

AspectGuidance
Use whenData or computation is naturally recursive, such as trees or divide-and-conquer.
Trade-offsDeep calls can exhaust the stack and missing progress causes nontermination.
RelatedFold, Tail Recursion

Tail Recursion

Place the recursive call in final position so an implementation may reuse the stack frame.

AspectGuidance
Use whenA recursive loop targets a runtime that guarantees tail-call optimization.
Trade-offsMany common runtimes do not optimize it, and accumulator style can be less direct.
RelatedRecursion, Trampoline

Trampoline

Represent recursive continuation steps as values and execute them in a loop.

AspectGuidance
Use whenDeep recursion must remain stack-safe without runtime tail-call optimization.
Trade-offsAllocates step objects and complicates debugging and return types.
RelatedTail Recursion, Continuation

Lazy Evaluation

Delay a computation until its value is demanded and optionally retain the result.

AspectGuidance
Use whenValues may never be needed or infinite and expensive structures are useful.
Trade-offsTiming, memory retention, error location, and performance become less predictable.
RelatedMemoization, Generator

Description

Patterns based on composition, immutability, and explicit effects.

References

Similar or alternative tools

Don't forget to set a bookmark for tool.io!
Privacy | Imprint | Cookies