on master help sign in
Merge remote-tracking branch 'origin/cleanorg' into cleanorg
commit52fea552f92ab3f8de3958a2ee3a90dc877859ea authorC. Guy Yarvin <cgyarvin@gmail.com> dateTue 19 Apr 2016, 16:28 (11 years ago) parent81d37cc632f03f
13 files changed+1855−57
docs/programming/arvo/system/api.md+11−9 docs/programming/arvo/system/security-driver.md+19−14 docs/programming/hoon/catalog.md+13−12 docs/programming/hoon/catalog/buc-mold/cab-shoe.md+2−1 docs/programming/hoon/cheat-sheets.md+1−1 docs/programming/hoon/examples.md+10−10 docs/programming/hoon/library.md+2−1 docs/programming/hoon/span.md+1−1 docs/programming/hoon/troubleshooting.md+4−3 docs/programming/hoon/twig.md+2−2 docs/programming/nock/nock.md → docs/programming/nock/interpreter.md+3−3 docs/programming/nock/reference.md+742 docs/programming/nock/tutorial.md+1045
docs/programming/arvo/system/api.md+11−9
@@ -4,6 +4,8 @@ sort: 12
44title: API Connectors
55---
66
7+# API Connectors
8+
79Most people have lots of data stored in online services, many of
810which have APIs. API connectors allow the user to access this
911data from within their Urbit.
@@ -23,7 +25,7 @@ app accomplishes both for Github.
2325After starting `%gh` (`|start %gh`), let's look at the root of
2426the tree that `%gh` exposes:
2527
26− ~sampel-sipnym:dojo> .^(arch %gy /=gh=)
28+ ~your-urbit:dojo> .^(arch %gy /=gh=)
2729 [fil=~ dir={[p=~.issues q=~]}]
2830
2931`%gh` is currently a skeleton -- it contains examples of all the
@@ -31,7 +33,7 @@ functionality necessary for a connector, but many endpoints
3133aren't implemented. As we can see here, only issues are
3234implemented. We can explore this tree:
3335
34− ~sampel-sipnym:dojo> .^(arch %gy /=gh=/issues)
36+ ~your-urbit:dojo> .^(arch %gy /=gh=/issues)
3537 [fil=~ dir={[p=~.by-repo q=~] [p=~.mine q=~]}]
3638
3739And eventually:
@@ -49,9 +51,9 @@ the `:pipe` app:
4951 :pipe|connect %gh /listen/philipcmonktest/testing/issues/'issue_comment' %public
5052
5153Now creating an issue results in the following message in your
52−`%public` channel:
54+`%public` `:talk` channel:
5355
54− ~sampel-sipnym[philipcmonktest@github]: opened issue #11: i found a bug!
56+ ~your-urbit[philipcmonktest@github]: opened issue #11: i found a bug!
5557
5658You'll also get notifications of issue status changes and
5759comments.
@@ -65,7 +67,7 @@ drifts out of sync with this doc).
6567We'll go over the two parts to an API connector (one-time reading vs listening
6668for events) separately.
6769
68−# Reading
70+## Reading
6971
7072A connector exposes a tree of data. Every read request has a
7173`care`, which is generally either `%x` or `%y. `%x` is a request
@@ -78,7 +80,7 @@ Unix `ls`.
7880> "should" produce a list of all Github users, but we don't do
7981> that because it's too long. Instead, we just produce our own
8082> username (from the `web.plan` file). You can still access
81−> repos from other uesrs, you just don't see them in the
83+> repos from other users, you just don't see them in the
8284> directory listing.
8385
8486The usual flow for implementing this tree of data makes heavy use
@@ -100,7 +102,7 @@ list of all the places we can request. A place consists of:
100102 to match `/issues/<user>/<repo>` use `{$issues @t @t $~}`.
101103
102104- `read-x`, called when someone tries to read the place with
103− care `%x`. Should produce a single move, usually either a
105+ `care` `%x`. Should produce a single move, usually either a
104106 `%diff` response if we can immediately answer or a `%hiss`
105107 http request if we need to make a request to the api. See the
106108 `++read-*` functions in `++helpers` for some common handlers.
@@ -156,7 +158,7 @@ control. There are four functions we need to define:
156158That's really all there is to the reading portion of API
157159connectors.
158160
159−# Listening
161+## Listening
160162
161163Listening for events is fairly service-specific. In some
162164services, we poll for changes. For an example of that, check out
@@ -175,7 +177,7 @@ up-to-date.
175177Flow of control starts in `++peer-listen`, where we just call
176178`++listen`. In `++listen`, for each event in the list of events,
177179we check to see if we have that hook set up (by checking whether
178−it exists in `hook`). If so, we call `++update-hook` to add th
180+it exists in `hook`). If so, we call `++update-hook` to add the
179181current bone to the set of listeners. Otherwise, we call
180182`++create-hook`, which sends a request to Github to set up the
181183new webhook. We also create an entry in `hook` with the current
docs/programming/arvo/system/security-driver.md+19−14
@@ -4,6 +4,8 @@ sort: 10
44title: Security Drivers
55---
66
7+# Security Drivers
8+
79A security driver is a file in `/=home=/sec/<tld>/<domain>/hoon`
810that handles the authentication for all HTTP requests to
911`https://<domain>.<tld>`. All requests to the domain are
@@ -29,21 +31,23 @@ models.
2931Still, it's worth seeing one or two built from the ground up.
3032Here, we'll build a connector for the Github API v3. The
3133simplest way to interact with the Github API is to just fetch
32−https://api.github.com.
34+https://api.github.com from the dojo:
3335
34− +https://api.github.com
36+ ~your-urbit:dojo> +https://api.github.com
3537
3638Github exposes a few endpoints to the general web, and the root
3739endpoint is one of them. This gives you a textual representation
3840of a JSON object that contains a bunch of urls to other parts of
3941Github's API. This is exactly the same response you would get
40−from just running `curl` on UNIX.
42+from just running `curl https://api.github.com` on UNIX.
4143
4244If we don't have a security driver for Github yet, many of the
4345endpoints won't be accessible, or they will only have publicly
4446accessible information. Most of what we care about requires us
4547to be authenticated.
4648
49+## Basic auth
50+
4751Here's a simple security driver:
4852
4953```
@@ -70,7 +74,7 @@ To try this out, we first have to initialize our credentials with
7074`|init-auth-basic`, which prompts for the url of the service
7175(api.github.com), username, and password. It stores this
7276information in a manner that `%eyre` knows how to decode and send
73−put into your bale. Note that `|init-auth-basic` is standard for
77+put into your `bale`. Note that `|init-auth-basic` is standard for
7478basic auth, but other auth schemes (like OAuth) are initialized
7579in other ways.
7680
@@ -80,8 +84,7 @@ you're logged in as.
8084
8185You can similarly POST:
8286
83− +https://api.github.com/gists &json _(cork poja need)
84− '{"files":{"file1.txt":{"content":"can\'t stop the signal"}}}'
87+ ~your-urbit:dojo> +https://api.github.com/gists &json _(cork poja need) '{"files":{"file1.txt":{"content":"can\'t stop the signal"}}}'
8588
8689This creates a gist, go to `https://gist.github.com/<username>` to
8790see it.
@@ -93,22 +96,24 @@ can send data of any mark as long as it has a conversion path to
9396`%mime`.
9497
9598Let's take a look at the code and see if we can figure out what's
96−happening here.
99+happening here:
100+
101+ /+ basic-auth
97102
98103First, we load a library called `basic-auth`. This library
99104exposes two items. `keys` is the type of the basic auth key,
100105which is essentially a base64'd username and password.
101−`standard` accepts a bale and produces a core with everything
106+`standard` accepts a `bale` and produces a core with everything
102107we'll need to implement basic auth.
103108
104109Every security driver needs some amount of state, which is stored
105−in the bale. The bale contains:
110+in `bale`. `bale` contains:
106111
107112- `our`, our urbit name
108113- `now`, the current time
109114- `eny`, 256 bits of entropy
110−- `byk`, the urbit, desk, and case which the security driver is
111− running off
115+- `byk`, the urbit, desk and case which the security driver is
116+ running from
112117- `usr`, the particular identity we're logging in with
113118- `dom`, the site we're accessing
114119- `key`, the secrets required to authenticate requests. The type
@@ -130,7 +135,7 @@ one of:
130135 asking the user to visit the given url to continue the
131136 authentication process.
132137
133−Every request to a Github url will be filtered through
138+Every request to a GitHub url will be filtered through
134139`++filter-request`, and we want to add the authentication header
135140to it. Our `++aut` core contains a function
136141`++out-addding-header`, which does exactly what we want.
@@ -141,9 +146,9 @@ service url, username, and password, and it stores them next to
141146the driver. In our case, that's
142147`/=home=/sec/com/gitub/api/atom`. These keys are stored
143148encrypted, and you don't want to edit them directly. `%eyre`
144−loads them directly into your bale.
149+loads them directly into your `bale`.
145150
146−# OAuth2
151+## OAuth2
147152
148153Most services are better accessed through some form of OAuth.
149154Github can be accessed with OAuth2, which is a little more
docs/programming/hoon/catalog.md+13−12
@@ -1,5 +1,6 @@
11---
2−sort: 3
2+sort: 10
3+title: Stems catalog
34---
45
56# Stems
@@ -8,67 +9,67 @@ sort: 3
89
910<div class="book">
1011
11−## `$ buc` (mold)
12+## `$ buc` (mold)
1213
1314<list src="buc-mold" dataPreview="true" className="runes" childIsFragment="true"></list>
1415
1516---
1617
17−## `| bar` (core)
18+## `| bar` (core)
1819
1920<list src="bar-core" dataPreview="true" className="runes" childIsFragment="true"></list>
2021
2122---
2223
23−## `: col` (cell)
24+## `: col` (cell)
2425
2526<list src="col-cell" dataPreview="true" className="runes" childIsFragment="true"></list>
2627
2728---
2829
29−## `% cen` (call)
30+## `% cen` (call)
3031
3132<list src="cen-call" dataPreview="true" className="runes" childIsFragment="true"></list>
3233
3334---
3435
35−## `. dot` (nock)
36+## `. dot` (nock)
3637
3738<list src="dot-nock" dataPreview="true" className="runes" childIsFragment="true"></list>
3839
3940---
4041
41−## `^ ket` (cast)
42+## `^ ket` (cast)
4243
4344<list src="ket-cast" dataPreview="true" className="runes" childIsFragment="true"></list>
4445
4546---
4647
47−## `~ sig` (hint)
48+## `~ sig` (hint)
4849
4950<list src="sig-hint" dataPreview="true" className="runes" childIsFragment="true"></list>
5051
5152---
5253
53−## `; sem` (make)
54+## `; sem` (make)
5455
5556<list src="sem-make" dataPreview="true" className="runes" childIsFragment="true"></list>
5657
5758---
5859
59−## `= tis` (flow)
60+## `= tis` (flow)
6061
6162<list src="tis-flow" dataPreview="true" className="runes" childIsFragment="true"></list>
6263
6364---
6465
65−## `? wut` (test)
66+## `? wut` (test)
6667
6768<list src="wut-test" dataPreview="true" className="runes" childIsFragment="true"></list>
6869
6970---
7071
71−## `! zap` (wild)
72+## `! zap` (wild)
7273
7374<list src="zap-wild" dataPreview="true" className="runes" childIsFragment="true"></list>
7475
docs/programming/hoon/catalog/buc-mold/cab-shoe.md+2−1
@@ -1,8 +1,9 @@
11---
22sort: 1
3+preview: Form a mold
34---
45
5−# `:shoe, $_, "buccab", {$shoe p/twig}`
6+# `:shoe $_ "buccab" {$shoe p/twig}`
67
78Form a mold which normalizes to an example.
89
docs/programming/hoon/cheat-sheets.md+1−1
@@ -1,5 +1,5 @@
11---
2−sort: 12
2+sort: 13
33---
44
55# Quick references
docs/programming/hoon/examples.md+10−10
@@ -1,5 +1,5 @@
11---
2−sort: 9
2+sort: 8
33title: Examples
44---
55
@@ -82,14 +82,14 @@ up through the factors we're removing.
8282Line `11`: we start a loop. The product of the loop is cast to
8383`..main`, which is the core we're in (`+1.main`).
8484
85−Lines `12` and `13`: we terminate the loop, returning `..main`,
85+Lines `12` and `13`: we terminate the loop, returning `..main`,
8686if the square of the counter exceeds the range.
8787
8888Line `14`: repeats the loop, incrementing the counter, and
8989replacing the core with a version sieved by `reap`.
9090
9191Lines `16` and `17`: the `reap` arm, which produces a gate that
92−removes multiples of a factor from the field (set of possible
92+removes multiples of a factor from the field (set of possible
9393primes). The sample of this gate is the factor to remove.
9494
9595Line `18`: we declare a variable `count`, an atom, with the
@@ -235,7 +235,7 @@ common pattern. (You could put the molds and the gates in the
235235same core, but the compiler couldn't constant-fold gate samples
236236that use these molds, an efficiency cost.)
237237
238−Line `12` defines the `side` mold, an alias for `atom` (`@`).
238+Line `12` defines the `side` mold, an alias for `atom` (`@`).
239239A side is a half of the board, as a marked/unmarked bitfield.
240240
241241Line `13` defines the `spot` mold, a 2D coordinate.
@@ -246,7 +246,7 @@ output action), as a book (tagged union). There are two forms of
246246(reporting that `'X'` or `'O'` won a game.
247247
248248Lines `17` to `20` define the `move` mold, a game move. This is
249−either `[%x spot]`, `[%o spot]`, or `[%z ~]` to reset the board.
249+either `[%x spot]`, `[%o spot]`, or `[%z ~]` to reset the board.
250250
251251Lines `21` to `23` define the `game` mold, the game state. This
252252is an `a` side, the next side to move; a `z` side, the other
@@ -266,7 +266,7 @@ to a bit index.
266266
267267Line `31` is the `get` gate, which produces the bit at a `spot`.
268268
269−Line `32` is the `set` gate, which produces a new side with the
269+Line `32` is the `set` gate, which produces a new side with the
270270bit at a `spot` set. It works by ORing (`con`) `half` with the
271271binary exponent (`bex`) of the offset (`off`) of the spot.
272272
@@ -331,7 +331,7 @@ side `z`, and replaces `z` with `next`.
331331 ++ spot {x/@ y/@}
332332 ++ fact $% {$tie $~}
333333 {$win p/cord}
334− ==
334+ ==
335335 ++ move $% {$x p/spot}
336336 {$o p/spot}
337337 {$z $~}
@@ -358,8 +358,8 @@ side `z`, and replaces `z` with `next`.
358358 |= act/move
359359 ^- {(unit fact) game}
360360 ?- act
361− {$x *} ?>(w.mag ~(mo on p.act))
362− {$o *} ?<(w.mag ~(mo on p.act))
361+ {$x *} ?>(w.mag ~(mo on p.act))
362+ {$o *} ?<(w.mag ~(mo on p.act))
363363 {$z *} [~ nu]
364364 ==
365365 ::
@@ -376,7 +376,7 @@ side `z`, and replaces `z` with `next`.
376376 ?: ~(win bo next)
377377 [[~ %win ?:(w.mag %x %o)] nu]
378378 [~ mag(w !w.mag, a z.mag, z next)]
379− --
379+ --
380380 --
381381--
382382```
docs/programming/hoon/library.md+2−1
@@ -1,5 +1,6 @@
11---
2−sort: 2
2+sort: 12
3+title: Standard Library
34---
45
56Library
docs/programming/hoon/span.md+1−1
@@ -1,5 +1,5 @@
11---
2−sort: 7
2+sort: 6
33next: true
44title: Type: span
55---
docs/programming/hoon/troubleshooting.md+4−3
@@ -1,5 +1,6 @@
11---
2−sort: 10
2+sort: 9
3+title: Troubleshooting
34---
45
56# Troubleshooting
@@ -53,7 +54,7 @@ Now your code parses but doesn't compile.
5354### Turn on debugging
5455
5556Your first step should be to put a `!:` ("zapcol") rune at the
56−top of the file. This is like calling the C compiler with `-g`;
57+top of the file. This is like calling the C compiler with `-g`;
5758it tells the Hoon compiler to generate tracing twigs.
5859
5960Bear in mind that `!:` breaks tail-call optimization. This is a
@@ -100,7 +101,7 @@ means you tried to pound a square peg into a round hole.
100101
101102What was the peg and what was the hole? Hoon doesn't tell you by
102103default, because moral fiber, and also because in too many cases
103−trivial errors lead to large intimidating dumps. However, you
104+trivial errors lead to large intimidating dumps. However, you
104105can use the `~!` rune ("sigzap", `:peep`) to print the type of
105106any twig in your stack trace.
106107
docs/programming/hoon/twig.md+2−2
@@ -1,7 +1,7 @@
11---
2−sort: 8
2+sort: 7
33next: true
4−title: Expression: twig
4+title: Expressions: twig
55---
66
77# Expression: `twig`
docs/programming/nock/nock.md → docs/programming/nock/interpreter.mdrenamed+3−3
@@ -1,5 +1,5 @@
11---
2−sort: 5
2+sort: 1
33next: true
44title: Interpreter
55---
@@ -54,7 +54,7 @@ can detect this crash and produce an out-of-band value instead.
5454*[a 4 b] +*[a b]
5555*[a 5 b] =*[a b]
5656
57−*[a 6 b c d] *[a 2 [0 1] 2 [1 c d] [1 0]
57+*[a 6 b c d] *[a 2 [0 1] 2 [1 c d] [1 0]
5858 2 [1 2 3] [1 0] 4 4 b]
5959*[a 7 b c] *[a 2 b 1 c]
6060*[a 8 b c] *[a 7 [[7 [0 1] b] 0 1] c]
@@ -70,7 +70,7 @@ can detect this crash and produce an out-of-band value instead.
7070The pseudocode notation defines five prefix operators: `?`, `+`,
7171`=`, `/`, and `*`.
7272
73−`?[x]` produces `0` if `x` is a cell, `1` if an atom.
73+`?[x]` produces `0` if `x` is a cell, `1` if an atom.
7474
7575`+[x]` produces the atom `x` plus `1`.
7676
docs/programming/nock/reference.mdnew file+742
@@ -0,0 +1,742 @@
1+---
2+sort: 3
3+title: Reference
4+---
5+
6+Nock Reference
7+==============
8+
9+Nouns
10+-----
11+
12+ 1 :: A noun is an atom or a cell.
13+ 2 :: An atom is a natural number.
14+ 3 :: A cell is an ordered pair of nouns.
15+
16+An **atom** is a natural number - ie, an unsigned integer. Nock does not
17+limit the size of **atoms**, or know what an **atom** means.
18+
19+For instance, the **atom** `97` might mean the number `97`, or it might
20+mean the letter `a` (ASCII 97). A very large **atom** might be the
21+number of grains of sand on the beach - or it might be a GIF of your
22+children playing on the beach. Typically when we represent strings or
23+files as **atoms**, the first byte is the low byte. But even this is
24+just a convention. An **atom** is an **atom**.
25+
26+A **cell** is an ordered pair of any two **nouns** - **cell** or
27+**atom**. We group cells with square brackets:
28+
29+ [1 1]
30+ [34 45]
31+ [[3 42] 12]
32+ [[1 0] [0 [1 99]]]
33+
34+*Nouns* are the dumbest data model ever. **Nouns** make JSON look like
35+XML and XML look like ASN.1. It may also remind you of Lisp's
36+S-expressions - you can think of nouns as "S-expressions without the S."
37+
38+To be exact, a *noun* is an S-expression, except that classic
39+S-expressions have multiple **atom** types ("S" is for "symbol"). Since
40+Nock is designed to be used with a higher-level type system (such as
41+Hoon's), it does not need low-level types. An **atom** is just an
42+unsigned integer of any size.
43+
44+For instance, it's common to represent strings (or even whole text
45+files) as atoms, arranging them LSB first - so "foo" becomes `0x6f6f66`.
46+How do we know to print this as "foo", not `0x6f6f66`? We need external
47+information - such as a Hoon type. Similarly, other common atomic
48+types - signed integers, floating point, etc — are all straightforward
49+to map into **atoms**.
50+
51+It's also important to note that, unlike Lisp, Nock cannot create
52+cyclical data structures. It is normal and common for **nouns** in a
53+Nock runtime system to have acyclic structure - shared subtrees. But
54+there is no Nock computation that can make a child point to its parent.
55+One consequence: Nock has no garbage collector. (Nor can dag structure
56+be detected, as with Lisp eq.)
57+
58+There is also no single syntax for **nouns**. If you have **nouns** you
59+have Nock; if you have Nock you have Hoon; if you have Hoon, you can
60+write whatever parser you like.
61+
62+------------------------------------------------------------------------
63+
64+The Nock Function
65+-----------------
66+
67+ 5 :: nock(a) *a
68+
69+Nock is a pure (stateless) function from **noun** to **noun**. In our
70+pseudocode (and only in our pseudocode) we express this with the prefix
71+operator `*`.
72+
73+A Nock program is given meaning by a process of reduction. To compute
74+`nock(x)`, where `x` is any **noun**, we step through the rules from the
75+top down, find the first left-hand side that matches `x`, and reduce it
76+to the right-hand side (in more mathematical notation, we might write
77+line 5 as `nock(a) -> *a`, a style we do use in documentation)
78+
79+When we use variable names, like `a`, in the pseudocode spec, we simply
80+mean that the rule fits for any **noun** `a`.
81+
82+So `nock(x)` is `*x`, for any **noun** `x`. And how do we reduce `*x`?
83+Looking up, we see that lines 23 through 39 reduce `*x` - for different
84+patterns of `x`.
85+
86+Normally `a` in `nock(a)` is a **cell** `[s f]`, or
87+
88+ [subject formula]
89+
90+Intuitively, the formula is your function and the subject is its
91+argument. Hoon, or any other high-level language built on Nock, will
92+build its own function calling convention which does not map directly to
93+`*[subject formula]`.
94+
95+------------------------------------------------------------------------
96+
97+Bracket Grouping
98+----------------
99+
100+ 6 :: [a b c] [a [b c]]
101+
102+Brackets associate to the right.
103+
104+So instead of writing
105+
106+ [2 [6 7]]
107+ [2 [6 [14 15]]]
108+ [2 [6 [[28 29] [30 31]]]]
109+ [2 [6 [[28 29] [30 [62 63]]]]]
110+
111+we can write
112+
113+ [2 6 7]
114+ [2 6 14 15]
115+ [2 6 [28 29] 30 31]
116+ [2 6 [28 29] 30 62 63]
117+
118+While this notational convenience is hardly rocket science, it's
119+surprising how confusing it can be, especially if you have a Lisp
120+background. Lisp's "S-expressions" are very similar to **nouns**, except
121+that Lisp has multiple types of **atom**, and Lisp's syntax
122+automatically adds list terminators to groups.
123+
124+For those with Lisp experience, it's important to note that Nock and
125+Hoon use tuples or "improper lists" much more heavily than Lisp. The
126+list terminator, normally 0, is never automatic. So the Lisp list
127+
128+ (a b c)
129+
130+becomes the Nock **noun**
131+
132+ [a b c 0]
133+
134+which is equivalent to
135+
136+ [a [b [c 0]]]
137+
138+Note that we can and do use unnecessary brackets anyway, for emphasis.
139+
140+------------------------------------------------------------------------
141+
142+Axiomatic Functions
143+-------------------
144+
145+ 8 :: ?[a b] 0
146+ 9 :: ?a 1
147+ 10 :: +[a b] +[a b]
148+ 11 :: +a 1 + a
149+ 12 :: =[a a] 0
150+ 13 :: =[a b] 1
151+
152+Here we define three of Nock's four axiomatic functions: **Cell-test**,
153+**Increment** and **Equals** (the fourth axiomatic function, called
154+**Address**, is defined in lines 16 through 21). These functions are
155+just pseudocode, not actual Nock syntax, and are only used to define the
156+behaviour of certain Nock operators.
157+
158+We should note that in Nock and Hoon, `0` (pronounced "yes") is true,
159+and `1` ("no") is false. This convention is the opposite of
160+old-fashioned booleans, so we try hard to say "yes" and "no" instead of
161+"true" and "false."
162+
163+------------------------------------------------------------------------
164+
165+### Cell-test `?`
166+
167+`?` (pronounced "wut") tests whether is a **noun** is a **cell**. Again,
168+`0` means "yes", `1` means "no":
169+
170+ 8 :: ?[a b] 0
171+ 9 :: ?a 1
172+
173+------------------------------------------------------------------------
174+
175+### Increment `+`
176+
177+`+` (pronounced "lus") adds `1` to an **atom**:
178+
179+ 10 :: +[a b] +[a b]
180+ 11 :: +a 1 + a
181+
182+------------------------------------------------------------------------
183+
184+### Equals `=`
185+
186+`=` (pronounced "tis") tests a cell for equality. `0` means "yes", `1`
187+means "no":
188+
189+ 12 :: =[a a] 0
190+ 13 :: =[a b] 1
191+ 14 :: =a =a
192+
193+Testing an **atom** for equality makes no sense and logically fails to
194+terminate.
195+
196+Because `+` works only for **atoms**, whereas `=` works only for
197+**cells**, the error rules match first for `+` and last for `=`.
198+
199+------------------------------------------------------------------------
200+
201+Noun Address
202+------------
203+
204+ 16 :: /[1 a] a
205+ 17 :: /[2 a b] a
206+ 18 :: /[3 a b] b
207+ 19 :: /[(a + a) b] /[2 /[a b]]
208+ 20 :: /[(a + a + 1) b] /[3 /[a b]]
209+ 21 :: /a /a
210+
211+We define a **noun** as a binary tree - where each node branches to a
212+left and right child - and assign an address, or **axis**, to every
213+element in the tree. The root of the tree is `/1`. The left child
214+(**head**) of every node at `/a` is `/2a`; the right child (**tail**) is
215+`/2a+1`. (Writing `(a + a)` is just a clever way to write `2a`, while
216+minimizing the set of pseudocode forms.)
217+
218+`1` is the root. The **head** of every **axis** `n` is `2n`; the
219+**tail** is `2n+1`. Thus a simple tree:
220+
221+ 1
222+ 2 3
223+ 4 5 6 7
224+ 14 15
225+
226+If the value of every leaf is its tree address, this tree is
227+
228+ [[4 5] [6 14 15]]
229+
230+Let's use the example `[[97 2] [1 42 0]]`. So
231+
232+ /[1 [97 2] [1 42 0]] -> [[97 2] [1 42 0]]
233+
234+because `/1` is the root of the tree, ie, the whole **noun**.
235+
236+Its left child (**head**) is `/2` (i.e. `(1 + 1)`):
237+
238+ /[2 [97 2] [1 42 0]] -> [97 2]
239+
240+And its right child (**tail**) is `/3` (i.e. `(1 + 1 + 1)`):
241+
242+ /[3 [97 2] [1 42 0]] -> [1 42 0]
243+
244+And delving into `/3`, we see `/(3 + 3)` and `/(3 + 3 + 1)`:
245+
246+ /[6 [97 2] [1 42 0]] -> 1
247+ /[7 [97 2] [1 42 0]] -> [42 0]
248+
249+It's also fun to build nouns in which every atom is its own axis:
250+
251+ 1
252+ [2 3]
253+ [2 6 7]
254+ [[4 5] 6 7]
255+ [[4 5] 6 14 15]
256+ [[4 5] [12 13] 14 15]
257+ [[4 [10 11]] [12 13] 14 15]
258+ [[[8 9] [10 11]] [12 13] 14 30 31]
259+
260+------------------------------------------------------------------------
261+
262+Distribution
263+------------
264+
265+ 23 :: *[a [b c] d] [*[a b c] *[a d]]
266+
267+The practical domain of the Nock function is always a **cell**. When `a`
268+is an **atom**, `*a`, or `nock(a)`, is always an error. Conventionally,
269+Nock proper is always a function of a **cell**. The **head** of this
270+**cell** is the **subject**, the **tail** is the **formula**
271+
272+ [subject formula]
273+
274+and the result of passing a **noun** through the Nock function is called
275+the **product**.
276+
277+ nock([subject formula]) => product
278+
279+or
280+
281+ *[subject formula] => product
282+
283+The **subject** is your data and the **formula** is your code. And the
284+**product** is your code's output.
285+
286+Notice that `a` in the Nock rules is always the **subject**, except line
287+39, which is a crash default for malformed **nouns** that do not
288+evaluate.
289+
290+A **formula** is always a **cell**. But when we look inside that
291+**cell**, we see two basic kinds of **formulas**:
292+
293+ [operator operands]
294+ [formula-x formula-y]
295+
296+An **operator** is always an **atom** (`0` through `10`). A **formula**
297+is always a **cell**. Line 23 distinguishes these forms:
298+
299+ 23 :: *[a [b c] d] [*[a b c] *[a d]]
300+
301+If your code contains multiple **formulas**, the **subject** will
302+distribute over those **formulas**.
303+
304+In other words, if you have two Nock **formulas** `x` and `y`, a
305+**formula** that computes the pair of them is just the **cell** `[x y]`.
306+
307+ *[subject [x y]] -> [*[subject x] *[subject y]]
308+
309+No **atom** is a valid **formula**, and every **formula** that does not
310+use line 23 has an atomic **head**.
311+
312+Suppose you have two **formulas** `f` and `g`, each of which computes
313+some function of the **subject** `s`. You can then construct the
314+**formula** `h` as `[f g]`; and `h(s) = [f(s) g(s)]`.
315+
316+For example:
317+
318+ *[[19 42] [0 3] 0 2]
319+
320+The **subject** `s` is `[19 42]`. The **formula** `h` is `[[0 3] 0 2]`.
321+
322+ *[s h]
323+
324+The **head** of `h` is `f`, which is `[0 3]`. The **tail** of `h` is
325+`g`, which is `[0 2]`.
326+
327+ *[s [f g]]
328+
329+by the distribution rule, `*[s [f g]]` is
330+
331+ [*[s f] *[s g]]
332+
333+or
334+
335+ [*[[19 42] [0 3]] *[[19 42] 0 2]]
336+
337+`*[s f]` is `f(s)` and produces `42`. `*[s g]` is `g(s)` and produces
338+19.
339+
340+Since `h(s)` is `[f(s) g(s)]`, `h(s)` is `[42 19]`:
341+
342+ *[[19 42] [0 3] 0 2] -> [42 19]
343+
344+------------------------------------------------------------------------
345+
346+Operator 0: Axis
347+----------------
348+
349+ 25 :: *[a 0 b] /[b a]
350+
351+Operator 0 is Nock's tree address or **axis** operator, using the tree
352+addressing structure defined in lines 16 through 20. `*[a 0 b]` simply
353+returns the value of the part of `a` at **axis** `b`. For any subject
354+`a`, the formula `[0 b]` produces `/[b a]`.
355+
356+For example,
357+
358+ *[[19 42] 0 3] -> /[3 19 42] -> 42.
359+
360+------------------------------------------------------------------------
361+
362+Operator 1: Just
363+----------------
364+
365+ 26 :: *[a 1 b] b
366+
367+`1` is the constant, or **Just operator**. It produces its operand `b`
368+without reference to the **subject**.
369+
370+For example,
371+
372+ *[42 1 57] -> 57
373+
374+**Operator 1** is named **Just** because it produces "just" its operand.
375+
376+------------------------------------------------------------------------
377+
378+Operator 2: Fire
379+----------------
380+
381+ 27 :: *[a 2 b c] *[*[a b] *[a c]]
382+
383+**Operator 2** is the **Fire operator**, which brings us the essential
384+magic of recursion. Given the **formula** `[2 b c]`, `b` is a
385+**formula** for generating a new **subject**; `c` is a **formula** for
386+generating a new **formula**. To compute `*[a 2 b c]`, we evaluate both
387+`b` and `c` against the current **subject** `a`.
388+
389+A common use of **Fire** is to evaluate data inside the **subject** as
390+code.
391+
392+For example:
393+
394+ *[[[40 43] [4 0 1]] [2 [0 4] [0 3]]] -> 41
395+
396+ *[[[40 43] [4 0 1]] [2 [0 5] [0 3]]] -> 44
397+
398+**Operator 2** is called **Fire** because it "fires" Nock **formulas**
399+at its (possibly modified) **subject**.
400+
401+------------------------------------------------------------------------
402+
403+Operator 3: Depth
404+-----------------
405+
406+ 28 :: *[a 3 b] ?*[a b]
407+
408+**Operator 3** applies the **Cell-test** function defined in lines 8 and
409+9 to the product of `*[a b]`.
410+
411+**Operator 3** is called **Depth** because it tests the "depth" of a
412+noun. **Cell-test** properly refers to the pseudocode function `?`.
413+
414+------------------------------------------------------------------------
415+
416+Operator 4: Bump
417+----------------
418+
419+ 29 :: *[a 4 b] +*[a b]
420+
421+**Operator 4** applies the **Increment** function defined in lines 10
422+and 11 to the product of `*[a b]`.
423+
424+**Operator 4** is called **Bump** because it "bumps" the atomic product
425+`*[a b]` up by 1. **Increment** properly refers to the pseudocode
426+function `+`.
427+
428+------------------------------------------------------------------------
429+
430+Operator 5: Same
431+----------------
432+
433+ 30 :: *[a 5 b] =*[a b]
434+
435+**Operator 5** applies the Equals function defined in lines 12, 13 and
436+14 to the product of \*[a b].
437+
438+**Operator 5** is called the **Same** operator, because it tests if the
439+head and tail of the product of `*[a b]` are the same. "Equals" properly
440+refers to the pseudocode function "=".
441+
442+------------------------------------------------------------------------
443+
444+Operator 6: If
445+--------------
446+
447+ 32 :: *[a 6 b c d] *[a 2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]
448+
449+**Operator 6** is a primitive known to every programmer - **If**. Its
450+operands, a **test formula** `b`, a **then formula** `c` and an **else
451+formula** `d`.
452+
453+If the **test** `b` applied to the **subject** evaluates to `0` ("yes"),
454+
455+ *[a b] -> 0
456+
457+then **If** produces the result of `c`, the **then formula**, applied to
458+the **subject**,
459+
460+ *[a c]
461+
462+Else, if applying the **test** to the **subject** produces `1` ("no"),
463+
464+ *[a b] -> 1
465+
466+**Operator 6** produces the result of `d`, the **else formula**, applied
467+to the **subject**,
468+
469+ *[a d]
470+
471+If `*[a b]` produces any value other than `0` ("yes") or `1` ("no"),
472+**If** crashes.
473+
474+Let's examine the internals of **Operator 6**:
475+
476+**If** could have been defined as a built-in pseudocode function, like
477+**Increment**:
478+
479+ :: $[0 b c] b
480+ :: $[1 b c] c
481+
482+Then **Operator 6** could have been restated quite compactly:
483+
484+ :: *[a 6 b c d] *[a $[*[a b] c d]]
485+
486+However, this is unnecessary complexity. **If** can be written as a
487+macro using the primitive operators:
488+
489+ 32 :: *[a 6 b c d] *[a 2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]
490+
491+Reducing the right-hand side (an excellent exercise for the reader)
492+produces:
493+
494+ *[a *[[c d] [0 *[[2 3] [0 ++*[a b]]]]]]
495+
496+Which is the reduced pseudocode form of **Operator 6**.
497+
498+Additionally, we could simplify the semantics of **If**, at the expense
499+of breaking the system, by creating a macro that works as if and only if
500+`*[a b]` produces either `0` or `1`.
501+
502+This simpler **If** would be:
503+
504+ :: *[a 6 b c d] *[a 2 [0 1] 2 [1 c d] [1 0] [4 4 b]]
505+
506+which reduces to:
507+
508+ *[a *[[c d] [0 ++*[a b]]]]
509+
510+Let's examine the internals of this macro with a test example:
511+
512+ *[[40 43] [6 [3 0 1] [4 0 2] [4 0 1]]]
513+
514+Fitting this to the reduced form:
515+
516+ *[[40 43] *[[4 0 2] [4 0 3]] [0 ++*[[40 43] [3 0 1]]]]]
517+
518+Our test:
519+
520+ *[[40 43] [3 0 1]]
521+
522+produces a 0,
523+
524+ *[[40 43] *[[[4 0 2] [4 0 3]] [0 ++0]]]]
525+
526+which gets incremented twice
527+
528+ *[[40 43] *[[[4 0 2] [4 0 3]] [0 2]]]
529+
530+and is used as an axis to select the head of [[4 0 2] [4 0 3]]
531+
532+ *[[40 43] [4 0 2]]
533+
534+which increments `40` to produce `41`. Had the **test** produced a "no"
535+instead of a "yes", **If** would have incremented the **tail** of the
536+subject instead of the **head**.
537+
538+The real **If** is only slightly more complicated:
539+
540+ :: *[a 6 b c d] *[a *[[c d] [0 *[[2 3] [0 ++*[a b]]]]]]
541+
542+There is an extra step in the real **If** to prevent unexpected
543+behaviour if the test produces a value other than 0 ("yes") or 1 ("no").
544+The real **If** will crash if this happens and the naive **If** may not
545+(the reader will find it a useful exercise to figure out why).
546+
547+It's worth noting that practical, compiler-generated Nock never does
548+anything as funky as these **Operator 6** macro internals.
549+
550+------------------------------------------------------------------------
551+
552+Operator 7: Compose
553+-------------------
554+
555+ 33 :: *[a 7 b c] *[a 2 b 1 c]
556+
557+**Operator 7** implements function composition. To use a bit of math
558+notation, if we define the formula `[7 b c]` as a function `d(x)`:
559+
560+ d(a) == c(b(a))
561+
562+This is apparent from the reduced pseudocode form of **Operator 7**:
563+
564+ *[*[a b] c]
565+
566+As an example,
567+
568+ *[[42 44] [7 [4 0 3] [3 0 1]]] -> 1
569+
570+The above sequentially applies the **formulas** `[4 0 3]` and `[3 0 1]`
571+to our subject `[42 44]`, first incrementing the **head**, then testing
572+the **depth**.
573+
574+------------------------------------------------------------------------
575+
576+Operator 8: Push
577+----------------
578+
579+ 34 :: *[a 8 b c] *[a 7 [[7 [0 1] b] 0 1] c]
580+
581+**Operator 8** pushes a new **noun** onto our **subject**, not at all
582+unlike pushing a new variable onto the stack.
583+
584+The internals of **Operator 8** are similar to **Operator 7**, except
585+that the **subject** for `c` is not simply the **product** of `b`, but
586+the ordered pair of the **product** of `b` and the original **subject**.
587+
588+This is apparent from the reduced pseudocode form of **Operator 8**:
589+
590+ *[[*[a b] a] c]
591+
592+**Operator 8** evaluates the **formula** `c` with the **cell** of
593+`*[a b]` and the original **subject** `a`. In math notation, if we
594+define `[8 b c]` as `d(x)`:
595+
596+ d(a) == c([b(a) a])
597+
598+Suppose, for the purposes of the **formula** `c`, we need not just the
599+**subject** `a`, but some intermediate **noun** computed from the
600+**subject** that will be useful in the calculation of `c`. **Operator
601+8** applies **formula** `c` to a new **subject** that is the pair of the
602+intermediate value and the old **subject**.
603+
604+In higher-level languages that compile to Nock, variable declarations
605+are likely to generate an **Operator 8**, because the variable is
606+computed against the present **subject**, and used in a calculation
607+which depends both on the original **subject** and the new variable.
608+
609+------------------------------------------------------------------------
610+
611+Op 9: Call
612+----------
613+
614+ 35 :: *[a 9 b c] *[a 7 c 2 [0 1] 0 b]
615+
616+**Operator 9** is the **Call** operator and is used for calling and
617+applying **formulas** inside **noun** structures called **cores**
618+
619+A **noun** can contain both data and code. By convention, all
620+interesting flow control in Nock is done with **cores**, which are
621+**cells** whose head is code (containing one or more **formulas**) and
622+whose **tail** is data (possibly containing other **cores**):
623+
624+[code data]
625+
626+All flow structures in other languages not built on Nock correspond to
627+**cores**. Functions and/or closures are **cores**, objects are
628+**cores**, modules are **cores**, even loops are **cores** (Nock, of
629+course, does not have a loop operator).
630+
631+The head of a **core** is called the **battery** and the tail is called
632+the **payload**:
633+
634+ [battery payload]
635+
636+The **payload** of a core is any useful data needed for computation.
637+
638+The **battery** of a **core** is a **noun** containing one or more
639+**arms**, which are **formulas** whose **subject** is the entire
640+**core**.
641+
642+For example, in the case of the **battery** containing three **arms**:
643+
644+ [arm1 [arm2 arm3]]
645+
646+Where `arm1` is at **axis** `/2` in the **battery**, `arm2` is at `/6`,
647+and `arm3` is at `/7`. The **axes** will differ depending on the number
648+of **arms**.
649+
650+Of course, because the **subject** of an **arm** is the entire **core**,
651+an **arm** can invoke itself (or any other **arm** in the **battery**).
652+Hence, it can loop. And this is what a loop is - the simplest of
653+**cores**.
654+
655+Also, by convention, we have terms for different kinds of **cores**,
656+depending on their structure:
657+
658+A **trap** is a **core** whose battery contains a single **arm**. By
659+convention, this arm is called `$` (pronounced 'buc'), which is the
660+empty-name. All **traps** have the following structure:
661+
662+ [$ payload]
663+
664+A **door** is a **core** with a **payload** of the form
665+`[sample context]`. The **sample** is dynamic data (such as the
666+arguments of a function) and the **context** is any data that might be
667+useful (such as other **cores**, variables, or the entire kernel of your
668+OS). All **doors** have the following structure:
669+
670+ [battery [sample context]]
671+
672+A **gate** is a **core** that is both a **door** and a **trap**.
673+**Gates** are the Nock equivalent of lambdas or functions. All **gates**
674+have the structure:
675+
676+ [$ [sample context]]
677+
678+**Operator 9** constructs a **core** and activates it by calling one of
679+its **arms**.
680+
681+Looking reduced pseudocode form of **Call**:
682+
683+ *[*[a c] *[*[a c] 0 b]]
684+
685+**Call** applies a **formula** `c` to the **subject** `a`, where
686+`*[a c]` produces a **core**. **Call** then calls an **arm** `b` of the
687+**core** produced by `*[a c]` and reflexively applies it to the same
688+**core**.
689+
690+------------------------------------------------------------------------
691+
692+Op 10: Hint
693+-----------
694+
695+ 36 :: *[a 10 [b c] d] *[a 8 c 7 [0 3] d]
696+ 37 :: *[a 10 b c] *[a c]
697+
698+**Operator 10** serves a hint to the interpreter.
699+
700+If `b` is an atom and `c` is a **formula**, the **formula** `[10 b c]`
701+appears to be equivalent to `c`. Likewise if `[b c]` is a **cell**,
702+`[10 [b c] d]` appears to be equivalent to `d`. **Operator 10** is
703+actually a hint operator. The `b` or `[b c]`is discarded information -
704+it is not used, formally, in the computation. It may help the
705+interpreter compute the expression more efficiently, however.
706+
707+Every Nock computes the same result - but not all at the same speed.
708+What hints are supported? What do they do? Hints are a higher-level
709+convention which do not, and should not, appear in the Nock spec. Some
710+are defined in Hoon. Indeed, a naive Nock interpreter not optimized for
711+Hoon will run Hoon quite poorly. When it gets the product, however, the
712+product will be right. (Why is the `c` in `[b c]` computed? Because `c`
713+could crash. A correct Nock cannot simply ignore it, and treat both
714+variants of `10` as equivalent.)
715+
716+------------------------------------------------------------------------
717+
718+Op 11: Retrieve
719+-----------
720+
721+**operator 11** retrieves data from the global namespace at the path it is given.
722+
723+nock 11 is an additional nock operation provided by arvo to provide access to the global namespace. It's provided by arvo, so even though it's not technically a part of the nock, any code that arvo runs has access to it. When nock running on top of arvo hits nock 11, it either produces a value or blocks. The most common usage is with clay, where ^(%cx /path/to/file) will produce the referred-to-file.
724+
725+Crash default
726+-------------
727+
728+ 39 :: *a *a
729+
730+The nock function is defined for every **noun**, but on many **nouns**
731+it does nothing useful. For instance, if `a` is an **atom**, `*a`
732+reduces to... `*a`. In theory, this means that Nock spins forever in an
733+infinite loop. In other words, Nock produces no result - and in
734+practice, your interpreter will stop.
735+
736+Another way to see this is that Nock has "crash-only" semantics. There
737+is no exception mechanism. The only way to catch Nock errors is to
738+simulate Nock in a higher-level virtual Nock - which, in fact, we do all
739+the time. A simulator (or a practical low-level interpreter) can report,
740+out of band, that Nock would not terminate. It cannot recognize all
741+infinite loops, of course (cf. Halting problem), but it can recognize
742+common and obvious ones, which is usually sufficient in practice.
docs/programming/nock/tutorial.mdnew file+1045
@@ -0,0 +1,1045 @@
1+---
2+sort: 2
3+next: true
4+title: Tutorial
5+---
6+
7+# Nock tutorial
8+
9+So let's learn Nock! But wait - why learn Nock? After all,
10+we're going to be programming in Hoon, not Nock.
11+
12+Like JVM bytecode, Nock is as inscrutable as assembly language.
13+In fact, you can think of it as a sort of "functional assembly
14+language." There are sometimes reasons to program in real
15+assembly language. There is never a reason to program in Nock.
16+Except to learn Nock.
17+
18+Indeed, it is not necessary for the Hoon programmer to learn
19+Nock. We recommend it strongly, however, because Hoon has a very
20+special relationship with Nock - not unlike the relationship
21+between C and assembly language.
22+
23+Just as C is a very shallow layer over the raw CPU, Hoon is a
24+very shallow layer over raw Nock - often little more than a
25+macro. If you try to learn C without understanding the CPU under
26+it, you will be forever bemused by why it works the way it does.
27+
28+So let's learn Nock! But wait - which Nock? Nock, though more
29+frozen than Walt Disney, does have versions. Nock versions are
30+measured by integer degrees Kelvin, newer being colder. The
31+newest, Nock 5K - roughly the temperature of Neptune. No change
32+is anticipated between 5K and absolute zero, though you never
33+know. Any such change would certainly be quite painful.
34+
35+#1.1 Definition#
36+
37+The best way to learn Nock is to read the spec and write your own
38+naive interpreter. Here is Nock 5K:
39+
40+**1. Structures**
41+
42+ A noun is an atom or a cell. An atom is a natural number.
43+ A cell is an ordered pair of nouns.
44+
45+**2. Pseudocode**
46+
47+ 1 :: nock(a) *a
48+ 2 :: [a b c] [a [b c]]
49+ 3 ::
50+ 4 :: ?[a b] 0
51+ 5 :: ?a 1
52+ 6 :: +[a b] +[a b]
53+ 7 :: +a 1 + a
54+ 8 :: =[a a] 0
55+ 9 :: =[a b] 1
56+ 10 :: =a =a
57+ 11 ::
58+ 12 :: /[1 a] a
59+ 13 :: /[2 [a b]] a
60+ 14 :: /[3 [a b]] b
61+ 15 :: /[(a + a) b] /[2 /[a b]]
62+ 16 :: /[(a + a + 1) b] /[3 /[a b]]
63+ 17 :: /a /a
64+ 18 ::
65+ 19 :: *[a [[b c] d]] [*[a [b c]] *[a d]]
66+ 20 ::
67+ 21 :: *[a [0 b]] /[b a]
68+ 22 :: *[a [1 b]] b
69+ 23 :: *[a [2 [b c]]] *[*[a b] *[a c]]
70+ 24 :: *[a [3 b]] ?*[a b]
71+ 25 :: *[a [4 b]] +*[a b]
72+ 26 :: *[a [5 b]] =*[a b]
73+ 27 ::
74+ 28 :: *[a [6 [b [c d]]]] *[a 2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]
75+ 29 :: *[a [7 [b c]]] *[a 2 b 1 c]
76+ 30 :: *[a [8 [b c]]] *[a 7 [[7 [0 1] b] 0 1] c]
77+ 31 :: *[a [9 [b c]]] *[a 7 c 2 [0 1] 0 b]
78+ 32 :: *[a [10 [[b c] d]]] *[a 8 c 7 [0 3] d]
79+ 33 :: *[a [10 [b c]]] *[a c]
80+ 34 ::
81+ 35 :: *a *a
82+
83+Your interpreter should be no more than a page of code in
84+any language. For extra credit, `6`-`10` are macros; implement
85+them directly. For extra extra credit, optimize tail calls.
86+To test your code, write a decrement formula b such that
87+`*[a b]` is `a - 1` for any atomic nonzero `a`.
88+
89+#1.2 Installation#
90+
91+The second best way to learn Nock is to boot up your own Arvo
92+virtual computer. See the Arvo tutorial for instructions.
93+
94+#1.3 Nock#
95+
96+To make Nock make sense, let's work through Nock 5K line by line.
97+First the data model:
98+
99+##1. Structures##
100+
101+ A noun is an atom or a cell. An atom is any natural number.
102+ A cell is any ordered pair of nouns.
103+
104+Nouns are the dumbest data model ever. Nouns make JSON look like
105+XML and XML look like ASN.1. It may also remind you of Lisp's
106+S-expressions - you can think of nouns as "S-expressions without
107+the S."
108+
109+To be exact, a noun _is_ an S-expression, except that classic
110+S-expressions have multiple atom types ("S" is for "symbol").
111+Since Nock is designed to be used with a higher-level type system
112+(such as Hoon's), it does not need low-level types. An atom is
113+just an unsigned integer of any size.
114+
115+For instance, it's common to represent strings (or even whole
116+text files) as atoms, arranging them LSB first - so "foo" becomes
117+`0x6f6f66`. How do we know to print this as "foo", not `0x6f6f66`?
118+We need external information - such as a Hoon type. Similarly,
119+other common atomic types - signed integers, floating point, etc
120+- are all straightforward to map into atoms.
121+
122+It's also important to note that, unlike Lisp, Nock cannot create
123+cyclical data structures. It is normal and common for nouns in a
124+Nock runtime system to have acyclic structure - shared subtrees.
125+But there is no Nock computation that can make a child point to
126+its parent. One consequence: Nock has no garbage collector.
127+(Nor can dag structure be detected, as with Lisp `eq`.)
128+
129+There is also no single syntax for nouns. If you have nouns you
130+have Nock; if you have Nock you have Hoon; if you have Hoon, you
131+can write whatever parser you like.
132+
133+Let's continue:
134+
135+##2. Pseudocode##
136+
137+It's important to recognize that the pseudocode of the Nock spec
138+is just that: pseudocode. It looks a little like Hoon. It isn't
139+Hoon - it's just pseudocode. Or in other words, just English.
140+At the bottom of every formal system is a system of axioms, which
141+can only be written in English. (Why pseudocode, not Hoon? Since
142+Hoon is defined in Nock, this would only give a false impression
143+of nonexistent precision.)
144+
145+The logic of this pseudocode is a pattern-matching reduction,
146+matching from the top down. To compute Nock, repeatedly reduce
147+with the first line that matches. Let's jump right in!
148+
149+##Line 1:##
150+
151+ 1 :: nock(a) *a
152+
153+Nock is a pure (stateless) function from noun to noun. In our
154+pseudocode (and only in our pseudocode) we express this with the
155+prefix operator `*`.
156+
157+This function is defined for every noun, but on many nouns it
158+does nothing useful. For instance, if `a` is an atom, `*a`
159+reduces to... `*a`. In theory, this means that Nock spins
160+forever in an infinite loop. In other words, Nock produces no
161+result - and in practice, your interpreter will stop.
162+
163+(Another way to see this is that Nock has "crash-only" semantics.
164+There is no exception mechanism. The only way to catch Nock
165+errors is to simulate Nock in a higher-level virtual Nock -
166+which, in fact, we do all the time. A simulator (or a practical
167+low-level interpreter) can report, out of band, that Nock would
168+not terminate. It cannot recognize all infinite loops, of
169+course, but it can catch the obvious ones - like `*42`.)
170+
171+Normally `a` in `nock(a)` is a cell `[s f]`, or as we say
172+
173+ [subject formula]
174+
175+Intuitively, the formula is your function and the subject is
176+its argument. We call them something different because Hoon,
177+or any other high-level language built on Nock, will build its
178+own function calling convention which *does not* map directly
179+to `*[subject formula]`.
180+
181+##Line 2:##
182+
183+ 2 :: [a b c] [a [b c]]
184+
185+Ie, brackets (in our pseudocode, as in Hoon) associate to the
186+right. For those with Lisp experience, it's important to note
187+that Nock and Hoon use tuples or "improper lists" much more
188+heavily than Lisp. The list terminator, normally 0, is never
189+automatic. So the Lisp list
190+
191+ (a b c)
192+
193+becomes the Nock noun
194+
195+ [a b c 0]
196+
197+which is equivalent to
198+
199+ [a [b [c 0]]]
200+
201+Note that we can and do use unnecessary brackets anyway, for
202+emphasis.
203+
204+Let's move on to the axiomatic functions.
205+
206+##Lines 4-10:##
207+
208+ 4 :: ?[a b] 0
209+ 5 :: ?a 1
210+ 6 :: +[a b] +[a b]
211+ 7 :: +a 1 + a
212+ 8 :: =[a a] 0
213+ 9 :: =[a b] 1
214+
215+Here we define more pseudocode operators, which we'll use in
216+reductions further down. So far we have four built-in functions:
217+`*` meaning Nock itself, `?` testing whether a noun is a cell or
218+an atom, `+` incrementing an atom, and `=` testing for equality.
219+Again, no rocket science here.
220+
221+We should note that in Nock and Hoon, `0` (pronounced "yes") is
222+true, and `1` ("no") is false. Why? It's fresh, it's different,
223+it's new. And it's annoying. And it keeps you on your toes.
224+And it's also just intuitively right.
225+
226+
227+##Lines 12-16:##
228+
229+ 12 :: /[1 a] a
230+ 13 :: /[2 a b] a
231+ 14 :: /[3 a b] b
232+ 15 :: /[(a + a) b] /[2 /[a b]]
233+ 16 :: /[(a + a + 1) b] /[3 /[a b]]
234+
235+Slightly more interesting is our tree numbering. Every noun is of course a tree. The `/` operator - pronounced
236+"slot" - imposes an address space on that tree, mapping every
237+nonzero atom to a tree position.
238+
239+1 is the root. The head of every node `n` is `2n`; the tail is
240+`2n+1`. Thus a simple tree:
241+
242+ 1
243+ 2 3
244+ 4 5 6 7
245+ 14 15
246+
247+If the value of every leaf is its tree address, this tree is
248+
249+ [[4 5] [6 14 15]]
250+
251+and, for some examples of addressing:
252+
253+ /[1 [[4 5] [6 14 15]]]
254+
255+is `[[4 5] [6 14 15]]`
256+
257+ /[2 [[4 5] [6 14 15]]]
258+
259+is `[4 5]`
260+
261+ /[3 [[4 5] [6 14 15]]]
262+
263+is `[6 14 15]`, and
264+
265+ /[7 [[4 5] [6 14 15]]]
266+
267+is `[14 15]`
268+
269+I do hope this isn't so terribly hard to follow.
270+
271+##Line 21:##
272+
273+Now we enter the definition of Nock itself - ie, the `*`
274+operator.
275+
276+ 21 :: *[a 0 b] /[b a]
277+
278+`0` is simply Nock's tree-addressing operator. Let's try it out
279+from the Arvo command line.
280+
281+Note that we're using Hoon syntax here. Since we do not use Nock
282+from Hoon all that often (it's sort of like embedding assembly in
283+C), we've left it a little cumbersome. In Hoon, instead of
284+writing `*[a 0 b]`, we write
285+
286+ .*(a [0 b])
287+
288+So, to reuse our slot example, let's try the interpreter:
289+
290+ ~tasfyn-partyv> .*([[4 5] [6 14 15]] [0 7])
291+
292+gives, while the sky remains blue and the sun rises in the east:
293+
294+ [14 15]
295+
296+Even stupider is line 21:
297+
298+##Line 21:##
299+
300+ 21 :: *[a 1 b] b
301+
302+`1` is the constant operator. It produces its argument without
303+reference to the subject. So
304+
305+ ~tasfyn-partyv> .*(42 [1 153 218])
306+
307+yields
308+
309+ [153 218]
310+
311+
312+##Line 23:##
313+
314+ 23 :: *[a 2 b c] *[*[a b] *[a c]]
315+
316+Line 22 brings us the essential magic of recursion.
317+`2` is the Nock operator. If you can compute a subject and a
318+formula, you can evaluate them in the interpreter. In most
319+fundamental languages, like Lisp, `eval` is a curiosity. But
320+Nock has no `apply` - so all our work gets done with `2`.
321+
322+Let's convert the previous example into a stupid use of `2`:
323+
324+ ~tasfyn-partyv> .*(77 [2 [1 42] [1 1 153 218]])
325+
326+with a constant subject and a constant formula, gives the same
327+
328+ [153 218]
329+
330+Like so:
331+
332+ *[77 [2 [1 42] [1 1 153 218]]]
333+
334+ 22 :: *[a 2 b c] *[*[a b] *[a c]]
335+
336+ *[*[77 [1 42]] *[77 [1 1 153 218]]]
337+
338+ 21 :: *[a 1 b] b
339+
340+ *[42 *[77 [1 1 153 218]]]
341+
342+ *[42 1 153 218]
343+
344+ [153 218]
345+
346+##Lines 24-26:##
347+
348+ 24 :: *[a 3 b] ?*[a b]
349+ 25 :: *[a 4 b] +*[a b]
350+ 26 :: *[a 5 b] =*[a b]
351+
352+In lines 23-25, we meet our axiomatic functions again:
353+
354+For instance, if `x` is a formula that calculates some product,
355+`[4 x]` calculates that product plus one. Hence:
356+
357+ ~tasfyn-partyv> .*(57 [0 1])
358+ 57
359+
360+and
361+
362+ ~tasfyn-partyv> .*([132 19] [0 3])
363+ 19
364+
365+and
366+
367+ ~tasfyn-partyv> .*(57 [4 0 1])
368+ 58
369+
370+and
371+
372+ ~tasfyn-partyv> .*([132 19] [4 0 3])
373+ 20
374+
375+If this seems obvious, you're doin' good. Finally, we jump back up
376+to line 18, the trickiest in the spec:
377+
378+##Line 19:##
379+
380+ 19 :: *[a [b c] d] [*[a b c] *[a d]]
381+
382+Um, what?
383+
384+Since Nock of an atom just crashes, the practical domain of the
385+Nock function is always a cell. Conventionally, the head of this
386+cell is the "subject," the tail is the "formula," and the result
387+of Nocking it is the "product." Basically, the subject is your
388+data and the formula is your code.
389+
390+We could write line 19 less formally:
391+
392+ *[subject [formula-x formula-y]]
393+ => [*[subject formula-x] *[subject formula-y]]
394+
395+In other words, if you have two Nock formulas `x` and `y`, a
396+formula that computes the pair of them is just `[x y]`. We can
397+recognize this because no atom is a valid formula, and
398+every formula that _does not_ use line 19 has an atomic head.
399+
400+If you know Lisp, you can think of this feature as a sort of
401+"implicit cons." Where in Lisp you would write `(cons x y)`,
402+in Nock you write `[x y]`.
403+
404+For example,
405+
406+ ~tasfyn-partyv> .*(42 [4 0 1])
407+
408+where `42` is the subject (data) and `[4 0 1]` is the formula
409+(code), happens to evaluate to `43`. Whereas
410+
411+ ~tasfyn-partyv> .*(42 [3 0 1])
412+
413+is `1`. So if we evaluate
414+
415+ ~tasfyn-partyv> .*(42 [[4 0 1] [3 0 1]])
416+
417+we get
418+
419+ [43 1]
420+
421+Except for the crash defaults (lines 6, 10, 17, and 35), we've actually
422+completed all the _essential_ aspects of Nock. The operators up
423+through 5 provide all necessary computational functionality.
424+Nock, though very simple, is actually much more complex than it
425+formally needs to be.
426+
427+Operators 6 through 10 are macros. They exist because Nock is
428+not a toy, but a practical interpreter. Let's see them all
429+together:
430+
431+##Lines 28-33:##
432+
433+ 28 :: *[a 6 b c d] *[a 2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]
434+ 29 :: *[a 7 b c] *[a 2 b 1 c]
435+ 30 :: *[a 8 b c] *[a 7 [[7 [0 1] b] 0 1] c]
436+ 31 :: *[a 9 b c] *[a 7 c 2 [0 1] 0 b]
437+ 32 :: *[a 10 [b c] d] *[a 8 c 7 [0 3] d]
438+ 33 :: *[a 10 b c] *[a c]
439+
440+Whoa! Have we entered rocket-science territory? Let's try to
441+figure out what these strange formulas do - simplest first.
442+The simplest is clearly line 33:
443+
444+ 33 :: *[a 10 b c] *[a c]
445+
446+If `x` is an atom and `y` is a formula, the formula `[10 x y]`
447+appears to be equivalent to... `y`. For instance:
448+
449+ ~tasfyn-partyv> .*([132 19] [10 37 [4 0 3]])
450+ 20
451+
452+Why would we want to do this? `10` is actually a hint operator.
453+The `37` in this example is discarded information - it is not
454+used, formally, in the computation. It may help the interpreter
455+compute the expression more efficiently, however.
456+
457+Every Nock computes the same result - but not all at the same
458+speed. What hints are supported? What do they do? Hints are a
459+higher-level convention which do not, and should not, appear in
460+the Nock spec. Some are defined in Hoon. Indeed, a naive Nock
461+interpreter not optimized for Hoon will run Hoon quite poorly.
462+When it gets the product, however, the product will be right.
463+
464+There is another reduction for hints - line 32:
465+
466+ 32 :: *[a 10 [b c] d] *[a 8 c 7 [0 3] d]
467+
468+Once we see what `7` and `8` do, we'll see that this complex hint
469+throws away an arbitrary `b`, but computes the formula `c`
470+against the subject and... throws away the product. This formula
471+is simply equivalent to `d`. Of course, in practice the product
472+of `c` will be put to some sordid and useful use. It could even
473+wind up as a side effect, though we try not to get _that_ sordid.
474+
475+(Why do we even care that `c` is computed? Because `c` could
476+crash. A correct Nock cannot simply ignore it, and treat both
477+variants of `10` as equivalent.)
478+
479+We move on to the next simplest operator, `7`. Line 29:
480+
481+ 29 :: *[a 7 b c] *[a 2 b 1 c]
482+
483+Suppose we have two formulas, `b` and `c`. What is the formula
484+`[7 b c]`? This example will show you:
485+
486+ ~tasfyn-partyv> .*(42 [7 [4 0 1] [4 0 1]])
487+ 44
488+
489+`7` is an old mathematical friend, function composition. It's
490+easy to see how this is built out of `2`. The data to evaluate
491+is simply `b`, and the formula is `c` quoted.
492+
493+Line 30 looks very similar:
494+
495+ 30 :: *[a 8 b c] *[a 7 [[7 [0 1] b] 0 1] c]
496+
497+Indeed, `8` is `7`, except that the subject for `c` is not simply
498+the product of `b`, but the ordered pair of the product of `b`
499+and the original subject. Hence:
500+
501+ ~tasfyn-partyv> .*(42 [8 [4 0 1] [0 1]])
502+ [43 42]
503+
504+and
505+
506+ ~tasfyn-partyv> .*(42 [8 [4 0 1] [4 0 3]])
507+ 43
508+
509+Why would we want to do this? Imagine a higher-level language
510+in which the programmer declares a variable. This language is
511+likely to generate an `8`, because the variable is computed
512+against the present subject, and used in a calculation which
513+depends both on the original subject and the new variable.
514+
515+For extra credit, explain why we can't just define
516+
517+ *[a 8 b c] *[a 7 [b 0 1] c]
518+
519+Another simple macro is line 31:
520+
521+ 31 :: *[a 9 b c] *[a 7 c 2 [0 1] 0 b]
522+
523+`9` is a calling convention. With `c`, we produce a noun which
524+contains both code and data - a _core_. We use this core as the
525+subject, and apply the formula within it at slot `b`.
526+
527+And finally, we come to the piece de resistance - line 28:
528+
529+ 28 :: *[a 6 b c d] *[a 2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]
530+
531+Great giblets! WTF is this doing? It seems we've finally
532+arrived at some real rocket science.
533+
534+Actually, `6` is a primitive known to every programmer - good old
535+"if." If `b` evaluates to `0`, we produce `c`; if `b` evaluates
536+to `1`, we produce `d`; otherwise, we crash.
537+
538+For instance:
539+
540+ ~tasfyn-partyv> .*(42 [6 [1 0] [4 0 1] [1 233]])
541+ 43
542+
543+and
544+
545+ ~tasfyn-partyv> .*(42 [6 [1 1] [4 0 1] [1 233]])
546+ 233
547+
548+In real life, of course, the Nock implementor knows that `6` is
549+"if" and implements it as such. There is no practical sense in
550+reducing through this macro, or any of the others. We could have
551+defined "if" as a built-in function, like increment - except that
552+we can write "if" as a macro. If a funky macro.
553+
554+It's a good exercise, however, to peek inside the funk.
555+
556+We can actually simplify the semantics of `6`, at the expense of
557+breaking the system a little, by creating a macro that works as
558+"if" only if `b` is a proper boolean and produces `0` or `1`.
559+Perhaps we have a higher-level type system which checks this.
560+
561+This simpler "if" would be:
562+
563+ *[a 6 b c d] *[a [2 [0 1] [2 [1 c d] [[1 0] [4 4 b]]]]]
564+
565+Or without so many unnecessary brackets:
566+
567+ *[a 6 b c d] *[a 2 [0 1] 2 [1 c d] [1 0] [4 4 b]]
568+
569+How does this work? We've replaced `[6 b c d]` with the formula
570+`[2 [0 1] [2 [1 c d] [[1 0] [4 4 b]]]]`. We see two uses of `2`,
571+our evaluation operator - an outer and an inner.
572+
573+Call the inner one `i`. So we have `[2 [0 1] i]`. Which means
574+that, to calculate our product, we use `[0 1]` - that is, the
575+original subject - as the subject; and the product of `i` as
576+the formula.
577+
578+Okay, cool. So `i` is `[2 [1 c d] [[1 0] [4 4 b]]]`. We compute
579+Nock with subject `[1 c d]`, formula `[[1 0] [4 4 b]]`.
580+
581+Obviously, `[1 c d]` produces just `[c d]` - that is, the ordered
582+pair of the "then" and "else" formulas. `[[1 0] [4 4 b]]` is a
583+line 19 cell - its head is `[1 0]`, producing just `0`, its tail
584+`[4 4 b]`, producing... what? Well, if `[4 b]` is `b` plus `1`,
585+`[4 4 b]` is `b` plus `2`.
586+
587+We're assuming that `b` produces either `0` or `1`. So `[4 4 b]`
588+yields either `2` or `3`. `[[1 0] [4 4 b]]` is either `[0 2]` or
589+`[0 3]`. Applied to the subject `[c d]`, this gives us either
590+`c` or `d` - the product of our inner evaluation `i`. This is
591+applied to the original subject, and the result is "if."
592+
593+But we need the full power of the funk, because if `b` produces,
594+say, `7`, all kinds of weirdness will result. We'd really like
595+`6` to just crash if the test product is not a boolean. How can
596+we accomplish this? This is an excellent way to prove to
597+yourself that you understand Nock: figure out what the real `6`
598+does. Or you could just agree that `6` is "if," and move on.
599+
600+(It's worth noting that in practical, compiler-generated Nock, we
601+never do anything as funky as these `6` macro internals. There's
602+no reason we couldn't build formulas at runtime, but we have no
603+reason to and we don't - except when actually metaprogramming.
604+As in most languages, normally code is code and data is data.)
605+
606+#1.4 Decrement in Nock#
607+
608+A good practice exercise for Nock is a decrement formula. Ie, a
609+formula `f` which implements the partial function that produces
610+`(s - 1)` if `s` is a nonzero atom, and otherwise does not
611+terminate.
612+
613+The normal Hoon programmer has written one Nock formula: this
614+one. Since decrement uses all the Nock techniques the Hoon
615+compiler uses, the exercise is a good foundation. After you
616+write decrement (or just follow this example), you'll never need
617+to deal with Nock again.
618+
619+As we know, the equivalent formula for increment is
620+
621+ [4 0 1]
622+
623+Thus:
624+
625+ ~>tasfyn-partyv .*(42 [4 0 1])
626+ 43
627+
628+Of course, increment is built into Nock. So, ha, that's easy.
629+
630+How do we decrement? A good way to start is to gaze fondly on
631+how we'd do it if we actually had a real language, ie, Hoon.
632+Here is a minimal decrement in Hoon:
633+
634+ => a=. :: line 1
635+ =+ b=0 :: line 2
636+ |- :: line 3
637+ ?: =(a +(b)) :: line 4
638+ b :: line 5
639+ $(b +(b)) :: line 6
640+
641+Or for fun, on one line:
642+
643+ =>(a=. =+(b=0 |-(?:(=(a +(b)) b $(b +(b))))))
644+
645+Does Hoon actually work?
646+
647+ ~tasfyn-partyv> =>(42 =>(a=. =+(b=0 |-(?:(=(a +(b)) b $(b +(b)))))))
648+ 41
649+
650+Let's translate this into English. How do we decrement the
651+subject? First (line 1), we rename the subject `a`. Second
652+(line 2), we add a variable, `b`, an atom with value `0`.
653+Third (line 3), we loop. Fourth, we test if `a` equals `b` plus
654+1 (line 4), produce `b` if it does (line 5), repeat the loop with
655+`b` set to `b` plus 1 (line 6) if it doesn't. Obviously, while
656+the syntax is unusual, the algorithm is anything but deep. We
657+are calculating `b` minus one by counting up from `0`.
658+
659+(Obviously, this is an O(n) algorithm. Is there a better way?
660+There is not. Do we actually do this in practice? Yes and no.)
661+
662+Unfortunately we are missing a third of our Rosetta stone. We
663+have decrement in Hoon and we have it in English. How do we
664+express this in Nock? What will the Hoon compiler generate from
665+the code above? Let's work through it line by line.
666+
667+Nock has no types, variable names, etc. So line 1 is a no-op.
668+
669+How do we add a variable (line 2)? We compute a new subject,
670+which is a cell of the present subject and the variable. With
671+this new subject, we execute another formula.
672+
673+Since `0` is a constant, a formula that produces it is
674+
675+ [1 0]
676+
677+To combine `0` with the subject, we compute
678+
679+ [[1 0] [0 1]]
680+
681+which, if our subject is 42, gives us
682+
683+ [0 42]
684+
685+which we can use as the subject for an inner formula, `g`.
686+Composing our new variable with `g`, we have `f` as
687+
688+ [2 [[1 0] [0 1]] [1 g]]
689+
690+which seems a little funky for something so simple. But we
691+can simplify it with the composition macro, `7`:
692+
693+ [7 [[1 0] [0 1]] g]
694+
695+and still further with the augmentation macro, `8`:
696+
697+ [8 [1 0] g]
698+
699+If you refer back to the Nock definition, you'll see that all
700+these formulas are semantically equivalent.
701+
702+Let's continue with our decrement. So what's `g`? We seem to
703+loop. Does Nock have a loop operator? It most certainly does
704+not. So what do we do?
705+
706+We build a noun called a _core_ - a construct which is behind any
707+kind of interesting control flow in Hoon. Of course, the Nock
708+programmer is not constrained to use the same techniques as the
709+Hoon compiler, but it is probably a good idea.
710+
711+In Hoon, all the flow structures from your old life as an Earth
712+programmer become cores. Functions and/or closures are cores,
713+objects are cores modules are cores, even loops are cores.
714+
715+The core is just a cell whose tail is data (possibly containing
716+other cores) and whose head is code (containing one or more
717+formulas). The tail is the _payload_ and the head is the
718+_battery_. Hence your core is
719+
720+ [bat pay]
721+
722+To activate a core, pick a formula out of the battery, and use
723+the entire core (_not_ just the payload) as the subject.
724+
725+(A core formula is called an _arm_. An arm is almost like an
726+object-oriented method, but not quite - a method would be an arm
727+that produces a function on an argument. The arm is just a
728+function of the core, ie, a computed attribute.)
729+
730+Of course, because we feed it the entire core, our arm can
731+invoke itself (or any other formula in the battery). Hence, it
732+can loop. And this is what a loop is - the simplest of cores.
733+
734+We need to do two things with this core: create it, and activate
735+it. To be precise, we need two formulas: a formula which
736+produces the core, and one which activates its subject. We can
737+compose these functions with the handy `7` operator:
738+
739+ [8 [1 0] [7 p a]]
740+
741+`p` produces our core, `a` activates it. Let's take these in
742+reverse order. How do we activate a core?
743+
744+Since we have only one formula, it's the battery itself.
745+Thus we want to execute Nock with the whole core (already the
746+subject, and the entire battery (slot `2`). Hence, `a` is
747+
748+ [2 [0 1] [0 2]]
749+
750+We could also use the handy `9` macro - which almost seems
751+designed for firing arms on cores:
752+
753+ [9 2 [0 1]]
754+
755+Which leaves us seeking
756+
757+ [8 [1 0] [7 p [9 2 0 1]]]
758+
759+And all we have to do is build the core, `p`. How do we build a
760+core? We add code to the subject, just as we added a variable
761+above. The initial value of our counter was a constant, `0`.
762+The initial (and permanent) value of our battery is a constant,
763+the loop formula `l`. So `p` is
764+
765+ [8 [1 l] [0 1]]
766+
767+Which would leave us seeking
768+
769+ [8 [1 0] [7 [8 [1 l] [0 1]] [9 2 0 1]]]
770+
771+except that we have duplicated the `8` pattern again, since we
772+know
773+
774+ [7 [8 [1 l] [0 1]] [9 2 0 1]]
775+
776+is equivalent to
777+
778+ [8 [1 l] [9 2 0 1]]
779+
780+so the full value of `f` is
781+
782+ [8 [1 0] [8 [1 l] [9 2 0 1]]]
783+
784+Thus our only formula to compose is the loop body, `l`.
785+Its subject is the loop core:
786+
787+ [bat pay]
788+
789+where `bat` is just the loop formula, and `pay` is the pair `[a
790+b]`, `a` being the input subject, and `b` the counter. Thus we
791+could also write this subject as
792+
793+ [l b a]
794+
795+and we see readily that `a` is at slot `7`, `b` `6`, `l` `2`.
796+With this subject, we need to express the Hoon loop body
797+
798+ ?: =(a +(b)) :: line 4
799+ b :: line 5
800+ $(b +(b)) :: line 6
801+
802+This is obviously an if statement, and it calls for `6`. Ie:
803+
804+ [6 t y n]
805+
806+Giving our decrement program as:
807+
808+ [8 [1 0] [8 [1 6 t y n] [9 2 0 1]]]
809+
810+For `t`, how do we compute a flag that is yes (`0`) if `a` equals
811+`b` plus one? Equals, we recall, is `5`. So `t` can only be
812+
813+ [5 [0 7] [4 0 6]]
814+
815+If so, our product `y` is just the counter `b`:
816+
817+ [0 6]
818+
819+And if not? We have to re-execute the loop with the counter
820+incremented. If we were executing it with the same counter,
821+obviously an infinite loop, we could use the same core:
822+
823+ [9 2 0 1]
824+
825+But instead we need to construct a new core with the counter
826+incremented:
827+
828+ [l +(b) a]
829+
830+ie,
831+
832+ [[0 2] [4 0 6] [0 7]]
833+
834+and `n` is:
835+
836+ [9 2 [[0 2] [4 0 6] [0 7]]]
837+
838+Hence our complete decrement. Let's reformat vertically so we
839+can actually read it:
840+
841+ [8
842+ [1 0]
843+ [ 8
844+ [ 1
845+ [ 6
846+ t
847+ y
848+ n
849+ ]
850+ ]
851+ [9 2 0 1]
852+ ]
853+ ]
854+
855+which becomes
856+
857+ [8
858+ [1 0]
859+ [ 8
860+ [ 1
861+ [ 6
862+ [5 [0 7] [4 0 6]]
863+ [0 6]
864+ [9 2 [[0 2] [4 0 6] [0 7]]]
865+ ]
866+ ]
867+ [9 2 0 1]
868+ ]
869+ ]
870+
871+or, on one line without superfluous brackets:
872+
873+ [8 [1 0] 8 [1 6 [5 [0 7] 4 0 6] [0 6] 9 2 [0 2] [4 0 6] 0 7] 9 2 0 1]
874+
875+which works for the important special case, 42:
876+
877+ ~tasfyn-partyv> .*(42 [8 [1 0] 8 [1 6 [5 [0 7] 4 0 6] [0 6] 9 2 [0 2] [4 0 6] 0 7] 9 2 0 1])
878+ 41
879+
880+If you understood this, you understand Nock. At least in principle!
881+
882+If you want to play around more with Nock, the command line will
883+start getting unwieldy. Fortunately, the standard install
884+contains the above Nock decrement packaged as an Arvo app, which
885+you can edit and change if you'd like to get ambitious. Just run
886+
887+ ~tasfyn-partyv> :toy/ndec 19
888+ 18
889+
890+The file driving this is
891+
892+ hub/$seat/toy/app/ndec.holw
893+
894+Edit this file, ignoring everything above the Nock formula, and
895+hit return in the console to see it update:
896+
897+ ~tasfyn-partyv>
898+ : ~tasfyn-partyv/toy/app/ndec/holw/
899+
900+If decrement seems fun - why not write add? I wrote a Nock adder
901+a long, long time ago. But I've forgotten where I put it. There
902+is absolutely no use in this exercise, except to prove to
903+yourself that you've mastered Nock.
904+
905+#Appendix A: Operator Reductions#
906+
907+##`6` Reduction:##
908+
909+ 28 :: *[a 6 b c d] *[a 2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]
910+
911+ *[a 2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]
912+
913+ 23 :: *[a 2 b c] *[*[a b] *[a c]]
914+
915+ *[*[a 0 1] *[a 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]]
916+
917+ 21 :: *[a 0 b] /[b a]
918+
919+ *[a *[a 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]]
920+
921+ 23 :: *[a 2 b c] *[*[a b] *[a c]]
922+
923+ *[a *[*[a [1 c d]] *[a [1 0] 2 [1 2 3] [1 0] 4 4 b]]]
924+
925+ 22 :: *[a 1 b] b
926+
927+ 19 :: *[a [b c] d] [*[a b c] *[a d]]
928+
929+ *[a *[[c d] [*[a 1 0] *[a 2 [1 2 3] [1 0] 4 4 b]]]]
930+
931+ 22 :: *[a 1 b] b
932+
933+ *[a *[[c d] [0 *[a 2 [1 2 3] [1 0] 4 4 b]]]]
934+
935+ 23 :: *[a 2 b c] *[*[a b] *[a c]]
936+
937+ *[a *[[c d] [0 *[*[a [1 2 3]] *[a [1 0] 4 4 b]]]]]
938+
939+ 22 :: *[a 1 b] b
940+
941+ *[a *[[c d] [0 *[[2 3] *[a [1 0] 4 4 b]]]]]
942+
943+ 19 :: *[a [b c] d] [*[a b c] *[a d]]
944+
945+ *[a *[[c d] [0 *[[2 3] [*[a [1 0]] *[a 4 4 b]]]]]]
946+
947+ 22 :: *[a 1 b] b
948+
949+ *[a *[[c d] [0 *[[2 3] [0 *[a 4 4 b]]]]]]
950+
951+ 25 :: *[a 4 b] +*[a b]
952+
953+ *[a *[[c d] [0 *[[2 3] [0 ++*[a b]]]]]]
954+
955+**`6` Reduced:**
956+
957+ 6r :: *[a 6 b c d] *[a *[[c d] [0 *[[2 3] [0 ++*[a b]]]]]]
958+
959+##`7` Reduction:##
960+
961+ 29 :: *[a 7 b c] *[a 2 b 1 c]
962+
963+ *[a 2 b 1 c]
964+
965+ 23 :: *[a 2 b c] *[*[a b] *[a c]]
966+
967+ *[*[a b] *[a 1 c]]
968+
969+ 22: *[a 1 b] b
970+
971+ *[*[a b] c]
972+
973+**`7` Reduced:**
974+
975+ 7r :: *[a 7 b c] *[*[a b] c]
976+
977+##`8` Reduction:##
978+
979+ 30 :: *[a 8 b c] *[a 7 [[7 [0 1] b] 0 1] c]
980+
981+ *[a 7 [[7 [0 1] b] 0 1] c]
982+
983+ 7r :: *[a 7 b c] *[*[a b] c]
984+
985+ *[*[a [7 [0 1] b] 0 1]] c]
986+
987+ 19 :: *[a [b c] d] [*[a b c] *[a d]]
988+
989+ *[[*[a [7 [0 1] b]] *[a 0 1]] c]
990+
991+ 21 :: *[a 0 b] /[b a]
992+
993+ *[[*[a [7 [0 1] b]] /[1 a]] c]
994+
995+ 12 :: /[1 a] a
996+
997+ *[[*[a [7 [0 1] b]] a] c]
998+
999+ 7r :: *[a 7 b c] *[*[a b] c]
1000+
1001+ *[[*[*[a 0 1]] b] a] c]
1002+
1003+**`8` Reduced:**
1004+
1005+ 8r :: *[a 8 b c] *[[*[a b] a] c]
1006+
1007+
1008+##`9` Reduction:##
1009+
1010+ 31 :: *[a 9 b c] *[a 7 c [2 [0 1] [0 b]]]
1011+
1012+ *[a 7 c [2 [0 1] [0 b]]]
1013+
1014+ 7r :: *[a 7 b c] *[*[a b] c]
1015+
1016+ *[*[a c] [2 [0 1] [0 b]]]
1017+
1018+ 23 :: *[a 2 b c] *[*[a b] *[a c]]
1019+
1020+ *[*[*[a c] [0 1]] *[*[a c] [0 b]]]
1021+
1022+ 21 :: *[a 0 b] /[b a]
1023+
1024+**`9` Reduced:**
1025+
1026+ 9r :: *[a 9 b c] *[*[a c] *[*[a c] 0 b]]
1027+
1028+
1029+##`10` Reduction:##
1030+
1031+ *[a 10 [b c] d] *[a 8 c 7 [0 3] d]
1032+
1033+ 8r :: *[a 8 b c] [[*[a b] a] c]
1034+
1035+ *[[*[a c] a] 7 [0 2] d]
1036+
1037+ 7r :: *[a 7 b c] *[*[a b] c]
1038+
1039+ *[*[[*[a c] a] 0 3] d]
1040+
1041+ 21 :: *[a 0 b] /[b a]
1042+
1043+**`10` reduced:**
1044+
1045+ 10r :: *[a 10 [b c] d] *[a d]