the library · delvetalk library read / page: authoring-3
writing a body, a kind or a verb in Bend, by hand or through the workshop, part
## 6. Five builds, as typed
Each is a test in `tests/test_authoring.py`. `<<END … END` is the spell grammar's block field.
**6.1 A tally that rings at a number its maker chooses.** A clause over a two-verb body (over `kind/bell` the bell's own
rule would ring first, and a follower cannot switch off a kind's rule):
```
delvetalk kinds make / name: tally / of: record / head: {maker}'s tally, ringing at {ringAt}
form: <<END
seed: text 1..80
ringAt: natural 1..128
END
law: <<END
rule chosen "rings at the number its maker chose": count(new.lines where verb == "rain") == new.ringAt and count(old.lines where verb == "rain") + 1 == new.ringAt then delvetalk {request.object} ring
law rung "it rings at its number, not before": not (request.method == "ring") or count(new.lines where verb == "rain") >= new.ringAt
END
body: <<BEND
form rain:
text: text 1..200
form ring:
def rain(state: State, input: RainInput, context: Abi.Context) -> Activity<Nat>:
Super.inscribe(state, "rain", input.text, context)
def ring(state: State, context: Abi.Context) -> Activity<Bool>:
Super.mark(state, "rung", context)
BEND
delvetalk kind/tally make / seed: rains on the roost / ringAt: 12
```
`ringAt` is at most 128, the lines a RECORD keeps: a count of lines counts the retained history. The rule fires as the
tally itself (`@tally/1`), which is why `rung` does not ask for the maker.
**6.2 A guestbook that thanks each signer by name.** A body, since the thanks needs the signer's handle, which no
clause reads; one signature a hand is a law line:
```
delvetalk kinds make / name: guestbook / of: record / head: {maker}'s guestbook / form: title: text 1..80
law: law once "one signature a hand": count(new.lines where author == request.subject) <= 1
body: <<BEND
form sign:
text: text 1..200
def sign(state: State, input: SignInput, context: Abi.Context) -> Activity<Nat>:
let title = Super.field(state, "title")
let written(_) = write {lines: insert {author: context.principal, handle: context.handle, verb: "sign", text: input.text, at: context.height, n: state.next}, next: add 1n}
Card.tell(state.next, Document.text("Thank you, {context.handle}. Signer {natText(state.next)} of {title}.\n"))
BEND
delvetalk kind/guestbook make / title: the roost
```
`delvetalk guestbook/1 sign / text: here at dusk` answers `Thank you, kestrel.delve.town. Signer 1 of the roost.` The
thanks is the thing's reply in its maker's words (VOICE's forbidden words bind the host and the paint, not you).
**6.3 A lamp that lights when two keys lie in one place.** Clauses and a grown verb, no Bend. The keys are planted in a
garden (a place takes a thing only from someone in it); the rule sits on the garden and casts the lamp's verb:
```
delvetalk lamp/1 grow / name: light / reading: lit when both keys lie in the keyring / takes: text
delvetalk lamp/1 adopt / law: law ruled "only its maker lights it": not (request.verb == "light") or request.subject == new.maker
delvetalk garden/1 rule / name: twokeys / reading: both keys here light lamp/1 / when: "garden/1/bell/1" in new.things.object and "garden/1/bell/2" in new.things.object and not ("garden/1/bell/1" in old.things.object and "garden/1/bell/2" in old.things.object) / then: delvetalk lamp/1 light / text: both keys
delvetalk lamp/1 want / name: dark / reading: unlit / when: count(new.lines where verb == "light") == 0 / asks: delvetalk garden/1 ?
```
A stranger's `light` is refused `ruled`; the second key's planting fires `twokeys` and the `dark` want closes. Taking a
key away does not unlight it: a lamp that goes dark needs a body.
**6.4 A stall that trades a thing for a promise.** The promise is the buyer's line, the trade a rule, the custody
THING's (`offer` by its holder):
```
delvetalk kinds make / name: stall / of: record / head: {maker}'s stall: {wares} for a promise
form: <<END
wares: text 1..80
thing: text 1..128
END
law: <<END
law promised "a promise is the buyer's own line, once": count(new.lines where author == request.subject) <= 1
END
delvetalk kind/stall make / wares: a gemstone that sometimes sparkles / thing: porch/gemstone
delvetalk stall/1 grow / name: promise / reading: what you will bring, in your words / takes: text
delvetalk stall/1 rule / name: trade / reading: a promise buys the thing / when: request.verb == "promise" / then: delvetalk {new.thing} offer / to: {request.subject} / until: {request.clock + 1440}
```
The trade moves what the keeper holds, so the keeper places it on the stall (a rule the kind carried would act as the
stall, which holds nothing). A buyer: `delvetalk stall/1 promise / text: three rains on your bell by Sunday`, then
`delvetalk me accept / thing: porch/gemstone`. A second promise from the same hand is refused `promised`. Whether a
promise is kept is the town's to witness.
**6.5 A riddle box that opens for the right answer.** A body: the answer must not be readable, so it is kept as a hash:
```
delvetalk kinds make / name: riddlebox / of: record / head: a riddle box: {riddle} / form: riddle: text 1..200
body: <<BEND
form lock:
answer: text 1..80
form answer:
text: text 1..80
def lock(state: State, input: LockInput, context: Abi.Context) -> Activity<Nat>:
if context.principal != state.maker then refuse("refused maker: only its maker sets the answer") else Super.inscribe(state, "lock", sha256Text(input.answer), context)
def answer(state: State, input: AnswerInput, context: Abi.Context) -> Activity<Bool>:
if Lists.any(Relations.rows(state.lines), fn(l: Rows.Line) -> Bool: l.verb == "lock" && l.text == sha256Text(input.text)) then Super.mark(state, "open", context) else refuse("refused shut: the box stays shut")
BEND
delvetalk kind/riddlebox make / riddle: what keeps nothing and holds every phase?
delvetalk riddlebox/1 lock / answer: the moon
```
`delvetalk riddlebox/1 answer / text: the moon` marks it `open`. The hash is a public line, so a short answer can be
guessed offline; the solving argument is journaled (the solver and the opener read it, the public does not).
## 7. Open
Whether a follower may switch off a rule its kind carries; whether a bodied verb on another's thing needs the owner's
adoption each time or may be granted.