@@ -7,7 +7,7 @@ next: true
77# Examples
88
99Now we know enough to write two quick examples: the Sieve of
10−Eratosthenes (a naive prime sieve) and a tictactoe engine.
10+Eratosthenes (a naive prime sieve) and a tic-tac-toe engine.
1111
1212(Note that these are not examples of perfect Hoon code; they are
1313meant for teaching. They err, more than usual for Hoon, on the
@@ -48,6 +48,12 @@ than its argument, an atom:
4848
4949## `sieve`: explanation
5050
51+```
52+:gate thru/atom :: 1
53+:cast (list atom) :: 2
54+:var field/(set atom) (silt (gulf 2 thru)) :: 3
55+```
56+
5157Line `1`: we are building a gate (function) whose sample
5258(argument) is `thru`, an atom.
5359
@@ -65,6 +71,12 @@ product of `main`. (`abet:main` means `:rap(abet main)`.)
6571The core is a state machine; `main` produces the core itself,
6672with the computation completed. `abet` then extracts the result.
6773
74+```
75+:core :: 5
76+++ abet :: 6
77+ (sort (~(tap in field) ~) lth) :: 7
78+```
79+
6880Line `5`: we wrap a core around our existing subject. The
6981`field` and `thru` atoms are within the payload and of course
7082remain accessible.
@@ -75,6 +87,12 @@ produces a gate that exports the set as a list, prepending it to
7587a tail which is nil in this case (and most cases). We sort this
7688list in ascending order with `lth` (less-than).
7789
90+```
91+++ main :: 9
92+ :var factor/atom 2 :: 10
93+ :loop :like ..main :: 11
94+```
95+
7896Line `9`: the `main` arm, which performs the main calculation.
7997
8098Line `10`: we declare a counter, `factor`, which will iterate
@@ -83,12 +101,24 @@ up through the factors we're removing.
83101Line `11`: we start a loop. The product of the loop is cast to
84102`..main`, which is the core we're in (`+1.main`).
85103
104+```
105+ :if (gth (mul factor factor) thru) :: 12
106+ ..main :: 13
107+ :moar(factor +(factor), ..main (reap factor)) :: 14
108+```
109+
86110Lines `12` and `13`: we terminate the loop, returning `..main`,
87111if the square of the counter exceeds the range.
88112
89113Line `14`: repeats the loop, incrementing the counter, and
90114replacing the core with a version sieved by `reap`.
91115
116+```
117+++ reap :: 16
118+ :gate factor/atom :: 17
119+ :var count/atom (mul 2 factor) :: 18
120+```
121+
92122Lines `16` and `17`: the `reap` arm, which produces a gate that
93123removes multiples of a factor from the field (set of possible
94124primes). The sample of this gate is the factor to remove.
@@ -96,6 +126,17 @@ primes). The sample of this gate is the factor to remove.
96126Line `18`: we declare a variable `count`, an atom, with the
97127initial value `(mul 2 factor)`.
98128
129+```
130+ :loop :like ..reap :: 19
131+ :if (gth count thru) :: 20
132+ ..reap :: 21
133+ :moar :: 22
134+ count (add count factor) :: 23
135+ field (~(del in field) count) :: 24
136+ == :: 25
137+-- :: 26
138+```
139+
99140Line `19`: we enter a loop. This loop produces the core itself.
100141
101142Lines `20` and `21`: we are done if the counter is out of range.
@@ -132,11 +173,11 @@ concise "kernel" style).
132173--
133174```
134175
135−### `toe`: tictactoe engine
176+### `toe`: tic-tac-toe engine
136177
137−The `toe` tictactoe engine applies a list of events to a game
138−state, producing a list of game actions. Events are tictactoe
139−moves (`move)`; actions are tictactoe results (`fact`).
178+The `toe` tic-tac-toe engine applies a list of events to a game
179+state, producing a list of game actions. Events are tic-tac-toe
180+moves (`move)`; actions are tic-tac-toe results (`fact`).
140181
141182```
142183:rap :gate feed/(list move) :: 1
@@ -205,19 +246,32 @@ moves (`move)`; actions are tictactoe results (`fact`).
205246
206247### `toe`: explanation
207248
249+```
250+:rap :gate feed/(list move) :: 1
251+ :new game/game :: 2
252+ :loop :cast (list fact) :: 3
253+ :ifno feed ~ :: 4
254+```
255+
208256Line `1` wraps a conclusion around a stack of cores. The cores
209257at `11` and `26` are the data structures and functions of the
210258engine; the conclusion is the interface and top-level logic. It
211259produces a gate whose sample is `feed`, a list of `move`.
212260
213261Line `2` declares a blank new variable named `game`, whose type
214−is the `game` mold (tictactoe game state) defined on line `21`.
262+is the `game` mold (tic-tac-toe game state) defined on line `21`.
215263Under line `2`, `game` pulls the variable and `^game` the mold.
216264
217265Line `3` enters a loop producing a list of game events, `fact`.
218266
219267Line `4` produces nil, `~`, if `feed` is empty.
220268
269+```
270+ :sip this/(unit fact) :: 5
271+ game :: 6
272+ (~(do go game) i.feed) :: 7
273+```
274+
221275Lines `5` through `7` apply the move. We open a `go` core on the
222276current game state, produce a `do` gate, and call that gate on
223277the move. The product of the `do` gate is a pair; the head is
@@ -225,12 +279,23 @@ the move. The product of the `do` gate is a pair; the head is
225279`game`. The `:sip` twig declares the head as a new variable,
226280`this`; it modifies the subject by setting `game` to the tail.
227281
282+```
283+ :var rest/(list fact) :moar(feed t.feed) :: 8
284+ :ifno(this rest [u.this rest]) :: 9
285+```
286+
228287Line `8` declares a new variable, `rest`, which is all the facts
229288generated by the moves in `t.feed`, the tail of the move list.
230289(Yes, this is gratuitous head recursion.) Line `9` produces
231290`rest` if the `i.feed` move produced no fact; otherwise it
232291prepends the new fact to `rest`.
233292
293+```
294+:per :core :: 11
295+ ++ side atom :: 12
296+ ++ spot {x/atom y/atom} :: 13
297+```
298+
234299Line `11` wraps a library core around a data structure core, a
235300common pattern. (You could put the molds and the gates in the
236301same core, but the compiler couldn't constant-fold gate samples
@@ -241,19 +306,50 @@ A side is a half of the board, as a marked/unmarked bitfield.
241306
242307Line `13` defines the `spot` mold, a 2D coordinate.
243308
309+```
310+ ++ fact :book {$tie $~} :: 14
311+ {$win p/cord} :: 15
312+ == :: 16
313+```
314+
244315Lines `14` to `16` define the `fact` mold, a game event (ie,
245316output action), as a book (tagged union). There are two forms of
246317`fact`: `[%tie ~]` (reporting a tie), and `[%win cord]`
247318(reporting that `'X'` or `'O'` won a game.
248319
320+```
321+ ++ move :book {$x p/spot} :: 17
322+ {$o p/spot} :: 18
323+ {$z $~} :: 19
324+ == :: 20
325+```
326+
249327Lines `17` to `20` define the `move` mold, a game move. This is
250328either `[%x spot]`, `[%o spot]`, or `[%z ~]` to reset the board.
251329
330+```
331+ ++ game :bank w/? :: 21
332+ a/side :: 22
333+ z/side :: 23
334+ == :: 24
335+ -- :: 25
336+```
337+
252338Lines `21` to `23` define the `game` mold, the game state. This
253339is an `a` side, the next side to move; a `z` side, the other
254340side; and `w`, which is `&` (yes) if `a` is X and `b` is O; `|`
255341otherwise. (Obviously, we swap `a` and `z` on every move.)
256342
343+```
344+:core :: 26
345+++ bo :: 27
346+ :door half/side :: 28
347+ ++ bit :gate(a/atom =(1 (cut 0 [a 1] half))) :: 29
348+ ++ off :gate(a/spot (add x.a (mul 3 y.a))) :: 30
349+ ++ get :gate(a/spot (bit (off a))) :: 31
350+ ++ set :gate(a/spot (con half (bex (off a)))) :: 32
351+```
352+
257353Line `26` introduces the library core, which contains the doors
258354`bo` (for `side` bitfields) and `go` (for game state).
259355
@@ -271,12 +367,27 @@ Line `32` is the `set` gate, which produces a new side with the
271367bit at a `spot` set. It works by ORing (`con`) `half` with the
272368binary exponent (`bex`) of the offset (`off`) of the spot.
273369
370+```
371+ ++ win :calt lien :: 33
372+ (rip 4 0wl04h0.4A0Aw.4A00s.0e070) :: 34
373+ :gate(a/atom =(a (dis a half))) :: 35
374+ -- :: 36
375+```
376+
274377Lines `33` to `35` are a victory test. It calls the
275378standard `lien` function, which iterates a boolean gate over a
276379list and produces `&` (yes) if any item tests as true, against a
277380list of magic bitfields (expanded from a base64 constant), each
278381of which must equal itself when ANDed (`dis`) with `half`.
279382
383+```
384+++ go :: 37
385+ :door game/game :: 38
386+ ++ do :: 39
387+ :gate act/move :: 40
388+ :cast {(unit fact) ^game} :: 41
389+```
390+
280391Lines `37` to `38` begin the `go` core, a door around a `game`.
281392Again we name the sample `game`. (This is a legitimate style,
282393but not used much.)
@@ -285,11 +396,29 @@ Lines `40` to `42` begin the `do` gate, whose sample is `act`, a
285396move. The product is cast to a pair of `(unit fact)` and a new
286397game state, written `^game` to skip to the second binding.
287398
399+```
400+ :case act :: 42
401+ {$x *} :sure(w.game ~(mo on p.act)) :: 43
402+ {$o *} :deny(w.game ~(mo on p.act)) :: 44
403+ {$z *} [~ nu] :: 45
404+ == :: 46
405+ :: :: 47
406+```
407+
288408Lines `42` through `46` switch on the form of `act`. If it's an
289409`%x` or `%o` move, we assert that it's the right turn, then use
290410the `mo` door to apply the move. If it's a `%z` move, we clear
291411the board.
292412
413+```
414+ ++ nu :like(game [& 0 0]) :: 48
415+ ++ on :: 49
416+ :door here/spot :: 50
417+ ++ is :or (~(get bo a.game) here) :: 51
418+ (~(get bo z.game) here) :: 52
419+ == :: 53
420+```
421+
293422Line `48` is the `nu` arm, which produces a blank game state.
294423
295424Lines `49` to `50` begin the `on` door, a door around `here`, a
@@ -300,6 +429,18 @@ against the combination of game state and coordinate.
300429Lines `51` to `53` define the `is` arm, which is `&` (yes) iff
301430either `a` or `z` has played `here`.
302431
432+```
433+ ++ mo :cast {(unit fact) ^game} :: 54
434+ :deny is :: 55
435+ :var next/side (~(set bo a.game) here) :: 56
436+ :if ~(win bo next) :: 57
437+ [[~ %win ?:(w.game %x %o)] nu] :: 58
438+ [~ game(w !w.game, a z.game, z next)] :: 59
439+ -- :: 60
440+ -- :: 62
441+-- :: 63
442+```
443+
303444Line `54` begins the `mo` arm, which produces (with a
304445nonessential cast) a pair of `(unit fact)` and game state.
305446Again we see `^game` to pull the mold, since `game` is the