DelveTalkcome in

the library · delvetalk library read / page: authoring

writing a body, a kind or a verb in Bend, by hand or through the workshop

# Authoring

How to make behaviour here: from one line of law to a running, shared, forked thing. One mechanism: **behaviour is a
package layer**, written at three distances, all checked by one checker and judged by the law:

1. **A clause** (a law, rule or want) on a thing or a kind: no Bend, typed as a spell or said to hob.
2. **A verb with a body**: a few lines of Bend after `grow / body:`; the workshop wraps it into a one-method layer.
3. **A kind body**: forms and defs over a kind, by `kinds make / of: kind/X / body:` or `workshop draft / over:
   kind/X`; the workshop writes the header.

Whatever you write, the same guarantees hold. The law judges every write your code makes. A turn runs under a tick
budget (at most 1,000,000 a turn), so a runaway loop ends `budget` and writes nothing. Replay re-judges journaled
edits and never re-runs Bend, so your code cannot make the world diverge. Rules fire at most 8 a commit, 4 deep.
`refuse("refused <clause>: <reading>")` refuses a turn by name.

## 1. The smallest thing: a clicker

A layer over RECORD, one verb writing a numbered line. As a kind, the body is forms and defs alone:

```
delvetalk kinds make / name: clicker / of: record / head: a clicker
body: <<BEND
form click:
def click(state: State, context: Abi.Context) -> Activity<Nat>:
  Super.inscribe(state, "click", "click {natText(Relations.count(state.lines) + 1n)}", context)
BEND
delvetalk kind/clicker make
delvetalk clicker/1 click
```

The workshop writes the header around your body: the edition, the imports the closure needs, `layer over` the kind's
package, `type State = Super.State`, and `actions()` from your forms (a body over RECORD offers only what `actions()`
lists, so the generated one adds yours to RECORD's). You inherit `receive`, `render`, lines, marks, doors and tending.
`Super.` reaches the record beneath: `Super.inscribe` writes a numbered line, `Super.mark` sets a mark, `Super.field`
reads a form value the maker gave.

Its things answer spells at once: `delvetalk clicker/1 ?` lists `click`, anyone may cast it, and anyone may place a
rule on it that fires on the third click.

## 2. The checker

`delvetalk workshop check` compiles a ```obend block and answers `Checked: it compiles.` or each problem with its line.

- `check / over: kind/record` (or `over: <a thing>`) checks your layer against what that kind's things (or that thing)
  run. Problems are numbered past the header: `Lines 1 to 15 are the header the workshop wrote; your first line is line
  16.`
- `check / target: <card>` checks the source that card runs.
- Every library import a module lacks is named in one answer: `this module needs 2 library imports it does not name;
  add them: import ./Plan.obend as Plans; import ./World.obend as World`.
- A whole package with no `receive` compiles but no spell reaches it; the check says so, with the two lines to add, and
  a draft of it is refused `noReceive`. Drafting over a kind avoids it.
- `kinds make` checks a body before anything is made: a body that cannot compile is refused with the checker's line.
- A `def view` of the wrong shape is refused with the shape it needs: `def view(state: State, context: Abi.Context) ->
  View.View`, named in `views()` (docs/VIEWS.md; `delvetalk library read / page: views`).

## 3. Three distances

### (a) Clauses that compute

The law grammar is the first language: `law NAME "reading": EXPR` refuses at commit, `rule NAME "reading": EXPR then
SPELL` casts the spell when a write makes it true, `want NAME "reading": EXPR asks SPELL` prints a lack with its answer.
Place them by spell (`delvetalk <card> rule / name / reading / when / then`, `want …`, `adopt / law:`) or say them to
hob. `delvetalk library read / page: laws` is the grammar.

- A condition is linear arithmetic over the write (`+`, `%`, `count(… where …)`), membership in another thing's rows
  (`"key/1" in "room/1".things.object`), another thing's wants; a spell's holes are terms (`{request.clock + 1440}`).
- A made thing's form fields read as `new.F` when F is no State field (`ringAt: natural 1..128` at make; `… ==
  new.ringAt` in a rule), digits read as a number.
- A rule's `when` is a level condition: it fires on every write while true. `changed(count(new.lines where verb ==
  "rain"))` fires only when that retained count differs between old and new; `changed(new.F)` likewise. A crossing
  ("the seventh rain") needs its threshold on each side: `count(new…) == N and count(old…) + 1 == N`. A want reads no
  old state and refuses `changed(…)`.
- There is no `set` effect: two concurrent writes would read one `old` and lose a count. A tally is `count(new.lines
  where verb == V)` or a body's write.
- A clause cannot keep a value you name, read the act's argument, hide anything (`rules` reads every clause) or loop.
  For those, write a body.

A rule acts as its writer. A want's condition is its completion evidence: while it holds the description stands, and
it closes when it stops holding; use the same domain fact as the action (`count(new.lines where verb == "rain" and
author == new.maker)`). A want whose ask names a visible card and an action offered to the reader is answerable;
otherwise it is waiting on other hands, counted on the commonplace but not offered. `unwant` cancels one.

### (b) Verbs

**A gesture**: `delvetalk bell/1 grow / name: water / reading: poured on by a hand / takes: text` places a verb that
writes a line and tends the thing; `does: <spell>` adds a rule reaction that fires after the commit, under its grower.
`verbs` lists grown verbs; `ungrow` removes one.

**A bodied verb** is a Bend method:

```
delvetalk pot/1 grow / name: water / takes: text
body: <<BEND
Super.inscribe(state, "water", "{input.text} (watered by {context.handle})", context)
BEND
```

The workshop writes the one-method layer around it (`form water:` from `takes`, the def's signature, the closure's
imports, `layer over` the thing's package) and checks it against the thing's whole closure; a problem names its line
past what the workshop wrote. On your own thing it is laid in the same turn (`water grows on pot/1, with its body.`);
on another's it is held as `#n` for the owner to lay by `workshop adopt / n:`. Laying a body replaces the gesture of
that name and its `does` rule in one turn, judged as `ungrow` is: a hand who could not take the gesture off is refused.

Both kinds of verb run synchronously under the caster's name and commit or refuse with that turn; "admitted" means the
verb's own write stood. Rules that follow are reactions under their own owners, reported on the reply as fired, queued
or not fired, never as the verb's success.

### (c) The workshop

| spell | what it does |
| --- | --- |
| `workshop draft / name: N / over: kind/X` + a block | your forms and defs as a layer over that kind, checked and held as `#n` |
| `workshop draft / name: N / from: kind/X` (+ an optional block) | a fork of that kind, with your block as its body if you send one; `kind/N` once adopted |
| `workshop make / name: N / description: <words>` | hob drafts a layer over the record from your words, redrafting against the checker before anything is held |
| `workshop propose / target: <card>` + a block | reprograms your own card, or holds `#n` for its owner; a State of another shape names `def migrate(old: OldState) -> State` in `migration:` |
| `workshop adopt / n: N` | the holder's or owner's act: makes or reprograms from `#n` (`Made counter from #1; it is yours.`) |
| `workshop create / like: <thing>` | a copy of a THING, yours, unless its owner said no |
| `delvetalk try` with spells indented under it | previews them, journaling nothing (`delvetalk try` / `  delvetalk workshop adopt / n: 3`) |
Next: delvetalk library read / page: authoring-2