@@ -0,0 +1,200 @@
10+Recursion is a common pattern for solving certain problems in most programming
11+languages, and Hoon is no exception. One of the classically recursive problems
12+is that of factorial. The factorial of _n_ is the product of all positive
13+integers less than or equal to N. Thus the factorial of 5, denoted as _5!_,
17+5 * 4 * 3 * 2 * 1 = 120
22+Let's implement a factorial calculator in Hoon. To do so, we'll write a
23+recursive `gate` (Hoon's equivalent of a function) to perform the relevant
24+computation. Save the code below as `factorial.hoon` in your ship's `/gen`
34+Our `gate` takes one sample (argument) `n` that must nest inside `@ud`, the
35+unsigned-integer type.
37+Next we check to see if `n` is `1`. If so, the result is just `1`, since
40+If, however, `n` is _not_ `1`, then we branch to the final line of the code,
41+`(mul n $(n (dec n)))`, where the recursion logic lives. Here, we multiply `n`
42+by the recursion of `n` minus `1`. `$` initiates recursion: it calls the gate
43+that we're already in, but replaces its sample.
45+In our example, we multiply `n` with the product of this _entire gate
46+all over again_ with `$(n (dec n))`, except when that new gate has its sample
47+decremented by one. This works recursively because each new gate will, of
48+course, itself contain the code to call a further-decremented gate. Gates will
49+continue to call new, further-decremented gates until `n` is `1`, and that `1`
50+will be the final number to be multiplied by.
52+Let's run the program in the Dojo:
59+It may help to visualize the operation of our example gate. The pseudo-Hoon below
60+illustrates what happens when we use it to find the factorial of 5:
65+(mul 5 (mul 4 (factorial 3)))
66+(mul 5 (mul 4 (mul 3 (factorial 2))))
67+(mul 5 (mul 4 (mul 3 (mul 2 (factorial 1)))))
68+(mul 5 (mul 4 (mul 3 (mul 2 1))))
69+(mul 5 (mul 4 (mul 3 2)))
75+It's easy to see how we're "floating" gate calls until we reach the final
76+iteration of such calls that only produces a value. The `mul n` component of the
77+gate leaves something like `mul 5`, waiting for the final series of terms
78+to be operated upon. The `$(n (dec n))` component is what expands out the
79+expression, as illustrated by `(factorial 4)`. Once the expression cannot be
80+expanded out further, the operations work backwards, successively feeding values
81+into the `mul` functions behind them.
83+##### Tail-Call Optimization
85+Our last example isn't a very efficient use computing resources. The
86+pyramid-shaped illustration approximates what's happening on the *call stack*, a
87+memory structure that tracks the instructions of the program. In our example
88+code, every time a parent gate calls another gate, the gate being called is
89+"pushed" to the top of the stack in the form of a frame. This process continues
90+until a value is produced instead of a function, completing the stack.
101+Once this stack of frames is completed, frames "pop" off the stack starting at
102+the top. When a frame is popped, it executes the contained gate and passes
103+produced data to the frame below it. This process continues until the stack
104+is empty, giving us the gate's output.
106+When a program's final expression uses the stack in this way, it's considered to
107+be *not tail-recursive*. This usually happens when the last line of executable
108+code calls more than one gate, our example code's `(mul n $(n (dec n)))` being
109+such a case. That's because such an expression needs to hold each iteration of
110+`$(n (dec n)` in memory so that it can know what to run against the `mul`
113+To reiterate: if you have to manipulate the result of a recursion as the last
114+expression of your gate, as we did in our example, the function is not
115+tail-recursive, and therefore not very efficient with memory. A problem arises
116+when we try to recurse more times that we have space on the stack. This will
117+result in our computation failing and producing a stack overflow. If we tried
118+to find the factorial of `5.000.000`, for example, we would almost certainly
119+run out of stack space.
121+But the Hoon compiler, like most compilers, is smart enough to notice when the
122+last statement of a parent can reuse the same frame instead of needing to
123+add new ones onto the stack. If we write our code properly, we can use a single
124+frame that simply has its values replaced with each recursion.
126+##### A Tail-Recursive Gate
128+With a bit of refactoring, we can write a version of our factorial gate that
129+_is_ tail-recursive and can take advantage of this feature:
137+$(n (dec n), t (mul t n))
140+The above code should look familiar. We are still building a gate that
141+takes one argument `n`. This time, however, we are also putting a face on a
142+`@ud` and setting it's initial value to 1. The `|-` here is used to create a new
143+gate with one arm `$` and immediately call it. Think of `|-` as the recursion
146+We then evaluate `n` to see if it is 1. If it is we return the value of `t`. In
147+the case that `n` is anything other than 1, we perform our recursion:
150+$(n (dec n), t (mul t n))
153+All we are doing here is recursing our new gate and modifying the values of `n`
154+and `t`. `t` is used as an accumulator variable that we use to keep a running
155+total for the factorial computation.
157+Let's use pseudo-Hoon to illustrate how the stack is working in this example for
170+We simply multiply `t` and `n` to produce the new value of `t`, and then
171+decrement `n` before repeating. Since this `$` call is the final and solitary
172+thing that is run in the default case and since we are doing all computation
173+before the call, this version is properly tail-recursive. We don't need to do
174+anything to the result of the recursion except recurse it again. That means that
175+each iteration can be replaced instead of held in memory.
179+`$` (pronounced "buc") is, in its use with recursion, a reference to the gate that we are inside
180+of. That's because a gate is just a core with a single arm named `$`. The
181+subject is searched depth-first, head before tail, with faces skipped, and
182+stopping on the first result. In other words, the first match found in the head
183+will be returned. If you wished to refer to the outer `$` in this context, the
184+idiomatic way would be to use [`^$`](/docs/reference/rune/ket). The `^` operator
185+skips the first match of a name.
187+The syntax used is also the irregular form of the `%=` rune.
191+1. Write a recursive gate that produces the first _n_
192+[Fibonacci numbers](https://en.wikipedia.org/wiki/Fibonacci_number)
194+2. Write a recursive gate that produces a list of moves to solve the
195+[Tower of Hanoi problem](https://en.wikipedia.org/wiki/Tower_of_Hanoi).
196+Disks are stacked on a pole by decreasing order of size. Move all of the
197+disks from one pole to another with a third pole as a spare, moving one
198+disc at a time, without putting a larger disk on top of a smaller disk.
200+### [Next Lesson: Multi-gate Cores and Doors](../multi-gate-cores-and-doors)