on master help sign in
Merge pull request #508 from baudtack/master

changes

commit0346851ca6fc646d04c1e03029828cba64cf9bf4 authorrmariani <robert@tlon.io> dateFri 24 May 2019, 10:35 (7 years ago) parent0992fe82fc5ec6
34 files changed+300−3274
getting-started/_index.md+2−2 concepts/contributing.md → getting-started/contributing.md+1−1 getting-started/installing-urbit.md+2−1 learn/hoon/hoon-tutorial/_index.md+24−24 learn/hoon/hoon-tutorial/ackermann.md+31 learn/hoon/hoon-tutorial/arms-and-cores.md+2−2 learn/hoon/hoon-tutorial/atoms-auras-and-simple-cell-types.md+4−4 learn/hoon/hoon-tutorial/bank-account.md+81 learn/hoon/workbook/caesar.md → learn/hoon/hoon-tutorial/caesar.md+5−2 learn/hoon/workbook/even.md → learn/hoon/hoon-tutorial/conditionals.md+6−4 learn/hoon/hoon-tutorial/cores-again.md−797 learn/hoon/hoon-tutorial/cores.md−396 learn/hoon/hoon-tutorial/multi-gate-cores-and-doors.md → learn/hoon/hoon-tutorial/doors.md+4−2 learn/hoon/hoon-tutorial/examples.md−488 learn/hoon/hoon-tutorial/fibonacci.md+62 learn/hoon/hoon-tutorial/gates.md+4−4 using/generators.md → learn/hoon/hoon-tutorial/generators.md+2−2 learn/hoon/hoon-tutorial/hoon-programs.md−162 learn/hoon/hoon-tutorial/hoon-syntax.md+3−4 learn/hoon/workbook/list.md → learn/hoon/hoon-tutorial/list-of-numbers.md+6−5 learn/hoon/hoon-tutorial/lists.md+4−3 learn/hoon/hoon-tutorial/nouns.md+12−24 learn/hoon/hoon-tutorial/recursion.md+8−7 learn/hoon/hoon-tutorial/setup.md+14−6 learn/hoon/hoon-tutorial/simple-one-gate-programs.md−888 learn/hoon/hoon-tutorial/structures-and-complex-types.md+3−3 learn/hoon/hoon-tutorial/the-subject-and-its-legs.md+1−1 learn/hoon/hoon-tutorial/trees-sets-and-maps.md+3−2 learn/hoon/hoon-tutorial/type-checking-and-type-inference.md+2−67 learn/hoon/hoon-tutorial/type-polymorphism.md+4−1 learn/hoon/workbook/recursion.md−192 using/_index.md+9−7 getting-started/creating-a-development-ship.md → using/creating-a-development-ship.md+1−1 using/layout.md−172
getting-started/_index.md+2−2
@@ -19,9 +19,9 @@ The Urbit software is a command-line application that runs the Arvo operating sy
1919
2020This guide teaches you how to get your ship operational and onto the Arvo network.
2121
22−### [Optional: Creating a Development Ship](./docs/getting-started/creating-a-development-ship.md)
22+### [Optional: Contributing](contributing)
2323
24−If you want to develop software for Arvo, or if you just want to try the operating system without connecting to the network, this section is for you.
24+This document will get your started with contributing code or contributing to the community.
2525
2626## Terminology
2727
concepts/contributing.md → getting-started/contributing.mdrenamed+1−1
@@ -1,6 +1,6 @@
11+++
22title = "Contributing"
3−weight = 3
3+weight = 5
44template = "doc.html"
55description = "A guide to getting involved with the Urbit project."
66+++
getting-started/installing-urbit.md+2−1
@@ -194,7 +194,8 @@ urbit
194194
195195One you've completed your installation, you can continue on to the instructions for [booting your ship](./docs/getting-started/booting-a-ship.md) to get on the Arvo network.
196196
197−Or, if you want to try testing and writing code, check out the guide to [getting an unnetworked development ship](./docs/getting-started/creating-a-development-ship.md).
197+Or, if you want to try testing and writing code, check out the guide to [getting an unnetworked development ship](/docs/using/creating-a-development-ship).
198+
198199
199200
200201## Set Up Swap
learn/hoon/hoon-tutorial/_index.md+24−24
@@ -4,44 +4,44 @@ weight = 1
44sort_by = "weight"
55template = "sections/docs/chapters.html"
66+++
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.
7+
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.
89
910Chapter 1 introduces and explains the fundamental concepts you need in order to understand Hoon's semantics.
1011
1112Hoon is a 'subject-oriented' programming language -- every expression of Hoon is evaluated relative to a **subject**. The subject is a piece of data that represents the environment, or the context, of an expression. After reading Chapter 1 you should understand what the subject is and how to refer to its various parts. In this chapter you'll also learn about **cores**, which are an important data structure in Hoon. Once you get the hang of cores you'll be able to write your own functions in Hoon.
1213
13−Chapter 2 covers the basics of writing full programs in Hoon.
14+Chapter 2 covers the type system, and writing apps, and the workings of the Arvo kernel.
1415
15−The first three lessons take you through a simple Hoon program, explain Hoon's syntax, and explains basic flow control. The next three lessons introduce Hoon's type system. Lessons 7 and 8 show you how to use cores effectively in your Hoon programs, including how to use them as state machines. Lessons 9 and 10 cover some of the basic data structures commonly used in Hoon, such as lists, trees, and sets. Those lessons also introduce many of the standard library functions for use with those data structures. Lesson 11 includes a walk-through of two Hoon programs that are intended to reinforce everything taught earlier in the chapter: a prime sieve and a tic-tac-toe program.
1616
1717## Lessons
1818
1919### Chapter 1
2020
21−- [1.1 Setup](./docs/learn/hoon/hoon-tutorial/setup.md)
22−- [1.2 Nouns](./docs/learn/hoon/hoon-tutorial/nouns.md)
23−- [1.3 The Subject and Its Legs](./docs/learn/hoon/hoon-tutorial/the-subject-and-its-legs.md)
24−- [1.4 Arms and Cores](./docs/learn/hoon/hoon-tutorial/arms-and-cores.md)
25−- [1.5 Gates (Hoon Functions)](./docs/learn/hoon/hoon-tutorial/gates.md)
26−- [1.6 Multi-gate Cores and Doors](./docs/learn/hoon/hoon-tutorial/multi-gate-cores-and-doors.md)
21+- [1.1 Setup](setup)
22+- [1.1.1 Walkthrough: List of Numbers](list-of-numbers)
23+- [1.2 Nouns](nouns)
24+- [1.2.1 Walkthrough: Boolean Branching](boolean-branching)
25+- [1.3 Hoon Syntax](hoon-syntax)
26+- [1.4 Lists](list)
27+- [1.4.1 Walkthrough: Fibonacci Sequence](fibonacci)
28+- [1.5 Gates (Hoon Functions)](gates)
29+- [1.5.1 Walkthrough: Recursion](recursion)
30+- [1.6 The Subject and Its Legs](the-subject-and-its-legs)
31+- [1.6.1 Walkthrough: Ackerman Function](ackermann)
32+- [1.7 Arms and Cores](arms-and-cores)
33+- [1.7.1 Walkthrough: Caesar Cipher](caesar)
34+- [1.8 Doors](doors)
35+- [1.8.1 Walkthough: Bank Account](bank-account)
36+- [1.9 Generators](generators)
2737
2838### Chapter 2
2939
30−- [2.1 Hoon Programs](./docs/learn/hoon/hoon-tutorial/hoon-programs.md)
31−- [2.2 Hoon Syntax](./docs/learn/hoon/hoon-tutorial/hoon-syntax.md)
32−- [2.3 Simple One-Gate Programs](./docs/learn/hoon/hoon-tutorial/simple-one-gate-programs.md)
33−- [2.4 Atoms, Auras, and Simple Cell Types](./docs/learn/hoon/hoon-tutorial/atoms-auras-and-simple-cell-types.md)
34−- [2.5 Type Checking and Type Inference](./docs/learn/hoon/hoon-tutorial/type-checking-and-type-inference.md)
35−- [2.6 Structures and Complex Types](./docs/learn/hoon/hoon-tutorial/structures-and-complex-types.md)
36−- [2.7 Cores](./docs/learn/hoon/hoon-tutorial/cores.md)
37−- [2.8 Cores Again](./docs/learn/hoon/hoon-tutorial/cores-again.md)
38−- [2.9 Standard Library: Lists](./docs/learn/hoon/hoon-tutorial/lists.md)
39−- [2.10 Standard Library: Trees, Sets, and Maps](./docs/learn/hoon/hoon-tutorial/trees-sets-and-maps.md)
40−- [2.11 Examples](./docs/learn/hoon/hoon-tutorial/examples.md)
41−
42−### Chapter 3
43−
44−- [3.1 Type Polymorphism](./docs/learn/hoon/hoon-tutorial/type-polymorphism.md)
40+- [2.1 Atoms, Auras, and Simple Cell Types](atoms-auras-and-simple-cell-types)
41+- [2.2 Type Checking and Type Inference](type-checking-and-type-inference)
42+- [2.3 Structures and Complex Types](structures-and-complex-types)
43+- [2.4 Standard Library: Trees, Sets, and Maps](trees-sets-and-maps)
44+- [2.5 Type Polymorphism](type-polymorphism)
4545
4646## Other Resources
4747
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 @@
11+++
22title = "Arms and Cores"
3−weight = 14
3+weight = 15
44template = "doc.html"
55+++
66The 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
417417-find.c
418418```
419419
420−### [Next Lesson: Gates](./docs/learn/hoon/hoon-tutorial/gates.md)
420+### [Next Up: Walkthrough -- Caesar Cipher](../caesar)
learn/hoon/hoon-tutorial/atoms-auras-and-simple-cell-types.md+4−4
@@ -1,5 +1,5 @@
11+++
2−title = "Atoms, Auras, and Simple Cell Types"
2+title = "2.1 Atoms, Auras, and Simple Cell Types"
33weight = 24
44template = "doc.html"
55+++
@@ -321,7 +321,7 @@ If you want to add signed atoms use the function `sum:si` instead of `add`:
321321--23
322322```
323323
324−### Exercise 2.4.1
324+### Exercise 2.1a
325325
326326Does 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.)
327327
@@ -750,7 +750,7 @@ That's it for this lesson. Move on to the next one to learn more about when a t
750750
751751## Exercise Answer
752752
753−### 2.4.1
753+### 2.1a
754754
755755There is no distinction between positive and negative zero for `@s`. To see this, let's cast each of `--0` and `-0` to `@s`:
756756
@@ -775,4 +775,4 @@ Hoon pretty-prints them the same way, but can we be sure that they are the same
775775They are indeed the same.
776776
777777
778−### [Next Lesson: Type Checking and Type Inference](./docs/learn/hoon/hoon-tutorial/type-checking-and-type-inference.md)
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 @@
11+++
2−title = "Caesar Cipher"
3−weight = 2
2+title = "1.7.1 Walkthrough: Caesar Cipher"
3+weight = 16
44template = "doc.html"
55+++
6+
67A Caesar cipher is a very simple way to obfuscate a message. The technique
78takes a string and swaps out each component letter with another letter that is
89a specified number of positions up or down in the alphabet. For example, with a
@@ -340,3 +341,5 @@ look for the legible result.
340341possible unshifted `tapes`.
341342
3423434. 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+6−4
@@ -1,10 +1,10 @@
11+++
2−title = "Even"
3−weight = 8
2+title = "1.2.1 Walkthrough: Conditionals"
3+weight = 6
44template = "doc.html"
55+++
66
7−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.
88
99```
1010:- %say
@@ -19,7 +19,7 @@ Write a generator that takes an integer and checks if it even and between 1 and
1919%.n
2020```
2121
22−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.
2323
2424```
2525|= [* [n=@ud ~] ~]
@@ -58,3 +58,5 @@ The second expression is:
5858```
5959
6060Again 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](content/docs/learn/hoon/hoon-tutorial/arms-and-cores.md), `+>` 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](./docs/learn/hoon/hoon-tutorial/lists.md)
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](./docs/learn/hoon/hoon-tutorial/cores-again.md)
learn/hoon/hoon-tutorial/multi-gate-cores-and-doors.md → learn/hoon/hoon-tutorial/doors.mdrenamed+4−2
@@ -1,5 +1,5 @@
11+++
2−title = "Multi-gate Cores and Doors"
2+title = "1.8 Doors"
33weight = 16
44template = "doc.html"
55+++
@@ -499,4 +499,6 @@ It's better simply to use the `~(arm rs arg)` syntax to replace the value of the
499499
500500## Conclusion
501501
502−You'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](./docs/learn/hoon/hoon-tutorial/hoon-programs.md) to get started.
502+You'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](./docs/learn/hoon/hoon-tutorial/type-polymorphism.md)
learn/hoon/hoon-tutorial/fibonacci.mdnew file+62
@@ -0,0 +1,62 @@
1++++
2+title = "1.4.1 Walkthrough: Fibonacci Sequence"
3+weight = 7
4+template = "doc.html"
5++++
6+
7+In this example, we will write a generator that produces a list of Fibonacci numbers up to `n`.
8+
9+```
10+|= n=@ud
11+%- flop
12+=+ [i=0 p=0 q=1 r=*(list @ud)]
13+|- ^+ r
14+?: =(i n) r
15+%= $
16+ i +(i)
17+ p q
18+ q (add p q)
19+ r [q r]
20+==
21+```
22+
23+On the first line, we use `|=` to produce a gate which takes an `@ud` that's stored in the face `n`. This `n` sample that we give our gate determines how long our Fibonacci sequence is. When the list that our program builds has `n` members, the program ends.
24+
25+```
26+%- flop
27+```
28+
29+In the line above, we use `flop` on the output of the rest of the program. `flop` is a standard library function to reverse a list.
30+
31+Why are we using this instead of just producing the list in the order we want it in the first place? Because with lists, adding an element to the end is a computationally expensive operation that gets more expensive the longer the list is, due to the fact that you need to traverse to the end of the tree. Adding an element to the front, however, is cheap. [In Big-O Notation](https://en.wikipedia.org/wiki/Big_O_notation), adding to the end of a list is O(n) and the front is O(1).
32+
33+```
34+=+ [i=0 p=0 q=1 r=*(list @ud)]
35+```
36+
37+Here we declare several values that we are going to use the execution of our program. The only one of these that is noteworthy is `r`: we're using `*` to bunt, or get the default value for, the mold `(list @ud)`.
38+
39+```
40+|- ^+ r
41+```
42+
43+With this code, we define `|-`, the _trap_ that acts as a recursion point and contains the rest of our program. We also use `^+` to cast the output by example. This will result in the output being the same type as `r`, a list of `@ud`.
44+
45+```
46+?: =(i n) r
47+```
48+
49+In the code above, `?:` checks whether the first child, `=(i n)`, our terminating case, is true or false. If it is true, it branches to `r` and the program ends. If it is false, the program continues to the code below.
50+
51+```
52+%= $
53+ i +(i)
54+ p q
55+ q (add p q)
56+ r [q r]
57+==
58+```
59+
60+The 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 @@
11+++
22title = "Gates (Hoon Functions)"
3−weight = 15
3+weight = 8
44template = "doc.html"
55+++
66In this lesson you're going to learn about Hoon functions.
@@ -167,7 +167,7 @@ Let's look at the context of `inc`:
167167
168168This 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.
169169
170−### Exercise 1.5.1
170+### Exercise 1.5.1a
171171
172172Write 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.
173173
@@ -257,7 +257,7 @@ Before finishing the lesson let's unbind `ten`:
257257> =ten
258258```
259259
260−## Exercise 1.5.1 Solution
260+## Exercise 1.5a Solution
261261
262262Write 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.
263263
@@ -271,4 +271,4 @@ Write a gate that takes an atom, `a=@`, and which returns double the value of `a
27127150
272272```
273273
274−### [Next Lesson: Multi-gate Cores and Doors](./docs/learn/hoon/hoon-tutorial/multi-gate-cores-and-doors.md)
274+### [Next Up: Walkthrough -- Recursion](../recursion)
using/generators.md → learn/hoon/hoon-tutorial/generators.mdrenamed+2−2
@@ -1,6 +1,6 @@
11+++
2−title = "Generators"
3−weight = 9
2+title = "1.9 Generators"
3+weight = 19
44template = "doc.html"
55+++
66Generators are the most straightforward way to write programs for Urbit. They
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](./docs/learn/hoon/hoon-tutorial/hoon-syntax.md)
learn/hoon/hoon-tutorial/hoon-syntax.md+3−4
@@ -1,9 +1,8 @@
11+++
2−title = "Hoon Syntax"
3−weight = 13
2+title = "1.3 Hoon Syntax"
3+weight = 6
44template = "doc.html"
55+++
6−# 1.3 Hoon Syntax
76
87The study of Hoon can be divided into two parts: syntax and semantics.
98
@@ -324,4 +323,4 @@ There are a couple useful runes associated with debugging:
324323
325324But there are more. Check out the aforementioned [troubleshooting](/docs/reference/troubleshooting/) page to see other handy debugging runes and how to use them.
326325
327−### [Next Lesson: The Subject and Its Legs](./docs/learn/hoon/hoon-tutorial/simple-one-gate-programs.md)
326+### [Next Up: Reading -- Lists](../lists)
learn/hoon/workbook/list.md → learn/hoon/hoon-tutorial/list-of-numbers.mdrenamed+6−5
@@ -1,13 +1,12 @@
11+++
2−title = "List of Numbers"
3−weight = 1
2+title = "1.1.1 Walkthrough: List of Numbers"
3+weight = 3
44template = "doc.html"
55+++
66This 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.
77
88Below 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]`.
99
10−
1110```
1211|= end=@ :: 1
1312=/ count=@ 1 :: 2
@@ -19,7 +18,7 @@ Below is a simple Hoon program that takes a single number `n` from the user as i
1918$(count (add 1 count)) :: 8
2019```
2120
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:
2322
2423`~your-ship:> +list 5`
2524
@@ -128,4 +127,6 @@ Our program works by having each iteration of the list creating a cell. In each
128127 4 ~
129128```
130129
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](./docs/learn/hoon/workbook/recursion.md).
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 @@
11+++
2−title = "Standard Library: Lists"
3−weight = 29
2+title = "1.4 Lists"
3+weight = 6
44template = "doc.html"
55+++
6+
67In this lesson we'll review what a list is and then cover many of the list-related functions in the Hoon standard library.
78
89## List Review
@@ -383,4 +384,4 @@ Run in dojo:
38338433
384385```
385386
386−### [Next Lesson: Trees, Sets, and Maps](./docs/learn/hoon/hoon-tutorial/trees-sets-and-maps.md)
387+### [Next Up: Walkthrough -- Fibonacci Sequence](../fibonacci)
learn/hoon/hoon-tutorial/nouns.md+12−24
@@ -1,9 +1,9 @@
11+++
2−title = "Nouns"
3−weight = 12
2+title = "1.2 Nouns"
3+weight = 4
44template = "doc.html"
55+++
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.
77
88## Noun Definition
99
@@ -24,18 +24,6 @@ Here are some cells:
2424
2525All of the above are nouns.
2626
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−
3927### Nouns as Binary Trees
4028
4129A [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
178166313
179167```
180168
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.
182170
183171#### Identities, Cords, and Terms
184172
@@ -351,7 +339,7 @@ When the dojo pretty-prints a cell it always removes superfluous cell brackets:
351339
352340However, you should always remember that though cells can be presented as lists of more than two nouns, they're always just pairs.
353341
354−### Exercise 1.2.1
342+### Exercise 1.2a
355343
356344Without using the dojo, assess whether each of the following pairs of nouns is equivalent. (Answers are at the bottom of the page.)
357345
@@ -438,7 +426,7 @@ As before, the root of the binary tree (i.e., the whole noun) is at address `1`.
438426
439427Address `1110` indicates "the head of the tail of the tail of the noun".
440428
441−### Exercise 1.2.2
429+### Exercise 1.2b
442430
443431Without using the dojo, evaluate the following expressions. (Answers are at the bottom of the page.)
444432
@@ -450,7 +438,7 @@ Without using the dojo, evaluate the following expressions. (Answers are at the
4504385. +10:[[[2 4 5] [3 6]] 11]
451439```
452440
453−### Exercise 1.2.3
441+### Exercise 1.2c
454442
455443Without 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.)
456444
@@ -464,9 +452,9 @@ Without using the dojo, for each fragment below provide the address relative to
464452
465453That's it for our basic introduction to nouns. Hit `ctrl-d` to exit your comet, or else move on to the next lesson.
466454
467−## 1.1 Exercise Answers
455+## Exercise Answers
468456
469−### 1.1.1
457+### 1.2a
470458
471459+ No
472460+ Yes
@@ -474,7 +462,7 @@ That's it for our basic introduction to nouns. Hit `ctrl-d` to exit your comet,
474462+ Yes
475463+ Yes
476464
477−### 1.1.2
465+### 1.2b
478466
479467+ 86
480468+ [[[65 35] 54] 77]
@@ -482,7 +470,7 @@ That's it for our basic introduction to nouns. Hit `ctrl-d` to exit your comet,
482470+ 77
483471+ 3
484472
485−### 1.1.3
473+### 1.2c
486474
487475+ +2
488476+ +6
@@ -490,4 +478,4 @@ That's it for our basic introduction to nouns. Hit `ctrl-d` to exit your comet,
490478+ +15
491479+ +31
492480
493−### [Next Lesson: The Subject and Its Legs](./docs/learn/hoon/hoon-tutorial/the-subject-and-its-legs.md)
481+### [Next Up: Reading -- Conditionals](../conditionals)
learn/hoon/hoon-tutorial/recursion.md+8−7
@@ -1,9 +1,8 @@
11+++
2−title = "Recursion"
3−weight = 0
2+title = "1.5.1 Walkthrough: Recursion"
3+weight = 9
44template = "doc.html"
55+++
6−
76Recursion is a common pattern for solving certain problems in most programming
87languages, and Hoon is no exception. One of the classically recursive problems
98is that of factorial. The factorial of _n_ is the product of all positive
@@ -77,7 +76,7 @@ expression, as illustrated by `(factorial 4)`. Once the expression cannot be
7776expanded out further, the operations work backwards, successively feeding values
7877into the `mul` functions behind them.
7978
80−##### Tail-Call Optimization
79+#### Tail-Call Optimization
8180
8281Our last example isn't a very efficient use computing resources. The
8382pyramid-shaped illustration approximates what's happening on the **call stack**, a
@@ -120,7 +119,7 @@ last statement of a parent can reuse the same frame instead of needing to
120119add new ones onto the stack. If we write our code properly, we can use a single
121120frame that simply has its values replaced with each recursion.
122121
123−##### A Tail-Recursive Gate
122+#### A Tail-Recursive Gate
124123
125124With a bit of refactoring, we can write a version of our factorial gate that
126125_is_ tail-recursive and can take advantage of this feature:
@@ -171,14 +170,14 @@ before the call, this version is properly tail-recursive. We don't need to do
171170anything to the result of the recursion except recurse it again. That means that
172171each iteration can be replaced instead of held in memory.
173172
174−##### A Note on `$`
173+#### A Note on `$`
175174
176175`$` (pronounced "buc") is, in its use with recursion, a reference to the gate that we are inside
177176of. That's because a gate is just a core with a single arm named `$`. The
178177subject is searched depth-first, head before tail, with faces skipped, and
179178stopping on the first result. In other words, the first match found in the head
180179will be returned. If you wished to refer to the outer `$` in this context, the
181−idiomatic way would be to use [`^$`](/docs/reference/rune/ket). The `^` operator
180+idiomatic way would be to use [`^$`](./docs/reference/hoon-expressions/rune/ket.md). The `^` operator
182181skips the first match of a name.
183182
184183### Exercises
@@ -191,3 +190,5 @@ skips the first match of a name.
191190Disks are stacked on a pole by decreasing order of size. Move all of the
192191disks from one pole to another with a third pole as a spare, moving one
193192disc 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 @@
11+++
2−title = "Setup"
3−weight = 11
2+title = "1.1 Setup"
3+weight = 1
44template = "doc.html"
55+++
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.
77
88## Installing Urbit
99
10−You can [install Urbit](./docs/getting-started/_index.md) 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.
1111
12−Once you're finished you can boot your very own urbit.
12+Once you're finished you can boot your very own ship.
1313
1414## What is an urbit?
1515
@@ -108,4 +108,12 @@ You'll see:
108108
109109You 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.
110110
111−### [Next Lesson: Nouns](./docs/learn/hoon/hoon-tutorial/nouns.md)
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](./docs/learn/hoon/hoon-tutorial/gates.md).)
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](./docs/learn/hoon/hoon-tutorial/nouns.md) 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](./docs/learn/hoon/hoon-tutorial/arms-and-cores.md) and [1.5](./docs/learn/hoon/hoon-tutorial/gates.md) 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](./docs/learn/hoon/hoon-tutorial/gates.md) 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](./docs/learn/hoon/hoon-tutorial/hoon-programs.md), `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](./docs/learn/hoon/hoon-tutorial/atoms-auras-and-simple-cell-types.md)
learn/hoon/hoon-tutorial/structures-and-complex-types.md+3−3
@@ -1,6 +1,6 @@
11+++
2−title = "Structures and Complex Types"
3−weight = 26
2+title = "2.3 Structures and Complex Types"
3+weight = 27
44template = "doc.html"
55+++
66In 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`.
352352
353353That's all we have to say about types in this chapter. More on types in [Chapter 3](./docs/learn/hoon/hoon-tutorial/type-polymorphism.md).
354354
355−### [Next Lesson: Cores](./docs/learn/hoon/hoon-tutorial/cores.md)
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:
652652
653653At 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.
654654
655−### [Next Lesson: Arms and Cores](./docs/learn/hoon/hoon-tutorial/arms-and-cores.md)
655+### [Next Up: Walkthrough -- Ackermann Function](../ackermann)
learn/hoon/hoon-tutorial/trees-sets-and-maps.md+3−2
@@ -1,8 +1,9 @@
11+++
2−title = "Standard Library: Trees, Sets, and Maps"
2+title = "2.4 Standard Library: Trees, Sets, and Maps"
33weight = 30
44template = "doc.html"
55+++
6+
67Along 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.
78
89In 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
318319
319320There are other map functions in the Hoon standard library that didn't cover here.
320321
321−### [Next Lesson: Examples](./docs/learn/hoon/hoon-tutorial/examples.md)
322+### [Next Up: <placeholder>]
learn/hoon/hoon-tutorial/type-checking-and-type-inference.md+2−67
@@ -1,5 +1,5 @@
11+++
2−title = "Type Checking and Type Inference"
2+title = "2.2 Type Checking and Type Inference"
33weight = 25
44template = "doc.html"
55+++
@@ -481,25 +481,6 @@ What makes this program is little harder to follow is that it has a recursion ca
481481
482482Once 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`.
483483
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−
503484#### Lists
504485
505486You 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:
648629~[12 13 33 22 12 11 33]
649630```
650631
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−
662632### Other Kinds of Type Inference
663633
664634So 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
669639
670640In 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.
671641
672−## Exercise Solutions
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](./docs/learn/hoon/hoon-tutorial/structures-and-complex-types.md)
642+### [Next Up: Reading -- Insertion Sort](../insertion)
learn/hoon/hoon-tutorial/type-polymorphism.md+4−1
@@ -1,5 +1,5 @@
11+++
2−title = "Type Polymorphism"
2+title = "2.5 Type Polymorphism"
33weight = 31
44template = "doc.html"
55+++
@@ -572,3 +572,6 @@ Once more let's clear up the dojo subject:
572572```
573573=lead-gate
574574```
575+
576+
577+### [Next Up: Walkthrough -- <placeholder>]
learn/hoon/workbook/recursion.mddeleted−192
@@ -1,192 +0,0 @@
1−+++
2−title = "Recursion"
3−weight = 3
4−template = "doc.html"
5−+++
6−Recursion is a common pattern for solving certain problems in most programming
7−languages, and Hoon is no exception. One of the classically recursive problems
8−is that of factorial. The factorial of _n_ is the product of all positive
9−integers less than or equal to N. Thus the factorial of 5, denoted as _5!_,
10−would be:
11−
12−```
13−5 * 4 * 3 * 2 * 1 = 120
14−```
15−
16−### Factorial In Hoon
17−
18−Let's implement a factorial calculator in Hoon. To do so, we'll write a
19−recursive `gate` (Hoon's equivalent of a function) to perform the relevant
20−computation. Save the code below as `factorial.hoon` in your ship's `/gen`
21−directory.
22−
23−```
24−|= n=@ud
25−?: =(n 1)
26− 1
27−(mul n $(n (dec n)))
28−```
29−
30−Our `gate` takes one sample (argument) `n` that must nest inside `@ud`, the
31−unsigned-integer type.
32−
33−Next we check to see if `n` is `1`. If so, the result is just `1`, since
34−`1 * 1 = 1`.
35−
36−If, however, `n` is _not_ `1`, then we branch to the final line of the code,
37−`(mul n $(n (dec n)))`, where the recursion logic lives. Here, we multiply `n`
38−by the recursion of `n` minus `1`. `$` initiates recursion: it calls the gate
39−that we're already in, but replaces its sample.
40−
41−In our example, we multiply `n` with the product of this _entire gate
42−all over again_ with `$(n (dec n))`, except when that new gate has its sample
43−decremented by one. This works recursively because each new gate will, of
44−course, itself contain the code to call a further-decremented gate. Gates will
45−continue to call new, further-decremented gates until `n` is `1`, and that `1`
46−will be the final number to be multiplied by.
47−
48−Let's run the program in the Dojo:
49−
50−```
51−> +factorial 5
52−120
53−```
54−
55−It may help to visualize the operation of our example gate. The pseudo-Hoon below
56−illustrates what happens when we use it to find the factorial of 5:
57−
58−```
59−(factorial 5)
60−(mul 5 (factorial 4))
61−(mul 5 (mul 4 (factorial 3)))
62−(mul 5 (mul 4 (mul 3 (factorial 2))))
63−(mul 5 (mul 4 (mul 3 (mul 2 (factorial 1)))))
64−(mul 5 (mul 4 (mul 3 (mul 2 1))))
65−(mul 5 (mul 4 (mul 3 2)))
66−(mul 5 (mul 4 6))
67−(mul 5 24)
68−120
69−```
70−
71−It's easy to see how we're "floating" gate calls until we reach the final
72−iteration of such calls that only produces a value. The `mul n` component of the
73−gate leaves something like `mul 5`, waiting for the final series of terms
74−to be operated upon. The `$(n (dec n))` component is what expands out the
75−expression, as illustrated by `(factorial 4)`. Once the expression cannot be
76−expanded out further, the operations work backwards, successively feeding values
77−into the `mul` functions behind them.
78−
79−##### Tail-Call Optimization
80−
81−Our last example isn't a very efficient use computing resources. The
82−pyramid-shaped illustration approximates what's happening on the **call stack**, a
83−memory structure that tracks the instructions of the program. In our example
84−code, every time a parent gate calls another gate, the gate being called is
85−"pushed" to the top of the stack in the form of a frame. This process continues
86−until a value is produced instead of a function, completing the stack.
87−
88−```
89− Push order Pop order
90−(fifth frame) ^ |
91−(fourth frame) | |
92−(third frame) | |
93−(second frame) | |
94−(first frame) | V
95−```
96−
97−Once this stack of frames is completed, frames "pop" off the stack starting at
98−the top. When a frame is popped, it executes the contained gate and passes
99−produced data to the frame below it. This process continues until the stack
100−is empty, giving us the gate's output.
101−
102−When a program's final expression uses the stack in this way, it's considered to
103−be **not tail-recursive**. This usually happens when the last line of executable
104−code calls more than one gate, our example code's `(mul n $(n (dec n)))` being
105−such a case. That's because such an expression needs to hold each iteration of
106−`$(n (dec n)` in memory so that it can know what to run against the `mul`
107−function every time.
108−
109−To reiterate: if you have to manipulate the result of a recursion as the last
110−expression of your gate, as we did in our example, the function is not
111−tail-recursive, and therefore not very efficient with memory. A problem arises
112−when we try to recurse more times that we have space on the stack. This will
113−result in our computation failing and producing a stack overflow. If we tried
114−to find the factorial of `5.000.000`, for example, we would almost certainly
115−run out of stack space.
116−
117−But the Hoon compiler, like most compilers, is smart enough to notice when the
118−last statement of a parent can reuse the same frame instead of needing to
119−add new ones onto the stack. If we write our code properly, we can use a single
120−frame that simply has its values replaced with each recursion.
121−
122−##### A Tail-Recursive Gate
123−
124−With 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:
126−
127−```
128−|= n=@ud
129−=/ t=@ud 1
130−|-
131−?: =(n 1)
132− t
133−$(n (dec n), t (mul t n))
134−```
135−
136−The above code should look familiar. We are still building a gate that
137−takes one argument `n`. This time, however, we are also putting a face on a
138−`@ud` and setting it's initial value to 1. The `|-` here is used to create a new
139−gate with one arm `$` and immediately call it. Think of `|-` as the recursion
140−point.
141−
142−We then evaluate `n` to see if it is 1. If it is we return the value of `t`. In
143−the case that `n` is anything other than 1, we perform our recursion:
144−
145−```
146−$(n (dec n), t (mul t n))
147−```
148−
149−All we are doing here is recursing our new gate and modifying the values of `n`
150−and `t`. `t` is used as an accumulator variable that we use to keep a running
151−total for the factorial computation.
152−
153−Let's use pseudo-Hoon to illustrate how the stack is working in this example for
154−factorial 5.
155−
156−```
157−(factorial 5)
158−(|- 5 1)
159−(|- 4 5)
160−(|- 3 20)
161−(|- 2 60)
162−(|- 1 120)
163−120
164−```
165−
166−We simply multiply `t` and `n` to produce the new value of `t`, and then
167−decrement `n` before repeating. Since this `$` call is the final and solitary
168−thing that is run in the default case and since we are doing all computation
169−before the call, this version is properly tail-recursive. We don't need to do
170−anything to the result of the recursion except recurse it again. That means that
171−each iteration can be replaced instead of held in memory.
172−
173−##### A Note on `$`
174−
175−`$` (pronounced "buc") is, in its use with recursion, a reference to the gate that we are inside
176−of. That's because a gate is just a core with a single arm named `$`. The
177−subject is searched depth-first, head before tail, with faces skipped, and
178−stopping on the first result. In other words, the first match found in the head
179−will be returned. If you wished to refer to the outer `$` in this context, the
180−idiomatic way would be to use [`^$`](./docs/reference/hoon-expressions/rune/ket.md). The `^` operator
181−skips the first match of a name.
182−
183−### Exercises
184−
185−1. Write a recursive gate that produces the first _n_
186−[Fibonacci numbers](https://en.wikipedia.org/wiki/Fibonacci_number)
187−
188−2. Write a recursive gate that produces a list of moves to solve the
189−[Tower of Hanoi problem](https://en.wikipedia.org/wiki/Tower_of_Hanoi).
190−Disks are stacked on a pole by decreasing order of size. Move all of the
191−disks from one pole to another with a third pole as a spare, moving one
192−disc at a time, without putting a larger disk on top of a smaller disk.
using/_index.md+9−7
@@ -6,10 +6,12 @@ template = "sections/docs/chapters.html"
66+++
77This section contains guides to using your urbit.
88
9−- [Admin and Operation](./docs/using/admin.md) is a guide to the basic commands used to interact with your ship.
10−- [Messaging](./docs/using/messaging.md) tells you how to use Talk, our chat system.
11−- [Shell](./docs/using/shell.md) is a guide to using Dojo, our command-line interface.
12−- [Introduction to the Filesystem](./docs/using/filesystem.md) explains the basics of using use Clay, our revision-control filesystem.
13−- [Source Layout](./docs/using/layout.md) walks you through the various directories of the Arvo operating system.
14−- [Sail and Udon](./docs/using/sail-and-udon.md) is a guide to Sail: Hoon markup that's used to build web pages with XML and Udon, which is our take on Markdown.
15−- [Generators](./docs/using/generators.md) will explain how to use the "generator," a kind of file that's the easiest way to run Hoon programs.
9+- [Creating a Development Ship](creating-a-development-ship) will show you how to set up the environment for coding on Urbit.
10+- [Admin and Operation](admin) is a guide to the basic commands used to interact with your ship.
11+- [Messaging](messaging) tells you how to use Talk, our chat system.
12+- [Shell](shell) is a guide to using Dojo, our command-line interface.
13+- [Introduction to the Filesystem](filesystem) explains the basics of using use Clay, our revision-control filesystem.
14+- [Source Layout](layout) walks you through the various directories of the Arvo operating system.
15+- [Sail](sail) is a guide to Sail: Hoon markup that's used to build web pages with XML.
16+- [Udon](udon) is a guide to Udon, which is our take on Markdown.
17+- [Generators](generators) will explain how to use the "generator," a kind of file that's the easiest way to run Hoon programs.
getting-started/creating-a-development-ship.md → using/creating-a-development-ship.mdrenamed+1−1
@@ -1,6 +1,6 @@
11+++
22title = "Creating a Development Ship"
3−weight = 4
3+weight = 0
44template = "doc.html"
55+++
66To do work with Hoon and with the system, we recommended using a "fake" ship -- one not connected to the network.
using/layout.mddeleted−172
@@ -1,172 +0,0 @@
1−+++
2−title = "Source layout"
3−weight = 5
4−template = "doc.html"
5−+++
6−When you boot an urbit, we transfer the current version of the Arvo
7−operating environment to your urbit over our network. That is, the
8−source for the system lives on your urbit. Here we'll take a brief tour
9−through the structure of a base Arvo desk.
10−
11−Looking at the top level of
12−[the Arvo repo](http://github.com/urbit/arvo), or any urbit desk that
13−has been mounted to unix, we see something like:
14−
15−```
16−app/
17−arvo/
18−gen/
19−lib/
20−mar/
21−ren/
22−sec/
23−sur/
24−sys/
25−tests/
26−web/
27−web.md
28−```
29−
30−Running the command `+ls %` from your urbit's Dojo produces something similar:
31−
32−```
33−~your-urbit:dojo> +ls %
34−LICENSE/txt app/ gen/ lib/ mar/ ren/ sec/com/ sur/ sys/ tests/ web/
35−```
36−
37−Let's step through, directory by directory.
38−
39−## sys/
40−
41−This is where the Arvo kernel lives. `sys/` contains:
42−
43−##### `sys/hoon.hoon`
44−
45−[Hoon](./docs/learn/hoon/_index.md) is our programming language. Since Hoon
46−compiles itself, the language is actually specified in this source file.
47−
48−##### `sys/zuse.hoon`
49−
50−Zuse is the Arvo standard library.
51−
52−##### `sys/arvo/hoon`
53−
54−This is the source file for the central Arvo event dispatcher.
55−
56−##### `sys/vane`
57−
58−Vanes are sort of like kernel modules. These are worth listing one by one:
59−
60−##### `sys/vane/ames.hoon`
61−
62−Ames is our network protocol.
63−
64−##### `sys/vane/behn.hoon`
65−
66−Behn is a simple timer.
67−
68−##### `sys/vane/clay.hoon`
69−
70−Clay is our filesystem.
71−
72−##### `sys/vane/dill.hoon`
73−
74−Dill is our terminal driver.
75−
76−##### `sys/vane/eyre.hoon`
77−
78−Eyre is our webserver.
79−
80−##### `sys/vane/ford.hoon`
81−
82−Ford is our build system.
83−
84−##### `sys/vane/gall.hoon`
85−
86−Gall is our application model.
87−
88−##### `sys/vane/jael.hoon`
89−
90−Jael is our secret vault.
91−
92−##### `sys/vane/xmas.hoon`
93−
94−Xmas is the new Ames, which will go live in our next big release.
95−
96−That's it. That's the whole system.
97−
98−---
99−
100−## app/
101−
102−This is where [Gall](./docs/learn/arvo/gall.md) apps live. Gall apps are stateful
103−servers, sort of like unix daemons. One familiar one is `app/hall.hoon` which is
104−the source code for [Hall](./docs/learn/arvo/hall.md), the Urbit messaging transport
105−layer. And there's also `app/dojo.hoon` — that's your shell.
106−
107−---
108−
109−## gen/
110−
111−`gen/` holds generators. Generators are short Dojo scripts.
112−
113−---
114−
115−## lib/
116−
117−`lib/` holds shared libraries for programs. `lib/sole` is a good
118−example — that's the console library that's shared by both Dojo in the
119−command line, and the Dojo web client.
120−
121−---
122−
123−## mar/
124−
125−This is where marks live. Marks are data type definitions used by Ford.
126−A mark is like a mime-type, but specified in executable code.
127−
128−---
129−
130−## ren/
131−
132−These are web renderers. A renderer handles web requests of a particular
133−type.
134−
135−Default web requests in urbit are handled as a `.urb`, which is caught
136−by the `urb.hoon` renderer. This wraps the request in our default `CSS`
137−and `JS` and adds some routing magic for certain paths.
138−
139−---
140−
141−## sec/
142−
143−Here are security drivers that Urbit uses to log into the APIs of various
144−non-Urbit services.
145−
146−---
147−
148−## sur/
149−
150−`sur/` contains shared data structures. Files in `sur` are like header
151−files in C.
152−
153−---
154−
155−## tests/
156−
157−`tests/` is the conventional place to put tests that use the +test generator and
158−lib/test/*
159−
160−---
161−
162−## web/
163−
164−Here are files publicly accessible to the web, as made possible by
165−[Eyre](./docs/learn/arvo/eyre.md).
166−
167−---
168−
169−## web.md
170−
171−This is the homepage for your urbit. You'll see it at
172−`http://localhost:8080/` or `https://your-urbit.urbit.org/`.