← Concepts

阅读中文版本

Closure of Operations

Closure of operations means an operation on a value of a type returns a value of the same type, enabling composition and chaining without type-casing at every step.

architecture

Definition

Closure of operations is a design property where an operation that takes values of type T returns a value of type T, so that the output of one operation can be the input of the next without conversion, enabling fluent composition, chaining, and algebraic reasoning about the combined behavior.

Context and scope

Applied in collection APIs, parser combinators, monetary calculations, and any domain where composing small operations into pipelines is the dominant usage pattern.

Common misconceptions

  • Closure is just method chaining — chaining is the syntactic consequence; closure is the semantic property that makes the chain type-check and compose meaningfully
  • Closure requires immutability — it requires that the type is preserved; immutability is a separate property that makes the operations safe to compose

Anti-patterns

  • Returning an Option from a find but a raw value from a get, forcing the caller to type-case at every step
  • Designing a fluent API where one method in the chain returns a different type, breaking the composition

Related concepts

Authoritative source

https://en.wikipedia.org/wiki/Closure_(mathematics)

What it is

Closure of operations is a design property where an operation that takes values of type T returns a value of type T, so that the output of one operation can be the input of the next without conversion, enabling fluent composition, chaining, and algebraic reasoning about the combined behavior. Applied in collection APIs, parser combinators, monetary calculations, and any domain where composing small operations into pipelines is the dominant usage pattern. The organizing principle is which decisions are hard to reverse and should be made once, versus which are easy to reverse and should be deferred.

How it works

Boundaries are drawn along axes of change: things that change together are colocated, things that change independently are separated by interfaces whose contracts are explicit and versioned. Dependencies point toward stability — domain logic depends on abstractions, infrastructure depends on domain, never the reverse. The structure makes the system’s intent legible without reading every module.

When to choose and pitfalls

Choose this structure when the system will outlive its first deployment and face requirements you cannot now predict. The pitfall is premature abstraction — adding indirection for a flexibility that never materializes, paying its complexity cost forever. The opposite pitfall is entangling concerns that later need to separate, forcing a rewrite instead of a refactor.