@@ -1,158 +0,0 @@
1−+++
2−title = "Magic 8-Ball"
3−weight = 5
4−template = "doc.html"
5−aliases = ["docs/learn/hoon/workbook/eightball"]
6−+++
7−In this lesson we'll write a generator that mimics the functionality of a
8−Magic 8-Ball, producing a randomized response with each run.
9−
10−Save the code below as `eightball.hoon` in your `/gen` directory.
11−
12−```hoon
13−!:
14−:- %say
15−|= [[* eny=@uv *] *]
16−:- %noun
17−^- tape
18−=/ answers=(list tape)
19− :~ "It is certain."
20− "It is decidedly so."
21− "Without a doubt."
22− "Yes - definitely."
23− "You may rely on it."
24− "As I see it, yes."
25− "Most likely."
26− "Outlook good."
27− "Yes."
28− "Signs point to yes."
29− "Reply hazy, try again"
30− "Ask again later."
31− "Better not tell you now."
32− "Cannot predict now."
33− "Concentrate and ask again."
34− "Don't count on it."
35− "My reply is no."
36− "My sources say no."
37− "Outlook not so good."
38− "Very doubtful."
39− ==
40−=/ rng ~(. og eny)
41−=/ val (rad:rng (lent answers))
42−(snag val answers)
43−```
44−
45−Let's go through our code in chunks so that we might more easily understand it.
46−
47−```hoon
48−!:
49−```
50−
51−We start with the `!:` rune to enable a full stack trace for any errors. This
52−is good practice whenever developing something in Hoon.
53−
54−
55−```hoon
56−:- %say
57−|= [[* eny=@uv *] *]
58−:- %noun
59−```
60−
61−To make our program produce a random result, we need entropy. To get entropy,
62−we need data from Arvo. To get data from Arvo, we use a generator of the
63−[`%say`](@/docs/hoon/hoon-school/generators.md) variety. The above code chunk is
64−the template that is followed for all `%say` generators.
65−
66−`:- %say` creates a cell with `%say` as that cell's head to define
67−the generator's format.
68−
69−`|= [[* eny=@uv *] *]` is the tail of the cell, a [gate](/docs/glossary/gate/), and that gate's first
70−child, a sample. Because the only external data our program is interested in
71−using is entropy to seed our random-number generator, that's the only one we
72−will assign a face (`eny`). The `*` elements that you see represent any [noun](/docs/glossary/noun/). We
73−use these as fillers: because we don't wish to use the data that's passed to
74−those parts of the sample, we don't assign them faces.
75−
76−`:- %noun` creates another cell, itself residing in the tail of our first cell
77−via our gate expression. In all `%say` generators, the head of this second cell
78−is a `mark` that's used to tell Arvo what kind of data the generator is
79−producing. In this case, we are using the `%noun` `mark` to tell the system how
80−to print the generator's outputted value. The tail of this cell is that value
81−itself, produced by the rest of our program.
82−
83−```hoon
84−^- tape
85−```
86−
87−Above is a cast statement that requires the non-`mark` component of our cell to
88−be of the `tape` type. If it's not, the program doesn't compile.
89−
90−```hoon
91−=/ answers=(list tape)
92− :~ "It is certain."
93− "It is decidedly so."
94− "Without a doubt."
95− "Yes - definitely."
96− "You may rely on it."
97− "As I see it, yes."
98− "Most likely."
99− "Outlook good."
100− "Yes."
101− "Signs point to yes."
102− "Reply hazy, try again"
103− "Ask again later."
104− "Better not tell you now."
105− "Cannot predict now."
106− "Concentrate and ask again."
107− "Don't count on it."
108− "My reply is no."
109− "My sources say no."
110− "Outlook not so good."
111− "Very doubtful."
112− ==
113−```
114−
115−The code in the chunk above constructs the list of possible responses.
116−
117−`=/ answers=(list tape)` is used to put add data to the subject with a face,
118−so that we can easily use it later. The face is `answers`, and we designate that
119−its accompanying value will be a `list` of `tape`. The value itself is given
120−as a `list` in the lines that follow.
121−
122−`:~` is a rune that constructs a null-terminated list. Here we have used the
123−tall form for readability, as an alternative to the wide form of `~[1 2 3]` that
124−you may be more familiar with.
125−
126−Contained within the `:~` rune are the elements of the list. In our case, those
127−elements are the `tape`s that are selected as the 8-Ball's responses.
128−
129−`==` terminates our list. `:~` expressions are always closed in this way.
130−
131−```hoon
132−=/ rng ~(. og eny)
133−=/ val (rad:rng (lent answers))
134−```
135−
136−The code above is our random-number engine.
137−
138−`og` is the [core](/docs/glossary/core/) in the standard library that contains [arms](/docs/glossary/arm/) that perform
139−randomness-related operations. `=/ rng ~(. og eny)` passes `eny` to the
140−subject of `og`, and then stores the resulting core in a face called `rng`.
141−
142−`=/ val (rad:rng (lent answers))` uses `rad` arm. `rad` produces a random
143−number from `0` to `n-1`, where `n` the entropy-seeded `rng` core and pulls.
144−Is the upper bound that we give it. In this case, the upper bound is the number
145−of elements in `answers`, obtained by using the `lent` standard-library arm. We
146−store the random result in `val`.
147−
148−```hoon
149−(snag val answers)
150−```
151−
152−`snag` is a standard-library arm that that takes two arguments: an [atom](/docs/glossary/atom/) and
153−a `list`. It fetches the element in position `n` of the list, where `n` is the
154−value of the atom it was passed. By using the randomized `val` as that position
155−argument, we can pull a different response from `answers` every time the
156−generator is run.
157−
158−TODO (rob): Exercises here.