on master help sign in
updates to hoon-2, polymorphism doc added
commita3d2d5cddb541fcbb18efde274881bca72799106 authorjoshuareagan <josh@tlon.io> dateThu 13 Dec 2018, 18:01 (8 years ago) parent176afe1
11 files changed+788−116
docs/tutorials/hoon/hoon-ch2-1.udon+10−6 docs/tutorials/hoon/hoon-ch2-11.udon+1 docs/tutorials/hoon/hoon-ch2-2.udon+9−9 docs/tutorials/hoon/hoon-ch2-3.udon+7−11 docs/tutorials/hoon/hoon-ch2-4.udon+8−8 docs/tutorials/hoon/hoon-ch2-5.udon+23−21 docs/tutorials/hoon/hoon-ch2-6.udon+17−29 docs/tutorials/hoon/hoon-ch2-7.udon+18−13 docs/tutorials/hoon/hoon-ch2-8.udon+20−18 docs/tutorials/hoon/hoon-ch2-9.udon+1−1 docs/tutorials/hoon/hoon-ch3-1.udon+674
docs/tutorials/hoon/hoon-ch2-1.udon+10−6
@@ -8,9 +8,9 @@
88
99# Writing Hoon Programs
1010
11−So far you've only entered short snippets of Hoon code into the dojo. Let's look at some substantive programs!
11+So far you've only entered short snippets of Hoon code into the dojo. Let's look at some substantive programs.
1212
13−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 later chapters.
13+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.
1414
1515## Setup
1616
@@ -25,11 +25,11 @@ To use your favorite text editor to write Hoon programs you'll first need to exp
2525
2626(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.)
2727
28−Mounting may take a moment. The `>=` response means the command is successful. From within Unix (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.
28+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.
2929
3030## List of Numbers
3131
32−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` to `n`. (Remember that an atom is just an unsigned integer.)
32+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.)
3333
3434Each line is commented with a number for convenient line reference:
3535
@@ -51,11 +51,13 @@ Save this as 'listnum.hoon' in `/home/gen` of your urbit's pier. To run it ente
5151~[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24]
5252```
5353
54+Note that `~[item-1 item-2 item-3 ...]` is, by convention, the way the dojo pretty-prints lists.
55+
5456### Functional Programming, Runes, and Whitespace
5557
5658Before going over how the above code works we should point out three things.
5759
58−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. 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.
60+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.
5961
6062Second, 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.
6163
@@ -97,7 +99,7 @@ four items: [item-1 [item-2 [item-3 [item-4 ~]]]]
9799 item-4 ~
98100```
99101
100−So, for example, the list of atoms `~[1 2 3 4]` is structured as the following noun:
102+So, for example, the list of atoms `1 2 3 4` is structured as the following noun:
101103
102104```
103105 [1 [2 [3 [4 ~]]]]
@@ -113,6 +115,8 @@ So, for example, the list of atoms `~[1 2 3 4]` is structured as the following n
113115 4 ~
114116```
115117
118+(Note that `~[1 2 3 4]` is equivalent to `[1 2 3 4 ~]`. The former is how the dojo pretty-prints lists.)
119+
116120The program is to generate the appropriate list of numbers given an input value, `end`: `~[1 2 3 ...]`. How?
117121
118122Essentially, 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.
docs/tutorials/hoon/hoon-ch2-11.udon+1
@@ -1,5 +1,6 @@
11:- :~ navhome/'/docs/'
22 navuptwo/'true'
3+ next/'true'
34 sort/'37'
45 title/'2.11 Examples'
56 ==
docs/tutorials/hoon/hoon-ch2-2.udon+9−9
@@ -10,7 +10,7 @@
1010
1111The study of Hoon can be divided into two parts: syntax and semantics.
1212
13−The [syntax](https://en.wikipedia.org/wiki/Syntax_(programming_languages%29) of a programming language is the set of rules that determine what counts as admissible code in that language. It determines which characters may be used in the source, and also how these characters may be assembled to constitute a program. Failing to follow these rules when writing a program and then trying to run it will result in a syntax error.
13+The [syntax](https://en.wikipedia.org/wiki/Syntax_(programming_languages%29) of a programming language is the set of rules that determine what counts as admissible code in that language. It determines which characters may be used in the source, and also how these characters may be assembled to constitute a program. Attempting to run a program that doesn't follow these rules will result in a syntax error.
1414
1515The [semantics](https://en.wikipedia.org/wiki/Semantics_(computer_science%29) of a programming language concerns the meaning of the various parts of that language's code.
1616
@@ -50,7 +50,7 @@ gap [>1 space, nl] rac ]
5050hax # rit )
5151```
5252
53−Learning and using these names of non-alphanumeric symbols is entirely optional; you can become an expert Hoon programmer without them. Many Hoon programmers find them helpful, however.
53+Learning and using these names of non-alphanumeric symbols is entirely optional; you can become an expert Hoon programmer without them. Many Hoon programmers find them helpful, however, particularly when talking to someone else who knows them.
5454
5555Note that the list includes two separate whitespace forms: `ace` for a single space; `gap` is either 2+ spaces or a newline. In Hoon, the only whitespace significance is the distinction between `ace` and `gap` -- i.e., the distinction between one space and more than one.
5656
@@ -93,7 +93,7 @@ We start with atom literals. Each of these is a basic expression of Hoon that e
93930b1101.1001
9494```
9595
96−Recall from [lesson 1.2](../../hoon-ch1/hoon-ch1-2) that even though atoms are unsigned integers, they can be pretty-printed in different ways. The way an atom is to be represented depends on its aura. The literal syntax for each of the hard-coded auras will be explained further in [lesson 2.4](../hoon-ch2-4).
96+Recall from [lesson 1.2](../hoon-ch1-2) that even though atoms are unsigned integers, they can be pretty-printed in different ways. The way an atom is to be represented depends on its aura. The literal syntax for each of the hard-coded auras will be explained further in [lesson 2.4](../hoon-ch2-4).
9797
9898Cell literals can be written in Hoon using `[ ]`. Cell literals are complex, because other expressions are put inside the square brackets. Examples:
9999
@@ -120,7 +120,7 @@ You can also put complex expressions inside square brackets to make a cell. The
120120
121121### Wings
122122
123−A wing expression is a series of limb expressions separated by `.`. You learned about these in [sections 1.3](../../hoon-ch1/hoon-ch1-3) and [sections 1.4](../../hoon-ch1/hoon-ch1-4).
123+A wing expression is a series of limb expressions separated by `.`. You learned about these in [sections 1.3](../hoon-ch1-3) and [sections 1.4](../hoon-ch1-4).
124124
125125Let's start with the base case: a single limb. A limb expression is a trivial wing expression -- there is only one limb in the series. Some one-limb wings:
126126
@@ -134,13 +134,13 @@ Let's start with the base case: a single limb. A limb expression is a trivial w
134134- `mul`
135135- `kebab-case-123`
136136
137−As a special limb we also have `$`. This is the name of the arm in special one-armed cores called "gates". (We covered the role of `$` in [lesson 1.5](../../hoon-ch1/hoon-ch1-5).)
137+As a special limb we also have `$`. This is the name of the arm in special one-armed cores called "gates". (We covered the role of `$` in [lesson 1.5](../hoon-ch1-5).)
138138
139139Wing expressions with multiple limbs are complex expressions. Examples:
140140
141141- `+2.+3.+4`
142142- `-.+.+`
143−- `search.path.into.subject`
143+- `resolution.path.into.subject`
144144- `+>.$`
145145- `a.b.c`
146146- `-.b.+2`
@@ -160,7 +160,7 @@ Expressions with a rune at the beginning are rune expressions. Most runes are u
160160
161161Runes are classified by family (with the exceptions of `--` and `==`). The first of the two symbols indicates the family -- e.g., the `^-` rune is in the `^` family of runes, and the `|=` and `|%` runes are in the `|` family. The runes of particular family usually have related meanings. Two simple examples: the runes in the `|` family are all used to create cores, and the runes in the `:` family are all used to create cells.
162162
163−Rune expressions are usually complex, which means they usually have one or more subexpressions. The appropriate syntax varies from rune to rune; after all, they're used for different purposes. To see the correct syntax of a particular rune, consult the rune reference (link). Nevertheless, there are some general principles that hold of all rune expressions.
163+Rune expressions are usually complex, which means they usually have one or more subexpressions. The appropriate syntax varies from rune to rune; after all, they're used for different purposes. To see the syntax rules for a particular rune, consult the [rune reference](../../../reference/rune). Nevertheless, there are some general principles that hold of all rune expressions.
164164
165165#### Tall and Flat Forms
166166
@@ -264,7 +264,7 @@ The irregular `( )` gate-calling syntax is versatile -- it is also a shortcut fo
264264
265265The `( )` gate-calling syntax can be used for gates of any other [arity](https://en.wikipedia.org/wiki/Arity) as well.
266266
267−You've already seen two other irregular forms. In [lesson 1.5](../../hoon-ch1/hoon-ch1-5), you made a gate that takes an atom `a` for its sample and returns `a + 1`: `|=(a=@ (add 1 a))`. This expression uses the `|=` rune in flat form.
267+You've already seen two other irregular forms. In [lesson 1.5](../hoon-ch1-5), you made a gate that takes an atom `a` for its sample and returns `a + 1`: `|=(a=@ (add 1 a))`. This expression uses the `|=` rune in flat form.
268268
269269```
270270> =inc |=(a=@ (add 1 a))
@@ -582,7 +582,7 @@ In a sufficiently complicated expression it's tedious to keep track of all the p
582582
583583In some programming languages there is an indentation convention according to which an expression embedded within a parent expression is indented more to the right. In a sufficiently long and complicated function with many embedded subexpressions, the tendency is for the code to shift more and more to the right. This tendency is called *indentation creep*, and it can become an irritating problem when working with long functions. It's true that short functions are better, but long ones sometimes need to be written.
584584
585−Ordinary indentation conventions give long functions a _diagonal_ shape, which is a poor fit for most editor windows. Hoon is designed to be written with 'backstep' indentation (explained later in this lesson) so that the code flows _down_, not down and across.
585+Ordinary indentation conventions give long functions a _diagonal_ shape, which is a poor fit for most editor windows. Because Hoon is designed to be written with 'backstep' indentation, the code flows _down_, not down and across.
586586
587587### Feature/label confusion
588588
docs/tutorials/hoon/hoon-ch2-3.udon+7−11
@@ -8,19 +8,19 @@
88
99# Simple One-Gate Programs
1010
11−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 defines a gate. (Gates are one-armed cores of Hoon that can be used as functions -- this is covered in [lesson 1.5](../../hoon-ch1/hoon-ch1-5).)
11+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](../hoon-ch1-5).)
1212
1313For 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.
1414
1515We will also continue to run one-line snippets of code in the dojo. We encourage you to enter these for yourself as well.
1616
17−## Intro to Writing Gates
17+## Writing Gates: A Review
1818
1919Let's look at a really simple gate: `|=(a=@ 15)`. This gate takes any atom as input and returns the value `15`.
2020
2121The `|=` 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`.
2222
23−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](../../hoon-ch1/hoon-ch1-2) 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.
23+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](../hoon-ch1-2) 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.
2424
2525You 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:
2626
@@ -31,9 +31,6 @@ You could have picked a different type for the first subexpression of `|=(a=@ 15
3131> (|=(@ 15) 22)
323215
3333
34−> (|=(* 15) 11)
35−15
36−
3734> (|=(* 15) 22)
383515
3936
@@ -43,7 +40,7 @@ nest-fail [crash message]
4340
4441The 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.
4542
46−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. The call didn't work! 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`.
43+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.)
4744
4845Ordinarily 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.
4946
@@ -102,7 +99,6 @@ Save this and try to run it from the dojo again:
10299
103100```
104101> +even 22
105−[stack trace]
106102nest-fail
107103```
108104
@@ -271,7 +267,7 @@ The reasons for Hoon's having both `?:` and `?.` involve code neatness and clari
271267
272268#### `?&` logical 'AND'
273269
274−The `?&` rune is for logical 'AND'. It takes two or more subexpressions, each of which must evaluate to a flag, `?`; and if all subhoons evaluate to `%.y` then the result of the `?&` hoon is `%.y`. Otherwise it's `%.n`. In tall form the expression is terminated with `==`.
270+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 `==`.
275271
276272```
277273> ?& %.y %.y %.y ==
@@ -634,7 +630,7 @@ The `$( )` syntax is an irregular form of the the `%=` rune. We can rewrite tha
634630
635631This 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 `==`.
636632
637−Remember from lessons [1.4](../../hoon-ch1/hoon-ch1-4) and [1.5](../../hoon-ch1/hoon-ch1-5) 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](../../hoon-ch1/hoon-ch1-5) 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.
633+Remember from lessons [1.4](../hoon-ch1-4) and [1.5](../hoon-ch1-5) 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](../hoon-ch1-5) 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.
638634
639635### Decrement
640636
@@ -712,7 +708,7 @@ Let's look at the decrement program again, this time using the regular version o
712708
713709Strictly 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.
714710
715−When we use `|-` in our decrement program, we'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 `|-`.
711+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 `|-`.
716712
717713When `$( )` 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 `%= ^$`.
718714
docs/tutorials/hoon/hoon-ch2-4.udon+8−8
@@ -22,7 +22,7 @@ In this lesson we'll cover (1)-(4) as they pertain to atoms and simple cell type
2222
2323## Atoms and Auras
2424
25−In [lesson 1.2](../../hoon-ch1/hoon-ch1-2) we defined what an atom is: any unsigned integer. In this lesson we'll expand on that discussion, going over how Hoon's type system implements auras.
25+In [lesson 1.2](../hoon-ch1-2) we defined what an atom is: any unsigned integer. In this lesson we'll expand on that discussion, going over how Hoon's type system implements auras.
2626
2727In the most straightforward sense, atoms simply are unsigned integers. But they can also be interpreted as representing signed integers, ASCII symbols, floating-point values, dates, binary numbers, hexadecimal numbers, and more. Every atom is, in and of itself, just an unsigned integer; but Hoon keeps track of type information about each atom, and this info tells Hoon how to interpret the atom in question.
2828
@@ -30,7 +30,7 @@ The piece of type information that determines how Hoon interprets an atom is cal
3030
3131How is aura information generated so that it can be tracked? One way involves *type inference*. In certain cases Hoon's type system can infer the type of an expression using syntactic clues. In the most straightforward case of type inference, the expression is simply data as a [literal](https://en.wikipedia.org/wiki/Literal_(computer_programming%29). Hoon recognizes the aura literal syntax and infers that the data in question is an atom with the aura associated with that syntax.
3232
33−To see the inferred type of a literal expression in the dojo, use the `?` operator. (Note: this operator isn't part of the Hoon programming language; it's a dojo-only tool. It's a very useful tool for learning Hoon, however.)
33+To see the inferred type of a literal expression in the dojo, use the `?` operator. (Note: this operator isn't part of the Hoon programming language; it's a dojo-only tool. It's a very useful tool for learning about types in Hoon, however.)
3434
3535The `?` dojo operator shows both the product and the inferred type of an expression. Let's try `?` on `15`:
3636
@@ -43,7 +43,7 @@ The `?` dojo operator shows both the product and the inferred type of an express
434315
4444```
4545
46−The '`@ud`' is the inferred type of `15` (and of course `15` is the product). The `@` is for 'atom' and the `ud` is for 'unsigned decimal'. The letters after the `@` indicate the 'aura' of the atom.
46+The `@ud` is the inferred type of `15` (and of course `15` is the product). The `@` is for 'atom' and the `ud` is for 'unsigned decimal'. The letters after the `@` indicate the 'aura' of the atom.
4747
4848One important role played by the type system is to make sure that the output of an expression is of the intended data type. If the output is of the wrong type then the programmer did something wrong. But how does Hoon know what the intended data type is? The programmer must specify this explicitly by using a 'cast'. To cast for an unsigned decimal atom, you can use the `^-` rune along with the `@ud` from above.
4949
@@ -56,9 +56,9 @@ Let's try one in the dojo. For the expression to be assessed we'll use `15` aga
565615
5757```
5858
59−Because `@ud` is the inferred type of `15`, the cast succeeds. Notice that the `^-` expression never does anything to modify the underlying noun of the second subexpression. It's used simply to mandate a type-check on that expression.
59+Because `@ud` is the inferred type of `15`, the cast succeeds. Notice that the `^-` expression never does anything to modify the underlying noun of the second subexpression. It's used simply to mandate a type-check on that expression. This check occurs at compile-time (i.e., when the expression is compiled to Nock).
6060
61−What about when the inferred type doesn't fit under the cast type? You get a `nest-fail` crash:
61+What about when the inferred type doesn't fit under the cast type? You get a `nest-fail` crash at compile-time:
6262
6363```
6464> ^-(@ud [13 14])
@@ -246,7 +246,7 @@ Hoon uses the outermost cast to infer the type:
2462460b1.0000
247247```
248248
249−As you can see, an atom with one aura can be converted to another aura. For a convenient shorthand, you can do this conversion with irregular cast syntax, e.g. `` `@ud` ``, rather than using the `^-` rune twice:
249+As you can see, an atom with one aura can be converted to another aura. For a convenient shorthand, you can do this conversion with irregular cast syntax, e.g. `\`@ud\``, rather than using the `^-` rune twice:
250250
251251```
252252> `@ud`0x10
@@ -259,7 +259,7 @@ As you can see, an atom with one aura can be converted to another aura. For a c
2592590xa
260260```
261261
262−This is what we mean when we call auras 'soft' types. The above examples show that the programmer can get around the type system for auras by casting up to `@` and then back down to the specific aura, say `@ub`; or by casting with `` `@ub` `` for short.
262+This is what we mean when we call auras 'soft' types. The above examples show that the programmer can get around the type system for auras by casting up to `@` and then back down to the specific aura, say `@ub`; or by casting with `\`@ub\`` for short.
263263
264264## Examples
265265
@@ -731,7 +731,7 @@ You are also free to embed more square brackets `[ ]` to indicate cells within c
731731nest-fail
732732```
733733
734−You can also specify just part of the type structure, leaving other parts more general. Keep in mind that when you do this, Hoon's type system will infer the type from these more general casts. Type information will be thrown away:
734+You can also be highly specific with certain parts of the type structure, leaving other parts more general. Keep in mind that when you do this, Hoon's type system will infer a general type from the general part of the cast. Type information may be thrown away:
735735
736736```
737737> ^-([^ @ux] [[12 --0b1101] 0xdead.beef])
docs/tutorials/hoon/hoon-ch2-5.udon+23−21
@@ -16,7 +16,7 @@ Let's enumerate the most common cases where a type check is called for in Hoon.
1616
1717### Cast Runes
1818
19−The most obvious case is when there is a cast rune in your code. These runes don't directly have any effect on the data produced by your code; they simply indicate that a type check should be performed on a piece of code.
19+The most obvious case is when there is a cast rune in your code. These runes don't directly have any effect on the compiled result of your code; they simply indicate that a type check should be performed on a piece of code at compile-time.
2020
2121#### `^-` Cast with a Type
2222
@@ -65,7 +65,7 @@ nest-fail
6565
6666The `^+` rune takes two subexpressions. The first subexpression is evaluated and its type is inferred. The second subexpression is evaluated and its inferred type is compared against the type of the first. If the type of the second provably nests under the type of the first, the result of the `^+` expression is just the value of its second subexpression. Otherwise, the code fails to compile.
6767
68−This rune is useful for casting when you already have an example noun whose type you may not know or be able to construct easily, but when you want the output of a expression to have that same type.
68+This rune is useful for casting when you already have a noun -- or expression producing a noun -- whose type you may not know or be able to construct easily. If you want your output value to be of the same type, you can use `^+`.
6969
7070More examples:
7171
@@ -99,7 +99,7 @@ You can evade the `.=` type-check by casting one of its subexpressions to a `*`,
9999%.n
100100```
101101
102−It isn't recommended that you evade type safety in this way, however.
102+It isn't recommended that you evade the rules in this way, however.
103103
104104The `.+` increment rune -- including its `+( )` irregular form -- does a type check to ensure that its subexpression must evaluate to an atom.
105105
@@ -172,7 +172,7 @@ Cast runes also shape how Hoon understands an expression type. The inferred typ
172172^+([0x1b 0b11] [0x123 0b101]) [@ux @ub]
173173```
174174
175−You can also use the irregular `` ` ` `` syntax for casting in the same way as `^-`; e.g., `` `@`123 `` for `^-(@ 123)`.
175+You can also use the irregular `\` \`` syntax for casting in the same way as `^-`; e.g., `\`@\`123` for `^-(@ 123)`.
176176
177177One thing to note about casts is that they can 'throw away' type information. The second subexpression of `^-` and `^+` casts may be inferred to have a very specific type. If the cast type is more general, then the more specific type information is lost. Consider the literal `[12 14]`. The inferred type of this expression is `[@ @]`, i.e., a cell of two atoms. If we cast over `[12 14]` with `^-(^ [12 14])` then the inferred type is just `^`, the set of all cells. The information about what kind of cell it is has been thrown away. If we cast over `[12 14]` with `^-(* [12 14])` then the inferred type is `*`, the set of all nouns. All interesting type information is thrown away on the latter cast.
178178
@@ -208,13 +208,13 @@ If you try to call this gate with the wrong kind of argument, you get a `nest-fa
208208
209209### Using Conditionals for Inference by Branch
210210
211−You learned about a few conditional runes earlier in the chapter (e.g., `?:`, `?.`), but other runes of the `?` family are used for branch-specialized type inference. The `?@`, `?^`, and `?~` conditionals take three subexpressions, which play the same basic role as the corresponding subexpressions of `?:` -- the first is the test condition, which evaluates to a flag `?`. If the test condition is true, the second subexpression is evaluated; otherwise the third. These second and third subexpressions are the 'branches' of the conditional.
211+You learned about a few conditional runes earlier in the chapter (e.g., `?:`, `?.`), but other runes of the `?` family are used for branch-specialized type inference. The `?@`, `?^`, and `?~` conditionals each take three subexpressions, which play the same basic role as the corresponding subexpressions of `?:` -- the first is the test condition, which evaluates to a flag `?`. If the test condition is true, the second subexpression is evaluated; otherwise the third. These second and third subexpressions are the 'branches' of the conditional.
212212
213−There is also a `?=` rune for matching expressions with certain types.
213+There is also a `?=` rune for matching expressions with certain types, returning `%.y` for a match and `%.n` otherwise.
214214
215215#### `?=` Non-recursive Type Match Test
216216
217−The `?=` rune takes two subexpressions. The first subexpression should be a type (specifically, it should not be a type that is defined recursively; more on this point later). The second subexpression is evaluated and the resulting value is compared to the first type. If the value is an instance of the type, `%.y` is produced. Otherwise, `%.n`. Examples:
217+The `?=` rune takes two subexpressions. The first subexpression should be a type. The second subexpression is evaluated and the resulting value is compared to the first type. If the value is an instance of the type, `%.y` is produced. Otherwise, `%.n`. Examples:
218218
219219```
220220> ?=(@ 12)
@@ -246,14 +246,14 @@ The `?=` rune takes two subexpressions. The first subexpression should be a typ
246246%.y
247247```
248248
249−We haven't talked much about recursively defined types yet. We'll discuss these more soon, but it's worth pointing out that every list type qualifies as such, and hence should not be used with `?=`:
249+We haven't talked much about types that are made with a type constructor yet. We'll discuss these more soon, but it's worth pointing out that every list type qualifies as such, and hence should not be used with `?=`:
250250
251251```
252252> ?=((list @) ~[1 2 3 4])
253253fish-loop
254254```
255255
256−Using a recursively defined non-basic type with the `?=` rune results in a `fish-loop` error.
256+Using these non-basic constructed types with the `?=` rune results in a `fish-loop` error.
257257
258258##### Using `?=` for Type Inference
259259
@@ -291,7 +291,7 @@ You can't see it here either, but the inferred type of `b` in `[| b]` is `^`. T
291291
292292##### The Type Spear
293293
294−I think I'm a trustworthy guy, but perhaps you don't want to take my word for it. What if you want to see the inferred type of `b` for yourself for each conditional branch? One way to do this is with a 'type spear'. But we need to understand the `!>` rune before using this mighty weapon of war. `!>` takes one subexpression, and constructs a cell from it. The subexpression is evaluated and becomes the tail of the product cell, with a `q` face attached. The head of the product cell is the inferred type of the subexpression. Examples:
294+We think we're trustworthy, but perhaps you don't want to take our word for it. What if you want to see the inferred type of `b` for yourself for each conditional branch? One way to do this is with a 'type spear'. But you need to understand the `!>` rune before using this mighty weapon of war. `!>` takes one subexpression and constructs a cell from it. The subexpression is evaluated and becomes the tail of the product cell, with a `q` face attached. The head of the product cell is the inferred type of the subexpression. Examples:
295295
296296```
297297> !>(15)
@@ -304,7 +304,9 @@ I think I'm a trustworthy guy, but perhaps you don't want to take my word for it
304304[#t/@ q=77]
305305```
306306
307−The `#t/` is just the pretty-printer's way of indicating a type. To get just the inferred type of a expression, we only want the head, `-`. So we can use the type spear, `-:!>`, to get just the type.
307+The `#t/` is just the pretty-printer's way of indicating a type.
308+
309+To get just the inferred type of a expression, we only want the head of the `!>` product, `-`. Thus we should use the type spear, `-:!>`.
308310
309311```
310312> -:!>(15)
@@ -331,7 +333,7 @@ Now let's try using `?=` with `?:` again. But this time we'll replace `[& b]` w
331333[%.n #t/{* *}]
332334```
333335
334−In both cases, `b` is defined initially as a generic noun, `*`. But when using `?:` with `?=(@ b)` as the test condition, `b` is inferred to be an atom, `@`, when the condition is true; otherwise `b` is inferred to be a cell, `^`.
336+In both cases, `b` is defined initially as a generic noun, `*`. But when using `?:` with `?=(@ b)` as the test condition, `b` is inferred to be an atom, `@`, when the condition is true; otherwise `b` is inferred to be a cell, `^` (identical to `{* *}`).
335337
336338##### `mint-vain`
337339
@@ -488,7 +490,7 @@ Once that new value for `c` is computed from the head of `a`, we're ready to che
488490
489491The 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.
490492
491−One way to compare noun fringes is to calculate the fringes of both first, then compare. 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.
493+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.
492494
493495Write a program named `samefringe.hoon` that solves the problem the 'better' way. A solution is given at the bottom of the lesson.
494496
@@ -505,11 +507,11 @@ Write a program named `samefringe.hoon` that solves the problem the 'better' way
505507
506508#### Lists
507509
508−We can put lists in two categories: (1) null lists, `~`, and (2) non-null lists. A null list is a list with no items in it. Naturally these aren't as interesting as non-null lists.
510+You learned about lists earlier in the chapter, but we left out a little bit of information about the way Hoon understands list types.
509511
510−A non-null list is a cell. If `b` is a non-null list then the head of `b` is the first item of `b` with an `i` face on it. The tail of `b` is the rest of the list. The 'rest of the list' is itself another list with a `t` face on it. Hoon lists are 'null-terminated', which means that the end of the list is signified with a `~` (a null list).
512+A non-null list is a cell. If `b` is a non-null list then the head of `b` is the first item of `b` _with an `i` face on it_. The tail of `b` is the rest of the list. The 'rest of the list' is itself another list _with a `t` face on it_. We can (and should) use these `i` and `t` faces in list functions.
511513
512−Let's say that `b` is the list of the atoms `11`, `22`, and `33`. Let's construct this in stages:
514+To illustrate: let's say that `b` is the list of the atoms `11`, `22`, and `33`. Let's construct this in stages:
513515
514516```
515517[i=11 t=[rest-of-list-b]]
@@ -519,7 +521,7 @@ Let's say that `b` is the list of the atoms `11`, `22`, and `33`. Let's constru
519521[i=11 t=[i=22 t=[i=33 t=~]]]
520522```
521523
522−There are lists of every type. Lists of `@ud`, `@ux`, `@` in general, `^`, `[^ [@ @]]`, etc. We can even have lists of lists of `@`, `^`, or `?`, etc.
524+(There are lists of every type. Lists of `@ud`, `@ux`, `@` in general, `^`, `[^ [@ @]]`, etc. We can even have lists of lists of `@`, `^`, or `?`, etc.)
523525
524526Here's a program that takes atoms `a` and `b` and returns a list of all atoms from `a` to `b`:
525527
@@ -546,7 +548,7 @@ Save this code as `gulf.hoon` in your urbit's pier and run it from the dojo:
546548~
547549```
548550
549−Where are all the `i`s and `t`s??? For the sake of neatness the Hoon pretty-printer doesn't show the `i` and `t` faces of lists, just the items. You'll also note that there is a `~` at the beginning of the cell. This is how the pretty-printer indicates that a cell is actually a list. `~[12 14]` is an irregular form of `[12 14 ~]`.
551+Where are all the `i`s and `t`s??? For the sake of neatness the Hoon pretty-printer doesn't show the `i` and `t` faces of lists, just the items.
550552
551553In fact, we could have left out the `i` and `t` faces in the program itself:
552554
@@ -599,7 +601,7 @@ Hoon will infer that `b` either is or isn't null based on which `?~` branch is e
599601
600602#### Using `?~` With Lists
601603
602−The `?~` is especially useful for working with lists. Here's a program using `?~` to calculate the number of items in a list of atoms:
604+The `?~` is especially useful for working with lists. Is a list null, or not? You probably want to do different things based on the answer to that question. Here's a program using `?~` to calculate the number of items in a list of atoms:
603605
604606```
605607|= a=(list @) :: 1
@@ -666,9 +668,9 @@ With insertion sort, you start with a full unsorted list, `(list @)`, and a seco
666668
667669So 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.
668670
669−In fact, there are several other ways that Hoon infers type. Any rune expressions that evaluates to a flag, `?`, e.g., `.=` will be inferred from accordingly. The `.+` rune always evaluates to an `@`, and Hoon knows that too. The cell constructor runes, `:-`, `:+`, `:^`, and `:*` are all known to produce cells.
671+In fact, there are several other ways that Hoon infers type. Any rune expression that evaluates to a flag, `?`, e.g., `.=`, will be inferred from accordingly. The `.+` rune always evaluates to an `@`, and Hoon knows that too. The cell constructor runes, `:-`, `:+`, `:^`, and `:*` are all known to produce cells.
670672
671−More subtly, the `=+`, `=/`, and `=|` modify the subject by pinning values to the head. Hoon infers from this that the subject has a new type: a cell whose head is the type of the pinned value and whose tail is the type of the (old) subject.
673+More subtly, the `=+`, `=/`, and `=|` runes modify the subject by pinning values to the head. Hoon infers from this that the subject has a new type: a cell whose head is the type of the pinned value and whose tail is the type of the (old) subject.
672674
673675In 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.
674676
docs/tutorials/hoon/hoon-ch2-6.udon+17−29
@@ -14,7 +14,7 @@ In this lesson we'll talk a little about how type expressions become structures,
1414
1515Attentive readers may remember that Hoon programs are made of expressions. By definition, an expression produces a value. We've talked about expressions for types such as `@`, `^`, `[? *]`, etc. What values do these subexpressions produce? The answer is that they produce a *structure*. But what are structures, and what role do they play in Hoon?
1616
17−You don't actually need to know much about what a structure is in order to write Hoon programs that use the type system effectively. Accordingly, we'll save the particular details for a later chapter. Here we'll give only a sketch of the most important features.
17+You don't actually need to know much about what a structure is in order to write Hoon programs that use the type system effectively. Accordingly, we'll save the particular details for a later lesson. Here we'll give only a sketch of the most important features.
1818
1919### Cast Expressions
2020
@@ -31,9 +31,9 @@ Structures play different roles in different code contexts. First, let's look a
3131[%.y [15 17]]
3232```
3333
34−The `@`, `^`, and `[? *]` subexpressions have no effect at all on the final value produced.
34+The `@`, `^`, and `[? *]` subexpressions have no effect on the overall value produced.
3535
36−It's important to understand that these casts don't affect the [runtime](https://en.wikipedia.org/wiki/Run_time_(program_lifecycle_phase%29) semantics of a program at all. They affect only the compiler behavior at compile time. The compiler does these type-checks when compiling, but the resulting code has no value corresponding to the types above.
36+It's important to understand that these casts don't affect the [runtime](https://en.wikipedia.org/wiki/Run_time_(program_lifecycle_phase%29) semantics of a program at all. They affect only the compiler behavior at compile-time. The compiler does these type-checks when compiling, but the resulting code has no value corresponding to the types above.
3737
3838Accordingly, the structures produced by the type subexpressions above aren't part of the program's runtime semantics. They are compile-time values only.
3939
@@ -41,14 +41,14 @@ Accordingly, the structures produced by the type subexpressions above aren't par
4141
4242In other cases, structures _can_ have an effect on runtime semantics. For example, consider the expression `|=(a=@ 15)`. This produces a gate that takes any atom as its sample and returns `15`.
4343
44−The `@` subexpression of `|=(a=@ 15)` produces a structure at compile time. In the compiled program this structure is converted to a default value for the appropriate type, sometimes called an *example* value (or a *bunt* value in older Hoon literature).
44+The `@` subexpression of `|=(a=@ 15)` produces a structure at compile time. In the compiled program this structure is converted to a default value for the appropriate type, sometimes called an *example* value (or a *bunt* value).
4545
4646```
4747> |=(a=@ 15)
4848< 1.xqz
4949 { a/@
5050 {our/@p now/@da eny/@uvJ}
51− <18.rrd 23.tfo 5.mxb 36.apb 119.xzz 238.eyc 51.txd 93.ape 74.dbd 1.qct $141>
51+ <19.arv 24.fmf 7.mpi 38.ard 119.spd 241.plj 51.zox 93.pqh 74.dbd 1.qct $141>
5252 }
5353>
5454
@@ -81,7 +81,7 @@ Structures can also become gates at runtime. To produce such a gate, use a type
8181< 1.goa
8282 { *
8383 {our/@p now/@da eny/@uvJ}
84− <18.rrd 23.tfo 5.mxb 36.apb 119.xzz 238.eyc 51.txd 93.ape 74.dbd 1.qct $141>
84+ <19.arv 24.fmf 7.mpi 38.ard 119.spd 241.plj 51.zox 93.pqh 74.dbd 1.qct $141>
8585 }
8686>
8787
@@ -89,7 +89,7 @@ Structures can also become gates at runtime. To produce such a gate, use a type
8989< 1.zgf
9090 { *
9191 {our/@p now/@da eny/@uvJ}
92− <18.rrd 23.tfo 5.mxb 36.apb 119.xzz 238.eyc 51.txd 93.ape 74.dbd 1.qct $141>
92+ <19.arv 24.fmf 7.mpi 38.ard 119.spd 241.plj 51.zox 93.pqh 74.dbd 1.qct $141>
9393 }
9494>
9595
@@ -97,12 +97,12 @@ Structures can also become gates at runtime. To produce such a gate, use a type
9797< 1.ylu
9898 { *
9999 {our/@p now/@da eny/@uvJ}
100− <18.rrd 23.tfo 5.mxb 36.apb 119.xzz 238.eyc 51.txd 93.ape 74.dbd 1.qct $141>
100+ <19.arv 24.fmf 7.mpi 38.ard 119.spd 241.plj 51.zox 93.pqh 74.dbd 1.qct $141>
101101 }
102102>
103103```
104104
105−In all three cases, the result of evaluation is a gate. For each, the head is a single arm, signified by `1.xxx`. The sample -- i.e., the head of the tail -- in each case is of the type `*`. These gates are called *molds*.
105+In all three cases, the result of evaluation is a gate. For each, the head is a single arm, signified by `1.xxx`. The sample -- i.e., the head of the tail -- in each case is of the type `*`. These gates are sometimes called *molds*.
106106
107107Molds are gates with two special properties: (1) they are guaranteed to produce a value of the type indicated by the type expression, and (2) they are [idempotent](https://en.wikipedia.org/wiki/Idempotence). (A gate `i` is idempotent if and only if the result of applying `i` multiple times to a value produces the same result as applying it once. In other words, `(i val)` must produce the same result as `(i (i val))`.)
108108
@@ -148,7 +148,7 @@ Let's review (1) and (2) briefly.
148148
149149The basic types of Hoon are: `*` for nouns, `@` for atoms (possibly with aura information, e.g., `@ud` and `@sx`), `^` for cells, `?` for flags, and `~` for null. You can also make constant, one-value types by using `%` followed by a series of lowercase letters, the hyphen symbol `-`, and numbers. E.g., `%red`, `%2`, `%kebab-case123`. The lone values of these one-value types are sometimes called 'tags'.
150150
151−Let's illustrate with the irregular `` ` ` `` cast syntax:
151+Let's illustrate with the irregular `\` \`` cast syntax:
152152
153153```
154154> `%blah`%blah
@@ -215,7 +215,7 @@ Here we can see the difference by noting how many molds each produces:
215215< 1.igg
216216 { *
217217 {our/@p now/@da eny/@uvJ}
218− <18.rrd 23.tfo 5.mxb 36.apb 119.xzz 238.eyc 51.txd 93.ape 74.dbd 1.qct $141>
218+ <19.arv 24.fmf 7.mpi 38.ard 119.spd 241.plj 51.zox 93.pqh 74.dbd 1.qct $141>
219219 }
220220>
221221
@@ -223,13 +223,13 @@ Here we can see the difference by noting how many molds each produces:
223223[ < 1.goa
224224 { *
225225 {our/@p now/@da eny/@uvJ}
226− <18.rrd 23.tfo 5.mxb 36.apb 119.xzz 238.eyc 51.txd 93.ape 74.dbd 1.qct $141>
226+ <19.arv 24.fmf 7.mpi 38.ard 119.spd 241.plj 51.zox 93.pqh 74.dbd 1.qct $141>
227227 }
228228 >
229229 < 1.zgf
230230 { *
231231 {our/@p now/@da eny/@uvJ}
232− <18.rrd 23.tfo 5.mxb 36.apb 119.xzz 238.eyc 51.txd 93.ape 74.dbd 1.qct $141>
232+ <19.arv 24.fmf 7.mpi 38.ard 119.spd 241.plj 51.zox 93.pqh 74.dbd 1.qct $141>
233233 }
234234 >
235235]
@@ -242,7 +242,7 @@ You can force `[@ ?]` to be interpreted as a single mold by prepending it with `
242242< 1.igg
243243 { *
244244 {our/@p now/@da eny/@uvJ}
245− <18.rrd 23.tfo 5.mxb 36.apb 119.xzz 238.eyc 51.txd 93.ape 74.dbd 1.qct $141>
245+ <19.arv 24.fmf 7.mpi 38.ard 119.spd 241.plj 51.zox 93.pqh 74.dbd 1.qct $141>
246246 }
247247>
248248```
@@ -262,22 +262,10 @@ nest-fail
262262nest-fail
263263
264264> `$-([@ @] @)`add
265−< 1|xpc
266− { {@ @}
267− {our/@p now/@da eny/@uvJ}
268− $~
269− <16.zwv 19.rrs 41.gam 112.cpm 224.nab 54.tyv 119.wim 31.ohr 1.jmk $143>
270− }
271−>
265+<1|efh {{@ @} {@ @} @}>
272266
273267> `$-([@ @] ?)`gte
274−< 1|uxz
275− { {@ @}
276− {our/@p now/@da eny/@uvJ}
277− $~
278− <16.zwv 19.rrs 41.gam 112.cpm 224.nab 54.tyv 119.wim 31.ohr 1.jmk $143>
279− }
280−>
268+<1|efh {{@ @} {@ @} ?($.n $.y)}>
281269```
282270
283271### `$?` Define a Union
@@ -367,4 +355,4 @@ Often `$@` is used to define a type with a null or trivial case for the `@` case
367355
368356Now the `~` value is included as a possible value for `user`.
369357
370−That's all we have to say about types in this chapter. More on types in Chapter 3!
358+That's all we have to say about types in this chapter. More on types in Chapter 3.
docs/tutorials/hoon/hoon-ch2-7.udon+18−13
@@ -30,7 +30,7 @@ The battery is a series of arms, each of which is intended to be evaluated with
3030
3131The 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'.
3232
33−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. A gates is a one-armed core with a sample. 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.
33+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.
3434
3535## Project Euler 1
3636
@@ -155,7 +155,7 @@ Let's write such a core and bind it to a face in the dojo. (Feel free to cut an
155155> t
156156< 3.axs
157157 { {our/@p now/@da eny/@uvJ}
158− <18.rrd 23.tfo 5.mxb 36.apb 119.xzz 238.eyc 51.txd 93.ape 74.dbd 1.qct $141>
158+ <19.min 24.fmf 7.mpi 38.ard 119.spd 241.plj 51.zox 93.pqh 74.dbd 1.qct $141>
159159 }
160160>
161161```
@@ -220,6 +220,12 @@ Let's try with other input types:
220220nest-fail
221221```
222222
223+Unbind `t` again:
224+
225+```
226+> =t
227+```
228+
223229## Cores with Samples (Doors)
224230
225231Cores 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*.
@@ -243,10 +249,14 @@ You can change the rounding rule by passing an argument to the `++ rs` core:
243249
244250```
245251> ~(add rs %u)
246−<1.dfv {{a/@rs b/@rs} <21.vij {r/?($n $u $d $z) <54.tyv 119.wim 31.ohr 1.jmk $143>}>}>
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+>
247255
248256> ~(add rs %d)
249−<1.dfv {{a/@rs b/@rs} <21.vij {r/?($n $u $d $z) <54.tyv 119.wim 31.ohr 1.jmk $143>}>}>
257+< 1.hsu
258+ {{a/@rs b/@rs} <21.fan {r/?($n $u $d $z) <51.zox 93.pqh 74.dbd 1.qct $141>}>}
259+>
250260```
251261
252262Each 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:
@@ -313,15 +323,10 @@ To use a door as a state machine, put the door in the subject and modify that do
313323 --
314324
315325> num
316−< 4.uzk
326+< 4.awp
317327 { a/@
318− { {rng/<4.wmp {a/@ud <54.tyv 119.wim 31.ohr 1.jmk $143>}> b/nlr(@) l/it(@)}
319− our/@p
320− now/@da
321− eny/@uvJ
322− }
323− $~
324− <16.cvy 19.rrs 41.gpy 112.lkm 224.nab 54.nhx 119.wim 31.ohr 1.jmk $143>
328+ {our/@p now/@da eny/@uvJ}
329+ <19.min 24.fmf 7.mpi 38.ard 119.spd 241.plj 51.zox 93.pqh 74.dbd 1.qct $141>
325330 }
326331>
327332
@@ -389,6 +394,6 @@ Now run it in the dojo:
3893941.002
390395```
391396
392−Each of the `=.` expressions 'modifies' `num` by replacing the old `num` core with a different version of it. In this program we're 'modifying' `num` four times.
397+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.
393398
394399For more on how to use cores as state machines see the next lesson.
docs/tutorials/hoon/hoon-ch2-8.udon+20−18
@@ -77,6 +77,8 @@ Now you can see the intermediate values of the sample of `a` for each modified v
7777
7878The `=^` 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`.
7979
80+This is particularly useful when you want to return data for the form `[result new-state]`.
81+
8082For 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.:
8183
8284```
@@ -99,7 +101,7 @@ You'll notice that the `plus` arm of the `num` core above evaluates to a gate.
99101 [(add a b) this(a (add a b))]
100102```
101103
102−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 for the desired output type. The desired output 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`?
104+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`?
103105
104106There 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`.
105107
@@ -151,7 +153,7 @@ Another way to cast for the type of the parent core of an arm is to use `_+>.$`.
151153
152154But what does it mean? First, the `_` indicates the irregular form of the `$_` rune. That is, `_+>.$` evaluates `+>.$` and produces a type from the resulting noun.
153155
154−What is `+>.$`? This is a wing of two limbs, `+>` and `$`. As you saw in [section 1.4](../../hoon-ch1/hoon-ch1-4), `+>` 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.
156+What is `+>.$`? This is a wing of two limbs, `+>` and `$`. As you saw in [section 1.4](../hoon-ch1-4), `+>` 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.
155157
156158Thus, `+>.$` evaluates to `+7` of the gate containing `$`. For our `plus` arm, the gate in question is the one defined by:
157159
@@ -194,13 +196,13 @@ To change the seed, we need to make a copy of `og` with a different sample. How
194196
195197```
196198> ~(. og 123)
197−<4.ihy {a/@ud <54.nhx 119.wim 31.ohr 1.jmk $143>}>
199+<4.rvc {a/@ud <51.zox 93.pqh 74.dbd 1.qct $141>}>
198200
199201> ~(. og 456)
200−<4.ihy {a/@ud <54.nhx 119.wim 31.ohr 1.jmk $143>}>
202+<4.rvc {a/@ud <51.zox 93.pqh 74.dbd 1.qct $141>}>
201203
202204> ~(. og 456.789)
203−<4.ihy {a/@ud <54.nhx 119.wim 31.ohr 1.jmk $143>}>
205+<4.rvc {a/@ud <51.zox 93.pqh 74.dbd 1.qct $141>}>
204206```
205207
206208The 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:
@@ -228,25 +230,25 @@ Part of the solution is to use the `rads` arm of `og` with the `=^` rune. The g
228230
229231```
230232> (rads:og 3)
231−[0 <4.wmp {a/@ <54.tyv 119.wim 31.ohr 1.jmk $143>}>]
233+[0 <4.rvc {a/@ <51.zox 93.pqh 74.dbd 1.qct $141>}>]
232234
233235> (rads:og 4)
234−[2 <4.wmp {a/@ <54.tyv 119.wim 31.ohr 1.jmk $143>}>]
236+[2 <4.rvc {a/@ <51.zox 93.pqh 74.dbd 1.qct $141>}>]
235237
236238> (rads:og 5)
237−[4 <4.wmp {a/@ <54.tyv 119.wim 31.ohr 1.jmk $143>}>]
239+[4 <4.rvc {a/@ <51.zox 93.pqh 74.dbd 1.qct $141>}>]
238240
239241> (rads:og 55)
240−[50 <4.wmp {a/@ <54.tyv 119.wim 31.ohr 1.jmk $143>}>]
242+[50 <4.rvc {a/@ <51.zox 93.pqh 74.dbd 1.qct $141>}>]
241243```
242244
243−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, the `++ og` arm in the Hoon standard library doesn't create a door until that arm is evaluated. If you try to mutate it before putting a copy of it in the subject, you'll run into problems.) Let's make a copy of the `og` door with its initial seed value as `123`:
245+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`:
244246
245247```
246248> =rng ~(. og 123)
247249
248250> rng
249−<4.ihy {a/@ud <54.nhx 119.wim 31.ohr 1.jmk $143>}>
251+<4.rvc {a/@ud <51.zox 93.pqh 74.dbd 1.qct $141>}>
250252
251253> +6:rng
252254a=123
@@ -268,14 +270,14 @@ For each random number generation, the `rng` core has a different seed number.
268270
269271```
270272> eny
271−\/0v2sq.hfljl.5shb8.5oin7.u7krj.21gmi.dnd6r.j3ufj.rd06o.522dk.1f2tn.2b8oh.65efn.i1kct.l\/
272− frsk.v0gpq.obh7j.48h0n.9caht.ihmgb.mu5b9
273−\/ \/
273+\/0v3en.c4udf.jg3op.njvu9.sdhp3.oq9vm.j5g93.2njmu.6bk6j.agjme.ef451.7icfo.134\/
274+ fv.i4dor.dv6ls.9m7ig.vb8m7.ir3mb.gt7vn.q57l6.sant1
275+\/ \/
274276
275277> eny
276−\/0v2q4.ek1s2.b5l01.6tjqs.esmsl.pi239.jn6gl.ghbem.bpo5g.a3i4i.gcn5l.6kts4.hirc8.fkpvf.3\/
277− ombq.n1eql.0scoe.85gva.59m3k.bff1h.3bdak
278−\/ \/
278+\/0v1hu.1i95m.infcn.a6sc2.47fph.idjoc.2jcd4.2hj3p.ma12d.jtphu.5585b.9t0ru.48q\/
279+ 61.3qmpl.gvn5b.evhl3.us653.kffap.vef21.kaavg.p5sl3
280+\/ \/
279281```
280282
281283`eny` is an environment value for [entropy](https://en.wikipedia.org/wiki/Entropy_(computing%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:
@@ -388,7 +390,7 @@ Save this as `deck.hoon` in the `/gen` directory of your urbit's pier and run in
388390]
389391```
390392
391−(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.)
393+(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'.)
392394
393395We 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.
394396
docs/tutorials/hoon/hoon-ch2-9.udon+1−1
@@ -158,7 +158,7 @@ Lines 11-14 do the same thing for the case in which `i.b` is a lowercase letter.
158158
159159Lists are a commonly used data structure. Accordingly, there are several functions in the Hoon standard library intended to make lists easier to use.
160160
161−For a complete list of these functions, check out the standard library reference for lists here (add link later). Here we'll look at a few of these functions.
161+For a complete list of these functions, check out the standard library reference for lists here (link). Here we'll look at a few of these functions.
162162
163163### `flop`
164164
docs/tutorials/hoon/hoon-ch3-1.udonnew file+674
@@ -0,0 +1,674 @@
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3+ sort/'38'
4+ title/'3.1 Type Polymorphism'
5+ ==
6+;>
7+
8+# Polymorphism
9+
10+There are many cases in which one may want to write a function that accepts as input various different types of data. Such a function is said to be [polymorphic](https://en.wikipedia.org/wiki/Polymorphism_(computer_science%29). ("Polymorphism" = "many forms"; so polymorphic functions accept many forms of data as input.)
11+
12+One relatively trivial form of polymorphism involves sub-typing. A gate whose sample is a raw `noun` can accept any Hoon data structure as input -- it's just that the sample will only be treated as a noun. For example, consider the `copy` gate below:
13+
14+```
15+> =copy |=(a=* [a a])
16+
17+> (copy 15)
18+[15 15]
19+
20+> (copy [15 16])
21+[[15 16] [15 16]]
22+
23+> (copy "Hello!")
24+[[72 101 108 108 111 33 0] [72 101 108 108 111 33 0]]
25+```
26+
27+`copy` takes the input, `a`, and returns a cell of `[a a]`. Because every piece of Hoon data is a noun, anything can be taken as input. Every other type in Hoon is a sub-type of `noun`. But the output of `copy` is always going to be just a cell of nouns; the type information of the original input value is not preserved by the gate. Consider the `tape` in the last example -- `"Hello!"` was pretty-printed in the dojo as a raw noun, not as a string. So `copy` is a relatively uninteresting polymorphic function.
28+
29+In this lesson we'll go over Hoon's support for more interesting polymorphic functions.
30+
31+## Polymorphic Properties of Cores
32+
33+Hoon supports type polymorphism at the core level. That is, each core has certain polymorphic properties that are tracked and maintained as metadata by Hoon's type system. (See `+$ type` of `hoon.hoon`.) These properties determine the extent to which a core can be used as an interface for values of various types.
34+
35+This is rather vaguely put so far. We can clarify by talking more specifically about the different kinds of polymorphism supported in Hoon. There are two kinds of type polymorphism for cores: [genericity](https://en.wikipedia.org/wiki/Generic_programming), to include certain kinds of of [parametric polymorphism](https://en.wikipedia.org/wiki/Parametric_polymorphism); and [variance polymorphism](https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science%29), which involves making use of special sub-typing rules for cores.
36+
37+If you don't understand these very well, that's okay. We'll explain them. Let's begin with the former.
38+
39+## Dry vs. Wet Cores
40+
41+To review briefly, a *core* is a pair of `[battery payload]`. The *battery* contains the various arms of the core (code), and the *payload* contains all the data needed to evaluate those arms correctly (data). Every arm is evaluated with its parent core as the subject. A *gate* (i.e., a Hoon function) is a core with exactly one arm named `$` and with a payload of the form: `[sample context]`. The *sample* is reserved for the function's argument value, and the *context* is any other data needed to evaluate `$` correctly.
42+
43+There are two kinds of cores: *dry* and *wet*. Dry cores, which are more typical, _don't_ make use of *genericity*. Wet cores do. In order to understand generic functions in Hoon, you first have to understand the difference between dry and wet cores.
44+
45+The cores produced with the `|=`, `|-`, `|%`, and `|_` runes, among others, are all dry. (Dry is more typical.) The cores produced with the `|*` and `|@` runes are wet. (`|*` and `|@` are the wet versions of `|=` and `|%`, respectively.)
46+
47+Briefly, the difference between dry and wet cores has to do with how they're treated at compile time, for type inference and type checking. During the type check, the product type of each arm is inferred. For computing a dry arm type, it's assumed that the arm's subject type is of the original parent core. For computing a wet arm type, the parent core type is used, except that the payload value may vary from the original type.
48+
49+Because of this difference, wet cores can be used to make functions that take different input types at different call sites. We'll go over the dry/wet distinction in more detail below and explain why it matters.
50+
51+### Dry Cores
52+
53+A core's payload can change its values swapped out for other values. How can we ensure that its arms are still able to run correctly?
54+
55+There is a type check for each arm of a dry core, intended to verify that the arm's parent core has a payload of the appropriate type. In this section we'll describe that type check.
56+
57+When an arm of a dry core is evaluated it takes its parent core as the subject, often with a modified sample _value_. But any change in sample _type_ should be conservative; the modified sample value must be of the same type as the default sample value (or possibly a subtype). When the `$` arm is evaluated it should have a subject of a type it knows how to use.
58+
59+For example, consider the gate created by `add`, a function in the Hoon standard library. The structure of the `add` gate is as follows:
60+
61+```
62+ add
63+ / \
64+ $ .
65+ / \
66+ sample context
67+```
68+
69+The `add` code depends on the fact that there are two atoms in the sample: the numbers to be added together. Hence, it is appropriate that only a cell of atoms is permitted for the sample. We can look at the default sample of `add` at address `+6`:
70+
71+```
72+> +6:add
73+[a=0 b=0]
74+```
75+
76+If we call `add` with no arguments, we get the sum of these two values:
77+
78+```
79+> (add)
80+0
81+```
82+
83+Any other type of value in the sample results in a `nest-fail` crash:
84+
85+```
86+> (add 12 "hello")
87+nest-fail
88+```
89+
90+This function call attempts to create a modified copy of the `add` gate, replacing the original sample `[0 0]` with `[12 "hello"]`, then evaluate the `$` arm of this modified core. (We ignore the `a` and `b` faces for now.) But this piece of code failed to compile; the type system knew to reject it.
91+
92+How does it know? The type system keeps track of two payload types for each core:
93+
94++ The original payload type, i.e., the type of the payload when the core was first created. In the case of `add`, the original sample type is a cell of atoms, `[@ @]`. This original type information is always preserved, regardless of what value type is used for calling `add`.
95++ The current payload type, i.e., the type of the payload after any substitutions or other changes have been made. In the last `add` call, `(add 12 "hello")`, this would have been a cell whose head is an `@ud`, and whose tail is a `tape`.
96+
97+The type check at compile time compares these two types, and if the current payload type doesn't nest under the original payload, the compile fails with a `nest-fail` crash. (E.g., a cell of type `[@ud tape]` doesn't nest under `[@ @]`!) Otherwise, the original payload _type_ is used for evaluation, even though the original sample _value_ has been replaced. So the arm of a dry core is guaranteed to run with exactly the same subject type each time it is evaluated.
98+
99+The type check for each arm in a dry core can be understood as implementing a version of the ["Liskov substitution principle"](https://en.wikipedia.org/wiki/Liskov_substitution_principle). The arm works for some (originally defined) payload type `P`. Payload type `Q` nests under `P`. Therefore the arm works for `Q` as well, though for type inference purposes the payload is treated as a `P`. The inferred type of the arm is based on the assumption that it's evaluated with a subject type exactly like that of its original parent core -- i.e., whose payload is of type `P`.
100+
101+### Wet Cores (Genericity)
102+
103+The type checking and inference rules for arms are a bit different for wet cores. Whereas the dry arm is understood as having _exactly_ its parent core type for its subject, wet arms can be evaluated with payloads of various types.
104+
105+When a function call occurs on a wet arm, the [call site](https://en.wikipedia.org/wiki/Call_site) argument value type is used as the sample type -- not the original parent core sample type. Correspondingly, the inferred type of a wet arm depends, among other things, on the type of the argument value -- i.e., the modified sample value type of the core, not the original. Thus, the inferred product type typically varies from one call site to another.
106+
107+The arms of wet cores must be able to handle subjects of various types -- they are interestingly polymorphic in a way that dry cores cannot be. The Hoon code that defines each wet arm must be [generic](https://en.wikipedia.org/wiki/Generic_programming) with respect to the sample type.
108+
109+An example will clarify how wet gates work. Recall the `copy` gate from earlier in the lesson:
110+
111+```
112+> =copy |=(a=* [a a])
113+
114+> (copy 15)
115+[15 15]
116+
117+> (copy [15 16])
118+[[15 16] [15 16]]
119+
120+> (copy "Hello!")
121+[[72 101 108 108 111 33 0] [72 101 108 108 111 33 0]]
122+```
123+
124+This gate is dry (as are all cores produced with `|=`), and so the inferred type of the product is determined based on the original core sample type. In this case, that's a raw noun, `*`. The dojo pretty-printer therefore has no way of knowing that the product of the last `copy` call should be printed as a pair of `tape`s -- it just sees a pair of nouns. If we want the original type information preserved, we must use a wet gate, which can be produced with `|*`:
125+
126+```
127+> =wet-copy |*(a=* [a a])
128+
129+> (wet-copy 15)
130+[15 15]
131+
132+> (wet-copy [15 16])
133+[[15 16] 15 16]
134+
135+> (wet-copy "Hello!")
136+["Hello!" "Hello!"]
137+```
138+
139+We see that the type information about the `tape` literal `"Hello!"` is preserved in the last function call, as desired. The original sample value of `wet-copy` is replaced with `"Hello!"`, and the original sample type is ignored in favor of the new sample type, `tape`. So the inferred arm type is a cell of `tape`s, which the dojo pretty-printer handles appropriately.
140+
141+In fact, `wet-copy` can take a Hoon value of any type you like!
142+
143+For another example, consider the following gate that switches the order of the head and tail of a cell:
144+
145+```
146+> =switch |*([a=* b=*] [b a])
147+
148+> (switch 2 3)
149+[3 2]
150+
151+> (switch "Hello" [11 22 33])
152+[[11 22 33] "Hello"]
153+
154+> (switch 0xbeef 0b1101)
155+[0b1101 0xbeef]
156+```
157+
158+Not only does `switch` reverse the order of the values, it also reverses their respective types, as desired. The dry version of switch is not as useful:
159+
160+```
161+> =dry-switch |=([a=* b=*] [b a])
162+
163+> (dry-switch "Hello" [11 22 33])
164+[[11 22 33] [72 101 108 108 111 0]]
165+
166+> (dry-switch 0xbeef 0b1101)
167+[13 48.879]
168+```
169+
170+Even though both `switch` and `dry-switch` are polymorphic in the sense that each can operate on any pair of nouns, the former does so in a way that makes use of the argument value types.
171+
172+But `switch` can't take just any input:
173+
174+```
175+> (switch 11)
176+-find.b
177+```
178+
179+It must take a cell, not an atom. So it's certainly possible to write a wet gate that doesn't take all possible input types.
180+
181+It is good practice to include a cast with all gates, even wet gates. But in many cases the desired output type depends on the input type. How can we cast appropriately? Often we can cast by example, using the input values themselves. For example, we can rewrite `switch` as:
182+
183+```
184+> =switch |*([a=* b=*] ^+([b a] [b a]))
185+
186+> (switch "Hello" 0xbeef)
187+[0xbeef "Hello"]
188+```
189+
190+As is the case with dry arms, there is a type-check associated with each wet arm. Or, rather, there are potentially many checks for each wet arm, one for each wing in the code that resolves to a wet arm. The product type of that arm is inferred at each call site, using the argument value type given at that site. If the type inference doesn't go through -- e.g., if there is a cast that doesn't succeed relative to the call site argument value -- then the compile will crash with a `nest-fail`. Otherwise the type check goes through with the inferred type of the wet arm at that call site. So the product type of a wet gate can differ from one call site to another, as we saw with `switch` above.
191+
192+### Parametric Polymorphism and `+*` Arms
193+
194+In Chapter 2 we saw how to use the `+*` rune to define an arm that produced a more complex type from one or more simpler types. This rune provides a way of making use of *parametric polymorphism* in Hoon.
195+
196+For example, we have `list`s, `tree`s, and `set`s in Hoon, which are each defined in `hoon.hoon` with `+*` arms. (Take a moment to see for yourself!) Each `+*` arm is followed by an argument definition, surrounded in square brackets `[ ]`. After that subexpression comes another that defines a type, relative to the input value. For example, here is the definition of `list` from `hoon.hoon`:
197+
198+```
199++* list [item]
200+ :: null-terminated list
201+ ::
202+ :: mold generator: produces a mold of a null-terminated list of the
203+ :: homogeneous type {a}.
204+ ::
205+ $@(~ [i=item t=(list item)])
206+```
207+
208+The `+*` rune is especially useful for defining [containers](https://en.wikipedia.org/wiki/Container_(abstract_data_type%29) of various kinds. A container is a kind of data structure for a collection of values of one or more given types. Indeed, `list`s, `tree`s, and `set`s are all examples of containers. You can have a `(list @)`, a `(list ^)`, a `(list *)`, and so on. Or a `(tree @)`, a `(tree ^)`, a `(tree *)`, etc. And the same for `set`.
209+
210+One nice thing about containers defined by `+*` is that they nest in the expected way. Intuitively a `(list @)` should nest under `(list *)`, because `@` nests under `*`. And so it does:
211+
212+```
213+> =a `(list @)`~[11 22 33]
214+
215+> ^-((list *) a)
216+~[11 22 33]
217+```
218+
219+Conversely, a `(list *)` should not nest under `(list @)`, because `*` does not nest under `@`:
220+
221+```
222+> =b `(list *)`~[11 22 33]
223+
224+> ^-((list @) b)
225+nest-fail
226+```
227+
228+Let's clear the dojo subject by unbinding the faces we've used up to now in the lesson:
229+
230+```
231+=a
232+
233+=b
234+
235+=copy
236+
237+=wet-copy
238+
239+=switch
240+
241+=dry-switch
242+```
243+
244+## Core Variance
245+
246+Let's say you want to write a function that takes a gate as one (or more) of its arguments. It's not hard to imagine useful cases of this. Consider `turn` from the Hoon standard library, which applies an arbitrary function to each item in a list and returns a modified list:
247+
248+```
249+> =b `(list @)`~[2 3 4 5]
250+
251+> (turn b |=(a=@ +(a)))
252+~[3 4 5 6]
253+
254+> (turn b |=(a=@ (mul 2 a)))
255+~[4 6 8 10]
256+
257+=b
258+```
259+
260+It's quite useful to be able to pass cores as arguments. But let's think about how to write a function that accepts a core as input. How do we define a sample so that it accepts a core?
261+
262+We _could_ define the sample by example -- i.e., with `$_`, or `_` for short -- using a core. Consider the following:
263+
264+```
265+> =mycore =>([12 13] |=(a=@ +(a)))
266+
267+> =apply |=([a=@ b=_mycore] (b a))
268+
269+> (apply 15 mycore)
270+16
271+
272+> (apply 15 =>([12 13] |=(a=@ +(+(a)))))
273+17
274+
275+> (apply 15 =>([12 13] |=(a=@ 123)))
276+123
277+```
278+
279+This works, but in fact `apply` is a very brittle function. It can only take as input a core whose payload is exactly like, or a subtype of, the payload of `mycore`:
280+
281+```
282+> (apply 15 |=(a=@ (mul 2 a)))
283+nest-fail
284+```
285+
286+A core created in one place of your code isn't likely to have the same payload as a core produced elsewhere, unless you intentionally define it so that it does. This often isn't practical, so we need another way to indicate that we want a core as input.
287+
288+Why did the last example crash? To understand this, you need to understand the the different variance properties a core can have. These properties determine the nesting and type inference rules associated with that core.
289+
290+The basic question to be answered is: when does one core type nest under another?
291+
292+The battery nesting rules for dry cores are relatively straightforward, and they're the same for all cores, regardless of variance properties. Let `A` and `B` be two cores. The type of `B` nests under the type of `A` only if two conditions are met: (i) the batteries of `A` and `B` have exactly the same tree shape, and (ii) the product type of each `B` arm nests under the product type of the corresponding `A` arm.
293+
294+The payload types of `A` and `B` must also be checked. Certain payload nesting rules apply to all cores, if `B` is to nest under `A`: (i) if `A` is dry (wet) then `B` must also be dry (wet); (ii) the original payload type of `A` must mutually nest with the current payload type of `A` (i.e., these types nest under each other); and (iii) the current payload type of `B` must nest under the original payload type of `B`.
295+
296+### The Four Kinds of Cores: Gold, Iron, Zinc, and Lead
297+
298+But there are different sets of nesting rules for finishing the payload type check, depending on the variance properties of the core.
299+
300+There are four kinds of core variance properties: *gold* (invariant sample), *iron* (contravariant sample), *zinc* (covariant sample), and *lead* (bivariant sample). These properties are tracked by the Hoon type system.
301+
302+In brief:
303+
304++ If `A` is a gold core, then core `B` nests under it only if `B` is gold and the sample of `B` doesn't vary in type from the sample of `A`. The sample `B` is *invariant* (i.e., neither co- nor contravariant) relative to the sample of an `A` it nests under. Gold cores have a read-write payload.
305++ If `A` is an iron core, then core `B` nests under it only if `B` is gold or iron and the sample of `A` nests under the sample of `B`. Notice that the nesting direction of the samples is the opposite of the nesting direction of the cores. I.e., the sample types *contravary* with respect to the iron core types. Iron cores have a write-only sample and an opaque context (neither read nor write).
306++ If `A` is a zinc core, then core `B` nests under it only if `B` is gold or zinc and the sample of `B` nests under the sample of `A`. Notice that the nesting direction of the samples is the same as the nesting direction of the cores. I.e., the sample types *co-vary* with respect to the zinc core types. Zinc cores have a read-only sample and an opaque context.
307++ If `A` is a lead core, then core `B` nests under it without any additional payload check beyond those described in the previous section. It trivially follows that the payload type both co- and contravaries with respect to the lead core types (hence lead cores are *bivariant*). Lead cores have an opaque payload.
308+
309+Let's go through each kind more carefully.
310+
311+#### Gold Cores (Invariant)
312+
313+By default, most cores are gold. This includes the cores produced with the `|%`, `|=`, `|_`, and `|-` runes, among others.
314+
315+Assume that `A` is a gold core and that `B` is some other core. The type of `B` nests under the type of `A` only if the original payload types of each mutually nest -- i.e., the original payload type of `A` nests under the original payload type of `B`, and _vice versa_. Furthermore, only gold cores nest under other gold cores; so `B` must be gold to nest under `A`.
316+
317+These payload nesting rules are the strictest ones for cores. The payload type is neither covariant nor contravariant; when type-checking against a gold core, the target payload cannot vary at all in type. Consequently, it is type-safe to modify every part of the payload: gold cores have a read-write payload.
318+
319+Usually it makes sense to cast for a gold core type when you're treating a core as a state machine. The check ensures that the payload, which includes the relevant state, doesn't vary in type. To see state machines that involve casts for gold cores, see Chapter 2 of the Hoon tutorial.
320+
321+Let's look at simpler examples here, using the `^+` rune:
322+
323+```
324+> ^+(|=(^ 15) |=(^ 16))
325+< 1.xqz
326+ { {* *}
327+ {our/@p now/@da eny/@uvJ}
328+ <19.rga 23.byz 5.rja 36.apb 119.ikf 238.utu 51.mcd 93.glm 74.dbd 1.qct $141>
329+ }
330+>
331+
332+> ^+(|=(^ 15) |=([@ @] 16))
333+nest-fail
334+
335+> ^+(|=(^ 15) |=(* 16))
336+nest-fail
337+```
338+
339+The first cast goes through because the right-hand gold core has the same sample type as the left-hand gold core. The sample types mutually nest. The second cast fails because the right-hand sample type is more specific than the left-hand sample type. (Not all cells, `^`, are pairs of atoms, `[@ @]`.) And the third cast fails because the right-hand sample type is broader than the left-hand sample type. (Not all nouns, `*`, are cells, `^`.)
340+
341+Two more examples:
342+
343+```
344+> ^+(=>([1 2] |=(@ 15)) =>([123 456] |=(@ 16)))
345+<1.xqz {@ @ud @ud}>
346+
347+> ^+(=>([1 2] |=(@ 15)) =>([123 456 789] |=(@ 16)))
348+nest-fail
349+```
350+
351+In these examples, the `=>` rune is used to give each core a simple context. The context of the left-hand core in each case is a pair of atoms, `[@ @]`. The first cast goes through because the right-hand core also has a pair of atoms as its context. The second cast fails because the right-hand core has the wrong type of context -- three atoms, `[@ @ @]`.
352+
353+#### Iron Cores (Contravariant)
354+
355+Assume that `A` is an iron core and `B` is some other core. The type of `B` nests under the type of `A` only if the original sample type of `A` nests under the original sample type of `B`. That is, `B`'s sample type must be equivalent or more general than the sample type of `A`. Furthermore, `B` must be either iron or gold to nest under `A`.
356+
357+The context type of `B` isn't checked at all; and because of the nesting rules it isn't type-safe to do type-inference on the sample of an iron gate. Thus, there are certain restrictions on iron cores that preserve type safety: (i) the context of an iron core is opaque, meaning that it cannot be written-to or read-from; and (ii) the iron core payload is write-only.
358+
359+Iron gates are particularly useful when you want to pass gates (having various payload types) to other gates. We can illustrate this use with a very simple example. Save the following as `gatepass.hoon` in the `gen` directory of your urbit's pier:
360+
361+```
362+|= a=_^|(|=(@ 15))
363+^- @
364+=/ b=@ (a 10)
365+(add b 20)
366+```
367+
368+This generator is mostly very simple. Everything about it should be clear except possibly the first line.
369+
370+The first line defines the gate sample as an iron gate and gives it the face `a`. So the function as a whole is for taking some gate, calling it by passing it the value `10`, adding `20` to it, and returning the result. Let's try it out in the dojo:
371+
372+```
373+> +gatepass |=(a=@ +(a))
374+31
375+
376+> +gatepass |=(a=@ (add 3 a))
377+33
378+
379+> +gatepass |=(a=@ (mul 3 a))
380+50
381+```
382+
383+But we still haven't fully explained the first line of the code. In particular, what does `_^|(|=(@ 15))` mean? The inside portion is clear enough -- `|=(@ 15)` produces a normal (i.e., gold) gate that takes an atom and returns `15`. The `^|` rune is used to turn gold gates to iron. (Reverse alchemy!) And the `_` character turns that iron gate value into a structure, i.e. a type. So the whole subexpression means, roughly: "the same type as an iron gate whose sample is an atom, `@`, and whose product is another atom, `@`". The context isn't checked at all. This is good, because that allows us to accept gates defined in drastically different environments. Let's try passing a gate with a different context:
384+
385+```
386+> +gatepass =>([22 33] |=(a=@ +(a)))
387+31
388+```
389+
390+Yup, it still works. You can't do that with a gold core sample!
391+
392+There's a simpler way to define an iron sample. Revise the first line of `gatepass.hoon` to the following:
393+
394+```
395+|= a=$-(@ @)
396+^- @
397+=/ b=@ (a 10)
398+(add b 20)
399+```
400+
401+If you test it you'll find that the generator behaves the same as it did before the edits. The `$-` rune is used to create an iron gate structure, i.e., an iron gate type. The first expression defines the sample type of the iron gate, and the second subexpression defines the gate output type.
402+
403+The sample type of an iron gate is contravariant. This means that, when doing a cast with some iron gate, the desired gate must have either the same sample type or a superset.
404+
405+Why is this a useful nesting rule for passing gates?
406+
407+Let's say you're writing a function `F` that takes as input some gate `G`. Let's also say you want `G` to be able to take as input any *mammal*. That's because the code of `F` is going to pass arbitrary *mammals* to `G`, so that `G` needs to know how to handle all *mammals* correctly. You can't pass `F` a gate that only takes *dogs* as input, because `F` might call it with a *cat*. But `F` can accept a gate that takes all *animals* as input, because a gate that can handle any *animal* can handle *any mammal*.
408+
409+Iron cores are designed precisely with this purpose in mind. The reason that the sample is write-only is that we want to be able to assume, within function `F`, that the sample of `G` is a *mammal*. But that might not be true when `G` is first passed into `F` -- the default value of `G` could be another *animal*, say, a *lizard*. So we restrict looking into the sample of `G` by making the sample write-only. The illusion is maintained and type safety secured.
410+
411+Let's illustrate iron core nesting properties:
412+
413+```
414+> ^+(^|(|=(^ 15)) |=(^ 16))
415+< 1|xqz
416+ { {* *}
417+ {our/@p now/@da eny/@uvJ}
418+ <19.rga 23.byz 5.rja 36.apb 119.ikf 238.utu 51.mcd 93.glm 74.dbd 1.qct $141>
419+ }
420+>
421+
422+> ^+(^|(|=(^ 15)) |=([@ @] 16))
423+nest-fail
424+
425+ ^+(^|(|=(^ 15)) |=(* 16))
426+< 1|xqz
427+ { {* *}
428+ {our/@p now/@da eny/@uvJ}
429+ <19.rga 23.byz 5.rja 36.apb 119.ikf 238.utu 51.mcd 93.glm 74.dbd 1.qct $141>
430+ }
431+>
432+```
433+
434+(As before, we use the `^|` rune to turn gold gates iron.)
435+
436+The first cast goes through because the two gates have the same sample type. The second cast fails because the right-hand gate has a more specific sample type than the left-hand gate does. If you're casting for a gate that accepts any cell, `^`, it's because we want to be able to pass any cell to it. A gate that is only designed for pairs of atoms, `[@ @]`, can't handle all such cases, naturally. The third cast goes through because the right-hand gate sample type is broader than the left-hand gate sample type. A gate that can take any noun as its sample, `*`, works just fine if we choose only to pass it cells, `^`.
437+
438+We mentioned previously that an iron core has a write-only sample and an opaque core. Let's prove it.
439+
440+Let's define a trivial gate with a context of `[g=22 h=44 .]`, convert it to iron with `^|`, and bind it to `iron-gate` in the dojo:
441+
442+```
443+> =iron-gate ^| =>([g=22 h=44 .] |=(a=@ (add a g)))
444+
445+> (iron-gate 10)
446+32
447+
448+> (iron-gate 11)
449+33
450+```
451+
452+Not a complicated function, but it serves our purposes. Normally (i.e., with gold cores) we can look at a context value `p` of some gate `q` with a wing expression: `p.q`. Not so with the iron gate:
453+
454+```
455+> g.iron-gate
456+-find.g.iron-gate
457+```
458+
459+And usually we can look at the sample value using the face given in the gate definition. Not in this case:
460+
461+```
462+> a.iron-gate
463+-find.a.iron-gate
464+```
465+
466+If you really want to look at the sample you can check `+6` of `iron-gate`:
467+
468+```
469+> +6.iron-gate
470+0
471+```
472+
473+...and if you really want to look at the head of the context (i.e., where `g` is located, `+14`) you can:
474+
475+```
476+> +14.iron-gate
477+22
478+```
479+
480+...but in both cases all the relevant type information has been thrown away:
481+
482+```
483+> -:!>(+6.iron-gate)
484+#t/*
485+
486+> -:!>(+14.iron-gate)
487+#t/*
488+```
489+
490+Let's clear up the dojo subject by unbinding `iron-gate`:
491+
492+```
493+=iron-gate
494+```
495+
496+#### Zinc Cores (Covariant)
497+
498+Zinc cores are like 'inverted' versions of iron cores.
499+
500+Assume that `A` is a zinc core and `B` is some other core. The type of `B` nests under the type of `A` only if the original sample type of `B` nests under the original sample type of `A`. That is, the target core sample type must be equivalent or a subset of the cast core sample type. Furthermore, `B` must be either zinc or gold to nest under `A`.
501+
502+As with iron cores, the context of zinc cores is opaque -- they cannot be written-to or read-from. The sample of a zinc core is read-only. That means, among other things, that zinc cores cannot be used for function calls. Function calls in Hoon involve a change to the sample (the sample is replaced with the argument value), which is disallowed as type-unsafe for zinc cores. (Note: due to a bug this isn't yet enforced properly.)
503+
504+We can illustrate the casting properties of zinc cores with a few examples. The `^&` rune is used to convert gold cores to zinc:
505+
506+```
507+> ^+(^&(|=(^ 15)) |=(^ 16))
508+< 1&xqz
509+ { {* *}
510+ {our/@p now/@da eny/@uvJ}
511+ <19.rga 23.byz 5.rja 36.apb 119.ikf 238.utu 51.mcd 93.glm 74.dbd 1.qct $141>
512+ }
513+>
514+
515+> ^+(^&(|=(^ 15)) |=([@ @] 16))
516+< 1&xqz
517+ { {* *}
518+ {our/@p now/@da eny/@uvJ}
519+ <19.rga 23.byz 5.rja 36.apb 119.ikf 238.utu 51.mcd 93.glm 74.dbd 1.qct $141>
520+ }
521+>
522+
523+> ^+(^&(|=(^ 15)) |=(* 16))
524+nest-fail
525+```
526+
527+The first two casts succeed because the right-hand core sample type is either the same or more specific than the laft-hand core sample type. The last one fails because the right-hand sample type is a superset.
528+
529+The arms of a zinc core can be computed, and the sample can be read. Let's test this with a zinc gate of our own:
530+
531+```
532+> =zinc-gate ^& |=(a=_22 (add 10 a))
533+
534+> a.zinc-gate
535+22
536+
537+> $.zinc-gate
538+32
539+```
540+
541+Zinc cores are not as widely used as gold or even iron cores. But they do have one plausible use. Imagine a core that serves effectively as an object, roughly in the object-oriented sense. The arms are methods and 'attributes' are kept as state, somewhere in the sample. We might imagine there being a class of such objects, defined as a type of core with an appropriate identifier in the sample somewhere. It may be that one class of objects is to be understood as a subclass of another. We can enforce this relationship with the nesting rules of zinc cores.
542+
543+An example will clarify. Let's define `animal` and `mammal` as types.
544+
545+```
546+> =mammal ?(%cow %dog %cat)
547+
548+> =animal ?(mammal %lizard %chicken)
549+```
550+
551+These aren't quite comprehensive, but are enough to illustrate cores as objects with classes. Let's test them with casts, to make sure they nest in the expected way:
552+
553+```
554+> `animal`%cow
555+%cow
556+
557+> `mammal`%cow
558+%cow
559+
560+> `animal`%lizard
561+%lizard
562+
563+> `mammal`%lizard
564+nest-fail
565+```
566+
567+Good. Now let's define a `%cow` named `bess` as a zinc core. We'll write `bess` so that she can gain weight by eating food:
568+
569+```
570+> =bess ^& |_ [species=%cow weight=_100]
571+ ++ this .
572+ ++ eat |=(food=@ this(weight (add food weight)))
573+ --
574+
575+> species.bess
576+%cow
577+
578+> weight.bess
579+100
580+
581+> =bess (eat.bess 20)
582+
583+> weight.bess
584+120
585+```
586+
587+Note that zinc cores can 'modify' themselves! (I.e., make a modified version of themselves, strictly speaking.) Nothing keeps you from treating a zinc core as a state machine. Only arms inside the zinc core can make modifications, however.
588+
589+Let's now define a `%lizard` named `leo` with the same eating function:
590+
591+```
592+> =leo ^& |_ [species=%lizard weight=_20]
593+ ++ this .
594+ ++ eat |=(food=@ this(weight (add food weight)))
595+ --
596+
597+> species.leo
598+%lizard
599+
600+> weight.leo
601+20
602+
603+> =leo (eat.leo 7)
604+
605+> weight.leo
606+27
607+```
608+
609+Good. Now let's write a function that only accepts *mammals* as input, and then which gives what the new *mammal* `weight` would be if fed `15`. First we define an 'object class' by example, i.e. a zinc core named `mammal-core` that can serve as a prototype *mammal*:
610+
611+```
612+> =mammal-core ^& |_ [species=mammal weight=@]
613+ ++ this .
614+ ++ eat |=(food=@ this(weight (add food weight)))
615+ --
616+
617+> =mammal-feed |=(a=_mammal-core (add 15 weight.a))
618+
619+> (mammal-feed bess)
620+135
621+
622+> (mammal-feed leo)
623+nest-fail
624+```
625+
626+(Note: the last example won't actually `nest-fail` in your dojo. This is a bug, however, and it will be corrected soon.)
627+
628+So you see that zinc cores can be used as prototypes of core classes, analogous to object classes in object-oriented languages.
629+
630+Let's clear up the dojo subject again:
631+
632+```
633+> =zinc-gate
634+
635+> =mammal-feed
636+
637+> =mammal-core
638+
639+> =leo
640+
641+> =bess
642+
643+> =mammal
644+
645+> =animal
646+```
647+
648+#### Lead Cores (Bivariant)
649+
650+Lead cores have more permissive nesting rules than either iron or zinc cores. There is no restriction on which payload types nest. That means, among other things, that the payload type of a lead core is both covariant and contravariant ('bivariant').
651+
652+In order to preserve type safety when working with lead cores, a severe restriction is needed. The whole payload of a lead core is opaque -- the payload can neither be written-to or read-from. For this reason, as was the case with zinc cores, lead cores cannot be called as functions. (Note: because of a type system bug, this is a lie. You can do function calls on lead gates right now. But it's bad for your soul and you shouldn't do it. I'll get that bug soon!)
653+
654+The arms of a lead core can still be evaluated, however. We can use the `^?` rune to convert a gold, iron, or zinc core to lead:
655+
656+```
657+> =lead-gate ^? |=(a=_22 (add 10 a))
658+
659+> $.lead-gate
660+32
661+```
662+
663+But don't try to read the sample:
664+
665+```
666+> a.lead-gate
667+-find.a.lead-gate
668+```
669+
670+Once more let's clear up the dojo subject:
671+
672+```
673+=lead-gate
674+```