Interaction model
The interaction model is the solution.
A program that touches the world needs two things: a name for what it touches, and a description of what it does with it.
Atoms
- Ref - a pointer to a resource: a kv slot, db row, a file path, an in-memory slot, a config key. Carries the address, not the value at the address.
- Interaction - what a program does with Refs (and with other Interactions): read, write, compute, branch, iterate, compose.
Two citizens. In the interaction model every element is either a Ref or an Interaction. Every touch of the world goes through a Ref - the Ref is the handle. An Interaction is everything else: composition, control flow, computation.
Set( # Interaction (write)
Ref("orders.total"), # Ref (the address)
Add( # Interaction (compute)
Ref("orders.total"),
1,
),
)The whole interaction model collapses to: name the locations, describe what to do with them. Refs name. Interactions describe. Anything richer (typing, scopes, orchestration) is layered on top.
Context
- Fabric - an addressable space where Refs live. The machinery that resolves Refs and executes Interactions over them. Postgres, fs, http api, in-memory dict are all fabrics. Not a citizen of the model; lives below it.
- Context - the union of Fabrics. The full addressable space a program runs against; each Fabric is an element of it.
A program names Refs symbolically and composes them with Interactions. It runs against a Context, which routes each Ref to a Fabric; the Fabric resolves the address and carries out the Interaction. Same program, different Context = different bag of Fabrics, different worlds - test, staging, and prod all run the same description by swapping the binding.
Refs name, Interactions describe, Fabrics execute.
program = Set(Ref("counter"), Add(Ref("counter"), 1))
ctx = { "counter": 41 } # binds Ref("counter") to an in-memory fabric
evaluate(program, ctx)
# ctx now is { "counter": 42 }The program is the Interaction; the world is in the Context.
Purpose
A program's single purpose is to update the Context.
Context v0
→
program
→
Context v1v1 ≠ v0. If the Context doesn't change, the program has no reason to run.