on master help sign in
copy editing and added back nock docs
447c2cbGalen Wolfe-Pauly
docs/programming/arvo/system/api.md+4−2
@@ -4,6 +4,8 @@ sort: 12
4title: API Connectors
4title: API Connectors
5---
5---
6
6
7+# API Connectors
8+
7Most people have lots of data stored in online services, many of
9Most people have lots of data stored in online services, many of
8which have APIs. API connectors allow the user to access this
10which have APIs. API connectors allow the user to access this
9data from within their Urbit.
11data from within their Urbit.
@@ -65,7 +67,7 @@ drifts out of sync with this doc).
65We'll go over the two parts to an API connector (one-time reading vs listening
67We'll go over the two parts to an API connector (one-time reading vs listening
66for events) separately.
68for events) separately.
67
69
68−# Reading
70+## Reading
69
71
70A connector exposes a tree of data. Every read request has a
72A connector exposes a tree of data. Every read request has a
71`care`, which is generally either `%x` or `%y. `%x` is a request
73`care`, which is generally either `%x` or `%y. `%x` is a request
@@ -156,7 +158,7 @@ control. There are four functions we need to define:
156That's really all there is to the reading portion of API
158That's really all there is to the reading portion of API
157connectors.
159connectors.
158
160
159−# Listening
161+## Listening
160
162
161Listening for events is fairly service-specific. In some
163Listening for events is fairly service-specific. In some
162services, we poll for changes. For an example of that, check out
164services, we poll for changes. For an example of that, check out
docs/programming/arvo/system/security-driver.md+5−1
@@ -4,6 +4,8 @@ sort: 10
4title: Security Drivers
4title: Security Drivers
5---
5---
6
6
7+# Security Drivers
8+
7A security driver is a file in `/=home=/sec/<tld>/<domain>/hoon`
9A security driver is a file in `/=home=/sec/<tld>/<domain>/hoon`
8that handles the authentication for all HTTP requests to
10that handles the authentication for all HTTP requests to
9`https://<domain>.<tld>`. All requests to the domain are
11`https://<domain>.<tld>`. All requests to the domain are
@@ -44,6 +46,8 @@ endpoints won't be accessible, or they will only have publicly
44accessible information. Most of what we care about requires us
46accessible information. Most of what we care about requires us
45to be authenticated.
47to be authenticated.
46
48
49+## Basic auth
50+
47Here's a simple security driver:
51Here's a simple security driver:
48
52
49```
53```
@@ -144,7 +148,7 @@ the driver. In our case, that's
144encrypted, and you don't want to edit them directly. `%eyre`
148encrypted, and you don't want to edit them directly. `%eyre`
145loads them directly into your `bale`.
149loads them directly into your `bale`.
146
150
147−# OAuth2
151+## OAuth2
148
152
149Most services are better accessed through some form of OAuth.
153Most services are better accessed through some form of OAuth.
150Github can be accessed with OAuth2, which is a little more
154Github can be accessed with OAuth2, which is a little more
docs/programming/nock/nock.md → docs/programming/nock/interpreter.mdrenamed+3−3
@@ -1,5 +1,5 @@
1---
1---
2−sort: 5
2+sort: 1
3next: true
3next: true
4title: Interpreter
4title: Interpreter
5---
5---
@@ -54,7 +54,7 @@ can detect this crash and produce an out-of-band value instead.
54*[a 4 b] +*[a b]
54*[a 4 b] +*[a b]
55*[a 5 b] =*[a b]
55*[a 5 b] =*[a b]
56
56
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]
58 2 [1 2 3] [1 0] 4 4 b]
58 2 [1 2 3] [1 0] 4 4 b]
59*[a 7 b c] *[a 2 b 1 c]
59*[a 7 b c] *[a 2 b 1 c]
60*[a 8 b c] *[a 7 [[7 [0 1] b] 0 1] c]
60*[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.
70The pseudocode notation defines five prefix operators: `?`, `+`,
70The pseudocode notation defines five prefix operators: `?`, `+`,
71`=`, `/`, and `*`.
71`=`, `/`, and `*`.
72
72
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.
74
74
75`+[x]` produces the atom `x` plus `1`.
75`+[x]` produces the atom `x` plus `1`.
76
76
docs/programming/nock/reference.mdnew file+743
@@ -0,0 +1,743 @@
1+---
2+sort: 3
3+next: true
4+title: Reference
5+---
6+
7+Nock Reference
8+==============
9+
10+Nouns
11+-----
12+
13+ 1 :: A noun is an atom or a cell.
14+ 2 :: An atom is a natural number.
15+ 3 :: A cell is an ordered pair of nouns.
16+
17+An **atom** is a natural number - ie, an unsigned integer. Nock does not
18+limit the size of **atoms**, or know what an **atom** means.
19+
20+For instance, the **atom** `97` might mean the number `97`, or it might
21+mean the letter `a` (ASCII 97). A very large **atom** might be the
22+number of grains of sand on the beach - or it might be a GIF of your
23+children playing on the beach. Typically when we represent strings or
24+files as **atoms**, the first byte is the low byte. But even this is
25+just a convention. An **atom** is an **atom**.
26+
27+A **cell** is an ordered pair of any two **nouns** - **cell** or
28+**atom**. We group cells with square brackets:
29+
30+ [1 1]
31+ [34 45]
32+ [[3 42] 12]
33+ [[1 0] [0 [1 99]]]
34+
35+*Nouns* are the dumbest data model ever. **Nouns** make JSON look like
36+XML and XML look like ASN.1. It may also remind you of Lisp's
37+S-expressions - you can think of nouns as "S-expressions without the S."
38+
39+To be exact, a *noun* is an S-expression, except that classic
40+S-expressions have multiple **atom** types ("S" is for "symbol"). Since
41+Nock is designed to be used with a higher-level type system (such as
42+Hoon's), it does not need low-level types. An **atom** is just an
43+unsigned integer of any size.
44+
45+For instance, it's common to represent strings (or even whole text
46+files) as atoms, arranging them LSB first - so "foo" becomes `0x6f6f66`.
47+How do we know to print this as "foo", not `0x6f6f66`? We need external
48+information - such as a Hoon type. Similarly, other common atomic
49+types - signed integers, floating point, etc — are all straightforward
50+to map into **atoms**.
51+
52+It's also important to note that, unlike Lisp, Nock cannot create
53+cyclical data structures. It is normal and common for **nouns** in a
54+Nock runtime system to have acyclic structure - shared subtrees. But
55+there is no Nock computation that can make a child point to its parent.
56+One consequence: Nock has no garbage collector. (Nor can dag structure
57+be detected, as with Lisp eq.)
58+
59+There is also no single syntax for **nouns**. If you have **nouns** you
60+have Nock; if you have Nock you have Hoon; if you have Hoon, you can
61+write whatever parser you like.
62+
63+------------------------------------------------------------------------
64+
65+The Nock Function
66+-----------------
67+
68+ 5 :: nock(a) *a
69+
70+Nock is a pure (stateless) function from **noun** to **noun**. In our
71+pseudocode (and only in our pseudocode) we express this with the prefix
72+operator `*`.
73+
74+A Nock program is given meaning by a process of reduction. To compute
75+`nock(x)`, where `x` is any **noun**, we step through the rules from the
76+top down, find the first left-hand side that matches `x`, and reduce it
77+to the right-hand side (in more mathematical notation, we might write
78+line 5 as `nock(a) -> *a`, a style we do use in documentation)
79+
80+When we use variable names, like `a`, in the pseudocode spec, we simply
81+mean that the rule fits for any **noun** `a`.
82+
83+So `nock(x)` is `*x`, for any **noun** `x`. And how do we reduce `*x`?
84+Looking up, we see that lines 23 through 39 reduce `*x` - for different
85+patterns of `x`.
86+
87+Normally `a` in `nock(a)` is a **cell** `[s f]`, or
88+
89+ [subject formula]
90+
91+Intuitively, the formula is your function and the subject is its
92+argument. Hoon, or any other high-level language built on Nock, will
93+build its own function calling convention which does not map directly to
94+`*[subject formula]`.
95+
96+------------------------------------------------------------------------
97+
98+Bracket Grouping
99+----------------
100+
101+ 6 :: [a b c] [a [b c]]
102+
103+Brackets associate to the right.
104+
105+So instead of writing
106+
107+ [2 [6 7]]
108+ [2 [6 [14 15]]]
109+ [2 [6 [[28 29] [30 31]]]]
110+ [2 [6 [[28 29] [30 [62 63]]]]]
111+
112+we can write
113+
114+ [2 6 7]
115+ [2 6 14 15]
116+ [2 6 [28 29] 30 31]
117+ [2 6 [28 29] 30 62 63]
118+
119+While this notational convenience is hardly rocket science, it's
120+surprising how confusing it can be, especially if you have a Lisp
121+background. Lisp's "S-expressions" are very similar to **nouns**, except
122+that Lisp has multiple types of **atom**, and Lisp's syntax
123+automatically adds list terminators to groups.
124+
125+For those with Lisp experience, it's important to note that Nock and
126+Hoon use tuples or "improper lists" much more heavily than Lisp. The
127+list terminator, normally 0, is never automatic. So the Lisp list
128+
129+ (a b c)
130+
131+becomes the Nock **noun**
132+
133+ [a b c 0]
134+
135+which is equivalent to
136+
137+ [a [b [c 0]]]
138+
139+Note that we can and do use unnecessary brackets anyway, for emphasis.
140+
141+------------------------------------------------------------------------
142+
143+Axiomatic Functions
144+-------------------
145+
146+ 8 :: ?[a b] 0
147+ 9 :: ?a 1
148+ 10 :: +[a b] +[a b]
149+ 11 :: +a 1 + a
150+ 12 :: =[a a] 0
151+ 13 :: =[a b] 1
152+
153+Here we define three of Nock's four axiomatic functions: **Cell-test**,
154+**Increment** and **Equals** (the fourth axiomatic function, called
155+**Address**, is defined in lines 16 through 21). These functions are
156+just pseudocode, not actual Nock syntax, and are only used to define the
157+behaviour of certain Nock operators.
158+
159+We should note that in Nock and Hoon, `0` (pronounced "yes") is true,
160+and `1` ("no") is false. This convention is the opposite of
161+old-fashioned booleans, so we try hard to say "yes" and "no" instead of
162+"true" and "false."
163+
164+------------------------------------------------------------------------
165+
166+### Cell-test `?`
167+
168+`?` (pronounced "wut") tests whether is a **noun** is a **cell**. Again,
169+`0` means "yes", `1` means "no":
170+
171+ 8 :: ?[a b] 0
172+ 9 :: ?a 1
173+
174+------------------------------------------------------------------------
175+
176+### Increment `+`
177+
178+`+` (pronounced "lus") adds `1` to an **atom**:
179+
180+ 10 :: +[a b] +[a b]
181+ 11 :: +a 1 + a
182+
183+------------------------------------------------------------------------
184+
185+### Equals `=`
186+
187+`=` (pronounced "tis") tests a cell for equality. `0` means "yes", `1`
188+means "no":
189+
190+ 12 :: =[a a] 0
191+ 13 :: =[a b] 1
192+ 14 :: =a =a
193+
194+Testing an **atom** for equality makes no sense and logically fails to
195+terminate.
196+
197+Because `+` works only for **atoms**, whereas `=` works only for
198+**cells**, the error rules match first for `+` and last for `=`.
199+
200+------------------------------------------------------------------------
201+
202+Noun Address
203+------------
204+
205+ 16 :: /[1 a] a
206+ 17 :: /[2 a b] a
207+ 18 :: /[3 a b] b
208+ 19 :: /[(a + a) b] /[2 /[a b]]
209+ 20 :: /[(a + a + 1) b] /[3 /[a b]]
210+ 21 :: /a /a
211+
212+We define a **noun** as a binary tree - where each node branches to a
213+left and right child - and assign an address, or **axis**, to every
214+element in the tree. The root of the tree is `/1`. The left child
215+(**head**) of every node at `/a` is `/2a`; the right child (**tail**) is
216+`/2a+1`. (Writing `(a + a)` is just a clever way to write `2a`, while
217+minimizing the set of pseudocode forms.)
218+
219+`1` is the root. The **head** of every **axis** `n` is `2n`; the
220+**tail** is `2n+1`. Thus a simple tree:
221+
222+ 1
223+ 2 3
224+ 4 5 6 7
225+ 14 15
226+
227+If the value of every leaf is its tree address, this tree is
228+
229+ [[4 5] [6 14 15]]
230+
231+Let's use the example `[[97 2] [1 42 0]]`. So
232+
233+ /[1 [97 2] [1 42 0]] -> [[97 2] [1 42 0]]
234+
235+because `/1` is the root of the tree, ie, the whole **noun**.
236+
237+Its left child (**head**) is `/2` (i.e. `(1 + 1)`):
238+
239+ /[2 [97 2] [1 42 0]] -> [97 2]
240+
241+And its right child (**tail**) is `/3` (i.e. `(1 + 1 + 1)`):
242+
243+ /[3 [97 2] [1 42 0]] -> [1 42 0]
244+
245+And delving into `/3`, we see `/(3 + 3)` and `/(3 + 3 + 1)`:
246+
247+ /[6 [97 2] [1 42 0]] -> 1
248+ /[7 [97 2] [1 42 0]] -> [42 0]
249+
250+It's also fun to build nouns in which every atom is its own axis:
251+
252+ 1
253+ [2 3]
254+ [2 6 7]
255+ [[4 5] 6 7]
256+ [[4 5] 6 14 15]
257+ [[4 5] [12 13] 14 15]
258+ [[4 [10 11]] [12 13] 14 15]
259+ [[[8 9] [10 11]] [12 13] 14 30 31]
260+
261+------------------------------------------------------------------------
262+
263+Distribution
264+------------
265+
266+ 23 :: *[a [b c] d] [*[a b c] *[a d]]
267+
268+The practical domain of the Nock function is always a **cell**. When `a`
269+is an **atom**, `*a`, or `nock(a)`, is always an error. Conventionally,
270+Nock proper is always a function of a **cell**. The **head** of this
271+**cell** is the **subject**, the **tail** is the **formula**
272+
273+ [subject formula]
274+
275+and the result of passing a **noun** through the Nock function is called
276+the **product**.
277+
278+ nock([subject formula]) => product
279+
280+or
281+
282+ *[subject formula] => product
283+
284+The **subject** is your data and the **formula** is your code. And the
285+**product** is your code's output.
286+
287+Notice that `a` in the Nock rules is always the **subject**, except line
288+39, which is a crash default for malformed **nouns** that do not
289+evaluate.
290+
291+A **formula** is always a **cell**. But when we look inside that
292+**cell**, we see two basic kinds of **formulas**:
293+
294+ [operator operands]
295+ [formula-x formula-y]
296+
297+An **operator** is always an **atom** (`0` through `10`). A **formula**
298+is always a **cell**. Line 23 distinguishes these forms:
299+
300+ 23 :: *[a [b c] d] [*[a b c] *[a d]]
301+
302+If your code contains multiple **formulas**, the **subject** will
303+distribute over those **formulas**.
304+
305+In other words, if you have two Nock **formulas** `x` and `y`, a
306+**formula** that computes the pair of them is just the **cell** `[x y]`.
307+
308+ *[subject [x y]] -> [*[subject x] *[subject y]]
309+
310+No **atom** is a valid **formula**, and every **formula** that does not
311+use line 23 has an atomic **head**.
312+
313+Suppose you have two **formulas** `f` and `g`, each of which computes
314+some function of the **subject** `s`. You can then construct the
315+**formula** `h` as `[f g]`; and `h(s) = [f(s) g(s)]`.
316+
317+For example:
318+
319+ *[[19 42] [0 3] 0 2]
320+
321+The **subject** `s` is `[19 42]`. The **formula** `h` is `[[0 3] 0 2]`.
322+
323+ *[s h]
324+
325+The **head** of `h` is `f`, which is `[0 3]`. The **tail** of `h` is
326+`g`, which is `[0 2]`.
327+
328+ *[s [f g]]
329+
330+by the distribution rule, `*[s [f g]]` is
331+
332+ [*[s f] *[s g]]
333+
334+or
335+
336+ [*[[19 42] [0 3]] *[[19 42] 0 2]]
337+
338+`*[s f]` is `f(s)` and produces `42`. `*[s g]` is `g(s)` and produces
339+19.
340+
341+Since `h(s)` is `[f(s) g(s)]`, `h(s)` is `[42 19]`:
342+
343+ *[[19 42] [0 3] 0 2] -> [42 19]
344+
345+------------------------------------------------------------------------
346+
347+Operator 0: Axis
348+----------------
349+
350+ 25 :: *[a 0 b] /[b a]
351+
352+Operator 0 is Nock's tree address or **axis** operator, using the tree
353+addressing structure defined in lines 16 through 20. `*[a 0 b]` simply
354+returns the value of the part of `a` at **axis** `b`. For any subject
355+`a`, the formula `[0 b]` produces `/[b a]`.
356+
357+For example,
358+
359+ *[[19 42] 0 3] -> /[3 19 42] -> 42.
360+
361+------------------------------------------------------------------------
362+
363+Operator 1: Just
364+----------------
365+
366+ 26 :: *[a 1 b] b
367+
368+`1` is the constant, or **Just operator**. It produces its operand `b`
369+without reference to the **subject**.
370+
371+For example,
372+
373+ *[42 1 57] -> 57
374+
375+**Operator 1** is named **Just** because it produces "just" its operand.
376+
377+------------------------------------------------------------------------
378+
379+Operator 2: Fire
380+----------------
381+
382+ 27 :: *[a 2 b c] *[*[a b] *[a c]]
383+
384+**Operator 2** is the **Fire operator**, which brings us the essential
385+magic of recursion. Given the **formula** `[2 b c]`, `b` is a
386+**formula** for generating a new **subject**; `c` is a **formula** for
387+generating a new **formula**. To compute `*[a 2 b c]`, we evaluate both
388+`b` and `c` against the current **subject** `a`.
389+
390+A common use of **Fire** is to evaluate data inside the **subject** as
391+code.
392+
393+For example:
394+
395+ *[[[40 43] [4 0 1]] [2 [0 4] [0 3]]] -> 41
396+
397+ *[[[40 43] [4 0 1]] [2 [0 5] [0 3]]] -> 44
398+
399+**Operator 2** is called **Fire** because it "fires" Nock **formulas**
400+at its (possibly modified) **subject**.
401+
402+------------------------------------------------------------------------
403+
404+Operator 3: Depth
405+-----------------
406+
407+ 28 :: *[a 3 b] ?*[a b]
408+
409+**Operator 3** applies the **Cell-test** function defined in lines 8 and
410+9 to the product of `*[a b]`.
411+
412+**Operator 3** is called **Depth** because it tests the "depth" of a
413+noun. **Cell-test** properly refers to the pseudocode function `?`.
414+
415+------------------------------------------------------------------------
416+
417+Operator 4: Bump
418+----------------
419+
420+ 29 :: *[a 4 b] +*[a b]
421+
422+**Operator 4** applies the **Increment** function defined in lines 10
423+and 11 to the product of `*[a b]`.
424+
425+**Operator 4** is called **Bump** because it "bumps" the atomic product
426+`*[a b]` up by 1. **Increment** properly refers to the pseudocode
427+function `+`.
428+
429+------------------------------------------------------------------------
430+
431+Operator 5: Same
432+----------------
433+
434+ 30 :: *[a 5 b] =*[a b]
435+
436+**Operator 5** applies the Equals function defined in lines 12, 13 and
437+14 to the product of \*[a b].
438+
439+**Operator 5** is called the **Same** operator, because it tests if the
440+head and tail of the product of `*[a b]` are the same. "Equals" properly
441+refers to the pseudocode function "=".
442+
443+------------------------------------------------------------------------
444+
445+Operator 6: If
446+--------------
447+
448+ 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]
449+
450+**Operator 6** is a primitive known to every programmer - **If**. Its
451+operands, a **test formula** `b`, a **then formula** `c` and an **else
452+formula** `d`.
453+
454+If the **test** `b` applied to the **subject** evaluates to `0` ("yes"),
455+
456+ *[a b] -> 0
457+
458+then **If** produces the result of `c`, the **then formula**, applied to
459+the **subject**,
460+
461+ *[a c]
462+
463+Else, if applying the **test** to the **subject** produces `1` ("no"),
464+
465+ *[a b] -> 1
466+
467+**Operator 6** produces the result of `d`, the **else formula**, applied
468+to the **subject**,
469+
470+ *[a d]
471+
472+If `*[a b]` produces any value other than `0` ("yes") or `1` ("no"),
473+**If** crashes.
474+
475+Let's examine the internals of **Operator 6**:
476+
477+**If** could have been defined as a built-in pseudocode function, like
478+**Increment**:
479+
480+ :: $[0 b c] b
481+ :: $[1 b c] c
482+
483+Then **Operator 6** could have been restated quite compactly:
484+
485+ :: *[a 6 b c d] *[a $[*[a b] c d]]
486+
487+However, this is unnecessary complexity. **If** can be written as a
488+macro using the primitive operators:
489+
490+ 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]
491+
492+Reducing the right-hand side (an excellent exercise for the reader)
493+produces:
494+
495+ *[a *[[c d] [0 *[[2 3] [0 ++*[a b]]]]]]
496+
497+Which is the reduced pseudocode form of **Operator 6**.
498+
499+Additionally, we could simplify the semantics of **If**, at the expense
500+of breaking the system, by creating a macro that works as if and only if
501+`*[a b]` produces either `0` or `1`.
502+
503+This simpler **If** would be:
504+
505+ :: *[a 6 b c d] *[a 2 [0 1] 2 [1 c d] [1 0] [4 4 b]]
506+
507+which reduces to:
508+
509+ *[a *[[c d] [0 ++*[a b]]]]
510+
511+Let's examine the internals of this macro with a test example:
512+
513+ *[[40 43] [6 [3 0 1] [4 0 2] [4 0 1]]]
514+
515+Fitting this to the reduced form:
516+
517+ *[[40 43] *[[4 0 2] [4 0 3]] [0 ++*[[40 43] [3 0 1]]]]]
518+
519+Our test:
520+
521+ *[[40 43] [3 0 1]]
522+
523+produces a 0,
524+
525+ *[[40 43] *[[[4 0 2] [4 0 3]] [0 ++0]]]]
526+
527+which gets incremented twice
528+
529+ *[[40 43] *[[[4 0 2] [4 0 3]] [0 2]]]
530+
531+and is used as an axis to select the head of [[4 0 2] [4 0 3]]
532+
533+ *[[40 43] [4 0 2]]
534+
535+which increments `40` to produce `41`. Had the **test** produced a "no"
536+instead of a "yes", **If** would have incremented the **tail** of the
537+subject instead of the **head**.
538+
539+The real **If** is only slightly more complicated:
540+
541+ :: *[a 6 b c d] *[a *[[c d] [0 *[[2 3] [0 ++*[a b]]]]]]
542+
543+There is an extra step in the real **If** to prevent unexpected
544+behaviour if the test produces a value other than 0 ("yes") or 1 ("no").
545+The real **If** will crash if this happens and the naive **If** may not
546+(the reader will find it a useful exercise to figure out why).
547+
548+It's worth noting that practical, compiler-generated Nock never does
549+anything as funky as these **Operator 6** macro internals.
550+
551+------------------------------------------------------------------------
552+
553+Operator 7: Compose
554+-------------------
555+
556+ 33 :: *[a 7 b c] *[a 2 b 1 c]
557+
558+**Operator 7** implements function composition. To use a bit of math
559+notation, if we define the formula `[7 b c]` as a function `d(x)`:
560+
561+ d(a) == c(b(a))
562+
563+This is apparent from the reduced pseudocode form of **Operator 7**:
564+
565+ *[*[a b] c]
566+
567+As an example,
568+
569+ *[[42 44] [7 [4 0 3] [3 0 1]]] -> 1
570+
571+The above sequentially applies the **formulas** `[4 0 3]` and `[3 0 1]`
572+to our subject `[42 44]`, first incrementing the **head**, then testing
573+the **depth**.
574+
575+------------------------------------------------------------------------
576+
577+Operator 8: Push
578+----------------
579+
580+ 34 :: *[a 8 b c] *[a 7 [[7 [0 1] b] 0 1] c]
581+
582+**Operator 8** pushes a new **noun** onto our **subject**, not at all
583+unlike pushing a new variable onto the stack.
584+
585+The internals of **Operator 8** are similar to **Operator 7**, except
586+that the **subject** for `c` is not simply the **product** of `b`, but
587+the ordered pair of the **product** of `b` and the original **subject**.
588+
589+This is apparent from the reduced pseudocode form of **Operator 8**:
590+
591+ *[[*[a b] a] c]
592+
593+**Operator 8** evaluates the **formula** `c` with the **cell** of
594+`*[a b]` and the original **subject** `a`. In math notation, if we
595+define `[8 b c]` as `d(x)`:
596+
597+ d(a) == c([b(a) a])
598+
599+Suppose, for the purposes of the **formula** `c`, we need not just the
600+**subject** `a`, but some intermediate **noun** computed from the
601+**subject** that will be useful in the calculation of `c`. **Operator
602+8** applies **formula** `c` to a new **subject** that is the pair of the
603+intermediate value and the old **subject**.
604+
605+In higher-level languages that compile to Nock, variable declarations
606+are likely to generate an **Operator 8**, because the variable is
607+computed against the present **subject**, and used in a calculation
608+which depends both on the original **subject** and the new variable.
609+
610+------------------------------------------------------------------------
611+
612+Op 9: Call
613+----------
614+
615+ 35 :: *[a 9 b c] *[a 7 c 2 [0 1] 0 b]
616+
617+**Operator 9** is the **Call** operator and is used for calling and
618+applying **formulas** inside **noun** structures called **cores**
619+
620+A **noun** can contain both data and code. By convention, all
621+interesting flow control in Nock is done with **cores**, which are
622+**cells** whose head is code (containing one or more **formulas**) and
623+whose **tail** is data (possibly containing other **cores**):
624+
625+[code data]
626+
627+All flow structures in other languages not built on Nock correspond to
628+**cores**. Functions and/or closures are **cores**, objects are
629+**cores**, modules are **cores**, even loops are **cores** (Nock, of
630+course, does not have a loop operator).
631+
632+The head of a **core** is called the **battery** and the tail is called
633+the **payload**:
634+
635+ [battery payload]
636+
637+The **payload** of a core is any useful data needed for computation.
638+
639+The **battery** of a **core** is a **noun** containing one or more
640+**arms**, which are **formulas** whose **subject** is the entire
641+**core**.
642+
643+For example, in the case of the **battery** containing three **arms**:
644+
645+ [arm1 [arm2 arm3]]
646+
647+Where `arm1` is at **axis** `/2` in the **battery**, `arm2` is at `/6`,
648+and `arm3` is at `/7`. The **axes** will differ depending on the number
649+of **arms**.
650+
651+Of course, because the **subject** of an **arm** is the entire **core**,
652+an **arm** can invoke itself (or any other **arm** in the **battery**).
653+Hence, it can loop. And this is what a loop is - the simplest of
654+**cores**.
655+
656+Also, by convention, we have terms for different kinds of **cores**,
657+depending on their structure:
658+
659+A **trap** is a **core** whose battery contains a single **arm**. By
660+convention, this arm is called `$` (pronounced 'buc'), which is the
661+empty-name. All **traps** have the following structure:
662+
663+ [$ payload]
664+
665+A **door** is a **core** with a **payload** of the form
666+`[sample context]`. The **sample** is dynamic data (such as the
667+arguments of a function) and the **context** is any data that might be
668+useful (such as other **cores**, variables, or the entire kernel of your
669+OS). All **doors** have the following structure:
670+
671+ [battery [sample context]]
672+
673+A **gate** is a **core** that is both a **door** and a **trap**.
674+**Gates** are the Nock equivalent of lambdas or functions. All **gates**
675+have the structure:
676+
677+ [$ [sample context]]
678+
679+**Operator 9** constructs a **core** and activates it by calling one of
680+its **arms**.
681+
682+Looking reduced pseudocode form of **Call**:
683+
684+ *[*[a c] *[*[a c] 0 b]]
685+
686+**Call** applies a **formula** `c` to the **subject** `a`, where
687+`*[a c]` produces a **core**. **Call** then calls an **arm** `b` of the
688+**core** produced by `*[a c]` and reflexively applies it to the same
689+**core**.
690+
691+------------------------------------------------------------------------
692+
693+Op 10: Hint
694+-----------
695+
696+ 36 :: *[a 10 [b c] d] *[a 8 c 7 [0 3] d]
697+ 37 :: *[a 10 b c] *[a c]
698+
699+**Operator 10** serves a hint to the interpreter.
700+
701+If `b` is an atom and `c` is a **formula**, the **formula** `[10 b c]`
702+appears to be equivalent to `c`. Likewise if `[b c]` is a **cell**,
703+`[10 [b c] d]` appears to be equivalent to `d`. **Operator 10** is
704+actually a hint operator. The `b` or `[b c]`is discarded information -
705+it is not used, formally, in the computation. It may help the
706+interpreter compute the expression more efficiently, however.
707+
708+Every Nock computes the same result - but not all at the same speed.
709+What hints are supported? What do they do? Hints are a higher-level
710+convention which do not, and should not, appear in the Nock spec. Some
711+are defined in Hoon. Indeed, a naive Nock interpreter not optimized for
712+Hoon will run Hoon quite poorly. When it gets the product, however, the
713+product will be right. (Why is the `c` in `[b c]` computed? Because `c`
714+could crash. A correct Nock cannot simply ignore it, and treat both
715+variants of `10` as equivalent.)
716+
717+------------------------------------------------------------------------
718+
719+Op 11: Retrieve
720+-----------
721+
722+**operator 11** retrieves data from the global namespace at the path it is given.
723+
724+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.
725+
726+Crash default
727+-------------
728+
729+ 39 :: *a *a
730+
731+The nock function is defined for every **noun**, but on many **nouns**
732+it does nothing useful. For instance, if `a` is an **atom**, `*a`
733+reduces to... `*a`. In theory, this means that Nock spins forever in an
734+infinite loop. In other words, Nock produces no result - and in
735+practice, your interpreter will stop.
736+
737+Another way to see this is that Nock has "crash-only" semantics. There
738+is no exception mechanism. The only way to catch Nock errors is to
739+simulate Nock in a higher-level virtual Nock - which, in fact, we do all
740+the time. A simulator (or a practical low-level interpreter) can report,
741+out of band, that Nock would not terminate. It cannot recognize all
742+infinite loops, of course (cf. Halting problem), but it can recognize
743+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]