on master help sign in
Merge branch 'cleanorg' of github.com:urbit/docs into cleanorg
57bd226Galen Wolfe-Pauly
docs/programming/hoon/advanced.mdnew file+197
@@ -0,0 +1,197 @@
1+---
2+sort: 7
3+next: true
4+title: Advanced types
5+---
6+
7+# Advanced types
8+
9+As we noted, the definition of `span` in the last chapter is a
10+subset. The Hoon type system is simple, but not *that* simple.
11+
12+The good news is that you can *skip this section*, at least when
13+you're first learning Hoon. Polymorphism and aliasing are mainly
14+for advanced programmers writing complex infrastructure and/or
15+large functions. Don't worry about them for a little while.
16+
17+## The complete, uncensored `span`
18+
19+```
20+++ span $@ $? $noun
21+ $void
22+ == $% {$atom p/term q/(unit atom)}
23+ {$cell p/span q/span}
24+ {$core p/span q/coil}
25+ {$face p/$@(term tune) q/span}
26+ {$fork p/(set span)}
27+ {$hold p/span q/twig}
28+ ==
29+::
30+++ coil $: p/?($gold $iron $lead $zinc)
31+ q/span
32+ r/{p/?($~ ^) q/(map term foot)}
33+ ==
34+++ foot $% {$dry p/twig}
35+ {$wet p/twig}
36+ ==
37+++ tune
38+ $: p/(map term (unit twig))
39+ q/(list twig)
40+ ==
41+```
42+
43+If you compare this to the basic `span`, you'll see that we've
44+changed two stems: `$core` and `$face`. We added polymorphism to
45+`$core`, aliases and bridges to `$face`.
46+
47+## `$core`: advanced polymorphism
48+
49+If cores never changed, we wouldn't need polymorphism. Of
50+course, nouns are immutable and never change, but we use them as
51+templates to construct a new noun
52+
53+Suppose we take a core, a cell `{battery payload}`, and replace
54+the payload with a different noun. Then, we invoke an arm from
55+the battery.
56+
57+Is this legal? Does it make sense? Every function call in Hoon
58+does this, so we'd better make it work well.
59+
60+The full core stores both payload spans. The span that describes
61+the payload currently in the core is `p`. The span that describes
62+the payload the core was compiled with is `q.q`.
63+
64+In the Bertrand Meyer tradition of type theory, there are two
65+forms of polymorphism: variance and genericity. In Hoon this
66+choice is per arm, which is why our battery went from `(map term
67+twig)` to `(map term foot)` when it went into the coil. A `foot`
68+is `$dry` or `$wet`. Dry polymorphism relies on variance; wet
69+polymorphism relies on genericity.
70+
71+### Dry arms
72+
73+For a dry arm, we apply the Liskov substitution principle: we
74+ask, "can we use any `p` as if it was a `q.q`"? This is the same
75+test as in `:cast` or any type comparison (`nest`). Intuitively,
76+we ask: is the new payload compatible with the old payload?
77+
78+For a core `a`, if `p.a` fits in `q.q.a`, we can use arms on the
79+core. The product of an dry arm whose twig is `b` is always
80+defined as `{$hold a(p q.q.a, p.q %gold) b}`.
81+
82+In other words, the subject of the arm computation is the
83+original core span. The span of the modified payload, `p`, is
84+thrown away. This is of course the normal behavior of a function
85+call in most languages.
86+
87+### Dry polymorphism and core nesting rules
88+
89+Dry polymorphism works by substituting cores. Typically, the
90+the programmer uses one core as an interface definition, then
91+replace it with another core which does something useful.
92+
93+For core `b` to nest within core `a`, the batteries of `a` and
94+`b` must have the same tree shape, and the product of each `b`
95+arm must nest within the product of the `a` arm. Wet arms (see
96+below) are not compatible unless the twig is exactly the same.
97+
98+But we also apply a payload test that depends on the rules of
99+variance. Again, this is traditional Meyer type theory; don't
100+worry if you don't know it. These rules should make sense if you
101+just think about them intuitively.
102+
103+Each core has a "metal" `p.q` which defines its variance model.
104+A core can be *invariant* (`$gold`), *bivariant* (`$lead`),
105+*covariant* (`$zinc`), or *contravariant* (`$iron`). The default
106+is gold; a gold core can be converted to any metal, and any metal
107+can be converted to lead.
108+
109+A gold core `a` has a read-write payload; another core `b` that
110+nests within it (ie, can be substituted for it) must be a gold
111+core whose payload is mutually compatible (`+3.a` nests in `+3.b`,
112+`+3.b` nests in `+3.a`). Hence, *invariant*.
113+
114+A lead core `a` has an opaque payload. There is no constraint on
115+the payload of a core `b` which nests within it. Hence,
116+*bivariant*.
117+
118+An iron core `a` has a write-only sample (payload head, `+6.a`)
119+and an opaque context (payload tail, `+7.a`). A core `b` which
120+nests within it must be a gold or iron core, such that `+6.a`
121+nests within `+6.b`. Hence, *contravariant*.
122+
123+A zinc core `a` has a read-only sample (payload head, `+6.a`)
124+and an opaque context (payload tail, `+7.a`). A core `b` which
125+nests within it must be a gold or zinc core, such that `+6.b`
126+nests within `+6.a`. Hence, *covariant*.
127+
128+### Wet arms
129+
130+For a wet arm, we ask: suppose this core was actually compiled
131+using `p` instead of `q.q`? Would the Nock formula we generated
132+for `q.q` actually work for a `p` payload?
133+
134+A wet arm with twig `b` in core `a` produces the span `{$hold a
135+b}`. Assuming `a` has a modified payload, this will (lazily)
136+analyze the arm with the caller's modified payload, `p`.
137+
138+But of course, we don't actually recompile the arm at runtime.
139+We actually run the formula generated for the original payload,
140+`q.q`.
141+
142+When we call a wet arm, we're essentially using the twig as a
143+macro. We are not generating new code for every call site; we
144+are creating a new type analysis path, which works as if we
145+expanded the callee with the caller's context.
146+
147+Consider a function like `turn` (Haskell `map`) which transforms
148+each element of a list. To use `turn`, we install a list and a
149+transformation function in a generic core. The span of the list
150+we produce depends on the span of the list and the span of the
151+transformation function. But the Nock formulas for transforming
152+each element of the list will work on any function and any list,
153+so long as the function's argument is the list item.
154+
155+Again, will this work? A simple (and not quite right) way to ask
156+this question is to compile all the twigs in the battery for both
157+a payload of `p` and a payload of `q.q`, and see if they generate
158+exactly the same Nock. The actual algorithm is a little more
159+interesting, but not much.
160+
161+A Haskeller might say that in a sense, `q.q` and `q.r.q` (the
162+original payload and the battery) define a sort of implicit
163+typeclass. And indeed, Hoon uses wet arms for the same kinds of
164+problems as Haskell typeclasses.
165+
166+Like typeclasses, wet arms / gates are a powerful tool. Don't
167+use them unless you know what you're doing.
168+
169+### Constant folding
170+
171+There's only one field of the `coil` we haven't explained yet:
172+`p.r.q`. This is simply the compiled battery, if available. (Of
173+course, we compile the twigs in a core against the core itself,
174+and the formulas can't be available while we're compiling them.)
175+External users of the core want this battery constant, though: it
176+lets us fold constants by executing arms at compile time.
177+
178+## `$face`: aliases and bridges
179+
180+In the advanced `tune` form, the `$face` span also has a couple
181+of secret superpowers for hacking the namespace. Remember that
182+Hoon doesn't have anything like a symbol table; to resolve a
183+limb, we just search the span depth-first.
184+
185+If a name is in the `p.p` map, it's an alias. The map contains a
186+`(unit twig)`; if the unit is full, the name resolves to that
187+twig (compiled against the `q` span). If the unit is empty,
188+the name is blocked / skipped (see [limb](twig/limb) for what
189+this means).
190+
191+If a name is in the `q.p` map, it's a bridge. When we search for
192+a name, we also compile the bridge, and check if the name
193+resolves against the bridge product. If so, we use it.
194+
195+These hacks let us deal with interesting large-scale problems,
196+like complex library dependencies. You definitely don't need to
197+understand them to just write simple Hoon programs.
docs/programming/hoon/syntax.mdnew file+367
@@ -0,0 +1,367 @@
1+---
2+sort: 4
3+next: true
4+title: Syntax
5+---
6+
7+# Hoon syntax
8+
9+Hoon's semantics are simple, but unusual. Hoon's syntax is
10+complex, and unusual. Sorry.
11+
12+## Motivation
13+
14+An excuse: the normal human brain doesn't have hardware support
15+for math, but it does have hardware support for syntax. Learning
16+math is harder than it looks. Learning syntax is easier.
17+
18+An explanation: the Hoon syntax is trying to solve three serious
19+problems in functional syntax design. These are *terminator
20+piles*, *indentation creep*, and *feature/label confusion*.
21+
22+## Terminator piles
23+
24+*Terminator piles* are like Lisp's stacks of right parenthesess.
25+Significant whitespace solves this problem and creates others.
26+
27+Hoon has no terminator piles. Except for a 1-space / more-space
28+distinction, it has no significant whitespace.
29+
30+## Indentation creep
31+
32+*Indentation creep* is a problem caused by indentation conventions
33+where the indentation point is a function of expression tree
34+depth. It's true that short functions are better than long ones,
35+but long ones sometimes need to be written.
36+
37+A procedural block has a backbone of statements which flows
38+straight down. Most expressions are flat and of limited depth.
39+With some bulging, a long function flows *down* the page.
40+
41+A functional language lacks the expression/statement distinction.
42+So a long function means a deep tree. Given normal indentation
43+conventions, a long function wants to flow *down and across*.
44+This *diagonal* shape fits poorly into most editor windows.
45+
46+Thanks to backstep indentation (see below), Hoon programs are
47+shaped more or less like procedural programs.
48+
49+## Feature/label confusion
50+
51+*Feature/label confusion* is any syntax which makes it hard for
52+the eye to tell whether a token on the screen is a feature of the
53+language, or a label in the program. For example, in Lisp a
54+special form has the same syntax as a function call.
55+
56+The worst-case result of FLC is "DSL cancer". Every source file
57+is effectively written in its own domain-specific language. To
58+read a new file is to learn a new language -- "write-only code."
59+
60+A fixed reserved-word set, especially with syntax highlighting,
61+and especially with orthogonal grammar (in C, you don't write
62+`for(a b c)`), may not be too bad. User-level macros, operator
63+overloading, even excessive use of higher-order programming,
64+can all lead quickly to the tragedy of write-only code.
65+
66+Hoon has very weak FLC in keyword style, none in rune style.
67+It has no user-level macros or overloading. It does support
68+higher-order programming; write-only Hoon can certainly be
69+(and has been) written. But good Hoon style is to avoid it.
70+
71+# Design
72+
73+Because each twig stem has its own bulb, each has its own parser
74+rule. We'll describe these grammars as we go through the stems.
75+
76+But Hoon has a general syntax design with common principles and
77+regularities. We'll cover those here.
78+
79+## Glyphs and characters
80+
81+Hoon is a heavy punctuation user. To make ASCII great again,
82+we've mapped each punctuation glyph to a syllable:
83+
84+```
85+ace [1 space] gal < pal (
86+bar | gap [>1 space, nl] par )
87+bas \ gar > sel [
88+buc $ hax # sem ;
89+cab _ hep - ser ]
90+cen % kel { sig ~
91+col : ker } soq '
92+com , ket ^ tar *
93+doq " lus + tec `
94+dot . pam & tis =
95+fas / pat @ wut ?
96+zap !
97+```
98+
99+You don't need to memorize these glyph names, but it helps. Code
100+is often vocalized or subvocalized. "pal" is easier to say,
101+aloud or silently, then "left paren."
102+
103+Note that the list includes two separate whitespace forms: `ace`
104+for a single space, `gap` for 2+, comment or newline. Hoon
105+Besides `ace` versus `gap`, whitespace is not significant.
106+
107+Comments start with `::` and run to the end of the line. Hard
108+tab characters are illegal, and an 80-column right margin is
109+strongly encouraged. Really well-groomed Hoon uses a 55-column
110+code margin and puts a standard line comment at column 57.
111+
112+Hoon does not accept non-ASCII text in source files, except UTF-8
113+in quoted strings.
114+
115+## Tall and flat forms
116+
117+There are two kinds of Hoon expression syntax: *tall* and *flat*.
118+Most stems have both tall and flat forms. Tall twigs can contain
119+flat twigs, but not vice versa.
120+
121+Visually, a tall twig looks like a "statement" and a flat twig
122+like an "expression," preserving the attractive visual shape of
123+procedural code without the nasty side effects.
124+
125+## Regular and irregular forms
126+
127+Most stems have *regular forms*, which share a common design.
128+There is a regular flat form and a regular tall form; most stems
129+implement both. All tall forms are regular.
130+
131+Some twigs also have *irregular forms*, which follow no
132+principles at all. All irregular forms are flat.
133+
134+Some twigs (simple leafy ones) have *only* irregular forms.
135+
136+## Keywords versus runes
137+
138+A regular form starts with a *sigil*, which is either a
139+*keyword* or a *rune* -- at the programmer's choice.
140+
141+A *keyword* is `:` and then the stem label - eg, `:cons`.
142+
143+A *rune* is a pair of ASCII punctuation marks (a digraph) - eg,
144+`:-`. The first glyph in the rune indicates the category - eg,
145+`:` runes make cells. Runes can be pronounced by their glyphs or
146+by their stem -- for `:-`, you can say either "colhep" or "cons".
147+
148+Keywords may be less challenging for early learners. Rune style
149+is less cluttered and distracting for experienced programmers;
150+the system codebase is all in rune style. Beginners can start
151+with keywords and move to runes; start with runes and stick
152+with runes; or start with keywords and stick with keywords.
153+
154+Here's the FizzBuzz demo code, in idiomatic rune syntax. Compare
155+with the [original](../../demo).
156+
157+```
158+ |= end/atom
159+ =/ count 1
160+ |- ^- (list tape)
161+ ?: =(100 count) ~
162+ :_ $(count (add 1 count))
163+ ?: =(0 (mod count 15))
164+ "FizzBuzz"
165+ ?: =(0 (mod count 5))
166+ "Fizz"
167+ ?: =(0 (mod count 3))
168+ "Buzz"
169+ (text !>(count))
170+```
171+
172+## Tall regular form
173+
174+Tall regular form starts with the sigil, followed by a `gap`
175+(any whitespace except `ace`), followed by a bulb whose twigs are
176+separated by `gap`.
177+
178+There are four body subtypes: *fixed*, *running*, *jogging*, and
179+*battery*. Stems with a *fixed* number of subexpressions
180+self-terminate. For instance, `:if` has three subexpressions and
181+is self-terminating. Otherwise the twig is terminated by a
182+`gap`, then either `==` (*running* or *jogging*, most twigs) or
183+`--` (*battery*).
184+
185+The *running* body is a list of twigs. The *jogging* body is a
186+list of twig pairs, separated by a `gap`. The *battery* body is
187+a list of symbol-twig pairs, separated by a gap, prefixed by `++`
188+and then a gap.
189+
190+This definition is enough to parse. But the proper shape of the
191+whitespace gaps demands an informal convention.
192+
193+Whitespace design in Hoon is an art, not a science. It involves
194+both tall/flat mode switches and well-shaped gaps. (Hoon layout
195+could probably be done automatically with reasonable quality.
196+But it would at least take machine learning, not a rule engine.)
197+
198+There only two real *rules* in Hoon whitespace design: don't
199+go past 80 characters, and don't use (completely) blank lines.
200+Otherwise, if it looks good and is easy to read, it's good. But
201+the best way to learn the art is to do everything by convention
202+until you know what you're doing. Here are the conventions:
203+
204+### Conventions: *fixed*
205+
206+Bulbs with *fixed* fanout use "backstep" indentation, which slopes
207+backward and to the right by two spaces per line. The first
208+child is two spaces after the end of the sigil.
209+
210+Some *1-fixed*, *2-fixed*, *3-fixed* and *4-fixed* examples:
211+
212+```
213+|.
214+p
215+
216+=| p
217+q
218+
219+?: p
220+ q
221+r
222+
223+%^ p
224+ q
225+ r
226+s
227+```
228+
229+The hope of backstep indentation is that the heaviest twigs are
230+at the bottom, keeping code flow vertical rather than diagonal.
231+Alternate, reversing
232+
233+### Conventions: *running*
234+
235+A *running* bulb (a simple child list) puts the first child two
236+spaces after the end of the sigil, and the following children
237+straight down:
238+
239+A *running* example:
240+
241+```
242+:* p
243+ q
244+ r
245+ s
246+ t
247+==
248+```
249+
250+### Conventions: *jogging*
251+
252+A *jogging* bulb (a list of child pairs) is like a running bulb,
253+but backsteps the head of the pair above the tail. Most jogging
254+twigs start with a *fixed* sequence; the first jogging pair is
255+below and two steps backward from the last fixed child.
256+
257+There are two jogging conventions: *flat* (pair on one line) and
258+*tall* (pair split across lines).
259+
260+A *flat jogging* example (preceded by *1-fixed* `p`)
261+
262+```
263+?- p
264+ q r
265+ s t
266+ u v
267+==
268+```
269+
270+A *tall jogging* example (preceded by *1-fixed* `p`):
271+
272+```
273+?- p
274+ q
275+ r
276+ s
277+ t
278+ u
279+ v
280+==
281+```
282+
283+### Conventions: *battery*
284+
285+A *battery* bulb is a list of symbol-twig pairs, for the battery
286+of a core. A conventional example:
287+
288+```
289+|%
290+++ foo
291+ p
292+++ bar
293+ q
294+--
295+```
296+
297+## Flat regular form
298+
299+Flat regular form starts with the sigil, followed by `pal`
300+(`(`, left parenthesis), followed by a bulb whose subexpressions
301+are separated by `ace` (one space), followed by `par` (`)`, right
302+parenthesis).
303+
304+A twig in flat form, `:if`, `?:`, `{$if p/twig q/twig r/twig}`:
305+
306+```
307+:if(p q r)
308+
309+?:(p q r)
310+```
311+
312+The only exception is *jogging* bodies, in which subexpression
313+pairs are separated by commas:
314+
315+```
316+:make(foo bar 42, baz 55, moo 17)
317+```
318+
319+There is no flat regular form for *battery* bodies. Be tall.
320+
321+## Naming conventions
322+
323+Hoon does not enforce any rule on symbols, except that capitals
324+are not allowed (use kebab-case). However, a lot of system code
325+is written in using "lapidary" conventions that need explanation.
326+
327+Naming things is one of the hard problems in CS. Dodging this
328+problem is one of the reasons mathematicians use Greek letters,
329+not variable names. Meaningful names also interpose a verbal
330+interpretation, distracting at best and confusing at worst, on
331+the formula or algorithm. Greek letters are not *meaningful*,
332+but they are *memorable*. And their interpretation is defined by
333+the formula and nothing else.
334+
335+### Lapidary and ultralapidary
336+
337+In the *lapidary* naming style, labels are pronounceable
338+three-letter strings, usually CVC (consonant-vowel-consonant).
339+Sometimes they encode a mnemonic, but usually they are just
340+memorable. Labels are reused wherever the analogy seems
341+appropriate.
342+
343+In the *ultralapidary* naming style, labels are single letters,
344+starting in order of construction from `a`, or within a tuple
345+mold `p`. Hoon uses single-letter names for the same reason
346+Algol style languages pass arguments by order, rather than
347+keyword. Naming items by order makes sense when there are no
348+more than three or four; five is stretching it; six is too many.
349+
350+For example, when defining `add`, we want to name the operands
351+`a` and `b`. It's silly to call them `foo` and `bar`, let alone
352+`left-operand` and `right-operand`. The smaller the scale of an
353+algorithm, the simpler its names should be.
354+
355+### When in doubt, don't be lapidary
356+
357+This works in the other direction: namelessness doesn't scale.
358+Most normal code shouldn't use lapidary naming at all. (Everyone
359+agrees: there is *way* too much lapidary Hoon in Urbit.)
360+
361+Lapidary naming is only for *inherently simple code*: code that
362+both aspires to high elegance and clarity, and *is solving a
363+simple and elegant problem*.
364+
365+Given an ugly or complex problem, lapidary naming is a liability,
366+no matter the excellence of the programmer. When in doubt, use
367+long names and/or kebab-case.
docs/programming/hoon/twig/bar-core.mdnew file+20
@@ -0,0 +1,20 @@
1+---
2+sort: 5
3+next: true
4+---
5+
6+# Cores (`|` runes)
7+
8+Core twigs are flow twigs. The compiler essentially pins a Nock
9+formula, or battery of formulas, to the subject.
10+
11+All `|` twigs are macros around `$core`. (See the `$core`
12+section in [`span`](../span) above.) `$core` uses the subject as
13+the payload of a battery, whose arms are compiled with the core
14+itself as the subject.
15+
16+## Twigs
17+
18+<list dataPreview="true" className="runes" linkToFragments="true"></list>
19+
20+<kids className="runes"></kids>
docs/programming/hoon/twig/bar-core/cab-door.mdnew file+69
@@ -0,0 +1,69 @@
1+---
2+sort: 5
3+---
4+
5+# `:door, |_, "buccab", {$door p/moss q/(map term foot)}`
6+
7+Form a door, a many-armed core with payload `{sample context}`.
8+
9+## Expands to
10+
11+```
12+:new p
13+:core
14+ q
15+==
16+```
17+
18+## Syntax
19+
20+Regular: *1-fixed*, then *battery*.
21+
22+## Discussion
23+
24+A door is the general case of a gate (function). A gate is a
25+door with only one arm, the empty name `$`.
26+
27+Other languages have no real equivalent of a door, but we often
28+see the pattern of multiple functions with the same argument
29+list, or with shared argument structure. In Hoon, this shared
30+structure becomes a door.
31+
32+Calling a door is just like calling a gate, but the caller needs
33+to specify the arm. For instance, to call the gate `foo` as a
34+door, instead of `(foo bar)` we would write `~($ foo bar)`. This
35+is an irregular form for `:open($ foo bar)`, `%~`, "censig".
36+
37+## Examples
38+
39+A trivial door:
40+
41+```
42+/~zod:dojo> =mol |_ a/@ud
43+ ++ succ +(a)
44+ ++ prev (dec a)
45+ --
46+/~zod:dojo> ~(succ mol 1)
47+2
48+/~zod:dojo> ~(succ mol ~(succ mol ~(prev mol 5)))
49+6
50+```
51+
52+A more interesting door, from the kernel library:
53+
54+```
55+++ ne
56+ |_ tig=@
57+ ++ d (add tig '0')
58+ ++ x ?:((gte tig 10) (add tig 87) d)
59+ ++ v ?:((gte tig 10) (add tig 87) d)
60+ ++ w ?:(=(tig 63) '~' ?:(=(tig 62) '-' ?:((gte tig 36) (add tig 29) x)))
61+ --
62+```
63+
64+The `ne` door prints a digit in base 10, 16, 32 or 64:
65+
66+```
67+~zod:dojo> `@t`~(x ne 12)
68+'c'
69+```
docs/programming/hoon/twig/bar-core/cen-core.mdnew file+41
@@ -0,0 +1,41 @@
1+---
2+sort: 1
3+---
4+
5+# `:core, |%, "barcen", {$core p/(map term foot)}`
6+
7+Form a core `{battery payload}` with subject as the payload.
8+
9+## Produces
10+
11+A core with battery `p`. Payload is the subject.
12+
13+## Syntax
14+
15+Regular: *battery*.
16+
17+## Discussion
18+
19+A core is like an "object" in a conventional language, but its
20+attributes (*arms*) are functions on the core, not the core and
21+an argument. A "method" on a core is an arm producing a gate.
22+gate.
23+
24+## Examples
25+
26+A trivial core:
27+
28+```
29+~zod:dojo> =foo =+ x 58
30+ |%
31+ ++ n (add 42 x)
32+ ++ g |= b/@
33+ (add b n)
34+ --
35+~zod:dojo> n.foo
36+100
37+~zod:dojo> (g.foo 1)
38+101
39+```
40+
41+In this trivial example, `g` id ther
docs/programming/hoon/twig/bar-core/dot-trap.mdnew file+52
@@ -0,0 +1,52 @@
1+---
2+sort: 3
3+---
4+
5+# `:trap. |., "bardot", {$trap p/twig}`
6+
7+Form a trap, a core with one arm `$`.
8+
9+## Expands to
10+
11+```
12+:core
13+++ $ p
14+--
15+```
16+
17+## Syntax
18+
19+Regular: *1-fixed*.
20+
21+## Discussion
22+
23+A trap is a deferred computation.
24+
25+## Examples
26+
27+A trivial trap:
28+
29+```
30+~zod:dojo> =foo |.(42)
31+~zod:dojo> $:foo
32+42
33+~zod:dojo> (foo)
34+42
35+```
36+
37+A more interesting trap:
38+
39+```
40+~zod:dojo> =foo :var reps 10
41+ :var step 0
42+ :var outp 0
43+ :trap
44+ :if =(step reps)
45+ outp
46+ :moar(outp (add outp 2), step +(step))
47+~zod:dojo> (foo)
48+20
49+```
50+
51+Note that we can use `:moar()` or `$()` to recurse back into the
52+trap, since it's a core with an `$` arm.
docs/programming/hoon/twig/bar-core/hep-loop.mdnew file+42
@@ -0,0 +1,42 @@
1+---
2+sort: 4
3+---
4+
5+# `:loop, |-, "barhep", {$loop p/twig}`
6+
7+Form a trap (a core with one dry arm `$`) and kick it.
8+
9+## Expands to
10+
11+```
12+:rap $
13+:core
14+++ $ p
15+--
16+```
17+
18+## Syntax
19+
20+Regular: *1-fixed*.
21+
22+## Examples
23+
24+A trivial loop doesn't even recurse:
25+
26+```
27+~zod:dojo> |-(42)
28+42
29+```
30+
31+The classic loop is a decrement:
32+
33+```
34+~zod:dojo> =foo :var a 42
35+ :var b 0
36+ :loop
37+ :if =(a +(b))
38+ b
39+ :moar(b +(b))
40+~zod:dojo> foo
41+41
42+```
docs/programming/hoon/twig/bar-core/tar-gill.mdnew file+47
@@ -0,0 +1,47 @@
1+---
2+sort: 6
3+---
4+
5+# `:gill, |*, "bartar", {$gill p/moss q/twig}`
6+
7+Form a gill, a wet one-armed core with payload `{sample context}`.
8+
9+## Expands to
10+
11+```
12+:new p
13+:core
14++- $
15+ q
16+--
17+```
18+
19+## Syntax
20+
21+Regular: *2-fixed*.
22+
23+## Discussion
24+
25+In a normal (dry) gate, your argument is converted into the
26+sample type. In a generic (wet) gate or gill, your argument type
27+passes through the function, rather as if it was a macro (there
28+is still only one copy of the code, however).
29+
30+Genericity is a powerful and dangerous tool. Use gills only if
31+you think you know what you're doing.
32+
33+## Examples
34+
35+Wet and dry gates in a nutshell:
36+
37+```
38+~zod:dojo> =foo :gate({a/* b/*} [b a])
39+~zod:dojo> =bar :gill({a/* b/*} [b a])
40+~zod:dojo> (foo %cat %dog)
41+[6.778.724 7.627.107]
42+~zod:dojo> (bar %cat %dog)
43+[%dog %cat]
44+```
45+
46+The dry gate does not preserve the span of `a` and `b`; the wet
47+gate does.
docs/programming/hoon/twig/bar-core/tis-gate.mdnew file+42
@@ -0,0 +1,42 @@
1+---
2+sort: 2
3+---
4+
5+# `:gate, |=, "bartis", {$gate p/moss q/twig}`
6+
7+Form a gate, a dry one-armed core with payload `{sample context}`.
8+
9+## Expands to
10+
11+```
12+:new p
13+:core
14+++ $
15+ q
16+--
17+```
18+
19+## Syntax
20+
21+Regular: *2-fixed*.
22+
23+## Discussion
24+
25+## Examples
26+
27+A trivial gate:
28+
29+```
30+~zod:dojo> =foo |=(a/@ +(a))
31+~zod:dojo> (foo 20)
32+21
33+```
34+
35+A slightly less trivial gate:
36+
37+```
38+~zod:dojo> =foo :gate {a/@ b/@}
39+ (add a b)
40+~zod:dojo> (foo 20 400)
41+420
42+```
docs/programming/hoon/twig/buc-mold.mdnew file+45
@@ -0,0 +1,45 @@
1+---
2+sort: 7
3+next: true
4+---
5+
6+# Molds (`$` runes).
7+
8+A *mold* is a `gate` (function) that helps us build simple and
9+rigorous data structures. (In fact, since "mold" sounds nasty,
10+molds are often called "structures.")
11+
12+## Overview
13+
14+While Hoon can't check this property statically, a proper mold
15+is a *normalizer*: an idempotent function across all nouns. If
16+the sample of a gate has span `%noun`, and its body obeys the
17+constraint that for any x, `=((mold x) (mold (mold x)))`, it's a
18+rectifier and can be used as a mold.
19+
20+Twigs in the `$` family are macros designed for making molds.
21+But any Hoon twig may produce a mold. (This is why `moss` is a
22+synonym for `twig`).
23+
24+Many macros *bunt* a mold, producing `:per(mold $)`. This value,
25+simply the result of executing the gate on the default sample,
26+is a constant by definition and normally can be compiled as such.
27+The range of a mold (the span of its bunt) is called its *icon*.
28+
29+Molds have two uses: defining simple and rigorous structures, and
30+validating untrusted input data. Validation, though very
31+important, is a rare use case. Except for direct raw input,
32+it's generally a faux pas to rectify nouns at runtime -- or even
33+in userspace.
34+
35+As a structure definition, a mold has three common uses. One,
36+its bunt is a default value (such as the sample in a gate.) Two,
37+the product of some computation is cast to its icon, both
38+checking the type and regularizing it. Three, it's used as a
39+building block in other molds.
40+
41+## Twigs
42+
43+<list dataPreview="true" className="runes" linkToFragments="true"></list>
44+
45+<kids className="runes"></kids>
docs/programming/hoon/twig/buc-mold/cab-shoe.mdnew file+41
@@ -0,0 +1,41 @@
1+---
2+sort: 1
3+preview: Form a mold
4+---
5+
6+# `:shoe $_ "buccab" {$shoe p/twig}`
7+
8+Form a mold which normalizes to an example.
9+
10+## Expands to
11+
12+```
13+:gate *
14+p
15+```
16+
17+## Syntax
18+
19+Regular: *1-fixed*.
20+
21+Irregular: `_foo` is `:shoe(foo)`.
22+
23+## Discussion
24+
25+A shoe discards the sample it's supposededly normalizing, and
26+produces its example instead.
27+
28+## Examples
29+
30+```
31+~zod:dojo> =foo :shoe([%foobar %moobaz])
32+
33+~zod:dojo> (foo %foo %bar)
34+[%foobar %moobaz]
35+
36+~zod:dojo> `foo`[%foobar %moobaz]
37+[%foobar %moobaz]
38+
39+~zod:dojo $:foo
40+[%foobar %moobaz]
41+```
docs/programming/hoon/twig/buc-mold/cen-book.mdnew file+42
@@ -0,0 +1,42 @@
1+---
2+sort: 2
3+---
4+
5+# `:book, $%, "buctis", {$book p/(list {{aura @} moss})}`
6+
7+Form a mold which normalizes a union distinguished by a head atom.
8+
9+## Normalizes to
10+
11+For any item `i` in `p`, a cell whose head is the atom `q.p.i.p`,
12+and whose tail recognizes `q.i.p`.
13+
14+Void if `p` is empty.
15+
16+## Defaults to
17+
18+For the first item `i` in `p`, the cell `[q.p.i.p $:q.i.p]`.
19+Crashes if `p` is empty.
20+
21+## Syntax
22+
23+Regular form: *2-running*.
24+
25+## Discussion
26+
27+A book is a tagged union, an extremely common data model.
28+
29+Each item in a book is called a "page." Make sure the first page
30+in the book terminates, or the default will be an infinite loop!
31+
32+## Examples
33+
34+```
35+~zod:dojo> =foo :book({$foo p/@ud q/@ud} {$bar p/@ud})
36+
37+~zod:dojo> (foo [%bar 37])
38+[%bar p=37]
39+
40+~zod:dojo> $:foo
41+[%foo p=0 q=0]~
42+```
docs/programming/hoon/twig/buc-mold/col-bank.mdnew file+41
@@ -0,0 +1,41 @@
1+---
2+sort: 3
3+---
4+
5+# `:bank, $:, "buccol", {$bank p/(list moss)}`
6+
7+Form a mold which recognizes a tuple.
8+
9+## Normalizes
10+
11+The tuple the length of `p`, normalizing each item, defaulting
12+where the tuple does not match.
13+
14+Void if `p` is empty.
15+
16+## Defaults to
17+
18+The tuple the length of `p`, defaulting each items.
19+
20+Crashes if `p` is empty.
21+
22+## Syntax
23+
24+Regular: *running*.
25+
26+Irregular: `{a b c}` is `:bank(a b c)`.
27+
28+## Examples
29+
30+```
31+~zod:dojo> =foo :bank(p/@ud q/@tas)
32+
33+~zod:dojo> (foo 33 %foo)
34+[p=33 q=%foo]
35+
36+~zod:dojo> `foo`[33 %foo]
37+[p=33 q=%foo]
38+
39+~zod:dojo> $:foo
40+[p=0 q=%$]
41+```
docs/programming/hoon/twig/buc-mold/hep-lamb.mdnew file+35
@@ -0,0 +1,35 @@
1+---
2+sort: 4
3+---
4+
5+# `:lamb, $-, "buchep", {$lamb p/moss q/moss}`
6+
7+Form a mold which normalizes to an example gate.
8+
9+## Expands to
10+
11+```
12+:shoe
13+:iron
14+:gate p
15+$:q
16+```
17+
18+## Syntax
19+
20+Regular: *2-fixed*.
21+
22+## Discussion
23+
24+Since a lamb is a shoe, it is not useful for normalizing, just
25+for its signature. In particular, the existence of lambs does
26+let us send gates or other cores over the network!
27+
28+## Examples
29+
30+```
31+~zod:dojo> =foo :lamb($foo $bar)
32+
33+~zod:dojo> ($:foo %foo)
34+%bar
35+```
docs/programming/hoon/twig/buc-mold/ket-bush.mdnew file+37
@@ -0,0 +1,37 @@
1+---
2+sort: 5
3+---
4+
5+# `:bush, $^, "bucket", {$bush p/moss q/moss}`
6+
7+Form a mold which normalizes a union distinguished by head depth.
8+
9+## Normalizes to
10+
11+Default, if the sample is an atom; `p`, if the head of the sample
12+is an atom; `q` otherwise.
13+
14+## Defaults to
15+
16+The default of `p`.
17+
18+## Syntax
19+
20+Regular: *2-fixed*.
21+
22+## Examples
23+
24+```
25+~zod:dojo> =a :book({$foo p/@ud q/@ud} {$bar p/@ud})
26+
27+~zod:dojo> =b :bush({a a} a)
28+
29+~zod:dojo> (b [[%bar 33] [%foo 19 22]])
30+[[%bar p=33] [%foo p=19 q=22]]
31+
32+~zod:dojo> (b [%foo 19 22])
33+[%foo p=19 q=22]
34+
35+~zod:dojo> $:b
36+[%bar p=0]
37+```
docs/programming/hoon/twig/buc-mold/pat-claw.mdnew file+39
@@ -0,0 +1,39 @@
1+---
2+sort: 6
3+---
4+
5+# `:claw, $@, "bucpat", {$claw p/moss q/moss}`
6+
7+Form a mold which normalizes a union distinguished by depth.
8+
9+## Normalizes to
10+
11+Default, if the sample is an atom; `p`, if the head of the sample
12+is an atom; `q` otherwise.
13+
14+## Defaults to
15+
16+The default of `p`.
17+
18+## Syntax
19+
20+Regular: *2-fixed*.
21+
22+Product: a mold which applies `p` if its sample is an atom,
23+`q` if its sample is a cell.
24+
25+Regular form: *2-fixed*.
26+
27+Example:
28+```
29+~zod:dojo> =a :claw($foo :bank(p/$bar q/@ud))
30+
31+~zod:dojo> (a %foo)
32+%foo
33+
34+~zod:dojo> `a`[%bar 99]
35+[p=%bar q=99]
36+
37+~zod:dojo> $:a
38+[%foo p=0 q=0]
39+```
docs/programming/hoon/twig/buc-mold/tis-coat.mdnew file+35
@@ -0,0 +1,35 @@
1+---
2+sort: 7
3+---
4+
5+# `:coat, $=, "buctis", {$coat p/@tas q/moss}`
6+
7+Form a mold which wraps a face around another mold.
8+
9+## Expands to
10+
11+```
12+:gate *
13+:name(p :call(q +6))
14+```
15+
16+## Syntax
17+
18+Regular: *2-fixed*.
19+
20+Irregular: `foo/bar` is `:coat(foo bar)`.
21+
22+## Discussion
23+
24+Note that the Hoon compiler is at least slightly clever about
25+compiling molds, and almost never has to actually put in a gate
26+layer (as seen in the expansion above) to apply a coat.
27+
28+## Examples
29+
30+```
31+~zod:dojo> =a :coat(p $foo)
32+
33+~zod:dojo> (a %bar)
34+p=%foo
35+```
docs/programming/hoon/twig/buc-mold/wut-pick.mdnew file+45
@@ -0,0 +1,45 @@
1+---
2+sort: 8
3+---
4+
5+# `:pick, $?, "bucwut", {$? p/(list moss)}`
6+
7+Form a mold which normalizes a general union.
8+
9+## Normalizes to
10+
11+The first item in `p` which normalizes the sample to itself;
12+otherwise, default.
13+
14+Void, if `p` is empty.
15+
16+## Defaults to
17+
18+The first item in `p`.
19+
20+## Syntax
21+
22+Regular: *running*.
23+
24+Irregular: `?(%foo %bar)` is `$?(%foo %bar)`.
25+
26+## Discussion
27+
28+For a union of atoms, a pick is fine. For more complex nouns,
29+always try to use a book, claw or bush, at least if you expect
30+your mold to be used as a normalizer.
31+
32+## Examples
33+
34+```
35+~zod:dojo> =a ?($foo $bar $baz)
36+
37+~zod:dojo> (a %baz)
38+%baz
39+
40+~zod:dojo> (a [37 45])
41+%foo
42+
43+~zod:dojo> $:a
44+$foo
45+```
docs/programming/hoon/twig/cen-call.mdnew file+16
@@ -0,0 +1,16 @@
1+---
2+sort: 6
3+next: true
4+---
5+
6+# Full make (`%` runes)
7+
8+We've already covered the irregular-only twigs `$wing` and
9+`$limb`. These are simple forms of the *invocation* family of
10+twigs, `%`, whose general form is `$make`, `%=`.
11+
12+## Twigs
13+
14+<list dataPreview="true" className="runes" linkToFragments="true"></list>
15+
16+<kids className="runes"></kids>
docs/programming/hoon/twig/cen-call/cab-keep.mdnew file+34
@@ -0,0 +1,34 @@
1+---
2+sort: 2
3+---
4+
5+# `:keep, %_, centis, {$keep p/wing q/(list (pair wing seed))}`
6+
7+Take a wing (attribute path) with changes, preserving type.
8+
9+## Expands to
10+
11+:like(p :make(p q))
12+
13+## Syntax
14+
15+Regular: *1-fixed*, then *jogging*.
16+
17+## Discussion
18+
19+`:keep` is different from `:make` because `:make` can change the
20+span of a limb with mutations.
21+
22+## Examples
23+
24+```
25+~zod:dojo> =foo [p=42 q=6]
26+~zod:dojo> foo(p %bar)
27+[p=%bar q=6]
28+~zod:dojo> foo(p [55 99])
29+[p=[55 99] q=6]
30+~zod:dojo> %_(foo p %bar)
31+[p=7.496.034 99]
32+~zod:dojo> %_(foo p [55 99])
33+! nest-fail
34+```
docs/programming/hoon/twig/cen-call/dot-lace.mdnew file+24
@@ -0,0 +1,24 @@
1+---
2+sort: 5
3+---
4+
5+# `:lace, %., "cendot", {$lace p/seed q/seed}`
6+
7+Call a gate (function), reversed.
8+
9+## Expands to
10+
11+`:call(q p)`.
12+
13+## Syntax
14+
15+Regular: *2-fixed*.
16+
17+## Examples
18+
19+```
20+~zod:dojo> =add-triple |=({a/@ b/@ c/@} :(add a b c))
21+~zod:dojo> %.([1 2 3] add-triple)
22+6
23+```
24+
docs/programming/hoon/twig/cen-call/hep-call.mdnew file+43
@@ -0,0 +1,43 @@
1+---
2+sort: 4
3+---
4+
5+# `:call, %-, "cenhep", {$call p/seed q/seed}`
6+
7+Call a gate (function).
8+
9+## Expands to
10+
11+`:open($ p q)`.
12+
13+## Syntax
14+
15+Regular: *2-fixed*.
16+
17+Irregular: `(a)` is `$:a`; `(a b c d)` is `:call(a [b c d])`.
18+
19+## Discussion
20+
21+`$call` is a function call; `p` is the function (`gate`), `q` the
22+argument. `$call` is a special case of `$open`, and a gate is a
23+special case of a door.
24+
25+In a gate, the modified core has only one anonymous arm; in a
26+door it gets a full battery. Intuitively, a gate defines one
27+algorithm it can compute upon its sample, `+6`. A door defines
28+many such algorithms.
29+
30+In classical languages, doors correspond to groups of functions
31+with the same argument list, or at least sharing a prefix. In
32+Hoon, this shared sample is likely to be pulled into a door.
33+
34+## Examples
35+
36+```
37+~zod:dojo> =add-triple |=({a/@ b/@ c/@} :(add a b c))
38+~zod:dojo> (add-triple 1 2 3)
39+6
40+~zod:dojo> %-(add-triple [1 2 3])
41+6
42+```
43+
docs/programming/hoon/twig/cen-call/ket-calq.mdnew file+23
@@ -0,0 +1,23 @@
1+---
2+sort: 7
3+---
4+
5+# `:calq, %^, "cenket", {$calq p/seed q/seed r/seed s/seed}`
6+
7+Call a gate (function), with a triple sample.
8+
9+## Expands to
10+
11+`:call(p [q r s])`.
12+
13+## Syntax
14+
15+Regular: *4-fixed*.
16+
17+## Examples
18+
19+```
20+~zod:dojo> =add-triple |=({a/@ b/@ c/@} :(add a b c))
21+~zod:dojo> %^(add-triple 1 2 3)
22+6
23+```
docs/programming/hoon/twig/cen-call/lus-calt.mdnew file+23
@@ -0,0 +1,23 @@
1+---
2+sort: 6
3+---
4+
5+# `:calt, %+, "cenlus", {$calt p/seed q/seed r/seed}`
6+
7+Call a gate (function), with a cell sample.
8+
9+## Expands to
10+
11+`:call(p [q r])`.
12+
13+## Syntax
14+
15+Regular: *3-fixed*.
16+
17+## Examples
18+
19+```
20+~zod:dojo> =add-triple |=({a/@ b/@ c/@} :(add a b c))
21+~zod:dojo> %+(add-triple 1 [2 3])
22+6
23+
docs/programming/hoon/twig/cen-call/sig-open.mdnew file+32
@@ -0,0 +1,32 @@
1+---
2+sort: 3
3+---
4+
5+# `:open, %~, "censig", {$cnsg p/wing q/twig r/twig}
6+
7+## Expands to
8+
9+```
10+:rap(p :make(q +6 r))
11+```
12+
13+## Syntax
14+
15+Regular: *3-fixed*.
16+
17+Irregular: `~(a b c)` is `%~(a b c)`; `~(a b c d e)` is `%~(a b
18+[c d e])`.
19+
20+## Discussion
21+
22+`:open` is the general case of a function call, `:call`. In
23+both, we replace the sample (`+6`) of a core. In `:call` the
24+core is a gate and we
25+
26+Most languages do not have cores, doors, or `:open`. "Just
27+learn to step outside your linear, Western way of thinking."
28+
29+## Examples
30+
31+See [`:door`](../bar-core/cab-door).
32+
docs/programming/hoon/twig/cen-call/tis-make.mdnew file+43
@@ -0,0 +1,43 @@
1+---
2+sort: 1
3+---
4+
5+# `:make, %=, centis, {$make p/wing q/(list (pair wing seed))}`
6+
7+Take a wing (attribute path) with changes.
8+
9+## Produces
10+
11+`p`, modified by the change list `q`.
12+
13+If `p` resolves to a leg, `q` is a list of changes to that leg.
14+If `p` resolves to an arm, `q` is a list of changes to the core
15+containing that arm. We compute the arm on the modified core.
16+
17+## Syntax
18+
19+Regular: *1-fixed*, then *jogging*.
20+
21+Irregular: `foo(x 1, y 2, z 3)` is `:make(foo x 1, y 2, z 3)`.
22+
23+## Discussion
24+
25+Note that `p` is a wing, not a twig. Knowing that a function
26+call `(foo bar)` involves making `foo`, replacing its sample
27+at slot `+6` with `bar`, and taking the `$` limb, you might think
28+`(foo bar)` would mean `:(make foo +6 bar)`.
29+
30+But it's actually `:pin(foo :(make $ +2 +6 bar))`. Even if `foo`
31+is a wing, we would just be mutating `+6` within the core that
32+defines the `foo` arm. Instead we want to modify the *product*
33+of `foo` -- the gate -- so we have to pin it into the subject.
34+
35+## Examples
36+
37+```
38+~zod:dojo> =foo [p=5 q=6]
39+~zod:dojo> foo(p 42)
40+[p=42 q=6]
41+~zod:dojo> foo(+3 99)
42+[p=5 99]
43+```
docs/programming/hoon/twig/col-cell.mdnew file+15
@@ -0,0 +1,15 @@
1+---
2+sort: 3
3+next: true
4+---
5+
6+# Cell construction (`:` runes)
7+
8+The cell twigs, `$cons` and friends, are simple and regular.
9+All `:` twigs expand to `$cons`.
10+
11+## Twigs
12+
13+<list dataPreview="true" className="runes" linkToFragments="true"></list>
14+
15+<kids className="runes"></kids>
docs/programming/hoon/twig/col-cell/cab-scon.mdnew file+24
@@ -0,0 +1,24 @@
1+---
2+sort: 6
3+---
4+
5+# `:scon, :_, "colcab", {$scon p/twig q/twig}`
6+
7+Construct a cell, inverted.
8+
9+## Expands to
10+
11+```
12+:cons(q p)
13+```
14+
15+## Syntax
16+
17+Regular: *2-fixed*.
18+
19+## Examples
20+
21+```
22+~zod:dojo> :_(1 2)
23+[2 1]
24+```
docs/programming/hoon/twig/col-cell/hep-cons.mdnew file+42
@@ -0,0 +1,42 @@
1+---
2+sort: 1
3+---
4+
5+# `:cons, :-, "colhep", {$cons p/twig q/twig}`
6+
7+Construct a cell (2-tuple).
8+
9+## Produces
10+
11+The cell of `p` and `q`.
12+
13+## Syntax
14+
15+Regular: *2-fixed*.
16+
17+Irregular: `[a b]` is `:cons(a b)`.
18+
19+Irregular: `[a b c]` is `[a [b c]]`.
20+
21+Irregular: `a^b^c` is `[a b c]`.
22+
23+Irregular: `a+b` is `[%a b]`.
24+
25+Irregular: `\`a` is `[~ a]`.
26+
27+Irregular: `~[a b]` is `[a b ~]`.
28+
29+Irregular: `[a b c]~` is `[[a b c] ~]`.
30+
31+## Discussion
32+
33+Hoon twigs actually use the same "autocons" pattern as Nock
34+formulas. If you're assembling twigs (which usually only the
35+compiler does), `[a b]` is the same as `[%cons a b]`.
36+
37+## Examples
38+
39+```
40+~zod:dojo> :-(1 2)
41+[1 2]
42+```
docs/programming/hoon/twig/col-cell/ket-conq.mdnew file+28
@@ -0,0 +1,28 @@
1+---
2+sort: 3
3+---
4+
5+# `:conq, :^, "colket", {$conq p/twig q/twig r/twig s/twig}`
6+
7+Construct a quadruple (4-tuple).
8+
9+## Expands to
10+
11+```
12+:cons(p :cons(q :cons(r s)))
13+```
14+
15+## Syntax
16+
17+Regular: *4-fixed*.
18+
19+## Examples
20+
21+```
22+/~zod:dojo> :^(1 2 3 4)
23+[1 2 3 4]
24+/~zod:dojo> :^ 5 6
25+ 7
26+ 8
27+[5 6 7 8]
28+```
docs/programming/hoon/twig/col-cell/lus-cont.mdnew file+28
@@ -0,0 +1,28 @@
1+---
2+sort: 2
3+---
4+
5+# `:cont, :+, "collus", {$cont p/twig q/twig r/twig}`
6+
7+Construct a triple (3-tuple).
8+
9+## Expands to:
10+
11+```
12+:cons(p :cons(q r))
13+```
14+
15+## Syntax
16+
17+Regular: *3-fixed*.
18+
19+## Examples
20+
21+```
22+/~zod:dojo> :+ 1
23+ 2
24+ 3
25+[1 2 3]
26+/~zod:dojo> :+(%a ~ 'b')
27+[%a ~ 'b']
28+```
docs/programming/hoon/twig/col-cell/sig-conl.mdnew file+33
@@ -0,0 +1,33 @@
1+---
2+sort: 5
3+---
4+
5+# `:conl, :~, "colsig", {$conl p/(list seed)}`
6+
7+Construct a null-terminated list.
8+
9+## Expands to
10+
11+```
12+|-(?~(p ~ :cons(i.p $(p t.p))))
13+```
14+
15+## Syntax
16+
17+Regular: *running*.
18+
19+## Examples
20+
21+```
22+~zod:dojo> :~(5 3 4 2 1)
23+[5 3 4 2 1 ~]
24+~zod:dojo> ~[5 3 4 2 1]
25+[5 3 4 2 1 ~]
26+~zod:dojo> :~ 5
27+ 3
28+ 4
29+ 2
30+ 1
31+ ==
32+[5 3 4 2 1 ~]
33+```
docs/programming/hoon/twig/col-cell/tar-conp.mdnew file+36
@@ -0,0 +1,36 @@
1+---
2+sort: 4
3+---
4+
5+# `:conp, :*, "coltar" {$conp p/(list twig)}`
6+
7+Construct an n-tuple.
8+
9+## Expands to
10+
11+```
12+|-(?~(p !! ?~(t.p i.p :cons(i.p $(p t.p)))))
13+```
14+
15+## Syntax
16+
17+Regular: *running*.
18+
19+## Examples
20+```
21+/~zod:dojo> :*(5 3 4 1 4 9 0 ~ 'a')
22+[5 3 4 1 4 9 0 ~ 'a']
23+/~zod:dojo> [5 3 4 1 4 9 0 ~ 'a']
24+[5 3 4 1 4 9 0 ~ 'a']
25+/~zod:dojo> :* 5
26+ 3
27+ 4
28+ 1
29+ 4
30+ 9
31+ 0
32+ ~
33+ 'a'
34+ ==
35+[5 3 4 1 4 9 0 ~ 'a']
36+```
docs/programming/hoon/twig/dot-nock.mdnew file+14
@@ -0,0 +1,14 @@
1+---
2+sort: 10
3+next: true
4+---
5+
6+# Intrinsics (`.` runes)
7+
8+Anything Nock can do, Hoon can do also.
9+
10+## Twigs
11+
12+<list dataPreview="true" className="runes" linkToFragments="true"></list>
13+
14+<kids className="runes"></kids>
docs/programming/hoon/twig/dot-nock/ket-wish.mdnew file+23
@@ -0,0 +1,23 @@
1+---
2+sort: 5
3+---
4+
5+# `:wish, .^, "dotket", {$wish p/moss q/seed}`
6+
7+Load data from the Arvo namespace with Nock `11`.
8+
9+## Produces
10+
11+The noun whose name is `q`, cast to the icon of `p`.
12+
13+## Discussion
14+
15+Nock has no `11` instruction, of course. But the virtual Nock
16+used to run userspace code does. Nock `11` loads from a
17+typed immutable namespace defined by its virtual context.
18+
19+We don't remold dynamically nouns in a `:wish`, but we do check
20+that the type of the value nests in `p`.
21+
22+## Examples
23+
docs/programming/hoon/twig/dot-nock/lus-bump.mdnew file+29
@@ -0,0 +1,29 @@
1+---
2+sort: 3
3+---
4+
5+# `:bump, .+, "dotlus", {$bump p/seed}`
6+
7+Increment an atom with Nock `4`.
8+
9+## Produces
10+
11+`p` plus `1` if `p` is an atom; otherwise, crashes. The product
12+atom has no aura.
13+
14+## Syntax
15+
16+Regular: *1-fixed*.
17+
18+Irregular: `+(6)` is `.+(6)`.
19+
20+## Examples
21+
22+```
23+~zod:dojo> +(6)
24+7
25+~zod:dojo> +(%foo)
26+7.303.015
27+~zod:dojo> +([1 2])
28+! nest-fail
29+```
docs/programming/hoon/twig/dot-nock/tar-nock.mdnew file+38
@@ -0,0 +1,38 @@
1+---
2+sort: 1
3+---
4+
5+# `:nock, .*, "dottar", {$nock p/twig q/twig}`
6+
7+Compute the Nock function.
8+
9+## Produces
10+
11+Nock of formula `q` and subject `p`, with span `%noun`.
12+
13+## Syntax
14+
15+Regular: *2-fixed*.
16+
17+## Discussion
18+
19+Note that `:nock` can be used to bypass the type system,
20+though its product contains no type information. It's
21+perfectly practical to use Hoon as a typeless language.
22+
23+## Examples
24+
25+```
26+~zod:dojo> .*([20 30] [0 2])
27+20
28+~zod:dojo> .*(33 [4 0 1])
29+34
30+~zod:dojo> .*(|.(50) [9 2 0 1])
31+50
32+~zod:dojo> .*(12 [7 [`1 [4 `1]] [`2 `3 `2]])
33+[12 13 12]
34+~zod:dojo> .*(~ [5 1^4 [4 1^3]])
35+0
36+~zod:dojo> .*(~ [5 1^5 [4 1^3]])
37+1
38+```
docs/programming/hoon/twig/dot-nock/tis-same.mdnew file+35
@@ -0,0 +1,35 @@
1+---
2+sort: 4
3+---
4+
5+# `:same, .=, "dottis", {$same p/twig q/twig}`
6+
7+Test for equality with Nock `5`.
8+
9+## Produces
10+
11+`&`, `%.y`, `0` if `p` equals `q`; otherwise `|`, `%.n`, `1`.
12+
13+## Syntax
14+
15+Regular: *2-fixed*.
16+
17+Irregular: `=(a b)` is `.=(a b)`.
18+
19+## Discussion
20+
21+Like Nock equality, `:same` tests if two nouns are the same,
22+ignoring invisible pointer structure. Because in a conventional
23+noun implementation each noun has a lazy short hash, comparisons
24+are fast unless the hash needs to be computed, or we are comparing
25+separate copies of identical nouns. (Comparing large duplicates
26+is a common cause of performance bugs.)
27+
28+## Examples
29+
30+```
31+~zod:dojo> =(0 0)
32+%.y
33+~zod:dojo> =(1 2)
34+%.n
35+```
docs/programming/hoon/twig/dot-nock/wut-deep.mdnew file+24
@@ -0,0 +1,24 @@
1+---
2+sort: 2
3+---
4+
5+# `:deep, .?, "dotwut", {$deep p/twig}`
6+
7+Test for cell or atom with Nock `3`.
8+
9+## Produces
10+
11+`&`, `%.y`, `0` if `p` is a cell; otherwise `|`, `%.n`, `1`.
12+
13+## Syntax
14+
15+Regular: *1-fixed*.
16+
17+## Examples
18+
19+```
20+~zod:dojo> .?(~)
21+%.n
22+~zod:dojo> .?([2 3])
23+%.y
24+```
docs/programming/hoon/twig/ket-cast.mdnew file+18
@@ -0,0 +1,18 @@
1+---
2+sort: 9
3+next: true
4+---
5+
6+# Type manipulation (`^` runes).
7+
8+`$cast`, `$like`, and `$name` let us adjust spans without
9+violating type constraints.
10+
11+The `nest` algorithm which tests span subtyping is conservative;
12+it never allows invalid nests, it sometimes rejects valid nests.
13+
14+## Twigs
15+
16+<list dataPreview="true" className="runes" linkToFragments="true"></list>
17+
18+<kids className="runes"></kids>
docs/programming/hoon/twig/ket-cast/bar-iron.mdnew file+39
@@ -0,0 +1,39 @@
1+---
2+sort: 5
3+---
4+
5+# `:iron ^| "ketbar" {$iron p/seed}`
6+
7+Convert a gold core to a contravariant core (write-only sample).
8+
9+## Produces
10+
11+`p` as an iron core; crash if not a gold core.
12+
13+## Syntax
14+
15+Regular: *1-fixed*.
16+
17+## Discussion
18+
19+An iron core is an opaque function (gate or door).
20+
21+Theorem: if span `x` nests within span `a`, and span `y` nests
22+within span `b`, a core accepting `b` and producing `x` nests
23+within a iron core accepting `y` and producing `a`.
24+
25+Informally, a function fits an interface if the function has a
26+more specific result and/or a less specific argument than the
27+interface.
28+
29+## Examples
30+
31+The prettyprinter shows the core metal (`.` gold, `|` iron):
32+
33+```
34+~zod:dojo> |=(@ 1)
35+<1.gcq [@ @n <250.yur 41.wda 374.hzt 100.kzl 1.ypj %151>]>
36+~zod:dojo> ^|(|=(@ 1))
37+<1|gcq [@ @n <250.yur 41.wda 374.hzt 100.kzl 1.ypj %151>]>
38+```
39+
docs/programming/hoon/twig/ket-cast/hep-cast.mdnew file+41
@@ -0,0 +1,41 @@
1+---
2+sort: 2
3+---
4+
5+# `:cast ^- "kethep" {$cast p/moss q/seed}`
6+
7+Cast by construction (mold).
8+
9+## Expands to
10+
11+```
12+:like(:bunt(p) q)
13+```
14+
15+## Syntax
16+
17+Regular: *2-fixed*
18+
19+## Discussion
20+
21+It's a good practice to put a `:cast` at the top of every arm
22+(including gates, loops, etc). This cast is strictly necessary
23+only in the presence of head recursion (otherwise you'll get a
24+`rest-loop` error, or if you really screw up spectacularly an
25+infinite loop in the compiler).
26+
27+## Examples
28+
29+``
30+~zod:dojo> (add 90 7)
31+97
32+~zod:dojo> `@t`(add 90 7)
33+'a'
34+~zod:dojo> ^-(@t (add 90 7))
35+'a'
36+/~zod:dojo> =foo |= a/@tas
37+ ^- (unit @ta)
38+ `a
39+/~zod:dojo> (foo 97)
40+[~ ~.a]
41+```
docs/programming/hoon/twig/ket-cast/lus-like.mdnew file+25
@@ -0,0 +1,25 @@
1+---
2+sort: 1
3+---
4+
5+# `:like ^+ "ketlus" {$like p/seed q/seed}`
6+
7+Cast by example (seed).
8+
9+## Produces
10+
11+The value of `p` with the span of `q`, if the span of `p` nests
12+within the span of `q`. Otherwise, `nest-fail`.
13+
14+## Syntax
15+
16+Regular: *2-fixed*.
17+
18+Irregular: `\`_foo\`bar` is `:like(foo bar)`.
19+
20+## Examples
21+
22+```
23+~zod:dojo> :like('text' 97)
24+'a'
25+```
docs/programming/hoon/twig/ket-cast/pam-zinc.mdnew file

No changes to the content.

docs/programming/hoon/twig/ket-cast/sig-burn.mdnew file+22
@@ -0,0 +1,22 @@
1+# `:burn`, `^~`, "ketsig", `{$burn p/twig}`
2+
3+Try executing `p` at compile time.
4+
5+Tries to execute `p` statically at compile time. If this
6+fails, `p` remains dynamic. Primarily useful for
7+optimization: when a value is static, `^~` can simplify the compilation.
8+
9+Regular form *1-fixed*
10+
11+Examples
12+--------
13+
14+ /~zod:dojo> (make '|-(42)')
15+ [%8 p=[%1 p=[1 42]] q=[%9 p=2 q=[%0 p=1]]]
16+ /~zod:dojo> (make '^~(|-(42))')
17+ [%1 p=42]
18+
19+Here we use `++make` to examine the nock generated for a particular
20+computation. We start with a simple kicked trap, `|-`, that just
21+generates the static value `42`. When we wrap our `|-` in a `^~` you can
22+see that our compilation is much simpler.
docs/programming/hoon/twig/ket-cast/tis-name.mdnew file+32
@@ -0,0 +1,32 @@
1+---
2+sort: 3
3+---
4+
5+# `:name ^= "kettis" {$name p/toga q/seed}`
6+
7+Name a value.
8+
9+## Produces
10+
11+If `p` is a term, the product `q` with span `[%face p q]`. `p`
12+may also be a tuple of terms, or a term-toga pair; the span of
13+`q` must divide evenly into cells to match it.
14+
15+## Syntax
16+
17+Regular: *2-fixed*.
18+
19+Irregular: `foo=bar` is `:name(foo bar)`.
20+
21+## Examples
22+```
23+~zod:dojo> a=1
24+a=1
25+~zod:dojo> ^= a
26+ 1
27+a=1
28+~zod:dojo> [b c d]=[1 2 3 4]
29+[b=1 c=2 d=[3 4]]
30+~zod:dojo> [b c d=[x y]]=[1 2 3 4]
31+[b=1 c=2 d=[x=3 y4]]
32+```
docs/programming/hoon/twig/ket-cast/wut-lead.mdnew file+37
@@ -0,0 +1,37 @@
1+---
2+sort: 4
3+---
4+
5+# `:lead ^? "ketwut" {$lead p/seed}`
6+
7+Convert any core to a bivariant core (opaque payload).
8+
9+## Produces
10+
11+`p` as a lead core; crash if not a core.
12+
13+## Syntax
14+
15+Regular: *1-fixed*.
16+
17+## Discussion
18+
19+A lead core is an opaque generator.
20+
21+Theorem: if span `x` nests within span `a`, a lead core producing
22+`x` nests within a lead core producing `a`.
23+
24+Informally, a more specific generator can be used as a less
25+specific generator.
26+
27+## Examples
28+
29+The prettyprinter shows the core metal (`.` gold, `?` lead):
30+
31+```
32+~zod:dojo> |=(@ 1)
33+<1.gcq [@ @n <250.yur 41.wda 374.hzt 100.kzl 1.ypj %151>]>
34+~zod:dojo> ^?(|=(@ 1))
35+<1?gcq [@ @n <250.yur 41.wda 374.hzt 100.kzl 1.ypj %151>]>
36+```
37+
docs/programming/hoon/twig/sem-make.mdnew file+14
@@ -0,0 +1,14 @@
1+---
2+sort: 11
3+next: true
4+---
5+
6+# Macros (`;` runes)
7+
8+Miscellaneous useful macros.
9+
10+## Twigs
11+
12+<list dataPreview="true" className="runes" linkToFragments="true"></list>
13+
14+<kids className="runes"></kids>
docs/programming/hoon/twig/sem-make/col-wad.mdnew file+30
@@ -0,0 +1,30 @@
1+---
2+sort: 3
3+---
4+
5+# `:wad ;: "semcol" {$wad p/seed q/(list seed)}`
6+
7+Call binary function as n-ary function.
8+
9+## Expands to
10+
11+```
12+|-(?~(q !! ?~(t.q !! ?~(t.t.q :call(p i.q i.t.q) :call(p i.q $(q t.q))))))
13+```
14+
15+## Syntax
16+
17+Regular: *1-fixed*, then *running*.
18+
19+Irregular: `:(add a b c)` is `;:(add a b c)`.
20+
21+## Examples
22+
23+```
24+~zod:dojo> (add 3 (add 4 5))
25+12
26+~zod:dojo> ;:(add 3 4 5)
27+12
28+~zod:dojo> :(add 3 4 5)
29+12
30+```
docs/programming/hoon/twig/sem-make/fas-nub.mdnew file+19
@@ -0,0 +1,19 @@
1+---
2+sort: 4
3+---
4+
5+# `:nub ;/ "semfas" {$nub p/seed}`
6+
7+Tape as XML element.
8+
9+## Expands to
10+
11+```
12+[%$ [%$ p ~] ~]
13+```
14+
15+## Examples
16+```
17+~zod/try=> :/("foo"
18+[[%$ [%$ "foo] ~] ~]
19+```
docs/programming/hoon/twig/sem-make/sem-fry.mdnew file+48
@@ -0,0 +1,48 @@
1+---
2+sort: 1
3+---
4+
5+# `:fry ;; "semsem" {$fry p/moss q/seed}`
6+
7+Normalize with a mold, asserting fixpoint.
8+
9+## Expands to
10+
11+```
12+:pin(:name(a (p q)) :sure(=(a (p a)) a))
13+```
14+
15+## Syntax
16+
17+Regular: *2-fixed*.
18+
19+## Examples
20+
21+Fails because of auras:
22+
23+```
24+~zod:dojo> ^-(tape ~[97 98 99])
25+! nest-fail
26+! exit
27+```
28+
29+Succeeds because molds don't care about auras:
30+
31+```
32+~zod:dojo> ;;(tape ~[97 98 99])
33+"abc"
34+```
35+
36+Succeeds because the mold normalizes:
37+
38+```
39+~zod:dojo> (tape [50 51 52])
40+"23"
41+```
42+
43+Fails because not a fixpoint:
44+
45+```
46+~zod:dojo> ;;(tape [50 51 52])
47+! exit
48+```
docs/programming/hoon/twig/sem-make/sig-dip.mdnew file+62
@@ -0,0 +1,62 @@
1+---
2+sort: 2
3+---
4+
5+# `:dip`, `;~`, "semsig" `{$dip p/seed q/(list seed)}`
6+
7+Glue a pipeline together with a product-sample adapter.
8+
9+## Produces
10+
11+The gates in `q` connected together using the gate `p`, which
12+transforms a `q` product and a `q` gate into a `q` sample.
13+
14+## Discussion
15+
16+Apparently `:dip` is a "Kleisli arrow." Whatevs. It's also
17+a close cousin of the infamous "monad." Don't let that bother
18+you either. Hoon doesn't know anything about category theory,
19+so you don't need to either.
20+
21+`:dip` is often used in parsers, but is not only for parsers.
22+
23+## Syntax
24+
25+Regular: *1-fixed*, then *running*.
26+
27+## Examples
28+
29+A simple "parser." `trip` converts a `cord` (atomic string) to
30+a `tape` (linked string).
31+
32+```
33+~zod:dojo> =cmp |=({a/tape b/$-(char tape)] `tape`?~(a ~ (weld (b i.a) t.a)))
34+~zod:dojo> ;~(cmp trip)
35+<1.xef [a=@ <374.hzt 100.kzl 1.ypj %164>]>
36+~zod:dojo> (;~(cmp trip) 'a')
37+"a"
38+```
39+
40+With just one gate in the pipeline `q`, the glue `p` is unused:
41+
42+```
43+~zod:dojo> (;~(cmp trip |=(a/@ ~[a a])) 'a')
44+"aa"
45+~zod:dojo> (;~(cmp trip |=(a/@ ~[a a])) '')
46+""
47+```
48+
49+But for multiple gates, we need it to connect the pipeline:
50+
51+```
52+~zod:dojo> (;~(cmp trip ;~(cmp |=(a/@ ~[a a]) |=(a/@ <(dec a)>))) 'b')
53+"97b"
54+~zod:dojo> (;~(cmp trip |=(a/@ ~[a a]) |=(a/@ <(dec a)>)) 'b')
55+"97b"
56+~zod:dojo> (;~(cmp trip |=(a/@ ~[a a]) |=(a/@ <(dec a)>)) '')
57+""
58+~zod:dojo> (;~(cmp trip |=(a/@ ~[a a]) |=(a/@ <(dec a)>)) 'a')
59+"96a"
60+~zod:dojo> (;~(cmp trip |=(a/@ ~[a a]) |=(a/@ <(dec a)>)) 'acd')
61+"96acd"
62+```
docs/programming/hoon/twig/sig-hint.mdnew file+15
@@ -0,0 +1,15 @@
1+---
2+sort: 12
3+next: true
4+---
5+
6+# Hints (`~` runes)
7+
8+Twigs that use Nock `10` to pass non-semantic info to the
9+interpreter.
10+
11+## Twigs
12+
13+<list dataPreview="true" className="runes" linkToFragments="true"></list>
14+
15+<kids className="runes"></kids>
docs/programming/hoon/twig/sig-hint/bar-show.mdnew file+27
@@ -0,0 +1,27 @@
1+---
2+sort: 2
3+---
4+
5+# `:show ~| "sigbar" {$show p/seed q/seed}`
6+
7+Tracing printf.
8+
9+## Expands to
10+
11+`q`.
12+
13+## Convention
14+
15+Prettyprints `p` in stack trace if `q` crashes.
16+
17+## Syntax
18+
19+Regular: *2-fixed*.
20+
21+## Examples
22+
23+```
24+~zod:dojo> ~|('sample error message' !!)
25+'sample error message'
26+ford: build failed
27+```
docs/programming/hoon/twig/sig-hint/buc-poll.mdnew file+26
@@ -0,0 +1,26 @@
1+---
2+sort: 12
3+---
4+
5+# `:poll ~$ "sigbuc" {$poll p/term q/seed}`
6+
7+Profiling hit counter.
8+
9+## Expands to
10+
11+`q`.
12+
13+## Convention
14+
15+If profiling is on, adds 1 to the hit counter for `p`.
16+
17+## Syntax
18+
19+Regular: *2-fixed*.
20+
21+## Examples
22+
23+```
24+~zod:dojo> ~$(%foo 3)
25+3
26+```
docs/programming/hoon/twig/sig-hint/cab-lurk.mdnew file+27
@@ -0,0 +1,27 @@
1+---
2+sort: 3
3+---
4+
5+# `:lurk ~_ "sigcab" {$lurk p/seed q/seed}`
6+
7+User-formatted tracing printf.
8+
9+## Expands to
10+
11+`q`.
12+
13+## Convention
14+
15+Shows `p` in stacktrace if `q` crashes.
16+
17+## Discussion
18+
19+`p` must produce a `tank` (prettyprint source).
20+
21+## Examples
22+
23+```
24+~zod:dojo> ~_([%leaf "sample error message"] !!)
25+"sample error message"
26+ford: build failed
27+```
docs/programming/hoon/twig/sig-hint/cen-fast.mdnew file+93
@@ -0,0 +1,93 @@
1+---
2+sort: 10
3+---
4+
5+# `:fast ~% "sigcen" {$fast p/term q/wing r/(list {term seed}) s/seed}`
6+
7+General jet hint.
8+
9+## Expands to
10+
11+`s`.
12+
13+## Convention
14+
15+Register a core with name `p`, with parent at leg `q`, exporting
16+the named formulas `r`, constructed by `s`.
17+
18+## Syntax
19+
20+Regular: *4-fixed*. For `r`, use `~` if empty. Otherwise, *jogging*
21+between opening and closing `==`.
22+
23+## Discussion
24+
25+`:fast` is for registering cores. A registered core declares its
26+formal identity to the interpreter, which may or may not be able
27+to recognize and/or accelerate it.
28+
29+Registered cores are are organized in a containment hierarchy.
30+The parent core is at any leg within the child core. When we
31+register a core, we state the leg to its parent, in the form of
32+wing `q`. We assume the parent is already registered -- as it
33+must be, if (a) we registered it on creation, (b) the child was
34+created by an arm defined on the parent.
35+
36+(Cores are actually managed by their formula/battery. Any
37+function call will create a new core with a new sample, but
38+batteries are constant. But it is not sufficient to match the
39+battery -- matching the semantics constrains the payload as well,
40+since the semantics of a battery may depend on any parent core
41+and/or payload constant.)
42+
43+The purpose of registration is always performance-related. It
44+may involve (a) a special-purpose optimizer or "jet", written
45+for a specific core and checked with a Merkle hash; (b) a
46+general-purpose hotspot optimizer or "JIT"; or (c) merely a
47+hotspot declaration for profiling.
48+
49+As always with hints, the programmer has no idea which of (a),
50+(b), and (c) will be applied. She should use `:fast`
51+indiscriminately on all hotspots, bottlenecks, etc, real or
52+suspected.
53+
54+The list `r` is a way for the Hoon programmer to help jet
55+implementors with named Nock formulas that act on the core.
56+In complex systems, jet implementations are often partial and
57+want to call back into userspace.
58+
59+The child core contains the parent, of course. When we register
60+a core, we state the leg to its parent, in the form of wing `q`.
61+We assume that the parent -- any core within the payload -- is
62+already registered.
63+
64+must already be registered.
65+The interpreter can thus
66+
67+`p` is the name of this core within its parent; `q` is a the leg
68+
69+Registers a jet in core `s` so that it can be called when that code is run.
70+
71+Regularm form: *4-fixed*
72+
73+## Examples
74+
75+Here's the AES
76+
77+ ++ aesc :: AES-256
78+ ~% %aesc + ~
79+ |%
80+ ++ en :: ECB enc
81+ ~/ %en
82+ |= {a/@I b/@H} ^- @uxH
83+ =+ ahem
84+ (be & (ex a) b)
85+ ++ de :: ECB dec
86+ ~/ %de
87+ |= {a/@I b/@H} ^- @uxH
88+ =+ ahem
89+ (be | (ix (ex a)) b)
90+ --
91+
92+Here we label the entire `++aesc` core for optimization. You can see the
93+jet in `jets/e/aesc.c`.
docs/programming/hoon/twig/sig-hint/fas-funk.mdnew file+28
@@ -0,0 +1,28 @@
1+---
2+sort: 1
3+
4+# `:funk ~/ "sigfas" {$funk p/term q/twig}`
5+
6+Jet hint for a gate whose context is a registered core.
7+
8+## Expands to
9+
10+```
11+:fast(p +7 ~ q)
12+```
13+
14+## Syntax
15+
16+Regular: *2-fixed*.
17+
18+## Examples
19+
20+From the kernel:
21+```
22+++ add
23+ ~/ %add
24+ |= {a/@ b/@}
25+ ^- @
26+ ?: =(0 a) b
27+ $(a (dec a), b +(b))
28+```
docs/programming/hoon/twig/sig-hint/gal-thin.mdnew file+30
@@ -0,0 +1,30 @@
1+---
2+sort: 6
3+---
4+
5+# :thin ~< "siggal" {$thin p/$@(term {p/term q/twig}) q/twig}
6+
7+Raw hint, applied to the result of computation.
8+
9+## Expands to
10+
11+`q`.
12+
13+## Syntax
14+
15+Regular: *2-fixed*. For the dynamic form, write `%term.twig`.
16+
17+## Discussion
18+
19+`:thin` is only used for jet hints (`:funk` and `:fast`) at the
20+moment; we are not telling the interpreter something about the
21+computation we're about to perform, but rather about the result.
22+
23+## Examples
24+
25+```
26+~zod:dojo> (make '~<(%a 42)')
27+[%7 p=[%1 p=42] q=[%10 p=97 q=[%0 p=1]]]
28+~zod:dojo> (make '~<(%a.+(.) 42)')
29+[%7 p=[%1 p=42] q=[%10 p=[p=97 q=[%4 p=[%0 p=1]]] q=[%0 p=1]]]
30+```
docs/programming/hoon/twig/sig-hint/gar-hint.mdnew file+36
@@ -0,0 +1,36 @@
1+---
2+sort: 5
3+---
4+
5+# `:hint ~> "siggar", {$hint p/$@(term {p/term q/twig}) q/twig}`
6+
7+Raw hint, applied before computation.
8+
9+## Expands to
10+
11+`q`.
12+
13+## Syntax
14+
15+Regular: *2-fixed*. For the dynamic form, write `%term.twig`.
16+
17+## Discussion
18+
19+Hoon has no way of telling what hints are used and what aren't.
20+Hints are all conventions at the interpreter level.
21+
22+## Examples
23+
24+```
25+~zod:dojo> ~>(%a 42)
26+42
27+```
28+
29+Running the compiler:
30+
31+```
32+~zod:dojo> (make '~>(%a 42)')
33+[%10 p=97 q=[%1 p=42]]
34+~zod:dojo> (make '~>(%a.+(2) 42)')
35+[%10 p=[p=97 q=[%4 p=[%1 p=2]]] q=[%1 p=42]]
36+```
docs/programming/hoon/twig/sig-hint/lus-memo.mdnew file+43
@@ -0,0 +1,43 @@
1+---
2+sort: 7
3+---
4+
5+# :memo ~+ "siglus" {$memo p/seed}`
6+
7+Cache a computation.
8+
9+## Expands to
10+
11+`p`.
12+
13+## Convention
14+
15+Caches the formula and subject of `p` in a local cache (generally
16+transient in the current event).
17+
18+## Syntax
19+
20+Regular: *1-fixed*.
21+
22+## Examples
23+
24+This may pause for a second:
25+
26+```
27+~zod:dojo> %.(25 |=(a/@ ?:((lth a 2) 1 (add $(a (sub a 2)) $(a (dec a))))))
28+121.393
29+```
30+
31+This may make you want to press ^C:
32+
33+```
34+~zod:dojo> %.(30 |=(a/@ ?:((lth a 2) 1 (add $(a (sub a 2)) $(a (dec a))))))
35+1.346.269
36+```
37+
38+This should work fine:
39+
40+```
41+~zod:dojo> %.(100 |=(a/@ ~+(?:((lth a 2) 1 (add $(a (sub a 2)) $(a (dec a)))))))
42+573.147.844.013.817.084.101
43+```
docs/programming/hoon/twig/sig-hint/pam-dump.mdnew file+27
@@ -0,0 +1,27 @@
1+---
2+sort: 1
3+---
4+
5+# `:dump ~& "sigpam" {$dump p/seed q/seed}`
6+
7+Debugging printf.
8+
9+## Expands to
10+
11+`q`.
12+
13+## Convention
14+
15+Prettyprints `p` on the console before computing `q`.
16+
17+## Syntax
18+
19+Regular: *2-fixed*.
20+
21+## Examples
22+
23+```
24+~zod:dojo> ~&('halp' ~)
25+'halp'
26+~
27+```
docs/programming/hoon/twig/sig-hint/tis-ddup.mdnew file+34
@@ -0,0 +1,34 @@
1+---
2+sort: 8
3+---
4+
5+# `:ddup ~= "sigtis" {$ddup p/seed q/seed}`
6+
7+Detect a duplicate.
8+
9+## Expands to
10+
11+`q`.
12+
13+## Convention
14+
15+If `p` equals `q`, produce `p` instead of `q`.
16+
17+## Discussion
18+
19+Duplicates are especially bad news in Hoon, because comparing them
20+takes O(n) time. Use `~=` to kill them as they breed.
21+
22+## Examples
23+
24+This code traverses a tree and replaces all instances of `42` with
25+`420`:
26+
27+```
28+~zod:dojo> =foo |= a/(tree)
29+ ?~(a ~ ~=(a [?:(=(n.a 42) 420 n.a) $(a l.a) $(a r.a)]))
30+~zod:dojo> (foo 42 ~ ~)
31+[420 ~ ~]
32+```
33+
34+Without `~=`, it would build a copy of a completely unchanged tree. Sad!
docs/programming/hoon/twig/sig-hint/wut-warn.mdnew file+29
@@ -0,0 +1,29 @@
1+---
2+sort: 4
3+---
4+
5+# `:warn ~? "sigwut" `{$warn p/twig q/twig r/twig}`
6+
7+Conditional debugging printf.
8+
9+## Expands to
10+
11+`r`.
12+
13+## Convention
14+
15+If `p` is true, prettyprints `q` on the console before computing `r`.
16+
17+## Syntax
18+
19+Regular: *4-fixed*.
20+
21+## Examples
22+
23+```
24+~zod:dojo> ~?((gth 1 2) 'oops' ~)
25+~
26+~zod:dojo> ~?((gth 1 0) 'oops' ~)
27+'oops'
28+~
29+```
docs/programming/hoon/twig/sig-hint/zap-peep.mdnew file+29
@@ -0,0 +1,29 @@
1+---
2+sort: 9
3+---
4+
5+# `:peep ~! "sigzap" {$peep p/seed q/seed}`
6+
7+Print type on compilation fail.
8+
9+## Expands to
10+
11+`q`.
12+
13+## Convention
14+
15+If compilation of `q` fails, prints the span of `p` in the trace.
16+
17+## Syntax
18+
19+Regular: *2-fixed*.
20+
21+## Examples
22+
23+```
24+~zod:dojo> a
25+! -find.a
26+~zod:dojo> ~!('foo' a)
27+! @t
28+! find.a
29+```
docs/programming/hoon/twig/tis-flow.mdnew file+33
@@ -0,0 +1,33 @@
1+---
2+sort: 4
3+next: true
4+---
5+
6+# Subject flow (`=` runes)
7+
8+Flow twigs change the subject. (Or more precisely, a flow twig
9+compiles at least one of its subtwigs with a different subject.)
10+All non-flow twigs (except cores) pass the subject down unchanged.
11+
12+## Overview
13+
14+The simplest way to change the subject is to compose two twigs,
15+`p` and `q`. Let `x` be `(mint subject p)`, with product span
16+`p.x` and nock formula `q.x`. Let `y` be `(mint p.x q)`. Then
17+their composition is `[p.y [7 q.x q.y]]`.
18+
19+This composition is the `$per` twig. A close relative is `$pin`,
20+which is `$per` over `[p .]`. The new subject is a cell of `p`
21+and the old subject. `$pin` is the simplest Hoon equivalent of
22+"declaring a variable" (introducing new data into the subject).
23+
24+Another way to change the subject is to mutate it. With the
25+`$set` twig, given a wing that resolves to a leg, we can write
26+instead of reading, *installing* a new value at that leg. Of
27+course, we are creating a copy, not modifying the original.
28+
29+## Twigs
30+
31+<list dataPreview="true" className="runes" linkToFragments="true"></list>
32+
33+<kids className="runes"></kids>
docs/programming/hoon/twig/tis-flow/bar-new.mdnew file+38
@@ -0,0 +1,38 @@
1+---
2+sort: 5
3+---
4+
5+# `:new, =|, "tisbar", {$new p/moss q/seed}`
6+
7+Combine a defaulted mold with the subject.
8+
9+## Expands to
10+
11+```
12+:pin(:bunt(p) q)
13+```
14+
15+## Syntax
16+
17+Regular: *2-fixed*.
18+
19+## Discussion
20+
21+`:new` "declares a variable" which is "uninitialized," presumably
22+because you'll set it in a loop or similar.
23+
24+A common mistake is to forget that since `p` is moldy,
25+`:new(foo=@ bar)` is wrong; you mean `:new(foo/@ bar)`, since
26+`foo=@` is `:name(foo @)` (putting a face on a seed) and `foo/@`
27+is `:coat(foo @)` (wrapping a face around a mold).
28+
29+## Examples
30+
31+```
32+~zod:dojo> =foo |= a/@
33+ =| b/@
34+ =- :(add a b c)
35+ c=2
36+~zod:dojo> (foo 5)
37+7
38+```
docs/programming/hoon/twig/tis-flow/col-fix.mdnew file+28
@@ -0,0 +1,28 @@
1+---
2+sort: 9
3+---
4+
5+# `:fix, =:, "tiscol", {$fix p/(list (pair wing twig)) q/twig}`
6+
7+Mutate multiple legs in the subject.
8+
9+## Expands to
10+
11+```
12+:per(:keep(. p q) r)
13+```
14+
15+## Syntax
16+
17+Regular: *jogging*, then *1-fixed*.
18+
19+## Examples
20+
21+```
22+~zod:dojo> =+ a=[b=1 c=2]
23+ =: c.a 4
24+ b.a 3
25+ ==
26+ a
27+[b=3 c=4]
28+```
docs/programming/hoon/twig/tis-flow/dot-set.mdnew file+35
@@ -0,0 +1,35 @@
1+---
2+sort: 8
3+---
4+
5+# `:set, =., "tisdot", {$set p/wing q/seed r/seed}`
6+
7+Mutate a leg in the subject.
8+
9+## Expands to
10+
11+```
12+:per(:keep(. p q) r)
13+```
14+
15+## Syntax
16+
17+Regular: *3-fixed*.
18+
19+## Discussion
20+
21+As usual, we are not actually mutating the subject, just creating
22+a new subject with a changed value. Note that the mutation uses
23+`:keep` (`%_`), so the type doesn't change.
24+
25+## Examples
26+
27+```
28+~zod:dojo> =+ a=[b=1 c=2]
29+ =. b.a 3
30+ a
31+[b=3 c=2]
32+~zod:dojo> =+ a=[b=1 c=2]
33+ =.(b.a 3 a)
34+[b=3 c=2]
35+```
docs/programming/hoon/twig/tis-flow/fas-var.mdnew file+35
@@ -0,0 +1,35 @@
1+---
2+sort: 6
3+---
4+
5+# `:var, =/, "tisfas", {$var p/taco q/twig r/twig}`
6+
7+Combine a named and/or typed noun with the subject.
8+
9+## Expands to
10+
11+```
12+?@(p :pin(:name(p q) r) :pin(:cast(:(coat p) q) r)
13+```
14+
15+## Syntax
16+
17+Regular: *3-fixed*.
18+
19+## Discussion
20+
21+`p` can be either a symbol or a symbol/mold. If it's just a
22+symbol, `:var` "declares a type-inferred variable." It has a
23+mold, `:var` "declares a type-checked variable."
24+
25+## Examples
26+
27+```
28+~zod:dojo> =foo |= a/@
29+ =/ b 1
30+ =/ c/@ 2
31+ :(add a b c)
32+~zod:dojo> (foo 5)
33+8
34+```
35+
docs/programming/hoon/twig/tis-flow/gal-rap.mdnew file+28
@@ -0,0 +1,28 @@
1+---
2+sort: 2
3+---
4+
5+# `:rap, =<, "tisgal", {$rap p/twig q/twig}`
6+
7+Compose two twigs, inverted.
8+
9+## Expands to
10+
11+```
12+:per(q p)
13+```
14+
15+## Syntax
16+
17+Regular: *2-fixed*.
18+
19+Irregular: `foo:bar` is `:rap(foo bar)`.
20+
21+## Examples
22+
23+```
24+~zod:dojo> b:[a=1 b=2 c=3]
25+2
26+~zod:dojo> [. .]:(add 2 4)
27+[6 6]
28+```
docs/programming/hoon/twig/tis-flow/gar-per.mdnew file+24
@@ -0,0 +1,24 @@
1+---
2+sort: 1
3+---
4+
5+# `:per, =>, "tisgar", {$per p/twig q/twig}`
6+
7+Compose two twigs.
8+
9+## Produces
10+
11+`q`, compiled against the product of `p`.
12+
13+## Syntax
14+
15+Regular: *2-fixed*.
16+
17+## Examples
18+
19+```
20+~zod:dojo> =>([a=1 b=2 c=3] b)
21+2
22+~zod:dojo> =>((add 2 4) [. .])
23+[6 6]
24+```
docs/programming/hoon/twig/tis-flow/hep-nip.mdnew file+33
@@ -0,0 +1,33 @@
1+---
2+sort: 4
3+---
4+
5+# `:nip, =-, "tishep", {$pin p/seed q/seed}`
6+
7+Combine a new noun with the subject, inverted.
8+
9+## Expands to
10+
11+```
12+:per(:cons(q .) p)
13+```
14+
15+## Syntax
16+
17+Regular: *2-fixed*.
18+
19+## Discussion
20+
21+`:nip` looks better than `:pin` when the twig you're pinning
22+is much smaller than the twig that uses it.
23+
24+## Examples
25+
26+```
27+~zod:dojo> =foo |= a/@
28+ =+ :name(b 1)
29+ =- :(add a b c)
30+ c=2
31+~zod:dojo> (foo 5)
32+8
33+```
docs/programming/hoon/twig/tis-flow/ket-sip.mdnew file+40
@@ -0,0 +1,40 @@
1+---
2+sort: 10
3+---
4+
5+# `:sip, =^, "tisket", {$sip p/taco q/wing r/twig s/twig}`
6+
7+Pin the head of a pair; mutate a leg with the tail.
8+
9+## Expands to
10+
11+```
12+:var(p -.r :set(q +.r s))
13+```
14+
15+## Syntax
16+
17+Regular: *4-fixed*.
18+
19+## Discussion
20+
21+We use `:sip` when we have a state machine with a function that
22+produces a cell, whose head is a result and whose tail is a new
23+state. We want to use the head as a new variable, and stuff the
24+tail back into wherever we stored the old state.
25+
26+This may also remind you of Haskell's State monad.
27+
28+## Examples
29+
30+The `og` core is a stateful pseudo-random number generator.
31+We have to change the core state every time we generate a
32+random number, so we need to `:sip`:
33+
34+```
35+~zod:dojo> =+ rng=~(. og 420)
36+ =^ r1 rng (rads:rng 100)
37+ =^ r2 rng (rads:rng 100)
38+ [r1 r2]
39+[99 46]
40+```
docs/programming/hoon/twig/tis-flow/lus-pin.mdnew file+32
@@ -0,0 +1,32 @@
1+---
2+sort: 3
3+---
4+
5+# `:pin, =+, "tislus", {$pin p/seed q/seed}`
6+
7+Combine a new noun with the subject.
8+
9+## Expands to
10+
11+```
12+:per(:cons(p .) q)
13+```
14+
15+## Syntax
16+
17+Regular: *2-fixed*.
18+
19+## Discussion
20+
21+`:pin` is the simplest way of "declaring a variable."
22+
23+## Examples
24+
25+```
26+~zod:dojo> =foo |= a/@
27+ =+ :name(b 1)
28+ =+ c=2
29+ :(add a b c)
30+~zod:dojo> (foo 5)
31+8
32+```
docs/programming/hoon/twig/tis-flow/sem-rev.mdnew file+28
@@ -0,0 +1,28 @@
1+---
2+sort: 7
3+---
4+
5+# `:rev, =;, "tissem", {$rev p/taco q/twig r/twig}`
6+
7+Combine a named and/or typed noun with the subject, inverted.
8+
9+## Expands to
10+
11+```
12+?@(p :pin(:name(p r) q) :pin(:cast(:(coat p) r) q)
13+```
14+
15+## Syntax
16+
17+Regular: *3-fixed*.
18+
19+## Examples
20+
21+```
22+~zod:dojo> =foo :gate a/@
23+ :var b 1
24+ :rev c/@ :(add a b c)
25+ 2
26+~zod:dojo> (foo 5)
27+8
28+```
docs/programming/hoon/twig/tis-flow/tar-aka.mdnew file+37
@@ -0,0 +1,37 @@
1+---
2+sort: 11
3+---
4+
5+# `:aka, =*, "tistar", {$aka p/term q/seed r/seed}`
6+
7+Define an alias.
8+
9+## Produces
10+
11+`r`, compiled with a subject in which `p` is aliased to `q`.
12+
13+## Syntax
14+
15+Regular: *3-fixed*.
16+
17+## Discussion
18+
19+The difference between aliasing and pinning is that the subject
20+noun stays the same; the alias is just recorded in its span.
21+`q` is calculated every time you use the `p` alias, of course.
22+
23+## Examples
24+
25+```
26+~zod:dojo>
27+ =+ a=1
28+ =* b a
29+ [a b]
30+[1 1]
31+~zod:dojo>
32+ =+ a=1
33+ =* b a
34+ =. a 2
35+ [a b]
36+[2 2]
37+```
docs/programming/hoon/twig/wut-test.mdnew file+33
@@ -0,0 +1,33 @@
1+---
2+sort: 8
3+next: true
4+---
5+
6+# Tests (`?` runes)
7+
8+Hoon has the usual branches and logical tests. For pattern
9+matching, it also has a `$fits` twig that tests whether a value
10+matches the icon of a mold. And it has branch inference,
11+learning from `$fits` tests in the condition of `:if` twigs.
12+
13+## Overview
14+
15+All `?` runes expand to `$if` (`?:`) and/or `$fits` (`?=`).
16+
17+If the condition of an `$if` is a `$fits`, *and* the `$fits` is
18+testing a leg of the subject, the compile specializes the subject
19+span for the branches of the `$if`. Branch inference also works
20+for twigs which expand to `$if`.
21+
22+The test does not have to be a single `$fits`; the compiler can
23+analyze arbitrary boolean logic (`$and`, `$or`, `$not`) with full
24+short-circuiting. Equality tests (`=`) are *not* analyzed.
25+
26+If the compiler detects that the branch is degenerate (only one
27+side is taken), it fails with an error.
28+
29+## Twigs
30+
31+<list dataPreview="true" className="runes" linkToFragments="true"></list>
32+
33+<kids className="runes"></kids>
docs/programming/hoon/twig/wut-test/bar-or.mdnew file+30
@@ -0,0 +1,30 @@
1+---
2+sort: 9
3+---
4+
5+# `:or`, `?|`, "wutbar" `{$or p/(list seed)}`
6+
7+Logical or.
8+
9+## Expands to
10+
11+```
12+:ifno p
13+ |
14+:if i.p
15+ &
16+:moar(p t.p)
17+```
18+
19+## Syntax
20+
21+Regular: *running*.
22+
23+Irregular: `|(foo bar baz)` is `?|(foo bar baz)`.
24+
25+## Examples
26+
27+```
28+~zod:dojo> |(=(6 42) =(42 42))
29+%.y
30+```
docs/programming/hoon/twig/wut-test/col-if.mdnew file+42
@@ -0,0 +1,42 @@
1+---
2+sort: 1
3+---
4+
5+# `:if, ?:, "wutcol", `{$if p/seed q/seed r/seed}`
6+
7+Branch on a boolean test.
8+
9+## Produces
10+
11+If `p` produces yes, then `q`. If `p` produces no, `r`.
12+If `p` is not a boolean, compiler yells at you.
13+
14+The subjects of `q` and `r` are constrained to match any
15+pattern-matching algebra in `p`. The analysis, which is
16+conservative, understands any combination of `:fits`
17+(`?=`), `:and` (`?&`), `:or` (`?|`), and `:not` (`?!`),
18+and reduces the subject appropriately when compiling.
19+
20+If test analysis reveals that either branch is not taken,
21+or if `p` is not a boolean, compilation fails. However,
22+an untaken branch can be indicated with the `:lost` twig.
23+
24+## Syntax
25+
26+Regular: *3-fixed*.
27+
28+## Discussion
29+
30+Short-circuiting in boolean tests works as you'd expect
31+and includes the expected inference. For instance,
32+if you write `:(and a b)`, `b` is only executed if `a` is
33+positive, and compiled with that assumption.
34+
35+Note also that all other branching twigs reduce to `:if`.
36+
37+## Examples
38+
39+```
40+~zod:dojo> ?:((gth 1 2) 3 4)
41+4
42+```
docs/programming/hoon/twig/wut-test/dot-lest.mdnew file+39
@@ -0,0 +1,39 @@
1+---
2+sort: 2
3+---
4+
5+# `:lest`, `?.`, "wutdot" `{$lest p/twig q/twig r/twig}`
6+
7+Branch on a boolean test, inverted.
8+
9+## Expands to
10+
11+```
12+:if p
13+ r
14+q
15+```
16+
17+## Syntax
18+
19+Regular: *3-fixed*.
20+
21+## Discussion
22+
23+As usual with inverted forms, use `:lest` when the positive
24+twig of an `:if` is much heavier than the negative twig.
25+
26+## Examples
27+
28+```
29+~zod:dojo> ?.((gth 1 2) 3 4)
30+3
31+~zod:dojo> ?.(?=(%a 'a') %not-a %yup)
32+%yup
33+~zod:dojo> ?. %.y
34+ 'this false case is less heavy than the true case'
35+ ?: =(2 3)
36+ 'two not equal to 3'
37+ 'but see how \'r is much heavier than \'q?'
38+'but see how \'r is much heavier than \'q?'
39+```
docs/programming/hoon/twig/wut-test/gal-deny.mdnew file+27
@@ -0,0 +1,27 @@
1+---
2+sort: 10
3+---
4+
5+# `:deny, ?<, "wutgal", {$deny p/seed q/seed}`
6+
7+Negative assertion.
8+
9+## Expands to
10+
11+```
12+:if p
13+ :zpzp
14+q
15+```
16+
17+## Syntax
18+
19+Regular: *2-fixed*.
20+
21+## Examples
22+
23+```
24+~zod:dojo> ?<(=(3 4) %foo)
25+%foo
26+```
27+
docs/programming/hoon/twig/wut-test/gar-sure.mdnew file+26
@@ -0,0 +1,26 @@
1+---
2+sort: 11
3+---
4+
5+# `:sure, ?<, "wutgar", {$sure p/seed q/seed}`
6+
7+Positive assertion.
8+
9+## Expands to
10+
11+```
12+:lest p
13+ :zpzp
14+q
15+```
16+
17+## Syntax
18+
19+Regular: *2-fixed*.
20+
21+## Examples
22+
23+```
24+~zod:dojo> ?>(=(3 3) %foo)
25+%foo
26+```
docs/programming/hoon/twig/wut-test/hep-case.mdnew file+49
@@ -0,0 +1,49 @@
1+---
2+sort: 12
3+---
4+
5+# `:case, ?-, "wuthep", {$case p/wing q/(list (pair moss seed))}`
6+
7+Switch against a union, with no default.
8+
9+## Expands to
10+
11+```
12+:ifno q
13+ :lost
14+:if :fits(p.i.q p)
15+ q.i.q
16+:moar(q t.q)
17+```
18+
19+## Syntax
20+
21+Regular: *1-fixed*, then *jogging*.
22+
23+## Discussion
24+
25+The compiler makes sure that your code neither misses a case of
26+the union, nor includes a double case that isn't there. This is
27+not special handling for `:case`, just a consequence of the
28+semantics of `:if`, which `:case` reduces to.
29+
30+A missing case will throw the `mint-lost` error. An extra case
31+will throw `mint-vain`. (Ecclesiastes did nothing wrong.)
32+
33+## Examples
34+
35+```
36+~zod:dojo> =cor |= vat/?($a $b)
37+ ?- vat
38+ $a 20
39+ $b 42
40+ ==
41+~zod:dojo> (cor %a)
42+20
43+~zod:dojo> (cor %b)
44+42
45+~zod:dojo> (cor %c)
46+! nest-fail
47+```
48+
49+
docs/programming/hoon/twig/wut-test/ket-ifcl.mdnew file+35
@@ -0,0 +1,35 @@
1+---
2+sort: 5
3+---
4+
5+# `:ifcl, ?^, "wutket", {$ifcl p/wing q/twig r/twig}`
6+
7+Branch on whether a wing of the subject is null.
8+
9+## Expands to
10+
11+```
12+:if :fits(^ p)
13+ q
14+r
15+```
16+
17+## Syntax
18+
19+Regular: *3-fixed*.
20+
21+## Discussion
22+
23+Regular form: *3-fixed*
24+
25+## Examples
26+
27+```
28+~zod:dojo> ?^(0 1 2)
29+! mint-vain
30+! exit
31+~zod:dojo> ?^(`*`0 1 2)
32+2
33+~zod:dojo> ?^(`*`[1 2] 3 4)
34+3
35+```
docs/programming/hoon/twig/wut-test/lus-deft.mdnew file+41
@@ -0,0 +1,41 @@
1+---
2+sort: 13
3+---
4+
5+# `:deft, ?-, "wutlus", {$case p/wing q/seed r/(list (pair moss seed))}`
6+
7+Switch against a union, with a default.
8+
9+## Expands to
10+
11+```
12+:ifno r
13+ q
14+:if :fits(p.i.r p)
15+ q.i.r
16+:moar(r t.r)
17+```
18+
19+## Syntax
20+
21+Regular: *2-fixed*, then *jogging*.
22+
23+## Discussion
24+
25+An extra case will throw `mint-vain`. A lost case defaults.
26+
27+## Examples
28+
29+```
30+~zod:dojo> =cor |= vat/?($a $b)
31+ ?+ vat 240
32+ $a 20
33+ $b 42
34+ ==
35+~zod:dojo> (cor %a)
36+20
37+~zod:dojo> (cor %b)
38+42
39+~zod:dojo> (cor %c)
40+240
41+```
docs/programming/hoon/twig/wut-test/pam-and.mdnew file+30
@@ -0,0 +1,30 @@
1+---
2+sort: 8
3+---
4+
5+# `:and, ?&, "wutpam", {$and p/(list seed)}`
6+
7+Logical and.
8+
9+## Expands to
10+
11+```
12+:ifno p
13+ &
14+:lest i.p
15+ |
16+:moar(p t.p)
17+```
18+
19+## Syntax
20+
21+Regular: *running*.
22+
23+Irregular: `&(foo bar baz)` is `?&(foo bar baz)`.
24+
25+## Examples
26+
27+```
28+~zod:dojo> &(=(6 6) =(42 42))
29+%.y
30+```
docs/programming/hoon/twig/wut-test/pat-ifat.mdnew file+31
@@ -0,0 +1,31 @@
1+---
2+sort: 4
3+---
4+
5+# `:ifat, ?@, "wutpat", {$ifat p/wing q/seed r/seed}`
6+
7+Branch on whether a wing of the subject is an atom.
8+
9+## Expands to
10+
11+```
12+:if :fits($~ p)
13+ q
14+r
15+```
16+
17+## Syntax
18+
19+Regular: *3-fixed*.
20+
21+## Examples
22+
23+```
24+~zod:dojo> ?@(0 1 2)
25+! mint-vain
26+! exit
27+~zod:dojo> ?@(`*`0 1 2)
28+1
29+~zod:dojo> ?@(`*`[1 2] 3 4)
30+4
31+```
docs/programming/hoon/twig/wut-test/sig-ifno.mdnew file+32
@@ -0,0 +1,32 @@
1+---
2+sort: 3
3+---
4+
5+# `ifno`, `?~`, "wutsig" `{$ifno p/wing q/seed r/seed}`
6+
7+Branch on whether a wing of the subject is null.
8+
9+## Expands to
10+
11+```
12+:if :fits($~ p)
13+ q
14+r
15+```
16+
17+## Syntax
18+
19+Regular: *3-fixed*.
20+
21+## Discussion
22+
23+It's bad style to use `:ifno` to test for any zero atom. Use it
24+only for a true null, `~`.
25+
26+## Examples
27+
28+```
29+~zod:dojo> =foo ""
30+~zod:dojo> ?~(foo 1 2)
31+11
32+```
docs/programming/hoon/twig/wut-test/tis-fits.mdnew file+40
@@ -0,0 +1,40 @@
1+---
2+sort: 6
3+---
4+
5+# `:fits, ?=, "wuttis", {$fits p/moss q/wing}
6+
7+Test whether the noun at wing `q` fits pattern `p`.
8+
9+## Produces
10+
11+`&` (yes) if the noun at `q` is in the icon of `p`;
12+`|` (no) otherwise.
13+
14+## Syntax
15+
16+Regular: *2-fixed*.
17+
18+## Discussion
19+
20+`:fits` is not as powerful as it might seem. For instance, it
21+can't generate a loop -- you cannot (and should not) use it to
22+test whether a `*` is a `(list @)`. Nor can it validate atomic
23+auras.
24+
25+Patterns should be as weak as possible. Unpack one layer of
26+union at a time. Don't confirm things the type system knows.
27+
28+For example, when matching a book containing a page `{$foo p/@
29+q/{@ @}}`, the proper pattern is `{$foo *}`. You have one
30+question, which is whether the head of the noun is `%foo`.
31+
32+A common error is `find.$`, meainng `p` is not a mold.
33+
34+## Examples
35+
36+```
37+~zod:dojo> =bar [%foo %bar %baz]
38+~zod:dojo> ?=({$foo *} bar)
39+%.y
40+```
docs/programming/hoon/twig/wut-test/zap-not.mdnew file+32
@@ -0,0 +1,32 @@
1+---
2+sort: 7
3+---
4+
5+# `:not, ?!, "wutzap", {$not p/seed}`
6+
7+Logical not.
8+
9+## Expands to
10+
11+```
12+:same(%.n p)
13+```
14+
15+Produces the logical "not" of `p`.
16+
17+## Syntax
18+
19+Regular: *1-fixed*.
20+
21+Irregular: `!(foo)` is `?!(foo)`.
22+
23+## Examples
24+
25+```
26+~zod:dojo> !&
27+%.n
28+~zod:dojo> !|
29+%.y
30+~zod:dojo> !(gth 5 6)
31+%.y
32+```
docs/programming/hoon/twig/zap-wild.mdnew file+12
@@ -0,0 +1,12 @@
1+---
2+sort: 13
3+next: true
4+---
5+
6+# Special tools (`!` runes).
7+
8+## Twigs
9+
10+<list dataPreview="true" className="runes" linkToFragments="true"></list>
11+
12+<kids className="runes"></kids>
docs/programming/hoon/twig/zap-wild/gar-wrap.mdnew file+27
@@ -0,0 +1,27 @@
1+---
2+sort: 2
3+---
4+
5+# `:wrap !> "zapgar" {$wrap p/twig}`
6+
7+Wrap a noun in its span.
8+
9+## Produces
10+
11+A cell whose tail is `p`, and whose head is the static span of p.
12+
13+## Syntax
14+
15+Regular: *1-fixed*.
16+
17+## Discussion
18+
19+In Hoon, dynamic type is static type compiled at runtime. This
20+span-noun cell is generally called a `vase`.
21+
22+## Examples
23+
24+```
25+~zod:dojo> !>(1)
26+[#t/@ud q=1]
27+```
docs/programming/hoon/twig/zap-wild/tis-code.mdnew file+26
@@ -0,0 +1,26 @@
1+---
2+sort: 3
3+---
4+
5+# `:code != "zaptis" {$code p/twig}`
6+
7+Make the Nock formula for a twig.
8+
9+## Produces
10+
11+The Nock generated by `p`.
12+
13+## Syntax
14+
15+Regular: *1-fixed*.
16+
17+## Examples
18+
19+```
20+~zod:dojo> !=(20)
21+[1 20]
22+~zod:dojo> !=(~zod)
23+[1 0]
24+~zod:dojo> !=((add 2 2))
25+[8 [9 3.110.356 0 31] 9 2 [0 4] [7 [0 3] 1 2 2] 0 11]
26+```
docs/programming/hoon/twig/zap-wild/wut-need.mdnew file+27
@@ -0,0 +1,27 @@
1+---
2+sort: 4
3+---
4+
5+# `:need !? "zapwut" {$need p/@ q/twig}`
6+
7+Restrict Hoon version.
8+
9+## Produces
10+
11+`q`, if `p` is greater than or equal to the Hoon kelvin version.
12+(Versions count down; the current version is 150.)
13+
14+## Syntax
15+
16+Regular: *2-fixed*.
17+
18+## Examples
19+
20+```
21+~zod:dojo> !?(264 (add 2 2))
22+4
23+~zod:dojo> !?(164 (add 2 2))
24+4
25+~zod:dojo> !?(64 (add 2 2))
26+! exit
27+```
docs/programming/hoon/twig/zap-wild/zap-fail.mdnew file+26
@@ -0,0 +1,26 @@
1+---
2+sort: 1
3+---
4+
5+# `:fail, !! "zapzap" {$fail $~}`
6+
7+Crash.
8+
9+## Produces
10+
11+Nothing. Always crashes, with span `%void`.
12+
13+## Syntax
14+
15+`!!`
16+
17+## Discussion
18+
19+`%void` nests in every other span, so you can stub out anything with `!!`.
20+
21+## Examples
22+
23+```
24+~zod:dojo> !!
25+! exit
26+```