@@ -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.