on master help sign in
Merge branch 'master' into zola-port
db111b9Morgan Sutherland
learn/hoon/hoon-tutorial/hoon-syntax.md+34−274
@@ -1,19 +1,21 @@
1+++
1+++
2title = "Hoon Syntax"
2title = "Hoon Syntax"
3−weight = 22
3+weight = 13
4template = "doc.html"
4template = "doc.html"
5+++
5+++
6+# 1.3 Hoon Syntax
7+
6The study of Hoon can be divided into two parts: syntax and semantics.
8The study of Hoon can be divided into two parts: syntax and semantics.
7
9
8−The [syntax](https://en.wikipedia.org/wiki/Syntax_%28programming_languages%29) of a programming language is the set of rules that determine what counts as admissible code in that language. It determines which characters may be used in the source, and also how these characters may be assembled to constitute a program. Attempting to run a program that doesn't follow these rules will result in a syntax error.
10+The [syntax](https://en.wikipedia.org/wiki/Syntax_(programming_languages%29) of a programming language is the set of rules that determine what counts as admissible code in that language. It determines which characters may be used in the source, and also how these characters may be assembled to constitute a program. Attempting to run a program that doesn't follow these rules will result in a syntax error.
9
11
10−The [semantics](https://en.wikipedia.org/wiki/Semantics_%28computer_science%29) of a programming language concerns the meaning of the various parts of that language's code.
12+The [semantics](https://en.wikipedia.org/wiki/Semantics_(computer_science%29) of a programming language concerns the meaning of the various parts of that language's code.
11
13
12−In this lesson we cover Hoon's syntax. A strict account of Hoon's syntax would refrain from making any reference at all to semantics, but for ease of exposition we won't be quite so fastidious.
14+In this lesson we will give a general overview of Hoon's syntax. By the end of it, you should be familiar with all the basic elements of Hoon code.
13
15
14## Hoon Characters
16## Hoon Characters
15
17
16−Hoon source files are composed almost entirely of the [printable ASCII characters](https://en.wikipedia.org/wiki/ASCII#Printable_characters). Hoon does not accept any other characters in source files except for [UTF-8](https://en.wikipedia.org/wiki/UTF-8) in quoted strings. Hard tab characters are illegal.
18+Hoon source files are composed almost entirely of the [printable ASCII characters](https://en.wikipedia.org/wiki/ASCII#Printable_characters). Hoon does not accept any other characters in source files except for [UTF-8](https://en.wikipedia.org/wiki/UTF-8) in quoted strings. Hard tab characters are illegal; use two spaces instead.
17
19
18```
20```
19> "You can put ½ in quotes, but not elsewhere!"
21> "You can put ½ in quotes, but not elsewhere!"
@@ -51,7 +53,7 @@ Note that the list includes two separate whitespace forms: `ace` for a single sp
51
53
52## Expressions of Hoon
54## Expressions of Hoon
53
55
54−An [expression](https://en.wikipedia.org/wiki/Expression_%28computer_science%29) is a combination of characters that the language interprets and evaluates as producing a value. Hoon programs are made up entirely of expressions.
56+An [expression](https://en.wikipedia.org/wiki/Expression_(computer_science%29) is a combination of characters that the language interprets and evaluates as producing a value. Hoon programs are made up entirely of expressions.
55
57
56Hoon expressions can be either basic or complex. Basic expressions of Hoon are fundamental, meaning that they can't be broken down into smaller expressions. Complex expressions are made up of smaller expressions (which are called **subexpressions**).
58Hoon expressions can be either basic or complex. Basic expressions of Hoon are fundamental, meaning that they can't be broken down into smaller expressions. Complex expressions are made up of smaller expressions (which are called **subexpressions**).
57
59
@@ -61,7 +63,7 @@ There are many categories of Hoon expressions: noun literals, wing expressions,
61
63
62A noun is either an atom or a cell. An atom is an unsigned integer and a cell is a pair of nouns.
64A noun is either an atom or a cell. An atom is an unsigned integer and a cell is a pair of nouns.
63
65
64−There are [literal](https://en.wikipedia.org/wiki/Literal_%28computer_programming%29) expressions for each kind of noun. A noun literal is just a notation for representing a fixed noun value.
66+There are [literal](https://en.wikipedia.org/wiki/Literal_(computer_programming%29) expressions for each kind of noun. A noun literal is just a notation for representing a fixed noun value.
65
67
66We start with atom literals. Each of these is a basic expression of Hoon that evaluates to itself. Examples:
68We start with atom literals. Each of these is a basic expression of Hoon that evaluates to itself. Examples:
67
69
@@ -80,12 +82,6 @@ We start with atom literals. Each of these is a basic expression of Hoon that e
80
82
81> ~zod
83> ~zod
82~zod
84~zod
83−
84−> 0xdead.beef
85−0xdead.beef
86−
87−> 0b1101.1001
88−0b1101.1001
89```
85```
90
86
91Recall from [lesson 1.2](./docs/learn/hoon/hoon-tutorial/nouns.md) that even though atoms are unsigned integers, they can be pretty-printed in different ways. The way an atom is to be represented depends on its aura. The literal syntax for each of the hard-coded auras will be explained further in [lesson 2.4](./docs/learn/hoon/hoon-tutorial/atoms-auras-and-simple-cell-types.md).
87Recall from [lesson 1.2](./docs/learn/hoon/hoon-tutorial/nouns.md) that even though atoms are unsigned integers, they can be pretty-printed in different ways. The way an atom is to be represented depends on its aura. The literal syntax for each of the hard-coded auras will be explained further in [lesson 2.4](./docs/learn/hoon/hoon-tutorial/atoms-auras-and-simple-cell-types.md).
@@ -127,7 +123,6 @@ Let's start with the base case: a single limb. A limb expression is a trivial w
127- `b`
123- `b`
128- `add`
124- `add`
129- `mul`
125- `mul`
130−- `kebab-case-123`
131
126
132As a special limb we also have `$`. This is the name of the arm in special one-armed cores called "gates". (We covered the role of `$` in [lesson 1.5](./docs/learn/hoon/hoon-tutorial/gates.md).)
127As a special limb we also have `$`. This is the name of the arm in special one-armed cores called "gates". (We covered the role of `$` in [lesson 1.5](./docs/learn/hoon/hoon-tutorial/gates.md).)
133
128
@@ -141,6 +136,7 @@ Wing expressions with multiple limbs are complex expressions. Examples:
141- `-.b.+2`
136- `-.b.+2`
142- `-.add`
137- `-.add`
143
138
139+
144### Type Expressions
140### Type Expressions
145
141
146Hoon is a statically typed language. You'll learn more about the type system later in the chapter. For now, just know that Hoon's type system uses special symbols to indicate certain fundamental types: `~` (null), `*` (noun), `@` (atom), `^` (cell), and `?` (flag). Each of these symbols can be used as a stand-alone expression of Hoon. In the case of `@` there may be a series of letters following it, to indicate an atom aura; e.g., `@s`, `@rs`, `@tas`, and `@tD`.
142Hoon is a statically typed language. You'll learn more about the type system later in the chapter. For now, just know that Hoon's type system uses special symbols to indicate certain fundamental types: `~` (null), `*` (noun), `@` (atom), `^` (cell), and `?` (flag). Each of these symbols can be used as a stand-alone expression of Hoon. In the case of `@` there may be a series of letters following it, to indicate an atom aura; e.g., `@s`, `@rs`, `@tas`, and `@tD`.
@@ -202,13 +198,6 @@ Let's look at another example. The `.=` rune takes two subexpressions, evaluate
202> .= 22 11
198> .= 22 11
203%.n
199%.n
204
200
205−> .= 22 (add 11 11)
206−%.y
207−
208−> .= 22
209− 11
210−%.n
211−
212> .= 22
201> .= 22
213 (add 11 11)
202 (add 11 11)
214%.y
203%.y
@@ -257,51 +246,7 @@ The irregular `( )` gate-calling syntax is versatile -- it is also a shortcut fo
25710
24610
258```
247```
259
248
260−The `( )` gate-calling syntax can be used for gates of any other [arity](https://en.wikipedia.org/wiki/Arity) as well.
249+The `( )` gate-calling syntax can be used for gates with any number of arguments.
261−
262−You've already seen two other irregular forms. In [lesson 1.5](./docs/learn/hoon/hoon-tutorial/gates.md), you made a gate that takes an atom `a` for its sample and returns `a + 1`: `|=(a=@ (add 1 a))`. This expression uses the `|=` rune in flat form.
263−
264−```
265−> =inc |=(a=@ (add 1 a))
266−
267−> (inc 10)
268−11
269−
270−> (inc 15)
271−16
272−```
273−
274−The `a=@` subexpression -- used to define the face and the type of the gate's sample -- is the irregular form of `$=(a @)`:
275−
276−```
277−> =inc |=($=(a @) (add 1 a))
278−
279−> (inc 10)
280−11
281−
282−> (inc 15)
283−16
284−```
285−
286−In the previous chapter you also defined faces in nouns as in the following examples:
287−
288−```
289−> b:[a=15 b=25 c=35]
290−25
291−
292−> c:[a=15 b=25 c=35]
293−35
294−```
295−
296−The `a=15` expression is the irregular form of `^=(a 15)`:
297−
298−```
299−> b:[^=(a 15) ^=(b 25) ^=(c 35)]
300−25
301−
302−> c:[^=(a 15) ^=(b 25) ^=(c 35)]
303−35
304−```
305
250
306You can find other irregular forms in the irregular expression [reference document](./docs/reference/hoon-expressions/irregular.md).
251You can find other irregular forms in the irregular expression [reference document](./docs/reference/hoon-expressions/irregular.md).
307
252
@@ -315,9 +260,6 @@ Below we use the `` ` `` symbol to create a cell whose head is null, `~`.
315> `12
260> `12
316[~ 12]
261[~ 12]
317
262
318−> `[12 14]
319−[~ 12 14]
320−
321> `[[12 14] 16]
263> `[[12 14] 16]
322[~ [12 14] 16]
264[~ [12 14] 16]
323```
265```
@@ -339,229 +281,47 @@ b=[16 18]
339
281
340> ,.+:[a=[12 14] b=[16 18]]
282> ,.+:[a=[12 14] b=[16 18]]
341[16 18]
283[16 18]
342−
343−> ,.+:[a=[12 14] [16 18]]
344−[16 18]
345```
284```
346
285
347To see other irregular expressions, check the irregular expression [reference document](./docs/reference/hoon-expressions/irregular.md).
286To see other irregular expressions, check the irregular expression [reference document](./docs/reference/hoon-expressions/irregular.md).
348
287
349−## Hoon Style
350−
351−See [Hoon Style Guide](./docs/learn/hoon/style.md).
352−
353−### Rune Expression Body Types
354−
355−Let's call everything in the expression after the initial rune the expression **body**. There are four kinds of body: **fixed**, **running**, **jogging**, and **battery**. There is a preferred manner of styling for each body.
356−
357−#### Fixed
358−
359−Some runes have a **fixed** number of subexpressions. For example, the `:-` and `.=` runes each have exactly two.
360−
361−Fixed bodies often use "backstep" indentation in tall form. In backstep indentation the code slopes backward and to the right by two spaces per line. The last subexpression isn't indented at all, and the first subexpression is on the same line as the rune. The indentation of the first subexpression therefore depends upon the total number of subexpressions.
362−
363−We'll use the `:` family of runes to illustrate. The `:-` rune creates a cell from two subexpressions, `:+` creates a cell from three, and `:^` creates a cell from four. In flat form:
364−
365−```
366−> :-(11 22)
367−[11 22]
368−
369−> :+(11 22 33)
370−[11 22 33]
371−
372−> :^(11 22 33 44)
373−[11 22 33 44]
374−```
375−
376−Let's look at these in tall form, using backstep indentation:
377−
378−```
379−> :- 11
380− 22
381−[11 22]
382−
383−> :+ 11
384− 22
385− 33
386−[11 22 33]
387−
388−> :^ 11
389− 22
390− 33
391− 44
392−[11 22 33 44]
393−```
394−
395−
396−Some other **1-fixed**, **2-fixed**, **3-fixed** and **4-fixed** examples, using `p`, `q`, `r`, and `s` for the subexpressions:
397−
398−```
399−|.
400−p
401−
402−=| p
403−q
404−
405−?: p
406− q
407−r
408−
409−%^ p
410− q
411− r
412−s
413−```
414−
415−In optimal usage of backstep indentation the most complicated subexpressions are at the bottom. This helps keep code flow vertical rather than diagonal.
416−
417−#### Running
418−
419−A **running** body doesn't have a fixed number of subexpressions; expressions with running bodies can be arbitrarily long.
420−
421−To indicate the end of such expressions in tall form, use the `==` rune. The first subexpression is two spaces after the initial rune, and all others are indented to line up with the first. The terminating `==` should align vertically with the initial rune. In flat form, parentheses are used around the expression body, so the terminating `==` is unnecessary.
422−
423−The `:*` rune is used to create a cell of arbitrary length:
424−
425−```
426−> :*(11 22 33)
427−[11 22 33]
428−
429−> :*(11 22 33 44)
430−[11 22 33 44]
431−
432−> :*(11 22 33 44 55)
433−[11 22 33 44 55]
434−```
435−
436−We'll use `:*` to illustrate proper tall form running body style:
437−
438−```
439−> :* 11
440− 22
441− 33
442− 44
443− 55
444− ==
445−[11 22 33 44 55]
446−```
447−
448−More generally:
449−
450−```
451−:* p
452− q
453− r
454− s
455− t
456−==
457−```
458−
459−#### Jogging
460−
461−A **jogging** body is an arbitrarily long series of subexpression pairs. Most jogging bodies are preceded by a fixed sequence of subexpressions. The first jogging pair is one line after the last fixed subexpression, and indented two spaces behind it. There are two jogging conventions: **flat** (each pair on one line) and **tall** (each pair split across lines). In either case the expression is terminated with a `==`.
462−
463−The `?-` rune is `1-fixed` followed by a jogging body. The fixed subexpression is evaluated and then compared against the left subexpression of each of the jogging pairs. When a match is found, the subexpression to the right of the match is evaluated.
464
288
465−For example:
289+## The Standard Library
466
290
467−```
291+The Hoon standard library is a compilation of generally useful Hoon gates (functions). You've seen these already: in expressions like `(add 11 11)`, `add` is a function from the standard library.
468−> ?- `?(%2 %3 %4)`%2
469− %2 %yes
470− %3 %no
471− %4 %no
472− ==
473−%yes
474−```
475−
476−More generally, the **flat jogging** style (preceded by **1-fixed** `p`):
477−
478−```
479−?- p
480− q r
481− s t
482− u v
483−==
484−```
485
292
486−A **tall jogging** example (preceded by **1-fixed** `p`):
293+It's important to know about standard library functions, because they make certain tasks much easier, and spare you from having to write the code itself. If you did not use the `add` library function, for example, you would have to write out code like this every time you wanted to find the sum of two numbers:
487
294
488```
295```
489−?- p
296+++ add
490− q
297+ ~/ %add
491− r
298+ |= [a=@ b=@]
492− s
299+ ^- @
493− t
300+ ?: =(0 a) b
494− u
301+ $(a (dec a), b +(b))
495− v
496−==
497```
302```
498
303
499−In flat form for **jogging** bodies, subexpression pairs are separated by commas:
304+Standard library functions are often built with other standard library functions, but ultimately those functions used are only built with runes. Notice how in the code above `add` is built with the `dec` function, which decrements a value by `1`.
500−
501−```
502−$(a +(a), b (dec b), c (add 2 c))
503−```
504−
505−#### Battery
506−
507−Certain runes are used to create a core. Cores with multiple arms have a special syntax for defining each of the arms in the battery. A core has no fixed limit on the number of arms contained in its battery, so you must terminate core expressions with the `--` rune. Each arm in the battery is defined with three things: (1) a rune in the `+` family (e.g., `++`, `+*`, and `+$`), (2) an arm name, and (3) a subexpression defining the content of that arm. Runes in the `+` family may only go in core subexpressions. Putting them anywhere else results in a syntax error.
508−
509−Here's an example of a **battery** body:
510−
511−```
512−|%
513−++ arm-1
514− %p
515−++ arm-2
516− %q
517−++ arm-3
518− %r
519−--
520−```
521
305
522−## Motivation
306+## Reference Materials
523
307
524−There's no denying that Hoon's syntax is a bit strange, especially for those used to working in other programming languages. Hoon makes heavy use of ASCII characters, and this can be intimidating to newcomers. However, we believe that anyone who learns Hoon syntax will find that it has a number of advantages.
308+The Hoon syntax can be intimidating for the uninitiated, so it's good to remember where you can look up expressions can be found. The [reference section](/docs/reference/) itself is a good place to find the reference materials that you need. These children sections are likely to be useful:
525−
526−Hoon's syntax is designed to address three serious problems in functional syntax design. These problems are: (1) **terminator piles**, (2) **indentation creep**, and (3) **feature/label confusion**.
527−
528−### Terminator piles
529−
530−A **terminator pile** is a series of termination characters required to end some expression in a language. Think of Lisp's stacks of right parentheses. For a trivial example, let's say you want to add 22 five times in Lisp using `+`:
531−
532−```
533−(+ 22 (+ 22 (+ 22 (+ 22 22))))
534−```
535−
536−In a sufficiently complicated expression it's tedious to keep track of all the parentheses in the terminator pile. You can write terminator piles in Hoon code if you really want to:
537−
538−```
539−> (add 22 (add 22 (add 22 (add 22 22))))
540−110
541−```
542−
543−...but you are never forced to do so. There is always a semantically equivalent alternative syntax without them:
544−
545−```
546−> %+ add 22
547− %+ add 22
548− %+ add 22
549− %+ add 22 22
550−110
551−```
552
309
553−### Indentation creep
310+- The [Runes](/docs/reference/hoon-expressions/) page will show you how to use any Hoon rune.
311+- The [Cheat sheet](/docs/reference/cheat-sheet/) is a more compact place to look up rune expressions.
312+- The [Standard library](/docs/reference/library/) section has its sub-pages arranged by category. So arithmetic functions, for example, are all found on the same page.
313+- The [Hoon Style Guide](/docs/learn/hoon/style/) will show you how to write your Hoon code so that it's idiomatic and easily understood by others.
554
314
555−In some programming languages there is an indentation convention according to which an expression embedded within a parent expression is indented more to the right. In a sufficiently long and complicated function with many embedded subexpressions, the tendency is for the code to shift more and more to the right. This tendency is called **indentation creep**, and it can become an irritating problem when working with long functions. It's true that short functions are better, but long ones sometimes need to be written.
315+### Debugging
556
316
557−Ordinary indentation conventions give long functions a _diagonal_ shape, which is a poor fit for most editor windows. Because Hoon is designed to be written with 'backstep' indentation, the code flows _down_, not down and across.
317+When you have an error in your Hoon code, one of two things can happen. Either the code does not run at all and you get an error (such as `nest-fail`), or your code _does_ run but produces the wrong results. The [Troubleshooting](/docs/reference/troubleshooting/) page is a good resource for figuring out how to debug your code.
558
318
559−### Feature/label confusion
319+There are a couple useful runes associated with debugging:
560
320
561−A language lends itself to **feature/label confusion** (FLC) when it's difficult to distinguish general features of the language from labels in a particular program. This can be a serious problem other functional programming languages. In Lisp, for example, a user-defined macro has the same syntax as a function call.
321+`!:` (zapcol), if written at the top of a Hoon file, turns on a full debugging stack-trace. It's good practice to use whenever you're learning.
562
322
563−The worst-case result of FLC is "DSL cancer". Every source file with this malady is effectively written in its own domain-specific language (DSL). Learning to read such a file is like learning a language. One can also describe the result as "write-only code". User-level macros, operator overloading, and even excessive use of higher-order programming, can all lead quickly to the tragedy of write-only code.
323+`~&` (sigpam) is used to print its argument every time that argument executes. So, if you wanted to see how many times your program executed `foo`, you would write `foo bar`. Then, when your program runs, it will print `foo` on a new line of output every time the program comes across it by recursion.
564
324
565−Hoon largely avoids FLC by its use of runes. Hoon has no user-level macros or operator overloading. It does support higher-order programming; write-only Hoon can certainly be (and has been) written. However, with a little discipline one can write Hoon without inventing a DSL.
325+But there are more. Check out the aforementioned [troubleshooting](/docs/reference/troubleshooting/) page to see other handy debugging runes and how to use them.
566
326
567−### [Next Lesson: Simple One-Gate Programs](./docs/learn/hoon/hoon-tutorial/simple-one-gate-programs.md)
327+### [Next Lesson: The Subject and Its Legs](./docs/learn/hoon/hoon-tutorial/simple-one-gate-programs.md)
learn/hoon/hoon-tutorial/recursion.mdnew file+193
@@ -0,0 +1,193 @@
1++++
2+title = "Recursion"
3+weight = 0
4+template = "doc.html"
5++++
6+
7+Recursion is a common pattern for solving certain problems in most programming
8+languages, and Hoon is no exception. One of the classically recursive problems
9+is that of factorial. The factorial of _n_ is the product of all positive
10+integers less than or equal to N. Thus the factorial of 5, denoted as _5!_,
11+would be:
12+
13+```
14+5 * 4 * 3 * 2 * 1 = 120
15+```
16+
17+### Factorial In Hoon
18+
19+Let's implement a factorial calculator in Hoon. To do so, we'll write a
20+recursive `gate` (Hoon's equivalent of a function) to perform the relevant
21+computation. Save the code below as `factorial.hoon` in your ship's `/gen`
22+directory.
23+
24+```
25+|= n=@ud
26+?: =(n 1)
27+ 1
28+(mul n $(n (dec n)))
29+```
30+
31+Our `gate` takes one sample (argument) `n` that must nest inside `@ud`, the
32+unsigned-integer type.
33+
34+Next we check to see if `n` is `1`. If so, the result is just `1`, since
35+`1 * 1 = 1`.
36+
37+If, however, `n` is _not_ `1`, then we branch to the final line of the code,
38+`(mul n $(n (dec n)))`, where the recursion logic lives. Here, we multiply `n`
39+by the recursion of `n` minus `1`. `$` initiates recursion: it calls the gate
40+that we're already in, but replaces its sample.
41+
42+In our example, we multiply `n` with the product of this _entire gate
43+all over again_ with `$(n (dec n))`, except when that new gate has its sample
44+decremented by one. This works recursively because each new gate will, of
45+course, itself contain the code to call a further-decremented gate. Gates will
46+continue to call new, further-decremented gates until `n` is `1`, and that `1`
47+will be the final number to be multiplied by.
48+
49+Let's run the program in the Dojo:
50+
51+```
52+> +factorial 5
53+120
54+```
55+
56+It may help to visualize the operation of our example gate. The pseudo-Hoon below
57+illustrates what happens when we use it to find the factorial of 5:
58+
59+```
60+(factorial 5)
61+(mul 5 (factorial 4))
62+(mul 5 (mul 4 (factorial 3)))
63+(mul 5 (mul 4 (mul 3 (factorial 2))))
64+(mul 5 (mul 4 (mul 3 (mul 2 (factorial 1)))))
65+(mul 5 (mul 4 (mul 3 (mul 2 1))))
66+(mul 5 (mul 4 (mul 3 2)))
67+(mul 5 (mul 4 6))
68+(mul 5 24)
69+120
70+```
71+
72+It's easy to see how we're "floating" gate calls until we reach the final
73+iteration of such calls that only produces a value. The `mul n` component of the
74+gate leaves something like `mul 5`, waiting for the final series of terms
75+to be operated upon. The `$(n (dec n))` component is what expands out the
76+expression, as illustrated by `(factorial 4)`. Once the expression cannot be
77+expanded out further, the operations work backwards, successively feeding values
78+into the `mul` functions behind them.
79+
80+##### Tail-Call Optimization
81+
82+Our last example isn't a very efficient use computing resources. The
83+pyramid-shaped illustration approximates what's happening on the **call stack**, a
84+memory structure that tracks the instructions of the program. In our example
85+code, every time a parent gate calls another gate, the gate being called is
86+"pushed" to the top of the stack in the form of a frame. This process continues
87+until a value is produced instead of a function, completing the stack.
88+
89+```
90+ Push order Pop order
91+(fifth frame) ^ |
92+(fourth frame) | |
93+(third frame) | |
94+(second frame) | |
95+(first frame) | V
96+```
97+
98+Once this stack of frames is completed, frames "pop" off the stack starting at
99+the top. When a frame is popped, it executes the contained gate and passes
100+produced data to the frame below it. This process continues until the stack
101+is empty, giving us the gate's output.
102+
103+When a program's final expression uses the stack in this way, it's considered to
104+be **not tail-recursive**. This usually happens when the last line of executable
105+code calls more than one gate, our example code's `(mul n $(n (dec n)))` being
106+such a case. That's because such an expression needs to hold each iteration of
107+`$(n (dec n)` in memory so that it can know what to run against the `mul`
108+function every time.
109+
110+To reiterate: if you have to manipulate the result of a recursion as the last
111+expression of your gate, as we did in our example, the function is not
112+tail-recursive, and therefore not very efficient with memory. A problem arises
113+when we try to recurse more times that we have space on the stack. This will
114+result in our computation failing and producing a stack overflow. If we tried
115+to find the factorial of `5.000.000`, for example, we would almost certainly
116+run out of stack space.
117+
118+But the Hoon compiler, like most compilers, is smart enough to notice when the
119+last statement of a parent can reuse the same frame instead of needing to
120+add new ones onto the stack. If we write our code properly, we can use a single
121+frame that simply has its values replaced with each recursion.
122+
123+##### A Tail-Recursive Gate
124+
125+With a bit of refactoring, we can write a version of our factorial gate that
126+_is_ tail-recursive and can take advantage of this feature:
127+
128+```
129+|= n=@ud
130+=/ t=@ud 1
131+|-
132+?: =(n 1)
133+ t
134+$(n (dec n), t (mul t n))
135+```
136+
137+The above code should look familiar. We are still building a gate that
138+takes one argument `n`. This time, however, we are also putting a face on a
139+`@ud` and setting it's initial value to 1. The `|-` here is used to create a new
140+gate with one arm `$` and immediately call it. Think of `|-` as the recursion
141+point.
142+
143+We then evaluate `n` to see if it is 1. If it is we return the value of `t`. In
144+the case that `n` is anything other than 1, we perform our recursion:
145+
146+```
147+$(n (dec n), t (mul t n))
148+```
149+
150+All we are doing here is recursing our new gate and modifying the values of `n`
151+and `t`. `t` is used as an accumulator variable that we use to keep a running
152+total for the factorial computation.
153+
154+Let's use pseudo-Hoon to illustrate how the stack is working in this example for
155+factorial 5.
156+
157+```
158+(factorial 5)
159+(|- 5 1)
160+(|- 4 5)
161+(|- 3 20)
162+(|- 2 60)
163+(|- 1 120)
164+120
165+```
166+
167+We simply multiply `t` and `n` to produce the new value of `t`, and then
168+decrement `n` before repeating. Since this `$` call is the final and solitary
169+thing that is run in the default case and since we are doing all computation
170+before the call, this version is properly tail-recursive. We don't need to do
171+anything to the result of the recursion except recurse it again. That means that
172+each iteration can be replaced instead of held in memory.
173+
174+##### A Note on `$`
175+
176+`$` (pronounced "buc") is, in its use with recursion, a reference to the gate that we are inside
177+of. That's because a gate is just a core with a single arm named `$`. The
178+subject is searched depth-first, head before tail, with faces skipped, and
179+stopping on the first result. In other words, the first match found in the head
180+will be returned. If you wished to refer to the outer `$` in this context, the
181+idiomatic way would be to use [`^$`](/docs/reference/rune/ket). The `^` operator
182+skips the first match of a name.
183+
184+### Exercises
185+
186+1. Write a recursive gate that produces the first _n_
187+[Fibonacci numbers](https://en.wikipedia.org/wiki/Fibonacci_number)
188+
189+2. Write a recursive gate that produces a list of moves to solve the
190+[Tower of Hanoi problem](https://en.wikipedia.org/wiki/Tower_of_Hanoi).
191+Disks are stacked on a pole by decreasing order of size. Move all of the
192+disks from one pole to another with a third pole as a spare, moving one
193+disc at a time, without putting a larger disk on top of a smaller disk.
learn/hoon/workbook/ackermann.mdnew file+18
@@ -0,0 +1,18 @@
1+Write a gate to compute [Ackermann's Function](https://en.wikipedia.org/wiki/Ackermann_function)
2+
3+```
4+|= [m=@ n=@]
5+?~ m +(n)
6+?~ n $(m (dec m), n 1)
7+$(m (dec m), n $(n (dec n)))
8+```
9+
10+Ackermann Function is one of the earliest examples of a function that is totally computable, meaning it can be solved, but is not primitive recursive, meaning it can not be rewritten in an iterative fashion.
11+
12+Our gate takes two argument, `m` and `n`. There are three cases.
13+
14+First, if `m` is zero, return the increment of `n`.
15+Second, if `n` is zero, decrement `m`, set `n` to 1 and recurse.
16+Else, decrement `m` and set `n` to be the value of the Ackermann function with `n` and the decrement of `n` as arguments.
17+
18+This is not a terribly useful function to compute but it has an interesting history in mathematics. When running this function the value grows rapidly even for very small input. The value of computing this where `m` is `4` and `n` is `2` is an integer with 19,729 digits.
learn/hoon/workbook/bank.mdnew file+79
@@ -0,0 +1,79 @@
1++++
2+title = "Bank Account"
3+weight = 0
4+template = "doc.html"
5++++
6+
7+Write a door that can act as a bank account with the ability to withdraw, deposit, and check the balance.
8+
9+```
10+:- %say
11+|= *
12+:- %noun
13+=< =~ new-account
14+ (deposit 100)
15+ (deposit 100)
16+ (withdraw 50)
17+ balance
18+ ==
19+|%
20+++ new-account
21+ |_ balance=@ud
22+ ++ deposit
23+ |= amount=@ud
24+ +>.$(balance (add balance amount))
25+ ++ withdraw
26+ |= amount=@ud
27+ +>.$(balance (sub balance amount))
28+ --
29+--
30+```
31+
32+We start with the three lines we have in every `%say` generator.
33+
34+```
35+:- %say
36+|= *
37+:- %noun
38+```
39+
40+We're creating a cell the head of which is a `%say` and the tail of which is a gate that produces a cell with a head of the mark of the kind of data we are going to produce.
41+
42+```
43+=< =~ new-account
44+ (deposit 100)
45+ (deposit 100)
46+ (withdraw 50)
47+ balance
48+ ==
49+```
50+
51+Here we're going to compose two runes using `=<` which has inverted arguments. We use this rune to keep the heaviest twig to the bottom of the code.
52+
53+`=~` is a rune that composes multiple expressions. We take `new-account` and use that as the subject for the call to `deposit`. `deposit` and `withdraw` both produce a new version of the door which is used in subsequent calls which is why we are able to chain them in this fashion, the final reference is to `balance` which is the balance contain in the core we are about to examine.
54+
55+```
56+|%
57+++ new-account
58+ |_ balance=@ud
59+ ++ deposit
60+ |= amount=@ud
61+ +>.$(balance (add balance amount))
62+ ++ withdraw
63+ |= amount=@ud
64+ +>.$(balance (sub balance amount))
65+ --
66+--
67+```
68+
69+We've chosen here to wrap our door in it's own core to emulate the style of programming that is used when creating libraries. `new-account` is the name of our door. Recall that a door is a core with one or more arms that has a sample. Here our door has a sample of one `@ud` with the face `balance` and two arms, `deposit` and `withdraw`.
70+
71+Each of these arms produces a gate which takes an `@ud` argument. Each of these gates has a similar bit of code inside.
72+
73+```
74++>.$(balance (add balance amount))
75+```
76+
77+With wing syntax remember that we're looking for `+>`, or the 3rd element, out of `$`, which is to say the subject of the gate we are in, which is the entire `new-account` door. We change `balance` to be the result of adding `balance` and `amount` and produce the door as the result. `withdraw` functions the same way only doing subtraction instead of addition.
78+
79+The important point to notice here is that the sample, `balance`, is stored as part of the door rather than existing outside of it.
weights.shnew file+23
@@ -0,0 +1,23 @@
1+#!/bin/bash
2+
3+EDITOR=${EDITOR:-atom}
4+
5+# build weights file
6+for file in $(find -type f -name \*.md); do
7+ [[ $file == *_index.md ]] && continue
8+ echo $(grep -m 1 "weight = " $file | sed 's/^weight = //') $file
9+done | sort -n > weights
10+
11+# edit weights file
12+$EDITOR weights
13+read -p "Edit weights and press enter to continue..."
14+
15+# for each line in weights file, read values weight and file, and update
16+# $weight in $file
17+cat weights | while read weight file; do
18+ echo $weight $file
19+ sed -i'' "s/^weight = [.0-9]*/weight = $weight/" $file
20+done
21+
22+# remove weights file
23+rm weights