Programming Ribbit
Write a distributed application as participants sharing memory. Each participant owns its truth, holds the state it depends on, and publishes what it did.
Address the truth first.
A cell has three coordinates: service.variable.instance. Its value is a JSON object, the bag. A write replaces that value and receives a write-order id from memory. Within a variable, use that id for ordering; a participant’s wall clock is not the ordering authority.
A rewrite does not merge competing versions. If independent participants write the same truth cell, fix the ownership or the address. Claims from competing participants belong in different cells, so every participant can derive the winner from the same published claims.
| Truth | Addressing | Reader behavior |
|---|---|---|
| Latest value | One owned cell, rewritten | A slow reader receives the latest value, not a backlog. |
| Distinct state | One cell for each record | Read records past the reader’s write-order mark. |
| Collection | One cell per element | A partial address selects the table; the instance names the element. |
| Container | Part cells, then a header | The owner publishes the visibility marker after the parts. |
| Reference | A tuple name in a cell | Read the referenced state instead of making a second copy of its truth. |
Five verbs, one memory surface.
| Verb | Meaning |
|---|---|
| Write | Publish a cell and receive its write-order id. |
| Read | Read one cell or a partially addressed table. |
| Held read | Park until state newer than an after-id is available, subject to the requested wait. |
| Read-fresh | Select cells within a reader-specified age, using the memory’s clock. |
| Remove | Remove by write-order id. |
A non-waiting write is also exposed. Vendors can add operations in their own RAM host, reached through the library’s call surface. API names differ by binding; use the binding’s documentation rather than translating these conceptual verbs into guessed function names. The supplied JavaScript programming guide describes write, writeNowait, read, remove and call.
// JavaScript binding: hold the table after the last observed id.
const cells = await ram.read('Retail', 'order', '', { after, waitS: 3600 });
// Process the state, then advance your own mark.Hold a view instead of fetching on every request.
Read the state once, build a snapshot, and hold a read for subsequent changes. Publish a new immutable snapshot when it changes. The application’s query path reads the snapshot; it need not perform a network operation for each query.
A participant can publish its own applied cell: “I hold everything through id N.” A test or dependent participant waits on that state. Publication makes a parked reader runnable; it does not mean the reader has completed its work when the writer returns.
The memory library’s semantic cache handles unchanged answers. A held application view has a different purpose: it is the participant’s present knowledge, available directly to its computation.
Coordination is state.
For a scarce item, every contender publishes its own claim. Every contender reads the claims and performs the same write-order arithmetic. For work whose result does not yet exist, a participant publishes a Want and holds the result address. A participant able to supply it holds the Wants. A failure can be a published result.
A foreign source has one participant responsible for reading it and publishing its state with provenance. Other participants use that state. Read-modify-write across several participants is a signal to revisit who owns the truth.
A participant writes its progress mark after the work. Rewriting the same owned result cells after a restart can be idempotent. That pattern does not automatically make an external payment or another irreversible side effect exactly once; its contract still has to support the recovery behavior.
Recovery changes the world you are reading.
When a memory host changes or a network splits or joins, previously held state may belong to an earlier world. In the Living Network model, participants reassert what they know and rediscover what they depend on. Replacement RAM is not a promise to restore the old contents.
Recovery hooks are implementation-specific. The October 11 engineering record still lists the Python wrapper’s missing heartbeat and on_database_change integration as open. Do not invent those APIs in an example. Region hosts and applications must define their own lifetime and restart contracts.
The vendor shapes the API.
The five verbs are the floor. A vendor can change the schema, instance encoding and host operations to fit the domain: selection, counts, joins, aggregates or other operations supported by its implementation. A well-known host location gets the application to the region; it does not dictate the region’s policy.
The current material includes C++, Python, a Kotlin member implementation and a separately supplied JavaScript binding guide. Kotlin’s FD&F member intentionally uses RAW requests; it is not evidence of semantic compression in that client. Anyone allowed to read a region may see its readable cells. Keep secrets out of shared application state.