on master help sign in
Merge pull request #1093 from urbit/zaptis-hoon-school

hoon school - doors are cores with samples

commit00c0d79ab43026b8b44991c330fb0a21b90f6b10 authorDavid Kerschner <david@tlon.io> dateThu 10 Jun 2021, 10:46 (5 years ago) parente1898785e131be
2 files changed+46−2
hoon/hoon-school/doors.md+41−2 hoon/hoon-school/lists.md+5
hoon/hoon-school/doors.md+41−2
@@ -226,7 +226,7 @@ It follows from this definition that a gate is a special case of a door. A gate
226226
227227Gates are useful for defining functions. But there are many-armed doors as well. How are they used? Doors are quite useful data structures. In Chapter 2 of the Hoon tutorial series you'll learn how to use doors to implement state machines, where the sample stores the relevant state data. For now let's talk about how to use doors for simpler purposes.
228228
229−### An Example Door
229+### An Example Door {#example}
230230
231231Let's write an example door in order to illustrate its features. Each of the arms in the door will define a simple gate. Let's bind the door to `c` as we did with the last core. To make a door we use the `|_` rune:
232232
@@ -248,9 +248,48 @@ The `|_` rune for making a door works exactly like the `|%` rune for making a co
248248
249249The first subexpression after the `|_` rune defines the door's sample. (This is the subexpression the `|%` rune lacks.) Following that are a series of `++` runes, each of which defines an arm of the door. Finally, the expression is terminated with a `--` rune.
250250
251+We emphasize that a door really is, at bedrock level, the same thing as a core
252+with a sample. Let's ask dojo to pretty print a simple door.
253+
254+```
255+> =a => ~ |_ b=@ ++ foo b --
256+> a
257+<1.zgd [b=@ %~]>
258+```
259+
260+Dojo tells us that `a` is a core with one arm and a payload of `[b=@ %~]`. Since
261+a door's payload is `[sample context]`, this means that `b` is the sample and
262+the context is null. Setting the context is what the `=> ~` did. The reason we
263+did this was to avoid including the standard library that is included in the
264+context by default in dojo, which would have made the pretty printed core much
265+more verbose.
266+
267+Now let's try to define a core with a sample:
268+
269+```
270+> =a => ~ =| b=@ |% ++ foo b --
271+> a
272+<1.zgd [b=@ %~]>
273+```
274+
275+Dojo gives us the same result! But is the pretty printer hiding something from
276+us? Recall that Hoon compiles down to Nock, Urbit's purely-functional
277+assembly-level language. The `!=` rune returns the Nock of any Hoon expression.
278+Let's try it on these expressions:
279+
280+```
281+> != => ~ |_ b=@ ++ foo b --
282+[7 [1 0] 8 [1 0] [1 0 6] 0 1]
283+> != => ~ =| b=@ |% ++ foo b --
284+[7 [1 0] 8 [1 0] [1 0 6] 0 1]
285+```
286+
287+You don't need to know any Nock to see that these two expressions are identical.
288+Thus we have witnessed that doors really are just cores with samples.
289+
251290#### Back to the Example
252291
253−For the door defined above, `c`, the sample is defined as an [atom](/docs/glossary/atom/), `@`, and given the face `b`. The `plus` arm defines a gate that takes a single [atom](/docs/glossary/atom/) as its argument, `a`, and which returns the sum of `a` and `b`. The `times` arm defines a gate that takes a single [atom](/docs/glossary/atom/), `a`, and returns `a` times `b`. The `greater` arm defines a gate that takes a single [atom](/docs/glossary/atom/), `a`, and if `a` is greater than `b` returns `%.y`; otherwise `%.n`.
292+For the door defined [above](#example), `c`, the sample is defined as an [atom](/docs/glossary/atom/), `@`, and given the face `b`. The `plus` arm defines a gate that takes a single [atom](/docs/glossary/atom/) as its argument, `a`, and which returns the sum of `a` and `b`. The `times` arm defines a gate that takes a single [atom](/docs/glossary/atom/), `a`, and returns `a` times `b`. The `greater` arm defines a gate that takes a single [atom](/docs/glossary/atom/), `a`, and if `a` is greater than `b` returns `%.y`; otherwise `%.n`.
254293
255294Let's try out the arms of `c` with ordinary function calls:
256295
hoon/hoon-school/lists.md+5
@@ -56,6 +56,11 @@ find-fork-d
5656~[2 3 4 5]
5757```
5858
59+`=>` is a reversed form of the `:` operator we've been using, meaning that `=> a b` is the
60+same as `b:a`. Here, this means we're evaluation the `?~` expression with the
61+`b=...` expression as the subject. We explore this rune in more detail in a
62+[later lesson](@/docs/hoon/hoon-school/arms-and-cores.md#cores-and-contexts).
63+
5964It's important to note that performing tests like `?~ mylist` will actually transform `mylist` into a `lest`, a non-null list. Because `lest` is a different type than `list`, performing such tests can come back to bite you later in non-obvious ways when you try to use some standard library functions meant for lists.
6065
6166You can construct lists of any type. `(list @)` indicates a list of atoms, `(list ^)` indicates a list of cells, `(list [@ ?])` indicates a list of cells whose head is an atom and whose tail is a flag, etc.