on master help sign in
typo fixes & example code more readily readable
418ce1bTobias Merkle
docs/hoon/basic.md+2−5
@@ -79,11 +79,8 @@ tail `q`.
79### `{$hold p/span q/twig}`
79### `{$hold p/span q/twig}`
80
80
81A `$hold` span, with span `p` and twig `q`, is a lazy reference
81A `$hold` span, with span `p` and twig `q`, is a lazy reference
82−to the span of `(mint p q)`. In English it means: "the type of
82+to the span of `(mint p q)`. In English, it means: "the type of
83−the product when we compile `q` against subject `p`.
83+the product when we compile `q` against subject `p`."
84−
85−This is "manual laziness." Hoon is a strict language, so we have
86−to express
87
84
88### `{$face p/term q/span}`
85### `{$face p/term q/span}`
89
86
docs/hoon/examples.md+147−6
@@ -7,7 +7,7 @@ next: true
7# Examples
7# Examples
8
8
9Now we know enough to write two quick examples: the Sieve of
9Now 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.
11
11
12(Note that these are not examples of perfect Hoon code; they are
12(Note that these are not examples of perfect Hoon code; they are
13meant for teaching. They err, more than usual for Hoon, on the
13meant for teaching. They err, more than usual for Hoon, on the
@@ -48,6 +48,12 @@ than its argument, an atom:
48
48
49## `sieve`: explanation
49## `sieve`: explanation
50
50
51+```
52+:gate thru/atom :: 1
53+:cast (list atom) :: 2
54+:var field/(set atom) (silt (gulf 2 thru)) :: 3
55+```
56+
51Line `1`: we are building a gate (function) whose sample
57Line `1`: we are building a gate (function) whose sample
52(argument) is `thru`, an atom.
58(argument) is `thru`, an atom.
53
59
@@ -65,6 +71,12 @@ product of `main`. (`abet:main` means `:rap(abet main)`.)
65The core is a state machine; `main` produces the core itself,
71The core is a state machine; `main` produces the core itself,
66with the computation completed. `abet` then extracts the result.
72with the computation completed. `abet` then extracts the result.
67
73
74+```
75+:core :: 5
76+++ abet :: 6
77+ (sort (~(tap in field) ~) lth) :: 7
78+```
79+
68Line `5`: we wrap a core around our existing subject. The
80Line `5`: we wrap a core around our existing subject. The
69`field` and `thru` atoms are within the payload and of course
81`field` and `thru` atoms are within the payload and of course
70remain accessible.
82remain accessible.
@@ -75,6 +87,12 @@ produces a gate that exports the set as a list, prepending it to
75a tail which is nil in this case (and most cases). We sort this
87a tail which is nil in this case (and most cases). We sort this
76list in ascending order with `lth` (less-than).
88list in ascending order with `lth` (less-than).
77
89
90+```
91+++ main :: 9
92+ :var factor/atom 2 :: 10
93+ :loop :like ..main :: 11
94+```
95+
78Line `9`: the `main` arm, which performs the main calculation.
96Line `9`: the `main` arm, which performs the main calculation.
79
97
80Line `10`: we declare a counter, `factor`, which will iterate
98Line `10`: we declare a counter, `factor`, which will iterate
@@ -83,12 +101,24 @@ up through the factors we're removing.
83Line `11`: we start a loop. The product of the loop is cast to
101Line `11`: we start a loop. The product of the loop is cast to
84`..main`, which is the core we're in (`+1.main`).
102`..main`, which is the core we're in (`+1.main`).
85
103
104+```
105+ :if (gth (mul factor factor) thru) :: 12
106+ ..main :: 13
107+ :moar(factor +(factor), ..main (reap factor)) :: 14
108+```
109+
86Lines `12` and `13`: we terminate the loop, returning `..main`,
110Lines `12` and `13`: we terminate the loop, returning `..main`,
87if the square of the counter exceeds the range.
111if the square of the counter exceeds the range.
88
112
89Line `14`: repeats the loop, incrementing the counter, and
113Line `14`: repeats the loop, incrementing the counter, and
90replacing the core with a version sieved by `reap`.
114replacing the core with a version sieved by `reap`.
91
115
116+```
117+++ reap :: 16
118+ :gate factor/atom :: 17
119+ :var count/atom (mul 2 factor) :: 18
120+```
121+
92Lines `16` and `17`: the `reap` arm, which produces a gate that
122Lines `16` and `17`: the `reap` arm, which produces a gate that
93removes multiples of a factor from the field (set of possible
123removes multiples of a factor from the field (set of possible
94primes). The sample of this gate is the factor to remove.
124primes). 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.
96Line `18`: we declare a variable `count`, an atom, with the
126Line `18`: we declare a variable `count`, an atom, with the
97initial value `(mul 2 factor)`.
127initial value `(mul 2 factor)`.
98
128
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+
99Line `19`: we enter a loop. This loop produces the core itself.
140Line `19`: we enter a loop. This loop produces the core itself.
100
141
101Lines `20` and `21`: we are done if the counter is out of range.
142Lines `20` and `21`: we are done if the counter is out of range.
@@ -132,11 +173,11 @@ concise "kernel" style).
132--
173--
133```
174```
134
175
135−### `toe`: tictactoe engine
176+### `toe`: tic-tac-toe engine
136
177
137−The `toe` tictactoe engine applies a list of events to a game
178+The `toe` tic-tac-toe engine applies a list of events to a game
138−state, producing a list of game actions. Events are tictactoe
179+state, producing a list of game actions. Events are tic-tac-toe
139−moves (`move)`; actions are tictactoe results (`fact`).
180+moves (`move)`; actions are tic-tac-toe results (`fact`).
140
181
141```
182```
142:rap :gate feed/(list move) :: 1
183:rap :gate feed/(list move) :: 1
@@ -205,19 +246,32 @@ moves (`move)`; actions are tictactoe results (`fact`).
205
246
206### `toe`: explanation
247### `toe`: explanation
207
248
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+
208Line `1` wraps a conclusion around a stack of cores. The cores
256Line `1` wraps a conclusion around a stack of cores. The cores
209at `11` and `26` are the data structures and functions of the
257at `11` and `26` are the data structures and functions of the
210engine; the conclusion is the interface and top-level logic. It
258engine; the conclusion is the interface and top-level logic. It
211produces a gate whose sample is `feed`, a list of `move`.
259produces a gate whose sample is `feed`, a list of `move`.
212
260
213Line `2` declares a blank new variable named `game`, whose type
261Line `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`.
215Under line `2`, `game` pulls the variable and `^game` the mold.
263Under line `2`, `game` pulls the variable and `^game` the mold.
216
264
217Line `3` enters a loop producing a list of game events, `fact`.
265Line `3` enters a loop producing a list of game events, `fact`.
218
266
219Line `4` produces nil, `~`, if `feed` is empty.
267Line `4` produces nil, `~`, if `feed` is empty.
220
268
269+```
270+ :sip this/(unit fact) :: 5
271+ game :: 6
272+ (~(do go game) i.feed) :: 7
273+```
274+
221Lines `5` through `7` apply the move. We open a `go` core on the
275Lines `5` through `7` apply the move. We open a `go` core on the
222current game state, produce a `do` gate, and call that gate on
276current game state, produce a `do` gate, and call that gate on
223the move. The product of the `do` gate is a pair; the head is
277the 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
225`game`. The `:sip` twig declares the head as a new variable,
279`game`. The `:sip` twig declares the head as a new variable,
226`this`; it modifies the subject by setting `game` to the tail.
280`this`; it modifies the subject by setting `game` to the tail.
227
281
282+```
283+ :var rest/(list fact) :moar(feed t.feed) :: 8
284+ :ifno(this rest [u.this rest]) :: 9
285+```
286+
228Line `8` declares a new variable, `rest`, which is all the facts
287Line `8` declares a new variable, `rest`, which is all the facts
229generated by the moves in `t.feed`, the tail of the move list.
288generated by the moves in `t.feed`, the tail of the move list.
230(Yes, this is gratuitous head recursion.) Line `9` produces
289(Yes, this is gratuitous head recursion.) Line `9` produces
231`rest` if the `i.feed` move produced no fact; otherwise it
290`rest` if the `i.feed` move produced no fact; otherwise it
232prepends the new fact to `rest`.
291prepends the new fact to `rest`.
233
292
293+```
294+:per :core :: 11
295+ ++ side atom :: 12
296+ ++ spot {x/atom y/atom} :: 13
297+```
298+
234Line `11` wraps a library core around a data structure core, a
299Line `11` wraps a library core around a data structure core, a
235common pattern. (You could put the molds and the gates in the
300common pattern. (You could put the molds and the gates in the
236same core, but the compiler couldn't constant-fold gate samples
301same 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.
241
306
242Line `13` defines the `spot` mold, a 2D coordinate.
307Line `13` defines the `spot` mold, a 2D coordinate.
243
308
309+```
310+ ++ fact :book {$tie $~} :: 14
311+ {$win p/cord} :: 15
312+ == :: 16
313+```
314+
244Lines `14` to `16` define the `fact` mold, a game event (ie,
315Lines `14` to `16` define the `fact` mold, a game event (ie,
245output action), as a book (tagged union). There are two forms of
316output action), as a book (tagged union). There are two forms of
246`fact`: `[%tie ~]` (reporting a tie), and `[%win cord]`
317`fact`: `[%tie ~]` (reporting a tie), and `[%win cord]`
247(reporting that `'X'` or `'O'` won a game.
318(reporting that `'X'` or `'O'` won a game.
248
319
320+```
321+ ++ move :book {$x p/spot} :: 17
322+ {$o p/spot} :: 18
323+ {$z $~} :: 19
324+ == :: 20
325+```
326+
249Lines `17` to `20` define the `move` mold, a game move. This is
327Lines `17` to `20` define the `move` mold, a game move. This is
250either `[%x spot]`, `[%o spot]`, or `[%z ~]` to reset the board.
328either `[%x spot]`, `[%o spot]`, or `[%z ~]` to reset the board.
251
329
330+```
331+ ++ game :bank w/? :: 21
332+ a/side :: 22
333+ z/side :: 23
334+ == :: 24
335+ -- :: 25
336+```
337+
252Lines `21` to `23` define the `game` mold, the game state. This
338Lines `21` to `23` define the `game` mold, the game state. This
253is an `a` side, the next side to move; a `z` side, the other
339is an `a` side, the next side to move; a `z` side, the other
254side; and `w`, which is `&` (yes) if `a` is X and `b` is O; `|`
340side; and `w`, which is `&` (yes) if `a` is X and `b` is O; `|`
255otherwise. (Obviously, we swap `a` and `z` on every move.)
341otherwise. (Obviously, we swap `a` and `z` on every move.)
256
342
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+
257Line `26` introduces the library core, which contains the doors
353Line `26` introduces the library core, which contains the doors
258`bo` (for `side` bitfields) and `go` (for game state).
354`bo` (for `side` bitfields) and `go` (for game state).
259
355
@@ -271,12 +367,27 @@ Line `32` is the `set` gate, which produces a new side with the
271bit at a `spot` set. It works by ORing (`con`) `half` with the
367bit at a `spot` set. It works by ORing (`con`) `half` with the
272binary exponent (`bex`) of the offset (`off`) of the spot.
368binary exponent (`bex`) of the offset (`off`) of the spot.
273
369
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+
274Lines `33` to `35` are a victory test. It calls the
377Lines `33` to `35` are a victory test. It calls the
275standard `lien` function, which iterates a boolean gate over a
378standard `lien` function, which iterates a boolean gate over a
276list and produces `&` (yes) if any item tests as true, against a
379list and produces `&` (yes) if any item tests as true, against a
277list of magic bitfields (expanded from a base64 constant), each
380list of magic bitfields (expanded from a base64 constant), each
278of which must equal itself when ANDed (`dis`) with `half`.
381of which must equal itself when ANDed (`dis`) with `half`.
279
382
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+
280Lines `37` to `38` begin the `go` core, a door around a `game`.
391Lines `37` to `38` begin the `go` core, a door around a `game`.
281Again we name the sample `game`. (This is a legitimate style,
392Again we name the sample `game`. (This is a legitimate style,
282but not used much.)
393but not used much.)
@@ -285,11 +396,29 @@ Lines `40` to `42` begin the `do` gate, whose sample is `act`, a
285move. The product is cast to a pair of `(unit fact)` and a new
396move. The product is cast to a pair of `(unit fact)` and a new
286game state, written `^game` to skip to the second binding.
397game state, written `^game` to skip to the second binding.
287
398
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+
288Lines `42` through `46` switch on the form of `act`. If it's an
408Lines `42` through `46` switch on the form of `act`. If it's an
289`%x` or `%o` move, we assert that it's the right turn, then use
409`%x` or `%o` move, we assert that it's the right turn, then use
290the `mo` door to apply the move. If it's a `%z` move, we clear
410the `mo` door to apply the move. If it's a `%z` move, we clear
291the board.
411the board.
292
412
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+
293Line `48` is the `nu` arm, which produces a blank game state.
422Line `48` is the `nu` arm, which produces a blank game state.
294
423
295Lines `49` to `50` begin the `on` door, a door around `here`, a
424Lines `49` to `50` begin the `on` door, a door around `here`, a
@@ -300,6 +429,18 @@ against the combination of game state and coordinate.
300Lines `51` to `53` define the `is` arm, which is `&` (yes) iff
429Lines `51` to `53` define the `is` arm, which is `&` (yes) iff
301either `a` or `z` has played `here`.
430either `a` or `z` has played `here`.
302
431
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+
303Line `54` begins the `mo` arm, which produces (with a
444Line `54` begins the `mo` arm, which produces (with a
304nonessential cast) a pair of `(unit fact)` and game state.
445nonessential cast) a pair of `(unit fact)` and game state.
305Again we see `^game` to pull the mold, since `game` is the
446Again we see `^game` to pull the mold, since `game` is the
docs/hoon/syntax.md+3−3
@@ -21,7 +21,7 @@ piles*, *indentation creep*, and *feature/label confusion*.
21
21
22## Terminator piles
22## Terminator piles
23
23
24−*Terminator piles* are like Lisp's stacks of right parenthesess.
24+*Terminator piles* are like Lisp's stacks of right parentheses.
25Significant whitespace solves this problem and creates others.
25Significant whitespace solves this problem and creates others.
26
26
27Hoon has no terminator piles. Except for a 1-space / more-space
27Hoon has no terminator piles. Except for a 1-space / more-space
@@ -228,7 +228,7 @@ s
228
228
229The hope of backstep indentation is that the heaviest twigs are
229The hope of backstep indentation is that the heaviest twigs are
230at the bottom, keeping code flow vertical rather than diagonal.
230at the bottom, keeping code flow vertical rather than diagonal.
231−Alternate, reversing
231+
232
232
233### Conventions: *running*
233### Conventions: *running*
234
234
@@ -345,7 +345,7 @@ starting in order of construction from `a`, or within a tuple
345mold `p`. Hoon uses single-letter names for the same reason
345mold `p`. Hoon uses single-letter names for the same reason
346Algol style languages pass arguments by order, rather than
346Algol style languages pass arguments by order, rather than
347keyword. Naming items by order makes sense when there are no
347keyword. Naming items by order makes sense when there are no
348−more than three or four; five is stretching it; six is too many.
348+more than three or four; five is stretching it; six is outright.
349
349
350For example, when defining `add`, we want to name the operands
350For 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
351`a` and `b`. It's silly to call them `foo` and `bar`, let alone
docs/hoon/twig.md+3−3
@@ -30,9 +30,9 @@ of this structure is a *subexpression* or just *leg*.
30Usually a subexpression is itself a `twig`; sometimes it's an
30Usually a subexpression is itself a `twig`; sometimes it's an
31`@tas` (symbol) or a `wing` (reference path).
31`@tas` (symbol) or a `wing` (reference path).
32
32
33−## Moldy moss and woody seed
33+## Moldy moss; woody seed
34
34
35−When defining each pages in the `twig` book, we never use `twig`
35+When defining each page in the `twig` book, we never use `twig`
36itself as a leg. Instead, we use the mold `moss` to describe
36itself as a leg. Instead, we use the mold `moss` to describe
37twigs whose product is used as a mold, and `seed` for twigs whose
37twigs whose product is used as a mold, and `seed` for twigs whose
38product could be anything. Both `moss` and `seed` are just
38product could be anything. Both `moss` and `seed` are just
@@ -47,7 +47,7 @@ For instance, `[%foo %bar]` is woody: a twig producing the noun
47producing a function whose product is always `[7.303.014
47producing a function whose product is always `[7.303.014
487.496.034]`.
487.496.034]`.
49
49
50−This mold of course is a noun (a gate). The value of that noun
50+This mold, of course, is a noun (a gate). The value of that noun
51is not `[7.303.014 7.496.034]`, or anything remotely like it.
51is not `[7.303.014 7.496.034]`, or anything remotely like it.
52The noun is a pile of code. It is probably a big pile of code,
52The noun is a pile of code. It is probably a big pile of code,
53because most cores include a lot of formulas, contexts, etc,
53because most cores include a lot of formulas, contexts, etc,