Skip to content

Future Or Promise

Prime #
874
Origin domain
Computer Science & Software Engineering
Subdomain
concurrency → Computer Science & Software Engineering
Aliases
Promise, Deferred Value

Core Idea

A future (or promise) is a first-class placeholder for a value that does not yet exist but is committed to be supplied later, together with a small protocol governing who fulfills it, who waits on it, what happens if it fails, and how downstream computations attach to it. The structural commitment has four components: a placeholder object that can be created, passed, stored, and reasoned about before the value exists; a producer side with authority to fulfill the placeholder with a value or reject it with a reason; a consumer side that can attach continuations or block until resolution; and a state machine through which the placeholder transitions exactly once from pending to either fulfilled or rejected, and stays there.

The pattern's structural sharpness lies in reifying the deferral itself. Without a future, code that depends on a not-yet-available value must block, poll, or tangle itself in callback inversion. With a future, the not-yet-available value becomes a thing — a referent that can be named, passed around, composed with other futures (race, all, sequence), chained with downstream operations, inspected, and reasoned about in types. The same reification is what makes async/await work: the future is the handle on which await operates. The pattern is sharper than "deferred resolution": a promise to be paid later may exist in informal practice, but a future as such requires that the deferred outcome be a first-class object — passable, composable, inspectable, with explicit fulfillment authority — and that requirement is what separates a promise from a mere expectation or hope. The substrate-neutral skeleton is the reified placeholder plus producer authority plus consumer attachment plus the once-only state machine, though many of its instances outside software carry an institutional flavour.

How would you explain it like I'm…

The Claim Ticket

Imagine you order food and they hand you a numbered ticket instead. The ticket isn't ice cream yet, but it's a real thing you can hold, save, or give to a friend. When your order is ready, the ticket turns into ice cream, or, if they ran out, into a "sorry" note. A future is that ticket for something that isn't ready yet.

Answer Coming Later

A future, also called a promise, is a placeholder object you get right away for a value that doesn't exist yet but is promised to come later. You can hold it, pass it around, and plan what to do with it before the real value shows up, like a claim ticket. One side, the producer, is in charge of filling it in with a result or marking it as failed. The other side, the consumer, can either wait for it or leave instructions for when it's ready. It changes exactly once, from "still waiting" to either "done" or "failed," and then it stays that way.

Placeholder For a Value

A future (or promise) is a first-class placeholder for a value that doesn't exist yet but is committed to arrive later, along with a small protocol for who fills it, who waits on it, what happens if it fails, and how later steps attach. It has four parts: a placeholder object you can create, pass, and store before the value exists; a producer side with the authority to fulfill it with a value or reject it with a reason; a consumer side that can attach follow-up steps or block until it resolves; and a state machine that moves exactly once from pending to either fulfilled or rejected and then stays put. The sharp idea is that it reifies the deferral itself: the not-yet-available value becomes an actual thing you can name, pass around, combine with other futures, and reason about. That is also exactly what makes async/await work, since the future is the handle that await operates on. It is sharper than just 'getting the answer later,' because a future as such requires the deferred outcome to be a real, passable, inspectable object with explicit fulfillment authority, which is what separates it from a mere hope or expectation.

 

A future, or promise, is a first-class placeholder for a value that does not yet exist but is committed to be supplied later, together with a small protocol governing who fulfills it, who waits on it, what happens if it fails, and how downstream computations attach to it. The structural commitment has four components: a placeholder object that can be created, passed, stored, and reasoned about before the value exists; a producer side with authority to fulfill the placeholder with a value or reject it with a reason; a consumer side that can attach continuations or block until resolution; and a state machine through which the placeholder transitions exactly once from pending to either fulfilled or rejected, and stays there. The pattern's sharpness lies in reifying the deferral itself. Without a future, code depending on a not-yet-available value must block, poll, or tangle itself in callback inversion. With a future, the not-yet-available value becomes a thing: a referent that can be named, passed, composed with other futures (race, all, sequence), chained with downstream operations, inspected, and reasoned about in types. That same reification is what makes async/await work, since the future is the handle on which await operates. The pattern is sharper than mere deferred resolution: a future as such requires the deferred outcome to be a first-class object, passable, composable, inspectable, with explicit fulfillment authority, and that requirement is what separates a promise from a mere expectation or hope.

Structural Signature

a reified placeholder for a not-yet-existing valuea producer holding fulfillment authoritya consumer attaching continuations or waitinga once-only state machine (pending → fulfilled | rejected)the deferral-reification invariantthe composition algebra over placeholders

An arrangement is a future/promise when the following hold:

  • A reified placeholder. A first-class object standing for a value that does not yet exist — created, named, passed, stored, and reasoned about before the value is available.
  • A producer with fulfillment authority. Exactly one party (or protocol) holds the right to settle the placeholder, either supplying a value or rejecting it with a reason. The authority is explicit, not ambient.
  • A consumer attaching intent. One or more parties attach continuations (what to do on resolution) or block awaiting it, without needing to know when resolution occurs.
  • A once-only state machine. The placeholder occupies exactly one of three states — pending, fulfilled, rejected — transitions out of pending at most once, and is thereafter immutable.
  • The deferral-reification invariant. The deferral itself, not merely the eventual value, is the object: passability, composability, and inspectability of the pending handle are required, distinguishing a future from a mere expectation.
  • A composition algebra. Placeholders combine under operators (then, all, race, sequence), so dependency structure among deferred outcomes is itself a manipulable, writable object.

These compose into one move: turn "a value will arrive later" into a first-class handle with explicit producer authority, consumer attachment, and a single irreversible resolution, then compose such handles into dependency graphs.

What It Is Not

  • Not lazy_evaluation. Lazy evaluation defers computation until a value is demanded (pull-driven, computed on access); a future reifies a deferred result that some producer will fulfill independently of when the consumer asks — the work may already be running or done.
  • Not optionality. Optionality is the right-without-obligation to act later; a future is a commitment to supply a value (or a reason for failure) exactly once. A future's producer is obligated; an option-holder is not.
  • Not a commitment_device. A commitment device binds a future self's behaviour by removing options to ensure follow-through; a future is a data-flow placeholder for a value-to-arrive, with no self-binding against temptation.
  • Not a callback alone. A callback is one continuation invoked on completion; a future is the first-class object on which many continuations can be attached, which can be passed, stored, composed, and inspected — it reifies the deferral that a bare callback leaves implicit.
  • Not state_and_state_transition in general. A future has a state machine, but a constrained one: a single, irreversible transition from pending to fulfilled-or-rejected. General state machines cycle and revisit states; a future resolves once and stays.
  • Common misclassification. Calling any "I'll get back to you later" a future. Catch it by testing for a first-class, passable, composable handle with explicit fulfillment authority and once-only resolution — an informal expectation or hope has none of these.

Broad Use

The skeleton recurs across substrates, most of them human-practice cases with software reification layered on top. In computer science it is the futures and promises of Java, JavaScript, C++, Scala, Python, and Rust; async/await across modern languages; and reactive streams. In distributed systems it is RPC return values, remote object references, and the agreed value of a consensus protocol seen from a participant's vantage. In finance it is futures contracts (a standardized obligation to deliver at a fixed date and price), forwards, options as conditional futures, and insurance claims as conditional fulfillments. In commercial law it is escrow accounts (the escrow holder as a producer with conditional authority), letters of credit, and layaway plans. In civil contracts it is pre-orders, reservations, and lease-with-option-to-buy. In project management it is milestone deliverables and release pre-announcements that pre-commit the producer. In diplomacy it is treaty commitments that fulfill at named conditions. In healthcare and operations it is surgical waitlists and organ-allocation queues — slot promises contingent on triage. In education it is conditional admission and deferred matriculation. In each case the same shape — a reified placeholder with a producer holding fulfillment authority, a consumer attaching intent, and a once-only pending-to-resolved transition — does the work.

Clarity

The prime clarifies the difference between a value and a handle on a future value. Many concurrency, contract, and planning bugs arise from confusing the two — treating a not-yet-fulfilled placeholder as if it were the value, or treating a value as if it were still pending. Once the distinction is named, the question "what happens if the producer never fulfills?" becomes immediately askable rather than implicit. The pattern also clarifies the difference between blocking on a result and attaching a continuation: blocking serializes, attaching parallelizes, and the same insight unifies async-callback discipline in software, escrow conditions in commerce, and conditional-execution clauses in contracts. Finally, it surfaces the producer–consumer authority split: who holds the right to fulfill and who holds the right to consume, since many contractual and protocol disputes are authority-split disputes mis-framed as content disputes. The clarifying force is to make the placeholder, its resolution states, and its authority structure explicit rather than tacit.

Manages Complexity

Reifying the deferred value lets a complex web of who waits on what be composed mechanically. Operations like wait-for-all, wait-for-the-first, and chain-after-fulfillment compose into pipelines whose dependency structure is explicit, shifting the cognitive load from "track all the temporal entanglements in your head" to "express the dependency graph in placeholder algebra." In commerce and law the same compression lets parties layer conditional commitments — an escrow that releases on shipping confirmation, itself a promise resolved by a logistics provider, itself dependent on a customs-clearance future — and the compositional discipline of the pattern is what makes deeply conditional commerce auditable. The management payoff is that temporal coupling, which is otherwise invisible and error-prone, becomes a manipulable object: the dependency structure among deferred outcomes can be written down, inspected, and composed, so the system's behaviour under each resolution outcome can be reasoned about ahead of time.

Abstract Reasoning

Recognizing the pattern licenses several reusable moves. Reasoning about pending state: any computation or commitment depending on a future must be analyzed under each of three resolution outcomes — pending forever, fulfilled, rejected — so the pattern forces case-completeness. Authority decomposition: who can fulfill, who can reject, who can timeout, who can cancel are separable authorities the pattern lets one split apart. Composition algebra: futures compose by then, all, and race, and this algebra carries to commerce (an option on an option, an escrow of escrows) and to planning (a milestone conditional on a milestone). Timeout and cancellation as first-class events: a future never resolves without an explicit timeout protocol, encoding the insight that "no resolution" is itself an outcome to be handled. And producer–consumer decoupling: the consumer attaches intent — what to do on resolution — without knowing when resolution will happen, the same decoupling that makes asynchronous architectures, supply-chain reservations, and conditional contracts compositional. The reasoner asks, of any deferred commitment: who is the producer, what does the consumer attach, what are the three outcomes, and how does it compose with other deferrals?

Knowledge Transfer

The intervention catalog transfers across software, commerce, law, scheduling, and diplomacy, and the historical transfers run in both directions. The explicit pending/fulfilled/rejected state machine, articulated in software futures, was imported into smart-contract languages and off-chain settlement protocols. The conditional-fulfillment-with-third-party-authority pattern of commercial escrow was re-implemented as cryptographic timelocks and multi-party signing escrows, with the future/promise structure made explicit in protocol diagrams. Financial futures, a centuries-old institutional implementation of the pattern, supplied the conceptual base for hedging, options pricing, and the derivatives market. Reservation systems — airline tickets, hotel bookings, surgical slots — are commercial futures whose programmatic counterparts directly inherit the structure. And the then/all/race composition algebra moved out of promise libraries into reactive UI frameworks and data pipelines. The role mappings are direct: placeholder ↔ Future object / escrow / reservation / treaty commitment, producer ↔ payment processor / escrow agent / warehouse / signatory, consumer ↔ continuation / buyer / patient / counterparty, state machine ↔ pending-fulfilled-rejected / open-released-returned / waitlisted-served- cancelled, composition ↔ all/race over sub-futures / conditional escrow chains. An engineer who composes payment, inventory, and shipping futures into one order confirmation recognizes the identical structure when an escrow releases only on inspection, title clearance, and lender approval — three sub-futures combined under "all," with defined behaviours on rejection for both parties. Because most non-software instances are human-practice arrangements that the software construct merely names precisely, the transfer is partly recognition and partly the import of a sharper vocabulary — producer authority, timeout discipline, composition operators — into domains that previously handled deferral ad hoc.

Examples

Formal/abstract

Take a JavaScript Promise resolving an HTTP fetch as the rigorous instance, treated as a state machine. The reified placeholder is the Promise object returned by fetch(url) — a first-class value created and returnable before the network response exists; it can be stored in a variable, passed to a function, and held in an array of other pending promises. The producer with fulfillment authority is the runtime's network layer, the unique party holding the right to settle this placeholder: it will call the internal resolve with the response body or reject with a network error. The consumer attaching intent is the .then(onFulfilled).catch(onRejected) chain, registering continuations without knowing when the response arrives. The once-only state machine is exact: the promise is pending, transitions out of pending at most once into fulfilled or rejected, and is thereafter immutable — a second resolve call is a no-op, which is the formal guarantee downstream code relies on. The composition algebra is what the prime promises: three such placeholders combine under Promise.all([a, b, c]) (settle when all fulfill, reject on the first rejection) or Promise.race (settle on the first to resolve), so the dependency graph among deferred outcomes becomes a written, manipulable object. The intervention the prime forces: case-completeness over the three outcomes — pending-forever (handled by an explicit timeout that races a rejecting timer against the fetch), fulfilled, and rejected — so "no resolution" is itself an outcome with a handler, not an unhandled hang.

Mapped back: The Promise instantiates every role — reified placeholder, single-authority producer, continuation-attaching consumer, once-only pending→fulfilled|rejected machine, and a then/all/race algebra — and shows reification turning invisible temporal coupling into an inspectable dependency graph.

Applied/industry

Consider a commercial escrow closing a real-estate sale, with a financial futures contract as a second instance. In the escrow the reified placeholder is the escrow account itself — a named, legally-recognized object standing for "the funds-and-title transfer that will happen later," created and reasoned about before either side performs. The producer with fulfillment authority is the escrow agent, the single neutral party holding the right to settle: release funds to the seller and title to the buyer (fulfill) or return both (reject). The consumer attaching intent is each counterparty, who attaches conditions — what releases on resolution — without controlling the timing. The once-only state machine is open→released|returned, irreversible once settled. The prime's composition algebra is exactly what makes deeply conditional closings auditable: the release is conditioned on the conjunction of three sub-futures — clear inspection, clear title search, and lender approval — combined under "all," each with defined behaviour on rejection. A financial futures contract runs the same structure at market scale: the placeholder is the standardized contract (deliver a commodity at a fixed date and price), the producer-side obligation is enforced by the clearinghouse, the consumer is the counterparty, and the once-only settlement is delivery-or-cash-settle at expiry. The intervention the prime enables in both: name the producer's authority explicitly and specify the timeout/rejection branch — what happens if a condition never clears — converting an ambiguous "deal in progress" into a fully case-complete commitment whose every resolution path is pre-reasoned.

Mapped back: Escrow and futures both run the prime end-to-end — a reified deferral, an authority-holding producer, condition-attaching consumers, a once-only settlement, and conjunctive/conditional composition — differing from the software case only in that the institution supplies the authority the runtime supplies in code.

Structural Tensions

T1 — Pending Forever versus Eventual Resolution. The state machine permits three outcomes, but the third — never leaving pending — is the one designers forget. The tension is temporal: a future promises resolution will come, yet nothing in the bare pattern guarantees it ever does. The failure mode is code or a contract that handles fulfilled and rejected but hangs indefinitely when the producer simply never settles — an unhandled await, an escrow that no party closes. Diagnostic: ask what races the resolution — is there an explicit timeout that converts "no resolution" into a handled rejection — and refuse to treat pending-forever as impossible.

T2 — Handle versus Value. The prime's whole sharpness is reifying the deferral as a first-class handle distinct from the value it will carry. The tension is that the handle and the value are easy to conflate, in either direction. The failure mode is treating a pending placeholder as if it already held the value (reading a future before it resolves) or treating a settled value as if it were still pending (re-awaiting something already done). Diagnostic: at every use site, ask whether you hold the handle or the value, and whether the code path has actually awaited resolution before consuming.

T3 — Producer Authority versus Consumer Expectation. Fulfillment authority sits with exactly one producer, while any number of consumers attach intent — an asymmetry the pattern makes explicit. The tension is that consumers form expectations the producer never committed to. The failure mode is a dispute mis-framed as a content disagreement when it is really an authority-split confusion: a consumer believing it could cancel or re-fulfill, a counterparty assuming a condition the producer never accepted. Diagnostic: separate who may fulfill, reject, timeout, and cancel into distinct named authorities, and check each expectation against the producer's actual rights.

T4 — Blocking versus Attaching. A consumer can either block awaiting resolution or attach a continuation; these look interchangeable but differ in concurrency consequences. The tension is scalar: blocking serializes and is simple at one waiter, but composes into deadlock and lost parallelism at scale; attaching parallelizes but scatters control flow. The failure mode is blocking inside a context that must stay responsive — awaiting synchronously on a hot path — turning a deferral meant to free the system into a stall. Diagnostic: ask whether the waiter must make progress meanwhile; if so, attach a continuation rather than block.

T5 — Once-Only Immutability versus Changing Reality. The placeholder transitions out of pending at most once and is thereafter immutable — the guarantee downstream relies on. The tension is that the underlying reality the future stood for may change after settlement: a fulfilled value goes stale, a delivered commodity's price moves, an approval is later revoked. The failure mode is trusting a resolved future as a live fact long after resolution, when immutability of the handle was never immutability of the world. Diagnostic: ask whether the settled value is a snapshot or a live reference, and attach freshness or revocation handling where the world can move under it.

T6 — Composition Algebra versus Failure Propagation. Futures compose under then/all/race into dependency graphs, but the composition operators carry implicit failure semantics — all rejects on the first sub-rejection, race ignores the losers. The tension is that the convenient combinator hides how failure flows through the graph. The failure mode is composing deeply conditional commitments under all and discovering one minor sub-future's rejection aborts the whole pipeline, or under race that a losing branch's side effects were never cleaned up. Diagnostic: for each combinator, trace what one sub-future's rejection does to its siblings and the parent before relying on the happy path.

Structural–Framed Character

Future Or Promise sits just on the structural side of the middle of the structural–framed spectrummixed-structural, aggregate 0.4, and genuinely borderline. The relational skeleton is real and clean — a reified placeholder, a producer with fulfillment authority, a consumer attaching intent, and a once-only pending→fulfilled|rejected state machine — but four of the five diagnostics carry half-weight because most of the prime's instances outside software are human-practice arrangements onto which the computer-science construct is layered.

Walk them. Vocabulary travels (0.5): the crispest articulation — producer authority, then/all/race composition, timeout discipline — is concurrency's home idiom, and applying the prime to an escrow or a treaty tends to carry that vocabulary along, sharpening the institution rather than being read off it neutrally. Evaluative weight (0): the lone zero — a future is neither good nor bad, just a handle that resolves once. Institutional origin (0.5): the reification originates in software, yet its richest real instances — futures contracts, escrow, letters of credit, reservation queues — are institutional constructs whose fulfillment authority is supplied by a clearinghouse, an escrow agent, or a court rather than a runtime. Human-practice-bound (0.5): most analogues (contracts, promises, waitlists) presuppose parties and obligations, a human practice; but the bare data-flow placeholder runs in a pure software substrate with no human practice required, which keeps this from a full 1.0. Import vs. recognize (0.5): calling an escrow a "future" imports the producer/consumer/state-machine framing, half-recognizing a deferral that was already there and half-overlaying a sharper vocabulary on it. The honest reading is a real once-only-resolution skeleton wrapped in a software-and-institutions frame heavy enough to push four criteria to 0.5 — exactly the 0.4 aggregate and mixed-structural label.

Substrate Independence

Future Or Promise is a moderately substrate-independent prime — composite 3 / 5 on the substrate-independence scale. The reified-placeholder skeleton — a first-class handle for a not-yet-existing value, a producer holding fulfillment authority, a consumer attaching intent, and a once-only pending→fulfilled|rejected state machine — is genuinely relational, and its domain breadth is fair: it appears as futures and async/await in software, as RPC return values in distributed systems, as futures contracts and options in finance, as escrow accounts and letters of credit in commercial law, as pre-orders and reservations in civil contracts, as treaty commitments in diplomacy, and as surgical waitlists and organ-allocation queues in healthcare. What pins the composite to the middle is the substrate ceiling honestly named in the structural-abstraction and transfer bands: nearly every instance outside software is a human-practice arrangement presupposing parties, obligations, and institutions — an escrow agent, a clearinghouse, a court supplies the fulfillment authority that a runtime supplies in code — and there is no physical or biological substrate in which the pattern simply holds. The transfer is correspondingly partial: it is as much the import of a sharper software vocabulary (producer authority, timeout discipline, then/all/race composition) into domains that previously handled deferral ad hoc as it is the recognition of one pre-existing shape. A real relational core, fair breadth, but a human-practice-and-institutions ceiling on abstraction and transfer give a well-justified 3.

  • Composite substrate independence — 3 / 5
  • Domain breadth — 4 / 5
  • Structural abstraction — 3 / 5
  • Transfer evidence — 3 / 5

Relationships to Other Primes

One-hop neighborhood: parents above, mutual partners to the right, children below.Future Or Promisesubsumption: State and State TransitionState and StateTransition

Parents (1) — more general patterns this builds on

  • Future Or Promise is a kind of State and State Transition

    The file: 'Not state_and_state_transition in general — a future has a CONSTRAINED state machine': a single irreversible transition pending -> fulfilled|rejected. A specialization of state_and_state_transition (general machines cycle/revisit).

Path to root: Future Or PromiseState and State Transition

Neighborhood in Abstraction Space

Future Or Promise sits in a sparse region of abstraction space (84th percentile for distinctiveness): few abstractions share its structure, so a faithful description tends to retrieve it precisely rather than landing on a neighbor.

Family — Identity, Reference & Placeholders (10 primes)

Nearest neighbors

Computed from structural-signature embeddings · 2026-06-14

Not to Be Confused With

The most common confusion in software contexts is with lazy_evaluation. Both defer something, but they defer different things in opposite directions. Lazy evaluation defers computation: the work is not done until a consumer demands the value, and demand is what triggers the work (pull-driven). A future defers a result: the computation may already be in flight or complete, and the future is merely a handle that lets a consumer attach to whatever the producer eventually supplies (the producer drives fulfillment). The practical signatures differ sharply — a lazy thunk that is never forced never runs at all, whereas a future's underlying work proceeds (and may finish, and may have side effects) regardless of whether anyone is waiting. Conflating them produces real bugs: assuming a future is "lazy" and so safe to ignore, when in fact its producer is already mutating state; or expecting a lazy value to be shareable and composable like a future when it is merely an unforced computation.

It is also distinct from optionality, with which it shares a future orientation. Optionality is the right without obligation to take an action later; its holder may or may not exercise it, and the value lies in keeping the choice open. A future is a commitment: its producer is obligated to resolve it exactly once, to a value or to a reason for failure. The asymmetry is total — an option-holder owes nothing and the counterparty bears the contingency, whereas a future's producer owes a resolution and the consumer is entitled to it. Reading a future as an option (treating its fulfillment as discretionary) or an option as a future (treating a kept-open choice as a guaranteed result) misplaces the obligation, which is exactly the thing the practitioner needs to track.

A third, more semantic confusion is with commitment_device. Both involve a promise about the future, but they bind different parties for different reasons. A commitment device binds an agent's own future self — it deliberately removes options now to guarantee follow-through later against anticipated temptation (Ulysses and the mast). A future binds a producer to a consumer in a data-flow sense: it is a placeholder for a value-to-arrive, with no element of self-restraint or temptation. The future's "promise" is about delivery of a value; the commitment device's is about constraining behaviour. When the word "promise" appears in an institutional setting, the discriminating question is whether the structure exists to deliver a result to a waiting party (future) or to lock in one's own conduct (commitment device).

These distinctions matter because they pin down who owes what to whom and when the work happens. Treating a future as lazy mis-times the work; treating it as an option misplaces the obligation; treating it as a commitment device imports self-binding semantics that are simply absent. The future's contract is narrow and precise — a passable, composable handle, a producer obligated to resolve once, a consumer entitled to attach — and each neighbouring prime relaxes exactly one of those clauses.

Solution Archetypes

No catalogued solution archetypes reference this prime yet.