Coordinating Multiple Grafts in One Arm
After reading: you'll use apply-<graft> wet-gates from domain-patterns to chain pokes through several grafts from one domain arm — three lines per step, not nine.
When a domain arm threads state through more than one graft (increment a counter, write to kv, append to the audit log), the hand-coded shape gets repetitive. vesl-core ships a small library, domain-patterns, with apply-<graft> wet-gates that bundle each graft's three-line poke shape into a single line:
:: near the top of your app.hoon, alongside the other /+ lines:
/+ *domain-patternsWalking the import:
/+is Hoon's import rune: import a named library fromhoon/lib/.- The
*prefix on the library name pulls all exposed names into the subject (*domain-patternsvs. selective import like/+ domain-patterns). domain-patternsis the library — it lives athoon/lib/domain-patterns.hoon.
Composing Two Graft Arms in One Domain Cause
This is the pattern nockup graft inject warns about when its weld-friction lint fires (see CLI → weld-friction). When one domain cause needs to drive two grafts in a defined order — writing to kv then logging the change, or incrementing a counter then settling a note — you thread the post-state of one graft into the next via the apply-<graft> helpers in domain-patterns.
A worked arm that fans a single domain cause out to three grafts — assuming the cause variant is [%record-event name=@t]:
:: inside ?-, a %record-event arm that increments a counter,
:: writes to kv, and appends to the audit log:
%record-event
=^ efx-c state (apply-counter [%counter-increment 'events'] state)
=^ efx-k state (apply-kv [%kv-set name.u.act 1] state)
=^ efx-l state (apply-log [%log-append name.u.act] state)
:_ state
^- (list effect)
(welp efx-c (welp efx-k efx-l))Walking the arm:
%record-eventis the cause tag this arm matches.=^ efx-c state (apply-counter ...)is the threading rune. It evaluates the expression, binds the head of the returned cell toefx-c(the counter's effects list), and rebindsstateto the tail (the post-counter state). The next line sees the updatedstate.- Each
apply-<graft>call takes the graft's cause noun and the currentstate, internally routes through the underlying<graft>-pokearm, and returns[effects new-state]. - After three
=^lines,statereflects all three graft updates and eachefx-*binding holds that graft's effect list. (welp efx-c (welp efx-k efx-l))concatenates the three lists into the single(list effect)the arm returns.welpis list concatenation; the nested call performs a three-way concat.:_ statereturns[effects state]inNockApp's required[effects new-state]shape.^- (list effect)ascribes the head's type.
Each apply-<graft> takes [cause versioned-state] and returns [(list <graft>-effect) versioned-state], suitable for direct =^ binding. See hoon/lib/domain-patterns.hoon for the full helper list.
Stuck?
Something broken? The breakage is probably already in Common Pitfalls.