on master help sign in
remove unmaintained hoon workbook
987cb5eJosh Lehman
hoon/hoon-school/workbook/_index.mddeleted−17
@@ -1,17 +0,0 @@
1−+++
2−title = "Hoon Workbook"
3−weight = 150
4−sort_by = "weight"
5−template = "sections/docs/chapters.html"
6−aliase = ["docs/learn/hoon/workbook/"]
7−+++
8−The Workbook is the place to sharpen your Hoon skills. Each entry in the
9−Workbook is a code walkthrough followed by exercises.
10−
11−- The [Digits](@/docs/hoon/hoon-school/workbook/digits.md) example demonstrates how to decompose a number into a list of its digits.
12−
13−- The [Magic 8-Ball](@/docs/hoon/hoon-school/workbook/eightball.md) example emulates everyone's favorite decision-making machine.
14−
15−- The [Traffic-light](@/docs/hoon/hoon-school/workbook/traffic-light.md) example demonstrates how to creates a state machine in Hoon.
16−
17−- The [Bomb-defusing](@/docs/hoon/hoon-school/workbook/bomb.md) exercise shows how to program, well, a bomb-defusing scenario.
hoon/hoon-school/workbook/bomb.mddeleted−140
@@ -1,140 +0,0 @@
1−+++
2−title = "Bomb Defusing"
3−weight = 7
4−template = "doc.html"
5−aliases = ["docs/learn/hoon/workbook/bomb"]
6−+++
7−In this exercise, we will build a generator that takes a list of wires to be cut
8−in order to defuse a bomb. The bomb is defused according to the following rules.
9−
10−There are 6 possible colors of wire: white, black, purple, red, green, and
11−orange.
12−
13−If you cut a white cable, you cannot cut white or black cable.
14−
15−If you cut a red cable, you must cut a green cable.
16−
17−If you cut a black cable, you cannot cut a white, green, or orange cable.
18−
19−If you cut an orange cable, you must cut a red or cable.
20−
21−If you cut a green cable, you must cut an orange or white cable.
22−
23−If you cut a purple cable, you cannot cut a purple, green, orange, or white
24−cable.
25−
26−If the list of cuts does not result in the bomb exploding, the output should be
27−a tape `bomb defused`. If any of the rules were broken, it should output the
28−tape `boom`.
29−
30−
31−```hoon
32−!:
33−:- %say
34−|= [* [cuts=(list tape) ~] ~]
35−:- %noun
36−=<
37−(defuse cuts)
38−|%
39−++ defuse
40− |= cuts=(list tape)
41− =| bad=(list tape)
42− |-
43− ?~ cuts
44− "bomb defused"
45− =/ cut i.cuts
46− ?~ bad
47− $(bad (~(got by rules) cut), cuts t.cuts)
48− ?~ (find [cut ~] bad)
49− $(bad (~(got by rules) cut), cuts t.cuts)
50− "boom"
51−++ rules
52− %- ~(gas by *(map tape (list tape)))
53− :~ :- "white"
54− :~ "white"
55− "black"
56− ==
57− :- "red"
58− :~ "white"
59− "red"
60− "black"
61− "orange"
62− "purple"
63− ==
64− :- "black"
65− :~ "white"
66− "green"
67− "orange"
68− ==
69− :- "orange"
70− :~ "white"
71− "orange"
72− "green"
73− "purple"
74− ==
75− :- "green"
76− :~ "red"
77− "black"
78− "green"
79− "purple"
80− ==
81− :- "purple"
82− :~ "purple"
83− "green"
84− "orange"
85− "white"
86− ==
87− ==
88−--
89−```
90−
91−The start of our generator is simple enough. The `!:` in the first line enables
92−a full stack trace in the event of an error. The following three lines create a
93−`%say` generator that takes a list of tape as an argument.
94−
95−We next use the `=<` rune to compose two hoons, inverted. Remember that it's
96−good Hoon style is to have the heaviest parts to the bottom -- that's what we're
97−doing here.
98−
99−We call `defuse` and pass it `cuts`, the list of tapes we were provided with
100−when the generator started.
101−
102−Next is the [core](/docs/glossary/core/) that has two [arms](/docs/glossary/arm/), `defuse` and `rules`. Let's look at `rules`
103−quickly.
104−
105−We can see that it is a `map` of `tape` to `list` of `tape`. For each of the
106−rules above we have specified when you cut a wire, which of the other wires you
107−cannot cut. This required some reformulating of the rules given to use at the
108−start, but it is much simpler to work with.
109−
110−```hoon
111−++ defuse
112− |= cuts=(list tape)
113− =| bad=(list tape)
114− |-
115− ?~ cuts
116− "bomb defused"
117− =/ cut i.cuts
118− ?~ bad
119− $(bad (~(got by rules) cut), cuts t.cuts)
120− ?~ (find [cut ~] bad)
121− $(bad (~(got by rules) cut), cuts t.cuts)
122− "boom"
123−```
124−
125−The `defuse` arm is the meat of our program. It is a `gate` that takes a `list`
126−of `tape`. We combine a defaulted `list` of `tape` with the face `bad` with the
127−subject.
128−
129−If `cuts` is empty, the bomb has been successfully defused.
130−
131−Otherwise, we give `i.cuts`, the first item in the list, a face called `cut`.
132−
133−If `bad` is empty, we recurse. This recursion sets `bad` to be the list of
134−wires we can not cut from the `rules` map and make `cuts` `t.cuts` or the tail
135−of `cuts`, removing the first element of the list.
136−
137−If `bad` is not empty, we want to search inside of it for the current `cut`. If
138−it's not listed, then we are safe to continue and recurse to process the rest of
139−the cuts. However, if it is found in the bad list, the user has failed and the
140−bomb explodes.
hoon/hoon-school/workbook/digits.mddeleted−113
@@ -1,113 +0,0 @@
1−+++
2−title = "Digits"
3−weight = 4
4−template = "doc.html"
5−aliases = ["docs/learn/hoon/workbook/digits/"]
6−+++
7−Let's write a generator that takes a `@ud` (unsigned decimal) and returns a list
8−of its digits.
9−
10−```hoon
11−!:
12−:- %say
13−|= [* [n=@ud ~] ~]
14−:- %noun
15−=| lis=(list @ud)
16−|- ^+ lis
17−?: (lte n 0)
18− lis
19−%= $
20− n (div n 10)
21− lis (mod n 10)^lis
22−==
23−```
24−
25−We're creating a [`%say` generator](@/docs/hoon/hoon-school/generators.md). That means we
26−need some "boilerplate" code in the format of `[%say [%noun "data"]]`:
27−
28−```hoon
29−:- %say
30−|= [* [n=@ud ~] ~]
31−:- %noun
32−```
33−
34−The head of this cell is the literal `%say`.
35−
36−In the tail is the [gate](/docs/glossary/gate/) and its sample: `|= [* [n=@ud ~] ~]`. This is
37−where we describe any arguments we are expecting to be passed in when the
38−generator is called. We are expecting data of type `@ud`. We give the data the
39−face `n` so that we can easily reference it later.
40−
41−Also in the tail is another `cell`, its head indicating to the `dojo` how to
42−print the value we are creating. In this case, we use the generic `%noun`.
43−
44−The tail of our second cell is the product of the rest of the program.
45−
46−```hoon
47−=| lis=(list @ud)
48−```
49−
50−We use the above code to construct a `list` of `@ud` by cutting up the `@ud` we
51−got passed and so we add a face onto that type. This list is empty until we
52−manipulate it further.
53−
54−```hoon
55−|- ^+ lis
56−?: (lte n 0)
57− lis
58−```
59−
60−`|-` creates a gate that functions as a recursion point.
61−
62−We are actually able to reuse `lis` for the type of output that we are going
63−to produce. A sibling of the `^-` rune, `^+` is distinct because it is for
64−casting _by example_. It takes type information from an _instance_ of that type.
65−It's useful when using a complicated type.
66−
67−```hoon
68−?: (lte n 0)
69− lis
70−```
71−
72−`?:` checks if the statement that follows is true or false. In our case, if it's
73−true that `n` is less than or equal to `0`, we simply return `lis`. Otherwise,
74−we branch to the following operations:
75−
76−```hoon
77−%= $
78− n (div n 10)
79− lis (mod n 10)^lis
80−==
81−```
82−
83−`%=` is the rune that takes a wing with any number changes, in the
84−form of a list. Our list has two elements that represent such changes, contained
85−in a `$` expression to perform recursion. This is the tall form of an equivalent
86−syntax that you may be more familiar with:
87−`$(n (div n 10), lis (mod n 10)^lis)`.
88−
89−The first change divides `n` by `10`, rounding down without a remainder, and
90−assigning that product as the new value for `n`.
91−
92−The second change prepends the remainder of `n` divided `10` to `lis` (`x^y` is
93−an alternative syntax for `[x y]`). `mod` performs the modulo operation.
94−
95−Together, these operations will pull each digit out of `n` and put it into a
96−`list`. That's because dividing `n` by 10 will knock off one decimal place from
97−the value, and `mod` will store the actual discarded digit. To visualize this
98−complementarity, let's run some operations in the dojo:
99−
100−```hoon
101−> (div 146 10)
102−14
103−
104−> (mod 146 10)
105−6
106−```
107−
108−* TODO What if we do this with vases? Can we accept a vase, map it to whatever
109−the correct value would be to extract each digit of the number in whatever base
110−we are interpreting it in?
111−
112−* TODO from Rob: we need a few exercises here. Maybe asking the reader to
113−make one that accepts a vase could be one?
hoon/hoon-school/workbook/eightball.mddeleted−158
@@ -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.
hoon/hoon-school/workbook/traffic-light.mddeleted−155
@@ -1,155 +0,0 @@
1−+++
2−title = "Traffic Light"
3−weight = 6
4−template = "doc.html"
5−aliases = ["docs/learn/hoon/workbook/traffic-light/"]
6−+++
7−Let's create a state machine in Hoon that models the functionality of a traffic
8−light. Save the code below as `traffic.hoon` in your `/gen` directory.
9−
10−```hoon
11−:- %say
12−|= *
13−:- %noun
14−=+ |%
15− ++ state ?(%red %yellow %green)
16− --
17−=/ current-state=state %red
18−=+ ^= traffic-light
19− |%
20− ++ look current-state
21− ++ set
22− |= s=state
23− +>.$(current-state s)
24− --
25−=+ a=traffic-light
26−=+ b=traffic-light
27−=. a (set.a %yellow)
28−[current-state.a current-state.b]
29−```
30−
31−Let's look at the code piece-by-piece.
32−
33−```hoon
34−:- %say
35−|= *
36−:- %noun
37−```
38−
39−Here's the boilerplate code to designate our generator as being a
40−[`%say` generator](@/docs/hoon/hoon-school/generators.md). We're using this variant because
41−it allows us to run the generator without any arguments. It's otherwise not
42−relevant to the functionality of our program.
43−
44−```hoon
45−=+ |%
46− ++ state ?(%red %yellow %green)
47− --
48−```
49−
50−`=+` adds a [noun](/docs/glossary/noun/) to the subject. In our case, the [noun](/docs/glossary/noun/) in question is the [core](/docs/glossary/core/)
51−that is opened with `|%` and closed with `--`. This core is used to store types,
52−and does that with the [arm](/docs/glossary/arm/) that it contains.
53−
54−`++ state` creates an arm called `state`, which will be used as the name of the
55−new type that is created in the code that follows, `?(%red %yellow %green)`.
56−That following code creates a new type from the union of its elements. In this
57−case, the state can be one of three values: `%red`, `%yellow`, or `%green`
58−corresponding to the three colors of a standard traffic light.
59−
60−Having new types in a separate core is a common idiom in Hoon programs that allows
61−the compiler to do [constant folding](https://en.wikipedia.org/wiki/Constant_folding),
62−which improves performance.
63−
64−```hoon
65−=/ current-state=state %red
66−```
67−
68−The line above creates a noun of type `state` - the type that we created with
69−the arm in previous code chunk - and gives it a default value. Because we are
70−putting this noun into the subject, it will be available for use in the
71−`traffic-light` core we are about to create.
72−
73−```hoon
74−=+ ^= traffic-light
75− |%
76− ++ look current-state
77− ++ set
78− |= s=state
79− +>.$(current-state s)
80− --
81−```
82−
83−`=+ ^= traffic-light` does two things. The `^=` rune assigns a face to that
84−noun so it's easier to reference. The `=+` rune adds a noun to the subject, in
85−this case the core that we just assigned a name and start to build on the next
86−line and assigned the name.
87−
88−With `|%`, we are finally at the meat of the program. This core that we just
89−named has two arms: `look`, which gives us the current state, defined later; and
90−`set`, which gives us a simple way to modify the value of `current-state`.
91−
92−The [gate](/docs/glossary/gate/) we are producing with `|=` may look a bit strange, so let's break it
93−down.
94−
95−`s=state` allows for an argument of type `state` and gives it a face `s`.
96−
97−We first produce a core with one arm named `$`. That `$` arm will produce a new
98−core with `current-state` changed to match the `s` provided when it was called.
99−How does this work?
100−
101−Remember that `.` is [wing syntax](@/docs/hoon/reference/limbs/wing.md) that
102−applies the wing expression on the left of it to the noun to the right of it.
103−`$` is the arm of the core. Then by using the wing expression `+>`, which means
104−"return the tail of the tail", we traverse the subject to the core to latch onto
105−its parent core. where we defined the arms `look` and `set`. The `( )` then
106−lists changes to the core we would like to make as we produce a new one. You
107−will often see `+>.$` used in this way.
108−
109−```hoon
110−=+ a=traffic-light
111−=+ b=traffic-light
112−```
113−
114−Now we have the last parts of our program. Remember that `=+` allows us to add a
115−noun to the head of the subject. In this case, we are adding two nouns, one with
116−the face `a` and a second with the face `b`. These two nouns will be copies of
117−the `traffic-light` core, with all the bits we previously created.
118−
119−```hoon
120−=. a (set.a %yellow)
121−```
122−
123−`=.` changes a leg in the subject. We use the `set` arm on `a` to produce a gate
124−and give that the argument of `%yellow`. Remember that we are actually producing
125−a new core in the gate, so we have to then assign that back to the face `a`.
126−
127−```hoon
128−[current-state.a current-state.b]
129−```
130−
131−Here we simply are creating a new cell that has the `current-state` from `a` as
132−its head and the `current-state` from `b` as its tail.
133−
134−Let's run it in the Dojo to get our product:
135−
136−```
137−> +traffic
138−[%yellow %red]
139−```
140−
141−### Exercises
142−
143−1. Modify the generator to include a way to cycle the light without
144−explicitly having to select the next color. That is, if the light is currently
145−`%green` then the next color would be `%yellow`. If `%yellow` then the next
146−color should be `%red`.
147−
148−2. Using what you have learned about creating state machines in Hoon,
149−produce a state machine that can act as a vending-machine emulator. It should
150−keep track of the amount of items it has, as well as the amount of money that an
151−item costs. To keep it simple, assume this vending machine only has one item for
152−sale.
153−
154−3. Modify your vending machine from exercise 2 to support holding multiple items
155−with different prices.