on master help sign in
Merge branch 'master' into urbyte
6bc00fcChristopher King
docs.md+3−4
@@ -1,13 +1,13 @@
1---
1---
2anchor: none
2anchor: none
3footer: true
3footer: true
4−title: Documentation
4+title: Docs
5sort: 4
5sort: 4
6---
6---
7
7
8<div class="lead">
8<div class="lead">
9 <div class="logo inverse"></div>
9 <div class="logo inverse"></div>
10− <h1 class="blue i-b">Urbit documentation</h1>
10+ <h1 class="blue i-b">Urbit docs</h1>
11</div>
11</div>
12
12
13<div class="col-md-12 head">
13<div class="col-md-12 head">
@@ -39,8 +39,7 @@ etc, should start with the [Nock definition](nock/definition) and work upward fr
39<ul>
39<ul>
40<li>Chat with us on <a href="https://urbit.org/stream"><code>:talk</code></a></li>
40<li>Chat with us on <a href="https://urbit.org/stream"><code>:talk</code></a></li>
41<li>Our discussion forum <a href="http://urbit.org/fora"><code>fora</code></a></li>
41<li>Our discussion forum <a href="http://urbit.org/fora"><code>fora</code></a></li>
42−<li>On Twitter <a href="https://twitter.com/urbit_">@urbit_</a></li>
42+<li>On Twitter <a href="https://twitter.com/urbit">@urbit</a></li>
43−<li>On Reddit <a href="https://reddit.com/r/urbit">/r/urbit</a></li>
44<li>Or email us at <a href="mailto:urbit@urbit.org">urbit@urbit.org</a></li>
43<li>Or email us at <a href="mailto:urbit@urbit.org">urbit@urbit.org</a></li>
45</ul>
44</ul>
46
45
docs/about/contributing.md+13−5
@@ -22,8 +22,9 @@ source](https://github.com/urbit/arvo/blob/master/arvo/hoon.hoon).
22
22
23## Docs guidelines
23## Docs guidelines
24
24
25−For documentation pull requests, acquire [pandoc](http://pandoc.org) and
25+For documentation pull requests, if you are making a brand new page, you'll want
26+it to conform to our general documentation standards. Acquire [pandoc](http://pandoc.org)
26−format your edited files with the following flags:
27+and make sure to format your edited files with the following flags:
27
28
28 $ pandoc --standalone \
29 $ pandoc --standalone \
29 --from=markdown+yaml_metadata_block \
30 --from=markdown+yaml_metadata_block \
@@ -31,8 +32,15 @@ format your edited files with the following flags:
31 -o output.md \
32 -o output.md \
32 input.md
33 input.md
33
34
35+If you are editing an existing page, reformatting the entire page with pandoc
36+will make the diff hard to read. Instead, just make sure that your edits generally
37+conform to the style of the existing docs around it. For example, you'll notice
38+that the paragraphs mostly wrap at column 80.
39+
40+**Note:** If you have an old version of Pandoc, it may convert the
34−**Note:** Pandoc will convert the terminating `---` in YAML metadata to
41+terminating `---` in YAML metadata to `...`, which is grounds for termination.
35−`...`, which is grounds for termination. Run the following one-liner to
42+Run the following one-liner to atone.
36−atone.
37
43
38 $ sed '1,/^$/ s/^\.\.\./---/g' input.md > output.md
44 $ sed '1,/^$/ s/^\.\.\./---/g' input.md > output.md
45+
46+Newer versions of pandoc (1.19.2.1, for example) don't have this issue.
docs/about/glossary.md+103−106
@@ -57,18 +57,22 @@ whose number is its bottom half. So the planet `~firbyr-napbes`,
57`48.879`, whose parent is `~mun`, `0xef`, `239`. The parent of `~mun`
57`48.879`, whose parent is `~mun`, `0xef`, `239`. The parent of `~mun`
58and all galaxies is `~zod`, `0`.
58and all galaxies is `~zod`, `0`.
59
59
60+##### <h5 id="pier">Pier</h5>
61+
62+A ship's *pier* is its Unix directory. For planets the name of the pier is usually the planet name.
63+
60### Nock
64### Nock
61
65
62> Nock is a Turing-complete, non-lambda combinator interpreter.
66> Nock is a Turing-complete, non-lambda combinator interpreter.
63
67
64−- *noun*: an *atom* or a *cell*
65- *atom*: any natural number
68- *atom*: any natural number
66- *cell*: any ordered pair of nouns
69- *cell*: any ordered pair of nouns
67−- *subject*: a noun - the data against which a `formula` is
68− evaluated
69- *formula*: a noun - a function at the Nock level
70- *formula*: a noun - a function at the Nock level
71+- *noun*: an *atom* or a *cell*
70- *product*: a noun - the result of evaluating a formula against a
72- *product*: a noun - the result of evaluating a formula against a
71 subject
73 subject
74+- *subject*: a noun - the data against which a `formula` is
75+ evaluated
72
76
73*See [Nock definition](../../nock/definition/).*
77*See [Nock definition](../../nock/definition/).*
74
78
@@ -77,26 +81,7 @@ and all galaxies is `~zod`, `0`.
77> Hoon is a strict, higher-order typed functional language that compiles
81> Hoon is a strict, higher-order typed functional language that compiles
78> itself to Nock.
82> itself to Nock.
79
83
80−###### span: an inferred type
81−
82−A *span* defines a set (finite or infinite) of nouns and ascribes some
83−semantics to it. There is no Hoon syntax for a span; it is always
84−produced as the inferred range of an expression (*twig*).
85−
86−*See [basic types](../../hoon/basic/#-type-span-and-mold).*
87−
88−###### core: a code-data cell
89−
90−The code (*battery*) is the head, the data (*payload*) is the tail. All
91−code-data structures in normal languages (functions, objects, modules,
92−etc) become *core*s in Hoon.
93−
94−- *battery*: the code of a core, a tree of *arms*
95−- *payload*: the data in a core
96−
97−*See [basic types](../../hoon/basic)*.
98−
99−###### arm: a named, functionally-computed attribute of a core
84+###### <h6 id="arm">arm:</h6> a named, functionally-computed attribute of a core
100
85
101The *twig* of each arm is compiled to a Nock formula, with the
86The *twig* of each arm is compiled to a Nock formula, with the
102enclosing `core` itself as the subject.
87enclosing `core` itself as the subject.
@@ -116,46 +101,6 @@ context.
116
101
117*See [advanced types](/hoon/advanced)*.
102*See [advanced types](/hoon/advanced)*.
118
103
119−###### metal: a variance model
120−
121−Every core has a *metal* which defines its variance model (ie, the
122−properties of the span of a compatible core). The default is `gold`
123−(invariant).
124−
125−- `gold`: *invariant*
126−- `lead`: *bivariant*
127−- `zinc`: *covariant*
128−- `iron`: *contravariant*
129−
130−*See [advanced types](/hoon/advanced)*.
131−
132−###### gate: a function/lambda/closure
133−
134−A *gate* is a core with one arm. To call a gate on an argument,
135−replace the sample (at [tree
136−address](../../hoon/twig/limb/limb/) `+6` in the core) with the
137−argument, and then compute the arm.
138−
139−The payload of a gate has a shape of `{sample context}`.
140−
141−- *sample*: the argument tuple
142−- *context*: the subject in which the gate was defined
143−
144−*See [basic types](../../hoon/basic/#-core-p-span-q-map-term-span),
145−[`%-` or `:call`](../../hoon/twig/cen-call/hep-call/) (the `twig` for
146−calling a `gate`).*
147−
148−###### mold: a type constructor / validator
149−
150−A *mold* is an idempotent gate (function), accepting any noun, and
151−producing a range with a useful span.
152−
153−- *bunt*: the value a mold produces when normalizing its default
154− sample
155−- *icon*: the span of the mold's range
156−
157−*See [mold twigs](/hoon/twig/buc-mold/).*
158−
159###### atom
104###### atom
160
105
161A Hoon *atom* span describes a Nock atom, with two additional pieces
106A Hoon *atom* span describes a Nock atom, with two additional pieces
@@ -192,46 +137,42 @@ Some common auras and their aliases:
192
137
193*See [basic types](../../hoon/basic/#-atom-p-term-q-unit-atom)*.
138*See [basic types](../../hoon/basic/#-atom-p-term-q-unit-atom)*.
194
139
195−###### twig: a Hoon expression
140+###### <h6 id="core">core:</h6> a code-data cell
196
141
197−A *twig* is a Hoon expression. Specifically, twig is the mold for the
142+The code (*battery*) is the head, the data (*payload*) is the tail. All
198−noun that a Hoon source expression compiles to. A twig is always a cell.
143+code-data structures in normal languages (functions, objects, modules,
144+etc) become *core*s in Hoon.
199
145
200−A twig has one of two forms: `{twig twig}`, which produces the ordered
146+- <h6 id="battery">*battery*:</h6> the code of a core, a tree of *arms*
201−pair of the two twigs, or a cell `{stem bulb}`, where `stem` is an
147+- <h6 id="payload">*payload*:</h6> the data in a core
202−atomic symbol.
203
148
204−- *stem*: an atomic symbol (`@tas`) - the name of a twig.
149+*See [basic types](../../hoon/basic)*.
205−- *bulb*: The mold of the twig's contents.
206
150
207−Most twigs have a *regular form*, beginning with a *sigil* which is
151+###### face: a labeled subtree
208−either a *keyword* or a *rune*. Some twigs also have a syntactic
209−*irregular form*; a few have *only* an *irregular form*.
210
152
211−- *sigil*: a *keyword* or *rune* used to begin a twig
153+Hoon has no scope or symbol-table; there is only the subject. To
212−- *keyword*: the value of a stem, prefixed with `:`.
154+"declare" a "variable" is to construct a new subject:
213−- *rune*: a pair of ASCII symbols used to begin a twig.
155+`[name=value old-subject]`.
214
156
215−For example, the stem `%if` becomes the keyword
157+A *face* is a span that wraps a name (`@tas`) around another span.
216−[`:if`](../../hoon/twig/wut-test/col-if/), with the rune `?:`. The first
217−symbol in a rune represents a family of related `twig`s. For example,
218−the [`?` family](../../hoon/twig/wut-test/) are all conditionals.
219
158
220−The keyword or rune forms are up to the programmer's choice. Most
159+*See [advanced types](../../hoon/advanced/#-face-aliases-and-bridges)*.
221−existing code uses runes, but the keyword form makes the learning path
222−easier.
223
160
224−A regular twig has two syntactic forms, *tall* and *flat*:
161+###### <h6 id="gate">gate:</h6> a function/lambda/closure
225
162
226−- *tall*: multiple lines, no parentheses, two or more spaces between
163+A *gate* is a core with one arm. To call a gate on an argument,
227− tokens
164+replace the sample (at [tree
228−- *flat*: one line, parentheses, one space between tokens
165+address](../../hoon/twig/limb/limb/) `+6` in the core) with the
166+argument, and then compute the arm.
229
167
230−Tall twigs can contain flat ones, but not vice versa. All irregular
168+The payload of a gate has a shape of `{sample context}`.
231−forms are flat.
232
169
233−*See [twig concept](../../hoon/concepts/#-twig-expression),
170+- *sample*: the argument tuple
234−[expressions](../../hoon/twig/), and [syntax](../../hoon/syntax/)*.
171+- *context*: the subject in which the gate was defined
172+
173+*See [basic types](../../hoon/basic/#-core-p-span-q-map-term-span),
174+[`%-` or `:call`](../../hoon/twig/cen-call/hep-call/) (the `twig` for
175+calling a `gate`).*
235
176
236###### limb: attribute or variable reference
177###### limb: attribute or variable reference
237
178
@@ -246,6 +187,44 @@ found, the result is the product of the arm.
246
187
247*See [Limbs and wings](../../hoon/twig/limb)*
188*See [Limbs and wings](../../hoon/twig/limb)*
248
189
190+###### loobean: a Hoon boolean
191+
192+`0` (`%.y`) is *yes*, `1` (`%.n`) is *no*.
193+
194+> Why? It's fresh, it's different, it's new. And it's annoying. And it
195+> keeps you on your toes. And it's also just intuitively right.
196+
197+###### metal: a variance model
198+
199+Every core has a *metal* which defines its variance model (ie, the
200+properties of the span of a compatible core). The default is `gold`
201+(invariant).
202+
203+- `gold`: *invariant*
204+- `lead`: *bivariant*
205+- `zinc`: *covariant*
206+- `iron`: *contravariant*
207+
208+*See [advanced types](/hoon/advanced)*.
209+
210+###### <h6 id="mold">mold:</h6> a type constructor / validator
211+
212+A *mold* is an idempotent gate (function), accepting any noun, and
213+producing a range with a useful span.
214+
215+- *bunt*: the value a mold produces when normalizing its default
216+ sample
217+- *icon*: the span of the mold's range
218+
219+*See [mold twigs](/hoon/twig/buc-mold/).*
220+
221+###### nest: type compatibility test
222+
223+*nest* is an internal function on two spans, which produces yes if the
224+set of nouns in the second span is provably a subset of the first.
225+
226+*See [advanced types](../../hoon/advanced/)*.
227+
249###### slot: a tree addressing scheme
228###### slot: a tree addressing scheme
250
229
251Every cell has a head and a tail, each of which may be either an atom or
230Every cell has a head and a tail, each of which may be either an atom or
@@ -253,26 +232,44 @@ a cell. Therefore every noun is a binary tree. `+1` or `.` resolves to
253the whole cell (technically this would work against an atom as well).
232the whole cell (technically this would work against an atom as well).
254The head of `+n` is `+2n`, the tail is `+(2n+1)`.
233The head of `+n` is `+2n`, the tail is `+(2n+1)`.
255
234
256−###### face: a labeled subtree
235+###### <h6 id="span">span:</h6> an inferred type
257
236
258−Hoon has no scope or symbol-table; there is only the subject. To
237+A *span* defines a set (finite or infinite) of nouns and ascribes some
259−"declare" a "variable" is to construct a new subject:
238+semantics to it. There is no Hoon syntax for a span; it is always
260−`[name=value old-subject]`.
239+produced as the inferred range of an expression (*twig*).
261
240
262−A *face* is a span that wraps a name (`@tas`) around another span.
241+*See [basic types](../../hoon/basic/#-type-span-and-mold).*
263
242
264−*See [advanced types](../../hoon/advanced/#-face-aliases-and-bridges)*.
243+###### <h6 id="twig">twig:</h6> a Hoon expression
265
244
266−###### nest: type compatibility test
245+A *twig* is a Hoon expression. Specifically, twig is the mold for the
246+noun that a Hoon source expression compiles to. A twig is always a cell.
267
247
268−*nest* is an internal function on two spans, which produces yes if the
248+A twig has one of two forms: `{twig twig}`, which produces the ordered
269−set of nouns in the second span is provably a subset of the first.
249+pair of the two twigs, or a cell `{stem bulb}`, where `stem` is an
250+atomic symbol.
270
251
271−*See [advanced types](../../hoon/advanced/)*.
252+- <h6 id="stem">*stem*:</h6> an atomic symbol (`@tas`) - the name of a twig.
253+- <h6 id="bulb">*bulb*:</h6> The mold of the twig's contents.
272
254
273−###### loobean: a Hoon boolean
255+Most twigs have a *regular form*, beginning with a *rune*. Some twigs
256+also have a syntactic *irregular form*; a few have *only* an *irregular form*.
274
257
275−`0` (`%.y`) is *yes*, `1` (`%.n`) is *no*.
258+- <h6 id="rune">*rune*:</h6> a pair of ASCII symbols used to begin a twig.
276
259
277−> Why? It's fresh, it's different, it's new. And it's annoying. And it
260+For example, the rune [`?:`](../../hoon/twig/wut-test/col-if/) is
278−> keeps you on your toes. And it's also just intuitively right.
261+Hoon's most common conditional, a branch on a boolean test. The first symbol
262+in a rune represents a family of related `twig`s. For example, the
263+[`?` family](../../hoon/twig/wut-test/) are all conditionals.
264+
265+A regular twig has two syntactic forms, *tall* and *flat*:
266+
267+- *tall*: multiple lines, no parentheses, two or more spaces between
268+ tokens
269+- *flat*: one line, parentheses, one space between tokens
270+
271+Tall twigs can contain flat ones, but not vice versa. All irregular
272+forms are flat.
273+
274+*See [twig concept](../../hoon/concepts/#-twig-expression),
275+[expressions](../../hoon/twig/), and [syntax](../../hoon/syntax/)*.
docs/arvo/basic.md+89−68
@@ -14,32 +14,68 @@ fundamentals of [Hoon](/docs/hoon/). To do this, we'll walk through two simple
14programs: the first [Project Euler](https://projecteuler.net/) problem
14programs: the first [Project Euler](https://projecteuler.net/) problem
15and [fizzbuzz](https://en.wikipedia.org/wiki/Fizz_buzz).
15and [fizzbuzz](https://en.wikipedia.org/wiki/Fizz_buzz).
16
16
17−To run this code, you'll need an urbit, and will have to copy the
17+To run this code, you'll need an urbit, and will have to either sync or copy the
18[examples repo](https://github.com/urbit/examples) into it.
18[examples repo](https://github.com/urbit/examples) into it.
19
19
20−If you haven't installed urbit yet, check out the [installation
20+## Installation
21−instructions](/docs/using/install). Once urbit is installed, take a look
22−at the [basic operation](/docs/using/admin) of your urbit.
23
21
24−If you haven't copied in the examples repo, running the following
22+First, you'll need a running urbit. Follow our urbit.org [install
25−commands from your urbit directory should do the trick:
23+instructions](https://urbit.org/docs/using/install), then
24+[setup](https://urbit.org/docs/using/setup) and urbit.
26
25
27−Make sure you've mounted your `%home` desk:
26+Follow the *Network install* below if your urbit is running on the live network
27+(comets are usually best for development). Follow the *Local install* instead
28+if you're on a
29+[fake ship](https://urbit.org/fora/posts/~2017.1.5..21.31.04..20f3~/) or are
30+otherwise experiencing problems with the network install.
28
31
29−```
32+### Network install
30−~fintud-macrep:dojo> |mount %
31−```
32
33
33−Then, copy the example into it
34+In your urbit's `:dojo`, run the command:
34
35
35−```
36+ ~your-urbit:dojo> |sync %examples ~ropmev-pocseb %examples
36−$ cp -r {urbit-examples}/gall/*/* {your-pier}/home/
37+
37−$ cp -r {urbit-examples}/dojo/*/* {your-pier}/home/
38+Depending on network traffic, this initial merge and sync could take anywhere
38−```
39+between thirty seconds to several minutes. Upon a successful sync you'll see the
40+output:
41+
42+ sync succeeded from %examples on ~ropmev-pocseb to %examples
43+
44+In which case, next run the commands:
45+
46+ ~your-urbit:dojo> =dir /=examples=
47+ ~your-urbit:dojo/examples> |serve %/web
48+ ~your-urbit:dojo/examples> |mount %
49+
50+If your sync isn't succeeding after a few minutes for whatever reason, run
51+`|cancel %examples` in your `:dojo` and follow the local install below instead.
52+
53+### Local install
54+
55+In your urbit's `:dojo`:
56+
57+ ~your-urbit:dojo> |merge %examples our %base, =gem %init
58+ ~your-urbit:dojo> =dir /=examples=
59+ ~your-urbit:dojo/examples> |serve %/web
60+ ~your-urbit:dojo/examples> |mount %
61+
62+If `~your-urbit` was installed at `/urbit/path` on your Unix machine, you can
63+now find your `%examples` desk at the path `/urbit/path/your-urbit/examples`.
64+
65+Lastly, in Unix, clone this repo somewhere and copy in the `examples` files to
66+your urbit's new mounted `%examples` desk. You can run the following shell
67+commands (*replacing your urbit's examples desk path as necessary*):
68+
69+ $ git clone https://github.com/urbit/examples
70+ $ for dir in {app,gen,lib,mar,sec,sur,web}; do cp -r ./examples/$dir* /urbit/path/your-urbit/examples; done
71+
72+Your `%clay` filesystem should acknowledge the newly added files.
73+
74+## Get started!
39
75
40Run an example to ensure it worked:
76Run an example to ensure it worked:
41
77
42− ~fintud-macrep:dojo> +examples-euler1
78+ ~fintud-macrep:dojo> +project-euler/p1
43 233.168
79 233.168
44
80
45Euler 1
81Euler 1
@@ -53,42 +89,44 @@ Let's check out the code for Euler 1. First, the problem:
53 Find the sum of all the multiples of 3 or 5 below 1000.
89 Find the sum of all the multiples of 3 or 5 below 1000.
54
90
55Here is the hoon solution (which should be in your pier directory under
91Here is the hoon solution (which should be in your pier directory under
56−`/gen/examples/euler1`):
92+`/examples/gen/project-euler/p1`):
57
93
58− :: project euler 1
94+ :: Project Euler 1
59− :: https://projecteuler.net/problem=1
95+ :: https://projecteuler.net/problem=1
60− :: run in dojo with +examples-euler1
61 ::
96 ::
62− :::: /hoon/euler1/examples/gen
97+ :: run in dojo with:
98+ :: ~your-urbit:dojo/examples> +project-euler/p1
99+ ::
100+ :::: /===/gen/project-euler/p1/hoon
63− ::
101+ ::
102+ !:
103+ ::
64− :- %say |= *
104+ :- %say |= *
65 :- %noun
105 :- %noun
66 =< (sum 1.000)
106 =< (sum 1.000)
67 ::
107 ::
68− :::: ~sivtyv-barnel
69− ::
70 |%
108 |%
71 ++ three
109 ++ three
72− |= a/@
110+ |= a/@
73− =| b/@
111+ =| b/@
74− |- ^- @u
112+ |- ^- @u
75 ?: (lth a b)
113 ?: (lth a b)
76− 0
114+ 0
77 (add b $(b (add 3 b)))
115 (add b $(b (add 3 b)))
78 ::
116 ::
79 ++ five
117 ++ five
80− |= a/@
118+ |= a/@
81− =| b/@
119+ =| b/@
82 |- ^- @
120 |- ^- @
83 ?: (lte a b)
121 ?: (lte a b)
84− 0
122+ 0
85 ?: =((mod b 3) 0)
123 ?: =((mod b 3) 0)
86− $(b (add b 5))
124+ $(b (add b 5))
87 (add b $(b (add b 5)))
125 (add b $(b (add b 5)))
88 ::
126 ::
89− ++ sum
127+ ++ sum
90 |= a/@u
128 |= a/@u
91− (add (five a) (three a))
129+ (add (five a) (three a))
92 --
130 --
93
131
94> Hoon is not generally whitespace sensitive, but we do have two
132> Hoon is not generally whitespace sensitive, but we do have two
@@ -97,7 +135,7 @@ Here is the hoon solution (which should be in your pier directory under
97> Really. For a more detailed explanation of when to use spaces vs.
135> Really. For a more detailed explanation of when to use spaces vs.
98> gaps, see the syntax section before the first exercises.
136> gaps, see the syntax section before the first exercises.
99
137
100−### Lines 1-11:
138+### Lines 1-13:
101
139
102Any line that begins with `::` is a comment.
140Any line that begins with `::` is a comment.
103
141
@@ -117,8 +155,8 @@ rune takes a specific number of children, either expressions formed by
117other runes or literals that produce their own value (some runes take
155other runes or literals that produce their own value (some runes take
118*N* children, and are usually closed with `==`).
156*N* children, and are usually closed with `==`).
119
157
120−For example, the rune `?:` from line 18 is the classic 'if-then-else'
158+For example, the rune `?:` from line 20 is the classic 'if-then-else' statement,
121−statement, and thus takes three children:
159+and thus takes three children:
122
160
123 ?: (lth a b) :: if first child evals to true
161 ?: (lth a b) :: if first child evals to true
124 0 :: then produce result of second
162 0 :: then produce result of second
@@ -149,32 +187,15 @@ See the entire naming scheme below.
149
187
150Using this scheme, we would pronounce `?:` as 'wutcol'.
188Using this scheme, we would pronounce `?:` as 'wutcol'.
151
189
152−For those who prefer to use reserved words to form expressions, you can
190+### Lines 14-37
153−substitute any rune with that rune's keyword, which you can find in
154−`++twig` in `/arvo/hoon.hoon`. For example, here's the code for `?:` in
155−`++twig`:
156
191
157−`{$if p/twig q/twig r/twig} :: ?: if/then/else`
158−
159−Instead of:
160−
161− ?:(=(1 2) 'this is true' 'this is false')
162− 'this is false'`
163−
164−You can write:
165−
166− :if(=(1 2) 'this is true' 'this is false')
167− 'this is false'
168−
169−### Lines 13-35
170−
171−Now let's quickly walk through this code line-by-line. Lines 13-35 are
192+Now let's quickly walk through this code line-by-line. Lines 14-37 are wrapped
172−wrapped in a `|%` ('[barcen](../../hoon/twig/bar-core/cen-core/)'), which produces a core. Cores are a
193+in a `|%` ('[barcen](../../hoon/twig/bar-core/cen-core/)'), which produces a
173−fundamental datatype in Hoon, similar to a struct, class, or object. A
194+core. Cores are a fundamental datatype in Hoon, similar to a struct, class, or
174−core is just a map of names to any kind of code, whether it be functions
195+object. A core is just a map of names to any kind of code, whether it be
175−or data. Each element in this map begins with a `++` followed by the
196+functions or data. Each element, called an arm, in this map begins with a `++`
176−name and the corresponding code. Since `|%` takes an arbitrary number of
197+followed by the name and the corresponding code. Since `|%` takes an arbitrary
177−children, it needs to be closed with a `--`.
198+number of children, it needs to be closed with a `--`.
178
199
179> `++` ('luslus') is not technically a rune, since it is only used in
200> `++` ('luslus') is not technically a rune, since it is only used in
180> core syntax, as shown above.
201> core syntax, as shown above.
@@ -184,7 +205,7 @@ Let's step into each of the three arms within our core.
184### `++ sum`
205### `++ sum`
185
206
186 ++ sum
207 ++ sum
187− |= a/@
208+ |= a/@u
188 (add (five a) (three a))
209 (add (five a) (three a))
189 --
210 --
190
211
@@ -195,10 +216,10 @@ takes two children:
195 one: `a`, which is required to be an atom or natural number, denoted
216 one: `a`, which is required to be an atom or natural number, denoted
196 by `@`.
217 by `@`.
197
218
198−2. The body of the function itself, which is executed when the function
219+2. The body of the function itself, which is executed when the function is
199− is called (in this case, with `(sum 1.000)`). This particular
220+ called (in this case, with `(sum 1.000)`). This particular function adds the
200− function adds the results of evaluating the gates `++ five` and
221+ results of evaluating the gates `++five` and `++three` with each of their
201− `++three` with each of their respective input parameters set to `a`.
222+ respective input parameters set to `a`.
202
223
203### ++ three
224### ++ three
204
225
docs/arvo/internals.md+2−2
@@ -103,6 +103,7 @@ following services:
103
103
104- `%ames` name of both our network and the vane that communicates over
104- `%ames` name of both our network and the vane that communicates over
105 it
105 it
106+- `%behn` a simple timer
106- `%clay` version-controlled, referentially- transparent, and global
107- `%clay` version-controlled, referentially- transparent, and global
107 filesystem
108 filesystem
108- `%dill` terminal driver. Unix sends keyboard events to `%dill` from
109- `%dill` terminal driver. Unix sends keyboard events to `%dill` from
@@ -110,9 +111,8 @@ following services:
110- `%eyre` http server. Unix sends http messages to `%eyre`, and
111- `%eyre` http server. Unix sends http messages to `%eyre`, and
111 `%eyre` produces http messages in response
112 `%eyre` produces http messages in response
112- `%ford` handles resources and publishing
113- `%ford` handles resources and publishing
113−- `%gall` manages our userspace applications.. `%gall` keeps state and
114+- `%gall` manages our userspace applications. `%gall` keeps state and
114 manages subscribers
115 manages subscribers
115−- `%time` a simple timer
116
116
117Cards
117Cards
118-----
118-----
docs/arvo/internals/ford/commentary.md+3−3
@@ -198,9 +198,9 @@ retrieve it from.
198 == ::
198 == ::
199
199
200This is how we represent the static resources hook files can load. The
200This is how we represent the static resources hook files can load. The
201−discussion of their use from a user's perspective is documented
201+discussion of their use from a user's perspective is documented in the [runes
202+documentation](https://urbit.org/docs/arvo/internals/runes), so we will here
202−elsewhere (link), so we will here only give a description of the data
203+only give a description of the data structure itself.
203−structure itself.
204
204
205A `%ape` horn is simply a twig that gets evaluated and placed in the
205A `%ape` horn is simply a twig that gets evaluated and placed in the
206subject.
206subject.
docs/arvo/internals/ford/runes.mdnew file+463
@@ -0,0 +1,463 @@
1+# `%ford` user manual
2+
3+## ford runes
4+
5+One of the most common ways to use ford is through ford's runes, all of which begin with `/` ("fas"). A ford rune runs a step of a ford build and places the result in the subject. There are various kinds of build steps, some of which take other build steps as parameters. The most common pattern is to have a sequence of ford runes at the top of a hoon source file that import the results of evaluating other hoon files. This is how we "import a library" in urbit: we add the result of compiling another hoon file into the current subject, possibly renaming it by wrapping a face around it.
6+
7+Another common use case is assembling and rendering markdown templates into a single HTML file, to be sent as an HTTP response in urbit's web server `%eyre`. It's important to keep in mind that %ford is quite flexible and generic, and is used in other parts of urbit -- such as the dojo -- that would not traditionally fall under the purview of a build system.
8+
9+### `/+` import from lib/
10+
11+The `/+` rune accepts a filename as an argument. It interprets that filename
12+as a hoon source file within the `lib` directory. This is how we import a shared
13+library in urbit.
14+
15+To run this example, put this code in your desk at `gen/faslus.hoon` and run
16+`+faslus` in your dojo. This example is a generator. For more information on
17+generators, see the [generator docs](https://urbit.org/docs/arvo/generators).
18+
19+```
20+/+ time-to-id
21+::
22+:- %say
23+|= {{now/@da * *} $~ $~}
24+:- %noun
25+(time-to-id now)
26+```
27+
28+produces: `"c.314d"` (or something similar depending on when you run it)
29+
30+You can import multiple libraries with a single `/+` rune by separating them
31+with commas.
32+
33+Replace the code in `gen/faslus.hoon` with the following:
34+
35+```
36+/+ time-to-id, hep-to-cab
37+::
38+:- %say
39+|= {{now/@da * *} $~ $~}
40+:- %noun
41+=/ id (time-to-id now)
42+=/ str "my-id-is-{id}"
43+(hep-to-cab (crip str))
44+```
45+
46+This should print something like `my_id_is_c.3588`.
47+
48+Another feature of the
49+`/+ and`/-`runes is the ability to specify the`ship`and`case\` from which to
50+load the library.
51+
52+Example:
53+
54+```
55+/+ time-to-id, hep-to-cab/4/~zod
56+```
57+
58+will load the `hep-to-cab` library from `~zod` at `%clay` revision `4`.
59+
60+### `/-` import from sur/
61+
62+The `/-` rune accepts a filename as an argument. It interprets that filename as
63+a hoon source file within the `sur` directory. The `sur` directory contains
64+shared structures that can be used by other parts of urbit. This is somewhat
65+similar to including a header file in C.
66+
67+Example:
68+```
69+/- talk
70+::
71+*serial:talk
72+```
73+produces: `0v0`
74+
75+`/-` can also take multiple files as arguments, and the ship and case of those
76+arguments can be specified. See the `/+` docs for more details about the syntax
77+for those features.
78+
79+### `/~` twig by hand
80+
81+`/~ <twig>` produces a "horn" that evaluates a twig and places the product in
82+the subject. Arbitrary hoon can be in the twig. A
83+[horn](https://urbit.org/docs/arvo/internals/ford/commentary/#-horn) is a data
84+structure representing a `%ford` static resource.
85+
86+Example:
87+```
88+/~ [a=0 b=1]
89+[a b]
90+```
91+produces:
92+`[0 1]`
93+
94+In wide-form, `/~` always takes a tuple (which may be a degenerate tuple of one element), and produces it.
95+
96+Example:
97+```
98+/~[%something]
99+```
100+produces: `%something`
101+
102+```
103+/~[%a %b]
104+```
105+produces: `[%a %b]`
106+
107+### `//` include a file by relative path
108+
109+`// <rel-path>` parses `rel-path` as a hoon twig, and then adds the resulting
110+twig to the subject. Note that the result type of this rune is not a horn, but
111+just a hoon twig, so its result can't be used as an argument to other runes
112+that expect a horn. There is no wide-form for this rune.
113+
114+Example:
115+```
116+// %/file-to-include
117+::
118+(frobnicate:file-to-include %.n)
119+
120+:: contents of file-to-include.hoon
121+|%
122+++ frobnicate
123+ |= a/? ^+ a
124+ !a
125+--
126+```
127+produces: `%.y`
128+
129+_Note: `%` means current directory, which in a hoon file will resolve to the
130+"directory" containing that file. Also, %clay doesn't have first-class
131+directories the way unix filesystems do. Whereas in unix, a directory is a
132+special kind of file, in %clay it's just a path prefix, and there is no file
133+stored at that path._
134+
135+### `/=` wrap a face around an included horn
136+
137+`/=` runs a horn (usually produced by another ford rune), takes the result of
138+that horn, and wraps a face around it.
139+
140+Example:
141+```
142+/= foo /~ [a=0 b=1]
143+::
144+[a.foo b.foo]
145+```
146+produces: `[0 1]`
147+
148+In wide-form, `/=` uses `=` as a delimiter: `/=foo=/~[a=0 b=1]`
149+
150+### `/:` evaluate at path, and `/<mark>/` render mark at current path
151+
152+`/:` takes a path and a horn, and evaluates the horn with the current path set to the supplied path.
153+`/mar/` renders the mark 'mar' at the current path.
154+
155+Example:
156+```
157+/= hoo-source /: /path/to/hoon-file /hoon/
158+::
159+`@t`hoo-source
160+```
161+
162+produces the text of the hoon file at "/path/to/hoon-file/hoon".
163+
164+`/hoon/` renders the current path using the `%hoon` mark, which in this case
165+passes the contents through unchanged. In general, rendering a file with a
166+mark will potentially run the contents through a series of conversion
167+operations. For details on marks, see the
168+[marks docs](https://urbit.org/docs/arvo/marks).
169+
170+Here's an example that includes a mark conversion:
171+```
172+/= page /: /path/to/html/file /mime/
173+::
174+page
175+
176+:: contents of /path/to/html/file:
177+<html><head><title>My Fascinating Blog</title></head></html>
178+```
179+produces:
180+`[[%text %html ~] 60 '<html><head><title>My Fascinating Blog</title></head></html>']`
181+
182+This result includes the MIME type ('text/html'), the content length in bytes,
183+and the HTML itself.
184+
185+In wide-form, `/:` uses `:` as a delimiter: `/=page=/:/path/to/html/file:/mime/`
186+
187+### `/!mark/` evaluate as hoon, then pass through mark
188+
189+Example:
190+```
191+/= mime /: /%/some-hoon-file /!mime/
192+::
193+mime
194+
195+:: contents of /%/some-hoon-file:
196+%produces-a-cord
197+```
198+produces: `[[%text %plain ~] 15 'produces-a-cord']`
199+
200+### `/&` pass through a series of marks
201+
202+`/&` passes a horn through multiple marks, right-to-left. It has both a
203+wide-form and a tall-form syntax. In wide-form, it takes a series of mark
204+arguments followed by a horn. In tall-form, it takes a single mark followed by
205+a horn.
206+
207+```
208+/= some-text /: /%/text-file /&mime&/txt/
209+::
210+some-text
211+```
212+produces: `[[%text %plain ~] p=17 q='Hi I\'m some text\0a']`
213+
214+This example shows two of the ways marks are used. The first way is what
215+happens with the `/txt/` mark: we use it to find a file in clay with that
216+extension, without performing any conversions. Since this file is stored with
217+the `%txt` mark in `%clay`, its type is a `wain`: a list of cords, where each
218+cord is a single line. Once we've read the file, the `%mime` mark converts the
219+`wain` to a triple that includes the MIME type ("text/plain"), the content
220+length in bytes, and the content itself as a cord.
221+
222+```
223+/= page /&html&elem&/~[;div.foo;]
224+::
225+page
226+```
227+produces: `'<html><head></head><body><div class="foo"></div></body></html>'`
228+
229+This runs the sail expression `;div.foo;` through the `%elem` mark, then
230+through the `%html` mark. The `/~` rune produces an item of mark `noun`. The
231+`%elem` mark converts the mark of the expression from `noun` to `elem` by
232+checking that the type fits in `manx` (a hoon/sail type indicating an XML
233+element). The `%html` mark recognizes the `%elem` and converts it to an HTML
234+string with enclosing `<html>`, `<head>`, and `<body>` tags.
235+
236+It's possible to use wide-form `/&` with more than two marks, by using `&` as a
237+delimiter between marks and adding a `/` before the last mark, like:
238+`/&d&c&b&/a/`. The last argument here can actually be any arbitrary horn, not
239+just a mark: `/&c&b&/:path:/mark/`
240+
241+Tall-form `/&` takes only two arguments: a mark and a horn. The mark does not
242+need to be enclosed in `/`'s: `/& html /elem/`
243+
244+### `/|` short-circuiting 'or'
245+
246+`/|` takes a series of horns and produces the first one (left-to-right) that
247+succeeds. If none succeed, it produces stack traces from all of its arguments.
248+
249+Example:
250+```
251+/= res /: /%/path/to/file
252+/|
253+ /!elem/
254+ /elem/
255+==
256+::
257+res
258+```
259+tries to parse the file at `/%/path/to/file` as a hoon expression and evaluate
260+it (`/!elem/`), and then if that fails, tries to convert the file to an HTML
261+element directly (`/elem/`). This is used in urbit's `tree` publishing system
262+to enable a user to place either a hoon file or a static file in a directory,
263+and have them both result in webpages, with preference given to treating the
264+file as hoon to be evaluated.
265+
266+Wide-form `/|` encloses its arguments in parentheses, with a single space as a delimiter:
267+`/|(/!elem/ /elem/)`
268+
269+### `/_` unfiltered: run a horn on each file in the current directory
270+
271+`/_` can be used in two ways: filtered and unfiltered.
272+
273+Unfiltered `/_` takes a horn as an argument. It produces a new horn representing the
274+result of mapping the supplied horn over the list of files in the current
275+directory. The keys in the resulting map are the basenames of the files in the
276+directory, and each value is the result of running that horn on the contents of
277+the file.
278+
279+Example:
280+```
281+/= kids /_ /hoon/
282+::
283+`(map term cord)`kids
284+```
285+
286+produces a value of type `(map term cord)`, where each key is the basename (the
287+filename without the prefix), and each value is the result of running the
288+contents of the file through the `%hoon` mark, which validates that it's valid
289+hoon code and returns it unmodified. So, the resulting map associates basenames
290+with file contents.
291+
292+Wide-form unfiltered `/_` doesn't need a delimiter: `/= kids /_/hoon/`
293+
294+### `/_` filtered: run a horn on each file in the directory matching an aura
295+
296+Filtered `/_` takes an aura and a horn, and filters the list of files in the
297+current directory by whether their filenames can be parsed to an atom of that
298+aura. It then produces a map where each key is the filename after parsing into
299+that atom type, and each value is the result of running the horn on the
300+contents of that file.
301+
302+Example:
303+```
304+/= timed-posts /_ @da /md/
305+`(map @da @t)`timed-posts
306+```
307+produces a map from dates to cords. This product will only contain files whose
308+names are parsable into `@da` dates. The values are the file contents converted
309+to a cord of markdown-formatted text.
310+
311+Wide-form filtered `/_` uses `_` as a delimiter: `/= timed-posts /_@da_/md/`
312+
313+### `/;` operate on
314+
315+`/;` takes a twig and a horn. The twig should evaluate to a gate, which is then slammed
316+with the result of the horn as its sample.
317+
318+Example:
319+```
320+/= goo
321+ /; |=({a/@ b/@} +(b))
322+ /~ [a=0 b=1]
323+::
324+goo
325+```
326+
327+produces: `2`
328+
329+Here's a slightly more complex example with runes that use the filesystem:
330+```
331+/= file-length
332+ /; |=(a/@t (lent (crip a)))
333+ /: /%/path/to/hoon/file /hoon/
334+::
335+file-length
336+```
337+produces the number of bytes in the file "/%/path/to/hoon/file."
338+
339+### `/,` switch by path
340+
341+`/,` is a switch statement, which picks a branch to evaluate based on
342+whether the current path matches the path in the switch statement.
343+Takes a sequence of pairs of (path, horn) terminated by a `==`. No wide-form.
344+
345+Example:
346+```
347+/= just-right
348+ /: /===/right-path :: set path to /%/right-path
349+ /,
350+ /wrong-path /~ ~
351+ /another-wrong-path /~ ~
352+ /right-path /~ %evaluate-me :: only evaluate this horn
353+ ==
354+::
355+`@t`just-right
356+```
357+
358+produces: `'evaluate-me'`
359+
360+### `/.` list
361+
362+Produce a null-terminated list from a sequence of horns, terminated by a `==`. No wide-form.
363+
364+Example:
365+```
366+/= vanes
367+ /.
368+ /~ %ames
369+ /~ %behn
370+ /~ %clay
371+ /~ %dill
372+ /~ %eyre
373+ /~ %ford
374+ /~ %gall
375+ ==
376+::
377+vanes
378+```
379+produces: `[%ames %behn %clay %dill %eyre %ford %gall ~]`.
380+
381+### `/*` heterogeneous map
382+
383+_DEPRECATED_
384+TODO: remove
385+
386+### `/^` cast
387+
388+`/^` takes a mold and a horn, and casts the result of the horn to the mold.
389+
390+Example:
391+```
392+/= liz /^ (list @) :: cast to real list
393+ /~ ~[1 2 3] :: no 'i' or 't' faces
394+::
395+?< ?=($~ liz) :: prevent find-fork
396+i.liz
397+```
398+
399+produces: `1`
400+
401+Without the cast, we wouldn't be able to access the 'i' face of the list.
402+
403+Wide-form `/^` uses `^` as a delimiter: `/^(list @)^/~[1 2 3 ~]`
404+
405+### `/#` insert dephash
406+
407+`/#` takes a horn and produces a cell of the dependency
408+hash of the result of the horn, and the result itself.
409+
410+Example:
411+```
412+/= inline /^ {dep/@uvH txt/@t} /# /: /%/my-script /js/
413+::
414+;= ;script: (trip txt.inline) :: set script contents
415+ ;script@"/~/on/{<dep.inline>}.js"; :: set script src
416+==
417+```
418+produces two `<script>` tags. The first has its contents set to the contents
419+of the JavaScript file we loaded from clay. The second is an auto-update
420+script that polls the server to check whether the dependency hash has changed.
421+This pattern is used in urbit's `tree` web publishing system.
422+
423+Wide-form `/#` does not need a delimiter:
424+`/= inline /^ {dep/@uvH txt/@t} /#/:/%/my-script:/js/`
425+
426+### `/$` process extra arguments
427+
428+`/$` will slam a gate on whatever extra arguments have been supplied to this build.
429+At the moment, only HTTP requests forwarded by `%eyre` contain any extra arguments,
430+and using this rune outside of that context will cause an error. Requests from `%eyre`
431+contain an argument representing the query string, which can be parsed using the
432+standard library gate `++fuel`.
433+
434+Example:
435+```
436+/= gas /$ fuel
437+::
438+:*
439+ %who {<(~(get ju aut.ced.gas) 0)>}
440+ %where {(spud s.bem.gas)}
441+ %case {(scow %ud p.r.bem.gas)}
442+==
443+```
444+produces: [%who '~zod' %where /ford/pages/web %case 60]
445+
446+Wide-form `/$` takes its arguments inside brackets, like `/~`:
447+`/=gas=/$[fuel]`
448+
449+### `/%` propagate extra arguments into renderers
450+
451+`/%` will forward extra arguments (usually from `%eyre`) on to any enclosed `/renderer/`'s. Without this,
452+renderers that use `/$` to read the extra arguments will crash.
453+
454+Example:
455+```
456+/= dat /% /tree-json/
457+::
458+dat
459+```
460+produces the results of running `ren/tree-json` on the current path. This renderer needs the query string,
461+which is one of the extra arguments passed in from `%eyre`.
462+
463+Wide-form `/%` has no delimiter: `/%/tree-json/`
docs/arvo/internals/gall.md+1−1
@@ -43,7 +43,7 @@ app's either `++peek` or `++peer` arm. The first response will always be
43either a `%nice` or a `%mean`, indicating whether or not the
43either a `%nice` or a `%mean`, indicating whether or not the
44subscription was successful. After the first response, there will be
44subscription was successful. After the first response, there will be
45zero or more responses of either `%rush` or `%rust`, which communicate
45zero or more responses of either `%rush` or `%rust`, which communicate
46−either a differntial or full update to the data stream. There may be a
46+either a differential or full update to the data stream. There may be a
47`%mean`, which indicates that the subscription has been canceled and no
47`%mean`, which indicates that the subscription has been canceled and no
48more responses will be received along this stream.
48more responses will be received along this stream.
49
49
docs/arvo/network.md+173−157
@@ -11,70 +11,73 @@ Network messages
11Now we've learned enough Hoon to do more interesting things. Let's get
11Now we've learned enough Hoon to do more interesting things. Let's get
12our planets to talk to each other.
12our planets to talk to each other.
13
13
14−All we've written up until now are just shell commands that produce a
14+All we've written up until now are just shell commands that produce a value and
15−value and then disappear. To listen for and receive messages from other
15+then disappear. To listen for and receive messages from other planets, we'll
16−planets, we'll need an app. Let's look at a very simple one:
16+need an app. Let's look at a very simple one, `echo.hoon`:
17
17
18 :: Accepts any noun from dojo and prints it out
18 :: Accepts any noun from dojo and prints it out
19 ::
19 ::
20− :::: /hoon/echo/examples/app
20+ :::: /===/app/echo/hoon
21 ::
21 ::
22− /? 314
22+ !: :: enables debug printfs
23− !:
23+ |% :: forms a core with subject as payload
24− |_ {bowl state/$~}
24+ ++ move {bone card} :: defines echo app's arvo move mold
25− ++ poke-noun
25+ ++ card $% $~ :: defines card (data) mold as null tagged union
26− |= arg/*
26+ == :: end of mold definition; see $%
27− ^- {(list) _+>.$}
27+ -- :: end of card arm definition
28− ~& [%argument arg]
28+ :: ::
29− [~ +>.$]
29+ |_ {bow/bowl $~} :: forms a core with bowl (app state) as sample
30− --
30+ ++ poke-noun :: begin definition of poke-noun arm
31+ |= non/* :: forms a gate which accepts any noun
32+ ^- {(list move) _+>.$} :: casts product to mold of moves and context
33+ ~& echo+noun+non :: debug printf, i.e. '[%echo %noun *]'
34+ [~ +>.$] :: produce a cell of empty list and our state
35+ -- :: end of poke-noun arm definition
31
36
32This is a very simple app that does only one thing. If you poke it with
37This is a very simple app that does only one thing. If you poke it with
33a value, it prints that value out. To try this out, you have to start
38a value, it prints that value out. To try this out, you have to start
34the app, then you can poke it from the command line with the following
39the app, then you can poke it from the command line with the following
35commands:
40commands:
36
41
37− ~fintud-macrep:dojo> |start %examples-echo
42+ ~fintud-macrep:dojo> |start %echo
38− 'prep'
39 >=
43 >=
40− ~fintud-macrep:dojo> :examples-echo 5
44+ ~fintud-macrep:dojo> :echo 5
41− [%argument 5]
45+ [%echo %noun 5]
42 >=
46 >=
43 ~fintud-macrep:dojo> :examples-echo [1 2]
47 ~fintud-macrep:dojo> :examples-echo [1 2]
44− [%argument [1 2]]
48+ [%echo %noun [1 2]]
45 >=
49 >=
46
50
47−> There is currently a bug where the `%argument` lines are printed
51+> There is currently a bug where the `[%echo %noun *]` lines are printed *above*
48−> *above* the line you entered, so your output may not look exactly like
52+> the line you entered, so your output may not look exactly like this. `>=`
49−> this. `>=` means that a command was successfully received and
53+> means that a command was successfully received and executed.
50−> executed.
51
54
52Most of the app code should be simple enough to guess its function. The
55Most of the app code should be simple enough to guess its function. The
53important part of this code is the definition of `++poke-noun`.
56important part of this code is the definition of `++poke-noun`.
54
57
55−Once an app starts, it's always running in the background and you
58+Once an app starts, it's always running in the background and you interact with
56−interact with it by sending it messages. The most straightforward way to
59+it by sending it messages. The most straightforward way to do that is to poke it
57−do that is to poke it from the command line, which we we did with
60+from the command line, which we we did with `:echo 5`
58−`:echo 5` (`:[app-name] [argument(s)]`).
61+(`:[app-name] [argument(s)]`).
59
62
60−In this case, `++poke-noun` takes an argument `arg` and prints it out
63+In this case, `++poke-noun` takes an argument (*sample*) `arg` and
61−with `~&` ([sigpam](../../hoon/twig/sig-hint/pam-dump/)). This is an unusual
64+prints it to dojo with `~&` ([sigpam](../../hoon/twig/sig-hint/pam-dump/)).
62−rune that formally "does nothing", but the interpreter detects it and
65+This is an unusual rune that formally "does nothing", but the interpreter
63−printfs the first child, before executing the second as if the first
66+detects it and printfs the first child, before executing the second as if the
64−didn't exist. This is a slightly hacky way of printing to the console,
67+first didn't exist. This is a slightly hacky way of printing to the console,
65but we'll get to the correct way later on.
68but we'll get to the correct way later on.
66
69
67−But what does `++poke-noun` produce? Recall that `^-` casts to a type.
70+But what does `++poke-noun` produce? Recall that `^-` casts to a type. In this
68−In this case, it's declaring that the end result of the function will be of
71+case, it's declaring that the end result (*product*) of the function
69−type `{(list) _+>.$}`. But what does this mean?
72+(`++poke-noun`'s *gate*) will be of type `{(list) _+>.$}`. But what does this
73+mean?
70
74
71−The phrase to remember is "a list of moves and our state". Urbit is a
75+The phrase to remember is "a list of moves and our state". Urbit is a message
72−message passing system, so whenever we want to do something that
76+passing system, so whenever we want to do something that interacts with the rest
73−interacts with the rest of the system, we send a message. Thus, a move
77+of the system, we send a message. Thus, a move is Arvo's equivalent of a
74−is Arvo's equivalent of a syscall. The first thing that `++poke-noun`
78+syscall. The first thing that `++poke-noun` produces is a list of messages,
75−produces is a list of messages, called "moves". In this case, we don't
76−actually want the system to do anything, so we produce the empty list,
79+called "moves". In this case, we don't actually want the system to do anything,
77−`~` (in the `[~ +>.$]` line).
80+so we produce the empty list, `~` (in the `[~ +>.$]` line).
78
81
79The second thing `++poke-noun` produces is our state. `+>.$` refers to a
82The second thing `++poke-noun` produces is our state. `+>.$` refers to a
80particular address in our subject where our formal app state is stored.
83particular address in our subject where our formal app state is stored.
@@ -85,21 +88,28 @@ Let's look at another example (edit your code in
85`/app/examples/echo/hoon` to reflect the code below). Say we want to
88`/app/examples/echo/hoon` to reflect the code below). Say we want to
86only accept a number, and then print out the square of that number.
89only accept a number, and then print out the square of that number.
87
90
88− /? 314
91+ :: Accepts an atom from the dojo and squares it.
89− !:
90− |_ {bowl state/$~}
91 ::
92 ::
93+ :::: /===/app/square/hoon
94+ ::
95+ !:
96+ |% ::> no moves in :square
97+ ++ move {bone card} ::> no cards in :square
98+ ++ card $% $~
99+ ==
100+ --
101+ :: ::< stateless
102+ |_ {bow/bowl $~}
92 ++ poke-atom
103 ++ poke-atom
93− |= arg/@
104+ |= tom/@
94− ^- {(list) _+>.$}
105+ ^- {(list move) _+>.$}
95− ~& [%square (mul arg arg)]
106+ ~& square+(mul tom tom)
96− [~ +>.$]
107+ [~ +>.$]
97− --
108+ --
98
109
99−A few things have changed. Firstly, we no longer accept arbitrary nouns
110+A few things have changed. Firstly, we no longer accept arbitrary nouns because
100−because we can only square atoms (integers, in this case an unsigned
111+we can only square atoms (integers, in this case an unsigned one). Thus, our
101−one). Thus, our argument is now `arg/@`. Secondly, it's `++poke-atom`
112+argument is now `tom/@`. Secondly, it's `++poke-atom` rather than `++poke-noun`.
102−rather than `++poke-noun`.
103
113
104Intro to marks
114Intro to marks
105==============
115==============
@@ -124,9 +134,9 @@ using `&[mark]`. Try the following commands:
124
134
125 ~fintud-macrep:dojo> |start %square
135 ~fintud-macrep:dojo> |start %square
126 >=
136 >=
127− ~fintud-macrep:dojo> :examples-square 6
137+ ~fintud-macrep:dojo> :square 6
128 gall: %square: no poke arm for noun
138 gall: %square: no poke arm for noun
129− ~fintud-macrep:dojo> :examples-square &atom 6
139+ ~fintud-macrep:dojo> :square &atom 6
130 [%square 36]
140 [%square 36]
131 >=
141 >=
132
142
@@ -143,68 +153,79 @@ so we'll be getting quite used to them.
143Sending a message to another urbit
153Sending a message to another urbit
144==================================
154==================================
145
155
146−Let's write our first network message! Here's `/app/examples/pong.hoon`:
156+Let's write our first network message! Here's `examples/app/pong.hoon`:
147
157
148− /? 314
158+ :: Allows one urbit to send the string 'Pong' to
159+ :: another urbit.
160+ ::
161+ :::: /===/app/pong/hoon
162+ ::
163+ !:
149 |%
164 |%
150− ++ move {bone term wire *}
165+ ++ move {bone card}
166+ ++ card $% {$poke wire dock poke-contents}
167+ ==
168+ ++ poke-contents $% {$atom @}
169+ ==
151 --
170 --
152− !:
171+ |_ {bow/bowl $~} ::< stateless
153− |_ {bowl state/$~}
154 ::
172 ::
155 ++ poke-urbit
173 ++ poke-urbit
156− |= to/@p
174+ |= to/ship
157 ^- {(list move) _+>.$}
175 ^- {(list move) _+>.$}
176+ ~& pong+'Outgoing pong!'
177+ :_ +>.$
158− [[[ost %poke /sending [to dap] %atom 'howdy'] ~] +>.$]
178+ ~[[ost.bow %poke /sending [to dap.bow] %atom 'Pong']]
159 ::
179 ::
160 ++ poke-atom
180 ++ poke-atom
161− |= arg/@
181+ |= tom/@
162 ^- {(list move) _+>.$}
182 ^- {(list move) _+>.$}
163− ~& [%receiving (@t arg)]
183+ ~& pong+'Incoming pong!'
184+ ~& pong+received+`@t`tom
164 [~ +>.$]
185 [~ +>.$]
165 ::
186 ::
166 ++ coup |=(* [~ +>.$])
187 ++ coup |=(* [~ +>.$])
188+ ::
167 --
189 --
168−
190+
169Run it with these commands:
191Run it with these commands:
170
192
171− ~fintud-macrep:dojo> |start %examples-pong
193+ ~fintud-macrep:dojo> |start %pong
172 >=
194 >=
173− ~fintud-macrep:dojo> :examples-pong &urbit ~sampel-sipnym
195+ ~fintud-macrep:dojo> :pong &urbit ~sampel-sipnym
174 >=
196 >=
175
197
176−Replace `~sampel-sipnym` with another urbit. The easiest thing to do is
198+Replace `~sampel-sipnym` with another urbit. The easiest thing to do is to start
177−to start a moon, a sub-identity of your urbit. If you don't know how to
199+a comet, a free and disposable Urbit identity. If you don't know how to start a
178−start a moon, see [the user admin section](/docs/using/admin/). Don't
200+comet, see [the user setup section](/docs/using/setup/). Don't forget to start
179−forget to start the `%examples-pong` app on that urbit, too. You should
201+the `%pong` app on that urbit, too. You should see, on the foreign
180−see, on the foreign urbit, this output:
202+urbit, this output:
181−
203+
182− [%receiving 'howdy']
204+ [%pong 'Incoming pong!']
183−
205+ [%pong %received 'Pong']
206+
184−Most of the code should be straightforward. In `++poke-atom`, the only
207+Most of the code should be straightforward. In `++poke-atom`, the only new thing
185−new thing is the expression `(@t arg)`, which is the type `@t` being
208+is the expression `` `@t`tom ``, which is *casting* the argument `tom` to type
186−called as a function with argument `arg`. As we already know, `@t` is
187−the type of "cord" text strings. In Hoon, when types are called as
209+`@t`. As we already know, `@t` is the type of "cord" (text string). In Hoon,
210+another way to perform a kind of casting is to use a type as a function, like
211+this: `(@t tom)`. When types are called like this, they are called "clams",
188−functions, they serve as a validator function called a "clam" -- that
212+and they serve as validator functions-- that is, functions whose domain is all
189−is, a function whose domain is all nouns, and range is the given type
213+nouns, and range is the given type (in this case, `@t`). Clams will "bunt" the
190−(in this case, `@t`).
214+default value of the mold whereas casts (`@t`tom) may `nest-fail` if the
191−
215+argument passed to it does not fit. An example of such a failure case is
192−In simpler terms, if a clam is passed a value of its own type, it
216+passing a cell to an atom: `` `@`[1 2] ``. Using a clam here instead
193−produces that value. Otherwise, it produces the default value (aka the
217+(`(@ [1 2])`) will bunt the default value of `@`, which is `0`. Try it in dojo!
194−"bunt") of its type. Here we call this `@t` function on the argument.
218+
195−This coerces the argument to text, so that we can print it out prettily
196−no matter what we're passed.
197−
198−The more interesting part is in `++poke-urbit`. The `urbit` mark is an
219+The more interesting part is in `++poke-urbit`. The `urbit` mark is an urbit
199−urbit identity, and the Hoon type associated with it is `@p` (the "p"
220+identity, and the Hoon type associated with it is `ship` or `@p` (the "p"
200stands for "phonetic base").
221stands for "phonetic base").
201
222
202−Recall that in a `++poke` arm we produce "a list of moves and our
223+Recall that in a `++poke` arm we produce "a list of moves and our state". Until
203−state". Until now, we've left the list of moves empty, since we haven't
224+now, we've left the list of moves empty, since we haven't wanted to tell Arvo to
204−wanted to tell Arvo to do anything in particular. Now we want to send a
225+do anything in particular. Now we want to send a message to another urbit. Thus,
205−message to another urbit. Thus, we produce a list with one element:
226+we produce a list with one element:
206
227
207− [ost %poke /sending [to-urbit-address %pong] %atom 'howdy']
228+ ~[[ost.bow %poke /sending [to dap.bow] %atom 'Pong]]
208
229
209### Moves
230### Moves
210
231
@@ -218,73 +239,68 @@ Let's walk through each of these elements step by step.
218
239
219#### Bones ("cause")
240#### Bones ("cause")
220
241
221−If you look up `++bone` in `hoon.hoon`, you'll see that it's a number
242+If you look up `++bone` in `hoon.hoon`, you'll see that it's a number (`@ud`),
222−(`@ud`), and that it's an opaque reference to a duct. `++duct` in
243+and that it's an opaque reference to a duct. `++duct` in `hoon.hoon` is a list
223−hoon.hoon is a list of `wire`s, where `++wire` is an alias for `++path`.
244+of `wire`s, where `++wire` is an alias for `++path`. `++path` is a list of
224−`++path` is a list of `++knot`s, which are ASCII text. Thus, a duct is a
245+`++knot`s, which are ASCII text. Thus, a duct is a list of paths, and a bone is
225−list of paths, and a bone is an opaque reference to it (in the same way
246+an opaque reference to it (in the same way that a Unix file descriptor is an
226−that a Unix file descriptor is an opaque reference to a file structure).
227−Thus, to truly understand bones, we must understand ducts.
247+opaque reference to a file structure). Thus, to truly understand bones, we must
228−
248+understand ducts.
249+
229−A duct is stack of causes, again, represented as paths, which are called
250+A duct is a stack of causes, again, represented as paths, which are called wires.
230−wires. At the bottom of every duct is a unix event, such as a keystroke,
251+At the bottom of every duct is a unix event, such as a keystroke, network
231−network packet, file change, or timer event. When Arvo is given this
252+packet, file change, or timer event. When Arvo is given this event, it routes
232−event, it routes the event to appropriate kernel module for handling.
253+the event to appropriate kernel module for handling.
233−
254+
234−Sometimes, the module can immediately handle the event and produce any
255+Sometimes, the module can immediately handle the event and produce any necessary
235−necessary results. For example, when we poked the `++poke-atom` arm
256+results. For example, when we poked the `++poke-atom` arm above, we poked %gall,
236−above, we poked %gall, our application server, which was able to respond
257+our application server, which was able to respond to our poke directly. When the
237−to our poke directly. When the module cannot service the request itself,
258+module cannot service the request itself, it sends instructions to another
238−it sends instructions to another kernel module or application (through the
259+kernel module or application (through the %gall module) to do a specified
239−%gall module) to do a specified action, and produces the result from
260+action, and produces the result from that.
240−that.
241
261
242Furthermore, when one module sends a message to another kernel module or
262Furthermore, when one module sends a message to another kernel module or
243−application, it also sends along the duct it was given with its new wire
263+application, it also sends along the duct it was given with its new wire tacked
244−tacked onto the end. Now the duct has two entries, with the unix event on
264+onto the top. Now the duct has two entries, with the unix event on the bottom
245−the bottom and the kernel module that handled it next. This process can
265+and the kernel module that handled it on top. This process can continue
246−continue indefinitely, adding more and more layers onto the duct. When
266+indefinitely, pushing more and more wires onto the top of the duct. When an
247−an entity finally produces a result, a layer is popped off the duct, and
267+entity finally produces a result, a wire is popped off the duct, and the result
248−the result is passed all the way back down.
268+is passed all the way back down, repeating the process of wire popping
249−
269+sequentially until the bottom of the duct is reached.
270+
250−In effect, a duct is an Arvo-level call stack. It's worth noting that
271+In effect, a duct is an Arvo-level call stack. It's worth noting that while in
251−while in traditional call stacks a function call happens synchronously
272+traditional call stacks a function call happens synchronously and returns
252−and returns exactly once. In Arvo, multiple moves can be sent at once,
273+exactly once. In Arvo, multiple moves can be sent at once, are evaluated
253−are evaluated asynchronously, and each one may be responded to zero or
274+asynchronously, and each one may be responded to zero or more times.
254−more times.
275+
255−
256−The point to take home is that whatever caused `++poke-urbit` to be
276+The point to take home is that whatever caused `++poke-urbit` to be called is
257−called is also the root cause for the network message we're trying to
277+also the root cause for the network message we're trying to send. Thus, we say
258−send. Thus, we say to send the network message along the given bone
278+to send the network message along the given bone `ost`.
259−`ost`.
279+
260−
280+##### Wire (path)
261−##### Wire ('tack on new layer to duct')
281+
262−
263−Of course, we have to push a new layer onto our duct before passing it
282+Of course, we have to push a new wire onto our duct before passing it along (or
264−along (or responding to it directly) anywhere. This layer can have any
283+responding to it directly) anywhere. This wire can have any data we want in it,
265−data we want in it, but we don't need anything specific here, so we just
284+but we don't need anything specific here, so we just use the wire `/sending`
266−use the wire `/sending` (`/elem1/elem2/elemN` is one syntax used to
285+(`/elem1/elem2/elemN` is one syntax used to create `++path`s and `++wire`s of N
267−create `++path`s and `++wire`s of N elements). If we were expecting a
268−response (which we're not), it would come back along the `/sending`
286+elements). If we were expecting a response (which we're not), it would come back
269−wire, meaning that the path `/sending` will be passed back to the
287+along the `/sending` wire, meaning that the path `/sending` will be passed back
270−response handler as an argument. Although it's not required, it's
288+to the response handler as an argument. Although it's not required, it's
271−generally a good idea to make the wire human-readable for bug-handling
289+generally a good idea to make the wire human-readable for bug-handling purposes.
272−purposes.
273
290
274##### Term (sys-call)
291##### Term (sys-call)
275
292
276−Each move also has a `term`, composed of lowercase ASCII and/or `-`.
293+Each move also has a `term`, composed of lowercase ASCII and/or `-`. This `term`
277−This `term` has the sign `@tas`. In this case, out `term` is `%poke`,
294+has the sign `@tas`. In this case, our `term` is `%poke`, which is the name of
278−which is the name of the particular kind of move we're sending. You can
295+the particular kind of move we're sending. You can always use `%poke` to message
279−always use `%poke` to message an app. Other common names include
280−`%warp`, to read from the filesystem; `%wait`, to set a timer; and
296+an app. Other common names include `%warp`, to read from the filesystem;
281−`%them`, to send an http request.
297+`%wait`, to set a timer; and `%them`, to send an http request.
282
298
283The move ends with `*` (that is, any noun) since each type of move takes
299The move ends with `*` (that is, any noun) since each type of move takes
284−different data. In our case, a `%poke` move takes a target (urbit and
300+different data. In our case, a `%poke` move takes a target (urbit and app) and
285−app) and marked data, then pokes the arm of the corresponding mark on
301+marked data, then pokes the arm of the corresponding mark on that app on that
286−that app on that urbit with that data. `[to-urbit-address %pong]` is the
302+urbit with that data. `[to-urbit-address %pong]` is the target urbit and app,
287−target urbit and app, `%atom` is the `mark`, and`'howdy'` is the data.
303+`%atom` is the `mark`, and`'Pong'` is the data.
288
304
289When Arvo receives a `%poke` move, it calls the appropriate `++poke`.
305When Arvo receives a `%poke` move, it calls the appropriate `++poke`.
290The same mechanism is used for sending messages between apps on the same
306The same mechanism is used for sending messages between apps on the same
@@ -300,7 +316,7 @@ urbit as for sending messages between apps on different urbits.
300- Extend either of the apps in the first two exercises to accept input
316- Extend either of the apps in the first two exercises to accept input
301 over the network in the same way as `pong`.
317 over the network in the same way as `pong`.
302
318
303−- Modify `examples-pong` to print out a message when it receives
319+- Modify `pong.hoon` to print out a message when it receives
304 acknowledgement.
320 acknowledgement.
305
321
306- Write two apps, `even` and `odd`. When you pass an atom to `even`,
322- Write two apps, `even` and `odd`. When you pass an atom to `even`,
docs/arvo/state.md+94−79
@@ -8,102 +8,117 @@ title: State
8State
8State
9=====
9=====
10
10
11−In the last section we built a few small apps that sent moves. These
11+In the last section we built a few small apps that sent moves. These apps were
12−apps were entirely stateless, however. Most useful apps require some
12+entirely stateless, however. Most useful apps require some amount of state.
13−amount of state. Let's build a trivial stateful app. It'll keep a
13+Let's build a trivial stateful app. It'll keep a running the sum of all the
14−running the sum of all the atoms we poke it with. Here's
14+atoms we poke it with. Here's `examples/app/sum.hoon`:
15−`app/examples/sum.hoon`:
15+
16−
16+ :: Keeps track of the sum of all the atoms it has been
17− /? 314
17+ :: poked with and prints the sum out
18+ ::
19+ :::: /===/app/sum/hoon
20+ ::
18 !:
21 !:
22+ |%
23+ ++ move {bone card}
24+ ++ card $% $~
25+ ==
26+ --
19− |_ {bowl state/@}
27+ |_ {bow/bowl sum/@}
28+ ::
20− ++ poke-atom
29+ ++ poke-atom
21− |= arg/@
30+ |= tom/@
22− ^- {(list) _+>.$}
31+ ^- {(list move) _+>.$}
23− ~& [%so-far (add state arg)]
32+ ~& sum+(add sum tom)
24− [~ +>.$(state (add state arg))]
33+ [~ +>.$(sum (add sum tom))]
34+ ::
35+ ++ coup
36+ |= {wir/wire err/(unit tang)}
37+ ^- {(list move) _+>.$}
38+ ?~ err
39+ ~& sum+success+'Poke succeeded!'
40+ [~ +>.$]
41+ ~& sum+error+'Poke failed. Error:'
42+ ~& sum+error+err
43+ [~ +>.$]
44+ ::
25 --
45 --
26
46
27−We can start it with `|start %examples-sum`, and then run it:
47+We can start it with `|start %sum`, and then run it:
28
48
29− ~fintud-macrep:dojo> :examples-sum &atom 5
49+ ~fintud-macrep:dojo> :sum &atom 5
30− [%so-far 5]
50+ [%sum 5]
31 >=
51 >=
32− ~fintud-macrep:dojo> :examples-sum &atom 2
52+ ~fintud-macrep:dojo> :sum &atom 2
33− [%so-far 7]
53+ [%sum 7]
34 >=
54 >=
35− ~fintud-macrep:dojo> :examples-sum &atom 15
55+ ~fintud-macrep:dojo> :sum &atom 15
36− [%so-far 22]
56+ [%sum 22]
37 >=
57 >=
38
58
39We can see that app state is being saved, but when, where, and how?
59We can see that app state is being saved, but when, where, and how?
40
60
41−The state is stored as the second thing in the `|_` line. In our case,
61+The state is stored as the second thing in the `|_` line. In our case, it's
42−it's simply an atom named `state`. We change it by producing our
62+simply an atom named `sum`. We change it by producing our state not with
43−state not with `+>.$` (as before), but with
63+`+>.$` (as before), but with `+>.$(sum (add sum tom))`. We've seen all these
44−`+>.$(state (add state arg))`. We've seen all these parts before, but
45−you might not recognize them.
64+parts before, but you might not recognize them.
46
65
47Recall in the first chapter that we recursed with the expression
66Recall in the first chapter that we recursed with the expression
48−`$(b (add 3 b))`. This meant "produce `$` with `b` changed to
67+`$(b (add 3 b))`. This meant "produce `$` with `b` changed to `(add 3 b)`.
49−`(add 3 b)`. Similarly, `+>.$(state (add state arg))` means "produce
68+Similarly, `+>.$(sum (add sum tom))` means "produce `+>.$` (i.e. our
50−`+>.$` (i.e. our context, which contains our state) with `state` changed
69+context, which contains our state) with `sum` changed to `(add sum tom)`.
51−to `(add state arg)`.
70+
52−
53−At a high level, then, when we handle state, we do it explicitly. It's
71+At a high level, then, when we handle state, we do it explicitly. It's passed in
54−passed in and produced explicitly. In Unix systems, application state is
72+and produced explicitly. In Unix systems, application state is just a block of
55−just a block of memory, which you need to serialize to disk if you want
73+memory, which you need to serialize to disk if you want to keep it around for
56−to keep it around for very long.
74+very long.
57−
75+
58−In Urbit, app state is a single (usually complex) value. In our example,
76+In Urbit, app state is a single (usually complex) value. In our example, we have
59−we have very simple state, so we defined `state/@`, meaning that our
77+very simple state, so we defined `sum/@`, meaning that our state is an atom.
60−state is an atom. Of course, `state` is just a name, and you're free to
78+Of course, `sum` is just a name, and you're free to name your state whatever
61−name your state whatever you like. But let's clarify a couple other
79+you like. But let's clarify a couple other things before we continue.
62−things before we continue.
80+
63−
64−First, `bowl` is a set of general global states. This set is managed by
81+First, `bowl` is a set of general global states. This set is managed by the
65−the system. It includes things like `now` (the current time), `our` (our
82+system. It includes things like `now` (the current time), `our` (our urbit
66−urbit identity), and `eny` (256 bits of guaranteed-fresh entropy). For
83+identity), and `eny` (256 bits of guaranteed-fresh entropy). For the full list
67−the full list of things in `++bowl`, search for `++ bowl` (note: two
84+of things in `++bowl`, search for `++ bowl` (note: two spaces) in
68−spaces) in `/arvo/zuse.hoon`.
85+`/arvo/zuse.hoon`.
69−
86+
70−> This is, perhaps, the most common way to learn Hoon. The easiest way
87+> This is, perhaps, the most common way to learn Hoon. The easiest way to learn
71−> to learn about an identifier you see in code is to search in
88+> about an identifier you see in code is to search in `/arvo/zuse.hoon` and
72−> `/arvo/zuse.hoon` and `/arvo/hoon.hoon` for it.\
73−> These "standard libraries" are usually simple to read. Since Urbit's
89+> `/arvo/hoon.hoon` for it.\\ These "standard libraries" are usually simple to
74−> codebase is less than 15000 lines of code combined, including the hoon
90+> read. Since Urbit's codebase is less than 15000 lines of code combined,
75−> parser, the compiler, and the `/arvo` microkernel, you can usually use
91+> including the hoon parser, the compiler, and the `/arvo` microkernel, you can
76−> the code and its comments as a reference doc.
92+> usually use the code and its comments as a reference doc.
77>
93>
78> You can also read
94> You can also read
79−> [zuse.hoon](https://github.com/urbit/arvo/blob/master/arvo/zuse.hoon)
95+> [zuse.hoon](https://github.com/urbit/arvo/blob/master/arvo/zuse.hoon) and
80−> and
81−> [hoon.hoon](https://github.com/urbit/arvo/blob/master/arvo/hoon.hoon)
96+> [hoon.hoon](https://github.com/urbit/arvo/blob/master/arvo/hoon.hoon) in your
82−> in your browser.
97+> browser.
83−
98+
84−The second thing we should clear up is this: Urbit needs no "serialize
99+The second thing we should clear up is this: Urbit needs no "serialize to disk"
85−to disk" step. Everything you produce in the app state is persistent
100+step. Everything you produce in the app state is persistent across calls to the
86−across calls to the app, restarts of the urbit, and even power failure.
101+app, restarts of the urbit, and even power failure. If you want to write to the
87−If you want to write to the Unix filesystem, you can, but it's not
102+Unix filesystem, you can, but it's not needed for persistence. Urbit has
88−needed for persistence. Urbit has transactional events, which makes it
103+transactional events, which makes it an [ACID operating
89−an [ACID operating system](https://en.wikipedia.org/wiki/ACID). Thus,
104+system](https://en.wikipedia.org/wiki/ACID). Thus, you don't have to worry about
90−you don't have to worry about persistence when programming in Urbit, or
105+persistence when programming in Urbit, or ever go through the hassle of having
91−ever go through the hassle of having to set up and write to a database.
106+to set up and write to a database.
92
107
93**Exercises**:
108**Exercises**:
94
109
95−- Modify `:examples-sum` to reset the counter when you poke it with 0.
110+- Modify `:sum` to reset the counter when you poke it with 0.
96
111
97−- Write an app that prints out the previous value you poked it with.
112+- Write an app called `last` that prints out the previous value you poked it with.
98 Sample output:
113 Sample output:
99
114
100−```
115+<!-- -->
116+
101−~fintud-macrep:dojo> :examples-last 7
117+ ~fintud-macrep:dojo> :last 7
102−[%last 0]
118+ [%last 0]
103−>=
119+ >=
104−~fintud-macrep:dojo> :examples-last [1 2 3]
120+ ~fintud-macrep:dojo> :last [1 2 3]
105−[%last 7]
121+ [%last 7]
106−>=
122+ >=
107−~fintud-macrep:dojo> :examples-last 'howdy'
123+ ~fintud-macrep:dojo> :last 'howdy'
108−[%last [1 2 3]]
124+ [%last [1 2 3]]
109−```
docs/arvo/subscriptions.md+218−140
@@ -13,62 +13,124 @@ want to subscribe to updates from another app. You could build a
13subscription model out of one-way pokes, but it's such a common pattern
13subscription model out of one-way pokes, but it's such a common pattern
14that it's built into arvo.
14that it's built into arvo.
15
15
16−Let's take a look at two apps, `:examples-source` and `:examples-sink`.
16+Let's take a look at two apps, `:source` and `:sink`. First,
17−First, `:examples-source`:
17+`:source`:
18−
18+
19− /? 314
19+ :: Sends subscription updates to sink.hoon
20+ ::
21+ :::: /===/app/source/hoon
22+ ::
20 !:
23 !:
24+ ::
21 |%
25 |%
22− ++ move {bone $diff mark *}
26+ ++ move {bone card}
27+ ++ card $% {$diff diff-contents}
28+ ==
29+ ++ diff-contents $% {$noun *}
30+ ==
23 --
31 --
32+ ::
24− |_ {hid/bowl state/$~}
33+ |_ {bow/bowl $~}
34+ ::
25− ++ poke-noun
35+ ++ poke-noun
26− |= arg/*
36+ |= non/*
27 ^- {(list move) _+>.$}
37 ^- {(list move) _+>.$}
28 :_ +>.$
38 :_ +>.$
29− %+ turn (prey /example-path hid)
39+ %+ turn (prey /example-path bow)
30− |=({o/bone *} `move`[o %diff %noun arg])
40+ |=({o/bone *} [o %diff %noun non])
41+ ::
31− ++ peer-example-path
42+ ++ peer-example-path
32 |= pax/path
43 |= pax/path
33 ^- {(list move) _+>.$}
44 ^- {(list move) _+>.$}
34− ~& [%subscribed-to pax=pax]
45+ ~& source+peer-notify+'Someone subscribed to you!'
46+ ~& source+[ship+src.bow path+pax]
47+ [~ +>.$]
48+ ::
49+ ++ coup
50+ |= {wir/wire err/(unit tang)}
51+ ^- {(list move) _+>.$}
52+ ?~ err
53+ ~& source+success+'Poke succeeded!'
54+ [~ +>.$]
55+ ~& source+error+'Poke failed. Error:'
56+ ~& source+error+err
57+ [~ +>.$]
58+ ::
59+ ++ reap
60+ |= {wir/wire err/(unit tang)}
61+ ^- {(list move) _+>.$}
62+ ?~ err
63+ ~& source+success+'Peer succeeded!'
64+ [~ +>.$]
65+ ~& source+error+'Peer failed. Error:'
66+ ~& source+error+err
35 [~ +>.$]
67 [~ +>.$]
68+ ::
36 --
69 --
37
70
38−And secondly, `:examples-sink`:
71+And secondly, `:sink`:
39−
72+
40− /? 314
73+ :: Sets up a simple subscription to source.hoon
74+ ::
75+ :::: /===/app/sink/hoon
76+ ::
77+ !:
41 |%
78 |%
42− ++ move {bone card}
79+ ++ move {bone card}
43− ++ card
44− $% {$peer wire {@p term} path}
80+ ++ card $% {$peer wire dock path}
45− {$pull wire {@p term} $~}
81+ {$pull wire dock $~}
46− ==
82+ ==
47 --
83 --
48− !:
84+ ::
49− |_ {bowl available/?}
85+ |_ {bow/bowl val/?}
86+ ::
50− ++ poke-noun
87+ ++ poke-noun
51− |= arg/*
88+ |= non/*
52 ^- {(list move) _+>.$}
89 ^- {(list move) _+>.$}
53− ?: &(=(%on arg) available)
90+ ?: &(=(%on non) val)
54− [[[ost %peer /subscribe [our %source] /example-path] ~] +>.$(available |)]
91+ :_ +>.$(val |)
55− ?: &(=(%off arg) !available)
92+ :~ :* ost.bow
93+ %peer
94+ /subscribe
95+ [our.bow %source]
96+ /example-path
97+ ==
98+ ==
99+ ?: &(=(%off non) !val)
100+ :_ +>.$(val &)
56− [[[ost %pull /subscribe [our %source] ~] ~] +>.$(available &)]
101+ ~[[ost.bow %pull /subscribe [our.bow %source] ~]]
102+ ~& ?: val
103+ sink+unsubscribed+'You are now unsubscribed!'
57− ~& ?:(available %not-subscribed %subscribed)
104+ sink+subscribed+'You are now subscribed!'
58 [~ +>.$]
105 [~ +>.$]
106+ ::
59− ++ diff-noun
107+ ++ diff-noun
60− |= {wir/wire arg/*}
108+ |= {wir/wire non/*}
61 ^- {(list move) _+>.$}
109 ^- {(list move) _+>.$}
62− ~& [%received-data arg]
110+ ~& sink+received-data+'You got something!'
111+ ~& sink+data+non
63 [~ +>.$]
112 [~ +>.$]
64− ++ reap
113+ ::
114+ ++ coup
65− |= {wir/wire error/(unit tang)}
115+ |= {wir/wire err/(unit tang)}
66 ^- {(list move) _+>.$}
116 ^- {(list move) _+>.$}
67− ?~ error
117+ ?~ err
68− ~& %successfully-subscribed
118+ ~& sink+success+'Poke succeeded!'
69− [~ +>.$]
119+ [~ +>.$]
70− ~& [%subscription-failed error]
120+ ~& sink+error+'Poke failed. Error:'
121+ ~& sink+error+err
71 [~ +>.$]
122 [~ +>.$]
123+ ::
124+ ++ reap
125+ |= {wir/wire err/(unit tang)}
126+ ^- {(list move) _+>.$}
127+ ?~ err
128+ ~& sink+success+'Peer succeeded!'
129+ [~ +>.$]
130+ ~& sink+error+'Peer f ailed. Error:'
131+ ~& sink+error+err
132+ [~ +>.$]
133+ ::
72 --
134 --
73
135
74Cheat sheet:
136Cheat sheet:
@@ -120,41 +182,43 @@ Cheat sheet:
120
182
121Here's some sample output of the two working together:
183Here's some sample output of the two working together:
122
184
123−
124− ~fintud-macrep:dojo> |start %examples-source
185+ ~fintud-macrep:dojo> |start %source
125 >=
186 >=
126− ~fintud-macrep:dojo> |start %examples-sink
187+ ~fintud-macrep:dojo> |start %sink
127 >=
188 >=
128− ~fintud-macrep:dojo> :examples-sink %on
189+ ~fintud-macrep:dojo> :sink %on
129− [%subscribed-to pax=/example-path]
190+ [%source %peer-notify 'Someone subscribed to you!']
130− %successfully-subscribed]
191+ [%source [%ship ~fintud-macrep] %path /]
192+ [%sink %success 'Peer succeeded!']
131 >=
193 >=
132− ~fintud-macrep:dojo> :examples-source 5
194+ ~fintud-macrep:dojo> :source 5
133− [%received-data 5]
195+ [%sink %received-data 'You got something!']
196+ [%sink %data 5]
134 >=
197 >=
135− ~fintud-macrep:dojo> :examples-sink %off
198+ ~fintud-macrep:dojo> :sink %off
136 >=
199 >=
137− ~fintud-macrep:dojo> :examples-source 6
200+ ~fintud-macrep:dojo> :source 6
138 >=
201 >=
139− ~fintud-macrep:dojo> :examples-sink %on
202+ ~fintud-macrep:dojo> :sink %on
140− [%subscribed-to pax=/example-path]
203+ [%source %peer-notify 'Someone subscribed to you!']
141− %successfully-subscribed]
204+ [%source [%ship ~fintud-macrep] %path /]
205+ [%sink %success 'Peer succeeded!']
142 >=
206 >=
143− ~fintud-macrep:dojo> :examples-source 7
207+ ~fintud-macrep:dojo> :source 7
144− [%received-data 7]
208+ [%sink %received-data 'You got something!']
209+ [%sink %data 7]
145 >=
210 >=
146
211
147−### :examples-source
212+### :source
148
213
149Hopefully you can get a sense for what's happening here. When we poke
214Hopefully you can get a sense for what's happening here. When we poke
150−`:examples-sink` with `%on`, `:examples-sink` subscribes to
215+`:sink` with `%on`, `:sink` subscribes to `:source`,
151−`:examples-source`, and so whenever we poke `:examples-source`,
216+and so whenever we poke `:source`, `:sink` gets the update and
152−`:examples-sink` gets the update and prints it out. Then we unsubscribe
217+prints it out. Then we unsubscribe by poking `:sink` with `%off`, and
153−by poking `:examples-sink` with `%off`, and `:examples-sink` stops
154−getting updates. We then resubscribe.
218+`:sink` stops getting updates. We then resubscribe.
155
219
156−There's a fair bit going on in this code. Let's look at
220+There's a fair bit going on in this code. Let's look at `:source`
157−`:examples-source` first.
221+first.
158
222
159Our definition of `move` is fairly specific, since we're only going to
223Our definition of `move` is fairly specific, since we're only going to
160sending one kind of move. The `%diff` move is a subscription update, and
224sending one kind of move. The `%diff` move is a subscription update, and
@@ -167,18 +231,16 @@ the discussion of ducts, a layer gets popped off the duct rather than
167added to it. This is why no wire is needed for the move -- we won't
231added to it. This is why no wire is needed for the move -- we won't
168receive anything in response to it.
232receive anything in response to it.
169
233
170−Anyways, there're two functions inside the `|_`. We already know when
234+Anyways, there are four functions (arms) inside the `|_`. We already know when
171−`++poke-noun` is called. `++peer` is called when someone tries to
235+`++poke-noun` is called. `++peer-example-path` is called when someone tries to
172−subscribe to our app. Of course, you don't just subscribe to an app; you
236+subscribe to our app. Of course, you don't just subscribe to an app; you
173−subscribe to a path on that app. This path comes in as the argument to
237+subscribe to a path on that app. This path comes in as the argument to `++peer`.
174−`++peer`.
238+
175−
176−In our case, we don't care what path you subscribed on, and all we do is
239+In our case, we don't care what path you subscribed on, and all we do is print
177−print out that you subscribed. Arvo keeps track of your subscriptions,
240+out that you subscribed. Arvo keeps track of your subscriptions, so you don't
178−so you don't have to. You can access your subscribers by looking at
241+have to. You can access your subscribers by looking at `sup` in the bowl that's
179−`sup` in the bowl that's passed in. `sup` is of type
180−`(map bone {@p path})`, which associates bones with the urbit who
242+passed in. `sup` is of type `(map bone {@p path})`, which associates bones with
181−subscribed, and which path they subscribed on. If you want to
243+the urbit who subscribed, and which path they subscribed on. If you want to
182communicate with your subscribers, send them messages along their bone.
244communicate with your subscribers, send them messages along their bone.
183
245
184`++poke-noun` "spams" the given argument to all our subscribers.
246`++poke-noun` "spams" the given argument to all our subscribers.
@@ -187,83 +249,99 @@ same as `[b a]`. It's just a convenient way of formatting things when
187the first thing in a cell is much more complicated than the second.
249the first thing in a cell is much more complicated than the second.
188Thus, we're producing our state unchanged.
250Thus, we're producing our state unchanged.
189
251
190−Our list of moves is the result of a call to `++turn`. `++turn` is what
252+Our list of moves is the result of a call to `++turn`. `++turn` is what many
191−many languages call "map" -- it runs a function on every item in a list
253+languages call "map" -- it runs a function on every item in a list and collects
192−and collects the results in a list. The list is `(prey /example-path hid)`
254+the results in a list. The list is `(prey /example-path bow)` and the function
193−and the function is the `|=` line right after it.
255+is the `|=` line right after it.
194
256
195−`++prey` is a standard library function defined in `zuse`. It takes a
257+`++prey` is a standard library function defined in `zuse.hoon`. It takes a path
196−path and a bowl and gives you a list of the subscribers who are
258+and a bowl and gives you a list of the subscribers who are subscribed on a path
197−subscribed on a path that begins with the given path. "Prey" is short
259+that begins with the given path. "Prey" is short for "prefix".
198−for "prefix".
199
260
200Now we have the list of relevant subscribers. This a list of triples,
261Now we have the list of relevant subscribers. This a list of triples,
201−`{bone @p path}`, where the only thing we really need is the bone,
262+`{bone @p path}`, where the only thing we really need is the bone, because we
202−because we don't need to know their urbit or what exact path they
263+don't need to know their urbit or what exact path they subscribed on. Thus, our
203−subscribed on. Thus, our transformer function takes `{o/bone *}` and
264+transformer function takes `{o/bone *}` and produces `[o %diff %noun non]`,
204−produces `[o %diff %noun arg]`, which is a move that provides bone `o`
265+which is a move that provides bone `o` with this subscription update:
205−with this subscription update: `[%noun arg]`". This is fairly dense
266+`[%noun non]`". This is fairly dense code, but what it's doing is
206−code, but what it's doing is straightforward.
267+straightforward!
207−
268+
208−### :examples-sink
269+### :sink
209−
270+
210−`:examples-source` should now make sense. `:examples-sink` is a little
271+`:source` should now make sense. `:sink` is a little longer, but not much more
211−longer, but not much more complicated.
272+complicated.
212−
273+
213−In `:examples-sink`, our definition of of `++move` is different. All
274+In `:sink`, our definition of of `++move` is different. All moves start
214−moves start with a `bone`, and we conventionally refer to the second
275+with a `bone`, and we conventionally refer to the second half as the "card", so
215−half as the "card", so that we can say a move is an action that sends a
276+that we can say a move is an action that sends a card along a bone.
216−card along a bone.
277+
217−
218−We have two kinds of cards here: we `%peer` to start a subscription, and
278+We have two kinds of cards here: we `%peer` to start a subscription, and we
219−we `%pull` to stop it. Both of these are "forward" moves that may
279+`%pull` to stop it. Both of these are "forward" moves that may receive a
220−receive a response, so they need a wire to tack onto the duct before
280+response, so they need a wire to tack onto the duct before they pass it on. They
221−they pass it on. They also need a target, which is a pair of an urbit
281+also need a target, which is a pair of an urbit and an app name. Additionally,
222−and an app name. Additionally, `%peer` needs a path on that app to
223−subscribe too. `%pull` doesn't need this, because its semantics are to
282+`%peer` needs a path on that app to subscribe too. `%pull` doesn't need this,
224−cancel any subscriptions coming over this duct. If your bone and wire
283+because its semantics are to cancel any subscriptions coming over this duct. If
225−are the same as when you subscribed, then the cancellation will happen
284+your bone and wire are the same as when you subscribed, then the cancellation
226−correctly.
285+will happen correctly.
227−
286+
228−The only state we need for `:examples-sink` is a boolean to indicate
287+The only state we need for `:sink` is a boolean to indicate whether
229−whether we're already subscribed to `:examples-source`. We use
288+we're already subscribed to `:source`. We use `val/?`, where `?`
230−`available/?`, where `?` is the sign of type boolean (similar to `*`,
289+is the sign of type boolean (similar to `*`, `@`), which defaults to true (that
231−`@`), which defaults to true (that is, `0`).
290+is, `0`).
232
291
233In `++poke-noun` we check our input to see both if it's `%on` and we're
292In `++poke-noun` we check our input to see both if it's `%on` and we're
234−available. If so, we produce the move to subscribe to
293+available (`val` is true). If so, we produce the move to subscribe to
235−`:examples-source`:
294+`:source`:
236−
295+
296+ :~ :* ost.bow
297+ %peer
298+ /subscribe
299+ [our.bow %source]
237− [ost %peer /subscribe [our %source] /example-path]
300+ /example-path
238−
301+ ==
302+ ==
303+
239−Also, we set available to false (`|`) with `+>.$(available |)`.
304+Also, in the preceding lines, we set `val` to false (`|`) with `+>.$(val |)`.
240−
305+Remember that the `:_` constructs an inverted cell, with the first child
306+(`+>.$(val |` in our case) as the tail and the second child as the head. Here,
307+the cell we produce when our subscription is `%on` and `val` is true has a
308+head with our new state where `val` is set to false and a tail of our list of
309+moves, which is shown in the code block above.
310+
241−Otherwise, if our input is `%off` and we're already subscribed (i.e.
311+Otherwise, if our input is `%off` and we're already subscribed (i.e. `val`
242−`available` is false), then we unsubscribe from `:examples-source`:
312+is false), then we unsubscribe from `:source` and set `val` back to true (`&`),
243−
313+again using our handy inverted cell constructor mold `:_`:
314+
315+ :_ +>.$(val &)
244− [ost %pull /subscribe [our %source] ~]
316+ ~[[ost.bow %pull /subscribe [our.bow %source] ~]]
245
317
246It's important to send over the same bone and wire (`/subscribe`) as the
318It's important to send over the same bone and wire (`/subscribe`) as the
247one we originally subscribed on.
319one we originally subscribed on.
248
320
249−We also set `available` to true (`&`).
321+If neither of these cases are true, then we print our current subscription
322+state, based on whether `val` is true or false, and return a cell containing
323+a null list of moves and our unchanged app state:
324+
325+ ~& ?: val
326+ sink+unsubscribed+'You are now unsubscribed!'
327+ sink+subscribed+'You are now subscribed!'
328+ [~ +>.$]
250
329
251−If neither of these cases are true, then we print our current
330+`++diff-noun` is called when we get a `%diff` update along a subscription with a
252−subscription state.
331+mark of `noun`. `++diff-noun` is given the wire that we originally passed with
332+the `%peer` subscription request along and the data we got back. In our case we
333+just print out the data:
253
334
254−`++diff-noun` is called when we get a `%diff` update along a
335+ ~& sink+received-data+'You got something!'
255−subscription with a mark of `noun`. `++diff-noun` is given the wire that
336+ ~& sink+data+non
256−we originally passed with the `%peer` subscription request along and the
257−data we got back. In our case we just print out the data.
258
337
259`++reap` is called when we receive an acknowledgment as to whether the
338`++reap` is called when we receive an acknowledgment as to whether the
260−subscription was handled successfully. You can remember that `++reap` is
339+subscription was handled successfully. You can remember that `++reap` is the
261−the counterpart to `++peer` as it's pronounced like 'peer' backwards.
340+counterpart to `++peer` as it's pronounced like 'peer' backwards. Similarly,
262−Similarly, `coup` is similar to 'poke' backwards.
341+`coup` is similar to 'poke' backwards.
263−
342+
264−Moving forward, `++reap` is given the wire we attempted to subscribe
343+Moving forward, `++reap` is given the wire we attempted to subscribe over,
265−over, possibly along with an error message in cases of failure.
344+possibly along with an error message in cases of failure. `(unit type)` means
266−`(unit type)` means "either `~` or `[~ type]`, which means it's used
345+"either `~` or `[~ type]`, which means it's used like Haskell's "maybe" or C's
267−like Haskell's "maybe" or C's nullability. If `error` is `~`, then the
268−subscription was successful and we tell that to the user. Otherwise, we
346+nullability. If `err` is `~`, then the subscription was successful and we tell
269−print out the error message.
347+that to the user. Otherwise, we print out the error message.
docs/arvo/web-apps.md+4−4
@@ -148,7 +148,7 @@ Please pardon the awkwardness of the name 'examples-click-click', but we used it
148# Frontend
148# Frontend
149
149
150That's all that's needed for the back end. The front end is just
150That's all that's needed for the back end. The front end is just
151−some "sail" html (Hoon markup for XML) and javascript. Here's `/web/click.hoon`:
151+some "sail" html (Hoon markup for XML) and javascript. Here's `/web/pages/examples/click.hoon`:
152
152
153```
153```
154;html
154;html
@@ -163,7 +163,7 @@ some "sail" html (Hoon markup for XML) and javascript. Here's `/web/click.hoon`
163 ;div#err(class "disabled");
163 ;div#err(class "disabled");
164 ;div#clicks;
164 ;div#clicks;
165 ==
165 ==
166− ;script(type "text/javascript", src "/click/main.js");
166+ ;script(type "text/javascript", src "/pages/examples/click/click.js");
167 ==
167 ==
168==
168==
169```
169```
@@ -177,7 +177,7 @@ To view the frontend, point your browser at `ship-name.urbit.org/~~/pages/exampl
177We have a button labeled "Poke!" and a div with id `clicks` where
177We have a button labeled "Poke!" and a div with id `clicks` where
178we'll put the number of clicks. We also include a small
178we'll put the number of clicks. We also include a small
179javascript file where the client-side application logic can be
179javascript file where the client-side application logic can be
180−found. It's in `/web/pages/examples/click.js`:
180+found. It's in `/web/pages/examples/click/click.js`:
181
181
182```
182```
183
183
@@ -230,7 +230,7 @@ of the available ones:
230
230
231In our case, we specify only that the mark is "click".
231In our case, we specify only that the mark is "click".
232
232
233−The callback funciton is called when we receive an
233+The callback function is called when we receive an
234acknowledgment. If there was an error, we put it in the `err`
234acknowledgment. If there was an error, we put it in the `err`
235div that we defined above. Otherwise, we printf to the console a
235div that we defined above. Otherwise, we printf to the console a
236message saying the poke succeeded. As is common, we gray
236message saying the poke succeeded. As is common, we gray
docs/byte/1.md+5−9
@@ -75,9 +75,9 @@ Let's type in some aura examples:
75
75
76```
76```
77
77
78−So decimal is aura `@ud`, hexadecimal is `@ux`. Note the cast
78+So decimal is aura `@ud`, hexadecimal is `@ux`. The cast
79−syntax, which lets us change the type of an atom, converting hex
79+syntax&mdash;`` `@ud` ``&mdash;lets us change the type of an
80−`0x42` to a decimal `66`.
80+atom, converting hex `0x42` to a decimal `66`.
81
81
82An aura is soft type. The programmer can always insist on how
82An aura is soft type. The programmer can always insist on how
83to interpret an atom. Hoon doesn't have "dependent types"; it
83to interpret an atom. Hoon doesn't have "dependent types"; it
@@ -136,10 +136,6 @@ slightly clunkier syntax in exchange for much simpler semantics.
136 @ux
136 @ux
1370x7469.6272.9cc3
1370x7469.6272.9cc3
138
138
139−> ? ~~Ürbit
140− @t
141−'Ürbit'
142−
143> ? ~.urbit
139> ? ~.urbit
144 @ta
140 @ta
145~.urbit
141~.urbit
@@ -304,8 +300,8 @@ The symbol rules, which are enforced by the Hoon parser but not
304(as we've discussed) the type system: a symbol is lowercase with
300(as we've discussed) the type system: a symbol is lowercase with
305infix hyphens ("kebab-case").
301infix hyphens ("kebab-case").
306
302
307−Loobeans are not true and false, but yes (`.y` or `&`) and no
303+Loobeans are not true and false, but yes (`%.y` or `&`) and no
308−(`.n` or `|`). This is because *yes is zero and no is one*.
304+(`%.n` or `|`). This is because *yes is zero and no is one*.
309This makes sense at a certain mathematical level, though it
305This makes sense at a certain mathematical level, though it
310was probably a mistake from a practical perspective.
306was probably a mistake from a practical perspective.
311
307
docs/byte/2.md+12−4
@@ -139,9 +139,9 @@ it? Let's keep working with our little test subject `a`.
139
139
140The most basic way to access the subject is *tree geometry*.
140The most basic way to access the subject is *tree geometry*.
141Every noun is a binary tree; every noun in the tree has a number
141Every noun is a binary tree; every noun in the tree has a number
142−which is its address. The root of the tree is `1`; if the
142+which is its address. The root of the tree is `1`. If the
143−address of a cell is `n`, its head is `2n` and its tail is
143+address of a cell is `n`, the address of its head is `2n` and the
144−`2n+1`.
144+address of its tail is `2n+1`.
145
145
146
146
147
147
@@ -172,7 +172,15 @@ The syntax for a fragment of the subject at a tree address, or
172[.3.14 ~m45]
172[.3.14 ~m45]
173```
173```
174
174
175−Of course, the fragment retains the type it had when we built it.
175+The fragment retains the type it had when we built it.
176+
177+Another (equivalent) way to think of tree addressing involves
178+binary. As before, the root of the tree is at address `1`. For
179+the node of a tree at some address `b`, where `b` is binary,
180+you get the address of the head by concatenating a `0` to
181+the end of `b`; and to get the tail, concatenate a `1` at the
182+end. For example, the head of the node at binary address `111`
183+is at `1110`, and the tail is at `1111`.
176
184
177## Labeled surfaces
185## Labeled surfaces
178
186
docs/hoon/concepts.md+21−21
@@ -22,7 +22,7 @@ maps poorly onto its semantics. For example, although Hoon is a
22typed language, the term "type" is not formally defined in Hoon.
22typed language, the term "type" is not formally defined in Hoon.
23"Type" is a great word, but Hoon has three separate concepts
23"Type" is a great word, but Hoon has three separate concepts
24which could comfortably claim it. We say "type" all the time; we
24which could comfortably claim it. We say "type" all the time; we
25−mean `span`, or `mold`, or `mark`, or possibly all three.
25+mean [`span`](#span), or `mold`, or `mark`, or possibly all three.
26
26
27Other common programming concepts used only informally in Hoon
27Other common programming concepts used only informally in Hoon
28are "function," "object," "event," "expression," "variable,"
28are "function," "object," "event," "expression," "variable,"
@@ -38,8 +38,8 @@ a few new words is a small price for avoiding this pain point.
38## Concepts
38## Concepts
39
39
40A few major Hoon concepts: `noun` (data), `nock` (interpreter),
40A few major Hoon concepts: `noun` (data), `nock` (interpreter),
41−`mint` (compiler), `span` (type), `twig` (expression), `gate`
41+[`mint`](#mint) (compiler), [`span`](#span) (type), [`twig`](#twig) (expression),
42−(function), `mold` (constructor), `core` (object), `mark`
42+`gate` (function), `mold` (constructor), `core` (object), `mark`
43(protocol).
43(protocol).
44
44
45### `noun` (data value)
45### `noun` (data value)
@@ -82,11 +82,11 @@ it's still fun and useful to [learn more](../../nock).
82
82
83## Compilation concepts
83## Compilation concepts
84
84
85−### `mint` (compiler)
85+### <a name="mint">`mint`</a> (compiler)
86
86
87−[`mint`](mint) is the Hoon compiler. It maps a cell `{span twig}` to a
87+[`mint`](#mint) is the Hoon compiler. It maps a cell `{span twig}` to a
88−cell `{span nock}`, where a `span` is a type, a `twig` is a compiled
88+cell `{span nock}`, where a [`span`](#span) is a type, a [`twig`](#twig)
89−expression (AST), and a `nock` is a Nock formula. `mint` accepts
89+is a compiled expression (AST), and a `nock` is a Nock formula. `mint` accepts
90a subject type and a source expression; it produces a product type
90a subject type and a source expression; it produces a product type
91and an executable formula.
91and an executable formula.
92
92
@@ -105,9 +105,9 @@ which makes your program more readable anyway. Also, the dumber
105the compiler, the easier it is for a dumb human to understand
105the compiler, the easier it is for a dumb human to understand
106what the compiler is thinking.
106what the compiler is thinking.
107
107
108−### `twig` (expression)
108+### <a name="twig">`twig`</a> (expression)
109
109
110−A [`twig`](twig) is a Hoon AST node, the result of parsing a
110+A [`twig`](../reference) is a Hoon AST node, the result of parsing a
111source expression. A Hoon source file encodes one twig.
111source expression. A Hoon source file encodes one twig.
112
112
113As the noun that the parser produces, a twig is a tagged union of
113As the noun that the parser produces, a twig is a tagged union of
@@ -146,12 +146,12 @@ or the tall rune syntax (here on one line, with double spaces):
146%- a b
146%- a b
147```
147```
148
148
149−### `span` (type, as range)
149+### <a name="span">`span`</a> (type, as range)
150
150
151−A [`span`](span) is a Hoon type. It defines a set (finite or
151+A `span` is a Hoon type. It defines a set (finite or
152infinite) of nouns and ascribes some semantics to it. There is
152infinite) of nouns and ascribes some semantics to it. There is
153no syntax for spans; they are always defined by inference (ie, by
153no syntax for spans; they are always defined by inference (ie, by
154−`mint`), usually using a constructor (`mold`).
154+[`mint`](#mint)), usually using a constructor (`mold`).
155
155
156### `gate` (function)
156### `gate` (function)
157
157
@@ -179,7 +179,7 @@ A `mold` is a constructor function (`gate`). Its sample is any
179noun; its product is a structured noun. A mold is idempotent;
179noun; its product is a structured noun. A mold is idempotent;
180`(mold (mold x))` always equals `(mold x)`.
180`(mold (mold x))` always equals `(mold x)`.
181
181
182−Since there's no such thing as a span declaration, we use molds
182+Since there's no such thing as a [`span`](#span) declaration, we use molds
183to define useful spans by example; we also use them to validate
183to define useful spans by example; we also use them to validate
184untrusted network input.
184untrusted network input.
185
185
@@ -193,19 +193,19 @@ The Hoon equivalent is `:var foo atom`. But Hoon has a
193homoiconic heap; there is no inscrutable scope or environment.
193homoiconic heap; there is no inscrutable scope or environment.
194There is just the subject, which is one noun. To "declare a
194There is just the subject, which is one noun. To "declare a
195variable" is to make a cell `[variable old-subject]`, and use it
195variable" is to make a cell `[variable old-subject]`, and use it
196−as the subject of the twig below.
196+as the subject of the [`twig`](#twig) below.
197
197
198−So the label `foo` isn't a key in a symbol table; it's in the
198+So the labe[`twig`](#twig)l `foo` isn't a key in a symbol table; it's in the
199−type (`span`) of the new value. It's not a variable named `foo`,
199+type ([`span`](#span)) of the new value. It's not a variable named `foo`,
200whose value is of type `atom`; it's a subtree of type `foo:atom`.
200whose value is of type `atom`; it's a subtree of type `foo:atom`.
201
201
202−### `limb` (attribute or variable reference)
202+### <a name="limb">`limb`</a> (attribute or variable reference)
203
203
204A [`limb`](../twig/limb/limb), like `foo`, is Hoon's equivalent of a variable
204A [`limb`](../twig/limb/limb), like `foo`, is Hoon's equivalent of a variable
205−reference. A limb is a twig; given a subject span, `mint`
205+reference. A limb is a [`twig`](#twig); given a subject [`span`](#span),
206−resolves it to a Nock formula and a product span.
206+[`mint`](#mint) resolves it to a Nock formula and a product [`span`](#span).
207
207
208−To resolve limb `foo`, `mint` searches the subject depth-first,
208+To resolve limb `foo`, [`mint`](#mint) searches the subject depth-first,
209head-first for either a `face` named `foo`, or a `core` with the
209head-first for either a `face` named `foo`, or a `core` with the
210arm `foo`. If it finds a face, the product is a *leg*, or
210arm `foo`. If it finds a face, the product is a *leg*, or
211subtree of the subject. If it finds a core, it computes the arm
211subtree of the subject. If it finds a core, it computes the arm
@@ -213,7 +213,7 @@ formula with that core as the subject.
213
213
214A limb can also be a slot (direct tree address), like `+15`.
214A limb can also be a slot (direct tree address), like `+15`.
215
215
216−### `wing` (limb path)
216+### `wing` ([`limb`](#limb) path)
217
217
218A [wing](../twig/limb/wing) is a list of limbs. Like attribute references in a
218A [wing](../twig/limb/wing) is a list of limbs. Like attribute references in a
219conventional language, it uses the syntax `a.b.c`, but inside
219conventional language, it uses the syntax `a.b.c`, but inside
docs/hoon/demo.md+52−37
@@ -11,53 +11,68 @@ Here's everyone's favorite whiteboard example, FizzBuzz. Each
11line is commented with its number:
11line is commented with its number:
12
12
13```
13```
14−:gate end/atom :: 1
14+|= end/atom :: 1
15−:var count 1 :: 2
15+=/ count 1 :: 2
16−:loop :: 3
16+|- :: 3
17−:cast (list tape) :: 4
17+^- (list tape) :: 4
18−:if =(end count) :: 5
18+?: =(end count) :: 5
19− ~ :: 6
19+ ~ :: 6
20−:cons :: 7
20+:- :: 7
21− :if =(0 (mod count 15)) :: 8
21+ ?: =(0 (mod count 15)) :: 8
22− "FizzBuzz" :: 9
22+ "FizzBuzz" :: 9
23− :if =(0 (mod count 5)) :: 10
23+ ?: =(0 (mod count 5)) :: 10
24− "Fizz" :: 11
24+ "Fizz" :: 11
25− :if =(0 (mod count 3)) :: 12
25+ ?: =(0 (mod count 3)) :: 12
26− "Buzz" :: 13
26+ "Buzz" :: 13
27− (pave :wrap(count)) :: 14
27+ (pave !>(count)) :: 14
28−:moar(count (add 1 count)) :: 15
28+$(count (add 1 count)) :: 15
29```
29```
30
30
31−Can you understand this code by just looking at it? Maybe.
32−But let's explain it anyway.
33−
34Hoon is a functional language. FizzBuzz is usually defined as a
31Hoon is a functional language. FizzBuzz is usually defined as a
35−side effect, but Hoon has no side effects. This code will
32+side effect, but officially Hoon has no side effects. This code
36−*make* a list of strings, not *print* a list of strings.
33+will *return* a list of strings, not *print* a list of strings.
34+(Of course, if you run this code from the Urbit `dojo` (shell) you
35+will be able to see the product.)
36+
37+The code produces a list in which each item is either a number
38+(as a string), "Fizz", "Buzz", or "Fizzbuzz". The value `~` is
39+"null" and indicates the end of the list.
37
40
41+Line 1 uses the `|=`
42+*[rune](https://urbit.org/docs/about/glossary#rune)* to define a
38−Line 1 defines a function of one argument, `end`, an unsigned
43+function of one argument, `end`, which is of the type `atom` (i.e.
39−integer.
44+an unsigned integer).
40
45
41Line 2 declares a variable, `count`, with initial value `1`.
46Line 2 declares a variable, `count`, with initial value `1`.
42
47
43Line 3 begins a loop.
48Line 3 begins a loop.
44
49
45−Line 4 casts the product of the loop to a list of `tape`
50+Line 4 defines the product of the loop as a list of `tape`s.
46−(string as a character list).
51+(A `tape` is a list of characters, one of Hoon's two string
52+types.) The `^-` rune is used for defining the product type the function
53+is to return.
47
54
55+Line 5 uses the `?:` rune, which is a conditional. This line
48−Line 5 checks if `count` equals `end`. If so, line 6 (and the
56+checks whether `count` equals `end`. If so, line 6 (and the
49−whole loop) produces the value `~`, null, the empty list. If
57+whole loop) returns the value `~`. The list is finished. If not,
50−not, line 7 begins an ordered pair.
58+line 7 produces an ordered pair. This pair will be: (a) the next
59+item in the list, determined by lines 8-14; and (b) the rest of
60+the list, determined by line 15.
51
61
52−The head of the pair is "FizzBuzz", or "Fizz", or "Buzz", if the
62+(a) The head of the pair is: (i) "FizzBuzz", or "Fizz", or
53−respective tests hit. If not, line 14 wraps a runtime type
63+"Buzz", if the respective tests hit; otherwise, it's
54−around `count`, then prints the type-value pair to a string (like
64+(ii) the number in question, `count`. In case (ii), line 14
55−C `sprintf()`). This string is the first item in the output list.
65+makes `count` into a `tape`, first by using `!>` to produce a
66+pair: runtime type of `count`, and `count` itself. `pave` is a
67+Hoon function that converts the type-value pair to a `tape`
68+(like C `sprintf()`).
56
69
70+(b) The tail of the pair&mdash;the rest of the output list&mdash;is
57−The tail of the pair is line 15, which repeats the loop (like
71+produced at line 15, which uses `$()` to repeat the loop (like
58−Clojure `recur`), with `count` incremented. This list of strings
72+Clojure `recur`), with `count` incremented.
59−is the rest of the output list.
60
73
61−You can test this code by mounting your home desk with `|mount %`;
74+You can test this code by mounting your home desk with
75+`|mount %` from the dojo; saving the above code as
62−copying it into `home/gen/fizzbuzz.hoon` in your Urbit pier; then
76+`home/gen/fizzbuzz.hoon` in your Urbit
77+[pier](https://urbit.org/docs/about/glossary#pier); then typing
63−typing `+fizzbuzz 100` in the Urbit dojo (shell).
78+`+fizzbuzz 100` in the dojo.
docs/hoon/library/2b.md+1−1
@@ -834,7 +834,7 @@ Source
834Examples
834Examples
835--------
835--------
836
836
837− > =a =|({p=@ q=@} |.((gth p q)))
837+ > =a =|({p/@ q/@} |.((gth p q)))
838 > (sort (limo [0 1 2 3 ~]) a)
838 > (sort (limo [0 1 2 3 ~]) a)
839 ~[3 2 1 0]
839 ~[3 2 1 0]
840
840
docs/hoon/library/2i.md+39−35
@@ -18,8 +18,8 @@ pairs. The contained arms inherit it's sample map, `a`.
18
18
19`a` is a map.
19`a` is a map.
20
20
21− > ~(. by (mo (limo [%a 1] [%b 2] ~)))
21+ > ~(. by (my [%a 1] [%b 2] ~))
22− <19.irb [nlr([p={%a %b} q=@ud]) <414.rvm 101.jzo 1.ypj %164>]>
22+ <22.znh {a/nlr({p/?($a $b) q/@ud}) <409.ofg 110.xht 1.ztu $151>}>
23
23
24------------------------------------------------------------------------
24------------------------------------------------------------------------
25
25
@@ -44,10 +44,10 @@ Computes the logical AND on the results of slamming every element in map
44
44
45`b` is a wet gate.
45`b` is a wet gate.
46
46
47− > =b (mo `(list {@t *})`[['a' 1] ['b' [2 3]] ~])
47+ > =b (my [['a' 1] ['b' [2 3]] ~])
48 > (~(all by b) |=(a/* ?@(a & |)))
48 > (~(all by b) |=(a/* ?@(a & |)))
49 %.n
49 %.n
50− > =a (mo `(list {@t @u})`[['a' 1] ['b' 2] ['c' 3] ['d' 4] ['e' 5] ~])
50+ > =a (my [['a' 1] ['b' 2] ['c' 3] ['d' 4] ['e' 5] ~])
51 > (~(all by a) |=(a/@ (lte a 6)))
51 > (~(all by a) |=(a/@ (lte a 6)))
52 %.y
52 %.y
53 > (~(all by a) |=(a/@ (lte a 4)))
53 > (~(all by a) |=(a/@ (lte a 4)))
@@ -74,11 +74,11 @@ gate `b`. Produces a loobean.
74
74
75`b` is a wet gate.
75`b` is a wet gate.
76
76
77− > =b (mo `(list {@t *})`[['a' 1] ['b' [2 3]] ~])
77+ > =b (my [['a' 1] ['b' [2 3]] ~])
78− > (~(all by b) |=(a/* ?@(a & |)))
78+ > (~(any by b) |=(a/* ?@(a & |)))
79 %.y
79 %.y
80− > =a (mo `(list {@t @u})`[['a' 1] ['b' 2] ['c' 3] ['d' 4] ['e' 5] ~])
80+ > =a (my [['a' 1] ['b' 2] ['c' 3] ['d' 4] ['e' 5] ~])
81− > (~(any by a) |=(a=@ (lte a 4)))
81+ > (~(any by a) |=(a/@ (lte a 4)))
82 %.y
82 %.y
83
83
84------------------------------------------------------------------------
84------------------------------------------------------------------------
@@ -111,9 +111,9 @@ Produces map `a` with the element located at key `b` removed.
111
111
112`b` is a key as a noun.
112`b` is a key as a noun.
113
113
114− > =b (mo `(list {@t *})`[['a' 1] ['b' [2 3]] ~])
114+ > =b (my [['a' 1] ['b' [2 3]] ~])
115− > (~(del by b) `a`)
115+ > (~(del by b) 'a')
116− {[p=`b` q=[2 3]]}
116+ {[p='b' q=[2 3]]}
117
117
118------------------------------------------------------------------------
118------------------------------------------------------------------------
119
119
@@ -139,8 +139,8 @@ Produce the axis of key `b` within map `a`.
139
139
140`b` is a key as a noun.
140`b` is a key as a noun.
141
141
142− > =b (mo `(list {@t *})`[['a' 1] ['b' [2 3]] ~])
142+ > =b (my [['a' 1] ['b' [2 3]] ~])
143− > (~(dig by b) `b`)
143+ > (~(dig by b) 'b')
144 [~ 2]
144 [~ 2]
145
145
146------------------------------------------------------------------------
146------------------------------------------------------------------------
@@ -165,10 +165,10 @@ Insert a list of key-value pairs `b` into map `a`.
165
165
166`b` is a list of cells of key-value nouns `p` and `q`.
166`b` is a list of cells of key-value nouns `p` and `q`.
167
167
168− > =a (mo `(list {@t *})`[[`a` 1] [`b` 2] ~])
168+ > =a (my [['a' 1] ['b' 2] ~])
169− > =b `(list {@t *})`[[`c` 3] [`d` 4] ~]
169+ > =b [['c' 3] ['d' 4] ~]
170 > (~(gas by a) b)
170 > (~(gas by a) b)
171− {[p=`d` q=4] [p=`a` q=1] [p=`c` q=3] [p=`b` q=2]}
171+ {[p='d' q=4] [p='a' q=1] [p='c' q=3] [p='b' q=2]}
172
172
173------------------------------------------------------------------------
173------------------------------------------------------------------------
174
174
@@ -194,8 +194,8 @@ Produce the unit value of the value located at key `b` within map `a`.
194
194
195`b` is a key as a noun
195`b` is a key as a noun
196
196
197− > =b (mo `(list {@t *})`[['a' 1] ['b' [2 3]] ~])
197+ > =b (my [['a' 1] ['b' [2 3]] ~])
198− > (~(get by b) `b`)
198+ > (~(get by b) 'b')
199 [~ [2 3]]
199 [~ [2 3]]
200
200
201------------------------------------------------------------------------
201------------------------------------------------------------------------
@@ -215,7 +215,7 @@ does not exist.
215
215
216`b` is a key.
216`b` is a key.
217
217
218− > =m (mo `(list {@t *})`[['a' 1] ['b' 2] ~])
218+ > =m (my [['a' 1] ['b' 2] ~])
219 > m
219 > m
220 {[p='a' q=1] [p='b' q=2]}
220 {[p='a' q=1] [p='b' q=2]}
221 > (~(get by m) 'a')
221 > (~(get by m) 'a')
@@ -244,10 +244,10 @@ loobean.
244
244
245`b` is a key as a noun.
245`b` is a key as a noun.
246
246
247− > =b (mo `(list {@t *})`[['a' 1] ['b' [2 3]] ~])
247+ > =b (my [['a' 1] ['b' [2 3]] ~])
248− > (~(has by b) `b`)
248+ > (~(has by b) 'b')
249 %.y
249 %.y
250− > (~(has by b) `c`)
250+ > (~(has by b) 'c')
251 %.n
251 %.n
252
252
253------------------------------------------------------------------------
253------------------------------------------------------------------------
@@ -285,27 +285,27 @@ different values, the element from map `b` is used.
285
285
286`b` is a map.
286`b` is a map.
287
287
288− > =n (mo `(list {@t *})`[['a' 1] ['c' 3] ~])
288+ > =n (my [['a' 1] ['c' 3] ~])
289 > n
289 > n
290 {[p='a' q=1] [p='c' q=3]}
290 {[p='a' q=1] [p='c' q=3]}
291 > m
291 > m
292 {[p='a' q=1] [p='b' q=2]}
292 {[p='a' q=1] [p='b' q=2]}
293 > (~(int by m) n)
293 > (~(int by m) n)
294 {[p='a' q=1]}
294 {[p='a' q=1]}
295− ~ravpel-holber/try=> =p (mo `(list {@t *})`[['a' 2] ['b' 2] ~])
295+ > =p (my [['a' 2] ['b' 2] ~])
296 > p
296 > p
297 {[p='a' q=2] [p='b' q=2]}
297 {[p='a' q=2] [p='b' q=2]}
298 > (~(int by p) n)
298 > (~(int by p) n)
299− {[p='a' q=2]}
299+ {[p='a' q=1]}
300− > =q (mo `(list {@t *})`[['a' 2] ['c' 2] ~])
300+ > =q (my [['a' 2] ['c' 2] ~])
301 > q
301 > q
302− {[p='a' q=2] [p='b' q=2]}
302+ {[p='a' q=2] [p='c' q=2]}
303 > (~(int by p) q)
303 > (~(int by p) q)
304− {[p='a' q=2] [p='b' q=2]}
304+ {[p='a' q=2]}
305− > =o (mo `(list {@t *})`[['c' 3] ['d' 4] ~])
305+ > =o (my [['c' 3] ['d' 4] ~])
306 > (~(int by m) o)
306 > (~(int by m) o)
307 {}
307 {}
308−
308+
309
309
310------------------------------------------------------------------------
310------------------------------------------------------------------------
311
311
@@ -471,6 +471,7 @@ Produces the list of all elements in map `a` that is prepended to list
471
471
472`b` is a list.
472`b` is a list.
473
473
474+ > m
474 {[p='a' q=1] [p='b' q=2]}
475 {[p='a' q=1] [p='b' q=2]}
475 > `*`m
476 > `*`m
476 [[98 2] [[97 1] 0 0] 0]
477 [[98 2] [[97 1] 0 0] 0]
@@ -521,9 +522,9 @@ shares a key with `a`, the tuple from `b` is preserved.
521 > (~(uni by m) ~)
522 > (~(uni by m) ~)
522 {[p='a' q=1] [p='b' q=2]}
523 {[p='a' q=1] [p='b' q=2]}
523 > n
524 > n
524− {[p='a' q=1] [p='c' q=9]}
525+ {[p='a' q=1] [p='c' q=3]}
525 > (~(uni by o) n)
526 > (~(uni by o) n)
526− {[p='d' q=4] [p='a' q=1] [p='c' q=9]}
527+ {[p='d' q=4] [p='a' q=1] [p='c' q=3]}
527
528
528------------------------------------------------------------------------
529------------------------------------------------------------------------
529
530
@@ -547,11 +548,14 @@ produces a noun (the new value).
547
548
548 > m
549 > m
549 {[p='a' q=1] [p='b' q=2]}
550 {[p='a' q=1] [p='b' q=2]}
551+
550− > (~(urn by m) |=(a=[p=* q=*] q.a))
552+ > (~(urn by m) |=(a/(pair * *) q.a))
551 {[p='a' q=1] [p='b' q=2]}
553 {[p='a' q=1] [p='b' q=2]}
554+
552− > (~(urn by m) |=(a=[p=* q=*] 7))
555+ > (~(urn by m) |=(a/(pair * *) 7))
553 {[p='a' q=7] [p='b' q=7]}
556 {[p='a' q=7] [p='b' q=7]}
557+
554− > (~(urn by m) |=(a=[p=* q=*] p.a))
558+ > (~(urn by m) |=(a/(pair * *) p.a))
555 {[p='a' q=97] [p='b' q=98]}
559 {[p='a' q=97] [p='b' q=98]}
556
560
557------------------------------------------------------------------------
561------------------------------------------------------------------------
docs/hoon/syntax.md+134−125
@@ -7,22 +7,19 @@ title: Syntax
7
7
8# Hoon syntax
8# Hoon syntax
9
9
10−Hoon's semantics are simple, but unusual. Hoon's syntax is
10+Hoon's syntax is unusual, and to beginners it can look a lot more
11−complex, and unusual. Sorry.
11+complex than it really is. However, we believe that anyone who
12+learns Hoon syntax will find that it has a number of advantages.
12
13
13# Motivation
14# Motivation
14
15
15−An excuse: the normal human brain doesn't have hardware support
16−for math, but it does have hardware support for syntax. Learning
17−math is harder than it looks. Learning syntax is easier.
18−
19−An explanation: the Hoon syntax is trying to solve three serious
16+Hoon syntax is trying to solve three serious
20problems in functional syntax design. These are *terminator
17problems in functional syntax design. These are *terminator
21piles*, *indentation creep*, and *feature/label confusion*.
18piles*, *indentation creep*, and *feature/label confusion*.
22
19
23## Terminator piles
20## Terminator piles
24
21
25−*Terminator piles* are like Lisp's stacks of right parentheses.
22+*Terminator piles* are like Lisp's stacks of right parentheses.
26Significant whitespace solves this problem and creates others.
23Significant whitespace solves this problem and creates others.
27
24
28Hoon has no terminator piles. Except for a 1-space / more-space
25Hoon has no terminator piles. Except for a 1-space / more-space
@@ -32,8 +29,9 @@ distinction, it has no significant whitespace.
32
29
33*Indentation creep* is a problem caused by indentation conventions
30*Indentation creep* is a problem caused by indentation conventions
34where the indentation point is a function of expression tree
31where the indentation point is a function of expression tree
32+depth. This problem is especially irritating when working with
35−depth. It's true that short functions are better than long ones,
33+long functions. It's true that short functions are better, but
36−but long ones sometimes need to be written.
34+long ones sometimes need to be written.
37
35
38A procedural block has a backbone of statements which flows
36A procedural block has a backbone of statements which flows
39straight down. Most expressions are flat and of limited depth.
37straight down. Most expressions are flat and of limited depth.
@@ -49,38 +47,37 @@ shaped more or less like procedural programs.
49
47
50## Feature/label confusion
48## Feature/label confusion
51
49
52−*Feature/label confusion* is any syntax which makes it hard for
50+*Feature/label confusion* (FLC) is the result of any syntax that
53−the eye to tell whether a token on the screen is a feature of the
51+makes it hard for the eye to tell whether a token on the screen is
54−language, or a label in the program. For example, in Lisp a
52+a feature of the language, or a label in the program. For example,
55−special form has the same syntax as a function call.
53+in Lisp a special form has the same syntax as a function call.
56
54
57The worst-case result of FLC is "DSL cancer." Every source file
55The worst-case result of FLC is "DSL cancer." Every source file
58is effectively written in its own domain-specific language. To
56is effectively written in its own domain-specific language. To
59−read a new file is to learn a new language -- "write-only code."
57+read a new file is to learn a new language&mdash;"write-only code."
60
58
61−A fixed reserved-word set, especially with syntax highlighting,
62−and especially with orthogonal grammar (in C, you don't write
63−`for(a b c)`), may not be too bad. User-level macros, operator
64−overloading, even excessive use of higher-order programming,
59+User-level macros, operator overloading, even excessive use of
65−can all lead quickly to the tragedy of write-only code.
60+higher-order programming, can all lead quickly to the tragedy of
61+write-only code.
66
62
67−Hoon has very weak FLC in keyword style, none in rune style.
68−It has no user-level macros or overloading. It does support
63+Hoon has no FLC, user-level macros, or overloading. It does
69−higher-order programming; write-only Hoon can certainly be
64+support higher-order programming; write-only Hoon can certainly be
70(and has been) written. But good Hoon style is to avoid it.
65(and has been) written. But good Hoon style is to avoid it.
71
66
72# Design
67# Design
73
68
74−Because each twig stem has its own bulb, each has its own parser
75−rule. We'll describe these grammars as we go through the stems.
76−
77−But Hoon has a general syntax design with common principles and
69+Hoon has a general syntax design with common principles and
78regularities. We'll cover those here.
70regularities. We'll cover those here.
79
71
80## Glyphs and characters
72## Glyphs and characters
81
73
74+Hoon source uses ASCII text. Hoon does not accept non-ASCII
75+text in source files, except UTF-8 in quoted strings. Hard
76+tab characters are illegal.
77+
82−Hoon is a heavy punctuation user. To make ASCII great again,
78+Hoon is a heavy punctuation user. Reading off code aloud
79+using the proper names of ASCII symbols is tedious, so we've
83−we've mapped each punctuation glyph to a syllable:
80+mapped each punctuation glyph to a syllable:
84
81
85```
82```
86ace [1 space] gal < pal (
83ace [1 space] gal < pal (
@@ -97,28 +94,59 @@ fas / pat @ wut ?
97zap !
94zap !
98```
95```
99
96
100−You don't need to memorize these glyph names, but it helps. Code
97+You don't need to memorize these glyph names, but it might help.
101−is often vocalized or subvocalized. "pal" is easier to say,
98+Code is often vocalized or subvocalized. "pal" is easier to say,
102−aloud or silently, then "left paren."
99+aloud or silently, than "left paren".
103
100
104Note that the list includes two separate whitespace forms: `ace`
101Note that the list includes two separate whitespace forms: `ace`
105−for a single space, `gap` for 2+, comment or newline. In Hoon,
102+for a single space; `gap` is either 2+ spaces or a newline. In Hoon,
106the only significance in whitespace is the difference between
103the only significance in whitespace is the difference between
107−`ace` and `gap`.
104+`ace` and `gap`. Comments also count as `gap` whitespace&mdash;they
105+start with `::` and run to the end of the line.
106+
107+An 80-column right margin is strongly encouraged. Really
108+well-groomed Hoon uses a 55-column code margin and puts a standard
109+line comment at column 57.
108
110
109−Comments start with `::` and run to the end of the line. Hard
111+## Expressions and Runes
110−tab characters are illegal, and an 80-column right margin is
111−strongly encouraged. Really well-groomed Hoon uses a 55-column
112−code margin and puts a standard line comment at column 57.
113
112
114−Hoon does not accept non-ASCII text in source files, except UTF-8
113+Each regular Hoon expression begins with a
115−in quoted strings.
114+[rune](https://urbit.org/docs/about/glossary#rune). A rune is a pair
115+of ASCII punctuation marks (a digraph)&mdash;e.g., `:-`. The first
116+glyph in the rune indicates the category&mdash;e.g., `:` runes make
117+[cells](https://urbit.org/docs/about/glossary#cell) (i.e., ordered
118+pairs). We pronounce runes using their glyph names&mdash;for `:-`,
119+we say "colhep".
120+
121+Each rune is followed by one or more subexpressions. The number and
122+kind of subexpressions depend on the rune used.
123+
124+```
125+:- 25
126+3
127+```
128+
129+This twig uses `:-` to produce a cell: `[25 3]`. There are always two
130+subexpressions following the `:-` in syntactically correct Hoon code,
131+the first of which, when evaluated, becomes the *head* (i.e., the left)
132+and the second of which becomes the *tail* (i.e., the right).
133+
134+Hoon expressions are sometimes called
135+[twigs](https://urbit.org/docs/about/glossary#twig). You'll find that
136+Hoon code has a tree-like structure, so you can think of the various
137+expressions as twigs of the tree. The subexpressions following the
138+rune are sometimes called the *children* of that twig.
116
139
117## Tall and flat forms
140## Tall and flat forms
118
141
119There are two kinds of Hoon expression syntax: *tall* and *flat*.
142There are two kinds of Hoon expression syntax: *tall* and *flat*.
120−Most stems have both tall and flat forms. Tall twigs can contain
143+Most runes can be used in both tall and flat twigs. Tall twigs can
121−flat twigs, but not vice versa.
144+contain flat twigs, but not vice versa.
145+
146+The `:-` expression in the last subsection was in tall form. Here's
147+the flat equivalent:
148+
149+`:-(25 3)`
122
150
123Visually, a tall twig looks like a "statement" and a flat twig
151Visually, a tall twig looks like a "statement" and a flat twig
124like an "expression," preserving the attractive visual shape of
152like an "expression," preserving the attractive visual shape of
@@ -126,71 +154,53 @@ procedural code without the nasty side effects.
126
154
127## Regular and irregular forms
155## Regular and irregular forms
128
156
129−Most stems have *regular forms*, which share a common design.
157+Most runes have *regular forms*, which share a common design.
130−There is a regular flat form and a regular tall form; most stems
158+There is a regular flat form and a regular tall form; most runes
131−implement both. All tall forms are regular.
159+have both kinds of implementation. All tall forms are regular.
132
160
133−Some twigs also have *irregular forms*, which follow no
161+Some runes also have *irregular forms*, which follow no
134principles at all. All irregular forms are flat.
162principles at all. All irregular forms are flat.
135
163
136−Some twigs (simple leafy ones) have *only* irregular forms.
164+```
137−
165+.= 22
138−## Keywords versus runes
166+23
139−
167+```
140−A regular form starts with a *sigil*, which is either a
141−*keyword* or a *rune* -- at the programmer's choice.
142−
143−A *keyword* is `:` and then the stem label - e.g., `:cons`.
144−
145−A *rune* is a pair of ASCII punctuation marks (a digraph) - e.g.,
146−`:-`. The first glyph in the rune indicates the category - e.g.,
147−`:` runes make cells. Runes can be pronounced by their glyphs or
148−by their stem -- for `:-`, you can say either "colhep" or "cons".
149
168
150−Keywords may be less challenging for early learners. Rune style
169+The `.=` rune tests for equality the two subexpressions that
151−is less cluttered and distracting for experienced programmers;
170+follow, and returns a boolean. Above is the tall, regular form of
152−the system codebase is all in rune style. Beginners can start
171+`.=`. Below is the irregular form:
153−with keywords and move to runes; start with runes and stick
154−with runes; or start with keywords and stick with keywords.
155
172
156−Here's the FizzBuzz demo code, in idiomatic rune syntax. Compare
173+`=(22 23)`
157−with the [original](../demo).
158
174
159−```
175+Some twigs have *only* irregular forms.
160− |= end/atom
161− =/ count 1
162− |- ^- (list tape)
163− ?: =(end count) ~
164− :_ $(count (add 1 count))
165− ?: =(0 (mod count 15))
166− "FizzBuzz"
167− ?: =(0 (mod count 5))
168− "Fizz"
169− ?: =(0 (mod count 3))
170− "Buzz"
171− (pave !>(count))
172−```
173
176
174## Tall regular form
177## Tall regular form
175
178
176−Tall regular form starts with the sigil, followed by a `gap`
179+Tall regular forms start with a rune followed by a `gap`.
177−(any whitespace except `ace`), followed by a bulb whose twigs are
180+(Remember, a `gap` is any whitespace other than `ace`.) After
178−separated by `gap`.
181+that are the number and types of subexpressions appropriate for
182+that rune. Each subexpression is separated from its neighboring
183+subexpressions by a `gap`.
184+
185+Let's call everything in the twig after the initial rune the twig
186+*body*. There are four body subtypes: *fixed*, *running*, *jogging*,
187+and *[battery](https://urbit.org/docs/about/glossary#battery)*.
179
188
180−There are four body subtypes: *fixed*, *running*, *jogging*, and
181−*battery*. Stems with a *fixed* number of subexpressions
189+Runes with a *fixed* number of subexpressions self-terminate. For
182−self-terminate. For instance, `:if` has three subexpressions and
190+instance, the `:-` and `.=` runes each have two subexpressions
183−is self-terminating. Otherwise the twig is terminated by a
191+and are self-terminating. Otherwise the twig is terminated by both
184−`gap`, then either `==` (*running* or *jogging*, most twigs) or
192+a `gap`, then either `==` (*running* or *jogging*, most twigs) or
185`--` (*battery*).
193`--` (*battery*).
186
194
187−The *running* body is a list of twigs. The *jogging* body is a
195+The *running* body has a list of *children* (i.e., subexpressions).
196+The *jogging* body has a list of child pairs, where the members of
188−list of twig pairs, separated by a `gap`. The *battery* body is
197+each pair are separated by a `gap`. The *battery* body is
189−a list of symbol-twig pairs, separated by a gap, prefixed by `++`
198+a list of symbol-child pairs, separated by a gap, prefixed by `++`
190and then a gap.
199and then a gap.
191
200
192−This definition is enough to parse. But the proper shape of the
201+This definition is enough to write Hoon that will parse. But
193−whitespace gaps demands an informal convention.
202+writing code with optimal whitespace management requires some
203+additional informal conventions.
194
204
195Whitespace design in Hoon is an art, not a science. It involves
205Whitespace design in Hoon is an art, not a science. It involves
196both tall/flat mode switches and well-shaped gaps. (Hoon layout
206both tall/flat mode switches and well-shaped gaps. (Hoon layout
@@ -199,15 +209,15 @@ But it would at least take machine learning, not a rule engine.)
199
209
200There are only two real *rules* in Hoon whitespace design: don't
210There are only two real *rules* in Hoon whitespace design: don't
201go past 80 characters, and don't use (completely) blank lines.
211go past 80 characters, and don't use (completely) blank lines.
202−Otherwise, if it looks good and is easy to read, it's good. But
212+Otherwise, if it looks good and is easy to read, it's good. The
203−the best way to learn the art is to do everything by convention
213+best way to learn the art is to do everything by convention
204until you know what you're doing. Here are the conventions:
214until you know what you're doing. Here are the conventions:
205
215
206### Conventions: *fixed*
216### Conventions: *fixed*
207
217
208−Bulbs with *fixed* fanout use "backstep" indentation, which slopes
218+Twig bodies with *fixed* fanout use "backstep" indentation, which
209−backward and to the right by two spaces per line. The first
219+slopes backward and to the right by two spaces per line. The first
210−child is two spaces after the end of the sigil.
220+twig child is two spaces after the end of the rune.
211
221
212Some *1-fixed*, *2-fixed*, *3-fixed* and *4-fixed* examples:
222Some *1-fixed*, *2-fixed*, *3-fixed* and *4-fixed* examples:
213
223
@@ -228,15 +238,14 @@ r
228s
238s
229```
239```
230
240
231−The hope of backstep indentation is that the heaviest twigs are
241+In optimal usage of backstep indentation, the most complicated twigs
232−at the bottom, keeping code flow vertical rather than diagonal.
242+are at the bottom, keeping code flow vertical rather than diagonal.
233−
234
243
235### Conventions: *running*
244### Conventions: *running*
236
245
237−A *running* bulb (a simple child list) puts the first child two
246+A *running* twig body (a simple child list) puts the first child two
238−spaces after the end of the sigil, and the following children
247+spaces after the end of the rune, and the following children straight
239−straight down:
248+down:
240
249
241A *running* example:
250A *running* example:
242
251
@@ -251,10 +260,11 @@ A *running* example:
251
260
252### Conventions: *jogging*
261### Conventions: *jogging*
253
262
254−A *jogging* bulb (a list of child pairs) is like a running bulb,
263+A *jogging* twig body (a list of child pairs) is like a running
255−but backsteps the head of the pair above the tail. Most jogging
264+body, but with a pair of children on each line, separated by
256−twigs start with a *fixed* sequence; the first jogging pair is
265+two spaces. Most jogging bodies start with a *fixed* sequence;
257−below and two steps backward from the last fixed child.
266+the first jogging pair is below and two steps backward from the
267+last fixed child.
258
268
259There are two jogging conventions: *flat* (pair on one line) and
269There are two jogging conventions: *flat* (pair on one line) and
260*tall* (pair split across lines).
270*tall* (pair split across lines).
@@ -284,8 +294,11 @@ A *tall jogging* example (preceded by *1-fixed* `p`):
284
294
285### Conventions: *battery*
295### Conventions: *battery*
286
296
287−A *battery* bulb is a list of symbol-twig pairs, for the battery
297+A *battery* body has a list of symbol-child pairs, for the
298+[battery](https://urbit.org/docs/about/glossary#battery)
299+of a
300+[core](https://urbit.org/docs/about/glossary#core). A
288−of a core. A conventional example:
301+conventional example:
289
302
290```
303```
291|%
304|%
@@ -300,24 +313,20 @@ of a core. A conventional example:
300
313
301## Flat regular form
314## Flat regular form
302
315
303−Flat regular form starts with the sigil, followed by `pal`
316+Flat regular form starts with the rune, followed by `pal`, `(`
304−(`(`, left parenthesis), followed by a bulb whose subexpressions
317+(left parenthesis), followed by a body whose subexpressions
305−are separated by `ace` (one space), followed by `par` (`)`, right
318+are separated by `ace` (one space), followed by `par`, `)` (right
306parenthesis).
319parenthesis).
307
320
308A twig in flat form, `:if`, `?:`, `{$if p/twig q/twig r/twig}`:
321A twig in flat form, `:if`, `?:`, `{$if p/twig q/twig r/twig}`:
309
322
310−```
311−:if(p q r)
312−
313−?:(p q r)
323+`?:(p q r)`
314−```
315
324
316The only exception is *jogging* bodies, in which subexpression
325The only exception is *jogging* bodies, in which subexpression
317pairs are separated by commas:
326pairs are separated by commas:
318
327
319```
328```
320−:make(foo bar 42, baz 55, moo 17)
329+foo(bar 42, baz 55, moo 17)
321```
330```
322
331
323There is no flat regular form for *battery* bodies. Be tall.
332There is no flat regular form for *battery* bodies. Be tall.
@@ -326,7 +335,7 @@ There is no flat regular form for *battery* bodies. Be tall.
326
335
327Hoon does not enforce any rule on symbols, except that capitals
336Hoon does not enforce any rule on symbols, except that capitals
328are not allowed (use kebab-case). However, a lot of system code
337are not allowed (use kebab-case). However, a lot of system code
329−is written in using "lapidary" conventions that need explanation.
338+is written using "lapidary" conventions that need explanation.
330
339
331Naming things is one of the hard problems in CS. Dodging this
340Naming things is one of the hard problems in CS. Dodging this
332problem is one of the reasons mathematicians use Greek letters,
341problem is one of the reasons mathematicians use Greek letters,
@@ -346,11 +355,11 @@ appropriate.
346
355
347In the *ultralapidary* naming style, labels are single letters,
356In the *ultralapidary* naming style, labels are single letters,
348starting in order of construction from `a`, or within a tuple
357starting in order of construction from `a`, or within a tuple
358+[mold](https://urbit.org/docs/about/glossary#mold) `p`. Hoon
349−mold `p`. Hoon uses single-letter names for the same reason
359+uses single-letter names for the same reason Algol style
350−Algol style languages pass arguments by order, rather than
360+languages pass arguments by order, rather than keyword. Naming
351−keyword. Naming items by order makes sense when there are no
361+items by order makes sense when there are no more than three or
352−more than three or four; five is stretching it; six is outright
362+four; five is stretching it; six is outright ridiculous.
353−ridiculous.
354
363
355For example, when defining `add`, we want to name the operands
364For example, when defining `add`, we want to name the operands
356`a` and `b`. It's silly to call them `foo` and `bar`, let alone
365`a` and `b`. It's silly to call them `foo` and `bar`, let alone
docs/hoon/twig/cen-call/tar-bake.md+12−2
@@ -18,7 +18,7 @@ r
18
18
19```
19```
20=+ q
20=+ q
21−=% p
21+%= p
22r
22r
23```
23```
24
24
@@ -26,6 +26,12 @@ r
26
26
27Regular: *2-fixed*, then *jogging*.
27Regular: *2-fixed*, then *jogging*.
28
28
29+## Discussion
30+
31+`%*` makes a limb from a twig, with changes. It's useful when you want
32+evaluate a twig, pull out a single limb from the result,
33+and then change some parts of the limb before using it.
34+
29## Examples
35## Examples
30
36
31```
37```
@@ -33,5 +39,9 @@ Regular: *2-fixed*, then *jogging*.
335
395
34~zod:dojo> =foo [a=1 b=2 c=3 d=4]
40~zod:dojo> =foo [a=1 b=2 c=3 d=4]
35~zod:dojo> %*(+ foo c %hello, d %world)
41~zod:dojo> %*(+ foo c %hello, d %world)
36−[b=2 c=%hello d=%world e=5]
42+[b=2 c=%hello d=%world]
43+~zod:dojo> =+(foo=[a=1 b=2 c=3] foo(b 7, c 10))
44+[a=1 b=7 c=10]
45+~zod:dojo> %*(foo [foo=[a=1 b=2 c=3]] b 7, c 10)
46+[a=1 b=7 c=10]
37```
47```
docs/hoon/twig/sem-make/sem-fry.md+2−2
@@ -11,13 +11,13 @@ sort: 1
11
11
12```
12```
13:pin :name(a (p q))
13:pin :name(a (p q))
14−:sure =(a (p a))
14+:sure =(`*`a `*`q)
15a
15a
16```
16```
17
17
18```
18```
19=+ a=(p q)
19=+ a=(p q)
20−?> =(a (p a))
20+?> =(`*`a `*`q)
21a
21a
22```
22```
23
23
docs/hoon/twig/sem-make/sig-dip.md+41−2
@@ -13,6 +13,40 @@ product-sample adapter.
13The gates in `q` connected together using the gate `p`, which
13The gates in `q` connected together using the gate `p`, which
14transforms a `q` product and a `q` gate into a `q` sample.
14transforms a `q` product and a `q` gate into a `q` sample.
15
15
16+## Expands to
17+
18+*Note: these are structurally correct, but elide some type-system complexity.*
19+
20+`;~(a b)` reduces to `b`.
21+
22+`;~(a b c)` expands to
23+
24+```
25+|= arg/*
26+(a (b arg) c(+6 arg))
27+```
28+
29+`;~(a b c d)` expands to
30+
31+```
32+|= arg/*
33+%+ a (b arg)
34+=+ arg=arg
35+|. (a (c arg) d(+6 arg))
36+```
37+
38+### Compiler macro
39+
40+```
41+?~ q !!
42+|-
43+?~ t.q i.q
44+=/ a $(q t.q)
45+=/ b i.q
46+=/ c ,.+6.b
47+|. (p (b c) a(,.+6 c))
48+```
49+
16## Discussion
50## Discussion
17
51
18Apparently `:dip` is a "Kleisli arrow." Whatevs. It's also
52Apparently `:dip` is a "Kleisli arrow." Whatevs. It's also
@@ -22,6 +56,11 @@ so you don't need to either.
22
56
23`:dip` is often used in parsers, but is not only for parsers.
57`:dip` is often used in parsers, but is not only for parsers.
24
58
59+This can be thought of as user-defined function composition; instead of simply
60+nesting the gates in `q`, each is passed individually to `p` with the product
61+of the previous gate, allowing arbitrary filtering, transformation, or
62+conditional application.
63+
25## Syntax
64## Syntax
26
65
27Regular: *1-fixed*, then *running*.
66Regular: *1-fixed*, then *running*.
@@ -32,9 +71,9 @@ A simple "parser." `trip` converts a `cord` (atomic string) to
32a `tape` (linked string).
71a `tape` (linked string).
33
72
34```
73```
35−~zod:dojo> =cmp |=({a/tape b/$-(char tape)] `tape`?~(a ~ (weld (b i.a) t.a)))
74+~zod:dojo> =cmp |=({a/tape b/$-(char tape)} `tape`?~(a ~ (weld (b i.a) t.a)))
36~zod:dojo> ;~(cmp trip)
75~zod:dojo> ;~(cmp trip)
37−<1.xef [a=@ <374.hzt 100.kzl 1.ypj %164>]>
76+<1.zje {a/@ <409.yxa 110.lxv 1.ztu $151>}>
38~zod:dojo> (;~(cmp trip) 'a')
77~zod:dojo> (;~(cmp trip) 'a')
39"a"
78"a"
40```
79```
docs/hoon/twig/wut-test.md+1−1
@@ -15,7 +15,7 @@ learning from `$fits` tests in the condition of `:if` twigs.
15All `?` runes expand to `$if` (`?:`) and/or `$fits` (`?=`).
15All `?` runes expand to `$if` (`?:`) and/or `$fits` (`?=`).
16
16
17If the condition of an `$if` is a `$fits`, *and* the `$fits` is
17If the condition of an `$if` is a `$fits`, *and* the `$fits` is
18−testing a leg of the subject, the compile specializes the subject
18+testing a leg of the subject, the compiler specializes the subject
19span for the branches of the `$if`. Branch inference also works
19span for the branches of the `$if`. Branch inference also works
20for twigs which expand to `$if`.
20for twigs which expand to `$if`.
21
21
docs/using/install.md+6−6
@@ -16,7 +16,7 @@ Debian (jessie), Mac OS X, FreeBSD and Fedora all work well.
16If you run into trouble installing Urbit, please let us know via
16If you run into trouble installing Urbit, please let us know via
17email, [questions@urbit.org](mailto:questions@urbit.org), or on the
17email, [questions@urbit.org](mailto:questions@urbit.org), or on the
18forum: [urbit.org/fora](https://urbit.org/fora). You can also chat
18forum: [urbit.org/fora](https://urbit.org/fora). You can also chat
19−with us at [urbit.org/stream](https://urbit.org/fora).
19+with us at [urbit.org/stream](https://urbit.org/stream).
20
20
21> Urbit is alpha software. It’s not yet completely stable, its crypto
21> Urbit is alpha software. It’s not yet completely stable, its crypto
22> hasn’t been audited, and there are plenty of rough edges. Urbit is
22> hasn’t been audited, and there are plenty of rough edges. Urbit is
@@ -41,13 +41,13 @@ below.
41
41
42**Debian**
42**Debian**
43
43
44−- Download `urbit_0.4.3-1_amd64.deb` [here](https://media.urbit.org/dist/debian/urbit_0.4.3-1_amd64.deb).
44+- Download `urbit_0.4.5-1_amd64.deb` [here](https://media.urbit.org/dist/debian/urbit_0.4.5-1_amd64.deb).
45−- Install with `dpkg -i urbit_0.4.3-1_amd64.deb`
45+- Install with `dpkg -i urbit_0.4.5-1_amd64.deb`
46- Then `apt-get install -f` to install any missing dependencies
46- Then `apt-get install -f` to install any missing dependencies
47
47
48## Source
48## Source
49
49
50−First, fetch the source tarball: **[urbit-0.4.3.tar.gz](https://media.urbit.org/dist/src/urbit-0.4.3.tar.gz)**.
50+First, fetch the source tarball: **[urbit-0.4.5.tar.gz](https://media.urbit.org/dist/src/urbit-0.4.5.tar.gz)**.
51
51
52### Dependencies
52### Dependencies
53
53
@@ -93,8 +93,8 @@ Which can usually be installed with the following one-liners:
93
93
94Once your dependencies are installed the rest is easy:
94Once your dependencies are installed the rest is easy:
95
95
96− $ tar xfvz urbit-0.4.tar.gz
96+ $ tar xfvz urbit-0.4.5.tar.gz
97− $ cd urbit-0.4
97+ $ cd urbit-0.4.5
98 $ make # gmake on FreeBSD
98 $ make # gmake on FreeBSD
99
99
100After running `make`, your Urbit executable is in `bin/urbit`. Install it wherever you'd like.
100After running `make`, your Urbit executable is in `bin/urbit`. Install it wherever you'd like.
docs/using/messaging.md+6
@@ -289,3 +289,9 @@ All nicknames must be 14 characters or less, lowercase. Nicknames are
289strictly local - like the names on entries in a phonebook. Sometimes in
289strictly local - like the names on entries in a phonebook. Sometimes in
290a post you want to mention someone you know by a nickname. Just type
290a post you want to mention someone you know by a nickname. Just type
291`~plato`, and `:talk` will replace it with `~your-urbit`.
291`~plato`, and `:talk` will replace it with `~your-urbit`.
292+
293+### Timestamps
294+
295+`;set showtime` - Show the timestamp for each message
296+
297+`;unset showtime` - Stop showing the timestamp for each message
docs/using/setup.md−3
@@ -38,9 +38,6 @@ matter:
38This will create the directory `mycomet/` and generate a 128-bit
38This will create the directory `mycomet/` and generate a 128-bit
39identity for your urbit.
39identity for your urbit.
40
40
41−WARNING: right now (June 2017) the network is extremely slow.
42−It will take hours, not minutes, to boot your ship. Sorry!
43−
44## Orientation
41## Orientation
45
42
46When your urbit is finished booting you should see a `dojo>` prompt.
43When your urbit is finished booting you should see a `dojo>` prompt.
readme.md+75−8
@@ -1,14 +1,81 @@
1−Urbit docs
1+# Urbit docs
2−==========
3
2
4−These are the urbit docs as they appear on [urbit.org](urbit.org/docs).
3+These are the urbit docs as they appear on [urbit.org](urbit.org/docs).
5
4
6−If you'd like to serve the contents from your Urbit just copy `docs/` and `docs.md` into `web/` inside your urbit.
5+We've found it helps to have a clone of the docs on hand in case urbit.org
6+experiences high traffic. Follow these steps to get these into your ship:
7
7
8+## Installation
8
9
9−Contributing
10+First, you'll need a running urbit. Follow our urbit.org [install
10−============
11+instructions](https://urbit.org/docs/using/install), then
12+[setup](https://urbit.org/docs/using/setup) an urbit.
11
13
12−PRs are more than welcome: both corrections and suggestions.
14+Follow the *Network install* below if your urbit is running on the live network
15+(comets are usually best for development). Follow the *Local install* instead if
16+you're on a [fake
17+ship](https://urbit.org/fora/posts/~2017.1.5..21.31.04..20f3~/) or are otherwise
18+experiencing problems with the network install.
13
19
14−We're almost always available on `:talk`, but you can also email [`urbit@urbit.org`](mailto:urbit@urbit.org) or post to [`urbit-dev`](https://groups.google.com/forum/#!forum/urbit-dev) if you have questions.
20+### Network install
21+
22+In your urbit's `:dojo`, run the command:
23+
24+ ~your-urbit:dojo> |sync %home ~ropmev-pocseb %docs
25+
26+Depending on network traffic, this initial merge and sync could take anywhere
27+between thirty seconds to several minutes. Upon a successful sync you'll see the
28+output:
29+
30+ sync succeeded from %docs on ~ropmev-pocseb to %home
31+
32+If your sync isn't succeeding after a few minutes for whatever reason, run
33+`|cancel %home` in your `:dojo` and follow the local install below instead.
34+
35+### Local install
36+
37+In your urbit's `:dojo`:
38+
39+ ~your-urbit:dojo> |mount /=home=
40+
41+If `~your-urbit` was installed at `/urbit/path` on your Unix machine, you can
42+now find your home desk at the path `/urbit/path/your-urbit/home`.
43+
44+In Unix, clone this repo somewhere and copy in the `docs` files to your urbit's
45+mounted `%home` desk. You can run the following shell commands (*replacing your
46+urbit's home desk path as necessary*):
47+
48+ $ git clone https://github.com/urbit/docs
49+ $ cp -r ./docs* /urbit/path/your-urbit/home/web
50+
51+Your `%clay` filesystem should acknowledge the newly added files.
52+
53+Lastly, serve your home desk's `web` directory to the web by running the
54+following `:dojo` command:
55+
56+ ~your-urbit:dojo> |serve /=home=/web
57+
58+## Get started!
59+
60+And now your docs are live! View them at:
61+
62+ http://localhost:8443/~~/docs
63+
64+> If you're running multiple ships locally, your port number will be `8444`,
65+> `8445`, and so on. Check your `:dojo` output for the correct local port of
66+> your examples urbit, or view these at `https://your-urbit.urbit.org` over DNS
67+> instead for live-network ships.
68+
69+## Learn a lot, and have fun!
70+
71+People are always around on
72+[`:talk`](https://urbit.org/docs/using/setup#-messaging-talk) and
73+[`:fora`](https://urbit.org/~~/fora) to answer your questions. Help each other
74+out, and don't hesitate if you have an idea for a docs improvement. We'd love if
75+the docs themselves became an Urbit community project.
76+
77+## Contributing / Feedback
78+
79+Give us feedback [on `:fora`](https://urbit.org/~~/fora/) on how we can make the
80+docs better. Let us know about your ideas, requests, and/or problems and we'll
81+try and get back to you quickly. Pull requests are more than welcome.