on master help sign in
restructures the Hoon Tutorial, and integrates walkthroughs into the tutorial
42b63a4Robert
learn/arvo.mddeleted−111
@@ -1,111 +0,0 @@
1−+++
2−title = "Arvo"
3−weight = 1
4−template = "doc.html"
5−+++
6−Arvo is Urbit's functional operating system, written in [Hoon](/docs/learn/hoon). It's composed of modules called _vanes_:
7−
8−## [Ames](ames)
9−
10−Ames is the name of our network and the vane that communicates over it. It's an encrypted P2P network composed of instances of the Arvo operating system.
11−
12−## [Behn](behn)
13−
14−Behn is our timer. It allows vanes and applications to set and timer events, which are managed in a simple priority queue.
15−
16−## [Clay](clay)
17−
18−Clay is our filesystem and revision-control system.
19−
20−## [Dill](dill)
21−
22−Dill is our terminal driver. Unix sends keyboard events to dill from the terminal, and dill produces terminal output.
23−
24−## [Eyre](eyre)
25−
26−Eyre is our HTTP server. Unix sends HTTP messages to `%eyre`, and `%eyre` produces HTTP messages in response.
27−
28−## [Ford](ford)
29−
30−Ford is our build system. It handles resources and publishing.
31−
32−## [Gall](gall)
33−
34−Gall is the vane for controlling userspace apps.
35−
36−### [Hall](hall)
37−
38−Hall isn't a vane, but an important Gall app that functions as the Urbit messaging protocol.
39−
40−## Principles
41−
42−At a high level `%arvo` takes a mess of Unix I/O events and turns them into something clean and structured for the programmer.
43−
44−`%arvo` is designed to avoid the usual state of complex event networks: event spaghetti. We keep track of every event's cause so that we have a clear causal chain for every computation. At the bottom of every chain is a Unix I/O event, such as a network request, terminal input, file sync, or timer event. We push every step in the path the request takes onto the chain until we get to the terminal cause of the computation. Then we use this causal stack to route results back to the caller.
45−
46−### Ducts
47−
48−The `%arvo` causal stack is called a `++duct`. This is represented simply as a list of paths, where each path represents a step in the causal chain. The first element in the path is the first letter of whichever vane handled that step in the computation, or the empty span for Unix.
49−
50−Here's a duct that was recently observed in the wild:
51−
52−```
53−~[
54− /g/a/~zod/4_shell_terminal/u/time
55− /g/a/~zod/shell_terminal/u/child/4/main
56− /g/a/~zod/terminal/u/txt
57− /d/term-mess
58− //term/1
59−]
60−```
61−
62−This is the duct the timer vane receives when "timer" sample app asks the timer vane to set a timer. This is also the duct over which the response is produced at the specified time. Unix sent a terminal keystroke event (enter), and Arvo routed it to `%dill` (our terminal), which passed it on to the `%gall` app terminal, which sent it to shell, its child, which created a new child (with process id 4), which on startup asked the timer vane to set a timer.
63−
64−The timer vane saves this duct, so that when the specified time arrives and Unix sends a wakeup event to the timer vane, it can produce the response on the same duct. This response is routed to the place we popped off the top of the duct, i.e. the time app. This app produces the text "ding", which falls down to the shell, which drops it through to the terminal. Terminal drops this down to dill, which converts it into an effect that Unix will recognize as a request to print "ding" to the screen. When dill produces this, the last path in the duct has an
65−initial element of the empty span, so this is routed to Unix, which applies the effects.
66−
67−This is a call stack, with a crucial feature: the stack is a first-class citizen. You can respond over a duct zero, one, or many times. You can save ducts for later use. There are definitely parallels to Scheme-style continuations, but simpler and with more structure.
68−
69−### Making Moves
70−
71−If ducts are a call stack, then how do we make calls and produce results? Arvo processes "moves" which are a combination of message data and metadata. There are two types of moves. A `%pass` move is analogous to a call:
72−
73−```
74−[duct %pass return-path=path vane-name=@tD data=card]
75−```
76−
77−Arvo pushes the return path (preceded by the first letter of the vane name) onto the duct and sends the given data, a card, to the vane we specified. Any response will come along the same duct with the path `return-path`.
78−
79−A `%give` move is analogous to a return:
80−
81−```
82−[duct %give data=card]
83−```
84−
85−Arvo pops the top path off the duct and sends the given card back to the caller.
86−
87−### Vanes
88−
89−As shown above, we use Arvo proper to route and control the flow of moves. However, Arvo proper is rarely directly responsible for processing the event data that directly causes the desired outcome of a move. This event data is contained within a card, which is simply a `(pair term noun)`. Instead, Arvo proper passes the card off to one of its vanes, which each present an interface to clients for a particular well-defined, stable, and general-purpose piece of functionality.
90−
91−As of this writing, we have seven vanes, which each provide the following services:
92−
93−- `%ames`: the name of both our network and the vane that communicates over it.
94−- `%behn`: a simple timer.
95−- `%clay`: our version-controlled, referentially- transparent, and global filesystem.
96−- `%dill`: a terminal driver. Unix sends keyboard events to `%dill` from either the console or telnet, and `%dill` produces terminal output.
97−- `%eyre`: an http server. Unix sends http messages to `%eyre`, and `%eyre` produces http messages in response.
98−- `%ford`: handles resources and publishing.
99−- `%gall`: manages our userspace applications. `%gall` keeps state and manages subscribers.
100−
101−### Cards
102−
103−Cards are the vane-specific portion of a move. Each vane defines a protocol for interacting with other vanes (via Arvo) by defining four types of cards: kisses, gifts, notes, and signs.
104−
105−When one vane is `%pass`ed a card in its `++kiss`, Arvo activates the `++call` gate with the card as its argument. To produce a result, the vane `%give`s one of the cards defined in its `++gift`. If the vane needs to request something of another vane, it `%pass`es it a `++note` card. When that other vane returns a result, Arvo activates the `++take` gate of the initial vane with one of the cards defined in its `++sign`.
106−
107−In other words, there are only four ways of seeing a move: (1) as a request seen by the caller, which is a ++note. (2) that same request as seen by the callee, a `++kiss`. (3) the response to that first request as seen by the callee, a `++gift`. (4) the response to the first request as seen by the caller, a `++sign`.
108−
109−When a `++kiss` card is passed to a vane, Arvo calls its `++call` gate, passing it both the card and its duct. This gate must be defined in every vane. It produces two things in the following order: a list of moves and a possibly modified copy of its context. The moves are used to interact with other vanes, while the new context allows the vane to save its state. The next time Arvo activates the vane it will have this context as its subject.
110−
111−This overview has detailed how to pass a card to a particular vane. To see the cards each vane can be `%pass`ed as a `++kiss` or return as a `++gift` (as well as the semantics tied to them), each vane's public interface is explained in detail in its respective overview.
learn/hoon/hoon-tutorial/_index.md+15−4
@@ -4,7 +4,8 @@ weight = 1
4sort_by = "weight"
4sort_by = "weight"
5template = "sections/docs/chapters.html"
5template = "sections/docs/chapters.html"
6+++
6+++
7+
7−This series is designed to teach you Hoon without assuming you have an extensive programming background. In fact, you should be able to follow much of it even if you have no programming experience at all, though of course experience helps. We strongly encourage you to try out all the examples of each lesson. These lessons are meant for the beginner but they aren't meant to be skimmed.
8+This series is designed to teach you Hoon without assuming you have an extensive programming background. In fact, you should be able to follow much of it even if you have no programming experience at all, though of course experience helps. We strongly encourage you to try out all the examples of each lesson. These lessons are meant for the beginner but they aren't meant to be skimmed. Each lesson falls into one of two categories: **readings**, which are prose-heavy explanations of Hoon fundamentals, and **walkthroughs**, which are line-by-line explanations of example programs. Walkthroughs are found between readings, offering a practical implementation of the concepts taught in the reading before.
8
9
9Chapter 1 introduces and explains the fundamental concepts you need in order to understand Hoon's semantics.
10Chapter 1 introduces and explains the fundamental concepts you need in order to understand Hoon's semantics.
10
11
@@ -19,11 +20,21 @@ The first three lessons take you through a simple Hoon program, explain Hoon's s
19### Chapter 1
20### Chapter 1
20
21
21- [1.1 Setup](setup)
22- [1.1 Setup](setup)
23+- [1.1.1 Walkthrough: List of Numbers](list-of-numbers)
22- [1.2 Nouns](nouns)
24- [1.2 Nouns](nouns)
23−- [1.3 The Subject and Its Legs](the-subject-and-its-legs)
25+- [1.2.1 Walkthrough: Boolean Branching](boolean-branching)
24−- [1.4 Arms and Cores](arms-and-cores)
26+- [1.3 Hoon Syntax](hoon-syntax)
27+- [1.4 Lists](list)
28+- [1.4.1 Walkthrough: Fibonacci Sequence](fibonacci)
25- [1.5 Gates (Hoon Functions)](gates)
29- [1.5 Gates (Hoon Functions)](gates)
26−- [1.6 Multi-gate Cores and Doors](multi-gate-cores-and-doors)
30+- [1.5.1 Walkthrough: Recursion](recursion)
31+- [1.6 The Subject and Its Legs](the-subject-and-its-legs)
32+- [1.6.1 Walkthrough: Ackerman Function](ackermann)
33+- [1.7 Arms and Cores](arms-and-cores)
34+- [1.7.1 Walkthrough: Caesar Cipher](caesar)
35+- [1.8 Doors](doors)
36+- [1.8.1 Walkthough: Bank Account](bank-account)
37+- [1.9 Generators](generators)
27
38
28### Chapter 2
39### Chapter 2
29
40
learn/hoon/hoon-tutorial/ackermann.mdnew file+31
@@ -0,0 +1,31 @@
1++++
2+title = "1.6.1 Walkthrough: Ackermann Function"
3+weight = 14
4+template = "doc.html"
5++++
6+
7+The Ackermann function is one of the earliest examples of a function that is both totally computable -- meaning that it can be solved -- and not primitively recursive -- meaning it can not be rewritten in an iterative fashion.
8+
9+In this lesson, we will write a gate that computes the [Ackermann function](https://en.wikipedia.org/wiki/Ackermann_function)
10+
11+ ```
12+|= [m=@ n=@]
13+?~ m +(n)
14+?~ n $(m (dec m), n 1)
15+$(m (dec m), n $(n (dec n)))
16+```
17+
18+With the first line, `|= [m=@ n=@]`, we create a gate that takes two arguments, `m` and `n`, both of the `@` type.
19+
20+
21+
22+There are three cases.
23+
24+First, if `m` is zero, return the increment of `n`.
25+Second, if `n` is zero, decrement `m`, set `n` to 1 and recurse.
26+Else, decrement `m` and set `n` to be the value of the Ackermann function with `n` and the decrement of `n` as arguments.
27+
28+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.
29+
30+
31+### [Next Up: Reading -- Arms and Cores](../arms-and-cores)
learn/hoon/hoon-tutorial/arms-and-cores.md+2−2
@@ -1,6 +1,6 @@
1+++
1+++
2title = "Arms and Cores"
2title = "Arms and Cores"
3−weight = 14
3+weight = 15
4template = "doc.html"
4template = "doc.html"
5+++
5+++
6The Hoon subject is a noun. Each fragment of this noun is either an arm or a leg. In the previous lesson you learned what a leg is, and how to return legs of the subject by various means. In this lesson you'll learn what an arm is. Arms are a bit more complex than legs -- a full understanding of them requires a bit more background knowledge. Accordingly, in this lesson we must also introduce an important Hoon data structure: a 'core'.
6The Hoon subject is a noun. Each fragment of this noun is either an arm or a leg. In the previous lesson you learned what a leg is, and how to return legs of the subject by various means. In this lesson you'll learn what an arm is. Arms are a bit more complex than legs -- a full understanding of them requires a bit more background knowledge. Accordingly, in this lesson we must also introduce an important Hoon data structure: a 'core'.
@@ -417,4 +417,4 @@ You can now unbind `c` in the dojo -- this will help to keep your dojo subject t
417-find.c
417-find.c
418```
418```
419
419
420−### [Next Lesson: Gates](../gates)
420+### [Next Up: Walkthrough -- Caesar Cipher](../caesar)
learn/hoon/hoon-tutorial/atoms-auras-and-simple-cell-types.md+4−4
@@ -1,5 +1,5 @@
1+++
1+++
2−title = "Atoms, Auras, and Simple Cell Types"
2+title = "2.1 Atoms, Auras, and Simple Cell Types"
3weight = 24
3weight = 24
4template = "doc.html"
4template = "doc.html"
5+++
5+++
@@ -321,7 +321,7 @@ If you want to add signed atoms use the function `sum:si` instead of `add`:
321--23
321--23
322```
322```
323
323
324−### Exercise 2.4.1
324+### Exercise 2.1a
325
325
326Does Hoon's `@s` aura make a distinction between positive and negative zero, e.g., `-0` and `--0`? Use what you've learned in this lesson so far to come up with a principled answer. (As always, exercise solutions are at the bottom of the lesson.)
326Does Hoon's `@s` aura make a distinction between positive and negative zero, e.g., `-0` and `--0`? Use what you've learned in this lesson so far to come up with a principled answer. (As always, exercise solutions are at the bottom of the lesson.)
327
327
@@ -750,7 +750,7 @@ That's it for this lesson. Move on to the next one to learn more about when a t
750
750
751## Exercise Answer
751## Exercise Answer
752
752
753−### 2.4.1
753+### 2.1a
754
754
755There is no distinction between positive and negative zero for `@s`. To see this, let's cast each of `--0` and `-0` to `@s`:
755There is no distinction between positive and negative zero for `@s`. To see this, let's cast each of `--0` and `-0` to `@s`:
756
756
@@ -775,4 +775,4 @@ Hoon pretty-prints them the same way, but can we be sure that they are the same
775They are indeed the same.
775They are indeed the same.
776
776
777
777
778−### [Next Lesson: Type Checking and Type Inference](../type-checking-and-type-inference)
778+### [Next Up: Reading -- Type Checking and Type Inference](../type-checking-and-type-inference)
learn/hoon/hoon-tutorial/bank-account.mdnew file+81
@@ -0,0 +1,81 @@
1++++
2+title = "1.8.1 Bank Account"
3+weight = 17
4+template = "doc.html"
5++++
6+
7+In this lesson, we will write a door that can act as a bank account with the ability to withdraw, deposit, and check the account's 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+In the above code chunk, we're creating a cell. The head of this cell is `%say`. The tail is a gate (`|= *`) that produces another cell (`:- %noun`) with a head of the mark of a the kind of data we are going to produce, a noun; the tail of the second cell is the rest of the program.
41+
42+```
43+=< =~ new-account
44+ (deposit 100)
45+ (deposit 100)
46+ (withdraw 50)
47+ balance
48+ ==
49+```
50+
51+In this code above, 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 that's 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 account balance contained in the core we that that we examine below.
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+`+>` is [wing syntax](/docs/reference/hoon-expressions/limb/limb/). This particularly wing construction looks for the the tail of the tail (the third element) in `$`, 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+It's important to notice that the sample, `balance`, is stored as part of the door rather than existing outside of it.
80+
81+### [Next Up: Reading -- Generators](../generators)
learn/hoon/workbook/caesar.md → learn/hoon/hoon-tutorial/caesar.mdrenamed+5−2
@@ -1,8 +1,9 @@
1+++
1+++
2−title = "Caesar Cipher"
2+title = "1.7.1 Walkthrough: Caesar Cipher"
3−weight = 2
3+weight = 16
4template = "doc.html"
4template = "doc.html"
5+++
5+++
6+
6A Caesar cipher is a very simple way to obfuscate a message. The technique
7A Caesar cipher is a very simple way to obfuscate a message. The technique
7takes a string and swaps out each component letter with another letter that is
8takes a string and swaps out each component letter with another letter that is
8a specified number of positions up or down in the alphabet. For example, with a
9a specified number of positions up or down in the alphabet. For example, with a
@@ -340,3 +341,5 @@ look for the legible result.
340possible unshifted `tapes`.
341possible unshifted `tapes`.
341
342
3424. Modify the example generator into a `%say` generator.
3434. Modify the example generator into a `%say` generator.
344+
345+### [Next Up: Reading -- Doors](../doors)
learn/hoon/workbook/even.md → learn/hoon/hoon-tutorial/conditionals.mdrenamed+10−2
@@ -1,4 +1,10 @@
1++++
2+title = "1.2.1 Walkthrough: Conditionals"
3+weight = 6
4+template = "doc.html"
5++++
6+
1−Write a generator that takes an integer and checks if it even and between 1 and 100.
7+In this lesson, we will write a generator that takes an integer and checks if it is an even number between 1 and 100. This will help demonstrate how boolean (true or false) conditional expressions work in Hoon.
2
8
3```
9```
4:- %say
10:- %say
@@ -13,7 +19,7 @@ Write a generator that takes an integer and checks if it even and between 1 and
13%.n
19%.n
14```
20```
15
21
16−On the very first line, with `:- %say` we are beginning to create a generator of the `%say` kind. The result of a `%say` generator is a cell with a head of `%say` and tail that is a gate, itself producing a `cask`, a pair of a `mark` and some data. For more information about `%say` generators, see the [Generators](/using/generators) documentation.
22+On the very first line, with `:- %say` we are beginning to create a generator of the `%say` variety. The result of a `%say` generator is a cell with a head of `%say` and tail that is a gate, itself producing a `cask`, a pair of a `mark` and some data. For more information about `%say` generators, see the [Generators](../generators) documentation.
17
23
18```
24```
19|= [* [n=@ud ~] ~]
25|= [* [n=@ud ~] ~]
@@ -52,3 +58,5 @@ The second expression is:
52```
58```
53
59
54Again we use the "and" operator on two expressions with `?&` the first is just checking if n is greater than or equal to 1. The second we have artificially use the `?!` rune to demonstrate its use. `?!` is a logical NOT operation. We use that on the result of asking if n is greater than 100 to effectively ask if it is less than or equal to 100.
60Again we use the "and" operator on two expressions with `?&` the first is just checking if n is greater than or equal to 1. The second we have artificially use the `?!` rune to demonstrate its use. `?!` is a logical NOT operation. We use that on the result of asking if n is greater than 100 to effectively ask if it is less than or equal to 100.
61+
62+### [Next Up: Reading -- Hoon Syntax](../hoon-syntax)
learn/hoon/hoon-tutorial/cores-again.mddeleted−797
@@ -1,797 +0,0 @@
1−+++
2−title = "Cores Again"
3−weight = 28
4−template = "doc.html"
5−+++
6−In the last lesson you learned a bit about how to use cores as state machines. In this lesson you'll expand on that knowledge, in particular by learning how to use the `=^` rune. At the end of the lesson you'll learn how to write a generator that shuffles a 52 card deck and deals hands from it.
7−
8−## The `num` Core Again
9−
10−In the last lesson we used a simple door to illustrate the use of doors as state machines. Let's modify the code for that core slightly:
11−
12−```
13−|_ a/@
14− ++ this .
15− ::
16− ++ inc
17− [+(a) this(a +(a))]
18− ::
19− ++ plus
20− |= b=@
21− [(add a b) this(a (add a b))]
22− ::
23− ++ reset
24− [a this(a 0)]
25−--
26−```
27−
28−The `this` arm is unchanged. The other arms -- `inc`, `plus`, and `reset` -- no longer evaluate to cores. They evaluate to cells in which the head is some value of type `@`, and the tail is a core, i.e., a variant of `this`. The idea behind these changes is that each arm should produce not just a new state, but a relevant atom value for the sample as well. When `inc` is evaluated the new value for `a` is produced, along with the new version of the core. When `reset` is evaluated, the sum total of `a` is produced, along with the new version of the core in which `a` is set to `0`.
29−
30−Here's a new version of the program that uses this new core code:
31−
32−```
33−|= c=@
34−=/ num :: define the `num` core
35− |_ a/@
36− ++ this .
37− ::
38− ++ inc
39− [+(a) this(a +(a))]
40− ::
41− ++ plus
42− |= b=@
43− [(add a b) this(a (add a b))]
44− ::
45− ++ reset
46− [a this(a 0)]
47− --
48−=^ v1 num inc.num :: increment `a` by 1, store in `v1`
49−=^ v2 num inc.num :: do it again, storing `a` in `v2`
50−=^ v3 num (plus:num c) :: add `c` to `a`, store in `v3`
51−=^ v4 num (plus:num c) :: do it again, storing `a` in `v4`
52−=^ v5 num reset.num :: reset `a` to `0`, total in `v5`
53−[v1 v2 v3 v4 v5] :: return `v1` through `v5`
54−```
55−
56−Save this as `numcore2.hoon` in `/gen` of your urbit's pier and run it in the dojo:
57−
58−```
59−> +numcore2 10
60−[1 2 12 22 22]
61−
62−> +numcore2 100
63−[1 2 102 202 202]
64−
65−> +numcore2 500
66−[1 2 502 1.002 1.002]
67−```
68−
69−Now you can see the intermediate values of the sample of `a` for each modified version of the `num` core that was created. Of course, you can't really understand how this program works until you understand what the `=^` rune does.
70−
71−### `=^` Pin a Value and Replace a Leg
72−
73−The `=^` rune takes four subexpressions: `=^(a b c d)`. The first three modify the subject, and the `d` is evaluated against that subject. `a` is a face name, `b` is a wing, and `c` is an expression that evaluates to a cell. The subject is modified as follows: (1) `c` is evaluated, producing a cell; (2) the head of that cell is pinned to the subject, `a` becoming the face name for it; and (3) the wing at `b` is replaced with the tail of the cell produced by `c`.
74−
75−This is particularly useful when you want to return data for the form `[result new-state]`.
76−
77−For example, let's consider `=^ v1 num inc.num` from the program above. `inc.num` produces a cell, the head of which is an atom. This atom is pinned to the head of the subject and given the face name `v1`. The tail of the cell produced by `inc.num` is a variant of the `num` core, and becomes the new value of `num`. The fourth subexpression of this `=^` expression is the rest of the program, i.e.:
78−
79−```
80−=^ v2 num inc.num
81−=^ v3 num (plus:num c)
82−=^ v4 num (plus:num c)
83−=^ v5 num reset.num
84−[v1 v2 v3 v4 v5]
85−```
86−
87−The `=^` rune was designed for use with state machine data structures, doors in particular. Understanding `=^` is important! This whole lesson is intended to emphasize the use and importance of this rune.
88−
89−### Casting for Cores
90−
91−You'll notice that the `plus` arm of the `num` core above evaluates to a gate.
92−
93−```
94−++ plus
95− |= b=@
96− [(add a b) this(a (add a b))]
97−```
98−
99−But this gate doesn't have a cast in it, and that's bad practice. Any time you produce a gate you should include a cast. The desired output type of the `plus` gate is a cell whose head is an atom and whose tail is a core of the same type as `num`. We know how to cast for the head -- it's just an atom, `@`. But what about the tail? How do we cast for a core of the same type as `num`?
100−
101−There is no straight-forward way of casting for a core in general, and anyway that isn't what is desired in this case. We don't want `plus` to produce just any core; we want it to produce a core of the same type as `num`.
102−
103−One way to cast appropriately is to use the `^+` rune, as in the following:
104−
105−```
106−++ plus
107− |= b=@
108− ^+ [0 this]
109− [(add a b) this(a (add a b))]
110−```
111−
112−The relevant addition is the line with `^+ [0 this]`. The `^+` rune is used when one wants to do a cast with an example noun, i.e., when you want to cast for a value of the same type as the example. The example `[0 this]` is a cell type whose head is an `@ud`, and whose tail is a core of the same type as `this`. And `this` is how the `num` core refers to itself.
113−
114−#### `$_` Create a Type From an Example
115−
116−Another way to add a cast to the `plus` arm is to use the `$_` rune to create a core type. This rune allows us to use the `^-` cast rune instead, as in the following:
117−
118−```
119−++ plus
120− |= b=@
121− ^- [@ $_(this)]
122− [(add a b) this(a (add a b))]
123−```
124−
125−The `$_` rune takes one subexpression. That subexpression is evaluated, and the type of the resulting noun is the type produced. The default value of that type is exactly the noun used to create it.
126−
127−The irregular form of `$_( )` is just `_`, so we can shorten the cast above to:
128−
129−```
130−++ plus
131− |= b=@
132− ^- [@ _this]
133− [(add a b) this(a (add a b))]
134−```
135−
136−This kind of casting is relatively common. It's generally used in cores used as state machines.
137−
138−#### The `_+>.$` Construction
139−
140−Another way to cast for the type of the parent core of an arm is to use `_+>.$`. This construction looks a bit complicated, but it's also used somewhat frequently in the Urbit codebase. It's worth a closer examination. We can use it in the `plus` arm as follows:
141−
142−```
143−++ plus
144− |= b=@
145− ^- [@ _+>.$]
146− [(add a b) this(a (add a b))]
147−```
148−
149−But what does it mean? First, the `_` indicates the irregular form of the `$_` rune. That is, `_+>.$` evaluates `+>.$` and produces a type from the resulting noun.
150−
151−What is `+>.$`? This is a wing of two limbs, `+>` and `$`. As you saw in [section 1.4](../arms-and-cores), `+>` is the lark syntax for `+7`, i.e., address space `7`. And `$` is the name of the lone arm in a gate. Whenever an arm name is used in a wing expression and isn't the left-most limb in the series, it evaluates to its parent core. The parent core of `$` is the gate itself.
152−
153−Thus, `+>.$` evaluates to `+7` of the gate containing `$`. For our `plus` arm, the gate in question is the one defined by:
154−
155−```
156−|= b=@
157−^- [@ _+>.$]
158−[(add a b) this(a (add a b))]
159−```
160−
161−What is `+7` of this gate? It's the subject of the expression used to define the gate. This gate is produced by the `plus` arm. Every arm in the `num` core, including `plus`, is evaluated with the `num` core as the subject. Hence, `+>.$` is just the `num` core.
162−
163−It follows that `_+>.$` is the type of the `num` core.
164−
165−## Random Number Generation
166−
167−The `=^` rune can be used with the `og` door in the Hoon standard library to generate random numbers. We'll illustrate this.
168−
169−First, let's use the `rad` arm in the `og` core. This arm takes an atom `n`, and produces another atom somewhere in the range of `0` to `n - 1` (inclusive):
170−
171−```
172−> (rad:og 3)
173−0
174−
175−> (rad:og 4)
176−2
177−
178−> (rad:og 5)
179−4
180−
181−> (rad:og 55)
182−50
183−
184−> (rad:og 155)
185−108
186−```
187−
188−Are these numbers randomly generated? Not really. The `og` core uses a 'seed number' which determines how a number is generated from the functions in `og`. The seed number is stored in the sample of the `og` core as an atom. In other words, `og` is a door whose 'state' is the seed number. The default seed number is `0`. If we use `rad` in `og` without changing the sample of the latter, the number produced by `rad` is always the same per any given argument. E.g., `(rad:og 55)` will produce `50` every time.
189−
190−To change the seed, we need to make a copy of `og` with a different sample. How do we do that? We do it as follows:
191−
192−```
193−> ~(. og 123)
194−<4.rvc {a/@ud <51.zox 93.pqh 74.dbd 1.qct $141>}>
195−
196−> ~(. og 456)
197−<4.rvc {a/@ud <51.zox 93.pqh 74.dbd 1.qct $141>}>
198−
199−> ~(. og 456.789)
200−<4.rvc {a/@ud <51.zox 93.pqh 74.dbd 1.qct $141>}>
201−```
202−
203−The seeds of these three cores are `123`, `456`, and `456.789`, respectively. We can use these variants of `og` with `rad` to get different values from the ones we got before:
204−
205−```
206−> (rad:~(. og 123) 3)
207−1
208−
209−> (rad:~(. og 123) 4)
210−3
211−
212−> (rad:~(. og 123) 5)
213−3
214−
215−> (rad:~(. og 123) 55)
216−28
217−
218−> (rad:~(. og 123) 155)
219−58
220−```
221−
222−This can be a bit tedious, however. And, in any case, this syntax requires that we pick a seed value manually.
223−
224−Part of the solution is to use the `rads` arm of `og` with the `=^` rune. The gate defined by the `rads` arm takes an atom `n` produces a pair of: (1) another atom somewhere in the range of `0` to `n - 1` (inclusive); and (2) another version of the `og` core with a different seed value.
225−
226−```
227−> (rads:og 3)
228−[0 <4.rvc {a/@ <51.zox 93.pqh 74.dbd 1.qct $141>}>]
229−
230−> (rads:og 4)
231−[2 <4.rvc {a/@ <51.zox 93.pqh 74.dbd 1.qct $141>}>]
232−
233−> (rads:og 5)
234−[4 <4.rvc {a/@ <51.zox 93.pqh 74.dbd 1.qct $141>}>]
235−
236−> (rads:og 55)
237−[50 <4.rvc {a/@ <51.zox 93.pqh 74.dbd 1.qct $141>}>]
238−```
239−
240−Let's create a copy of the `og` core in the dojo, giving it the face `rng`. By first putting it in the subject as a door, we're able to mutate it. (Strictly speaking, there is no `og` door until the `++ og` arm in the Hoon standard library is evaluated. If you try to mutate it before putting a copy of the core in the subject, you'll run into problems.) Let's make a copy of the `og` door with its initial seed value as `123`:
241−
242−```
243−> =rng ~(. og 123)
244−
245−> rng
246−<4.rvc {a/@ud <51.zox 93.pqh 74.dbd 1.qct $141>}>
247−
248−> +6:rng
249−a=123
250−```
251−
252−Good. Now let's use the `=^` rune with `rng`. Paste the multi-line expression into the dojo:
253−
254−```
255−> =^ r1 rng (rads:rng 3)
256− =^ r2 rng (rads:rng 4)
257− =^ r3 rng (rads:rng 5)
258− =^ r4 rng (rads:rng 55)
259− =^ r5 rng (rads:rng 155)
260− [r1 r2 r3 r4 r5]
261−[1 0 4 22 88]
262−```
263−
264−For each random number generation, the `rng` core has a different seed number. However, we still picked the initial seed value. This isn't random enough; given the same initial seed and the same arguments for `rads`, the resulting numbers produced by `rads` will be the same as well. This is what `eny` is for:
265−
266−```
267−> eny
268−\/0v3en.c4udf.jg3op.njvu9.sdhp3.oq9vm.j5g93.2njmu.6bk6j.agjme.ef451.7icfo.134\/
269− fv.i4dor.dv6ls.9m7ig.vb8m7.ir3mb.gt7vn.q57l6.sant1
270−\/ \/
271−
272−> eny
273−\/0v1hu.1i95m.infcn.a6sc2.47fph.idjoc.2jcd4.2hj3p.ma12d.jtphu.5585b.9t0ru.48q\/
274− 61.3qmpl.gvn5b.evhl3.us653.kffap.vef21.kaavg.p5sl3
275−\/ \/
276−```
277−
278−`eny` is an environment value for [entropy](https://en.wikipedia.org/wiki/Entropy_%28computing%29). Its value changes every time it's evaluated. We can use `eny` to produce a seed value for `rng` and retry the `=^` expression from above:
279−
280−```
281−> =rng ~(. og eny)
282−
283−> =^ r1 rng (rads:rng 3)
284− =^ r2 rng (rads:rng 4)
285− =^ r3 rng (rads:rng 5)
286− =^ r4 rng (rads:rng 55)
287− =^ r5 rng (rads:rng 155)
288− [r1 r2 r3 r4 r5]
289−[0 2 4 51 40]
290−```
291−
292−(Your output values will differ.)
293−
294−## Dealing Cards
295−
296−Let's write a gate that shuffles and deals from a deck of cards. We'll start with a simpler gate that produces an unshuffled deck.
297−
298−```
299−|= *
300−=| sorted=(list [@tas @tas])
301−=/ values=(list @tas)
302− :* %two
303− %three
304− %four
305− %five
306− %six
307− %seven
308− %eight
309− %nine
310− %ten
311− %jack
312− %queen
313− %king
314− %ace
315− ~ ==
316−=/ suits=(list @tas)
317− ~[%spades %diamonds %clubs %hearts]
318−|- ^- (list [@tas @tas])
319−?~ suits sorted
320−%= $
321− suits t.suits
322− sorted |- ^- (list [@tas @tas])
323− ?~ values sorted
324− [[i.values i.suits] $(values t.values)]
325−==
326−```
327−
328−Save this as `deck.hoon` in the `/gen` directory of your urbit's pier and run in the dojo:
329−
330−```
331−> +deck 1
332−~[
333− [%two %hearts]
334− [%three %hearts]
335− [%four %hearts]
336− [%five %hearts]
337− [%six %hearts]
338− [%seven %hearts]
339− [%eight %hearts]
340− [%nine %hearts]
341− [%ten %hearts]
342− [%jack %hearts]
343− [%queen %hearts]
344− [%king %hearts]
345− [%ace %hearts]
346− [%two %clubs]
347− [%three %clubs]
348− [%four %clubs]
349− [%five %clubs]
350− [%six %clubs]
351− [%seven %clubs]
352− [%eight %clubs]
353− [%nine %clubs]
354− [%ten %clubs]
355− [%jack %clubs]
356− [%queen %clubs]
357− [%king %clubs]
358− [%ace %clubs]
359− [%two %diamonds]
360− [%three %diamonds]
361− [%four %diamonds]
362− [%five %diamonds]
363− [%six %diamonds]
364− [%seven %diamonds]
365− [%eight %diamonds]
366− [%nine %diamonds]
367− [%ten %diamonds]
368− [%jack %diamonds]
369− [%queen %diamonds]
370− [%king %diamonds]
371− [%ace %diamonds]
372− [%two %spades]
373− [%three %spades]
374− [%four %spades]
375− [%five %spades]
376− [%six %spades]
377− [%seven %spades]
378− [%eight %spades]
379− [%nine %spades]
380− [%ten %spades]
381− [%jack %spades]
382− [%queen %spades]
383− [%king %spades]
384− [%ace %spades]
385−]
386−```
387−
388−(This gate doesn't use the sample for anything, but you still have to give one when you run the generator. That's because of the kind of generator this is, 'naked'.)
389−
390−We can create our own types for use with this generator. In the following modified version, we create the types `value` for card value, `suit` for card suit, and `card` for a pair of value and suit. We put these definitions into a core and put that core into the subject so we can use them from elsewhere in the gate.
391−
392−```
393−|= *
394−=<
395−=| sorted=(list card)
396−=/ values=(list value)
397− :* %two
398− %three
399− %four
400− %five
401− %six
402− %seven
403− %eight
404− %nine
405− %ten
406− %jack
407− %queen
408− %king
409− %ace
410− ~ ==
411−=/ suits=(list suit)
412− ~[%spades %diamonds %clubs %hearts]
413−|- ^- (list card)
414−?~ suits sorted
415−%= $
416− suits t.suits
417− sorted |- ^- (list card)
418− ?~ values sorted
419− [[i.values i.suits] $(values t.values)]
420−==
421−::
422−|%
423−::
424−+$ card [value suit]
425−::
426−+$ value @tas
427−::
428−+$ suit $? %clubs
429− %hearts
430− %spades
431− %diamonds
432− ==
433−--
434−```
435−
436−This version of the gate produces the same result as the last version, but uses the custom types we defined instead of the native Hoon types.
437−
438−Next, let's use the `og` core to shuffle the deck of cards:
439−
440−```
441−|= *
442−=<
443−=/ deck=(list card) sorted-deck :: `deck` is sorted deck of cards
444−=| shuffled=(list card) :: `shuffled` is shuffled deck
445−=/ len=@ (lent deck) :: `len` is # of cards in `deck`
446−=/ rng ~(. og 123) :: `rng` is copy of `og` core, seed 123
447−|- ^- (list card)
448−?: =(~ deck) shuffled :: when `deck` is null, return shuffled
449−=^ val rng (rads:rng len) :: `val` picks random card from `deck`
450−%= $
451− shuffled [(snag val deck) shuffled] :: add random card to `shuffled`
452− deck (oust [val 1] deck) :: remove that card from `deck`
453− len (dec len) :: decrement # of cards in `deck`
454−==
455−::
456−|%
457−::
458−++ sorted-deck
459− =| sorted=(list card)
460− =/ values=(list value)
461− :* %two
462− %three
463− %four
464− %five
465− %six
466− %seven
467− %eight
468− %nine
469− %ten
470− %jack
471− %queen
472− %king
473− %ace
474− ~ ==
475− =/ suits=(list suit)
476− ~[%spades %diamonds %clubs %hearts]
477− |- ^- (list card)
478− ?~ suits sorted
479− %= $
480− suits t.suits
481− sorted |- ^- (list card)
482− ?~ values sorted
483− [[i.values i.suits] $(values t.values)]
484− ==
485−::
486−+$ card [value suit]
487−::
488−+$ value @tas
489−::
490−+$ suit $? %clubs
491− %hearts
492− %spades
493− %diamonds
494− ==
495−--
496−```
497−
498−Save this as a new copy of `deck.hoon` and run it in the dojo:
499−
500−```
501−> +deck 1
502−~[
503− [%two %clubs]
504− [%five %diamonds]
505− [%ace %spades]
506− [%three %hearts]
507− [%queen %clubs]
508− [%four %clubs]
509− [%seven %hearts]
510− [%king %clubs]
511− [%seven %clubs]
512− [%six %diamonds]
513− [%nine %diamonds]
514− [%eight %clubs]
515− [%eight %spades]
516− [%king %hearts]
517− [%four %hearts]
518− [%ten %clubs]
519− [%jack %clubs]
520− [%nine %hearts]
521− [%six %hearts]
522− [%five %clubs]
523− [%nine %spades]
524− [%two %hearts]
525− [%three %clubs]
526− [%queen %hearts]
527− [%five %hearts]
528− [%five %spades]
529− [%six %spades]
530− [%ten %hearts]
531− [%king %diamonds]
532− [%three %spades]
533− [%eight %hearts]
534− [%king %spades]
535− [%ten %diamonds]
536− [%queen %diamonds]
537− [%nine %clubs]
538− [%jack %hearts]
539− [%queen %spades]
540− [%jack %diamonds]
541− [%eight %diamonds]
542− [%jack %spades]
543− [%three %diamonds]
544− [%four %spades]
545− [%ace %hearts]
546− [%ten %spades]
547− [%two %spades]
548− [%ace %diamonds]
549− [%six %clubs]
550− [%seven %spades]
551− [%seven %diamonds]
552− [%two %diamonds]
553− [%ace %clubs]
554− [%four %diamonds]
555−]
556−```
557−
558−The deck is shuffled, but the way it's shuffled depends upon the seed value manually entered for `rng`. You can use `eny` in the dojo, but this environment value isn't available in the kind of generator we're using above. We've been using 'naked' generators in this chapter. Let's use a different kind which does have access to `eny`: a `%say` generator.
559−
560−A naked generator must evaluate to a gate, but a `%say` generator must evaluate to a pair of (1) the `@tas` noun `%say`, and (2) a gate. But the latter can't be just any gate. The gate in (2) must produce a pair of (1) type information, and (2) output of the type indicated in (1).
561−
562−We won't explain all the details of `%say` generators here; that's for a later tutorial. But we'll show a version of the program above that can use `eny` as entropy for the `rng` seed:
563−
564−```
565−:- %say :: pair of `%say` and gate
566−|= [[* eny=@ *] [* ~] ~] :: don't worry about this line for now
567−:- %noun :: pair of `%noun` and gate output
568−=<
569−=/ deck=(list card) sorted-deck
570−=| shuffled=(list card)
571−=/ len=@ (lent deck)
572−=/ rng ~(. og eny) :: `rng` has seed of `eny`
573−|- ^- (list card)
574−?: =(~ deck) shuffled
575−=^ val rng (rads:rng len)
576−%= $
577− shuffled [(snag val deck) shuffled]
578− deck (oust [val 1] deck)
579− len (dec len)
580−==
581−::
582−|%
583−::
584−++ sorted-deck
585− =| sorted=(list card)
586− =/ values=(list value)
587− :* %two
588− %three
589− %four
590− %five
591− %six
592− %seven
593− %eight
594− %nine
595− %ten
596− %jack
597− %queen
598− %king
599− %ace
600− ~ ==
601− =/ suits=(list suit)
602− ~[%spades %diamonds %clubs %hearts]
603− |- ^- (list card)
604− ?~ suits sorted
605− %= $
606− suits t.suits
607− sorted |- ^- (list card)
608− ?~ values sorted
609− [[i.values i.suits] $(values t.values)]
610− ==
611−::
612−+$ card [value suit]
613−::
614−+$ value @tas
615−::
616−+$ suit $? %clubs
617− %hearts
618− %spades
619− %diamonds
620− ==
621−--
622−```
623−
624−With this version of the program, you get a different sorted deck of cards each time it's run!
625−
626−### Dealing Cards with a State Machine
627−
628−Let's use a door as a state machine. The state will have two parts: (1) `deck`, a deck of cards, and (2) `rng`, a copy of the `og` core with a seed value. Instead of having functions that produce a sorted deck of cards or a shuffled deck of cards, let's have the arms of this door compute a new version of the state machine with an appropriately modified state.
629−
630−We'll use this state machine in a program that deals `a` hands of `b` cards each:
631−
632−```
633−::
634−:: carddeal.hoon
635−::
636−:: this program deals cards from a randomly shuffled deck.
637−::
638−:: save as `carddeal.hoon` in the `/gen` directory of your
639−:: urbit's pier and run in the dojo:
640−::
641−:: +carddeal [4 5]
642−::
643−::
644−:: this is a %say generator; unlike naked gens, these have access
645−:: to environment data such as entropy
646−::
647−:- %say
648−::
649−:: a is the number of hands to be dealt
650−:: b is the number of cards per hand
651−::
652−|= [[* eny=@ *] [[a=@ b=@] ~] ~]
653−:- %noun
654−=<
655−::
656−:: `cards` is a core with a shuffled deck and `rng` as state
657−::
658−=/ cards shuffle:sorted-deck:cards
659−|- ^- (list (list card))
660−?: =(0 a) ~
661−::
662−:: `draw` returns a pair of [hand cards]
663−:: `hand` is a list of cards, i.e. a dealt hand, and
664−:: `cards` is the core with a modified deck
665−:: (the cards of `hand` were removed from the deck)
666−::
667−=^ hand cards (draw:cards b)
668−[hand $(a (dec a))]
669−::
670−|%
671−::
672−:: a `card` is a pair of [value suit]
673−::
674−+$ card [value suit]
675−::
676−:: a `value` is a `@tas`, e.g., %two, %queen
677−::
678−+$ value @tas
679−::
680−:: the card suits are: clubs, hearts, spades,
681−:: and diamonds
682−::
683−+$ suit $? %clubs
684− %hearts
685− %spades
686− %diamonds
687− ==
688−::
689−:: `cards` is a door with `deck` and `rng` as state
690−:: `deck` is a deck of cards
691−:: `rng` is a Hoon stdlib core for random # generation
692−:: a door is a core with a sample, often multi-arm
693−::
694−++ cards
695− |_ [deck=(list card) rng=_~(. og eny)]
696− ::
697− :: `this` is, by convention, how a door refers
698− :: to itself
699− ::
700− ++ this .
701− ::
702− :: `draw` returns two things: (1) a list of cards (i.e. a hand),
703− :: and (2) a modified core for `cards`. the `deck` in `cards`
704− :: has the dealt cards removed.
705− ::
706− ++ draw
707− |= a=@
708− =| hand=(list card)
709− |- ^- [(list card) _this]
710− ?: =(0 a) [hand this]
711− ?~ deck !!
712− %= $
713− hand [i.deck hand]
714− deck t.deck
715− a (dec a)
716− ==
717− ::
718− :: `shuffle` returns the `cards` core with a modifed `deck`.
719− :: the cards in the deck have been shuffled randomly.
720− ::
721− ++ shuffle
722− =| shuffled=(list card)
723− =/ len=@ (lent deck)
724− |- ^- _this
725− ?: =(~ deck) this(deck shuffled)
726− =^ val rng (rads:rng len)
727− %= $
728− shuffled [(snag val deck) shuffled]
729− deck (oust [val 1] deck)
730− len (dec len)
731− ==
732− ::
733− :: `sorted-deck` returns the `cards` core with a modifed
734− :: `deck`. the full deck of cards is provided, unshuffled.
735− ::
736− ++ sorted-deck
737− %_ this
738− deck =| sorted=(list card)
739− =/ values=(list value)
740− :* %two
741− %three
742− %four
743− %five
744− %six
745− %seven
746− %eight
747− %nine
748− %ten
749− %jack
750− %queen
751− %king
752− %ace
753− ~ ==
754− =/ suits=(list suit)
755− ~[%spades %diamonds %clubs %hearts]
756− |- ^- (list card)
757− ?~ suits sorted
758− %= $
759− suits t.suits
760− sorted |- ^- (list card)
761− ?~ values sorted
762− [[i.values i.suits] $(values t.values)]
763− ==
764− ==
765− --
766−--
767−```
768−
769−Save this as `carddeal.hoon` in `/gen` of your urbit's pier and run in the dojo:
770−
771−```
772−> +carddeal [3 4]
773−~[
774− ~[[%queen %spades] [%jack %hearts] [%three %diamonds] [%six %spades]]
775− ~[[%king %diamonds] [%eight %hearts] [%five %clubs] [%two %diamonds]]
776− ~[[%three %clubs] [%nine %spades] [%six %diamonds] [%three %hearts]]
777−]
778−
779−> +carddeal [3 4]
780−~[
781− ~[[%king %clubs] [%ten %clubs] [%ten %diamonds] [%seven %spades]]
782− ~[[%six %hearts] [%six %clubs] [%three %spades] [%four %hearts]]
783− ~[[%seven %clubs] [%jack %diamonds] [%two %spades] [%five %spades]]
784−]
785−
786−> +carddeal [3 4]
787−~[
788− ~[[%seven %diamonds] [%nine %clubs] [%five %diamonds] [%three %diamonds]]
789− ~[[%ace %spades] [%jack %spades] [%two %spades] [%nine %hearts]]
790− ~[[%king %diamonds] [%six %spades] [%queen %clubs] [%eight %clubs]]
791−]
792−
793−```
794−
795−You get a different set of hands each time you run the generator.
796−
797−### [Next Lesson: Lists](../lists)
learn/hoon/hoon-tutorial/cores.mddeleted−396
@@ -1,396 +0,0 @@
1−+++
2−title = "Cores"
3−weight = 27
4−template = "doc.html"
5−+++
6−You learned what a core is in previous lessons. After a brief review, let's talk about how to use cores effectively in Hoon programming.
7−
8−A core is a particularly useful kind of Hoon data: a cell whose head is a battery and whose tail is a payload:
9−
10−```
11− [core]
12− / \
13− [battery] [payload]
14−```
15−
16−The battery is a series of arms, each of which is intended to be evaluated with the parent core as the subject. Some cores have samples and some don't. Those that do have a payload structured as a cell. The head is the sample and the tail is the context:
17−
18−```
19− [core]
20− / \
21− [battery] [payload]
22− / \
23− [sample] [context]
24−```
25−
26−The context is all the relevant data needed to evaluate the arms in the battery correctly, apart from the sample. In cores with no sample, there is no distinction between 'payload' and 'context'.
27−
28−In this lesson you'll learn how to produce various kinds of cores. You've already been using one kind of core, produced with the `|=` rune: gates. But in this lesson you'll learn how to produce many-armed cores, with and without samples. You'll also learn how to make use of these cores in your own programs.
29−
30−## Project Euler 1
31−
32−Let's start with an example program illustrating the use of a many-armed core.
33−
34−[Problem 1 of Project Euler](https://projecteuler.net/problem=1) is as follows:
35−
36−```
37−If we list all the natural numbers below 10 that are multiples of
38−3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
39−
40−Find the sum of all the multiples of 3 or 5 below 1000.
41−```
42−
43−The program below provides a solution:
44−
45−```
46−|= a=@
47−=< (euler-sum a)
48−::
49−|%
50−++ threes
51− |= a/@
52− =| b/@
53− |- ^- @
54− ?: (lth a b)
55− 0
56− (add b $(b (add 3 b)))
57−::
58−++ fives
59− |= a/@
60− =| b/@
61− |- ^- @
62− ?: (lte a b)
63− 0
64− ?: =((mod b 3) 0)
65− $(b (add b 5))
66− (add b $(b (add b 5)))
67−::
68−++ euler-sum
69− |= a=@
70− (add (threes a) (fives a))
71−--
72−```
73−
74−Save this as `euler1.hoon` in the `/gen` directory of your urbit's pier and run it in the dojo:
75−
76−```
77−> +euler1 1.000
78−233.168
79−```
80−
81−Success! (We could use the same program to find the sum of the multiples of 3 and 5 for numbers other than `1.000` as well.)
82−
83−Let's take a closer look at the code (with part of it elided).
84−
85−```
86−|= a=@
87−=< (euler-sum a)
88−::
89−|%
90− ...
91−--
92−```
93−
94−This uses `|=` to produce a gate whose sample is an atom labeled `a`. The `=<` rune creates a new subject using `|%` and evaluates `(euler-sum a)` against that subject. `euler-sum` isn't a function in the Hoon standard library---it's a user-defined gate. This gate is only defined in the core created by the `|%` expression.
95−
96−### `|%` Produce a Core with No Sample
97−
98−The `|%` rune produces a core with no sample; nearly always it's used to create a multi-arm core. The `|%` rune takes a series of arm definitions. The expression is terminated with the `--` rune. From the above example:
99−
100−```
101−|%
102−++ threes
103− |= a/@
104− =| b/@
105− |- ^- @
106− ?: (lth a b)
107− 0
108− (add b $(b (add 3 b)))
109−::
110−++ fives
111− |= a/@
112− =| b/@
113− |- ^- @
114− ?: (lte a b)
115− 0
116− ?: =((mod b 3) 0)
117− $(b (add b 5))
118− (add b $(b (add b 5)))
119−::
120−++ euler-sum
121− |= a=@
122− (add (threes a) (fives a))
123−--
124−```
125−
126−As you can see, the expression begins with `|%`, ends with `--`, and in between it has three arm definitions. Each arm definition begins with `++` followed by an arm name. After each name is the Hoon expression for that arm. In this example, each arm defines a gate. Once this core is in the subject these gates can be called like any other standard library gate.
127−
128−The `|%` rune produces a core with no sample. The composition of the head of this core, i.e., the battery, is determined by the arm definitions of the `|%` expression. The tail of the core, i.e., the payload, is the subject against which the `|%` expression was evaluated. This is important -- the arm definitions can use any data from the subject, and that data is guaranteed to be available to the arm regardless of the arm evaluation context. Each arm can make calls to any of the other arms in that core as well, because arms are evaluated with the entire parent core as the subject.
129−
130−## Cores and Types
131−
132−The `++` rune is used for most arm definitions in `|%`, but there are other runes for special kinds of arms.
133−
134−### Defining Types with Core Arms
135−
136−Let's say that you want to define several types and make use of them throughout your Hoon program. One common way to do this involves producing a core that defines these types and keeping it in the subject. Each arm of such a core defines a type. Arms that define types are created with the `+$` rune instead of `++`.
137−
138−Let's write such a core and bind it to a face in the dojo. (Feel free to cut and paste the core definition for `t` below.)
139−
140−```
141−> =t |%
142− +$ integer @
143− +$ integer-pair [integer integer]
144− +$ tagged-pair
145− $% [%abc integer-pair]
146− [%def integer-pair]
147− ==
148− --
149−
150−> t
151−< 3.axs
152− { {our/@p now/@da eny/@uvJ}
153− <19.min 24.fmf 7.mpi 38.ard 119.spd 241.plj 51.zox 93.pqh 74.dbd 1.qct $141>
154− }
155−>
156−```
157−
158−We now have a core that defines three types: `integer`, which is essentially just an alias for `@`; `integer-pair` which is the type for a pair of `integers`, and `tagged-pair` which is an `integer-pair` in a cell, with one of two possible tags as the head of that cell, `%abc` or `%def`. Let's do some casting in the dojo using the types of this core:
159−
160−```
161−> `integer.t`15
162−15
163−
164−> `integer-pair.t`[15 20]
165−[15 20]
166−
167−> `tagged-pair.t`[%abc [15 20]]
168−[%abc 15 20]
169−
170−> `integer.t`[15 20]
171−nest-fail
172−
173−> `integer-pair.t`15
174−nest-fail
175−```
176−
177−Unbind `t` in the dojo subject as follows:
178−
179−```
180−> =t
181−```
182−
183−### Type Constructor Arms
184−
185−`(list @)` is a type. So is `(list ^)`, `(list tape)`, `(list ?)`, etc. These are all lists of one sort or another, but they're all distinct types. You can think of `list` as a function that takes one type and returns another -- it takes, e.g., `@` and returns an atom list type. We may call `list` one kind of **type constructor**.
186−
187−A type constructor takes one or more types, and constructs another type from them. You can define your own type constructors using core arms.
188−
189−To define a type constructor with an arm, use the `+*` rune. This rune is followed by (1) an arm name, (2) one or more faces naming the input types inside square brackets, and (3) a type expression that must evaluate to a structure.
190−
191−To illustrate, let's make a type constructor that makes a pair of some input types. E.g., if given `@`, it returns the type `[@ @]`.
192−
193−```
194−> =t |%
195− +* pair-of [a] [a a]
196− --
197−
198−> `(pair-of.t @)`[12 14]
199−[12 14]
200−
201−> `(pair-of.t @)`[12 14 17]
202−nest-fail
203−```
204−
205−Let's try with other input types:
206−
207−```
208−> `(pair-of.t ?)`[& |]
209−[%.y %.n]
210−
211−> `(pair-of.t ^)`[[10 11] [12 13]]
212−[[10 11] 12 13]
213−
214−> `(pair-of.t ^)`[[10 11] 12]
215−nest-fail
216−```
217−
218−Unbind `t` again:
219−
220−```
221−> =t
222−```
223−
224−## Cores with Samples (Doors)
225−
226−Cores without samples are often useful, but sometimes more is desired. Sometimes you'll want to use a core with a sample. Such cores are called **doors**.
227−
228−One way they can be used is to produce different versions of a function. There is a door in the Hoon standard library, `++ rs`, for producing single-precision float functions. The various arms of this door (e.g., `add`, `sub`, `mul`) are designed for use with atoms whose aura is `@rs`:
229−
230−```
231−> (add:rs .3.14 .2.72)
232−.5.86
233−
234−> (sub:rs .3.14 .2.72)
235−.4.2000008e-1
236−
237−> (mul:rs .3.14 .2.72)
238−.8.5408
239−```
240−
241−But there are different versions of these gates for different rounding rules. The default rule is to round to zero. Accordingly, when `add` is evaluated with `rs` as the subject, a gate is produced that adds single-precision floats with that rounding rule assumed.
242−
243−You can change the rounding rule by passing an argument to the `++ rs` core:
244−
245−```
246−> ~(add rs %u)
247−< 1.hsu
248− {{a/@rs b/@rs} <21.fan {r/?($n $u $d $z) <51.zox 93.pqh 74.dbd 1.qct $141>}>}
249−>
250−
251−> ~(add rs %d)
252−< 1.hsu
253− {{a/@rs b/@rs} <21.fan {r/?($n $u $d $z) <51.zox 93.pqh 74.dbd 1.qct $141>}>}
254−>
255−```
256−
257−Each of these expressions produces a version of the `add` gate from `rs`. By using `~( )` to pass `%u` to `rs` before producing `add`, you're creating an `add` gate for floats that rounds up. By passing `%d`, you're producing an `add` gate for floats that rounds down:
258−
259−```
260−> (~(add rs %u) .3.14159265 .1.11111111)
261−.4.252704
262−
263−> (~(add rs %d) .3.14159265 .1.11111111)
264−.4.2527037
265−```
266−
267−There are other uses for doors. Often you'll want a door to serve as a 'state machine'. That is, you'll want a core with data inside it representing various 'states' of the core. This mutable core data is stored in the core's sample. Usually the arms of such cores are designed to make use of the sample data, either by using the data to produce a value or by modifying the sample data.
268−
269−Doors can be used a lot like objects in object-oriented programming languages. The arms of doors are like computed attributes of objects.
270−
271−### `|_` Produce a Door, i.e., a Core with a Sample
272−
273−The `|_` rune is for producing a door. Syntactically it's like the `|%` rune, but it takes an extra subexpression to define the sample. The first subexpression following the `|_` defines the sample; then there is a series of arm definitions. This series is terminated with the `--` rune.
274−
275−For an example of a door 'in the wild', you can look at `++ rs` in the `hoon.hoon` standard library [here](https://github.com/urbit/arvo/blob/master/sys/hoon.hoon#L2752).
276−
277−Let's look at a simpler door, one that can be used as a state machine:
278−
279−```
280−|_ a/@
281− ++ this .
282− ::
283− ++ inc
284− this(a +(a))
285− ::
286− ++ plus
287− |= b=@
288− this(a (add a b))
289− ::
290− ++ reset
291− this(a 0)
292−--
293−```
294−
295−The door produced by this code has four arms and a sample `a` of the type `@`.
296−
297−But what is each arm doing? To put it briefly, the `inc` arm adds `1` to the atom in the sample, the `plus` arm adds `b` to the sample, and the `reset` arm resets the sample value to `0`.
298−
299−But in order to make the door behave like a state machine, these arms can't simply evaluate to an atom. Each of the arms above evaluates to a core. Specifically, they each evaluate to a version of the parent core.
300−
301−Remember, the subject of an arm is the core in which that arm is defined. The `this` arm evaluates simply to `.`, i.e., the unmodified parent core. `inc` evaluates to `this`, i.e., the parent core, but with the sample `a` modified to be `+(a)`. `plus` evaluates to `this` except with the sample `a` modified to be `(add a b)`. And `reset` evaluates to `this` but with the sample `a` set to `0`.
302−
303−To use a door as a state machine, put the door in the subject and modify that door using its arms. Let's do this in the dojo first, then we'll use a generator. Set the dojo face `num` to the `|_` expression above. You can paste the multi-line code above directly into the dojo if you like:
304−
305−```
306−> =num |_ a/@
307− ++ this .
308− ::
309− ++ inc
310− this(a +(a))
311− ::
312− ++ plus
313− |= b=@
314− this(a (add a b))
315− ::
316− ++ reset
317− this(a 0)
318− --
319−
320−> num
321−< 4.awp
322− { a/@
323− {our/@p now/@da eny/@uvJ}
324− <19.min 24.fmf 7.mpi 38.ard 119.spd 241.plj 51.zox 93.pqh 74.dbd 1.qct $141>
325− }
326−>
327−
328−> a.num
329−0
330−
331−> =num inc.num
332−
333−> a.num
334−1
335−
336−> =num inc.num
337−
338−> a.num
339−2
340−
341−> =num (plus:num 100)
342−
343−> a.num
344−102
345−
346−> =num reset.num
347−
348−> a.num
349−0
350−```
351−
352−As you can see, you never actually 'change' the `num` core literally; you actually produce a variant of that core and set that as the new value of `num`. You can see the sample value of `num` using `a.num`.
353−
354−Let's do the same sort of thing in a generator. Save the following as `numcore.hoon` in the `/gen` directory of your urbit's pier:
355−
356−```
357−|= c=@
358−=/ num :: define the `num` core
359− |_ a/@
360− ++ this .
361− ::
362− ++ inc
363− this(a +(a))
364− ::
365− ++ plus
366− |= b=@
367− this(a (add a b))
368− ::
369− ++ reset
370− this(a 0)
371− --
372−=. num inc.num :: increment the sample
373−=. num inc.num :: do it again
374−=. num (plus:num c) :: add `c` to the sample
375−=. num (plus:num c) :: do it again
376−a.num :: produce the sample value
377−```
378−
379−Now run it in the dojo:
380−
381−```
382−> +numcore 10
383−22
384−
385−> +numcore 100
386−202
387−
388−> +numcore 500
389−1.002
390−```
391−
392−Each of the `=.` expressions 'modifies' `num` by replacing the old `num` core with a different version of it. In this program we 'modify' `num` four times.
393−
394−For more on how to use cores as state machines see the next lesson.
395−
396−### [Next Lesson: Cores Again](../cores-again)
learn/hoon/hoon-tutorial/multi-gate-cores-and-doors.md → learn/hoon/hoon-tutorial/doors.mdrenamed+3−1
@@ -1,5 +1,5 @@
1+++
1+++
2−title = "Multi-gate Cores and Doors"
2+title = "1.8 Doors"
3weight = 16
3weight = 16
4template = "doc.html"
4template = "doc.html"
5+++
5+++
@@ -500,3 +500,5 @@ It's better simply to use the `~(arm rs arg)` syntax to replace the value of the
500## Conclusion
500## Conclusion
501
501
502You've now reached the end of Chapter 1 of the Hoon tutorial. Ideally you should have a fair understanding of the fundamental concepts of subject-oriented programming: limbs, legs, faces, wings, arms, cores, gates, and doors. If you can master these concepts you should have little or no trouble learning to write substantial Hoon programs. Continue to [Chapter 2](../hoon-programs) to get started.
502You've now reached the end of Chapter 1 of the Hoon tutorial. Ideally you should have a fair understanding of the fundamental concepts of subject-oriented programming: limbs, legs, faces, wings, arms, cores, gates, and doors. If you can master these concepts you should have little or no trouble learning to write substantial Hoon programs. Continue to [Chapter 2](../hoon-programs) to get started.
503+
504+### [Next Up: Walkthrough -- Bank Account](../bank-account)
learn/hoon/hoon-tutorial/examples.mddeleted−488
@@ -1,488 +0,0 @@
1−+++
2−title = "Examples"
3−weight = 33
4−template = "doc.html"
5−+++
6−Let's look at two more examples of Hoon code: the Sieve of Eratosthenes (a naive prime sieve) and a tic-tac-toe engine.
7−
8−## Sieve of Eratosthenes
9−
10−The following program produces the list of primes less than or equal to its argument, an atom:
11−
12−```
13−|= thru=@ :: 1
14−^- (list @) :: 2
15−=/ field=(set @) (sy (gulf 2 thru)) :: 3
16−|^ (sort ~(tap in sieve) lth) :: 4
17−++ sieve :: 5
18− =/ factor=@ 2 :: 6
19− |- ^- (set @) :: 7
20− ?: (gth (mul factor factor) thru) :: 8
21− field :: 9
22− $(factor +(factor), field (reap factor)) :: 10
23−:: :: 11
24−++ reap :: 12
25− |= factor=@ :: 13
26− =/ count=@ (mul 2 factor) :: 14
27− |- ^- (set @) :: 15
28− ?: (gth count thru) :: 16
29− field :: 17
30− %= $ :: 18
31− count (add count factor) :: 19
32− field (~(del in field) count) :: 20
33− == :: 21
34−-- :: 22
35−```
36−
37−Save it as `sieve.hoon` in `/gen` of your urbit's pier and run in the dojo:
38−
39−```
40−> +sieve 50
41−~[2 3 5 7 11 13 17 19 23 29 31 37 41 43 47]
42−```
43−
44−### Sieve Explanation
45−
46−```
47−|= thru=@ :: 1
48−^- (list @) :: 2
49−=/ field=(set @) (sy (gulf 2 thru)) :: 3
50−```
51−
52−Line 1: build a gate (function) whose sample (argument) is `thru`, an atom.
53−
54−Line 2: the product of this gate is a list of atoms.
55−
56−Line 3: introduce a face (variable) `field`, whose type is a set of atoms. `gulf` creates a list of atoms, from `2` to `thru` inclusive. The `sy` function converts this list to a set of those same atoms.
57−
58−```
59−|^ (sort ~(tap in sieve) lth) :: 4
60−++ sieve :: 5
61− ...
62−++ reap :: 12
63− ...
64−-- :: 22
65−```
66−
67−Before explaining line 4, let's first talk about what the `|^` rune is for. It creates a many-armed core, the first of which is named `$` and evaluated automatically. The first subexpression after the `|^` rune defines the `$` arm. This is followed by a series of arm definitions which is terminated with `--`.
68−
69−Line 4: introduce a core which does the desired work. The `$` arm is defined by the expression `(sort ~(tap in sieve) lth)`. The `sieve` arm of the core evaluates to a set of prime numbers in `field`. `tap` of `in` converts this set to a list, and `sort` arranges this list from least to greatest.
70−
71−```
72−++ sieve :: 5
73− =/ factor=@ 2 :: 6
74− |- ^- (set @) :: 7
75− ?: (gth (mul factor factor) thru) :: 8
76− field :: 9
77− $(factor +(factor), field (reap factor)) :: 10
78−```
79−
80−Lines 5-10 define the `sieve` arm of the `|^` core. This arm works as a loop, sieving out non-primes from `field` on every pass until no primes are left.
81−
82−Line 6: the `factor` face (variable) is given an initial value of `2`.
83−
84−Line 7: indicates a recursion start point, i.e., the loop start point. The product of the loop is cast to a `(set @)`, i.e., a set of atoms.
85−
86−Lines 8-9: if `(mul factor factor)` is greater than `thru` then there are no more primes in `field`. In that case, return `field`.
87−
88−Line 10: Otherwise there may still be primes in `field`. Recurse (i.e., loop back to `|-`) but with `factor` increased in value by `1` and with the value of `field` replaced with `(reap factor)`. What does `reap` do?
89−
90−```
91−++ reap :: 12
92− |= factor=@ :: 13
93− =/ count=@ (mul 2 factor) :: 14
94− |- ^- (set @) :: 15
95− ?: (gth count thru) :: 16
96− field :: 17
97− %= $ :: 18
98− count (add count factor) :: 19
99− field (~(del in field) count) :: 20
100− == :: 21
101−```
102−
103−Lines 12-21 define the `reap` arm of the core. This arm removes all multiples of `factor` from field except `factor` itself.
104−
105−Line 13 produces a gate (function) whose sample (argument) is an atom with the face `factor`.
106−
107−Line 14: sets the face (variable) `count` to the initial value of `(mul 2 factor)`.
108−
109−Line 15: indicates a recursion start point, i.e., a loop start point. The value produced by the loop is to be a `(set @)`, i.e., a set of atoms.
110−
111−Lines 16-17: if `count` is greater than `thru`, return `field`.
112−
113−Lines 18-21: otherwise, recurse (i.e. loop back to `|-`), but with the value of `count` changed to `(add count factor)` and `field` changed to `(~(del in field) count)`. `(~(del in field) count)` removes the atom `count` from `field`, if it's there.
114−
115−## Tic-tac-toe
116−
117−```
118− x | |
119−-----------
120− | x |
121−-----------
122− o | x | o
123−```
124−
125−The `toe` tic-tac-toe program below takes a list of tic-tac-toe moves -- for example the move `[%x %2 %1]` indicates an `x` in the bottom-center square -- and returns and end-game result, e.g., `%x-wins`.
126−
127−```
128−=< |= moves=(list move) :: 1
129− ^- outcome :: 2
130− ?~ moves ~ :: 3
131− =^ out game (step i.moves) :: 4
132− ?~ out $(moves t.moves) :: 5
133− out :: 6
134−:: :: 7
135−=> |% :: 8
136− +$ move [=player =spot] :: 9
137− +$ player ?(%x %o) :: 10
138− +$ spot [x=num y=num] :: 11
139− +$ num ?(%1 %2 %3) :: 12
140− +$ outcome $? ~ :: 13
141− %x-wins :: 14
142− %o-wins :: 15
143− %tie :: 16
144− == :: 17
145− -- :: 18
146−:: :: 19
147−|_ [board=(map spot player) last=?] :: 20
148−++ game . :: 21
149−:: :: 22
150−++ step :: 23
151− |= mov=move :: 24
152− ^- [outcome _game] :: 25
153− ?: ?| &(last =(player.mov %o)) :: 26
154− &(!last =(player.mov %x)) :: 27
155− == :: 28
156− ~&(%move-order !!) :: 29
157− ?: (~(has by board) spot.mov) ~&(%spot-taken !!) :: 30
158− =. board (~(put by board) [spot.mov player.mov]) :: 31
159− [outcome-check game(last !last)] :: 32
160−:: :: 33
161−++ outcome-check :: 34
162− ?: win-check :: 35
163− ?:(last %x-wins %o-wins) :: 36
164− ?:(tie-check %tie ~) :: 37
165−:: :: 38
166−++ win-check :: 39
167− =/ who=player ?:(last %x %o) :: 40
168− %+ lien winning-rows :: 41
169− |= a=(list spot) :: 42
170− %+ levy a :: 43
171− |= b=spot :: 44
172− =/ c=(unit player) (~(get by board) b) :: 45
173− ?~(c | =(who u.c)) :: 46
174−:: :: 47
175−++ tie-check :: 48
176− =(~(wyt in board) 9) :: 49
177−:: :: 50
178−++ winning-rows :: 51
179− ^- (list (list spot)) :: 52
180− :~ ~[[%1 %1] [%2 %1] [%3 %1]] :: 53
181− ~[[%1 %2] [%2 %2] [%3 %2]] :: 54
182− ~[[%1 %3] [%2 %3] [%3 %3]] :: 55
183− ~[[%1 %1] [%1 %2] [%1 %3]] :: 56
184− ~[[%2 %1] [%2 %2] [%2 %3]] :: 57
185− ~[[%3 %1] [%3 %2] [%3 %3]] :: 58
186− ~[[%1 %3] [%2 %2] [%3 %1]] :: 59
187− ~[[%1 %1] [%2 %2] [%3 %3]] :: 60
188− == :: 61
189−-- :: 62
190−```
191−
192−Save this as `toe.hoon` in `/gen` of your urbit's pier and run in the dojo:
193−
194−```
195−> +toe ~[[%x %2 %2]]
196−~
197−
198−> +toe ~[[%x %2 %2] [%o %1 %1] [%x %1 %3] [%o %3 %2] [%x %3 %1]]
199−%x-wins
200−
201−> +toe ~[[%x %2 %2] [%o %1 %3] [%x %1 %1] [%o %3 %3] [%x %2 %3] [%o %2 %1] [%x %1 %2] [%o %3 %2] [%x %3 %1]]
202−%tie
203−```
204−
205−### Tic-tac-toe Explanation
206−
207−```
208−=< |= moves=(list move) :: 1
209− ^- outcome :: 2
210− ?~ moves ~ :: 3
211− =^ out game (step i.moves) :: 4
212− ?~ out $(moves t.moves) :: 5
213− out :: 6
214−```
215−
216−Lines 1-6 constitute the main loop of the program. The game state (`game`) is modified for each `move` of the sample list until either the game ends in a victory or a tie, or there are no more moves to evaluate.
217−
218−Lines 1-2: the `=<` rune is used to put a core into the subject before running the gate. (We'll look at that core later in the code, but it's important to keep in mind that data from that core is used in lines 1-6.)
219−
220−The `|=` rune produces a gate whose sample is `(list move)`, where a `move` represents a single move of tic-tac-toe. The `^-` is used to cast for an `outcome`. `move` and `outcome` are custom types defined later in the code.
221−
222−Line 3: if there are no more moves in `moves`, the game ends without a victory or a tie.
223−
224−Line 4: additional context is needed to understand this line.
225−
226−`game`, as defined by code later in the program, is a door, i.e., a many-armed core with a sample. This door has two pieces of data in its sample: (1) data representing the current game board arrangement, and (2) data representing which player made the last move, `x` or `o`. We're basically using the `game` core as a state machine, where the core sample is the mutable state.
227−
228−`step` is a function (defined later) that takes a `move` and returns two things: (1) an `outcome`, and (2) a modified version of `game` with the board modified to account the latest move.
229−
230−The `=^` rune is used to evaluate the `step` call, setting the product `outcome` of (1) to `out`, and changing the value of `game` to the newer version from (2).
231−
232−Lines 5-6: if `out` is `~` (i.e., not a victory or a tie), then there is a recursion back to `|-` on the next `move` in the list. Otherwise, `out` is returned.
233−
234−```
235−=> |% :: 8
236− +$ move [=player =spot] :: 9
237− +$ player ?(%x %o) :: 10
238− +$ spot [x=num y=num] :: 11
239− +$ num ?(%1 %2 %3) :: 12
240− +$ outcome $? ~ :: 13
241− %x-wins :: 14
242− %o-wins :: 15
243− %tie :: 16
244− == :: 17
245− -- :: 18
246−```
247−
248−Lines 8-18 use a `|%` core to define all the custom types used in the program.
249−
250−Line 8: the `=>` rune is used to put the `|%` core into the subject before going on to evaluate something else later in the code. (This 'something else' is another core for defining `game`.)
251−
252−Line 9: the `move` type is for cells in which the head is a `player` and the tail is a `spot`. The `=player` and `=spot` syntax may be unfamiliar to you. The former is used to indicate that the `player` value should have a `player` face on it, and the latter to indicate that the `spot` value should have the `spot` face on it. If value `g` is known to be of the type `move`, you can get the `player` value with `player.g`.
253−
254−Line 10: the `player` type is for the set of two constants: `%x` and `%o`.
255−
256−Line 11: a `spot` is a pair of `num`s, one for the x coordinate and one for the y coordinate.
257−
258−Line 12: `num` is for the set of three constants: `%1`, `%2`, `%3`.
259−
260−Line 13: `outcome` is for the set of four constants: `~`, `%x-wins`, `%o-wins`, and `%tie`.
261−
262−```
263−|_ [board=(map spot player) last=?] :: 20
264−++ game . :: 21
265−:: :: 22
266−++ step :: 23
267− ...
268−++ outcome-check :: 34
269− ...
270−++ win-check :: 39
271− ...
272−++ tie-check :: 48
273− ...
274−++ winning-rows :: 51
275− ...
276−-- :: 62
277−```
278−
279−Lines 20-62 produce a door, i.e., a many-armed core with a sample. The sample of this core defines the game state, and the arms define the computations for making appropriate changes to that state. The `game` arm is trivial; it's just the value from `.`. Remember that `.` resolves to the entire subject, and that the subject of an arm computation is the parent core; hence, `game` is effectively a name of the entire door.
280−
281−The door has a two-part sample: `board` is a map from `spot` to `player`. `board` is essentially a record of which moves have already been made. `last` is a simple flag for keeping track of whose turn it is to make a move.
282−
283−```
284−++ step :: 23
285− |= mov=move :: 24
286− ^- [outcome _game] :: 25
287− ?: ?| &(last =(player.mov %o)) :: 26
288− &(!last =(player.mov %x)) :: 27
289− == :: 28
290− ~&(%move-order !!) :: 29
291− ?: (~(has by board) spot.mov) ~&(%spot-taken !!) :: 30
292− =. board (~(put by board) [spot.mov player.mov]) :: 31
293− [outcome-check game(last !last)] :: 32
294−```
295−
296−Lines 23-32 are for the `step` arm. This arm is the step function of the state machine. It takes a `move` and returns a pair of (1) `outcome` and (2) a new state for the `game` door.
297−
298−Lines 24-25: `mov` is the name of the `move` in the sample. The cast on line 25 is for a pair of `outcome` and a core of the same type as `game`. (Remember that `_game` is short for `$_(game)`.)
299−
300−Lines 26-30: these lines are for checking whether the correct player made the latest move. If not, the program will crash.
301−
302−The `?:` conditional on line 26 has a complex condition that spans three lines. If either of `&(last =(player.mov %o))` or `&(!last =(player.mov %x))` is true, the `true` branch is evaluated: `~&(%move-order !!)`.
303−
304−Let's look at the first more carefully. `&( )` is for logical AND, so `&(last =(player.mov %o))` is true if and only if both `last` and `=(player.mov %o)` are true. When `last` is true, it's `x`'s turn to make a move. If `o` moves out of turn, then the `!!` rune is used to crash the program.
305−
306−Line 30: checks whether the latest move is for a `board` square that is already taken. If `spot.mov` already has an assignment in `board`, the `!!` rune is used to crash the program.
307−
308−Line 31: modifies `board` by `put`ing the latest move into it.
309−
310−Line 32: return the pair of `outcome-check` and the `game` core with the `last` flag value flipped. (Remember that `!` is for logical NOT -- `!last` is opposite in value to `last`.) `outcome-check` is another arm in the core.
311−
312−```
313−++ outcome-check :: 34
314− ?: win-check :: 35
315− ?:(last %x-wins %o-wins) :: 36
316− ?:(tie-check %tie ~) :: 37
317−```
318−
319−Lines 34-37 define the `outcome-check` arm, which is used to check the state and see whether a final game outcome has occurred. First a `win-check` is performed to see whether the latest `move` is a winning one. If so, that player wins. Otherwise, a `tie-check` is performed.
320−
321−```
322−++ win-check :: 39
323− =/ who=player ?:(last %x %o) :: 40
324− %+ lien winning-rows :: 41
325− |= a=(list spot) :: 42
326− %+ levy a :: 43
327− |= b=spot :: 44
328− =/ c=(unit player) (~(get by board) b) :: 45
329− ?~(c | =(who u.c)) :: 46
330−```
331−
332−Lines 39-46 define the `win-check` arm, which is used to see whether the latest `move` is a winning one. `who` is the last player to make a move. This arm uses the `lien` and `levy` functions from the Hoon standard library.
333−
334−`lien` takes a list and a gate that produces a flag, and it applies the gate to each item in the list. If at least one of the resulting products is `%.y`, then `lien` produces `%.y`; otherwise, it produces a `%.n`. (You can think of `lien` as being a logical OR for a list.) For example:
335−
336−```
337−> =g `(list @)`~[10 11 12 13]
338−
339−> =h |=(a=@ (gth a 12))
340−
341−> (lien g h)
342−%.y
343−```
344−
345−`levy` is the same thing, except that it only evaluates to `%.y` if all applications of the gate to list items result in `%.y`. (You can think of `levy` as being a logical AND for a list.) For example:
346−
347−```
348−> =g `(list @)`~[10 11 12 13]
349−
350−> =h |=(a=@ (gth a 12))
351−
352−> (levy g h)
353−%.n
354−
355−> =h |=(a=@ (gth a 7))
356−
357−> (levy g h)
358−%.y
359−```
360−
361−With those functions in mind, let's get back to the code:
362−
363−```
364−++ win-check :: 39
365− =/ who=player ?:(last %x %o) :: 40
366− %+ lien winning-rows :: 41
367− |= a=(list spot) :: 42
368− %+ levy a :: 43
369− |= b=spot :: 44
370− =/ c=(unit player) (~(get by board) b) :: 45
371− ?~(c | =(who u.c)) :: 46
372−```
373−
374−Lines 41-46: `winning-rows` is an arm that evaluates to a list of the eight victory conditions for tic-tac-toe. `lien` is used to determine if at least one of these eight conditions holds for the last player to make a move.
375−
376−Each victory condition is recorded as a list of spots. `levy` is used to determine whether the player has his mark on all of those spots. If so, the last player wins.
377−
378−The `~(get by board)` call is used to see which player has a mark on the spot in question, `b`. `get` of `by` returns a `unit`, which means that `c` must be a `(unit player)`, not just a `player`. We must use `?~` to test whether `c` is null before we can get the raw player data using `u.c`.
379−
380−If no player has a mark at spot `b`, then the `~(get by board)` call returns `~`, null.
381−
382−```
383−++ tie-check :: 48
384− =(~(wyt in board) 9) :: 49
385−```
386−
387−Lines 48-49 define the `tie-check` arm, which is used to see if the result is a tie game. The game is tied if all nine `board` squares are taken and no one has won. Because the `win-check` occurs before the `tie-check`, we only need to determine if all nine `board` squares have been taken.
388−
389−We use `wyt` of `in` to check how many squares have been taken; if it's `9`, then return `%.y`, otherwise `%.n`. `wyt` is a function that returns the number of items in a set. It can be used for maps as well.
390−
391−```
392−++ winning-rows :: 51
393− ^- (list (list spot)) :: 52
394− :~ ~[[%1 %1] [%2 %1] [%3 %1]] :: 53
395− ~[[%1 %2] [%2 %2] [%3 %2]] :: 54
396− ~[[%1 %3] [%2 %3] [%3 %3]] :: 55
397− ~[[%1 %1] [%1 %2] [%1 %3]] :: 56
398− ~[[%2 %1] [%2 %2] [%2 %3]] :: 57
399− ~[[%3 %1] [%3 %2] [%3 %3]] :: 58
400− ~[[%1 %3] [%2 %2] [%3 %1]] :: 59
401− ~[[%1 %1] [%2 %2] [%3 %3]] :: 60
402− == :: 61
403−```
404−
405−Lines 51-61 define the `winning-rows` arm, which produces a list of the eight victory conditions for tic-tac-toe. Each victory condition is a list of three `spot`s. The `:~` rune is used to produce a list from a series of expressions, terminated with `==`.
406−
407−Now you know how to write tic-tac-toe in Hoon!
408−
409−## Exercise: Conway's Game of Life
410−
411−Conway's Game of Life is a zero-player game played on an `n x n` grid of spaces, each of which is either 'alive' or 'dead'. Every iteration, some or all of the spaces change from alive to dead or from dead to alive.
412−
413−Specifically, for each iteration, each dead space becomes alive if and only if it is adjacent to exactly three live spaces. Each live remains alive if and only if it is adjacent to either two or three live spaces. In this context, "adjacent to" includes the eight spaces that share either a side or a corner with the space. Thus, in the following map, the center space (dead) is adjacent to exactly three live spaces, so it will be alive in the next iteration. `#` signifies a live space and `.` signifies a dead space.
414−
415−```
416− ..#
417− ...
418− ##.
419−```
420−
421−+ Write a function `next-generation` that takes nine flag inputs, `nw`, `nc`, `ne`, `cw`, `cc`, `ce`, `sw`, `sc`, and `se`. Produce 'yes' if the center space will be alive in the next generation and 'no' if it will be dead.
422−
423−+ Write a function `create-board` that takes an integer `n` and produces an `n` by `n` grid of flags, (hereafter, "board"), initialized to 'no'. This grid should be represented as a list of `n` lists of length `n`.
424−
425−+ Write a function `toggle-space` that takes a board, a row index, and a column index, and produces a new board, identical to the old except that the state of the space referred to by the row and column indices has been toggled.
426−
427−+ Use the following function `print-board` to pretty-print the board. For bonus points, try to follow what it's doing.
428−
429− ```
430− |= board=(list (list ?))
431− ^- tang
432− %+ turn board
433− |= row=(list ?)
434− :- %leaf
435− ^- tape
436− %+ turn row
437− |= space=?
438− ?: space
439− '# '
440− '. '
441− ```
442−
443− If you run this function with a board, you'll get a
444− pretty-printable object (a `tang`), but it won't be
445− pretty-printed. When running the generator from the dojo,
446− run `&tang +generator arguments` to mark the result as a
447− `tang`, which will tell the dojo to pretty-print it
448− appropriately.
449−
450−+ Using the functions created in the previous exercises, create a 10 by 10 board, and flip the states of the spaces at coordinates (counting from the top left, indexed from 0) `(2,1)`, `(3,2)`, `(1,3)`, `(2,3)`, and `(3,3)`. Use the pretty printer to print out the board. Your output should be the following:
451−
452− ```
453− . . . . . . . . . .
454− . . # . . . . . . .
455− . . . # . . . . . .
456− . # # # . . . . . .
457− . . . . . . . . . .
458− . . . . . . . . . .
459− . . . . . . . . . .
460− . . . . . . . . . .
461− . . . . . . . . . .
462− . . . . . . . . . .
463− ```
464−
465−+ Write a function `step` that iterates every space on the board. Print out the new board. It should look like this:
466−
467− ```
468− . . . . . . . . . .
469− . . . . . . . . . .
470− . # . # . . . . . .
471− . . # # . . . . . .
472− . . # . . . . . . .
473− . . . . . . . . . .
474− . . . . . . . . . .
475− . . . . . . . . . .
476− . . . . . . . . . .
477− . . . . . . . . . .
478− ```
479−
480− > Note that the spaces on the edge don't have the full nine neighbors. For now, assume that they're always dead.
481−
482−+ Write a function `life` that runs the above function `n` times on the board. Observe the board as the game progresses. Congratulations, you've written Conway's Game of Life in Hoon!
483−
484−+ One common way to handle the edge of the board is to pretend that it "wraps around", forming a torus. In other words, say that the spaces on the left edge of the map are adjacent to the ones on the right edge, and the spaces on the top edge are adjacent to the spaces on the bottom edge. Modify `step` to act this way. Pay special attention to the corners.
485−
486−+ Modify `create-board` to use `++og` to randomly initialize the board with live or dead spaces.
487−
488−### [Next Lesson: Type Polymorphism](../type-polymorphism)
learn/hoon/workbook/fib.md → learn/hoon/hoon-tutorial/fibonacci.mdrenamed+8
@@ -1,3 +1,9 @@
1++++
2+title = "1.4.1 Walkthrough: Fibonacci Sequence"
3+weight = 7
4+template = "doc.html"
5++++
6+
1In this example, we will write a generator that produces a list of Fibonacci numbers up to `n`.
7In this example, we will write a generator that produces a list of Fibonacci numbers up to `n`.
2
8
3```
9```
@@ -52,3 +58,5 @@ In the code above, `?:` checks whether the first child, `=(i n)`, our terminatin
52```
58```
53
59
54The final expression in our program calls the `$` arm of the trap we are but makes some changes: we increment `i`, set `p` to be `q` and `q` becomes the sum of `p` and `q`. `r` becomes a cell of `q` and whatever `r` was previously. The list built from this is the one that will get `flop`ped to produce the result at the end of the computation.
60The final expression in our program calls the `$` arm of the trap we are but makes some changes: we increment `i`, set `p` to be `q` and `q` becomes the sum of `p` and `q`. `r` becomes a cell of `q` and whatever `r` was previously. The list built from this is the one that will get `flop`ped to produce the result at the end of the computation.
61+
62+### [Next Up: Reading -- Gates](../gates)
learn/hoon/hoon-tutorial/gates.md+4−4
@@ -1,6 +1,6 @@
1+++
1+++
2title = "Gates (Hoon Functions)"
2title = "Gates (Hoon Functions)"
3−weight = 15
3+weight = 8
4template = "doc.html"
4template = "doc.html"
5+++
5+++
6In this lesson you're going to learn about Hoon functions.
6In this lesson you're going to learn about Hoon functions.
@@ -167,7 +167,7 @@ Let's look at the context of `inc`:
167
167
168This is exactly the default dojo subject, from before we put `inc` into the subject. The `|=` expression defines the context as whatever the subject is. This guarantees that the context has all the information it needs to have for the `$` arm to work correctly.
168This is exactly the default dojo subject, from before we put `inc` into the subject. The `|=` expression defines the context as whatever the subject is. This guarantees that the context has all the information it needs to have for the `$` arm to work correctly.
169
169
170−### Exercise 1.5.1
170+### Exercise 1.5.1a
171
171
172Write a gate that takes an atom, `a=@`, and which returns double the value of `a`. Bind this gate to `double` and test it in the dojo. A solution is given at the end of this lesson.
172Write a gate that takes an atom, `a=@`, and which returns double the value of `a`. Bind this gate to `double` and test it in the dojo. A solution is given at the end of this lesson.
173
173
@@ -257,7 +257,7 @@ Before finishing the lesson let's unbind `ten`:
257> =ten
257> =ten
258```
258```
259
259
260−## Exercise 1.5.1 Solution
260+## Exercise 1.5a Solution
261
261
262Write a gate that takes an atom, `a=@`, and which returns double the value of `a`. Bind this gate to `double` and test it in the dojo.
262Write a gate that takes an atom, `a=@`, and which returns double the value of `a`. Bind this gate to `double` and test it in the dojo.
263
263
@@ -271,4 +271,4 @@ Write a gate that takes an atom, `a=@`, and which returns double the value of `a
27150
27150
272```
272```
273
273
274−### [Next Lesson: Multi-gate Cores and Doors](../multi-gate-cores-and-doors)
274+### [Next Up: Walkthrough -- Recursion](../recursion)
learn/hoon/hoon-tutorial/hoon-programs.mddeleted−162
@@ -1,162 +0,0 @@
1−+++
2−title = "Hoon Programs"
3−weight = 21
4−template = "doc.html"
5−+++
6−So far you've only entered short snippets of Hoon code into the dojo. Let's look at some substantive programs.
7−
8−There many kinds of Hoon programs: generators, Gall apps, Sail documents, and more. In this chapter we'll work exclusively with a subset of the first kind: generators. This narrow focus will allow us to set aside complications that aren't necessary for learning the basics of Hoon. We won't even talk about the full range of generators supported in Urbit just yet. Other kinds of programs will be covered in other lessons.
9−
10−## Setup
11−
12−For now we'll work exclusively with 'naked' generators. A naked generator is a gate that can be run from the dojo and that takes exactly one argument for its sample. Generators are to be stored in the `/gen` directory of your urbit's filesystem.
13−
14−To use your favorite text editor to write Hoon programs you'll first need to expose your urbit's filesystem to Unix. If you haven't already done so, 'mount' your home desk as follows:
15−
16−```
17−> |mount %
18−>=
19−```
20−
21−(Note: we are assuming that you have mounted from your 'home' desk in the dojo. If you don't know what this means, don't worry -- this only matters if you have changed directories since you've booted your urbit, and you probably haven't.)
22−
23−Mounting may take a moment. The `>=` response means the command is successful. From the command line (or your favorite file explorer) you should be able to see a `/home` directory in your urbit's pier, and in that directory is `/gen`. This is where you'll put Hoon source files in order to run them from the dojo.
24−
25−## List of Numbers
26−
27−Let's look at a Hoon program that implements a simple function: it takes as input some atom `n` and returns a list of all the atoms from `1` up to `n`. (Remember that an atom is just an unsigned integer.)
28−
29−Each line is commented with a number for convenient line reference:
30−
31−```
32−|= end=@ :: 1
33−=/ count=@ 1 :: 2
34−|- :: 3
35−^- (list @) :: 4
36−?: =(end count) :: 5
37− ~ :: 6
38−:- count :: 7
39−$(count (add 1 count)) :: 8
40−```
41−
42−Save this as 'listnum.hoon' in `/home/gen` of your urbit's pier. To run it enter `+listnum 25` in the dojo:
43−
44−```
45−> +listnum 25
46−~[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24]
47−```
48−
49−Note that `~[item-1 item-2 item-3 ...]` is, by convention, the way the dojo pretty-prints lists.
50−
51−### Functional Programming, Runes, and Whitespace
52−
53−Before going over how the above code works we should point out three things.
54−
55−First, when Listnum is written in a non-functional language it's typically simpler to generate the output as a side effect of the program, e.g., with a `printf()` command inside a loop. Hoon is a functional language, so the code above instead defines a function. Officially, functions don't have side effects. The `listnum` function takes an atom as its input, and then returns an entire list of atoms as a single piece of data.
56−
57−Second, one syntactic feature of Hoon that distinguishes it from other programming languages is its use of _runes_ rather than keywords. A rune is just a pair of non-alphanumeric ASCII characters. Below we give a brief explanation of each of the runes used so you can have a rough idea of how the program works.
58−
59−Finally, it's important to know that whitespace is more strictly regulated in Hoon than it is in most other languages. Attempting to run a Hoon program with incorrect spacing results in a syntax error. The spacing rules will be explained in the next lesson.
60−
61−### High Level Overview
62−
63−The program returns a list of numbers, `(list @)`, from `1` up to `end`. But what do we mean by a 'list'?
64−
65−There are two kinds of lists in Hoon: empty and non-empty. The empty list has nothing in it; it's just the null value, `~`. A non-empty list has at least one item and is a cell of the following sort:
66−
67−```
68−[item-1 rest-of-list]
69−```
70−
71−That is, the head of the cell is the first list item, and the tail is the rest of the list. The tail is itself another list. In Hoon, the end of a list is indicated with the null character, `~`. Accordingly, we say that lists in Hoon are 'null-terminated'.
72−
73−Below are binary trees representing a two-item list and a four-item list, respectively:
74−
75−```
76−two items: [item-1 [item-2 ~]]
77−
78− .
79− / \
80− item-1 .
81− / \
82− item-2 ~
83−
84−four items: [item-1 [item-2 [item-3 [item-4 ~]]]]
85−
86− .
87− / \
88− item-1 .
89− / \
90− item-2 .
91− / \
92− item-3 .
93− / \
94− item-4 ~
95−```
96−
97−So, for example, the list of atoms `1 2 3 4` is structured as the following noun:
98−
99−```
100− [1 [2 [3 [4 ~]]]]
101−
102− .
103− / \
104− 1 .
105− / \
106− 2 .
107− / \
108− 3 .
109− / \
110− 4 ~
111−```
112−
113−(Note that `~[1 2 3 4]` is equivalent to `[1 2 3 4 ~]`. The former is how the dojo pretty-prints lists.)
114−
115−The program is to generate the appropriate list of numbers given an input value, `end`: `~[1 2 3 ...]`. How?
116−
117−Essentially, the program uses a loop to produce the list. Assuming the initial value of `end` is `> 1`, a cell is created in which the head is the value `count`. The tail is the rest of the list, itself a list. It's created by incrementing `count` by `1`, and then looping and running the same code again. When `count` equals `end`, the list is complete and the program ends.
118−
119−Let's look at the code line-by-line.
120−
121−### Listnum.hoon: Code explanation
122−
123−```
124−|= end=@ :: 1
125−=/ count=@ 1 :: 2
126−|- :: 3
127−^- (list @) :: 4
128−```
129−
130−Line 1 uses the gate rune, `|=`, to define a function that takes one argument (i.e., input value). The argument labelled `end` is stored as the gate's sample; and the sample must be of the type `@`, an atom. The rest of the program determines the value to be returned by the function.
131−
132−Line 2 uses `=/` to put an atom into the subject, `1`, labelled `count`. This is analogous to defining a variable and giving it an initial value in other languages.
133−
134−Line 3 uses `|-` to indicate a loop starting point. We'll give `|-` a more precise definition later in the chapter.
135−
136−Line 4 uses a 'cast' rune, `^-`, to define the product of the loop as a `(list @)`, i.e., as a list of atoms. If the rest of the program following `(list @)` doesn't provably evaluate to a list of atoms, the program will fail to compile.
137−
138−```
139−?: =(end count) :: 5
140− ~ :: 6
141−```
142−
143−The `?:` rune in line 5 is an ordinary "if-then-else" conditional. If the expression that comes directly after it, `=(end count)`, evaluates to true, then the expression on line 6 is evaluated; otherwise the code starting at line 7 is evaluated. `=(end count)` itself is nothing more than a test of equality on `end` and `count`.
144−
145−If the values of `count` and `end` are equal then line 6 produces the
146−value `~`, null. This indicates the end of the list. When `count` is equal to `end`, the program is finished.
147−
148−Otherwise...
149−
150−```
151−:- count :: 7
152−$(count (add 1 count)) :: 8
153−```
154−
155−If not, line 7 uses the rune `:-` to produce a cell. Why is the program producing a cell here? Remember that cells are used to represent non-null lists in Hoon. The head of the cell is the value `count` and the tail is the product of evaluating `$(count (add 1 count))`.
156−
157−The product of the `$( )` call on line 8 is another list. It essentially says that the value of `count` is to be replaced by `(add 1 count)`, and that the code starting at `|-` is to be run again.
158−
159−And that's it!
160−
161−
162−### [Next Lesson: Hoon Syntax](../hoon-syntax)
learn/hoon/hoon-tutorial/hoon-syntax.md+3−4
@@ -1,9 +1,8 @@
1+++
1+++
2−title = "Hoon Syntax"
2+title = "1.3 Hoon Syntax"
3−weight = 13
3+weight = 6
4template = "doc.html"
4template = "doc.html"
5+++
5+++
6−# 1.3 Hoon Syntax
7
6
8The study of Hoon can be divided into two parts: syntax and semantics.
7The study of Hoon can be divided into two parts: syntax and semantics.
9
8
@@ -323,4 +322,4 @@ There are a couple useful runes associated with debugging:
323
322
324But there are more. Check out the aforementioned [troubleshooting](/docs/reference/troubleshooting/) page to see other handy debugging runes and how to use them.
323But there are more. Check out the aforementioned [troubleshooting](/docs/reference/troubleshooting/) page to see other handy debugging runes and how to use them.
325
324
326−### [Next Lesson: The Subject and Its Legs](../the-subect-and-its-legs)
325+### [Next Up: Reading -- Lists](../lists)
learn/hoon/workbook/list.md → learn/hoon/hoon-tutorial/list-of-numbers.mdrenamed+6−5
@@ -1,13 +1,12 @@
1+++
1+++
2−title = "List of Numbers"
2+title = "1.1.1 Walkthrough: List of Numbers"
3−weight = 1
3+weight = 3
4template = "doc.html"
4template = "doc.html"
5+++
5+++
6This code-example is intended to familiarize you with the basics of Hoon syntax. It's okay if you don't understand everything immediately; some concepts may beyond your grasp for now. What's important is that you become accustomed to the elements of the code and their look once combined into a valid program.
6This code-example is intended to familiarize you with the basics of Hoon syntax. It's okay if you don't understand everything immediately; some concepts may beyond your grasp for now. What's important is that you become accustomed to the elements of the code and their look once combined into a valid program.
7
7
8Below is a simple Hoon program that takes a single number `n` from the user as input and produces a list of numbers from `1` up to (but not including) `n`. So, if the user gives the number `5`, the program will produce: `~[1 2 3 4]`.
8Below is a simple Hoon program that takes a single number `n` from the user as input and produces a list of numbers from `1` up to (but not including) `n`. So, if the user gives the number `5`, the program will produce: `~[1 2 3 4]`.
9
9
10−
11```
10```
12|= end=@ :: 1
11|= end=@ :: 1
13=/ count=@ 1 :: 2
12=/ count=@ 1 :: 2
@@ -19,7 +18,7 @@ Below is a simple Hoon program that takes a single number `n` from the user as i
19$(count (add 1 count)) :: 8
18$(count (add 1 count)) :: 8
20```
19```
21
20
22−The easiest way to use such a program is to run it as a _generator_. Saving a file in the `/home/gen` directory of your ship allows you to run it from your ship's Dojo (command line) as a generator. Save the above code there as `list.hoon`. Now you can run it in the Dojo as so:
21+As we mentioned in the previous lesson, the easiest way to use such a program is to run it as a _generator_. Saving a file in the `/home/gen` directory of your ship allows you to run it from your ship's Dojo (command line) as a generator. Save the above code there as `list.hoon`. Now you can run it in the Dojo as so:
23
22
24`~your-ship:> +list 5`
23`~your-ship:> +list 5`
25
24
@@ -128,4 +127,6 @@ Our program works by having each iteration of the list creating a cell. In each
128 4 ~
127 4 ~
129```
128```
130
129
131−If you still don't intuit how this is working, don't worry. We'll take a deeper look into recursion later with our [Recursion example](../recursion).
130+If you still don't intuit how this is working, don't worry. We'll take a deeper look into recursion later with our [Recursion walkthrough](../recursion).
131+
132+### [Next Up: Reading -- Nouns](../nouns)
learn/hoon/hoon-tutorial/lists.md+4−3
@@ -1,8 +1,9 @@
1+++
1+++
2−title = "Standard Library: Lists"
2+title = "1.4 Lists"
3−weight = 29
3+weight = 6
4template = "doc.html"
4template = "doc.html"
5+++
5+++
6+
6In this lesson we'll review what a list is and then cover many of the list-related functions in the Hoon standard library.
7In this lesson we'll review what a list is and then cover many of the list-related functions in the Hoon standard library.
7
8
8## List Review
9## List Review
@@ -383,4 +384,4 @@ Run in dojo:
38333
38433
384```
385```
385
386
386−### [Next Lesson: Trees, Sets, and Maps](../trees-sets-and-maps)
387+### [Next Up: Walkthrough -- Fibonacci Sequence](../fibonacci)
learn/hoon/hoon-tutorial/nouns.md+12−24
@@ -1,9 +1,9 @@
1+++
1+++
2−title = "Nouns"
2+title = "1.2 Nouns"
3−weight = 12
3+weight = 4
4template = "doc.html"
4template = "doc.html"
5+++
5+++
6−In Urbit every piece of data is a noun. In order to understand Hoon one must first understand nouns.
6+In Urbit every piece of data is a noun. In order to understand Hoon, one must first understand nouns.
7
7
8## Noun Definition
8## Noun Definition
9
9
@@ -24,18 +24,6 @@ Here are some cells:
24
24
25All of the above are nouns.
25All of the above are nouns.
26
26
27−## Recursive Definitions
28−
29−You may or may not have noticed that the definition of 'noun' is [recursive](https://en.wikipedia.org/wiki/Recursion). Recursion is an important concept for functional programming, so it's worth taking a moment to understand it better.
30−
31−A recursive definition has three clauses: a base clause, a generating clause, and a closure clause. Let's say you want to use recursion to define some X. The definition should allow one to determine whether any given object is a member of X. The **base clause** of the recursive definition defines one or more objects as trivial members of X. The **generating clause** defines other objects as also being X by their relationship to previously established members of X. The **closure clause** asserts that nothing else is a member of X than what has been given in the first two clauses. Often the closure clause is not explicitly stated.
32−
33−For example, let's say you want to define the phrase 'ancestor of George Washington'. Which 'objects' are members of that set? The base clause is simple: the parents of George Washington are trivial ancestors of George Washington. The generating clause is: given that some x is an ancestor of George Washington, the parents of x are also ancestors of George Washington. The closure clause is: nothing else is an ancestor of George Washington. That's it!
34−
35−Let's restate the definition of **noun** in these terms. The base clause of the definition of a 'noun' is: all atoms are nouns (where an 'atom' is an unsigned integer). The generating clause is: if x and y are nouns, then the cell `[x y]` is also a noun. (A 'cell' is an ordered pair of nouns.). The closure clause is: nothing else is a noun.
36−
37−We belabor this point about recursion only because it's an important concept for having a firm grasp of functional programming. We'll talk more about recursion at various points in this series.
38−
39### Nouns as Binary Trees
27### Nouns as Binary Trees
40
28
41A [binary tree](https://en.wikipedia.org/wiki/Binary_tree) has a single base node, and each node of the tree may have up to two child nodes (but it need not have any). A node without children is a 'leaf'. You can think of a noun as a binary tree whose leaves are atoms, i.e., unsigned integers. All non-leaf nodes are cells. To visualize this, consider the following representation of the noun: `[12 [17 45]]`:
29A [binary tree](https://en.wikipedia.org/wiki/Binary_tree) has a single base node, and each node of the tree may have up to two child nodes (but it need not have any). A node without children is a 'leaf'. You can think of a noun as a binary tree whose leaves are atoms, i.e., unsigned integers. All non-leaf nodes are cells. To visualize this, consider the following representation of the noun: `[12 [17 45]]`:
@@ -178,7 +166,7 @@ All of the above are atoms. The underlying noun of each is just an unsigned int
178313
166313
179```
167```
180
168
181−The `\`@\`` syntax is used to 'cast' a value to a raw atom, i.e., an atom without an aura. Don't worry about exactly what `\`@\`` means just yet. Casts will be explained in more detail in a later lesson. For now all you need to know is that a cast doesn't change the underlying value of the noun; it's used here only to change how the value is printed in the dojo output.
169+The `` `@` `` syntax is used to 'cast' a value to a raw atom, i.e., an atom without an aura. Don't worry about exactly what `` `@` `` means just yet. Casts will be explained in more detail in a later lesson. For now all you need to know is that a cast doesn't change the underlying value of the noun; it's used here only to change how the value is printed in the dojo output.
182
170
183#### Identities, Cords, and Terms
171#### Identities, Cords, and Terms
184
172
@@ -351,7 +339,7 @@ When the dojo pretty-prints a cell it always removes superfluous cell brackets:
351
339
352However, you should always remember that though cells can be presented as lists of more than two nouns, they're always just pairs.
340However, you should always remember that though cells can be presented as lists of more than two nouns, they're always just pairs.
353
341
354−### Exercise 1.2.1
342+### Exercise 1.2a
355
343
356Without using the dojo, assess whether each of the following pairs of nouns is equivalent. (Answers are at the bottom of the page.)
344Without using the dojo, assess whether each of the following pairs of nouns is equivalent. (Answers are at the bottom of the page.)
357
345
@@ -438,7 +426,7 @@ As before, the root of the binary tree (i.e., the whole noun) is at address `1`.
438
426
439Address `1110` indicates "the head of the tail of the tail of the noun".
427Address `1110` indicates "the head of the tail of the tail of the noun".
440
428
441−### Exercise 1.2.2
429+### Exercise 1.2b
442
430
443Without using the dojo, evaluate the following expressions. (Answers are at the bottom of the page.)
431Without using the dojo, evaluate the following expressions. (Answers are at the bottom of the page.)
444
432
@@ -450,7 +438,7 @@ Without using the dojo, evaluate the following expressions. (Answers are at the
4505. +10:[[[2 4 5] [3 6]] 11]
4385. +10:[[[2 4 5] [3 6]] 11]
451```
439```
452
440
453−### Exercise 1.2.3
441+### Exercise 1.2c
454
442
455Without using the dojo, for each fragment below provide the address relative to the noun `[51 52 53 54 55]`. (Answers are at the bottom of the page.)
443Without using the dojo, for each fragment below provide the address relative to the noun `[51 52 53 54 55]`. (Answers are at the bottom of the page.)
456
444
@@ -464,9 +452,9 @@ Without using the dojo, for each fragment below provide the address relative to
464
452
465That's it for our basic introduction to nouns. Hit `ctrl-d` to exit your comet, or else move on to the next lesson.
453That's it for our basic introduction to nouns. Hit `ctrl-d` to exit your comet, or else move on to the next lesson.
466
454
467−## 1.1 Exercise Answers
455+## Exercise Answers
468
456
469−### 1.1.1
457+### 1.2a
470
458
471+ No
459+ No
472+ Yes
460+ Yes
@@ -474,7 +462,7 @@ That's it for our basic introduction to nouns. Hit `ctrl-d` to exit your comet,
474+ Yes
462+ Yes
475+ Yes
463+ Yes
476
464
477−### 1.1.2
465+### 1.2b
478
466
479+ 86
467+ 86
480+ [[[65 35] 54] 77]
468+ [[[65 35] 54] 77]
@@ -482,7 +470,7 @@ That's it for our basic introduction to nouns. Hit `ctrl-d` to exit your comet,
482+ 77
470+ 77
483+ 3
471+ 3
484
472
485−### 1.1.3
473+### 1.2c
486
474
487+ +2
475+ +2
488+ +6
476+ +6
@@ -490,4 +478,4 @@ That's it for our basic introduction to nouns. Hit `ctrl-d` to exit your comet,
490+ +15
478+ +15
491+ +31
479+ +31
492
480
493−### [Next Lesson: The Subject and Its Legs](../the-subject-and-its-legs)
481+### [Next Up: Reading -- Conditionals](../conditionals)
learn/hoon/workbook/recursion.md → learn/hoon/hoon-tutorial/recursion.mdrenamed+7−5
@@ -1,6 +1,6 @@
1+++
1+++
2−title = "Recursion"
2+title = "1.5.1 Walkthrough: Recursion"
3−weight = 3
3+weight = 9
4template = "doc.html"
4template = "doc.html"
5+++
5+++
6Recursion is a common pattern for solving certain problems in most programming
6Recursion is a common pattern for solving certain problems in most programming
@@ -76,7 +76,7 @@ expression, as illustrated by `(factorial 4)`. Once the expression cannot be
76expanded out further, the operations work backwards, successively feeding values
76expanded out further, the operations work backwards, successively feeding values
77into the `mul` functions behind them.
77into the `mul` functions behind them.
78
78
79−##### Tail-Call Optimization
79+#### Tail-Call Optimization
80
80
81Our last example isn't a very efficient use computing resources. The
81Our last example isn't a very efficient use computing resources. The
82pyramid-shaped illustration approximates what's happening on the **call stack**, a
82pyramid-shaped illustration approximates what's happening on the **call stack**, a
@@ -119,7 +119,7 @@ last statement of a parent can reuse the same frame instead of needing to
119add new ones onto the stack. If we write our code properly, we can use a single
119add new ones onto the stack. If we write our code properly, we can use a single
120frame that simply has its values replaced with each recursion.
120frame that simply has its values replaced with each recursion.
121
121
122−##### A Tail-Recursive Gate
122+#### A Tail-Recursive Gate
123
123
124With a bit of refactoring, we can write a version of our factorial gate that
124With a bit of refactoring, we can write a version of our factorial gate that
125_is_ tail-recursive and can take advantage of this feature:
125_is_ tail-recursive and can take advantage of this feature:
@@ -170,7 +170,7 @@ before the call, this version is properly tail-recursive. We don't need to do
170anything to the result of the recursion except recurse it again. That means that
170anything to the result of the recursion except recurse it again. That means that
171each iteration can be replaced instead of held in memory.
171each iteration can be replaced instead of held in memory.
172
172
173−##### A Note on `$`
173+#### A Note on `$`
174
174
175`$` (pronounced "buc") is, in its use with recursion, a reference to the gate that we are inside
175`$` (pronounced "buc") is, in its use with recursion, a reference to the gate that we are inside
176of. That's because a gate is just a core with a single arm named `$`. The
176of. That's because a gate is just a core with a single arm named `$`. The
@@ -190,3 +190,5 @@ skips the first match of a name.
190Disks are stacked on a pole by decreasing order of size. Move all of the
190Disks are stacked on a pole by decreasing order of size. Move all of the
191disks from one pole to another with a third pole as a spare, moving one
191disks from one pole to another with a third pole as a spare, moving one
192disc at a time, without putting a larger disk on top of a smaller disk.
192disc at a time, without putting a larger disk on top of a smaller disk.
193+
194+### [Next Up: Reading -- The Subject and its Legs](../lists)
learn/hoon/hoon-tutorial/setup.md+14−6
@@ -1,15 +1,15 @@
1+++
1+++
2−title = "Setup"
2+title = "1.1 Setup"
3−weight = 11
3+weight = 1
4template = "doc.html"
4template = "doc.html"
5+++
5+++
6−Before we begin working on Hoon you should first (1) have Urbit installed and (2) boot an 'urbit' that you can use for trying out Hoon examples. Interactive learning is far superior to passive reading.
6+Before we begin working on Hoon, you should first (1) have Urbit installed and (2) boot a ship that you can use for trying out Hoon examples. If you Interactive learning is far superior to passive reading.
7
7
8## Installing Urbit
8## Installing Urbit
9
9
10−You can [install Urbit](/docs/getting-started) on any Mac or Unix machine; follow the steps for creating a development ship. On Windows, make a virtual Linux machine using VirtualBox or a similar tool.
10+You can install Urbit on any Mac or Unix machine; follow the steps for [creating a development ship](/docs/using/creating-a-development-ship). On Windows, make a virtual Linux machine using VirtualBox or a similar tool.
11
11
12−Once you're finished you can boot your very own urbit.
12+Once you're finished you can boot your very own ship.
13
13
14## What is an urbit?
14## What is an urbit?
15
15
@@ -108,4 +108,12 @@ You'll see:
108
108
109You asked dojo to evaluate `17` and it echoed the number back at you. This value is a 'noun'. But what is a noun? Move on to lesson 1.2 for the answer.
109You asked dojo to evaluate `17` and it echoed the number back at you. This value is a 'noun'. But what is a noun? Move on to lesson 1.2 for the answer.
110
110
111−### [Next Lesson: Nouns](../nouns)
111+## Generators
112+
113+Generators are the most straightforward way to write Hoon programs. They are a concept in Arvo, and involve saving Hoon code in a `.hoon` text file. While they aren't strictly part of the Hoon language, we'll be dealing with generators throughout this tutorial.
114+
115+The simplest type of generator is the **naked generator**. All naked generators are `gates`: functions that take an argument and produce an output. So, to create a generator, all you need to do is write a `gate` and put it into a file in the `/home/gen` directory of your ship as a `.hoon` file. To run a generator named `mygen.hoon`, you would type `+myhoon <argument>` in your ship's Dojo.
116+
117+If this doesn't make sense yet, that's okay. In the next lesson, we will walk you through an example `gate` that is run as a generator.
118+
119+### [Next Up: Walkthrough -- List of Numbers](../list-of-numbers)
learn/hoon/hoon-tutorial/simple-one-gate-programs.mddeleted−888
@@ -1,888 +0,0 @@
1−+++
2−title = "Simple One-Gate Programs"
3−weight = 23
4−template = "doc.html"
5−+++
6−In this lesson we'll try to cover enough basic Hoon so that you can write (and understand) your own simple programs. Each of the programs given in this lesson produces a gate. (Gates are one-armed cores of Hoon that can be used as functions -- this is covered in [lesson 1.5](../gates).)
7−
8−For each program we encourage you to: (1) write out the program yourself, (2) save it to the `/home/gen` directory of your urbit's pier, and (3) run it from the dojo. The best way to learn to program in Hoon is by getting your hands dirty.
9−
10−We will also continue to run one-line snippets of code in the dojo. We encourage you to enter these for yourself as well.
11−
12−## Writing Gates: A Review
13−
14−Let's look at a really simple gate: `|=(a=@ 15)`. This gate takes any atom as input and returns the value `15`.
15−
16−The `|=` rune takes two subexpressions. The first must indicate a type, and the second may evaluate to any value. The first defines the gate's sample type and possibly binds a face to it, and the second defines the output of the gate. In the example `|=(a=@ 15)` the `|=` subexpressions are `a=@` and `15`.
17−
18−The following characters represent basic Hoon types: `@` for atoms, `^` for cells, `?` for flags, and `*` for nouns. You should already know what atoms, cells, and nouns are. (See [lesson 1.2](../nouns) if you need a reminder.) There are two values for the `?` type: `%.y` for yes, and `%.n` for no. In other words, `?` is for the [Boolean values](https://en.wikipedia.org/wiki/Boolean_data_type) of Hoon.
19−
20−You could have picked a different type for the first subexpression of `|=(a=@ 15)` and left off the face. To illustrate this let's call different versions of the gate with the `(gate arg)` function call syntax:
21−
22−```
23−> (|=(@ 15) 11)
24−15
25−
26−> (|=(@ 15) 22)
27−15
28−
29−> (|=(* 15) 22)
30−15
31−
32−> (|=(^ 15) 11)
33−nest-fail [crash message]
34−```
35−
36−The argument for each of these function calls is either `11` or `22`. These are atoms, `@`, and hence also nouns, `*`. So when you define the sample to be either `@` or `*` the evaluation works as desired.
37−
38−In the last function call, however, the gate's sample is defined to be a cell, `^`, and `11` isn't a cell. This is why, when that gate is called with `11`, the result is a `nest-fail` crash message. For all function calls, Hoon's type system checks whether the type of the argument matches the type of the sample. If not, the the function will not be evaluated and you get the `nest-fail`. (What counts as "nesting" will be covered more carefully in the next few lessons.)
39−
40−Ordinarily a face is included in the first subexpression after the `|=` rune. This makes it easier to refer to the sample in the second `|=` subexpression. Usually you'll want the gate product to depend on the arguments passed.
41−
42−```
43−> (|=(a=@ (add 2 a)) 12)
44−14
45−
46−> (|=(a=@ (add 2 a)) 14)
47−16
48−```
49−
50−### Checking the Gate's Output
51−
52−You are probably fallible. A fallible person will, at least occasionally, write code that produces output of the wrong type. Hoon's type system is designed to help you avoid this problem, but to take full advantage of this help you have to ask. You can do this with a 'cast' expression. It is good practice to include a cast in every gate expression you write in Hoon.
53−
54−A cast is a test that the value produced by an expression is provably of the desired type. When the code is compiled, the compiler does type inference on the expression in question. (We'll talk in more detail about how Hoon's type inference works later in the chapter.) If the inferred type 'nests' under the desired type then the cast succeeds and the program is compiled. Otherwise, the compile halts with a `nest-fail` crash. In the latter case the program -- at least potentially -- produces the wrong kind of value and needs to be debugged.
55−
56−There are different ways to cast, but for now we'll just use the `^-` rune. Consider the even number checker given in the last lesson:
57−
58−```
59−|= a=@ :: even number checker
60−^- ? :: output is a flag
61−=(0 (mod a 2)) :: if remainder=0 'yes'
62−```
63−
64−The first subexpression after `|=` is `a=@`, and the second is the rather more complex:
65−
66−```
67−^- ?
68−=(0 (mod a 2))
69−```
70−
71−This latter subexpression begins with the `^-` rune, which itself takes two subexpressions. The first `^-` subexpression must indicate a type, `?`, and the second is to be evaluated, `=(0 (mod a 2))`. The value of the second subexpression is the value produced by the whole `^-` expression.
72−
73−The inferred type of `=(0 (mod a 2))` is compared against `?`. If the former type fits under the latter, the type-check passes. Otherwise the program will fail to compile, `nest-fail`.
74−
75−Save the even number checker to the `/home/gen` directory of your pier as `even.hoon` and run it from the dojo:
76−
77−```
78−> +even 11
79−%.n
80−
81−> +even 22
82−%.y
83−```
84−
85−Now replace the `=(0 (mod a 2))` in the third line with just `15`. The result:
86−
87−```
88−|= a=@ :: even number checker
89−^- ? :: output is a flag
90−15 :: return 15
91−```
92−
93−Save this and try to run it from the dojo again:
94−
95−```
96−> +even 22
97−nest-fail
98−```
99−
100−You changed the gate so that the output is `15`, which is an atom, `@`. But you're casting for a flag, `?` -- either `%.y` or `%.n`. Because `@` doesn't nest under `?` the program fails to compile.
101−
102−### Multiple Inputs and Outputs
103−
104−A gate is a one-armed core with a sample:
105−
106−```
107− [gate]
108− / \
109− [$ arm] [payload]
110− / \
111− [sample] [context]
112−```
113−
114−When a function call to a gate occurs, the `$` arm is evaluated with the gate itself as the subject. But the gate's payload is usually modified. The modification in question is to the sample: the default gate sample is replaced with the argument(s) of the function call. This is how the `$` arm 'knows' what the argument(s) of the function are.
115−
116−The sample is just the noun in that slot of the gate, `+6`. The product of the arm evaluation is just another noun. Thus, gates always have a single noun for input and a single noun for output.
117−
118−But we would like to use functions that take multiple inputs as well as functions with multiple outputs. How? The obvious solution is to use cells.
119−
120−Let's write a program that checks two numbers at a time and tells us if each is even:
121−
122−```
123−::
124−:: even2.hoon
125−::
126−:: this gate takes a pair of atoms, tests whether each is even, and then
127−:: returns two flags.
128−::
129−|= [a=@ b=@] :: check two numbers
130−^- [? ?] :: output is two flags
131−:- =(0 (mod a 2)) :: :-(x y) makes [x y]
132−=(0 (mod b 2)) ::
133−```
134−
135−The first `|=` subexpression is now `[a=@ b=@]`. This indicates a complex type for the gate's sample. The gate takes a pair of atoms, labeling the first `a` and the second `b`.
136−
137−The second `|=` subexpression is:
138−
139−```
140−^- [? ?]
141−:- =(0 (mod a 2))
142−=(0 (mod b 2))
143−```
144−
145−The first of two `^-` subexpressions is `[? ?]`, indicating another complex type. The inferred type of the second `^-` subexpression must be a cell of two flags, or else the program will fail to compile. The second `^-` subexpression:
146−
147−```
148−:- =(0 (mod a 2))
149−=(0 (mod b 2))
150−```
151−
152−The `:-` rune takes two subexpressions and makes them into a cell. Each of these, `=(0 (mod a 2))` and `=(0 (mod b 2))`, evaluates to a flag value, `?`.
153−
154−Save the whole program in your pier as `even2.hoon` (or as something else if you like) and test it in the dojo. Remembering to pass the two arguments as a cell:
155−
156−```
157−> +even2 [2 2]
158−[%.y %.y]
159−
160−> +even2 [2 3]
161−[%.y %.n]
162−
163−> +even2 [3 3]
164−[%.n %.n]
165−
166−> +even2 [22 33]
167−[%.y %.n]
168−```
169−
170−A gate may take as input or produce as output arbitrarily complex cells. For example, one could write a gate that takes a cell of five different things:
171−
172−```
173−|= [a=* b=@ud c=^ d=? e=@sb]
174−...
175−```
176−
177−## Basic Tools
178−
179−### `.+` and `.=`
180−
181−The `.+` rune is for 'incrementing'; it takes an atom and adds `1` to it. That's it! Here it is in action:
182−
183−```
184−> .+ 22
185−23
186−
187−> .+(22)
188−23
189−
190−> .+(101)
191−102
192−```
193−
194−But it's nearly always used in its irregular form, which lacks the `.`:
195−
196−```
197−> +(22)
198−23
199−
200−> +(101)
201−102
202−```
203−
204−You've already used the `.=` rune in its irregular form, `=( )`. This rune takes two subexpressions, evaluates them, and then does a simple test of equality on the resulting values.
205−
206−```
207−> =(22 11)
208−%.n
209−
210−> =(22 (add 11 11))
211−%.y
212−```
213−
214−But there's one more quirk that you should know about: `.=(a b)` includes a type check. Of the inferred types of `a` and `b`, one must nest in the other or else the code won't compile:
215−
216−```
217−> =(12 [12 14])
218−nest-fail
219−```
220−
221−The inferred type of `12` is `@ud`, and the inferred type of `[12 14]` is `[@ud @ud]`. Neither type nests under the other, so the code fails to compile. There is a way to get around this type check, which we'll explain later in this chapter. The best policy is to avoid wiggling out of type safety checks, however.
222−
223−### Introduction to Conditionals: The `?` Rune Family
224−
225−We won't cover all the `?` runes here -- we'll save some for the upcoming lesson on types. But we'll cover enough to get you writing simple Hoon programs.
226−
227−#### `?:` if-then-else
228−
229−The `?:` rune indicates an 'if-then-else' expression and takes three subexpressions: (1) the condition, which must evaluate to a flag, (2) an expression to be evaluated if the condition evaluates to `%.y`, and (3) an expression to be evaluated if the condition evaluates to `%.n`.
230−
231−```
232−> ?:(%.y 11 22)
233−11
234−
235−> ?: %.y
236− 11
237− 22
238−11
239−
240−> ?:(%.n 11 22)
241−22
242−```
243−
244−#### `?.` ifnot-then-else
245−
246−The `?.` rune does precisely the same thing as `?:`, except reversed: if the condition evaluates to `%.n` then the second subexpression is evaluated, otherwise the third is evaluated.
247−
248−```
249−> ?.(%.y 11 22)
250−22
251−
252−> ?. %.y
253− 11
254− 22
255−22
256−
257−> ?.(%.n 11 22)
258−11
259−```
260−
261−The reasons for Hoon's having both `?:` and `?.` involve code neatness and clarity. Use whichever makes your code better.
262−
263−#### `?&` logical 'AND'
264−
265−The `?&` rune is for logical 'AND'. It takes two or more subexpressions, each of which must evaluate to a flag, `?`; and if all of them evaluate to `%.y` then the result of the `?&` expression is `%.y`. Otherwise it's `%.n`. In tall form the expression is terminated with `==`.
266−
267−```
268−> ?& %.y %.y %.y ==
269−%.y
270−
271−> ?& & | & ==
272−%.n
273−
274−> ?&(%.y %.y %.y)
275−%.y
276−
277−> ?&(& =(1 2) &)
278−%.n
279−```
280−
281−You may be confused about the lone `&` and `|` characters in the second and fourth examples above. The `&` character (used by itself) is another alias for 'yes', and `|` (used by itself) is another alias for 'no':
282−
283−```
284−> &
285−%.y
286−
287−> |
288−%.n
289−```
290−
291−The irregular form of `?&` allows you to drop the `?` symbol:
292−
293−```
294−> &(& & &)
295−%.y
296−
297−> &(| & &)
298−%.n
299−
300−> &(& | &)
301−%.n
302−
303−> &(& & |)
304−%.n
305−```
306−
307−To be clear, in `&(blah-1 blah-2)` the `&()` is the irregular `?&` rune; and anywhere else in the code `&` by itself means 'yes', `%.y`.
308−
309−#### `?|` logical 'OR'
310−
311−The `?|` rune is for logical 'OR'. It takes two or more subexpressions, each of which must evaluate to a flag, `?`. If at least one evaluates to `%.y` then the whole `?|` expression evals to `%.y`; otherwise it's `%.n`:
312−
313−```
314−> ?| %.n %.n %.n ==
315−%.n
316−
317−> ?| | | & ==
318−%.y
319−
320−> ?|(=(12 12) | |)
321−%.y
322−```
323−
324−The irregular form drops the `?` symbol:
325−
326−```
327−> |(=(12 12) | |)
328−%.y
329−
330−> |(=(12 13) | |)
331−%.n
332−```
333−
334−#### `?!` logical 'NOT'
335−
336−The `?!` rune is for logical 'NOT'. It takes one subexpression that evaluates to a flag and returns the opposite value.
337−
338−```
339−> ?! &
340−%.n
341−
342−> ?!(|)
343−%.y
344−```
345−
346−The irregular form drops the `?` symbol and uses no parentheses:
347−
348−```
349−> !|
350−%.y
351−
352−> =(22 33)
353−%.n
354−
355−> !=(22 33)
356−%.y
357−```
358−
359−#### Are All Three Even?
360−
361−Let's write a program that takes three atoms, `@`, and returns `%.y` if they're all even, otherwise `%.n`.
362−
363−```
364−|= [a=@ b=@ c=@] :: check three @
365−^- ? :: output is a flag
366−?& =(0 (mod a 2)) :: `a` is even AND
367− =(0 (mod b 2)) :: `b` is even AND
368− =(0 (mod c 2)) :: `c` is even
369−==
370−```
371−
372−Save this in your urbit's pier as `even3.hoon` and run it from the dojo:
373−
374−```
375−> +even3 [12 13 14]
376−%.n
377−
378−> +even3 [12 16 14]
379−%.y
380−```
381−
382−#### If So, Multiply -- Otherwise Add
383−
384−Let's write a slightly more complicated program. The gate takes three atoms, `@`, and if all three are even it multiplies all of them together. Otherwise, it adds them all together.
385−
386−```
387−|= [a=@ b=@ c=@] :: take three @
388−^- @ :: output is an @
389−?: ?& =(0 (mod a 2)) :: if `a` is even AND
390− =(0 (mod b 2)) :: `b` is even AND
391− =(0 (mod c 2)) :: `c` is even
392− ==
393− (mul a (mul b c)) :: then multiply
394−(add a (add b c)) :: otherwise add
395−```
396−
397−Save this as `addmul.hoon` and try it from the dojo:
398−
399−```
400−> +addmul [2 2 2]
401−8
402−
403−> +addmul [2 2 3]
404−7
405−
406−> +addmul [4 4 4]
407−64
408−
409−> +addmul [4 4 5]
410−13
411−```
412−
413−### Subject Modification: The `=` Rune Family
414−
415−As with the `?` family, we won't explain all the runes of the `=` family -- just a few to get you started.
416−
417−#### `=>` Evaluate a Hoon Against a Subject
418−
419−The `=>` rune takes two subexpressions. The first is evaluated, with the result becoming the new subject; the second subexpression is evaluated against that subject.
420−
421−A few examples:
422−
423−```
424−> => [[a=12 b=14] [c=16 d=18]] +
425−[c=16 d=18]
426−
427−> => [[a=12 b=14] [c=16 d=18]] -
428−[a=12 b=14]
429−
430−> => [[a=12 b=14] [c=16 d=18]] +>
431−d=18
432−
433−> => [[a=12 b=14] [c=16 d=18]] a
434−12
435−
436−> => [[a=12 b=14] [c=16 d=18]] d
437−18
438−```
439−
440−#### `=<` Evaluate a Hoon Against a Subject, Reversed
441−
442−The `=<` rune is just like `=>` but reversed. The second subexpression is evaluated, with the result becoming the new subject; the first subexpression is evaluated against that subject.
443−
444−A few examples:
445−
446−```
447−> =< + [[a=12 b=14] [c=16 d=18]]
448−[c=16 d=18]
449−
450−> =< - [[a=12 b=14] [c=16 d=18]]
451−[a=12 b=14]
452−
453−> =< +> [[a=12 b=14] [c=16 d=18]]
454−d=18
455−
456−> =< a.- [[a=12 b=14] [c=16 d=18]]
457−12
458−
459−> =< d.+ [[a=12 b=14] [c=16 d=18]]
460−18
461−```
462−
463−The `=>` and `=<` runes should seem vaguely familiar, in spirit if not otherwise. You've already used the irregular version of `=<`, with the `:` character:
464−
465−```
466−> +:[[a=12 b=14] [c=16 d=18]]
467−[c=16 d=18]
468−
469−> -:[[a=12 b=14] [c=16 d=18]]
470−[a=12 b=14]
471−
472−> +>:[[a=12 b=14] [c=16 d=18]]
473−d=18
474−
475−> a:[[a=12 b=14] [c=16 d=18]]
476−12
477−
478−> d:[[a=12 b=14] [c=16 d=18]]
479−18
480−```
481−
482−#### `=+` 'Pin' a Noun to the Subject
483−
484−The `=+` rune takes two subexpressions. The first is evaluated and then the resulting value is 'pinned' to the head of the subject -- that is, the old subject becomes the tail of the new subject, and the value produced by the first `=+` subexpression becomes the head of the new subject. The second `=+` subexpression is evaluated against the new subject. Examples:
485−
486−```
487−> => [22 33 44] =+(101 -)
488−101
489−
490−> => [22 33 44] =+(101 +)
491−[22 33 44]
492−
493−> => [22 33 44] =+(101 +1)
494−[101 22 33 44]
495−
496−> => [b=22 c=33 d=44] a
497−-find.a
498−
499−> => [b=22 c=33 d=44] =+(a=101 a)
500−101
501−```
502−
503−#### `=/` Pin a Faced (and Possibly Typed) Noun To the Subject
504−
505−The `=/` rune is a more powerful variation of `=+`. `=/` takes three subexpressions: (1) the first is the face for the noun to be pinned (e.g., `a`), and possibly includes a type (e.g., `a=@`); (2) the second is the noun to be pinned; and (3) the third is the expression to be evaluated on the modified subject.
506−
507−Some examples:
508−
509−```
510−> =/(b=@ 22 [b b b])
511−[22 22 22]
512−
513−> =/(b=@ 22 (add b b))
514−44
515−```
516−
517−The `=/` rune is the closest thing Hoon has to an instruction for 'initializing a variable' while giving it an initial value. What actually occurs in Hoon is that the value is pinned to the head of the subject, and the indicated face is bound to that value.
518−
519−#### `=|` Pin a Faced, Typed Default Noun to the Subject
520−
521−The `=|` is a lot like the `=/` rune except that (1) you must include type information when you use it, and (2) the programmer doesn't set the initial value of the face -- it's a default value for the type in question, sometimes called a 'bunt' value. The `=|` rune takes two subexpressions. The first is a face names (e.g., `a`), followed by `=`, followed by a type (e.g., `@`). The second is to be evaluated against the modified subject.
522−
523−```
524−> =| a=@ a
525−0
526−
527−> =| a=^ a
528−[0 0]
529−
530−> =| a=? a
531−%.y
532−```
533−
534−The `=|` rune is a lot like 'initializing a variable' but for faces, without giving the face an interesting initial value (a default value for the type is used instead, i.e., the 'bunt' value).
535−
536−#### `=.` Change a Leg of the Subject
537−
538−The `=.` rune takes three subexpression. The first is a wing expression, indicating the leg of the subject whose value is to be changed. The second is the new value for the indicated leg. The third is the expression to be evaluated against the modified subject.
539−
540−```
541−> =/ a=@ 22 =.(a 99 a)
542−99
543−
544−> =/ a=@ 22 [a =.(a 99 a)]
545−[22 99]
546−
547−> => [12 14] =.(+2 22 .)
548−[22 14]
549−```
550−
551−This rune is often used for modifying the value of a face whose value was set beforehand.
552−
553−## Recursion
554−
555−How do we do loops in Hoon? Like other functional programming languages Hoon uses [recursion](https://en.wikipedia.org/wiki/Recursion_%28computer_science%29). In rough terms, a recursive function solves a problem in part by calling on itself to solve a slightly easier or smaller case of the same problem. The self-calling loop continues until the simplified problem is so simple that it has a trivial solution.
556−
557−Seeing an example will make this process easier to understand.
558−
559−### Addition
560−
561−Let's write a gate that takes a pair of atoms, `@`, and which returns the sum of these atoms. There is a cheap solution to this problem, of course. The Hoon standard library has `add` in it:
562−
563−```
564−> (add 22 33)
565−55
566−```
567−
568−But let's solve the problem without using `add` from the Hoon standard library. We have the `.+` rune for adding `1` and the `.=` rune for testing equality. We'll also use `dec` from the standard library and some recursion. That's it!
569−
570−What's `dec`? It takes some atom, `@`, and returns the decrement -- i.e., it takes some number `a` and returns `a - 1`:
571−
572−```
573−> (dec 101)
574−100
575−
576−> (dec 51)
577−50
578−
579−> (dec 11)
580−10
581−```
582−
583−For adding two atoms together, the algorithm we'll use is very simple. We start with two numbers, `a` and `b`. If `b` is `0`, then the answer is `a`. (This is the trivial case of addition for our algorithm, sometimes also called the 'base' case.) Otherwise, the answer is the sum of `a + 1` and `b - 1` -- now do **that** addition. (This is the **recursive** case.)
584−
585−Do you see how this process calls for a loop of sorts? If you want to sum `7` and `2`, check to see whether the second number is `0`. It isn't, so now figure out the sum of `8` and `1`. Is the second number `0`? No, so do the sum of `9` and `0`. Now the second number is `0` -- the answer is `9`.
586−
587−Here's the program:
588−
589−```
590−|= [a=@ b=@] :: take two @
591−^- @ :: output is one @
592−?: =(b 0) :: if b is 0
593− a :: return a, else
594−$(a +(a), b (dec b)) :: add a+1 and b-1
595−```
596−
597−Save it as `add.hoon` in your urbit's pier and run it from the dojo:
598−
599−```
600−> +add [22 33]
601−55
602−
603−> +add [122 33]
604−155
605−```
606−
607−It works!
608−
609−Every line of `add.hoon` should be clear up to the last one. What's going on there? The `$( )` is used for recursive function calls. That is, it's a way for a function to call itself, but with certain values modified according to the instructions inside the parentheses. Two values are being modified for the call: `a` is modified to `+(a)`, and `b` is modified to `(dec b)`. A comma is used to separate the two modification instructions. (Of course, in programs that call for it, more than two modifications may be made here.)
610−
611−### `%=` Resolve to a Wing with Changes
612−
613−The `$( )` syntax is an irregular form of the the `%=` rune. We can rewrite that part of `add.hoon` in regular form:
614−
615−```
616−|= [a=@ b=@] :: take two @
617−^- @ :: output is one @
618−?: =(b 0) :: if b is 0
619− a :: return a, else
620−%= $ :: resolve to $
621− a +(a) :: but change a to +(a)
622− b (dec b) :: and b to (dec b)
623−==
624−```
625−
626−This version is precisely equivalent to the old one. The first `%=` subexpression is for a wing. In the program above, this is just `$`. The other subexpressions of `%=` indicate the changes to be made upon resolution to the wing. You can make as many of these changes as desired when using `%=`, so the expression is ended with `==`.
627−
628−Remember from lessons [1.4](../arms-and-cores) and [1.5](../gates) that wing resolution works in two different ways. If the wing resolves to a leg, that fragment of the subject is returned. If the wing resolves to an arm, the arm is evaluated with its parent core as the subject. In [lesson 1.5](../gates) you learned that `$` is the special name of the arm of a gate. (Remember, a gate is a one-armed core with a sample.) Because we wrote `add.hoon` with `|=` it produces a gate. The `%=` expression above thus evaluates the `$` arm of the gate, but only after having made changes to the parent core: `a` is incremented, and `b` is decremented.
629−
630−### Decrement
631−
632−We've used `dec`, but now let's write our own version. That is, let's write a gate that takes some atom, `@`, and returns the 'decrement' of that value. There is a cheap solution to this problem too. The Hoon standard library has the `sub` function in it for subtraction:
633−
634−```
635−> (sub 100 50)
636−50
637−
638−> (sub 100 1)
639−99
640−```
641−
642−But let's solve the problem without using the Hoon standard library. We have the `.+` rune for adding `1`, the `.=` rune for testing equality, and various runes of the `=` family for manipulating the subject. And we'll again use recursion.
643−
644−How do we decrement using only those tools? The algorithm is pretty simple. We'll start by defining a counter value, `0`, and binding it to `c`.
645−
646−If `c + 1` equals the value to be decremented, then `c` is the answer. (This is the trivial case.) Otherwise, we increment `c` by `1` and try again. (This is the recursive case.)
647−
648−There's one quirk about this algorithm that makes it different from the addition algorithm. We didn't set any initial values in the addition program, and so calling the whole function at the end was an acceptable option. If we do the same thing with decrement -- call the whole function at the end -- we'll end up setting the same face, `c`, to the same initial value again, `0`. We don't want that. We want the counter to increase in value for each loop! There should be a recursion start point that comes after `c` is set initially. For that you can use the `|-` rune.
649−
650−Here's the program:
651−
652−```
653−|= a=@ :: take one @
654−=/ c=@ 0 :: set c to 0
655−|- :: recursion start
656−^- @ :: output is @
657−?: =(a +(c)) :: if a = c+1
658− c :: return c, else
659−$(c +(c)) :: add 1 to c, recurse
660− :: back to the |-
661−```
662−
663−Save it as `dec.hoon` and try it from the dojo:
664−
665−```
666−> +dec 101
667−100
668−
669−> +dec 97
670−96
671−
672−> +dec 11
673−10
674−```
675−
676−At an intuitive level this code should make sense. The `$( )` at the end effectively serves as a loop going back to the `|-` rune, with a modification to the value of `c`. But isn't `$` the name of the gate's single arm? What's going on? Let's take a moment to understand how `|-` works at a deeper level.
677−
678−### `|-` Make and Call a One-armed Core
679−
680−The `|-` rune makes a one-armed core whose arm has the name `$`, and then it calls `$`. The `|-` rune takes one subexpression, which determines what `$` does:
681−
682−```
683−> |- 2
684−2
685−
686−> |- (add 22 33)
687−55
688−```
689−
690−Let's look at the decrement program again, this time using the regular version of the `%=` rune.
691−
692−```
693−|= a=@ :: take one @
694−=/ c=@ 0 :: set c to 0
695−|- :: recursion start
696−^- @ :: output is @
697−?: =(a +(c)) :: if a = c+1
698− c :: return c, else
699−%= $ :: resolve to $
700− c +(c) :: add 1 to c
701−==
702−```
703−
704−Strictly speaking, when you use `$( )` or `%= $` you're asking for a resolution to `$` (with changes indicated in parentheses). And because `$` is an arm, that means evaluating it with its parent core as the subject.
705−
706−When you use `|-` in the decrement program, you're defining a _new_ core whose arm name is `$`, in addition to the one created by `|=`. So the subject ends up having two arms named `$` in it: one for the gate defined by `|=`, and one for the core defined by `|-`.
707−
708−When `$( )` or `%= $` is executed, the subject is searched for the `$` arm. The `|-` `$` arm is found first because it was defined later than the `|=` arm. You can skip the first name match for `$` by using `^`, if you like. That is, if you like, you can recurse all the way to the beginning of the function using `^$( )` or `%= ^$`.
709−
710−### Exercises
711−
712−You should know enough at this point to write some basic Hoon programs. Practice with some of these exercises. Solutions are provided at the bottom of the page.
713−
714−#### Exercise 2.3.1: Subtraction
715−
716−Write a program that takes two numbers and returns the difference. You may use `dec`, but don't use anything else from the Hoon standard library.
717−
718−#### Exercise 2.3.2: Factorial
719−
720−Write a program that takes a number `n` and returns the factorial of `n`, `n!`. `1!` is `1`, `2!` is `2 x 1`, `3!` is `3 x 2 x 1`, `4!` is `4 x 3 x 2 x 1`, and so on. You may use the Hoon standard library.
721−
722−#### Exercise 2.3.3: Prime Number Checker
723−
724−Write a program that takes a number `n` and returns `%.y` if it's prime, and `%.n` if it isn't. You may use the Hoon standard library.
725−
726−## Fizzbuzz
727−
728−Let's write a Hoon implementation of [FizzBuzz](https://en.wikipedia.org/wiki/Fizz_buzz). Fizzbuzz takes some number `n` and then makes a list of numbers from `1` to `n`, except that numbers evenly divisible by `3` are replaced with 'Fizz', numbers evenly divisible by `5` are replaced with 'Buzz', and numbers evenly divisible by both are replaced with 'FizzBuzz'.
729−
730−You already saw a program that produces a list of atoms from `1` to `n` in [lesson 2.1](../hoon-programs), `listnum.hoon`:
731−
732−```
733−|= end=@ :: 1
734−=/ count=@ 1 :: 2
735−|- :: 3
736−^- (list @) :: 4
737−?: =(end count) :: 5
738− ~ :: 6
739−:- count :: 7
740−$(count (add 1 count)) :: 8
741−```
742−
743−The difference for FizzBuzz is that certain items of the product list must be replaced with strings: `"Fizz"`, `"Buzz"`, and `"FizzBuzz"`.
744−
745−Below is our implementation of FizzBuzz. Each line is commented with a number for convenient line reference:
746−
747−```
748−|= end=@ :: 1
749−=/ count=@ 1 :: 2
750−|- :: 3
751−^- (list tape) :: 4
752−?: =(end count) :: 5
753− ~ :: 6
754−:- :: 7
755− ?: =(0 (mod count 15)) :: 8
756− "FizzBuzz" :: 9
757− ?: =(0 (mod count 3)) :: 10
758− "Fizz" :: 11
759− ?: =(0 (mod count 5)) :: 12
760− "Buzz" :: 13
761− <count> :: 14
762−$(count (add 1 count)) :: 15
763−```
764−
765−Save this as 'fizzbuzz.hoon' in `/home/gen` of your urbit's pier. To run it enter `+fizzbuzz 25` in the dojo:
766−
767−```
768−> +fizzbuzz 25
769−<<
770− "1"
771− "2"
772− "Fizz"
773− "4"
774− "Buzz"
775− "Fizz"
776− "7"
777− "8"
778− "Fizz"
779− "Buzz"
780− "11"
781− "Fizz"
782− "13"
783− "14"
784− "FizzBuzz"
785− "16"
786− "17"
787− "Fizz"
788− "19"
789− "Buzz"
790− "Fizz"
791− "22"
792− "23"
793− "Fizz"
794−>>
795−```
796−
797−### Explaining Fizzbuzz
798−
799−```
800−|= end=@ :: 1
801−=/ count=@ 1 :: 2
802−|- :: 3
803−^- (list tape) :: 4
804−```
805−
806−This gate takes an atom, `end`, for its sample. The initial value of `count`, an atom, is `1`. Line `3` uses `|-` for a recursion (or loop) starting point, so that `count` is only set to `1` once.
807−
808−The gate output is cast to `(list tape)`, i.e., to a list of `tape`s. A `tape` is one of Hoon's two string types and is pretty-printed as a string in double quotes.
809−
810−```
811−> "This is a tape."
812−"This is a tape."
813−
814−> "So is this!"
815−"So is this!"
816−```
817−
818−Moving on:
819−
820−```
821−?: =(end count) :: 5
822− ~ :: 6
823−```
824−
825−If `end` and `count` are the same value, then the list is finished. The null character, `~`, is returned. (Reminder: Hoon lists are null-terminated.)
826−
827−Otherwise...
828−
829−```
830−:- :: 7
831− ?: =(0 (mod count 15)) :: 8
832− "FizzBuzz" :: 9
833− ?: =(0 (mod count 3)) :: 10
834− "Fizz" :: 11
835− ?: =(0 (mod count 5)) :: 12
836− "Buzz" :: 13
837− <count> :: 14
838−$(count (add 1 count)) :: 15
839−```
840−
841−If not, line 7 uses the rune `:-` to produce a cell. This cell is the FizzBuzz list, in which the head is the first list item and the tail is the rest of the list, itself another list.
842−
843−The head of this cell is produced by lines 8-14, and the tail by line 15.
844−
845−For value of the head there are two possibilities . First, the value is "FizzBuzz", or "Fizz", or "Buzz", if any of the respective conditional tests hit. For example, if `=(0 (mod count 15))` is true -- i.e., if `count` is evenly divisible by 15 -- then the value returned is "FizzBuzz". Second, if none of the three test conditions is true, then the value is the number in question, `count`. In the latter case, line 14 uses the `< >` syntax to convert `count` from an `@` to a `tape`. Remember that the cast is for a list of `tape`s, so each list item must be a `tape`.
846−
847−For the value of the cell's tail: the rest of the output list is produced by line 15. This line uses `$( )` to loop back to the `|-` in line 3, but only after modifying the value of `count`: `count` is increased in value by `1`.
848−
849−The product of the `$( )` call on line 15 is another list. Either the modified `count` equals `end`, in which case the null list, `~`, is returned on line 6; or a new cell is produced in which case the head is an item determined by lines 7-14 and the tail is determined by line 15. The process repeats until `count` equals `end`.
850−
851−## Exercise Answers
852−
853−There are many possible solutions so yours may look a bit different from the ones we have below. These solutions aren't optimized for performance. Instead, clarity and simplicity have been prioritized.
854−
855−#### Exercise 2.3.1 Solution: Subtraction
856−
857−```
858−|= [x=@ y=@]
859−^- @
860−?: =(y 0)
861− x
862−$(x (dec x), y (dec y))
863−```
864−
865−#### Exercise 2.3.2 Solution: Factorial
866−
867−```
868−|= n=@
869−^- @
870−?: (lte n 1)
871− 1
872−(mul n $(n (dec n)))
873−```
874−
875−#### Exercise 2.3.3 Solution: Prime
876−
877−```
878−|= a=@
879−?: (lth a 2) |
880−?: =(a 2) &
881−=/ c 2
882−|- ^- ?
883−?: =(0 (mod a c)) |
884−?: (gth (mul c 2) a) &
885−$(c +(c))
886−```
887−
888−### [Next Lesson: Atoms, Auras, and Simple Cell Types](../atoms-auras-and-simple-cell-types)
learn/hoon/hoon-tutorial/structures-and-complex-types.md+3−3
@@ -1,6 +1,6 @@
1+++
1+++
2−title = "Structures and Complex Types"
2+title = "2.3 Structures and Complex Types"
3−weight = 26
3+weight = 27
4template = "doc.html"
4template = "doc.html"
5+++
5+++
6In this lesson we'll talk a little about how type expressions become structures, and how these structures manifest in different ways in different parts of your Hoon code. We'll also talk about how to create your own custom-defined complex types from simpler ones.
6In this lesson we'll talk a little about how type expressions become structures, and how these structures manifest in different ways in different parts of your Hoon code. We'll also talk about how to create your own custom-defined complex types from simpler ones.
@@ -352,4 +352,4 @@ Now the `~` value is included as a possible value for `user`.
352
352
353That's all we have to say about types in this chapter. More on types in [Chapter 3](../type-polymorphism).
353That's all we have to say about types in this chapter. More on types in [Chapter 3](../type-polymorphism).
354
354
355−### [Next Lesson: Cores](../cores)
355+### [Next Up: Walkthrough -- Taxonomy](../taxonomy)
learn/hoon/hoon-tutorial/the-subject-and-its-legs.md+1−1
@@ -652,4 +652,4 @@ You can also use more complex wings and modify their values as well:
652
652
653At this point you should have at least a rough idea of what the subject is, and a fair understanding of how to get legs of the subject using wings. But legs are only one kind of limb -- we'll talk about arms in the next lesson.
653At this point you should have at least a rough idea of what the subject is, and a fair understanding of how to get legs of the subject using wings. But legs are only one kind of limb -- we'll talk about arms in the next lesson.
654
654
655−### [Next Lesson: Arms and Cores](../arms-and-cores)
655+### [Next Up: Walkthrough -- Ackermann Function](../ackermann)
learn/hoon/hoon-tutorial/trees-sets-and-maps.md+3−2
@@ -1,8 +1,9 @@
1+++
1+++
2−title = "Standard Library: Trees, Sets, and Maps"
2+title = "2.4 Standard Library: Trees, Sets, and Maps"
3weight = 30
3weight = 30
4template = "doc.html"
4template = "doc.html"
5+++
5+++
6+
6Along with lists, the Hoon standard library also supports trees, sets, and maps as data structures. A Hoon `tree` is the data structure for a binary tree. A Hoon `set` is the data structure for a set of values. A Hoon `map` is the data structure for a set of `[key value]` pairs.
7Along with lists, the Hoon standard library also supports trees, sets, and maps as data structures. A Hoon `tree` is the data structure for a binary tree. A Hoon `set` is the data structure for a set of values. A Hoon `map` is the data structure for a set of `[key value]` pairs.
7
8
8In this lesson we'll cover each.
9In this lesson we'll cover each.
@@ -318,4 +319,4 @@ You can use `run` of `by` to apply a gate to each value in a map, producing a ma
318
319
319There are other map functions in the Hoon standard library that didn't cover here.
320There are other map functions in the Hoon standard library that didn't cover here.
320
321
321−### [Next Lesson: Examples](../examples)
322+### [Next Up: <placeholder>]
learn/hoon/hoon-tutorial/type-checking-and-type-inference.md+2−67
@@ -1,5 +1,5 @@
1+++
1+++
2−title = "Type Checking and Type Inference"
2+title = "2.2 Type Checking and Type Inference"
3weight = 25
3weight = 25
4template = "doc.html"
4template = "doc.html"
5+++
5+++
@@ -481,25 +481,6 @@ What makes this program is little harder to follow is that it has a recursion ca
481
481
482Once that new value for `c` is computed from the head of `a`, we're ready to check the tail of `a`, `+.a`. We've already got everything we want from `-.a`, so we throw that away and replace `a` with `+.a`.
482Once that new value for `c` is computed from the head of `a`, we're ready to check the tail of `a`, `+.a`. We've already got everything we want from `-.a`, so we throw that away and replace `a` with `+.a`.
483
483
484−#### 'Samefringe' Exercise
485−
486−The samefringe program takes two nouns and checks whether they have the same 'fringe', returning 'yes' if they do and 'no' otherwise. The fringe of a noun is the series of atoms of that noun, in the same order of appearance. The cell-structure of the noun is disregarded. For example, `[[3 2] 32]` has the same fringe as `[3 2 32]`, even though they're different nouns; their leaves appear in the same order.
487−
488−One way to compare noun fringes is to calculate the total fringes of each, then compare afterward. A better way to do this is to compare both fringes one atom at a time and halt the computation once the two fringes differ.
489−
490−Write a program named `samefringe.hoon` that solves the problem the 'better' way. A solution is given at the bottom of the lesson.
491−
492−```
493−> +samefringe [[[11 10] 12] [10 [10 12]]]
494−%.n
495−
496−> +samefringe [[[11 10] 12] [11 [10 12]]]
497−%.y
498−
499−> +samefringe [[[123 [456 [789 123]] 456] 789] [123 456 789 123 456 789]]
500−%.y
501−```
502−
503#### Lists
484#### Lists
504
485
505You learned about lists earlier in the chapter, but we left out a little bit of information about the way Hoon understands list types.
486You learned about lists earlier in the chapter, but we left out a little bit of information about the way Hoon understands list types.
@@ -648,17 +629,6 @@ Save the above code as `listleaf.hoon` and run it from the dojo:
648~[12 13 33 22 12 11 33]
629~[12 13 33 22 12 11 33]
649```
630```
650
631
651−#### Insertion Sort Exercise
652−
653−Write a program that takes a list of `@` and sorts them by value using the [insertion sort](https://en.wikipedia.org/wiki/Insertion_sort) algorithm. A solution is provided at the end of the lesson.
654−
655−With insertion sort, you start with a full unsorted list, `(list @)`, and a second sorted list (whose initial value is just the null list, `~`). Incrementally place each element of the unsorted list into sorted position in the second list, until the first list is empty and the second list is the sorted final list.
656−
657−```
658−> +insertionsort ~[53 287 59 3 29 98 12 0]
659−~[0 3 12 29 53 59 98 287]
660−```
661−
662### Other Kinds of Type Inference
632### Other Kinds of Type Inference
663
633
664So far you've learned about four kinds of type inference, using: (1) literals, (2) explicit casts, (3) gate sample definitions, and (4) branch specialization using runes in the `?` family.
634So far you've learned about four kinds of type inference, using: (1) literals, (2) explicit casts, (3) gate sample definitions, and (4) branch specialization using runes in the `?` family.
@@ -669,39 +639,4 @@ More subtly, the `=+`, `=/`, and `=|` runes modify the subject by pinning values
669
639
670In general, anything that modifies the subject modifies the type of the subject. Type inference can work in subtle ways for various expressions. However, we have covered enough that it should be relatively clear how to anticipate how type inference works for the vast majority of ordinary use cases.
640In general, anything that modifies the subject modifies the type of the subject. Type inference can work in subtle ways for various expressions. However, we have covered enough that it should be relatively clear how to anticipate how type inference works for the vast majority of ordinary use cases.
671
641
672−## Exercise Solutions
642+### [Next Up: Reading -- Insertion Sort](../insertion)
673−
674−### Samefringe
675−
676−```
677−|= [a=* b=*]
678−^- ?
679−?: =(a b) &
680−?@ a |
681−?@ b |
682−?^ -.a
683− $(a [-<.a ->.a +.a])
684−?^ -.b
685− $(b [-<.b ->.b +.b])
686−?. =(-.a -.b) |
687−$(a +.a, b +.b)
688−```
689−
690−### Insertion Sort
691−
692−```
693−|= a=(list @)
694−=| b=(list @)
695−|- ^- (list @)
696−?~ a b
697−%= $
698− b |- ^- (list @)
699− ?~ b [i.a b]
700− ?: (gth i.a i.b)
701− [i.b $(b t.b)]
702− [i.a b]
703− a t.a
704−==
705−```
706−
707−### [Next Lesson: Structures and Complex Types](../structures-and-complex-types)
learn/hoon/hoon-tutorial/type-polymorphism.md+4−1
@@ -1,5 +1,5 @@
1+++
1+++
2−title = "Type Polymorphism"
2+title = "2.5 Type Polymorphism"
3weight = 31
3weight = 31
4template = "doc.html"
4template = "doc.html"
5+++
5+++
@@ -572,3 +572,6 @@ Once more let's clear up the dojo subject:
572```
572```
573=lead-gate
573=lead-gate
574```
574```
575+
576+
577+### [Next Up: Walkthrough -- <placeholder>]