@@ -0,0 +1,453 @@
1+---
2+sort: 9
3+---
4+
5+# Examples
6+
7+Now we know enough to write two quick examples: the Sieve of
8+Eratosthenes (a naive prime sieve) and a tictactoe engine.
9+
10+(Note that these are not examples of perfect Hoon code; they are
11+meant for teaching. They err, more than usual for Hoon, on the
12+side of simple manual construction over high-octane FP.)
13+
14+## `sieve`: code in basic style
15+
16+A function that produces the list of primes less than or equal to
17+than its argument, an atom:
18+```
19+:gate thru/atom :: 1
20+:cast (list atom) :: 2
21+:var field/(set atom) (silt (gulf 2 thru)) :: 3
22+:rap abet:main :: 4
23+:core :: 5
24+++ abet :: 6
25+ (sort (~(tap in field) ~) lth) :: 7
26+:: :: 8
27+++ main :: 9
28+ :var factor/atom 2 :: 10
29+ :loop :like ..main :: 11
30+ :if (gth (mul factor factor) thru) :: 12
31+ ..main :: 13
32+ :moar(factor +(factor), ..main (reap factor)) :: 14
33+:: :: 15
34+++ reap :: 16
35+ :gate factor/atom :: 17
36+ :var count/atom (mul 2 factor) :: 18
37+ :loop :like ..reap :: 19
38+ :if (gth count thru) :: 20
39+ ..reap :: 21
40+ :moar :: 22
41+ count (add count factor) :: 23
42+ field (~(del in field) count) :: 24
43+ == :: 25
44+-- :: 26
45+```
46+
47+## `sieve`: explanation
48+
49+Line `1`: we are building a gate (function) whose sample
50+(argument) is `thru`, an atom.
51+
52+Line `2`: the product of this gate is a list of atoms.
53+
54+Line `3`: we introduce a variable `field`, whose type is a set of
55+atoms. The `silt` function converts a list to a set. The `gulf`
56+function creates the range `2` through `thru` inclusive, as a
57+list of atoms.
58+
59+Line `4`: below, we introduce a core which does our work. With
60+reverse flow, we compute `main` on this core, then `abet` on the
61+product of `main`. (`abet:main` means `:rap(abet main)`.)
62+
63+The core is a state machine; `main` produces the core itself,
64+with the computation completed. `abet` then extracts the result.
65+
66+Line `5`: we wrap a core around our existing subject. The
67+`field` and `thru` atoms are within the payload and of course
68+remain accessible.
69+
70+Lines `6` and `7`: the `abet` arm, which produces the field as a
71+sorted list. `in` is the set core; `tap` is an arm which
72+produces a gate that exports the set as a list, prepending it to
73+a tail which is nil in this case (and most cases). We sort this
74+list in ascending order with `lth` (less-than).
75+
76+Line `9`: the `main` arm, which performs the main calculation.
77+
78+Line `10`: we declare a counter, `factor`, which will iterate
79+up through the factors we're removing.
80+
81+Line `11`: we start a loop. The product of the loop is cast to
82+`..main`, which is the core we're in (`+1.main`).
83+
84+Lines `12` and `13`: we terminate the loop, returning `..main`,
85+if the square of the counter exceeds the range.
86+
87+Line `14`: repeats the loop, incrementing the counter, and
88+replacing the core with a version sieved by `reap`.
89+
90+Lines `16` and `17`: the `reap` arm, which produces a gate that
91+removes multiples of a factor from the field (set of possible
92+primes). The sample of this gate is the factor to remove.
93+
94+Line `18`: we declare a variable `count`, an atom, with the
95+initial value `(mul 2 factor)`.
96+
97+Line `19`: we enter a loop. This loop produces the core itself.
98+
99+Lines `20` and `21`: we are done if the counter is out of range.
100+
101+Lines `22` to `25`: repeat the loop, stepping `count` to the next
102+multiple of `factor`, and deleting it from `field`.
103+
104+## `sieve`: code in kernel style
105+
106+Finally, the same code transliterated into runes (and in a more
107+concise "kernel" style).
108+
109+```
110+|= top/@
111+^- (list @)
112+=+ fed=(silt (gulf 2 top))
113+=< abet:main
114+|%
115+++ abet (sort (~(tap in fed)) lth)
116+++ main
117+ =+ fac=2
118+ |- ^+ ..main
119+ ?: (gth (mul fac fac) top)
120+ ..main
121+ $(fac +(fac), ..main (reap fac))
122+::
123+++ reap
124+ |= fac/atom
125+ =+ cot=(mul 2 fac)
126+ |- ^+ ..reap
127+ ?: (gth cot top)
128+ ..reap
129+ $(cot (add cot fac), fed (~(del in fed) cot))
130+--
131+```
132+
133+### `toe`: tictactoe engine
134+
135+The `toe` tictactoe engine applies a list of events to a game
136+state, producing a list of game actions. Events are tictactoe
137+moves (`move)`; actions are tictactoe results (`fact`).
138+
139+```
140+:rap :gate feed/(list move) :: 1
141+ :new game/game :: 2
142+ :loop :cast (list fact) :: 3
143+ :ifno feed ~ :: 4
144+ :sip this/(unit fact) :: 5
145+ game :: 6
146+ (~(do go game) i.feed) :: 7
147+ :var rest/(list fact) :moar(feed t.feed) :: 8
148+ :ifno(this rest [u.this rest]) :: 9
149+:: :: 10
150+:per :core :: 11
151+ ++ side atom :: 12
152+ ++ spot {x/atom y/atom} :: 13
153+ ++ fact :book {$tie $~} :: 14
154+ {$win p/cord} :: 15
155+ == :: 16
156+ ++ move :book {$x p/spot} :: 17
157+ {$o p/spot} :: 18
158+ {$z $~} :: 19
159+ == :: 20
160+ ++ game :bank w/? :: 21
161+ a/side :: 22
162+ z/side :: 23
163+ == :: 24
164+ -- :: 25
165+:core :: 26
166+++ bo :: 27
167+ :door half/side :: 28
168+ ++ bit :gate(a/atom =(1 (cut 0 [a 1] half))) :: 29
169+ ++ off :gate(a/spot (add x.a (mul 3 y.a))) :: 30
170+ ++ get :gate(a/spot (bit (off a))) :: 31
171+ ++ set :gate(a/spot (con half (bex (off a)))) :: 32
172+ ++ win :calt lien :: 33
173+ (rip 4 0wl04h0.4A0Aw.4A00s.0e070) :: 34
174+ :gate(a/atom =(a (dis a half))) :: 35
175+ -- :: 36
176+++ go :: 37
177+ :door game/game :: 38
178+ ++ do :: 39
179+ :gate act/move :: 40
180+ :cast {(unit fact) ^game} :: 41
181+ :case act :: 42
182+ {$x *} :sure(w.game ~(mo on p.act)) :: 43
183+ {$o *} :deny(w.game ~(mo on p.act)) :: 44
184+ {$z *} [~ nu] :: 45
185+ == :: 46
186+ :: :: 47
187+ ++ nu :like(game [& 0 0]) :: 48
188+ ++ on :: 49
189+ :door here/spot :: 50
190+ ++ is :or (~(get bo a.game) here) :: 51
191+ (~(get bo z.game) here) :: 52
192+ == :: 53
193+ ++ mo :cast {(unit fact) ^game} :: 54
194+ :deny is :: 55
195+ :var next/side (~(set bo a.game) here) :: 56
196+ :if ~(win bo next) :: 57
197+ [[~ %win ?:(w.game %x %o)] nu] :: 58
198+ [~ game(w !w.game, a z.game, z next)] :: 59
199+ -- :: 60
200+ -- :: 62
201+-- :: 63
202+```
203+
204+### `toe`: explanation
205+
206+Line `1` wraps a conclusion around a stack of cores. The cores
207+at `11` and `26` are the data structures and functions of the
208+engine; the conclusion is the interface and top-level logic. It
209+produces a gate whose sample is `feed`, a list of `move`.
210+
211+Line `2` declares a blank new variable named `game`, whose type
212+is the `game` mold (tictactoe game state) defined on line `21`.
213+Under line `2`, `game` pulls the variable and `^game` the mold.
214+
215+Line `3` enters a loop producing a list of game events, `fact`.
216+
217+Line `4` produces nil, `~`, if `feed` is empty.
218+
219+Lines `5` through `7` apply the move. We open a `go` core on the
220+current game state, produce a `do` gate, and call that gate on
221+the move. The product of the `do` gate is a pair; the head is
222+`(unit fact)`, either `~` or `[~ fact]`; the tail is a new
223+`game`. The `:sip` twig declares the head as a new variable,
224+`this`; it modifies the subject by setting `game` to the tail.
225+
226+Line `8` declares a new variable, `rest`, which is all the facts
227+generated by the moves in `t.feed`, the tail of the move list.
228+(Yes, this is gratuitous head recursion.) Line `9` produces
229+`rest` if the `i.feed` move produced no fact; otherwise it
230+prepends the new fact to `rest`.
231+
232+Line `11` wraps a library core around a data structure core, a
233+common pattern. (You could put the molds and the gates in the
234+same core, but the compiler couldn't constant-fold gate samples
235+that use these molds, an efficiency cost.)
236+
237+Line `12` defines the `side` mold, an alias for `atom` (`@`).
238+A side is a half of the board, as a marked/unmarked bitfield.
239+
240+Line `13` defines the `spot` mold, a 2D coordinate.
241+
242+Lines `14` to `16` define the `fact` mold, a game event (ie,
243+output action), as a book (tagged union). There are two forms of
244+`fact`: `[%tie ~]` (reporting a tie), and `[%win cord]`
245+(reporting that `'X'` or `'O'` won a game.
246+
247+Lines `17` to `20` define the `move` mold, a game move. This is
248+either `[%x spot]`, `[%o spot]`, or `[%z ~]` to reset the board.
249+
250+Lines `21` to `23` define the `game` mold, the game state. This
251+is an `a` side, the next side to move; a `z` side, the other
252+side; and `w`, which is `&` (yes) if `a` is X and `b` is O; `|`
253+otherwise. (Obviously, we swap `a` and `z` on every move.)
254+
255+Line `26` introduces the library core, which contains the doors
256+`bo` (for `side` bitfields) and `go` (for game state).
257+
258+Lines `27` to `28` begin the `bo` core, a door around `half`, a
259+board side.
260+
261+Line `29` is the `bit` gate, which tests a bit in `half`.
262+
263+Line `30` is the `off` gate, which maps from a `spot` (coordinate)
264+to a bit index.
265+
266+Line `31` is the `get` gate, which produces the bit at a `spot`.
267+
268+Line `32` is the `set` gate, which produces a new side with the
269+bit at a `spot` set. It works by ORing (`con`) `half` with the
270+binary exponent (`bex`) of the offset (`off`) of the spot.
271+
272+Lines `33` to `35` are a victory test. It calls the
273+standard `lien` function, which iterates a boolean gate over a
274+list and produces `&` (yes) if any item tests as true, against a
275+list of magic bitfields (expanded from a base64 constant), each
276+of which must equal itself when ANDed (`dis`) with `half`.
277+
278+Lines `37` to `38` begin the `go` core, a door around a `game`.
279+Again we name the sample `game`. (This is a legitimate style,
280+but not used much.)
281+
282+Lines `40` to `42` begin the `do` gate, whose sample is `act`, a
283+move. The product is cast to a pair of `(unit fact)` and a new
284+game state, written `^game` to skip to the second binding.
285+
286+Lines `42` through `46` switch on the form of `act`. If it's an
287+`%x` or `%o` move, we assert that it's the right turn, then use
288+the `mo` door to apply the move. If it's a `%z` move, we clear
289+the board.
290+
291+Line `48` is the `nu` arm, which produces a blank game state.
292+
293+Lines `49` to `50` begin the `on` door, a door around `here`, a
294+`spot`. Just as we have multiple computed attributes against the
295+game state, we have multiple computed attributes (`is` and `mo`)
296+against the combination of game state and coordinate.
297+
298+Lines `51` to `53` define the `is` arm, which is `&` (yes) iff
299+either `a` or `z` has played `here`.
300+
301+Line `54` begins the `mo` arm, which produces (with a
302+nonessential cast) a pair of `(unit fact)` and game state.
303+Again we see `^game` to pull the mold, since `game` is the
304+current game state in the `go` core.
305+
306+Line `55` asserts that no one has yet played `here`.
307+
308+Line `56` declares a variable `next`, as game side `a` with
309+`here` played in it.
310+
311+Lines `57` and `58` test if `a` has won with this move. If so,
312+we produce the win fact and a blank game state.
313+
314+Line `59` produces no fact (since nothing has happened), but
315+inverts the `w` turn indicator, replaces side `a` with the other
316+side `z`, and replaces `z` with `next`.
317+
318+### `toe`: code, kernel style
319+
320+```
321+=< |= fed/(list move)
322+ =| mag/game
323+ |- ^- (list fact)
324+ ?~ fed ~
325+ =^ did/(unit fact) mag (~(do go mag) i.fed)
326+ =+ res=$(fed t.fed)
327+ ?~(did res [u.did res])
328+=> |%
329+ ++ side @
330+ ++ spot {x/@ y/@}
331+ ++ fact $% {$tie $~}
332+ {$win p/cord}
333+ ==
334+ ++ move $% {$x p/spot}
335+ {$o p/spot}
336+ {$z $~}
337+ ==
338+ ++ game $: w/?
339+ a/side
340+ z/side
341+ ==
342+ --
343+|%
344+++ bo
345+ |_ haf/side
346+ ++ bit |=(a/atom =(1 (cut 0 [a 1] haf)))
347+ ++ get |=(a/spot (bit (off a)))
348+ ++ off |=(a/spot (add x.a (mul 3 y.a)))
349+ ++ set |=(a/spot (con haf (bex (off a))))
350+ ++ win %+ lien
351+ (rip 4 0wl04h0.4A0Aw.4A00s.0e070)
352+ |=(a/atom =(a (dis a haf)))
353+ --
354+++ go
355+ |_ mag/game
356+ ++ do
357+ |= act/move
358+ ^- {(unit fact) game}
359+ ?- act
360+ {$x *} ?>(w.mag ~(mo on p.act))
361+ {$o *} ?<(w.mag ~(mo on p.act))
362+ {$z *} [~ nu]
363+ ==
364+ ::
365+ ++ nu `game`[& 0 0]
366+ ++ on
367+ =| her/spot
368+ |%
369+ ++ is ?| (~(get bo a.mag) her)
370+ (~(get bo z.mag) her)
371+ ==
372+ ++ mo ^- {(unit fact) game}
373+ ?< is
374+ =+ next=(~(set bo a.mag) her)
375+ ?: ~(win bo next)
376+ [[~ %win ?:(w.mag %x %o)] nu]
377+ [~ mag(w !w.mag, a z.mag, z next)]
378+ --
379+ --
380+--
381+```
382+
383+## Basic molds
384+```
385+++ atom @ :: just an atom
386+++ axis @ :: tree address
387+++ bean ? :: 0=&=yes, 1=|=no
388+++ bloq @ :: blockclass
389+++ char @tD :: UTF-8 byte
390+++ cord @t :: text atom (UTF-8)
391+++ gate $-(* *) :: general gate
392+++ knot @ta :: ASCII text
393+++ noun * :: any noun
394+++ null $~ :: null, nil, etc
395+++ time @da :: galactic time
396+++ path (list knot) :: eg, fs location
397+++ tang (list tank) :: error trace
398+++ tank ::
399+ $% {$leaf p/tape} :: printing formats
400+ $: $palm :: backstep list
401+ p/{p/tape q/tape r/tape s/tape} ::
402+ q/(list tank) ::
403+ == ::
404+ $: $rose :: flat list
405+ p/{p/tape q/tape r/tape} :: mid open close
406+ q/(list tank) ::
407+ == ::
408+ == ::
409+++ tanq :: future tank
410+ $? {$~ p/(list tanq)} :: list of printables
411+ {$~ $~ p/tape} :: simple string
412+ (pair @tas tanq) :: captioned
413+ == ::
414+++ tape (list char) :: string as list
415+++ term @tas :: ascii symbol
416+++ wall (list tape) :: text lines (no \n)
417+++ wain (list cord) :: text lines (no \n)
418+
419+::::
420+::::
421+
422+++ tree |* a/gate :: binary tree
423+ $@($~ {n/a l/(tree a) r/(tree a)}) ::
424+++ trap |*(a/_* _|?(*a)) :: makes perfect sense
425+++ trel |* {a/gate b/gate c/gate} :: just a triple
426+ {p/a q/b r/c} ::
427+++ each |* {a/gate b/gate} :: either a or b
428+ $%({$& p/a} {$| p/b}) :: a default
429+
430+++ qual |* {a/gate b/gate c/gate d/gate} :: just a quadruple
431+ {p/a q/b r/c s/d} ::
432+++ pair |*({a/gate b/gate} {p/a q/b}) :: just a pair
433+++ quid |*({a/gate b/*} {a _b}) :: for =^
434+++ quip |*({a/gate b/*} {(list a) _b}) :: for =^
435+++ unit |* a/gate :: maybe
436+ $@($~ {$~ u/a}) ::
437+++ list |* a/gate :: null-term list
438+ $@($~ {i/a t/(list a)}) ::
439+++ lone |*(a/gate p/a) :: just one thing
440+
441+::::
442+::::
443+++ map |* {a/gate b/gate} :: associative tree
444+ $@($~ {n/{p/a q/b} l/(map a b) r/(map a b)}) ::
445+++ qeu |* a/gate :: queue
446+ $@($~ {n/a l/(qeu a) r/(qeu a)}) ::
447+++ set |* a/gate :: set
448+ $@($~ {n/a l/(set a) r/(set a)}) ::
449+++ jar |*({a/gate b/gate} (map a (list b))) :: map of lists
450+++ jug |*({a/gate b/gate} (map a (set b))) :: map of sets
451+```
452+
453+### Basic libraries