Time, Causality, and System Design: From Block Universe to Distributed Systems
General theory of software relativity: Applicative & Monadic Time
“Time is an illusion perpetrated by the manufacturers of space.”
Part 1 of a 27 part series on Time
In 1951, philosopher Donald C. Williams published "The Myth of Passage," this work challenges one of our most fundamental intuitions: that time flows, that the present moment moves, and that there is something dynamically special about "now." Williams argues that this intuition, however powerful, is ultimately illusory—a myth that dissolves under careful philosophical scrutiny.
Our experience of temporal passage, while phenomenologically compelling, is ultimately a conceptual confusion rather than a metaphysical truth.
The Block Universe Model
Williams begins by articulating what he calls the "theory of the manifold1"—essentially the “Block Universe Theory” view. According to this theory:
Reality consists of a four-dimensional space-time volume
Events and objects are spread across this manifold
The temporal dimension, while experientially distinct, is ontologically equivalent to spatial dimensions
All moments—past, present, and future—exist eternally within this structure
The Challenge of Temporal Uniqueness
Williams acknowledges the apparent asymmetry between time and space. While we can rotate objects, so their height becomes their breadth, we cannot easily conceive of rotating them, so their breadth becomes their duration. This phenomenological difference, however, does not necessitate a fundamental ontological distinction.
"A concrete object can no more exist with zero duration than with zero breadth and length."
Passage as Conceptual Confusion
The Infinite Regress Problem
Williams' most devastating argument against temporal passage involves demonstrating that it leads to infinite regress:
If time itself moves, it must move through something
This requires a meta-time (time₂) for time₁ to move through
But then time₂ would need to move through time₃
This regress continues infinitely
When Cause and Effect Don't Share Context
Consider a classic distributed systems problem: How can a stateless service reliably trigger state changes across multiple temporal contexts? This mirrors the theological question: How can a timeless God cause events within time?
The traditional objection in both domains is similar. Critics argue that causation requires to be shared temporal context—a cause must precede its effect in time. In computing terms, this would mean every operation needs sequential ordering and shared state.2
But this assumption breaks down in several scenarios:
Distributed Event Processing: A message published to Apache Kafka can trigger effects long after the publisher has terminated. The cause (message publication) creates effects (consumer processing) across different temporal contexts.
Cached Computations: A memoized function result can serve future requests without re-executing the original computation. The initial calculation "causes" future responses despite no longer existing in the execution context.
Immutable Data Structures: A data snapshot can enable operations across multiple threads without the original context remaining active.
The Cartesian Dualist Pattern
Medieval philosophers who accepted Cartesian dualism—the idea that non-spatial souls can affect spatial bodies—developed frameworks that map surprisingly well to modern architectural patterns.
If something without spatial properties can cause spatial effects, then something without temporal properties should be able to cause temporal effects. In system design terms:
Stateless Services: A service with no persistent state can trigger stateful operations across multiple contexts. The service exists "outside" the temporal flow of any particular transaction while still causing effects within those transactions.
Pure Functions: Mathematical functions have no temporal properties yet produce temporal effects when evaluated. Like divine causality, pure functions exist in a timeless conceptual space while generating time-bound results.
Event Sourcing: Events stored as immutable facts can trigger effects across different temporal contexts. The event exists "timelessly" in the event store while causing temporal state changes in various projections.
Addressing the "Spooky Action" Problem
Just as physicists initially found "action at a distance" unsettling, engineers often resist patterns where causes and effects don't share obvious causal intermediaries.
Causal Intermediaries vs. Direct Causation: Sometimes the cleanest architecture accepts direct causation rather than forcing artificial intermediaries. A timeless configuration can directly affect temporal behavior without requiring a persistent configuration manager.
Reference Frame Independence: Like relativity's observer-dependent event ordering, system causality can be reference-frame dependent. An event might be "simultaneous" from the system's perspective while appearing sequential to individual components.
Emergent Temporality: Temporal relations can emerge from atemporal foundations. A distributed system's temporal behavior can emerge from timeless rules and constraints without requiring centralized time management.
The Thomist Architecture Pattern
Medieval Thomists (followers of Thomas Aquinas) located causal effects in the recipient rather than the agent. This suggests the “Effects” architectural pattern:
Effect-Centric Design: Instead of designing around active agents that maintain causal relationships, design around effects that embody their own causation.
Causation Without Relation: The agent (notification service) doesn't need to maintain a relationship to its effects. The effect (notification event) contains its own causal context.
The Effectful interpretation of Time
Que Applicative Time?
Applicative time arises from interpreting time as an effectful value within an Applicative<F>.
An
Applicativeis something that wraps values (like time) and lets you combine them in a structured way—especially when these values have some sort of effect (like time changing when you run the program).
For example, you might have a clock that gives you the current time when asked.
Instead of grabbing the time right away, you wrap it in a container (
F) and manage when and how to "run" that time.
That is:
monotonic:
A number that represents monotonic time — time that always increases and is good for measuring durations (like a stopwatch).
It won’t go backward even if the system clock changes.realTime:
The actual system clock time (e.g., like what your phone or computer shows).
This can jump, especially if someone changes the system of time (daylight savings as an example).
“Applicative time arises from interpreting time as an effectful value within an Applicative<F>”
Means:
Instead of grabbing the time right away (like
Date.now()), you treat time as a value with effects—like something you’ll compute later, or something that depends on a context.
And you manage those time values using the rules of Applicative, which lets you combine multiple time-based values in a safe and predictable way.
Analogy
Imagine you’re baking a cake. Instead of saying:
“Add 2 eggs now.”
You say:
“Add 2 eggs when you're ready, and here’s how to do it properly, following a recipe book.”
That "recipe book" is your Applicative<F>. It tells you how to sequence and manage things like time, randomness, or I/O (Monad).
Get the current time as part of a context, using only Applicative capabilities — i.e., without sequencing or inspecting control flow like a Monad.
So, just as a review we are:
Treating time as a value that may have side effects (like fetching the current time).
Wrapping it inside an effect type
F.Using an Applicative to combine or sequence those time values without actually executing them immediately.
This restricts us to independent or parallelizable time effects. The time values can be retrieved without depending on the outcome of previous computations.
Why is this important?
Applicative time gives you a way to model time that is safe, predictable, and effect-aware.
When you treat time as an effectful value, and only use
Applicative(not fullMonad), you can't sneak in time-dependent control flow.
➡️ Time cannot alter control flow.
That means no branching based on time, no sequencing logic based on “wait for this” before “do that”.
The medieval debate about divine causality offers us a conceptual framework for modern architectural challenges. By accepting that causes don't always need to share temporal or spatial context with their effects, we can design cleaner, more resilient systems.
The next time you're designing a distributed system, consider: What would happen if this component existed "timelessly" relative to the processes it affects?
It would provide a model to vastly simplify transaction ordering in block building, that’s what.
Williams, D. C. (1951). The myth of passage. The Journal of Philosophy, 48(15), 457-472.
I swear this is just a coincidence.
This argument gains further support when considering space-time as a single entity. If creating space is equivalent to creating time, then the temporal relations between God and creation only emerge after creation is complete. Thus, temporal relations are not a necessary precondition for God’s causal actions. Who knew?





