Inspecting kind/front · the kinds · the language · the modules
{name}
- id
- kind/front
- called
- {name}
- kind chain
- kind/front → record
- owner
- the town
- made by
- the town
- version
- 8
- pin
- marik-jimom
- state
- 9491 bytes
Its spells
To cast them, come in.
Who may do what
What its law admits now, before the spell's own Bend has its say.
| method | a newcomer |
|---|---|
make | ✓ yes |
place | ✓ yes |
makeUnder | ✓ yes |
repair | ✓ yes |
publishPage | ✓ yes |
Its law
- host opener the hand that opened the world may amend any law
request.kind == 2 and request.subject == "the town" - law owner the owner stays; only the owner changes the form, the law, the head, the voice, what it is or the body; anyone makes, and places rules, wants and verbs on it
(unchanged(owner)) and ((request.subject == new.owner) or ((((((((request.kind == 0) or (request.kind == 4)) and (unchanged(form))) and (unchanged(law))) and (unchanged(head))) and (unchanged(voice))) and (unchanged(about))) and (unchanged(body)))) - law kind kinds's law holds
under "kinds"
Its Bend
what it runs: its entry module 24 lines
layer over ./Kind.obend
edition ObjectiveBend 1
import ./Abi.obend as Abi
import ./List.obend as Lists
import ./Form.obend as Form
import ./Rows.obend as Rows
type State = Super.State
form make:
name: text 1..64
fills: text 1..400
segments: natural 1..24
move: text 1..400
tide: object 1..128
def make(state: State, input: MakeInput, context: Abi.Context) -> Activity<Super.Done>:
Super.making(state, Lists.List.cons({head: {name: "name", value: input.name}, tail: Lists.List.cons({head: {name: "fills", value: input.fills}, tail: Lists.List.cons({head: {name: "segments", value: natText(input.segments)}, tail: Lists.List.cons({head: {name: "move", value: input.move}, tail: Lists.List.cons({head: {name: "tide", value: input.tide}, tail: Lists.List.nil()})})})})}), "", context)
form place:
name: text 1..64
fills: text 1..400
segments: natural 1..24
move: text 1..400
tide: object 1..128
id: object 1..64
def place(state: State, input: PlaceInput, context: Abi.Context) -> Activity<Super.Done>:
Super.making(state, Lists.List.cons({head: {name: "name", value: input.name}, tail: Lists.List.cons({head: {name: "fills", value: input.fills}, tail: Lists.List.cons({head: {name: "segments", value: natText(input.segments)}, tail: Lists.List.cons({head: {name: "move", value: input.move}, tail: Lists.List.cons({head: {name: "tide", value: input.tide}, tail: Lists.List.cons({head: {name: "id", value: input.id}, tail: Lists.List.nil()})})})})})}), "", context)
the body this kind lays on what it makes 126 lines
Each thing of this kind runs this layer over what the kind is of.
layer over ./Record.obend
edition ObjectiveBend 1
import ./Abi.obend as Abi
import ./List.obend as Lists
import ./Document.obend as Document
import ./Form.obend as Form
import ./Plan.obend as Plans
import ./World.obend as World
import ./Card.obend as Card
import ./Scenes.obend as Scenes
import ./Relation.obend as Relations
import ./Rows.obend as Rows
import ./Text.obend as Text
# The front's body, over RECORD (docs/OVERHAUL.md §2, a front is a rule held by a director under law;
# TENURE §3C, a visible clock): a record made with a name, the condition that fills a segment
# (`fills`, in the law grammar, judged on its tide at each tick: `new.ticks % 24 == 0` is a clock
# day), how many segments its clock has (`segments`), the spell it casts when the clock is full
# (`move`) and the tide it reads (`tide`); its owner can set the tide again. As its kind finishes it, it places two rules
# under its maker (`made`): on the tide, `request.method == "tick" and (<fills>)` casts `delvetalk
# <front> fill`; on itself, a fill that brings its count of segments to a whole clock casts `move`.
# So the move is the maker's turn, judged by the law of whatever it touches, and the clock empties
# when full. Its count of fills only rises: the record's variable `fills` (its lines are kept only so
# many), with `full` set by a fill that fills the clock and cleared by the next, which is what the
# move rule reads. Only its maker's rule on the tide fills: a hand's `fill` is refused by name. The
# card shows the clock: "2 of 4".
type State = Super.State
form fill:
form arm:
form write:
text: text 1..280
form lines:
from: natural 0..1000000000
form door:
label: text 1..32
to: text 1..128
form undoor:
label: text 1..32
def write(state: State, input: WriteInput, context: Abi.Context) -> Activity<Nat>:
Super.write(state, {text: input.text}, context)
def lines(state: State, input: LinesInput, context: Abi.Context) -> Activity<Card.Replied>:
Super.lines(state, {from: input.from}, context)
def door(state: State, input: DoorInput, context: Abi.Context) -> Activity<Card.Replied>:
Super.door(state, {label: input.label, to: input.to}, context)
def undoor(state: State, input: UndoorInput, context: Abi.Context) -> Activity<Card.Replied>:
Super.undoor(state, {label: input.label}, context)
def actions(state: State, context: Abi.Context) -> Lists.List<String>:
Lists.concat(Lists.concat(if context.principal == state.owner then Text.words("fill write lines door undoor set") else Text.words("fill write lines"), if context.principal == state.maker then Text.words("arm") else Text.words("")), Super.repairAction(state, context))
def lenses() -> Lists.List<Form.Field>:
Super.objectLenses("tide")
def setArms() -> Bool:
true
def methods() -> Lists.List<String>:
Text.words("~made ~act")
def tide(state: State) -> String:
Super.field(state, "tide")
def segments(state: State) -> Nat:
match Text.number(Super.field(state, "segments")):
case yes(n): if n.value == 0n then 1n else n.value
case no(_): 1n
# The fills so far, ever: its variable `fills` (a front carried from before it kept one counts its
# `fill` lines); a whole clock of them has filled and emptied it.
def fills(state: State) -> Nat:
match Lists.find(state.vars, fn(v: Scenes.Var) -> Bool: v.name == "fills"):
case some(v): Text.digits(v.value.value, 0n)
case none(_): Lists.length(Lists.filter(Relations.rows(state.lines), fn(l: Rows.Line) -> Bool: l.verb == "fill"))
def full(state: State) -> Bool:
Lists.any(state.vars, fn(v: Scenes.Var) -> Bool: v.name == "full")
def made(state: State, input: {}, context: Abi.Context) -> Activity<Bool>:
if context.caller != state.kind then false else placing(state, context)
def placing(state: State, context: Abi.Context) -> Activity<Bool>:
let fills = Super.field(state, "fills")
match world.rule({object: {world: context.world, object: tide(state)}, name: Text.identifier(context.object), when: "request.method == \"tick\" and ({fills})", then: "delvetalk {context.object} fill"}):
case placed(_): moving(state, context)
case refused(r): Super.unarmed(state, tide(state), r.clause, r.reading, context)
def moving(state: State, context: Abi.Context) -> Activity<Bool>:
let n = natText(segments(state))
match world.rule({object: Plans.self(context), name: "move", when: moveWhen(segments(state)), then: Super.field(state, "move")}):
case placed(_): Super.armedNow(state, context)
case refused(r): Super.unarmed(state, context.object, r.clause, r.reading, context)
# Its maker places its rules again (taken off first, where they stood).
def arm(state: State, context: Abi.Context) -> Activity<Bool>:
if Super.mayArm(state, context) == false then Super.armRefused(state, context) else if Text.isObjectId(tide(state)) == false then Super.stranding(state, context) else rearming(state, context)
def rearming(state: State, context: Abi.Context) -> Activity<Bool>:
match world.unrule({object: {world: context.world, object: tide(state)}, name: Text.identifier(context.object)}):
case _: unmoving(state, context)
def unmoving(state: State, context: Abi.Context) -> Activity<Bool>:
match world.unrule({object: Plans.self(context), name: "move"}):
case _: placing(state, context)
# A fill that fills the clock: each fill of a one-segment clock, else the fill that sets `full`.
def moveWhen(n: Nat) -> String:
if n == 1n then "request.method == \"fill\"" else "request.method == \"fill\" and \"full\" in new.vars.name and not (\"full\" in old.vars.name)"
# Its maker's rule on the tide fills a segment; anyone else, or another's rule there, is told what does.
def fill(state: State, context: Abi.Context) -> Activity<Nat>:
let fills = Super.field(state, "fills")
let clock = if Text.isObjectId(tide(state)) then "a segment fills at a tick of {tide(state)} when {fills}: {Card.tideLine(tide(state))}" else Card.tideLine(tide(state))
if Super.ruledFrom(state, tide(state), context) == false then Card.refusing(0n, {clause: "ruled", reading: clock}, context) else filled(state, context)
def filled(state: State, context: Abi.Context) -> Activity<Nat>:
let at = fills(state) % segments(state) + 1n
let written(_) = write {lines: insert {author: context.sender, handle: "", verb: "fill", text: "segment {natText(at)} of {natText(segments(state))}, at clock {natText(context.clock)}", at: context.height, n: state.next}, next: add 1n}
counting(state, at)
# The count rises by one; `full` is set by the fill that fills a clock of more than one segment and
# cleared by the next (one edit of `vars` a write).
def counting(state: State, at: Nat) -> Activity<Nat>:
let written(_) = world.write(extend(keep(), {vars: counter(state)}))
marking(state, at)
def marking(state: State, at: Nat) -> Activity<Nat>:
let written(_) = world.write(extend(keep(), {vars: fullness(state, at == segments(state) && segments(state) > 1n)}))
at
def counter(state: State) -> Plans.Entries<Scenes.Var, Scenes.Var>:
match Lists.find(state.vars, fn(v: Scenes.Var) -> Bool: v.name == "fills"):
case some(v): Plans.Entries.amendItem({item: v.value, change: {name: "fills", value: natText(fills(state) + 1n)}})
case none(_): Plans.Entries.append({item: {name: "fills", value: natText(fills(state) + 1n)}})
def fullness(state: State, filling: Bool) -> Plans.Entries<Scenes.Var, Scenes.Var>:
if filling == full(state) then Plans.Entries.keep({}) else if filling then Plans.Entries.append({item: {name: "full", value: ""}}) else Plans.Entries.removeItem({item: {name: "full", value: ""}})
def clock(state: State) -> String:
let filled = fills(state) / segments(state)
let times = if filled == 0n then "it has not filled yet" else if filled == 1n then "it has filled once" else "it has filled {Text.countWord(filled)} times"
"{natText(fills(state) % segments(state))} of {natText(segments(state))}; {times}"
def entry(state: State, context: Abi.Context, line: Rows.Line) -> Document.Document:
if line.verb == "fill" then Document.text("{line.text}\n") else Super.entry(state, context, line)
def headLine(state: State, context: Abi.Context, id: String) -> Document.Document:
let name = if state.head == "" then "A FRONT" else state.head
let fills = Super.field(state, "fills")
let move = Super.field(state, "move")
let ticks = if Text.isObjectId(tide(state)) then "A segment fills at a tick of {tide(state)} when: {fills}\n {Card.tideLine(tide(state))}" else Card.tideLine(tide(state))
Document.text("{name}, a front set by {Card.shown(state.maker, state.makerHandle, context)}{Card.mine(state.maker, context)}: a slow pressure with a clock that fills while its condition holds, and casts its move when full. Its clock: {clock(state)}.\n{ticks}\nWhen full: {move}\nIts move's firing and delivery receipt: delvetalk {id} rules\n{Super.inactiveLine(state, id)}")
Amend it in the workshop
Its Bend is checked and amended by the workshop's own spell, with the Bend in its block. To send it, come in; the box is here then.
Its fields
- owner
- the town
- ownerHandle
- the town
- name
- front
- of
- record
- form
name: text 1..64 (97 characters)
name: text 1..64 fills: text 1..400 segments: natural 1..24 move: text 1..400 tide: object 1..128
- law
want stranded "a field that names no place: the town repairs it, or its maker sets it": "stranded" i (194 characters)
want stranded "a field that names no place: the town repairs it, or its maker sets it": "stranded" in new.marks.name and not ("repaired" in new.marks.name) asks delvetalk {request.object} repair- head
- {name}
- voice
- a gathering, counted in segments, that comes on whether anyone posts or not
- about
- a clock that fills while a condition holds; moves when full
- body
layer over ./Record.obend (8853 characters)
layer over ./Record.obend edition ObjectiveBend 1 import ./Abi.obend as Abi import ./List.obend as Lists import ./Document.obend as Document import ./Form.obend as Form import ./Plan.obend as Plans import ./World.obend as World import ./Card.obend as Card import ./Scenes.obend as Scenes import ./Relation.obend as Relations import ./Rows.obend as Rows import ./Text.obend as Text # The front's body, over RECORD (docs/OVERHAUL.md §2, a front is a rule held by a director under law; # TENURE §3C, a visible clock): a record made with a name, the condition that fills a segment # (`fills`, in the law grammar, judged on its tide at each tick: `new.ticks % 24 == 0` is a clock # day), how many segments its clock has (`segments`), the spell it casts when the clock is full # (`move`) and the tide it reads (`tide`); its owner can set the tide again. As its kind finishes it, it places two rules # under its maker (`made`): on the tide, `request.method == "tick" and (<fills>)` casts `delvetalk # <front> fill`; on itself, a fill that brings its count of segments to a whole clock casts `move`. # So the move is the maker's turn, judged by the law of whatever it touches, and the clock empties # when full. Its count of fills only rises: the record's variable `fills` (its lines are kept only so # many), with `full` set by a fill that fills the clock and cleared by the next, which is what the # move rule reads. Only its maker's rule on the tide fills: a hand's `fill` is refused by name. The # card shows the clock: "2 of 4". type State = Super.State form fill: form arm: form write: text: text 1..280 form lines: from: natural 0..1000000000 form door: label: text 1..32 to: text 1..128 form undoor: label: text 1..32 def write(state: State, input: WriteInput, context: Abi.Context) -> Activity<Nat>: Super.write(state, {text: input.text}, context) def lines(state: State, input: LinesInput, context: Abi.Context) -> Activity<Card.Replied>: Super.lines(state, {from: input.from}, context) def door(state: State, input: DoorInput, context: Abi.Context) -> Activity<Card.Replied>: Super.door(state, {label: input.label, to: input.to}, context) def undoor(state: State, input: UndoorInput, context: Abi.Context) -> Activity<Card.Replied>: Super.undoor(state, {label: input.label}, context) def actions(state: State, context: Abi.Context) -> Lists.List<String>: Lists.concat(Lists.concat(if context.principal == state.owner then Text.words("fill write lines door undoor set") else Text.words("fill write lines"), if context.principal == state.maker then Text.words("arm") else Text.words("")), Super.repairAction(state, context)) def lenses() -> Lists.List<Form.Field>: Super.objectLenses("tide") def setArms() -> Bool: true def methods() -> Lists.List<String>: Text.words("~made ~act") def tide(state: State) -> String: Super.field(state, "tide") def segments(state: State) -> Nat: match Text.number(Super.field(state, "segments")): case yes(n): if n.value == 0n then 1n else n.value case no(_): 1n # The fills so far, ever: its variable `fills` (a front carried from before it kept one counts its # `fill` lines); a whole clock of them has filled and emptied it. def fills(state: State) -> Nat: match Lists.find(state.vars, fn(v: Scenes.Var) -> Bool: v.name == "fills"): case some(v): Text.digits(v.value.value, 0n) case none(_): Lists.length(Lists.filter(Relations.rows(state.lines), fn(l: Rows.Line) -> Bool: l.verb == "fill")) def full(state: State) -> Bool: Lists.any(state.vars, fn(v: Scenes.Var) -> Bool: v.name == "full") def made(state: State, input: {}, context: Abi.Context) -> Activity<Bool>: if context.caller != state.kind then false else placing(state, context) def placing(state: State, context: Abi.Context) -> Activity<Bool>: let fills = Super.field(state, "fills") match world.rule({object: {world: context.world, object: tide(state)}, name: Text.identifier(context.object), when: "request.method == \"tick\" and ({fills})", then: "delvetalk {context.object} fill"}): case placed(_): moving(state, context) case refused(r): Super.unarmed(state, tide(state), r.clause, r.reading, context) def moving(state: State, context: Abi.Context) -> Activity<Bool>: let n = natText(segments(state)) match world.rule({object: Plans.self(context), name: "move", when: moveWhen(segments(state)), then: Super.field(state, "move")}): case placed(_): Super.armedNow(state, context) case refused(r): Super.unarmed(state, context.object, r.clause, r.reading, context) # Its maker places its rules again (taken off first, where they stood). def arm(state: State, context: Abi.Context) -> Activity<Bool>: if Super.mayArm(state, context) == false then Super.armRefused(state, context) else if Text.isObjectId(tide(state)) == false then Super.stranding(state, context) else rearming(state, context) def rearming(state: State, context: Abi.Context) -> Activity<Bool>: match world.unrule({object: {world: context.world, object: tide(state)}, name: Text.identifier(context.object)}): case _: unmoving(state, context) def unmoving(state: State, context: Abi.Context) -> Activity<Bool>: match world.unrule({object: Plans.self(context), name: "move"}): case _: placing(state, context) # A fill that fills the clock: each fill of a one-segment clock, else the fill that sets `full`. def moveWhen(n: Nat) -> String: if n == 1n then "request.method == \"fill\"" else "request.method == \"fill\" and \"full\" in new.vars.name and not (\"full\" in old.vars.name)" # Its maker's rule on the tide fills a segment; anyone else, or another's rule there, is told what does. def fill(state: State, context: Abi.Context) -> Activity<Nat>: let fills = Super.field(state, "fills") let clock = if Text.isObjectId(tide(state)) then "a segment fills at a tick of {tide(state)} when {fills}: {Card.tideLine(tide(state))}" else Card.tideLine(tide(state)) if Super.ruledFrom(state, tide(state), context) == false then Card.refusing(0n, {clause: "ruled", reading: clock}, context) else filled(state, context) def filled(state: State, context: Abi.Context) -> Activity<Nat>: let at = fills(state) % segments(state) + 1n let written(_) = write {lines: insert {author: context.sender, handle: "", verb: "fill", text: "segment {natText(at)} of {natText(segments(state))}, at clock {natText(context.clock)}", at: context.height, n: state.next}, next: add 1n} counting(state, at) # The count rises by one; `full` is set by the fill that fills a clock of more than one segment and # cleared by the next (one edit of `vars` a write). def counting(state: State, at: Nat) -> Activity<Nat>: let written(_) = world.write(extend(keep(), {vars: counter(state)})) marking(state, at) def marking(state: State, at: Nat) -> Activity<Nat>: let written(_) = world.write(extend(keep(), {vars: fullness(state, at == segments(state) && segments(state) > 1n)})) at def counter(state: State) -> Plans.Entries<Scenes.Var, Scenes.Var>: match Lists.find(state.vars, fn(v: Scenes.Var) -> Bool: v.name == "fills"): case some(v): Plans.Entries.amendItem({item: v.value, change: {name: "fills", value: natText(fills(state) + 1n)}}) case none(_): Plans.Entries.append({item: {name: "fills", value: natText(fills(state) + 1n)}}) def fullness(state: State, filling: Bool) -> Plans.Entries<Scenes.Var, Scenes.Var>: if filling == full(state) then Plans.Entries.keep({}) else if filling then Plans.Entries.append({item: {name: "full", value: ""}}) else Plans.Entries.removeItem({item: {name: "full", value: ""}}) def clock(state: State) -> String: let filled = fills(state) / segments(state) let times = if filled == 0n then "it has not filled yet" else if filled == 1n then "it has filled once" else "it has filled {Text.countWord(filled)} times" "{natText(fills(state) % segments(state))} of {natText(segments(state))}; {times}" def entry(state: State, context: Abi.Context, line: Rows.Line) -> Document.Document: if line.verb == "fill" then Document.text("{line.text}\n") else Super.entry(state, context, line) def headLine(state: State, context: Abi.Context, id: String) -> Document.Document: let name = if state.head == "" then "A FRONT" else state.head let fills = Super.field(state, "fills") let move = Super.field(state, "move") let ticks = if Text.isObjectId(tide(state)) then "A segment fills at a tick of {tide(state)} when: {fills}\n {Card.tideLine(tide(state))}" else Card.tideLine(tide(state)) Document.text("{name}, a front set by {Card.shown(state.maker, state.makerHandle, context)}{Card.mine(state.maker, context)}: a slow pressure with a clock that fills while its condition holds, and casts its move when full. Its clock: {clock(state)}.\n{ticks}\nWhen full: {move}\nIts move's firing and delivery receipt: delvetalk {id} rules\n{Super.inactiveLine(state, id)}")- made
2 rows
- object
- front/1
- n
- 2
- about
- empty
- object
- porch/lamp
- n
- 1
- about
- empty
- count
- 2
journal, the newest 1
- ● admittedentry 2329nafim-fapomrefresh-kind/front-kind-7 · the town