on master help sign in
Merge branch 'master' of http://github.com/urbit/docs
commitaa78b7cd44a81f64d58a1ae7ce7a7eec7e8c1178 authorC. Guy Yarvin <cgyarvin@gmail.com> dateWed 13 Jul 2016, 14:45 (10 years ago) parent2e423b629332ab
53 files changed+2052−489
docs.md+38−12 docs/about/contributing.md+38 docs/about/glossary.md+270 docs/arvo.md+6−2 docs/arvo/basic.md+28−21 docs/arvo/generators.md+30−91 docs/arvo/http.md+19−29 docs/arvo/internals/eyre/commentary.md+3−3 docs/arvo/marks.md+5−3 docs/arvo/network.md+34−33 docs/arvo/state.md+10−5 docs/arvo/subject.md+7−7 docs/arvo/subscriptions.md+11−11 docs/arvo/web-apps.md+14−18 docs/hoon.md+6−2 docs/hoon/advanced.md+8−8 docs/hoon/examples.md+2−2 docs/hoon/exercises/data-structures.md+1−1 docs/hoon/exercises/fizzbuzz.md+2−2 docs/hoon/library/2b.md+236−3 docs/hoon/library/2h.md+44 docs/hoon/library/2n.md+6−4 docs/hoon/library/2q.md+2−2 docs/hoon/library/4h.md+1−1 docs/hoon/library/zuse/core/epur.md+1−1 docs/hoon/library/zuse/core/yu.md+1−1 docs/hoon/library/zuse/diff.md+1−1 docs/hoon/library/zuse/gate/jesc.md+1−1 docs/hoon/library/zuse/gate/tope.md+1−1 docs/hoon/reference.md+4 docs/hoon/syntax.md+4−4 docs/hoon/twig.md+1−1 docs/hoon/twig/bar-core/cab-door.md+1−1 docs/hoon/twig/bar-core/dot-trap.md+3 docs/hoon/twig/bar-core/hep-loop.md+9 docs/hoon/twig/bar-core/tar-gill.md+5 docs/hoon/twig/bar-core/tis-gate.md+6 docs/hoon/twig/buc-mold/hep-lamb.md+1−1 docs/hoon/twig/tis-flow/bar-new.md+1−1 docs/hoon/twig/wut-test/gar-sure.md+1−1 docs/hoon/twig/wut-test/lus-deft.md+1−1 docs/hoon/twig/wut-test/zap-not.md+3−1 docs/hoon/twig/zap-wild/gar-wrap.md+1−1 docs/nock.md+4 docs/nock/implementations/csharp.md+478 docs/using.md+4 docs/using/filesystem.md+91−86 docs/using/layout.md+1−1 docs/using/messaging.md+127−43 docs/using/setup.md+41−32 docs/using/shell.md+72−48 docs/using/urb.md+356 docs/using/web.md+11−2
docs.md+38−12
@@ -1,7 +1,7 @@
11---
22anchor: none
33footer: true
4−title: Develop
4+title: Documentation
55sort: 4
66---
77
@@ -10,21 +10,47 @@ sort: 4
1010 <h1 class="blue i-b">Urbit docs</h1>
1111</div>
1212
13−Go to the [technical overview](about/overview) for a high-level
14−architecture description. To install and run Urbit, read forward from the
15−[installation guide](using/install).
13+<div class="col-md-12 head">
1614
17−To begin developing for Urbit, start by learning Hoon [syntax](hoon/syntax),
18−then walk through the [Arvo tutorials](arvo). The examples and exercises
19−in Arvo will teach you to build high-level programs and interact with the network.
15+<div class="col-md-8">
16+
17+Check out the [technical overview](about/overview) for a high-level
18+architecture description. To install and run Urbit, head to the Using section, starting with the [installation guide](using/install) and continuing forward.
19+
20+To begin developing for Urbit, start by learning Hoon [syntax](hoon/syntax),
21+then walk through the [Arvo tutorials](arvo). The examples and exercises
22+in Arvo will teach you to build high-level programs and interact with the network.
2023
2124Dig into the mechanics of Urbit with [Core Hoon](hoon). Refer back
22−there for pure-code exercises and functions in the [standard library](hoon/library).
25+there for pure-code exercises and functions in the [standard library](hoon/library).
26+
27+Registered academics are required to start with the [Nock definition](nock/definition) and work upward from there.
28+
29+</div>
30+
31+<div class="col-md-4">
2332
24−Registered academics are required to start with the [Nock definition](nock/definition)
25−and work upward from there.
26−<br/>
27−<br/>
33+<b>Source on GitHub</b>
34+<ul>
35+<li><a href="https://github.com/urbit/urbit">Main repo</a></li>
36+<li><a href="https://github.com/urbit/examples">Examples</a></li>
37+<li><a href="https://github.com/urbit/docs">Documentation</a></li>
38+</ul>
39+
40+<br />
41+
42+<b>Community / contact</b>
43+<ul>
44+<li>We use <code>:talk</code> on Urbit to chat.</li>
45+<li><a href="https://reddit.com/r/urbit">/r/urbit on Reddit</a></li>
46+<li><a href="https://twitter.com/urbit_">@urbit_ on Twitter</a></li>
47+<li><a href="https://groups.google.com/forum/#!forum/urbit-dev">urbit-dev mailing list</a></li>
48+<li><a href="mailto:urbit@urbit.org">urbit@urbit.org</a></li>
49+</ul>
50+
51+</div>
52+
53+</div>
2854
2955<div class="sections">
3056 <kids grid="true"></kids>
docs/about/contributing.mdnew file+38
@@ -0,0 +1,38 @@
1+---
2+navhome: '/docs'
3+next: True
4+sort: 4
5+title: Contributing to Urbit
6+---
7+
8+# Contributing to Urbit
9+
10+It's always a good day for pull requests! We gladly accept submissions
11+for improving our [code](https://github.com/urbit/urbit/) and
12+[documentation](https://github.com/urbit/docs/) alike.
13+
14+## Code guidelines
15+
16+Our official guide to contributing can be found
17+[here](https://github.com/urbit/urbit/blob/master/CONTRIBUTING.md),
18+which is most useful for large and low-level changes. For simpler
19+revisions, refer to [Hoon Syntax](../../hoon/syntax) for an in-depth guide to
20+good Hoon. Alternatively, [browse the
21+source](https://github.com/urbit/arvo/blob/master/arvo/hoon.hoon).
22+
23+## Docs guidelines
24+
25+For documentation pull requests, acquire [pandoc](http://pandoc.org) and
26+format your edited files with the following flags:
27+
28+ $ pandoc --standalone \
29+ --from=markdown+yaml_metadata_block \
30+ --atx-headers \
31+ -o output.md \
32+ input.md
33+
34+**Note:** Pandoc will convert the terminating `---` in YAML metadata to
35+`...`, which is grounds for termination. Run the following one-liner to
36+atone.
37+
38+ $ sed '1,/^$/ s/^\.\.\./---/g' input.md > output.md
docs/about/glossary.mdnew file+270
@@ -0,0 +1,270 @@
1+---
2+navhome: '/docs'
3+next: True
4+sort: 3
5+title: Urbit glossary
6+---
7+
8+# Urbit glossary
9+
10+Urbit is renowned for its exotic terminology. Here's a simple overview
11+from the strange words in.
12+
13+As Dijkstra put it: "The purpose of abstraction is not to be vague, but
14+to create a new semantic level in which one can be absolutely precise."
15+
16+## Ships
17+
18+An Urbit `ship` is a cryptographic identity, a human-memorable name, and
19+a packet routing address. Ships are classed by the number of bits in
20+their address:
21+
22+ Size Name Parent Object Example
23+ ----- ------ ------ ------ -------
24+ 2^8 galaxy ~ supernode ~zod
25+ 2^16 star galaxy supernode ~dozbud
26+ 2^32 planet star user ~tasfyn-partyv
27+ 2^64 moon planet device ~sigsam-nimbot-tasfyn-partyv
28+ 2^128 comet ~ bot ~racmus-mollen-fallyt-linpex--watres-sibbur-modlux-rinmex
29+
30+Any ship can be called an `urbit`.
31+
32+> A summary [here](http://urbit.org/posts/address-space/).
33+
34+An Urbit identity is a string like `~firbyr-napbes`. It means nothing,
35+but it's easy to remember and say out loud. `~firbyr-napbes` is actually
36+just a 32-bit number, like an IP address, that we turn into a
37+human-memorable string.
38+
39+Technically, an urbit is a secure digital identity that you own and
40+control with a cryptographic key, like a Bitcoin wallet. As in Bitcoin,
41+the supply of urbits is mathematically limited. This keeps the network
42+friendly, by making spam and abuse expensive.
43+
44+An urbit name is just a number; smaller numbers make shorter names.
45+Shorter names are easier to remember, so they're more valuable. So
46+urbits are classified by the number of bits in their name. (A ship name
47+is just a scrambled base-256 representation of the number.)
48+
49+A 32-bit urbit (like `~firbyr-napbes`) is called a "planet." A 16-bit
50+urbit (like `~pollev)` is a "star." An 8-bit ship (like `~mun`) is a
51+"galaxy." A planet is an identity for an independent, adult human. Stars
52+and galaxies are network infrastructure.
53+
54+Each planet or star is launched by its "parent," the star or galaxy
55+whose number is its bottom half. So the planet `~firbyr-napbes`,
56+`0xdead.beef` or `3.735.928.559`, is the child of `~pollev`, `0xbeef` or
57+`48.879`, whose parent is `~mun`, `0xef`, `239`. The parent of `~mun`
58+and all galaxies is `~zod`, `0`.
59+
60+### Nock
61+
62+> Nock is a Turing-complete, non-lambda combinator interpreter.
63+
64+- `noun`: an `atom` or a `cell`
65+- `atom`: any natural number
66+- `cell`: any ordered pair of `noun`s
67+- `subject`: a `noun` - the data against which a `formula` is
68+ evaluated
69+- `formula`: a `noun` - a function at the Nock level
70+- `product`: a `noun` - the result of evaluating a `formula` against a
71+ `subject`
72+
73+*See [Nock definition](../../nock/definition/).*
74+
75+### Hoon
76+
77+> Hoon is a strict, higher-order typed functional language that compiles
78+> itself to Nock.
79+
80+###### `span`: an inferred type
81+
82+A `span` defines a set (finite or infinite) of `noun`s 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 `arm`s
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`
100+
101+The `twig` of each `arm` is compiled to a Nock formula, with the
102+enclosing `core` itself as the subject.
103+
104+There are two kinds of `arm`s: `dry` and `wet`. Most arms are dry.
105+
106+- `dry`: normal, `++`, polymorphic by means of *variance*
107+
108+For a `dry` `arm`, we ask, is the new `payload` compatible with the old
109+`payload` (against which the `core` was compiled)?
110+
111+- `wet`: unusual, `+-`, polymorphic by means of *genericity*
112+
113+A `wet` `arm` uses the `twig` as a macro. We create a new type analysis
114+path, which works as if we expanded the callee with the caller's
115+context.
116+
117+*See [advanced types](/hoon/advanced)*.
118+
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 address `6` in the `core`) with the
136+argument, and then compute the `arm`.
137+
138+The `payload` of a `gate` has a shape of `{sample context}`.
139+
140+- `sample`: the argument tuple
141+- `context`: the subject in which the `gate` was defined
142+
143+*See [basic types](../../hoon/basic/#-core-p-span-q-map-term-span),
144+[`%-` or `:call`](../../hoon/twig/cen-call/hep-call/) (the `twig` for
145+calling a `gate`).*
146+
147+###### `mold`: a type constructor / validator
148+
149+A mold is an idempotent `gate` (function), accepting any `noun`, and
150+producing a range with a useful `span`.
151+
152+- `bunt`: the value a `mold` produces when normalizing its default
153+ sample
154+- `icon`: the `span` of the `mold`'s range
155+
156+*See [`mold` `twig`s](/hoon/twig/buc-mold/).*
157+
158+###### `atom`
159+
160+A Hoon `atom` span describes a Nock `atom`, with two additional pieces
161+of metadata: an `aura`, and an optional constant.
162+
163+An `atom` span is `warm` or `cold` based on whether the constant exists.
164+
165+- `warm`: if the constant is `~` (null), any `atom` is in the `span`
166+- `cold`: if the constant is `[~ atom]`, its only legal value is
167+ `atom`.
168+
169+*See [basic types](../../hoon/basic/#-atom-p-term-q-unit-atom)*
170+
171+###### `aura`: a soft `atom` type
172+
173+`aura` is a name for an atom type. It represents the structure of an
174+`atom` in a string beginning with `@`. An aura may represent units,
175+print format, or other semantics. Its constraints on the value of an
176+atom aren't enforced in any way.
177+
178+Two `aura`s are compatible if one is a prefix of the other. You can
179+change any `aura` into any other `aura` by casting through the empty
180+`aura`, `@`. The standard library has molds which alias many common
181+auras.
182+
183+Some common auras and their aliases:
184+
185+- `term` (`@tas`): a symbol - an atomic ASCII string which obeys
186+ symbol rules: lowercase and digit only, infix hyphen ("kebab-case"),
187+ first character must be lowercase alphabetic.
188+- `cord` (`@t`): UTF-8 text, least-significant-byte first
189+- `char` (`@tD`): a character, a single unicode byte (for multi-byte
190+ characters and codepoints, see `@c`)
191+
192+*See [basic types](../../hoon/basic/#-atom-p-term-q-unit-atom)*.
193+
194+###### `twig`: a Hoon expression
195+
196+A `twig` is a Hoon expression. Specifically, `twig` is the mold for the
197+noun that a Hoon source expression compiles to. A twig is always a cell.
198+
199+A twig has one of two forms: `{twig twig}`, which produces the ordered
200+pair of the two twigs, or a cell `{stem bulb}`, where `stem` is an
201+atomic symbol.
202+
203+- `stem`: an atomic symbol (`@tas`) - the name of a `twig`.
204+- `bulb`: The `mold` of the `twig`'s contents.
205+
206+Most `twig`s have a *regular form*, beginning with a `sigil` which is
207+either a `keyword` or a `rune`. Some `twig`s also have a syntactic
208+*irregular form*; a few have *only* an *irregular form*.
209+
210+- `sigil`: a `keyword` or `rune` used to begin a `twig`
211+- `keyword`: the value of a stem, prefixed with `:`.
212+- `rune`: a pair of ASCII symbols used to begin a `twig`.
213+
214+For example, the stem `%if` becomes the keyword
215+[`:if`](../../hoon/twig/wut-test/col-if/), with the rune `?:`. The first
216+symbol in a rune represents a family of related `twig`s. For example,
217+the [`?` family](../../hoon/twig/wut-test/) are all conditionals.
218+
219+The keyword or rune forms are up to the programmer's choice. Most
220+existing code uses runes, but the keyword form makes the learning path
221+easier.
222+
223+A regular twig has two syntactic forms, *tall* and *flat*:
224+
225+- `tall`: multiple lines, no parentheses, two or more spaces between
226+ tokens
227+- `flat`: one line, parentheses, one space between tokens
228+
229+`tall` twigs can contain `flat` ones, but not vice versa. All irregular
230+forms are `flat`.
231+
232+*See [`twig` concept](../../hoon/concepts/#-twig-expression),
233+[expressions](../../hoon/twig/), and [syntax](../../hoon/syntax/)*.
234+
235+###### `limb`: attribute or variable reference
236+
237+To resolve a `limb` named "foo", the `subject` is searched depth-first,
238+head-first for either a `face` named "foo" or a `core` with an `arm` of
239+"foo". If a `face` is found, the result is a `leg`, if a `core` is
240+found, the result is the `product` of the `arm`.
241+
242+- `leg`: a subexpression, or subtree of the `subject`.
243+- `wing`: a list of `limb`s, searched from right to left (`a.b` means
244+ `b` within `a`).
245+
246+*See [Limbs and wings](../../hoon/twig/limb)*
247+
248+###### `face`: a labeled subtree
249+
250+Hoon has no scope or symbol-table; there is only the `subject`. To
251+"declare" a "variable" is to construct a new `subject`:
252+`[name=value old-subject]`.
253+
254+A `face` is a `span` that wraps a name (`@tas`) around another `span`.
255+
256+*See [advanced types](../../hoon/advanced/#-face-aliases-and-bridges)*.
257+
258+###### `nest`: type compatibility test
259+
260+`nest` is an internal function on two spans, which produces yes if the
261+set of nouns in the second span is provably a subset of the first.
262+
263+*See [advanced types](../../hoon/advanced/)*.
264+
265+###### `loobean`: a Hoon boolean
266+
267+`0` (`%.y`) is *yes*, `1` (`%.n`) is *no*.
268+
269+> Why? It's fresh, it's different, it's new. And it's annoying. And it
270+> keeps you on your toes. And it's also just intuitively right.
docs/arvo.md+6−2
@@ -1,8 +1,12 @@
11---
22navhome: /docs
3−sort: 4
3+sort: 3
44---
55
6−# Arvo
6+# Arvo programming
7+
8+This example-based sequence of tutorials shows you how to build simple programs in hoon and use the basic features of Arvo.
9+
10+If you like to learn by example, start here.
711
812<list/>
docs/arvo/basic.md+28−21
@@ -2,20 +2,15 @@
22navhome: /docs
33sort: 1
44next: true
5−title: Hoon refresher / crash course
5+title: Basic Hoon
66---
77
88Basic Hoon
99==========
1010
11−This recapitulates material you've already learned in
12−[Hoon](/docs/hoon/). It will be a very abrupt tutorial if you don't know
13−Hoon already, but it may be enough in and of itself. If you don't find
14−it obvious at first glance, try working up from Hoon.
15−
1611Our goal is to get you programming interesting and useful things as soon
1712as possible. To get there, we have to quickly cover some of the
18−fundamentals of hoon. To do this, we'll walk through two simple
13+fundamentals of [Hoon](/docs/hoon/). To do this, we'll walk through two simple
1914programs: the first [Project Euler](https://projecteuler.net/) problem
2015and [fizzbuzz](https://en.wikipedia.org/wiki/Fizz_buzz).
2116
@@ -23,14 +18,24 @@ To run this code, you'll need an urbit, and will have to copy the
2318[examples repo](https://github.com/urbit/examples) into it.
2419
2520If you haven't installed urbit yet, check out the [installation
26−instructions](/docs/user/install). Once urbit is installed, take a look
27−at the [basic operation](/docs/user/basic) of your urbit.
21+instructions](/docs/using/install). Once urbit is installed, take a look
22+at the [basic operation](/docs/using/admin) of your urbit.
2823
2924If you haven't copied in the examples repo, running the following
3025commands from your urbit directory should do the trick:
3126
32−`$ cp -r {wherever-you've-pulled-to}/examples/gall/*/ arvo/`
33−`$ cp -r {wherever-you've-pulled-to}/examples/dojo/*/ arvo/`
27+Make sure you've mounted your `%home` desk:
28+
29+```
30+~fintud-macrep:dojo> |mount %
31+```
32+
33+Then, copy the example into it
34+
35+```
36+$ cp -r {urbit-examples}/gall/*/*/ {your-pier}/home/
37+$ cp -r {urbit-examples}/dojo/*/*/ {your-pier}/home/
38+```
3439
3540Run an example to ensure it worked:
3641
@@ -157,13 +162,13 @@ Instead of:
157162
158163You can write:
159164
160− if(=(1 2) 'this is true' 'this is false')
165+ :if(=(1 2) 'this is true' 'this is false')
161166 'this is false'
162167
163168### Lines 12-34
164169
165170Now let's quickly walk through this code line-by-line. Lines 12-34 are
166−wrapped in a `|%` ('barcen'), which produces a core. Cores are a
171+wrapped in a `|%` ('[barcen](../../hoon/twig/bar-core/cen-core/)'), which produces a core. Cores are a
167172fundamental datatype in Hoon, similar to a struct, class, or object. A
168173core is just a map of names to any kind of code, whether it be functions
169174or data. Each element in this map begins with a `++` followed by the
@@ -182,7 +187,7 @@ Let's step into each of the three arms within our core.
182187 (add (five a) (three a))
183188 --
184189
185−`|=` ('bartis') produces a function, much like a lambda in lisp. It
190+`|=` ('[bartis](../../hoon/twig/bar-core/tis-gate/)') produces a function, much like a lambda in lisp. It
186191takes two children:
187192
1881931. A set of argument(s). In this case our argument set only contains
@@ -207,14 +212,14 @@ takes two children:
207212As above, `++three` takes an integer argument, `a`, and then executes
208213the remainder of the code with `a` set to the actual arguments.
209214
210−Similarly, `=|` ('tisbar') pushes its first child, `b` into our context
215+Similarly, `=|` ('[tisbar](../../hoon/twig/tis-flow/bar-new/)') pushes its first child, `b` into our context
211216(in other words, it declares a variable `b`) and executes the remainder
212217of the code. However, `b` is not an argument; `=|` sets `b` to the
213218default value of whatever type it is declared as. Since the default
214219value of an atom is `0`, b is set to `0`.
215220
216−> To produce the default value of any given type, use `$*` ('buctar')
217−> followed by the type. Alternatively, use the irregular form `*`.
221+> To produce the default value of any given type, use `*` ('tar')
222+> followed by the type. This operaction is called *bunt*.
218223>
219224> > *@ :: produce the default value of atom @
220225> 0
@@ -225,10 +230,10 @@ value of an atom is `0`, b is set to `0`.
225230So now we have two variables: `a` is set to our input, and `b` is
226231initialized to `0`.
227232
228−One way to think about `|-` ('barhep') is that it lays down a recursion
233+One way to think about `|-` ('[barhep](../../hoon/twig/bar-core/hep-loop/)') is that it lays down a recursion
229234point. More on this later.
230235
231−`^-` ('kethep') is just a cast that sets the result of the remainder of
236+`^-` ('[kethep](../../hoon/core/ket-cast/hep-cast/)') is just a cast that sets the result of the remainder of
232237the code to an unsigned integer, `@u`.
233238
234239In pseudocode, the last three lines read like this: if `a` is less than
@@ -246,10 +251,10 @@ function call, then you have to specify every argument.
246251
247252**Exercises**:
248253
249−Tweak your code to complete the following excercises.
254+Tweak your code to complete the following exercises.
250255
251256There are a few runes and some syntax that we have yet to cover that you
252−will need to complete the excercises below. For these, please refer to
257+will need to complete the exercises below. For these, please refer to
253258our cheatsheat at the bottom.
254259
2552601. Read and understand `++five` line by line.
@@ -272,6 +277,8 @@ our cheatsheat at the bottom.
272277 =(a b) test equality
273278 (function args ...) call function with args
274279
280+Lookup each of these expressions (and all others!) in the [Twig Expressions](../../hoon/twig/) definition.
281+
275282### New material
276283
2772841. There are two syntaxes for writing Hoon: tallform and wideform.
docs/arvo/generators.md+30−91
@@ -15,7 +15,7 @@ the "plumbing" way to interact with apps. Generators are the
1515`|merge`, there are no marks in sight.
1616
1717We've used generators before, back in [Basic
18−Operation](/docs/user/basic). At that point, we just used the generators
18+Operation](/docs/using/admin). At that point, we just used the generators
1919to produce values -- we didn't pipe their results into apps. In
2020the dojo cast, the role of a generator is to take a list of
2121arguments and produce a value, which is often, though not always,
@@ -65,90 +65,33 @@ optionally specify the message as well.
6565We'll need a new mark for our arguments. Let's call it
6666`examples-ping-message`.
6767
68−<blockquote class="blockquote">
69−For app-specific marks, it's good style to prefix the name of
70−the mark with the name of the app. Since many apps have
71−several such marks, subdirectories in `/mar` are rendered as
72−`-`, so that `ping-message` is written in
73−(/mar/examples/ping/message.hoon).
74−</blockquote>
68+> For app-specific marks, it's good style to prefix the name of
69+> the mark with the name of the app. Since many apps have
70+> several such marks, subdirectories in `/mar` are rendered as
71+> `-`, so that `ping-message` is written in
72+> (/mar/examples/ping/message.hoon).
7573
7674```
77−:: Up-ness monitor. Accepts atom url, 'on', or 'off'
7875::
79−:::: /hoon/up/examples/app
76+:::: /hoon/message/ping/examples/app
8077 ::
8178/? 314
82−|%
83−++ move {bone card}
84−++ card
85− $% {$hiss wire $~ $httr {$purl p/purl}}
86− {$wait wire @da}
87− ==
88−++ action
89− $% {$on $~} :: enable polling('on')
90− {$off $~} :: disable polling('off)
91− {$target p/cord} :: set poll target('http://...')
92− ==
93−--
94−|_ {hid/bowl on/_| in-progress/_| target/@t}
95−++ poke-atom
96− |= url-or-command/@t ^- (quip move +>)
97− =+ ^- act/action
98− ?: ?=($on url-or-command) [%on ~]
99− ?: ?=($off url-or-command) [%off ~]
100− [%target url-or-command]
101− ?- -.act
102− $target [~ +>.$(target p.act)]
103− $off [~ +>.$(on |)]
104− $on
105− :- ?: |(on in-progress) ~
106− [ost.hid %hiss /request ~ %httr %purl (need (epur target))]~
107− +>.$(on &, in-progress &)
108− ==
109−::
110−
111−:: ~& 'i get here'
112−:: ^- {(list move) _+>.$}
113−:: ?: =('off' url)
114−:: [~ +>.$(on |)]
115−:: ?: =('on' url)
116−:: :_ +>.$(on &, in-progress &)
117−:: ?: |(on in-progress)
118−:: ~
119−:: [ost.hid %them /request ~ (need (epur target)) %get ~ ~]~
120−:: [~ +>.$(target url)]
121−++ sigh-httr
122− |= {wir/wire code/@ud headers/mess body/(unit octs)}
123− ~& 'arrive here'
124− ^- {(list move) _+>.$}
125− ?: &((gte code 200) (lth code 300))
126− ~& [%all-is-well code]
127− :_ +>.$
128− [ost.hid %wait /timer (add ~s10 now.hid)]~
129− ~& [%we-have-a-problem code]
130− ~& [%headers headers]
131− ~& [%body body]
132− :_ +>.$
133− [ost.hid %wait /timer (add ~s10 now.hid)]~
134−++ wake-timer
135− |= {wir/wire $~} ^- (quip move +>)
136− ?: on
137− :_ +>.$
138− [ost.hid %hiss /request ~ %httr %purl (need (epur target))]~
139− [~ +>.$(in-progress |)]
140−::
141−++ prep ~& target _`. ::
79+|_ {to/@p message/@t}
80+++ grab
81+ |%
82+ ++ noun {@p @t}
83+ --
14284--
14385```
14486
14587The app can easily be modified to use this (`/app/examples/ping.hoon`):
14688
14789```
90+:: Allows one ship to ping another with a string of text
14891::
14992:::: /hoon/ping/examples/app
15093 ::
151−/? 151
94+/? 314
15295|%
15396 ++ move {bone term wire *}
15497--
@@ -174,8 +117,6 @@ The app can easily be modified to use this (`/app/examples/ping.hoon`):
174117::
175118++ coup |=(* `+>)
176119--
177−
178−
179120```
180121
181122Now we can run this with:
@@ -197,7 +138,7 @@ to `:examples-ping`, let's put it in `/gen/examples/ping/send.hoon`:
197138
198139```
199140:- %say
200−|= {^ {{to/@p message/?($~ {text/@t $~})} $~}
141+|= {^ {to/@p message/?($~ {text/@t $~})} $~}
201142[%examples-ping-message to ?~(message 'howdy' text.message)]
202143```
203144
@@ -214,23 +155,21 @@ text and null.
214155Secondly, `?~(a b c)` is a rune which means "if the `a` is null,
215156do `b`, else `c`". It is roughly equivalent to `?:(=(~ a) b c)`.
216157
217−<blockquote class="blockquote">
218−`?~(a b c)` is actually equivalent to `?:=(?=(~ a) b c)`,
219−which, although identical at run time, is subtly different at
220−compile time. Specifically, using `?=` rather than `=` means
221−that we're checking whether `a` is in the *type* of `~`, and so
222−the compiler knows that in the `b` case `a` is null, and in the
223−`c` case `a` is not null. Since `=` is purely a runtime value
224−check with no type implications, the compiler doesn't gain any
225−information.
226−
227−At any rate, this is the reason why we can refer to
228−`text.message` in the `c` clause. The compiler knows that
229−`message` is not null, so it must have `text` within it. If
230−you used `?:(=(~ message) 'howdy' text.message)` the compiler
231−would complain that it doesn't know whether `message` has
232−`text` within it.
233−</blockquote>
158+> `?~(a b c)` is actually equivalent to `?:=(?=(~ a) b c)`,
159+> which, although identical at run time, is subtly different at
160+> compile time. Specifically, using `?=` rather than `=` means
161+> that we're checking whether `a` is in the *type* of `~`, and so
162+> the compiler knows that in the `b` case `a` is null, and in the
163+> `c` case `a` is not null. Since `=` is purely a runtime value
164+> check with no type implications, the compiler doesn't gain any
165+> information.
166+>
167+> At any rate, this is the reason why we can refer to
168+> `text.message` in the `c` clause. The compiler knows that
169+> `message` is not null, so it must have `text` within it. If
170+> you used `?:(=(~ message) 'howdy' text.message)` the compiler
171+> would complain that it doesn't know whether `message` has
172+> `text` within it.
234173
235174This is run as follows:
236175
docs/arvo/http.md+19−29
@@ -77,12 +77,10 @@ line, though.
7777Firstly, there's two kinds of cards we're sending to arvo. A
7878`%them` card makes an HTTP requrest out of a unit `hiss`.
7979
80−<blockquote class="blockquote">
81−Recall that `++unit` means "maybe". Formally, "`(unit a)` is
82−either null or a pair of null and a value in `a`". Also recall
83−that to pull a value out of a unit `(u.unit)`, you must first
84−verify that the unit is not null (for example with `?~`).
85−</blockquote>
80+> Recall that `++unit` means "maybe". Formally, "`(unit a)` is
81+> either null or a pair of null and a value in `a`". Also recall
82+> that to pull a value out of a unit `(u.unit)`, you must first
83+> verify that the unit is not null (for example with `?~`).
8684
8785A `hiss` (all of the following terms are defined in `zuse`) is a
8886pair of a `purl` and a `moth`. A `purl` is a parsed url
@@ -96,11 +94,9 @@ of HTTP headers. The `(unit octs)` is a possible octet stream
9694representing the body. If it's null, then no body is sent (as in
9795this case).
9896
99−<blockquote class="blockquote">
100−An octect stream is a pair of the length in bytes of the data
101−plus the data itself. You can use `++taco` takes text and
102−turns it into an octet strem.
103−</blockquote>
97+> An octect stream is a pair of the length in bytes of the data
98+> plus the data itself. You can use `++taco` takes text and
99+> turns it into an octet strem.
104100
105101When you send this request, you can expect a `%thou` with the
106102response, which we handle later on in `++thou-request`.
@@ -108,11 +104,9 @@ response, which we handle later on in `++thou-request`.
108104For `%wait`, you just pass a [`@da`]() (absolute date), and arvo will
109105produce a `%wake` when the time comes.
110106
111−<blockquote class="blockquote">
112−A timer is guaranteed to not be triggered before the given
113−time, but it's currently impossible to guarantee the timer will be
114−triggered at exactly the requested time.
115−</blockquote>
107+> A timer is guaranteed to not be triggered before the given
108+> time, but it's currently impossible to guarantee the timer will be
109+> triggered at exactly the requested time.
116110
117111Let's take a look at our state:
118112
@@ -133,11 +127,9 @@ of `value`, but make the default value be `value`". Thus, our
133127type is still a boolean, just like `?`, but the default value is
134128`|` (false).
135129
136−<blockquote class="blockquote">
137−This is the same `_` used in `_+>.$`, which means "the same
138−type as the value "+>.$". In other words, the same type as our
139−current context and state.
140−</blockquote>
130+> This is the same `_` used in `_+>.$`, which means "the same
131+> type as the value "+>.$". In other words, the same type as our
132+> current context and state.
141133
142134Let's take a look at `++poke-cord`. When we're poked with a
143135cord, we first check whether it's `'off'`. If so, we set `on` to
@@ -151,14 +143,12 @@ This request follows the pattern in `++hiss` well. `(need (epur
151143target))` is the parsed url, `%get` is the HTTP method, `~`
152144means no extra headers, and another `~` means no body.
153145
154−<blockquote class="blockquote">
155−Note the `~` at the end of the move. This is a convenient
156−shortcut for creating a list of a single element. It's part of
157−a small family of such shortcuts. `~[a b c]` is `[a b c ~]`,
158−`[a b c]~` is `[[a b c] ~]` and `\`[a b c]` is `[~ a b c]`.
159−These may be mixed and matched to create various convoluted
160−structures and emojis.
161−</blockquote>
146+> Note the `~` at the end of the move. This is a convenient
147+> shortcut for creating a list of a single element. It's part of
148+> a small family of such shortcuts. `~[a b c]` is `[a b c ~]`,
149+> `[a b c]~` is `[[a b c] ~]` and `\`[a b c]` is `[~ a b c]`.
150+> These may be mixed and matched to create various convoluted
151+> structures and emojis.
162152
163153If the argument is neither 'off' nor 'on', then we assume it's an
164154actual url, so we save it in `target`.
docs/arvo/internals/eyre/commentary.md+3−3
@@ -96,7 +96,7 @@ initiates the long-polling loop, run against an injected `urb.js` of
9696
9797A `%js` `pest` is `resolve`d as a `text/javascript` success `%this`.
9898
99−When `poll.js` is recieved by the client, it opens an `XMLHttpRequest` for
99+When `poll.js` is received by the client, it opens an `XMLHttpRequest` for
100100`/~/on/{window.urb.poll}.json`, bringing us back to `%poll:process`.
101101
102102In the case of a non-`%js` `/~/on/`, `%poll:process-parsed` turns into a
@@ -167,7 +167,7 @@ the first nontrivial `++check-oryx` occurs, `++grab-body` the request oryx and
167167ensuring it is recorded for the session. The request parsed with `++need-body`
168168to a `[%auth %try {password}]` perk. `%get:process-auth` checks it against
169169`++load-secret`, upon success updates the session with `++logon:ya`, and
170−serves a fresh `auth.json` which reflects the changed `user`. Upon recieving
170+serves a fresh `auth.json` which reflects the changed `user`. Upon receiving
171171this, the page is refreshed to retry the original request.
172172
173173## Post-authentication: app communication. [#auth-ok]
@@ -212,7 +212,7 @@ Upon receipt, the client realizes the long-poll isn't actually running, so that
212212is started using `urb.poll`. At `/~/of/{ixor}`, perk
213213`[%view ixor ~ {sequence-number}]`, it is `process`ed by `++poll:ix` (the cyst
214214is retrieved by `++ire-ix` form global state, using the perk `ixor`): the
215−sequence number is in the past, so the previously recieved `%rush` is
215+sequence number is in the past, so the previously received `%rush` is
216216`++give-even`. After deleting the previous message in the queue and invoking
217217`++pass-took` to signal `%gall` of this occurrence, the data is annotated with
218218the source app+path `++subs-to-json`, and returned to the polling duct.
docs/arvo/marks.md+5−3
@@ -5,6 +5,8 @@ sort: 6
55title: Marks
66---
77
8+# Marks
9+
810We've used predefined marks already, but we haven't yet created
911our own marks. Let's write a sample mark of our own, then chain
1012it together with some preexisting ones to have fun with type
@@ -28,14 +30,14 @@ text, but there's no predefined mark for it. Let's put the following code in:
2830--
2931```
3032
31−Let's go through this line by line. `/? 314` is the required
33+`/? 314` is the required
3234version number, just like in apps. After that everything's in a
3335`|_`, which is a `|%` core, but with input arguments. In our
3436case, the argument is the marked data.
3537
3638There are three possible top-level arms in the `|_` core,
37−`++grab`, `++grow`, and `++grad`. `++grad` is used for revision
38−controlv (it contains diff/patch logic), and is covered elsewhere. `++grab` specifies
39+`++grab`, `++grow`, and `++grad` (which is used for revision
40+control, covered elsewhere). `++grab` specifies
3941functions to convert from another mark to the current mark.
4042`++grow` specifies how to convert from the current mark to
4143another one.
docs/arvo/network.md+34−33
@@ -34,7 +34,8 @@ a value, it prints that value out. To try this out, you have to start
3434the app, then you can poke it from the command line with the following
3535commands:
3636
37− ~fintud-macrep:dojo> |start %echo
37+ ~fintud-macrep:dojo> |start %examples-echo
38+ 'prep'
3839 >=
3940 ~fintud-macrep:dojo> :examples-echo 5
4041 [%argument 5]
@@ -57,7 +58,7 @@ do that is to poke it from the command line, which we we did with
5758`:echo 5` (`:[app-name] [argument(s)]`).
5859
5960In this case, `++poke-noun` takes an argument `arg` and prints it out
60−with `~&` ([sigpam](/hoon/twig/sig-hint/pam-dump/)). This is an unusual
61+with `~&` ([sigpam](../../hoon/twig/sig-hint/pam-dump/)). This is an unusual
6162rune that formally "does nothing", but the interpreter detects it and
6263printfs the first child, before executing the second as if the first
6364didn't exist. This is a slightly hacky way of printing to the console,
@@ -86,7 +87,7 @@ only accept a number, and then print out the square of that number.
8687
8788 /? 314
8889 !:
89− |_ {bowl state=~}
90+ |_ {bowl state/$~}
9091 ::
9192 ++ poke-atom
9293 |= arg/@
@@ -149,7 +150,7 @@ Let's write our first network message! Here's `/app/examples/pong.hoon`:
149150 ++ move {bone term wire *}
150151 --
151152 !:
152− |_ {bowl state=$~}
153+ |_ {bowl state/$~}
153154 ::
154155 ++ poke-urbit
155156 |= to/@p
@@ -169,7 +170,7 @@ Run it with these commands:
169170
170171 ~fintud-macrep:dojo> |start %examples-pong
171172 >=
172− ~fintud-macrep:dojo> :pong &examples-urbit ~sampel-sipnym
173+ ~fintud-macrep:dojo> :examples-pong &urbit ~sampel-sipnym
173174 >=
174175
175176Replace `~sampel-sipnym` with another urbit. The easiest thing to do is
@@ -220,7 +221,7 @@ Let's walk through each of these elements step by step.
220221If you look up `++bone` in `hoon.hoon`, you'll see that it's a number
221222(`@ud`), and that it's an opaque reference to a duct. `++duct` in
222223hoon.hoon is a list of `wire`s, where `++wire` is an alias for `++path`.
223−`++path` is a list of `++span`s, which are ASCII text. Thus, a duct is a
224+`++path` is a list of `++knot`s, which are ASCII text. Thus, a duct is a
224225list of paths, and a bone is an opaque reference to it (in the same way
225226that a Unix file descriptor is an opaque reference to a file structure).
226227Thus, to truly understand bones, we must understand ducts.
@@ -234,7 +235,7 @@ Sometimes, the module can immediately handle the event and produce any
234235necessary results. For example, when we poked the `++poke-atom` arm
235236above, we poked %gall, our application server, which was able to respond
236237to our poke directly. When the module cannot service the request itself,
237−it sends instructions to another kernel module or application (the the
238+it sends instructions to another kernel module or application (through the
238239%gall module) to do a specified action, and produces the result from
239240that.
240241
@@ -283,7 +284,7 @@ The move ends with `*` (that is, any noun) since each type of move takes
283284different data. In our case, a `%poke` move takes a target (urbit and
284285app) and marked data, then pokes the arm of the corresponding mark on
285286that app on that urbit with that data. `[to-urbit-address %pong]` is the
286−target urbit and app, `%atom` is the mark`, and`'howdy'\` is the data.
287+target urbit and app, `%atom` is the `mark`, and`'howdy'` is the data.
287288
288289When arvo receives a `%poke` move, it calls the appropriate `++poke`.
289290The same mechanism is used for sending messages between apps on the same
@@ -304,7 +305,7 @@ urbit as for sending messages between apps on different urbits.
304305
305306- Write two apps, `even` and `odd`. When you pass an atom to `even`,
306307 check whether it's even. If so, divide it by two and recurse;
307− otherwise, poke `odd` with it. When `odd` recieves an atom, check
308+ otherwise, poke `odd` with it. When `odd` receives an atom, check
308309 whether it's equal to one. If so, terminate, printing "%success".
309310 Otherwise, check whether it's odd. If so, multiply it by three, add
310311 one, and recurse; otherwise, poke `even` with it. When either app
@@ -312,30 +313,30 @@ urbit as for sending messages between apps on different urbits.
312313 the end, you should be able to watch Collatz's conjecture play out
313314 between the two apps. Sample output:
314315
315−<!-- -->
316−
317− ~fintud-macrep:dojo> :even &atom 18
318− [%even 18]
319− [%odd 9]
320− [%even 28]
321− [%even 14]
322− [%odd 7]
323− [%even 22]
324− [%odd 11]
325− [%even 34]
326− [%odd 17]
327− [%even 52]
328− [%even 26]
329− [%odd 13]
330− [%even 40]
331− [%even 20]
332− [%even 10]
333− [%odd 5]
334− [%even 16]
335− [%even 8]
336− [%even 4]
337− [%even 2]
338− %success
316+```
317+~fintud-macrep:dojo> :even &atom 18
318+[%even 18]
319+[%odd 9]
320+[%even 28]
321+[%even 14]
322+[%odd 7]
323+[%even 22]
324+[%odd 11]
325+[%even 34]
326+[%odd 17]
327+[%even 52]
328+[%even 26]
329+[%odd 13]
330+[%even 40]
331+[%even 20]
332+[%even 10]
333+[%odd 5]
334+[%even 16]
335+[%even 8]
336+[%even 4]
337+[%even 2]
338+%success
339+```
339340
340341- Put `even` and `odd` on two separate urbits and pass the messages
341342 over the network. Post a link to a working solution in :talk to
docs/arvo/state.md+10−5
@@ -20,8 +20,6 @@ running the sum of all the atoms we poke it with. Here's
2020 ++ poke-atom
2121 |= arg/@
2222 ^- {(list) _+>.$}
23− ?: =(arg 0)
24− [~ +>.$(state 0)]
2523 ~& [%so-far (add state arg)]
2624 [~ +>.$(state (add state arg))]
2725 --
@@ -99,6 +97,13 @@ ever go through the hassle of having to set up and write to a database.
9997- Write an app that prints out the previous value you poked it with.
10098 Sample output:
10199
102−\`\`\` \~fintud-macrep:dojo\> :examples-last 7 [%last 0] \>=
103−\~fintud-macrep:dojo\> :examples-last [1 2 3][%last 7] \>=
104−\~fintud-macrep:dojo\> :examples-last 'howdy' [%last [1 2 3]]
100+```
101+~fintud-macrep:dojo> :examples-last 7
102+[%last 0]
103+>=
104+~fintud-macrep:dojo> :examples-last [1 2 3]
105+[%last 7]
106+>=
107+~fintud-macrep:dojo> :examples-last 'howdy'
108+[%last [1 2 3]]
109+```
docs/arvo/subject.md+7−7
@@ -15,7 +15,7 @@ Now we're going to cover the boiler plate that we skimmed over earlier.
1515 =< (sum [1.000 2.000])
1616
1717The first rune, `:-` (colhep, aka
18−[:cons](/hoon/twig/col-cell/hep-cons/)), constructs the 2-element cell
18+[:cons](../../hoon/twig/col-cell/hep-cons/)), constructs the 2-element cell
1919that will be our program. The first element, `%say`, tells the
2020interpreter what to produce--in this case a value.
2121
@@ -28,7 +28,7 @@ Similarly, the rest of the program (which we construct with another
2828producing a value of type `noun`, and the code that we run to actually
2929produce our value of the type `noun`.
3030
31−`=<` ([tisgal](/hoon/twig/tis-flow/gal-rap/)) is a rune that takes two
31+`=<` ([tisgal](../../hoon/twig/tis-flow/gal-rap/)) is a rune that takes two
3232children. The second child is the context against which we run the first
3333child. So in this case, we are running the expression
3434`(sum [1.000 2.000])` against everything contained within the `|%`. In
@@ -36,7 +36,7 @@ Hoon, we call the code executed the "formula" and its context the
3636"subject".
3737
3838 ::::::::::::::::::::::::::::::
39− =< (sum [1.000 2.000]) :: formula
39+ =< (sum [1.000 2.000]) :: formula
4040 ::::::::::::::::::::::::::::::
4141 |% ::
4242 ++ three ::
@@ -58,8 +58,8 @@ Hoon, we call the code executed the "formula" and its context the
5858 (add b $(b (add b 5))) ::
5959 ::
6060 ++ sum ::
61− |= a/@u ::
62− (add (five a) (three a)) ::
61+ |= {a/@u b/@u} ::
62+ (add (five a) (three b)) ::
6363 -- ::
6464 ::::::::::::::::::::::::::::::
6565
@@ -72,7 +72,7 @@ allows a sort of reification of the context through continutations, and
7272some may see a parallel to Forth's stack, but Hoon takes takes the
7373concept one step further.
7474
75−Our starting subject is the [standard library](/hoon/library), which is
75+Our starting subject is the [standard library](../../hoon/library), which is
7676defined in `/arvo/hoon.hoon` and `/arvo/zuse.hoon`. This is where
7777functions like `add` are defined. When we define a core with `|%`, we
7878don't throw away the subject (i.e. the standard library); rather, we
@@ -93,7 +93,7 @@ Cheatsheet:
9393
9494- To pass arguments from the command line to a program, you replace
9595 the `*` in the first line of the boiler plate to
96− `{^ {{arg/TYPE ~} ~}}` where `TYPE` is replaced with the type of
96+ `{^ {{arg/TYPE $~} $~}}` where `TYPE` is replaced with the type of
9797 argument you're expecting. Then `+euler1 a` from the dojo sets `arg`
9898 to `a`.
9999- The empty list is `~`
docs/arvo/subscriptions.md+11−11
@@ -59,7 +59,7 @@ And secondly, `:examples-sink`:
5959 ++ diff-noun
6060 |= {wir/wire arg/*}
6161 ^- {(list move) _+>.$}
62− ~& [%recieved-data arg]
62+ ~& [%received-data arg]
6363 [~ +>.$]
6464 ++ reap
6565 |= {wir/wire error/(unit tang)}
@@ -75,42 +75,42 @@ Cheat sheet:
7575
7676- `&` (pam) can either be the boolean true (as can `%.y`, `0`), or
7777 the irregular wide form of the `?&`
78− ([wutpam](/hoon/twig/wut-test/pam-and)) rune, which computes
78+ ([wutpam](../../hoon/twig/wut-test/pam-and)) rune, which computes
7979 logical `AND` on its two children.
8080
8181- Similar to `&`,`|` is either the boolean false (along with `%.n` and
8282 `1`), or the irregular short for of `?|`
83− ([wutbar](/hoon/twig/wut-test/bar-or)), which computes logical `OR`
83+ ([wutbar](../../hoon/twig/wut-test/bar-or)), which computes logical `OR`
8484 on its two children.
8585
8686- `!` is the irregular wide form of `?!`
87− ([wutzap](/hoon/twig/wut-test/zap-not/)), which computes logical
87+ ([wutzap](../../hoon/twig/wut-test/zap-not/)), which computes logical
8888 `NOT` on its child.
8989
90−- `?~` ([wutsig](/hoon/twig/wut-test/sig-ifno/)) is basically an
90+- `?~` ([wutsig](../../hoon/twig/wut-test/sig-ifno/)) is basically an
9191 if-then-else that checks whether condition `p` is `~` (null). `?~`
9292 is slightly different from `?:(~ %tru %fal)` in that `?~` reduces to
9393 `?:($=(%type value) %tru %false)`. `$=`
94− ([buctis](/hoon/twig/buc-mold/tis-coat/)) tests whether value `q` is
94+ ([buctis](../../hoon/twig/buc-mold/tis-coat/)) tests whether value `q` is
9595 of type `p`.
9696 <!--One thing to watch out for in hoon: if you do `?~`, it
9797 affects the type of the conditional value: XXexample-->
9898
99−- `:_` ([colcab](/hoon/twig/col-cell/cab-scon/)) is inverted `:-`: it
99+- `:_` ([colcab](../../hoon/twig/col-cell/cab-scon/)) is inverted `:-`: it
100100 accepts `p` and `q`, and produces `[q p]`.
101101
102102- `++bowl` is the type of the system state within our app. For
103103 example, it includes things like `our`, the name of the host urbit,
104104 and `now`, the current time.
105105
106−- `$%` ([buccen](/hoon/twig/buc-mold/cen-book/)) is a type
106+- `$%` ([buccen](../../hoon/twig/buc-mold/cen-book/)) is a type
107107 constructor: it defines a new type, composed of `n` types that it is
108108 passed. For example `$% @ * ^ ==` is the type of either `@`,
109109 `*`, or a cell `^`. <!--XX this is a union, right?-->
110110
111111- You may have noticed the separate `|%`
112− ([barcen](/hoon/twig/bar-core/cen-core/)) above the application core
113− `|_` ([barcab](/hoon/twig/bar-core/cab-door/). We usually put our
112+ ([barcen](../../hoon/twig/bar-core/cen-core/)) above the application core
113+ `|_` ([barcab](../../hoon/twig/bar-core/cab-door/). We usually put our
114114 types in another core on top of the application core. We can access
115115 these type from our `|_` because in `hoon.hoon` files, all cores are
116116 called against each other. (The shorthand for 'called' is `=>`.)
@@ -180,7 +180,7 @@ so you don't have to. You can access your subscribers by looking at
180180subscribed, and which path they subscribed on. If you want to
181181communicate with your subscribers, send them messages along their bone.
182182
183−`++poke-noun` "spams" the given arguement to all our subscribers.
183+`++poke-noun` "spams" the given argument to all our subscribers.
184184There's a few things we haven't seen before. Firstly, `:_(a b)` is the
185185same as `[b a]`. It's just a convenient way of formatting things when
186186the first thing in a cell is much more complicated than the second.
docs/arvo/web-apps.md+14−18
@@ -72,18 +72,16 @@ asserting the parsing succeeded with `need`, and asserting the
7272result was 'click' with `?>`, which asserts that its first child
7373is true.
7474
75−<blockquote class="blockquote">
76−Note the argument to `++json`is `jon/^json`. Why `^json`?
77−`++json` shadows the type definition, so if we want to refer to
78−the type, we have to prepend a `^`. This extends to multiple
79−levels: `^^^foo` means the fourth most innermost instance of `foo`.
80−
81−`++jo` in `zuse` is a useful library for parsing complex json
82−into hoon structures. In this case, the `:` between `so` and
83−`jo` means 'inside of', because `so` is an arm contained within
84−the core `jo`. Our case is actually simple enough that the
85−`?>` line could have been `?> =([%s 'click'] jon)`.
86−</blockquote>
75+> Note the argument to `++json`is `jon/^json`. Why `^json`?
76+> `++json` shadows the type definition, so if we want to refer to
77+> the type, we have to prepend a `^`. This extends to multiple
78+> levels: `^^^foo` means the fourth most innermost instance of `foo`.
79+
80+> `++jo` in `zuse` is a useful library for parsing complex json
81+> into hoon structures. In this case, the `:` between `so` and
82+> `jo` means 'inside of', because `so` is an arm contained within
83+> the core `jo`. Our case is actually simple enough that the
84+> `?>` line could have been `?> =([%s 'click'] jon)`.
8785
8886We can test this mark from the command line (don't forget to start your app with `|start %click`)
8987
@@ -115,11 +113,9 @@ And `/mar/clicks.hoon`:
115113`clicks` is just an atom. We convert to json by creating an
116114object with a single field "clicks" with our value.
117115
118−<blockquote class="blockquote">
119−Be sure to checkout section 3bD, JSON and XML, in zuse.hoon
120−`++joba` is just a function that takes a key-value pair and
121−produces a JSON object with one element.
122−</blockquote>
116+> Be sure to checkout section 3bD, JSON and XML, in zuse.hoon
117+> `++joba` is just a function that takes a key-value pair and
118+> produces a JSON object with one element.
123119
124120```
125121~fintud-macrep:dojo> &json &clicks 6
@@ -149,7 +145,7 @@ the app from the command line.
149145 `:click` and print out the subscription updates on the command
150146 line.
151147
152−#Frontend
148+# Frontend
153149
154150That's all that's needed for the back end. The front end is just
155151some "sail" html (Hoon markup for XML) and javascript. Here's `/web/click.hoon`:
docs/hoon.md+6−2
@@ -1,8 +1,12 @@
11---
22navhome: /docs
3−sort: 3
3+sort: 4
44---
55
6−# Hoon
6+# Hoon reference
7+
8+This in-depth reference covers all the features of Hoon.
9+
10+If you prefer to learn from the bottom up, feel free to start here.
711
812<list/>
docs/hoon/advanced.md+8−8
@@ -72,12 +72,12 @@ polymorphism relies on genericity.
7272### Dry arms
7373
7474For a dry arm, we apply the Liskov substitution principle: we
75−ask, "can we use any `p` as if it was a `q.q`"? This is the same
75+ask, "can we use any `p` as if it was a `q.q`?" This is the same
7676test as in `:cast` or any type comparison (`nest`). Intuitively,
77−we ask: is the new payload compatible with the old payload?
77+we ask: "is the new payload compatible with the old payload?"
7878
7979For a core `a`, if `p.a` fits in `q.q.a`, we can use arms on the
80−core. The product of an dry arm whose twig is `b` is always
80+core. The product of a dry arm whose twig is `b` is always
8181defined as `{$hold a(p q.q.a, p.q %gold) b}`.
8282
8383In other words, the subject of the arm computation is the
@@ -89,7 +89,7 @@ call in most languages.
8989
9090Dry polymorphism works by substituting cores. Typically, the
9191the programmer uses one core as an interface definition, then
92−replace it with another core which does something useful.
92+replaces it with another core which does something useful.
9393
9494For core `b` to nest within core `a`, the batteries of `a` and
9595`b` must have the same tree shape, and the product of each `b`
@@ -108,7 +108,7 @@ is gold; a gold core can be cast or converted to any metal, and
108108any metal can be cast or converted to lead.
109109
110110A gold core `a` has a read-write payload; another core `b` that
111−nests within it (ie, can be substituted for it) must be a gold
111+nests within it (i.e., can be substituted for it) must be a gold
112112core whose payload is mutually compatible (`+3.a` nests in `+3.b`,
113113`+3.b` nests in `+3.a`). Hence, *invariant*.
114114
@@ -128,8 +128,8 @@ nests within `+6.a`. Hence, *covariant*.
128128
129129### Wet arms
130130
131−For a wet arm, we ask: suppose this core was actually compiled
132−using `p` instead of `q.q`? Would the Nock formula we generated
131+For a wet arm, we ask: "suppose this core was actually compiled
132+using `p` instead of `q.q`?" Would the Nock formula we generated
133133for `q.q` actually work for a `p` payload?
134134
135135A wet arm with twig `b` in core `a` produces the span `{$hold a
@@ -186,7 +186,7 @@ limb, we just search the span depth-first.
186186If a name is in the `p.p` map, it's an alias. The map contains a
187187`(unit twig)`; if the unit is full, the name resolves to that
188188twig (compiled against the `q` span). If the unit is empty,
189−the name is blocked / skipped (see [limb](twig/limb) for what
189+the name is blocked / skipped (see [limb](../twig/limb) for what
190190this means).
191191
192192If a name is in the `q.p` map, it's a bridge. When we search for
docs/hoon/examples.md+2−2
@@ -17,7 +17,7 @@ side of simple manual construction over high-octane FP.)
1717## `sieve`: code in basic style
1818
1919A function that produces the list of primes less than or equal to
20−than its argument, an atom:
20+its argument, an atom:
2121```
2222:gate thru/atom :: 1
2323:cast (list atom) :: 2
@@ -313,7 +313,7 @@ Line `13` defines the `spot` mold, a 2D coordinate.
313313 == :: 16
314314```
315315
316−Lines `14` to `16` define the `fact` mold, a game event (ie,
316+Lines `14` to `16` define the `fact` mold, a game event (i.e.,
317317output action), as a book (tagged union). There are two forms of
318318`fact`: `[%tie ~]` (reporting a tie), and `[%win cord]`
319319(reporting that `'X'` or `'O'` won a game.
docs/hoon/exercises/data-structures.md+1−1
@@ -26,7 +26,7 @@ exercises, you'll need to refer to the [library reference for
2626 `'javacript'`, `'python'`.
2727
28281. At the dojo, take the union of `s` and `l`. Delete
29− `'javascript'` from the result, and add `'coffescript'`.
29+ `'javascript'` from the result, and add `'coffeescript'`.
3030
31311. Create an alphabetized list of the members of the set created
3232 in the previous exercise.
docs/hoon/exercises/fizzbuzz.md+2−2
@@ -28,8 +28,8 @@ comments: true
2828 ```
2929
3030 Modify this to produce "Fuzz" when the number is divisible by
31− 7, "Fuzz" when divisible by 21, "FuzzFizz" when divisble by 35,
32− and "FuzzFizzBuzz" when divisble by 105.
31+ 7, "Fuzz" when divisible by 21, "FuzzFizz" when divisible by 35,
32+ and "FuzzFizzBuzz" when divisible by 105.
3333
34341. Modify FizzBuzz from the previous exercise to take both a
3535 start and an end number.
docs/hoon/library/2b.md+236−3
@@ -128,6 +128,113 @@ Examples
128128
129129
130130
131+***
132+### `++find`
133+
134+First index in list
135+
136+Produces the index of the first occurrence of `++list` `nedl` in
137+`++list` `hstk` as the `++unit` of an atom.
138+
139+Accepts
140+-------
141+
142+`nedl` is a list.
143+
144+`hstk` is a list.
145+
146+Produces
147+--------
148+
149+The `++unit` of an atom.
150+
151+Source
152+------
153+
154+ ++ find :: first index
155+ ~/ %find
156+ |= {nedl/(list) hstk/(list)}
157+ =| i/@ud
158+ |- ^- (unit @ud)
159+ =+ [n=nedl h=hstk]
160+ |-
161+ ?: |(?=($~ n) ?=($~ h))
162+ ~
163+ ?: =(i.n i.h)
164+ ?~ t.n
165+ `i
166+ $(n t.n, h t.h)
167+ ^$(i +(i), hstk +.hstk)
168+
169+
170+Examples
171+--------
172+
173+ > (find [3]~ ~[1 2 3])
174+ [~ 2]
175+ > (find [4]~ ~[1 2 3])
176+ ~
177+ > (find ['a']~ "cbabab")
178+ [~ 2]
179+ > (find "ab" "cbabab")
180+ [~ 2]
181+
182+
183+
184+***
185+### `++fand`
186+
187+All indices in list
188+
189+Produces the indices of all occurrences of `++list` `nedl` in
190+`++list` `hstk` as a `++list` of atoms.
191+
192+Accepts
193+-------
194+
195+`nedl` is a list.
196+
197+`hstk` is a list.
198+
199+Produces
200+--------
201+
202+A `++list` of atoms.
203+
204+Source
205+------
206+
207+ ++ fand :: all indices
208+ ~/ %fand
209+ |= {nedl/(list) hstk/(list)}
210+ =| i/@ud
211+ =| fnd/(list @ud)
212+ |- ^+ fnd
213+ =+ [n=nedl h=hstk]
214+ |-
215+ ?: |(?=($~ n) ?=($~ h))
216+ (flop fnd)
217+ ?: =(i.n i.h)
218+ ?~ t.n
219+ ^$(i +(i), hstk +.hstk, fnd [i fnd])
220+ $(n t.n, h t.h)
221+ ^$(i +(i), hstk +.hstk)
222+
223+
224+Examples
225+--------
226+
227+ > (fand [3]~ ~[1 2 3])
228+ ~[2]
229+ > (fand [4]~ ~[1 2 3])
230+ ~
231+ > (fand ['a']~ "cbabab")
232+ ~[2 4]
233+ > (fand "ab" "cbabab")
234+ ~[2 4]
235+
236+
237+
131238***
132239### `++levy`
133240
@@ -650,7 +757,7 @@ Examples
650757
651758 > (snag 2 "asdf")
652759 ~~d
653− > (snag 0 `(list ,@ud)`~[1 2 3 4])
760+ > (snag 0 `(list @ud)`~[1 2 3 4])
654761 1
655762
656763
@@ -667,7 +774,7 @@ sorted according to `b`.
667774Accepts
668775-------
669776
670−`b` is a gate that ccepts two nouns and produces a boolean.
777+`b` is a gate that accepts two nouns and produces a boolean.
671778
672779Produces
673780--------
@@ -766,7 +873,7 @@ Source
766873Examples
767874--------
768875
769− > (turn (limo [104 111 111 110 ~]) ,@t)
876+ > (turn (limo [104 111 111 110 ~]) @t)
770877 <|h o o n|>
771878 > =a |=(a/@ (add a 4))
772879 > (turn (limo [1 2 3 4 ~]) a)
@@ -774,6 +881,132 @@ Examples
774881
775882
776883
884+***
885+### `++spin`
886+
887+Gate to list, with state
888+
889+Accepts a `++list` `a`, a gate `b`, and some state `c`. Produces a list with
890+the gate applied to each element of the original list. `b` is called with
891+a tuple -- the head is an element of `a` and the tail is the state `c`, and
892+should produce a tuple of the transformed element and the (potentially
893+modified) state `c`.
894+
895+Accepts
896+-------
897+
898+`a` is a `++list`.
899+
900+`b` is a gate.
901+
902+`c` is a noun.
903+
904+Produces
905+--------
906+
907+A list.
908+
909+Source
910+------
911+
912+ ++ spin
913+ |* {a/(list) b/_|=({* *} [** +<+]) c/*}
914+ :: ?< ?=($-([_?<(?=($~ a) i.a) _c] [* _c]) b)
915+ |-
916+ ?~ a
917+ ~
918+ =+ v=(b i.a c)
919+ [i=-.v t=$(a t.a, c +.v)]
920+
921+
922+Examples
923+--------
924+
925+A trivial example -- does nothing with the state:
926+
927+ > %^ spin (limo ~[4 5 6])
928+ |=({n/@ a/@} [n a])
929+ 0
930+ ~[4 5 6]
931+
932+Create a list of pairs, `p` as the index and `q` as the list element:
933+
934+ > %^ spin (limo ~[4 5 6])
935+ |=({n/@ a/@} [`(pair)`[a n] +(a)])
936+ 0
937+ ~[[p=0 q=4] [p=1 q=5] [p=2 q=6]]
938+
939+Create 10 random numbers less than `10`:
940+
941+ > %^ spin (reap 10 0)
942+ |=({n/@ rng/_og} (rads:rng 10))
943+ ~(. og eny)
944+ ~[5 5 9 4 1 7 9 9 9 6]
945+
946+*Notes*:
947+
948+`(~(rads og eny) 2)` creates a random number less than `2`, seeding the RNG
949+with entropy (`eny`). The head of the product is the random number, the tail
950+is the continuation of the RNG.
951+
952+
953+
954+***
955+### `++spun`
956+
957+Gate to list, with state
958+
959+Accepts a `++list` `a` and a gate `b`. `c` is internal state, initially
960+derived by *bunting* the tail of the sample of gate `b`, instead of
961+being passed in explicitly as in `++spin`. Produces a list with the
962+gate applied to each element of the original list. `b` is called with a tuple
963+-- the head is an element of `a` and the tail is the state `c`, and should
964+produce a tuple of the transformed element and the (potentially modified)
965+state `c`.
966+
967+Accepts
968+-------
969+
970+`a` is a `++list`.
971+
972+`b` is a gate.
973+
974+Produces
975+--------
976+
977+A list.
978+
979+Source
980+------
981+
982+ ++ spun
983+ |* {a/(list) b/_|=({* *} [** +<+])}
984+ =| c/_+<+.b
985+ |-
986+ ?~ a
987+ ~
988+ =+ v=(b i.a c)
989+ [i=-.v t=$(a t.a, c +.v)]
990+
991+
992+Examples
993+--------
994+
995+Create a list of pairs, `p` as the index and `q` as the list element:
996+
997+ > %+ spun (limo ~[4 5 6])
998+ |=({n/@ a/@} [`(pair)`[a n] +(a)])
999+ ~[[p=0 q=4] [p=1 q=5] [p=2 q=6]]
1000+
1001+Join two lists into a list of pairs, `p` from `l` and `q` from the sample:
1002+
1003+ > =l (limo ~[7 8 9])
1004+ > %+ spun (limo ~[4 5 6])
1005+ |=({n/@ a/@} [`(pair)`[(snag a l) n] +(a)])
1006+ ~[[p=7 q=4] [p=8 q=5] [p=9 q=6]]
1007+
1008+
1009+
7771010***
7781011### `++weld`
7791012
docs/hoon/library/2h.md+44
@@ -461,6 +461,50 @@ Examples
461461
462462------------------------------------------------------------------------
463463
464+### `+-run:in`
465+
466+Apply gate to set (often called *map*)
467+
468+Produce a `++set` containing the products of gate `b` applied to each element
469+in `a`.
470+
471+Accepts
472+-------
473+
474+`a` is a `++set`.
475+
476+`b` is a gate.
477+
478+Produces
479+--------
480+
481+A set.
482+
483+Source
484+------
485+
486+ +- run :: apply gate to values
487+ ~/ %run
488+ |* b/gate
489+ =| c/(set _?>(?=(^ a) (b n.a)))
490+ |- ?~ a c
491+ =. c (~(put in c) (b n.a))
492+ =. c $(a l.a, c c)
493+ $(a r.a, c c)
494+
495+
496+
497+Examples
498+--------
499+
500+ > =s (sy ~["a" "A" "b" "c"])
501+ > s
502+ {"A" "a" "c" "b"}
503+ > (~(run in s) cuss)
504+ {'A' 'C' 'B'}
505+
506+------------------------------------------------------------------------
507+
464508### `+-tap:in`
465509
466510Set to list
docs/hoon/library/2n.md+6−4
@@ -145,10 +145,12 @@ not.
145145Source
146146------
147147
148− ++ cury :: curry left
149− |* {a/_|=(^ **) b/*}
150− |* c/_+<+.a
151− (a b c)
148+ ++ hard :: force coerce to span
149+ |* han/mold
150+ |= fud/* ^- han
151+ ~| %hard
152+ =+ gol=(han fud)
153+ ?>(=(gol fud) gol)
152154 ::
153155
154156Examples
docs/hoon/library/2q.md+2−2
@@ -147,9 +147,9 @@ Source
147147Examples
148148--------
149149
150− > `(list ,char)`"foobar"
150+ > `(list char)`"foobar"
151151 "foobar"
152− > `(list ,@)`"foobar"
152+ > `(list @)`"foobar"
153153 ~[102 111 111 98 97 114]
154154
155155
docs/hoon/library/4h.md+1−1
@@ -61,7 +61,7 @@ Examples
6161Parse backslash
6262
6363Parses ASCII character 92, the backslash. Note the extra `\` in the calling of
64−`bas` with [`++just`](/doc/hoon/library/2ec#++just) is to escape the escape
64+`bas` with [`++just`](/docs/hoon/library/2ec#++just) is to escape the escape
6565character, `\`.
6666
6767Source
docs/hoon/library/zuse/core/epur.md+1−1
@@ -12,7 +12,7 @@ Parses an entire URL.
1212Accepts
1313-------
1414
15−`a` is a [`++cord`](/doc/hoon/library/1#++cord).
15+`a` is a [`++cord`](/docs/hoon/library/1#++cord).
1616
1717Produces
1818--------
docs/hoon/library/zuse/core/yu.md+1−1
@@ -153,7 +153,7 @@ Examples
153153Back-shifted leap second dates
154154
155155Produces a [`++list`]() of absolute dates ([`@da`]()s) that represent the Urbit
156−Galactc Time equivalents of the UTC leap second dates in [`++les`](/doc/hoon/library/3bc#++les).
156+Galactc Time equivalents of the UTC leap second dates in [`++les`](/docs/hoon/library/3bc#++les).
157157
158158Produces
159159--------
docs/hoon/library/zuse/diff.md+1−1
@@ -227,7 +227,7 @@ Examples
227227Find common
228228
229229Finds a subsequence of repeated elements within two
230−[`++list`](/doc/hoon/library/1#++list)s, producing a [\`++tape]().
230+[`++list`](/docs/hoon/library/1#++list)s, producing a [\`++tape]().
231231
232232Accepts
233233-------
docs/hoon/library/zuse/gate/jesc.md+1−1
@@ -7,7 +7,7 @@ navhome: /docs
77
88Escape JSON character
99
10−Produces a [`++tape`]() of an escaped [`++json`](/doc/hoon/library/3bi#++json) character `a`.
10+Produces a [`++tape`]() of an escaped [`++json`](/docs/hoon/library/3bi#++json) character `a`.
1111
1212Accepts
1313-------
docs/hoon/library/zuse/gate/tope.md+1−1
@@ -24,7 +24,7 @@ A `++path`.
2424 ^- path
2525 [(scot %p p.bem) q.bem (scot r.bem) (flop s.bem)]
2626
27−Parses a [`++beam`]() to a [`++path`](/doc/hoon/library/1#++path).
27+Parses a [`++beam`]() to a [`++path`](/docs/hoon/library/1#++path).
2828
2929 ~zod/try=/zop> (tope [~zod %main ud/1] /hook/down/sur)
3030 /~zod/main/1/sur/down/hook
docs/hoon/reference.md+4
@@ -10,6 +10,10 @@ title: Twig reference
1010
1111<div class="book">
1212
13+### [Atoms and strings](../twig/atom)
14+
15+### [Limbs and wings](../twig/limb)
16+
1317## `$ buc` (mold)
1418
1519<list src="../twig/buc-mold" dataPreview="true" className="runes" childIsFragment="true"></list>
docs/hoon/syntax.md+4−4
@@ -159,7 +159,7 @@ with the [original](../demo).
159159 |= end/atom
160160 =/ count 1
161161 |- ^- (list tape)
162− ?: =(100 count) ~
162+ ?: =(end count) ~
163163 :_ $(count (add 1 count))
164164 ?: =(0 (mod count 15))
165165 "FizzBuzz"
@@ -167,7 +167,7 @@ with the [original](../demo).
167167 "Fizz"
168168 ?: =(0 (mod count 3))
169169 "Buzz"
170− (text !>(count))
170+ (pave !>(count))
171171```
172172
173173## Tall regular form
@@ -371,7 +371,7 @@ long names and/or kebab-case.
371371
372372If you came all this way to learn how to write apps, you're all
373373set. This is about all you need to know to start getting your
374−hands dirty. Refer back here or to the [standard library](/hoon/library) when
375−needed, but for now, move on to [Arvo](/arvo) to continue learning.
374+hands dirty. Refer back here or to the [standard library](../../hoon/library) when
375+needed, but for now, move on to [Arvo](../../arvo) to continue learning.
376376
377377If, however, good enough is *not* enough, feel free to dive deeper:
docs/hoon/twig.md+1−1
@@ -28,7 +28,7 @@ Most stems are implemented as internal macros, however.
2828The bulb is usually a tuple, sometimes a list or map. An element
2929of this structure is a *subexpression* or just *leg*.
3030
31−Usually a subexpression is itself a `twig`; sometimes it's an
31+Usually a subexpression is itself a `twig`; sometimes it's a
3232`@tas` (symbol) or a `wing` (reference path).
3333
3434## Moldy moss; woody seed
docs/hoon/twig/bar-core/cab-door.md+1−1
@@ -4,7 +4,7 @@ sort: 5
44
55---
66
7−# `:door |_ "buccab"`
7+# `:door |_ "barcab"`
88
99`{$door p/moss q/(map term foot)}`: form a door, a many-armed core
1010with a sample.
docs/hoon/twig/bar-core/dot-trap.md+3
@@ -52,3 +52,6 @@ A more interesting trap:
5252
5353Note that we can use `:moar()` or `$()` to recurse back into the
5454trap, since it's a core with an `$` arm.
55+
56+> `:moar()` expands to `:make($)` (`%=($)`), accepting a *jogging* body
57+> containing a list of changes to the subject.
docs/hoon/twig/bar-core/hep-loop.md+9
@@ -21,6 +21,15 @@ sort: 4
2121
2222Regular: *1-fixed*.
2323
24+## Discussion
25+
26+The `:loop` keyword (and `|-` rune) can be thought of as a "recursion point" -
27+since `:loop` makes a `:trap` (a core with one arm named `$`), we can recurse
28+back into it with `:moar()` or `$()`.
29+
30+> `:moar()` expands to `:make($)` (`%=($)`), accepting a *jogging* body
31+> containing a list of changes to the subject.
32+
2433## Examples
2534
2635A trivial loop doesn't even recurse:
docs/hoon/twig/bar-core/tar-gill.md+5
@@ -32,6 +32,11 @@ is still only one copy of the code, however).
3232Genericity is a powerful and dangerous tool. Use gills only if
3333you think you know what you're doing.
3434
35+Just as with a `:gate`, we can recurse back into a `:gill` with `:moar()` or `$()`.
36+
37+> `:moar()` expands to `:make($)` (`%=($)`), accepting a *jogging* body
38+> containing a list of changes to the subject.
39+
3540## Examples
3641
3742Wet and dry gates in a nutshell:
docs/hoon/twig/bar-core/tis-gate.md+6
@@ -24,6 +24,12 @@ Regular: *2-fixed*.
2424
2525## Discussion
2626
27+A gate is a core with one arm named `$`, so, just as with `:loop` (`|-`),
28+we can recurse back into it with `:moar()` or `$()`.
29+
30+> `:moar()` expands to `:make($)` (`%=($)`), accepting a *jogging* body
31+> containing a list of changes to the subject.
32+
2733## Examples
2834
2935A trivial gate:
docs/hoon/twig/buc-mold/hep-lamb.md+1−1
@@ -4,7 +4,7 @@ sort: 8
44
55---
66
7−# `:lamb $-, "buchep"`
7+# `:lamb $- "buchep"`
88
99`{$lamb p/moss q/moss}`: mold which normalizes to an example gate.
1010
docs/hoon/twig/tis-flow/bar-new.md+1−1
@@ -3,7 +3,7 @@ navhome: /docs
33sort: 5
44---
55
6−# `:new =| , "tisbar"`
6+# `:new =| "tisbar"`
77
88`{$new p/moss q/seed}`: combine a defaulted mold with the subject.
99
docs/hoon/twig/wut-test/gar-sure.md+1−1
@@ -3,7 +3,7 @@ navhome: /docs
33sort: 11
44---
55
6−# `:sure ?< "wutgar"`
6+# `:sure ?> "wutgar"`
77
88`{$sure p/seed q/seed}`: positive assertion.
99
docs/hoon/twig/wut-test/lus-deft.md+1−1
@@ -3,7 +3,7 @@ navhome: /docs
33sort: 13
44---
55
6−# `:deft ?- "wutlus"`
6+# `:deft ?+ "wutlus"`
77
88`{$case p/wing q/seed r/(list (pair moss seed))}`: switch against
99a union, with a default.
docs/hoon/twig/wut-test/zap-not.md+3−1
@@ -19,11 +19,13 @@ Produces the logical "not" of `p`.
1919
2020Regular: *1-fixed*.
2121
22−Irregular: `!(foo)` is `?!(foo)`.
22+Irregular: `!foo` is `?!(foo)`.
2323
2424## Examples
2525
2626```
27+~zod:dojo> ?!(.=(1 2))
28+%.y
2729~zod:dojo> !&
2830%.n
2931~zod:dojo> !|
docs/hoon/twig/zap-wild/gar-wrap.md+1−1
@@ -24,5 +24,5 @@ span-noun cell is generally called a `vase`.
2424
2525```
2626~zod:dojo> !>(1)
27−[#t/@ud q=1]
27+[p=#t/@ud q=1]
2828```
docs/nock.md+4
@@ -6,4 +6,8 @@ title: Nock
66
77# Nock
88
9+Nock is our nano-VM. If you're into combinators or want to understand the foundation of Urbit, dive in.
10+
11+Building a Nock interpreter is a fun exercise, as you can see in the [implementations](nock/implementations)
12+
913<list/>
docs/nock/implementations/csharp.mdnew file+478
@@ -0,0 +1,478 @@
1+---
2+navhome: /docs
3+title: C#
4+sort: 12
5+next: true
6+---
7+
8+# C#
9+
10+From [Julien Beasley](https://github.com/zass30/Nock5KCSharp):
11+
12+```
13+using System;
14+using System.Collections.Generic;
15+using System.Linq;
16+using System.Text;
17+using System.Text.RegularExpressions;
18+
19+namespace NockInterpreter
20+{
21+ class Interpreter
22+ {
23+ static Dictionary<string, Noun> memocache = new Dictionary<string, Noun>();
24+
25+ public static Noun Nock(Noun noun)
26+ {
27+ Start:
28+ Noun cache_noun;
29+ if (memocache.TryGetValue(noun.ToString(), out cache_noun))
30+ {
31+ return cache_noun;
32+ }
33+
34+ if (Atom.IsAtom(noun))
35+ throw new Exception("Infinite loop nocking an atom: " + noun.ToString());
36+ else
37+ {
38+ Noun subject = noun.n1;
39+ if (Noun.IsCell(noun.n2))
40+ {
41+ Cell formula = (Cell)noun.n2;
42+ if (Noun.IsAtom(formula.n1)) // we have lines 25-37 of spec
43+ {
44+ Atom op = (Atom)formula.n1;
45+ Noun operands = formula.n2;
46+
47+ switch (op.value)
48+ {
49+ case 0: // 25 :: *[a 0 b] /[b a]
50+ memocache[noun.ToString()] = fas(operands, subject);
51+ return memocache[noun.ToString()];
52+ case 1: // 26 :: *[a 1 b] b
53+ memocache[noun.ToString()] = operands;
54+ return memocache[noun.ToString()];
55+ case 2: // 27 :: *[a 2 b c] *[*[a b] *[a c]]
56+ if (Noun.IsCell(operands))
57+ {
58+ Noun a = Nock(subject, operands.n1);
59+ Noun b = Nock(subject, operands.n2);
60+ noun = Noun.CreateNoun(a, b);
61+ goto Start;
62+ // return Nock(Nock(subject, operands.n1), Nock(subject, operands.n2));
63+ }
64+ throw new Exception("Atom after operand 2: " + operands.ToString());
65+ case 3: // 28 :: *[a 3 b] ?*[a b]
66+ memocache[noun.ToString()] = wut(Nock(subject, operands));
67+ return memocache[noun.ToString()];
68+ case 4: // 29 :: *[a 4 b] +*[a b]
69+ memocache[noun.ToString()] = lus(Nock(subject, operands));
70+ return memocache[noun.ToString()];
71+ case 5: // 30 :: *[a 5 b] =*[a b]
72+ memocache[noun.ToString()] = tis(Nock(subject, operands));
73+ return memocache[noun.ToString()];
74+ case 6: // 32 :: *[a 6 b c d] *[a 2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]
75+ if (Noun.IsCell(operands) && Noun.IsCell(operands.n2))
76+ {
77+ Noun b = operands.n1;
78+ Noun c = operands.n2.n1;
79+ Noun d = operands.n2.n2;
80+ noun = Noun.CreateNoun("[" + subject + " 2 [0 1] 2 [1 " + c + " " + d + "] [1 0] 2 [1 2 3] [1 0] 4 4 " + b + "]");
81+ goto Start;
82+ // return Nock(Noun.CreateNoun("[" + subject + " 2 [0 1] 2 [1 " + c + " " + d + "] [1 0] 2 [1 2 3] [1 0] 4 4 " + b + "]"));
83+ }
84+ throw new Exception("Unhandled pattern for operand 6");
85+ case 7: // 33 :: *[a 7 b c] *[a 2 b 1 c]
86+ if (Noun.IsCell(operands))
87+ {
88+ Noun b = operands.n1;
89+ Noun c = operands.n2;
90+ noun = Noun.CreateNoun("[" + subject + " 2 " + b + " 1 " + c + "]");
91+ goto Start;
92+ // return Nock(Noun.CreateNoun("[" + subject + " 2 " + b + " 1 " + c + "]"));
93+ }
94+ throw new Exception("Atom after operand 7: " + operands.ToString());
95+ case 8: // 34 :: *[a 8 b c] *[a 7 [[7 [0 1] b] 0 1] c]
96+ if (Noun.IsCell(operands))
97+ {
98+ Noun b = operands.n1;
99+ Noun c = operands.n2;
100+ noun = Noun.CreateNoun("[" + subject + " 7 [[7 [0 1] " + b + "] 0 1] " + c + "]");
101+ goto Start;
102+ // return Nock(Noun.CreateNoun("[" + subject + " 7 [[7 [0 1] " + b + "] 0 1] " + c + "]"));
103+ }
104+ throw new Exception("Atom after operand 8: " + operands.ToString());
105+ case 9: // 35 :: *[a 9 b c] *[a 7 c 2 [0 1] 0 b]
106+ if (Noun.IsCell(operands))
107+ {
108+ Noun b = operands.n1;
109+ Noun c = operands.n2;
110+ noun = Noun.CreateNoun("[" + subject + " 7 " + c + " 2 [0 1] 0 " + b + "]");
111+ goto Start;
112+ // return Nock(Noun.CreateNoun("[" + subject + " 7 " + c + " 2 [0 1] 0 " + b + "]"));
113+ }
114+ throw new Exception("Atom after operand 9: " + operands.ToString());
115+ case 10:
116+ if (Noun.IsCell(operands))
117+ {
118+ if (Noun.IsCell(operands.n1)) // 36 :: *[a 10 [b c] d] *[a 8 c 7 [0 3] d]
119+ {
120+ Noun b = operands.n1.n1;
121+ Noun c = operands.n1.n2;
122+ Noun d = operands.n2;
123+ noun = Noun.CreateNoun("[" + subject + " 8 " + c + " 7 [0 3] " + d + "]");
124+ goto Start;
125+ // return Nock(Noun.CreateNoun("[" + subject + " 8 " + c + " 7 [0 3] " + d + "]"));
126+ }
127+ else // 37 :: *[a 10 b c] *[a c]
128+ {
129+ Noun c = operands.n2;
130+ noun = Noun.CreateNoun(subject, c);
131+ goto Start;
132+ // return Nock(subject, c);
133+ }
134+ }
135+ throw new Exception("Atom after operand 10: " + operands.ToString());
136+ default:
137+ throw new Exception("Unknown operand: " + op.value);
138+ }
139+ }
140+ else // 23 :: *[a [b c] d] [*[a b c] *[a d]]
141+ {
142+ memocache[noun.ToString()] = Noun.CreateNoun(Nock(subject, formula.n1), Nock(subject, formula.n2));
143+ return memocache[noun.ToString()];
144+ }
145+ }
146+ }
147+ throw new Exception("Unhandled pattern");
148+ }
149+
150+ public static Noun Nock(string program)
151+ {
152+ Noun noun = Noun.CreateNoun(program);
153+ return Nock(noun);
154+ }
155+
156+ public static Noun Nock(Noun n1, Noun n2)
157+ {
158+ Noun noun = Noun.CreateNoun(n1, n2);
159+ return Nock(noun);
160+ }
161+
162+ private static Noun tis(Noun noun)
163+ {
164+ if (Noun.IsAtom(noun.ToString()))
165+ throw new Exception("Infinite loop tising an atom: " + noun.ToString());
166+ else
167+ {
168+ Cell cell = (Cell)noun;
169+
170+ if (cell.n1.ToString() == cell.n2.ToString())
171+ return Noun.CreateNoun("0");
172+ else
173+ return Noun.CreateNoun("1");
174+ }
175+ }
176+
177+ private static Noun lus(Noun noun)
178+ {
179+ if (Noun.IsAtom(noun.ToString()))
180+ {
181+ Atom a = (Atom)noun;
182+ int v = a.value + 1;
183+ return Noun.CreateNoun(v.ToString());
184+ }
185+ else
186+ throw new Exception("Infinite loop lusing a cell: " + noun.ToString());
187+ }
188+
189+ private static Noun wut(Noun noun)
190+ {
191+ if (Noun.IsAtom(noun.ToString()))
192+ return Noun.CreateNoun("1");
193+ else
194+ return Noun.CreateNoun("0");
195+ }
196+
197+ private static Noun fas(Noun n1, Noun n2)
198+ {
199+ Noun noun = Noun.CreateNoun(n1, n2);
200+ return fas(noun);
201+ }
202+
203+ private static Noun fas(Noun noun)
204+ {
205+ if (Noun.IsAtom(noun.ToString()))
206+ throw new Exception("Infinite loop fasing an atom: " + noun.ToString());
207+ else
208+ {
209+ Cell c = (Cell)noun;
210+ // If n1 isn't an atom, I assume we throw? This isn't defined in the spec. Confirmed by John B by email. This spins forever.
211+ if (Noun.IsCell(c.n1.ToString()))
212+ throw new Exception("Axis must be an atom: " + c.ToString());
213+ else
214+ {
215+ Atom a = (Atom)c.n1;
216+ if (a.value == 1)
217+ return c.n2;
218+ else if (a.value >= 2)
219+ {
220+ if (!Noun.IsCell(c.n2.ToString()))
221+ {
222+ throw new Exception("Only a cell can have an axis of 2 or 3: " + c.n2.ToString());
223+ }
224+ else
225+ {
226+ Cell c2 = (Cell)c.n2;
227+ if (a.value == 2)
228+ return c2.n1;
229+ else if (a.value == 3)
230+ return c2.n2;
231+ else if (a.value % 2 == 0)
232+ {
233+ int half = a.value / 2;
234+ return fas(Noun.CreateNoun("2", fas(Noun.CreateNoun(half.ToString(), c2))));
235+ }
236+ else if (a.value % 2 == 1)
237+ {
238+ int half = a.value / 2;
239+ return fas(Noun.CreateNoun("3", fas(Noun.CreateNoun(half.ToString(), c2))));
240+ }
241+ else
242+ {
243+ throw new Exception("Infinite loop somewhere in fasing: " + c.n2.ToString());
244+ }
245+ }
246+ }
247+ }
248+ throw new Exception("Infinite loop somewhere in fasing: " + c.n2.ToString());
249+ }
250+ }
251+ }
252+
253+ class Noun
254+ {
255+ public Noun n1;
256+ public Noun n2;
257+
258+ // takes a program, returns a pair of nouns, stringified.
259+ public static Tuple<string, string> SplitCell(string program)
260+ {
261+
262+ int stackCount = 0;
263+ int i = 0;
264+ // split the string right after the first space
265+ foreach (char c in program)
266+ {
267+ if (IsValidChar(c))
268+ {
269+ if (c == '[')
270+ stackCount++;
271+ else if (c == ']')
272+ stackCount--;
273+ else if (c == ' ')
274+ {
275+ // if we see a space, and our stack count is at 1, then we've found our split point
276+ if (stackCount == 1)
277+ {
278+ string a = program.Substring(1, i - 1);
279+ string b = program.Substring(i + 1, program.Length - (i + 2));
280+
281+ // to implement proper bracket closing, surround b with brackets if it isn't a cell and isn't an atom
282+ if (!IsCell(b) && !IsAtom(b))
283+ b = "[" + b + "]";
284+ Tuple<string, string> tuple = new Tuple<string, string>(a, b);
285+ return tuple;
286+ }
287+ }
288+ }
289+ else
290+ throw new Exception("Invalid char in cell: " + c);
291+ i++;
292+ }
293+ throw new Exception("Invalid cell: " + program);
294+ }
295+
296+ public static bool IsCell(string program)
297+ {
298+ // check if cell is valid, as above but make sure no space after bracket
299+ // valid tokens are: space, int, [, ]
300+ // from [ => [, int
301+ // from int => space, ], int
302+ // from ] => space, ]
303+ // from space => int, [
304+
305+ // stack count must always be nonzero
306+ // first and last elements must be [ and ]
307+
308+ int i = 0; // i is the stack count for brackets.
309+ int counter = 0;
310+ char s = '\0'; // s is the last seen character
311+ // split the string right after the first space
312+ foreach (char c in program)
313+ {
314+ if (s == '\0')
315+ {
316+ if (c != '[')
317+ return false;
318+ }
319+ else if (s == '[')
320+ {
321+ if (!(c == '[' || IsInt(c)))
322+ return false;
323+ }
324+ else if (IsInt(s))
325+ {
326+ if (!(IsInt(c) || c == ' ' || c == ']'))
327+ return false;
328+ }
329+ else if (s == ']')
330+ {
331+ if (!(c == ']' || c == ' '))
332+ return false;
333+ }
334+ else if (s == ' ')
335+ {
336+ if (!(c == '[' || IsInt(c)))
337+ return false;
338+ }
339+ s = c;
340+ counter++;
341+ if (c == '[')
342+ i++;
343+ else if (c == ']')
344+ i--;
345+ if (i <= 0 && counter != program.Length) // stack count can't be zero unless it's the last character
346+ return false;
347+ }
348+
349+ // We should end with stack count of zero
350+ if (i == 0)
351+ return true;
352+ else
353+ return false;
354+ }
355+
356+ public static bool IsInt(char c)
357+ {
358+ if (c == '0' ||
359+ c == '1' ||
360+ c == '2' ||
361+ c == '3' ||
362+ c == '4' ||
363+ c == '5' ||
364+ c == '6' ||
365+ c == '7' ||
366+ c == '8' ||
367+ c == '9')
368+ return true;
369+ else
370+ return false;
371+ }
372+
373+ public static bool IsValidChar(char c)
374+ {
375+ if (c == ' ' ||
376+ c == '[' ||
377+ c == ']' ||
378+ IsInt(c))
379+ return true;
380+ else
381+ return false;
382+ }
383+
384+ public static bool IsAtom(string program)
385+ {
386+ int i = 0;
387+ if (int.TryParse(program, out i))
388+ {
389+ if (i >= 0)
390+ return true;
391+ }
392+ return false;
393+ }
394+
395+ public static bool IsAtom(Noun noun)
396+ {
397+ return IsAtom(noun.ToString());
398+ }
399+
400+ public static bool IsCell(Noun noun)
401+ {
402+ return IsCell(noun.ToString());
403+ }
404+
405+ public static Noun CreateNoun(string program)
406+ {
407+ if (IsAtom(program))
408+ return new Atom(program);
409+ else
410+ return new Cell(program);
411+ }
412+
413+ public static Noun CreateNoun(Noun n1, Noun n2)
414+ {
415+ return CreateNoun("[" + n1.ToString() + " " + n2.ToString() + "]");
416+ }
417+
418+ public static Noun CreateNoun(string p1, Noun n2)
419+ {
420+ return CreateNoun("[" + p1 + " " + n2.ToString() + "]");
421+ }
422+
423+ public static Noun CreateNoun(Noun n1, string p2)
424+ {
425+ return CreateNoun("[" + n1.ToString() + " " + p2 + "]");
426+ }
427+
428+ public static Noun CreateNoun(string p1, string p2)
429+ {
430+ return CreateNoun("[" + p1 + " " + p2 + "]");
431+ }
432+ }
433+
434+ class Atom : Noun
435+ {
436+ public int value;
437+
438+ public override string ToString()
439+ {
440+ return value.ToString();
441+ }
442+
443+ public Atom(string program)
444+ {
445+ if (IsAtom(program))
446+ {
447+ int i = 0;
448+ bool result = int.TryParse(program, out i);
449+ value = i;
450+ }
451+ else
452+ throw new ArgumentException("Invalid Atom: " + program);
453+ n1 = null;
454+ n2 = null;
455+ }
456+ }
457+
458+ class Cell : Noun
459+ {
460+ public override string ToString()
461+ {
462+ return "[" + n1.ToString() + " " + n2.ToString() + "]";
463+ }
464+
465+ public Cell(string program)
466+ {
467+ if (IsCell(program))
468+ {
469+ Tuple<string, string> split = SplitCell(program);
470+ n1 = CreateNoun(split.Item1);
471+ n2 = CreateNoun(split.Item2);
472+ }
473+ else
474+ throw new ArgumentException("Invalid Cell: " + program);
475+ }
476+ }
477+}
478+```
docs/using.md+4
@@ -5,4 +5,8 @@ sort: 2
55
66# Using
77
8+These short guides will get you installed, setup, and walk you through the basic features of Urbit. Each section has a quickstart at the top that covers the basics.
9+
10+The sections do build on eachother, so it's a good idea to at least skim them in order.
11+
812<list/>
docs/using/filesystem.md+91−86
@@ -1,24 +1,28 @@
11---
2−navhome: /docs
3−next: true
2+navhome: '/docs'
3+next: True
44sort: 6
55title: Filesystem
66---
77
88# Filesystem (`%clay`)
99
10−<div class="row"> <div class="col-md-8">
10+<div class="row">
1111
12−Urbit has its own revision-controlled filesystem, `%clay`. `%clay` is
13−a typed, global, referentially transparent namespace. An easy way to
14−think about it is like typed `git` with continuous sync.
12+<div class="col-md-8">
1513
16−The most common way to use `%clay` is to mount a `%clay` node in a
17−Unix directory. The Urbit process will watch this directory and
18−automatically record edits as changes, Dropbox style. The mounted
19−directory is always at the root of your pier directory.
14+Urbit has its own revision-controlled filesystem, `%clay`. `%clay` is a
15+typed, global, referentially transparent namespace. An easy way to think
16+about it is like typed `git` with continuous sync.
2017
21−</div> </div>
18+The most common way to use `%clay` is to mount a `%clay` node in a Unix
19+directory. The Urbit process will watch this directory and automatically
20+record edits as changes, Dropbox style. The mounted directory is always
21+at the root of your pier directory.
22+
23+</div>
24+
25+</div>
2226
2327## Quickstart
2428
@@ -28,14 +32,13 @@ Create a `%sandbox` desk based on the `%home` desk:
2832
2933 |merge %sandbox ~your-urbit %home
3034
31−Most of the time we want to use `%clay` from Unix.
35+Most of the time we want to use `%clay` from Unix.
3236
3337Mount the entire contents of your `sandbox` desk to Unix:
3438
3539 ~your-urbit:dojo> |mount /=sandbox=
3640
37−To explore the filesystem from inside Urbit `+ls` and `+cat` are
38−useful:
41+To explore the filesystem from inside Urbit `+ls` and `+cat` are useful:
3942
4043 ~your-urbit:dojo> +ls /=sandbox=/web
4144
@@ -50,37 +53,41 @@ Sync from your friend `~some-ship`'s `%experiment` desk to your
5053
5154## Manual
5255
53−<h3 class="first child">Paths</h3>
56+<h3 class="first child">
57+Paths
58+</h3>
5459
55−A path in `%clay` is a list of URL-safe text, restricted to `[a
56−z]`,`[0 9]`, `.`, `-`, `_` and `~`. Formally this is a `(list knot)`
60+A path in `%clay` is a list of URL-safe text, restricted to
61+`[a z]`,`[0 9]`, `.`, `-`, `_` and `~`. Formally this is a `(list knot)`
5762where each segment is a `@ta`.
5863
5964Paths can be expressed as either `/foo/bar/baz` or `[%foo %bar %baz]`.
6065The first three segments of an urbit path are `/plot/desk/case`, for
61−example `/~doznec/home/1`.
66+example `/~dozbud/home/1`.
6267
6368#### Relative paths
6469
6570Relative paths are expressed using `%` which is roughly equivalent to
66−Unix `.`. `%%` is `..` and `%%%` is what you would expect `...` to
67−be. There are no local relative paths. `foo/bar` must be written
71+Unix `.`. `%%` is `..` and `%%%` is what you would expect `...` to be.
72+There are no local relative paths. `foo/bar` must be written
6873`%/foo/bar`.
6974
7075#### Substitution
7176
7277If the default path is `/foo/bar/baz`, `/=/moo` means `/foo/moo`, and
73−`/=/moo/=/goo` means `/foo/moo/baz/goo`. Also, instead of `/=/=/zoo`
74−or `/=/=/=/voo`, write `/==zoo` or `/===voo`.
78+`/=/moo/=/goo` means `/foo/moo/baz/goo`. Also, instead of `/=/=/zoo` or
79+`/=/=/=/voo`, write `/==zoo` or `/===voo`.
7580
76−Most commonly this is used to avoid having to know the current
77−revision number in the `dojo`. Instead of writing
81+Most commonly this is used to avoid having to know the current revision
82+number in the `dojo`. Instead of writing
7883`/~your-urbit/home/4/path/to/file` you can just write
7984`/=home=/path/to/file`.
8085
8186### Revision-control
8287
83−<h3 class="first child"><code>|mount clay-path [unix-name]</code></h3>
88+<h3 class="first child">
89+<code>|mount clay-path [unix-name]</code>
90+</h3>
8491
8592Mount the `clay-path` at the unix mount point `unix-name`.
8693
@@ -108,44 +115,44 @@ Unmounts the path `%/web` from whatever name it was mounted as.
108115
109116Unmounts the Unix path `/generators`.
110117
111−### `|merge desk beak [strategy]`
118+### `|merge desk beak[, =gem strategy]`
112119
113120Merges a `beak` into a `desk` using an optional merge `strategy`.
114121
115−A `beak` is either a desk (`%home`), a plot-desk cell (`[~doznec
116−%home]`), or a plot-desk-case (`/~doznec/home/2/web/md`)
122+A `beak` is a ship-desk-case triple, encoded as a
123+path(`/~dozbud/home/2`)
117124
118125**Examples:**
119126
120− |merge %home-work /=home= %fine
127+ |merge %home-work /=home=, =gem %fine
121128
122129Merge `/=home=` into `%home-work` using merge strategy `%fine`.
123130
124− |merge %examples [~wacbex-ribmex %examples]
131+ |merge %examples ~wacbex-ribmex %examples
125132
126133Merge the `%examples` desk from `~waxbex-ribmex`
127134
128135### `|sync desk plot [plot-desk]`
129136
130137Subscribe to continuous updates from remote `plot` on local `desk`.
131−`plot-desk` can specify the remote `desk` name. When omitted it's
132−assumed to be the same as `desk`. Moons have `|sync %home ~parent
133−%kids` automatically set up (where `~parent` is the planet that issued
134−the moon).
138+`plot-desk` can specify the remote `desk` name. When omitted it is
139+defaulted to being the same as `desk`. Non-comet urbits have
140+`|sync %home ~parent %kids` automatically set up (where `~parent` is the
141+planet that issued a moon, the star that issued a planet, or the galaxy
142+that issued a star).
135143
136144**Examples:**
137145
138− |sync %home-local ~doznec %home |sync %home ~doznec
146+ |sync %home-local ~dozbud %home |sync %home ~doznec
139147
140148### `|unsync desk plot [plot-desk]`
141149
142150Unsubscribe from updates from remote `plot` on local `desk` with
143−optional `plot-desk`. Arguments must match original `|sync` command
144−exactly.
151+optional `plot-desk`. Arguments must match original `|sync` command.
145152
146153Example:
147154
148− |unsync %home-local ~doznec %home
155+ |unsync %home-local ~dozbud %home
149156
150157### `|label desk name`
151158
@@ -157,84 +164,82 @@ Example:
157164
158165### Merge strategies
159166
160−`%init` - Used if it's the first commit to a desk. Also can be
161−used to "reinitialize" a desk -- revision numbers keep going up,
162−but the new revision isn't necessarily a descendent of the
163−previously-numbered version.
167+`%init` - Used if it's the first commit to a desk. Also can be used to
168+"reinitialize" a desk -- revision numbers keep going up, but the new
169+revision isn't necessarily a descendent of the previously-numbered
170+version, allowing merges to be rerun.
164171
165172`%this` - Keep what's in Bob's desk, but join the ancestry.
166173
167174`%that` - take what's in Alice's desk, but join the ancestry. This is
168−the reverse of `%this`. This is different from `%init` because
169−the new commit has both sides in its ancestry.
175+the reverse of `%this`. This is different from `%init` because the new
176+commit has both sides in its ancestry.
170177
171178`%fine` - "fast-forward" merge. This succeeds iff one head is in the
172179ancestry of the other.
173180
174−`%meet`, `%mate`, and `%meld` - find the most recent common ancestor
175−to use as our merge base.
181+`%meet`, `%mate`, and `%meld` - find the most recent common ancestor to
182+use as our merge base.
176183
177184A `%meet` merge only succeeds if the changes from the merge base to
178−Alice's head (hereafter, "Alice's changes") are in different files
179−than Bob's changes. In this case, the parents are both Alice's and
180−Bob's heads, and the data is the merge base plus Alice's changed files
181−plus Bob's changed files.
185+Alice's head (hereafter, "Alice's changes") are in different files than
186+Bob's changes. In this case, the parents are both Alice's and Bob's
187+heads, and the data is the merge base plus Alice's changed files plus
188+Bob's changed files.
182189
183190A `%mate` merge attempts to merge changes to the same file when both
184−Alice and Bob change it. If the merge is clean, we use it; otherwise,
185−we fail. A merge between different types of changes -- for example,
191+Alice and Bob change it. If the merge is clean, we use it; otherwise, we
192+fail. A merge between different types of changes -- for example,
186193deleting a file vs changing it -- is always a conflict. If we succeed,
187−the parents are both Alice's and Bob's heads, and the data is the
188−merge base plus Alice's changed files plus Bob's changed files plus
189−the merged files.
194+the parents are both Alice's and Bob's heads, and the data is the merge
195+base plus Alice's changed files plus Bob's changed files plus the merged
196+files.
190197
191198A `%meld` merge will succeed even if there are conflicts. If there are
192−conflicts in a file, then we use the merge base's version of that
193−file, and we produce a set of files with conflicts. The parents are
194−both Alice's and Bob's heads, and the data is the merge base plus
195−Alice's changed files plus Bob's changed files plus the successfully
196−merged files plus the merge base's version of the conflicting files.
197−
198−`%auto` - meta-strategy. Check to see if Bob's desk exists, and if it
199−doesn't we use an `%init` merge. Otherwise, we progressively try
200−`%fine`, `%meet`, and `%mate` until one succeeds. If none succeed, we
201−merge Bob's desk into a scratch desk. Then, we merge Alice's desk
202−into the scratch desk with the `%meld` option to force the merge.
203−Finally, we annotate any conflicts, if we know how.
199+conflicts in a file, then we use the merge base's version of that file,
200+and we produce a set of files with conflicts. The parents are both
201+Alice's and Bob's heads, and the data is the merge base plus Alice's
202+changed files plus Bob's changed files plus the successfully merged
203+files plus the merge base's version of the conflicting files.
204+
205+`%auto` - meta-strategy. Check to see if Bob's desk exists, and if it
206+doesn't we use an `%init` merge. Otherwise, we progressively try
207+`%fine`, `%meet`, and `%mate` until one succeeds. If none succeed, we
208+merge Bob's desk into a scratch desk. Then, we merge Alice's desk into
209+the scratch desk with the `%meld` option to force the merge. Finally, we
210+annotate any conflicts, if we know how.
204211
205212### Manipulation
206213
207−<h3 class="first child"><code>|rm path</code></h3>
214+<h3 class="first child">
215+<code>|rm path</code>
216+</h3>
208217
209−Remove the data at `path`. `path` must be a path to actual node, not
210−a 'directory'
218+Remove the data at `path`. `path` must be a path to actual node, not a
219+'directory'
211220
212−### `|cp to from how`
221+### `|cp to from`
213222
214−Copy the subtree `from` into the subtree `to`, committing it with the
215−specified merge strategy `how`.
223+Copy the file at `from` into the path `to`.
216224
217−#### `|mv to from how`
225+#### `|mv to from`
218226
219−Move the subtree `from` into the subtree `to`, committing it with the
220−specified merge strategy `how`.
227+Move the file at `from` into the path `to`.
221228
222−In `%clay`, `|mv` is just a shorthand for `|cp` then `|rm`. The `|rm`
229+In `%clay`, `|mv` is just a shorthand for `|cp` then `|rm`. The `|rm`
223230doesn't happen unless the `|cp` succeeds.
224231
225232### Generators
226233
227−<h3 class="first child"><code>+cat path</code> / <code>+cal [path
228−...]</code></h3>
229−
230−Similar to Unix `cat`. `+cat` takes a single `path`, `+cal` a list of
231−paths.
234+<h3 class="first child">
235+<code>+cat path [path ...]</code>
236+</h3>
232237
233−Produces the contents of the file at the given `path`.
238+Similar to Unix `cat`. `+cat` takes one or more `path`s, and prints
239+their contents.
234240
235−### `+ls path` / `+ll [path ...]`
241+### `+ls path`
236242
237−Similar to Unix `ls`. `+ls` takes a single `path`, `+ll` a list of
238−paths.
243+Similar to Unix `ls`. `+ls` takes a single `path`.
239244
240245Produces a list of names at the `path`.
docs/using/layout.md+1−1
@@ -1,6 +1,6 @@
11---
22navhome: /docs
3−sort: 8
3+sort: 9
44title: Source layout
55---
66
docs/using/messaging.md+127−43
@@ -1,33 +1,49 @@
11---
2−navhome: /docs
3−next: true
2+navhome: '/docs'
3+next: True
44sort: 4
5−title: Messaging (:talk)
5+title: 'Messaging (:talk)'
66---
77
88# Messaging (`:talk`)
99
1010<div class="row">
11+
1112<div class="col-md-8">
1213
13−`:talk` is the Urbit messaging and notifications protocol. Today we use `:talk` just to chat and coordinate, but it's really a general purpose piece of infrastructure.
14+`:talk` is the Urbit messaging and notifications protocol. Today we use
15+`:talk` just to chat and coordinate, but it's really a general purpose
16+piece of infrastructure.
1417
15−For the time being come join us in `/urbit-meta` by using the <a href="#-quickstart">quickstart</a> below.
18+For the time being come join us in `/urbit-meta` by using the
19+<a href="#-quickstart">quickstart</a> below.
1620
17−Today `:talk` is sort of like a distributed, encrypted Slack that can be used from the CLI and the browser. There’s no central `:talk` server. Any Urbit can host one.
21+Today `:talk` is sort of like a distributed, encrypted Slack that can be
22+used from the CLI and the browser. There’s no central `:talk` server.
23+Any Urbit can host one.
1824
19−`:talk` is a general purpose tool for both aggregating and publishing streams of messages. Applications can use `:talk` as their transport protcol, API connectors can push disparate data sources into `:talk`, and so on. There are lots of things a distributed message protocol can be used for that we haven't even thought of.
25+`:talk` is a general purpose tool for both aggregating and publishing
26+streams of messages. Applications can use `:talk` as their transport
27+protcol, API connectors can push disparate data sources into `:talk`,
28+and so on. There are lots of things a distributed message protocol can
29+be used for that we haven't even thought of.
2030
2131</div>
32+
2233</div>
2334
2435## Quickstart
2536
26−For the most part we use `:talk` as a single-instance of Slack: one main channel (`/urbit-meta`) and dms. Everyone is more than welcome in `/urbit-meta`. It's the place to get help, ask questions and chat about Urbit in general.
37+For the most part we use `:talk` as a single-instance of Slack: one main
38+channel (`/urbit-meta`) and dms. Everyone is more than welcome in
39+`/urbit-meta`. It's the place to get help, ask questions and chat about
40+Urbit in general.
2741
2842Let's join `/urbit-meta`:
2943
30− ~your-urbit: ;join ~doznec/urbit-meta
44+Use `ctrl-x` to switch from `:dojo` to `:talk`, then:
45+
46+ ~your-urbit:talk> ;join ~dozbud/urbit-meta
3147
3248You'll see:
3349
@@ -35,14 +51,14 @@ You'll see:
3551 ---------:talk| rules of /urbit-meta:
3652 ---------:talk| don't be rude
3753 ---------:talk| urbit-meta is politically correct and safe for work
38− ~doznec= ~your-urbit admitted to %urbit-meta
54+ ~dozbud= ~your-urbit admitted to %urbit-meta
3955 ~your-urbit:talk>
4056
4157Post a line to `/urbit-meta`:
4258
4359 ~your-urbit:talk> hello, world
4460
45−You'll see, echoed back at you through `~doznec`:
61+You'll see, echoed back at you through `~dozbud`:
4662
4763 ~your-urbit> hello, world
4864
@@ -58,11 +74,18 @@ Now you and `~talsur-todres` can exchange messages directly.
5874
5975To set your audience back to `/urbit-meta`:
6076
61− ~your-urbit:talk> ;~doznec/urbit-meta
77+ ~your-urbit:talk> ;~dozbud/urbit-meta
78+
79+Use `;leave` to unsubscribe from a channel:
80+
81+ ~your-urbit:talk> ;leave ~dozbud/urbit-meta
6282
63−There are two ways of using `:talk`: from the CLI or through a web ui available at `http://your-urbit.urbit.org/talk` (or `http://localhost:8080/talk`).
83+There are two ways of using `:talk`: from the CLI or through a web ui
84+available at `http://your-urbit.urbit.org/talk` (or
85+`http://localhost:8080/talk`).
6486
65−The web ui ships as compiled JavaScript on your Urbit, but has its own source repo [here](https://github.com/urbit/talk).
87+The web ui ships as compiled JavaScript on your Urbit, but has its own
88+source repo [here](https://github.com/urbit/talk).
6689
6790Last, let's create a channel we can invite some friends to:
6891
@@ -72,11 +95,18 @@ Now you can tell your friends to `;join ~your-urbit/my-channel`.
7295
7396## Manual
7497
75−`:talk`'s design is similar in spirit to [nntp](https://en.wikipedia.org/wiki/Network_News_Transfer_Protocol), the underlying protocol for Usenet.
98+`:talk`'s design is similar in spirit to
99+[nntp](https://en.wikipedia.org/wiki/Network_News_Transfer_Protocol),
100+the underlying protocol for Usenet.
76101
77−Our design is pretty simple: `:talk` messages are called ‘posts’. Posts go to ‘stations’. Any urbit can host or subscribe to any number of stations.
102+Our design is pretty simple: `:talk` messages are called ‘posts’. Posts
103+go to ‘stations’. Any urbit can host or subscribe to any number of
104+stations.
78105
79−There are four kinds of station: a write-only `%mailbox` for direct messages, an invite-only `%party` for private conversation, a read-only `%journal` for curated content, and a public-access `%channel` for general use.
106+There are four kinds of station: a write-only `%mailbox` for direct
107+messages, an invite-only `%party` for private conversation, a read-only
108+`%journal` for curated content, and a public-access `%channel` for
109+general use.
80110
81111### Posts
82112
@@ -84,33 +114,79 @@ For the time being a post is either a line, a URL or a command.
84114
85115#### Lines
86116
87−A line is 64 bytes of ASCII lowercase, spaces and punctuation. If the line starts with '@', it's an action (IRC `/me`).
117+A line is 64 bytes of ASCII lowercase, spaces and punctuation. If the
118+line starts with '@', it's an action (IRC `/me`).
88119
89−The `:talk` interface will let you keep typing past 64 bytes, but
90−insert a Unicode bullet-point character in an appropriate space
91−in your post, to show you the prospective linebreak. Your essay
92−will be posted in multiple lines.
120+The `:talk` interface will let you keep typing past 64 bytes, but insert
121+a Unicode bullet-point character in an appropriate space in your post,
122+to show you the prospective linebreak. Your essay will be posted in
123+multiple lines.
124+
125+ ~your-urbit:talk> this is a long message, so it will by truncated right at this•spot
126+
127+will print as
128+
129+ ~your-urbit; this is a long message, so it will by truncated right at this
130+ ~your-urbit; spot
93131
94132#### URLs
95133
96134A URL is any valid URL.
97135
136+ ~your-urbit:talk> http://example.com
137+
98138### Commands
99139
100−A command is a hoon expression, prefaced by '#'.
140+A command is a hoon expression, prefaced by '\#'.
141+
142+ ~your-urbit:talk> #(add 2 2)
143+
144+### Activating Lines
145+
146+A line number identifying the *subsequent* line is displayed every 5
147+lines.
148+
149+ ---------[0]
150+ ~your-urbit; this is my message
151+ ~your-urbit@ this is an @ message
152+ ~your-urbit; this is a long message, so it will by truncated right at this
153+ ~your-urbit; spot
154+ ~your-urbit/ http://example.com/
155+ ---------[5]
156+ ~your-urbit# (add 2 2) 4
157+
158+You can use a line number to *activate* a line:
159+
160+ ~your-urbit:talk> ;0
161+
162+which prints the number, line identifier, timestamp, sender, audience,
163+and contents:
164+
165+ ? 0
166+ 0v3.hl51p.jhege.amhec.vb37r.3rejr at ~2016.6.24..04.48.21..a235
167+ ~your-urbit to ~another-urbit
168+ this is my message
169+
170+Activating a URL will print the full URL (it could have been truncated),
171+and activating a command will evaluate it.
172+
173+You can activate the most recent line with `;`, the second-most recent
174+with `;;`, and so on.
101175
102176### Creating and managing stations
103177
104−`;create journal %serious-journal 'description'` - Creates a `%journal`, a privately writable publicly readable station.
178+`;create journal %serious-journal 'description'` - Creates a `%journal`,
179+a privately writable publicly readable station.
105180
106−`;create channel %serious-channel 'description'` - Creates a `%channel`, a publicly readable publicly writeable station.
181+`;create channel %serious-channel 'description'` - Creates a `%channel`,
182+a publicly readable publicly writeable station.
107183
108184### Presence
109185
110−You'll see presence notifications when people enter or leave
111−stations you're subscribed to.
186+You'll see presence notifications when people enter or leave stations
187+you're subscribed to.
112188
113−`;who` - list everyone in all your stations
189+`;who` - list everyone in all your stations
114190
115191`;who station` - list everyone in that station
116192
@@ -120,13 +196,16 @@ Glyphs are assigned by station hash out of the following list
120196
121197 > = + - } ) , . " ' ^ $ % & @
122198
123−Alphanumeric characters and `|#;:*~_` are reserved; all others (the above lists, and `\/!?({<`) can be manually assigned.
199+Alphanumeric characters and `|#;:*~_` are reserved; all others (the
200+above lists, and `\/!?({<`) can be manually assigned.
124201
125202`;bind > /urbit-test` - assigns the `>` glyph to `/urbit-test`.
126203
127204### Prefixes
128205
129−Received posts are prefixed with a glyph to let you know what the audience is. You can activate an individual post to see the full audience.
206+Received posts are prefixed with a glyph to let you know what the
207+audience is. You can activate an individual post to see the full
208+audience.
130209
131210`|` - Informational messages
132211
@@ -140,7 +219,8 @@ Received posts are prefixed with a glyph to let you know what the audience is.
140219
141220#### Prompt
142221
143−The audience you're sending to is always shown in your prompt. If there's a glyph for it, it's shown as the glyph.
222+The audience you're sending to is always shown in your prompt. If
223+there's a glyph for it, it's shown as the glyph.
144224
145225Here we're talking to the station bound to `=`:
146226
@@ -160,20 +240,21 @@ Here we're talking directly to `~dannum-mitryl`:
160240
161241`;%station` - Set audience to a station on your own ship
162242
163−`;~dannum-mitryl this is a private message` - Set the audience and send a post in the same line. This works for all of the above.
243+`;~dannum-mitryl this is a private message` - Set the audience and send
244+a post in the same line. This works for all of the above.
164245
165−Your audience is configured 'implicitly' with regard to the following rules (in order):
246+Your audience is configured 'implicitly' with regard to the following
247+rules (in order):
166248
167−- if you manually locked the audience, that audience.
168−- if typing a post, the audience when you started typing.
169−- if you activated a post, the post you activated.
170−- audience of the last post received.
171−- audience of the last post sent.
249+- if you manually locked the audience, that audience.
250+- if typing a post, the audience when you started typing.
251+- if you activated a post, the post you activated.
252+- audience of the last post received.
253+- audience of the last post sent.
172254
173−Clear any 'implicit' audience setting by moving your cursor to
174−the start of the line and pressing backspace (whether the line is
175−empty or not). Posting a line clears the typing and activation
176−configurations.
255+Clear any 'implicit' audience setting by moving your cursor to the start
256+of the line and pressing backspace (whether the line is empty or not).
257+Posting a line clears the typing and activation configurations.
177258
178259### Nicknames
179260
@@ -191,4 +272,7 @@ configurations.
191272
192273`;unset noob` show urbit names instead of nicknames
193274
194−All nicknames must be 14 characters or less, lowercase. Nicknames are strictly local - like the names on entries in a phonebook. Sometimes in a post you want to mention someone you know by a nickname. Just type `~plato`, and `:talk` will replace it with `~your-urbit`.
275+All nicknames must be 14 characters or less, lowercase. Nicknames are
276+strictly local - like the names on entries in a phonebook. Sometimes in
277+a post you want to mention someone you know by a nickname. Just type
278+`~plato`, and `:talk` will replace it with `~your-urbit`.
docs/using/setup.md+41−32
@@ -1,49 +1,55 @@
11---
2−navhome: /docs
3−next: true
2+navhome: '/docs'
3+next: True
44sort: 2
55title: Setup
66---
77
88# Getting started
99
10−On disk your urbit is an append-only log and a checkpoint. Or, in simpler terms, a directory where we keep your urbit’s state. We call this a ‘pier’.
10+On disk your urbit is an append-only log and a checkpoint. Or, in
11+simpler terms, a directory where we keep your urbit’s state. We call
12+this a ‘pier’.
1113
1214## Initialize
1315
14−To create an urbit, we need an identity. This identity
15−is both a network address and a memorable name.
16+To create an urbit, we need an identity. This identity is both a network
17+address and a memorable name.
1618
17−You are probably creating one of two kinds of urbit: a 32-bit
18−"planet" or a 128-bit "comet." For a quick terminology guide
19−and high-level refresher, refer to this [handy reference sheet](/about/terminology).
19+You are probably creating one of two kinds of urbit: a 32-bit "planet"
20+or a 128-bit "comet." For a quick terminology guide and high-level
21+refresher, refer to this [handy reference sheet](/docs/about/glossary).
2022
2123If you have an Urbit invitation, you'll have a planet like
22−`~fintud-macrep` and `~fortyv-tombyt-tabsen-sonres`. To create
23−your pier:
24+`~fintud-macrep` and `~fortyv-tombyt-tabsen-sonres`. To create your
25+pier:
2426
2527 $ bin/urbit -w fintud-macrep -t fortyv-tombyt-tabsen-sonres
2628
27−This will create a directory `fintud-macrep/` and begin building
28−your urbit. This may take a few minutes.
29+This will create a directory `fintud-macrep/` and begin building your
30+urbit. This may take a few minutes.
2931
30−If you do not have a ticket, you can still make a 'comet', a wild
31−urbit drifting through cyberspace. Pick your own directory name,
32−it doesn't matter:
32+If you do not have a ticket, you can still make a 'comet', a wild urbit
33+drifting through cyberspace. Pick your own directory name, it doesn't
34+matter:
3335
3436 $ bin/urbit -c mycomet
3537
36−This will create the directory `mycomet/` and generate a 128-bit identity for your urbit.
38+This will create the directory `mycomet/` and generate a 128-bit
39+identity for your urbit.
3740
3841## Orientation
3942
40−When your urbit is finished booting you should see a `dojo>` prompt. Welcome!
43+When your urbit is finished booting you should see a `dojo>` prompt.
44+Welcome!
4145
42−By default your urbit is quite bare-bones. Let's stroll through what's already running:
46+By default your urbit is quite bare-bones. Let's stroll through what's
47+already running:
4348
4449### Shell — `:dojo`
4550
46−The command prompt in front of you is a simple shell and Hoon REPL. Let's make sure it works:
51+The command prompt in front of you is a simple shell and Hoon REPL.
52+Let's make sure it works:
4753
4854 ~fitund-macrep:dojo> (add 2 2)
4955
@@ -56,29 +62,30 @@ Good.
5662
5763### Messaging — `:talk`
5864
59−Use `^X` (ctrl-x) to change your prompt. Let's join the main Urbit chat channel:
65+Use `^X` (ctrl-x) to change your prompt. Let's join the main Urbit chat
66+channel:
6067
61− ~fitund-macrep:talk() ;join ~doznec/urbit-meta
68+ ~fitund-macrep:talk() ;join ~dozbud/urbit-meta
6269
6370`:talk` is stateful, so your urbit will download a backlog.
64−`/urbit-meta` is the place to ask questions, get help and talk
65−about anything Urbit-related.
71+`/urbit-meta` is the place to ask questions, get help and talk about
72+anything Urbit-related.
6673
6774### Web — `:tree`
6875
69−Urbit is also accessible through the web. Try opening:
76+Urbit is also accessible through the web. Try opening:
7077
7178 http://localhost:8080/
7279
73−in your favorite browser. You'll be prompted to use `+code`.
74−This page was generated by `:tree`, the basic Urbit web
75−interface. You can also access your urbit through
76−`http://fintud-macrep.urbit.org` (where `fintud-macrep` is your
77−planet name).
80+in your favorite browser. You'll be prompted to use `+code`. This page
81+was generated by `:tree`, the basic Urbit web interface. You can also
82+access your urbit through `http://fintud-macrep.urbit.org` (where
83+`fintud-macrep` is your planet name).
7884
7985### Filesystem — `%clay`
8086
81−`%clay`, the Urbit filesystem, isn't mounted to unix by default. Switch to the `:dojo` prompt and run:
87+`%clay`, the Urbit filesystem, isn't mounted to unix by default. Switch
88+to the `:dojo` prompt and run:
8289
8390 ~fitund-macrep:dojo> |mount %
8491
@@ -89,10 +96,12 @@ This should produce:
8996
9097which indicates the command was processed.
9198
92−`|mount %` will cause a `home/` directory to appear inside your pier folder. Changes to these files are automatically synced into your urbit.
99+`|mount %` will cause a `home/` directory to appear inside your pier
100+folder. Changes to these files are automatically synced into your urbit.
93101
94102## Learn more
95103
96−If you're eager to get started programming you're ready to head over to <a href="../../hoon/demo">the Hoon demo</a>.
104+If you're eager to get started programming you're ready to head over to
105+<a href="../../hoon/demo">the Hoon demo</a>.
97106
98107To learn more about using the system, let's keep going:
docs/using/shell.md+72−48
@@ -1,21 +1,22 @@
11---
2−navhome: /docs
3−next: true
2+navhome: '/docs'
3+next: True
44sort: 5
5−title: Shell (:dojo)
5+title: 'Shell (:dojo)'
66---
77
88# Shell (`:dojo`)
99
1010<div class="row">
11+
1112<div class="col-md-8">
1213
13−The `:dojo` is the place to quickly experiment with Urbit. On
14−the surface the `:dojo` is just a Hoon REPL. On the inside, the
15−`:dojo` is a system for operating on and transforming data in
16−Urbit.
14+The `:dojo` is the place to quickly experiment with Urbit. On the
15+surface the `:dojo` is just a Hoon REPL. On the inside, the `:dojo` is a
16+system for operating on and transforming data in Urbit.
1717
1818</div>
19+
1920</div>
2021
2122## Quickstart
@@ -28,7 +29,7 @@ Evaluate a hoon expression:
2829Tall form Hoon may require multiple lines:
2930
3031 ~your-urbit:dojo> %+ add
31− ~your-urbit:dojo< 2
32+ ~your-urbit:dojo< 2
3233 ~your-urbit:dojo< 2
3334
3435Use `=var` to save a shell variable:
@@ -51,72 +52,89 @@ Run system commands from `:hood`, like `reload`, using `|`:
5152
5253 ~your-urbit:dojo> |reload %eyre
5354
54−
5555### Generators
5656
57−**`+cat`** - Similar to Unix `cat`. Accepts a path.
57+**`+cat`** - Similar to Unix `cat`. Accepts a path.
5858
5959 ~your-urbit:dojo> +cat %/web/md
6060 ~your-urbit:dojo> +cat /~talsur-todres/home/2/web/notes/md
6161
62−**`+curl`** - Similar to Unix `curl`. Accepts a `tape`.
62+**`+curl`** - Similar to Unix `curl`. Accepts a `tape`.
6363
6464 ~your-urbit:dojo> +curl "http://nyt.com"
6565
66−**`+hello`** - Just prints the argument. Accepts a `@ta`.
66+**`+hello`** - Just prints the argument. Accepts a `@ta`.
6767
6868 ~your-urbit:dojo> +hello 'mars'
6969
70−**`+ls`** - Similar to Unix `ls`. Accepts a path.
70+**`+ls`** - Similar to Unix `ls`. Accepts a path.
7171
7272 ~your-urbit:dojo> +ls %/web
7373 ~your-urbit:dojo> +ls /~talsur-todres/home/2/web/notes
7474
75−**`+moon`** - Generate a random moon from a planet. No arguments.
75+**`+moon`** - Generate a random moon from a planet. No arguments.
76+
77+ ~your-urbit:dojo> +moon
78+
79+**`+solid`** - Compile the current state of the kernel and output a
80+noun. Usually downloaded to a file in unix. No arguments.
7681
77−**`+solid`** - Compile the current state of the kernel and output a noun. Usually downloaded to a file in unix. No arguments.
78−
7982 ~your-urbit:dojo> .urbit/pill +solid
8083
81−**`+ticket`** - Generate a ticket for an Urbit plot. Takes an Urbit name (`@p`).
84+**`+ticket`** - Generate a ticket for an Urbit plot. Takes an Urbit name
85+(`@p`).
8286
8387 ~your-urbit:dojo> +ticket ~talsur-todres-your-urbit
8488
85−**`+tree`** - Generate a recursive directory listing. Takes a path.
89+**`+tree`** - Generate a recursive directory listing. Takes a path.
8690
8791 ~your-urbit:dojo> +tree %/web
8892
8993### Hood
9094
91−The hood is the system daemon. See `gen/hood` and `app/hood`.
95+The hood is the system daemon. See `gen/hood` and `app/hood`.
9296
93−**`|hi`** - Sends a direct message. Sort of like Unix `write`. Accepts an urbit name (`@p`) and a string (`cord`).
97+**`|hi`** - Sends a direct message. Sort of like Unix `write`. Accepts
98+an urbit name (`@p`) and a string (`cord`).
9499
95− ~your-urbit:dojo> |hi ~doznec 'you there?'
100+ ~your-urbit:dojo> |hi ~dozbud "you there?"
96101
97−**`|link`** / **`|unlink`** - Link / unlink a remote app. Accepts an Urbit name and an app name.
102+**`|link`** / **`|unlink`** - Link / unlink a remote app. Accepts an
103+Urbit name and an app name.
98104
99105 ~your-urbit:dojo> |link ~talsur-todres %octo
100106
101−**`|mass`** - Prints the current memory usage of all the kernel modules. No arguments.
107+**`|mass`** - Prints the current memory usage of all the kernel modules.
108+No arguments.
102109
103−**`|reload`** - Reloads a kernel module (vane) from source. Accepts any number of vane names.
110+ ~your-urbit:dojo> |mass
111+
112+**`|reload`** - Reloads a kernel module (vane) from source. Accepts any
113+number of vane names.
104114
105115 ~your-urbit:dojo> |reload %clay %eyre
106116
107−**`|reset`** - Reloads `hoon.hoon`. No arguments.
117+**`|reset`** - Reloads `hoon.hoon` and all modules. No arguments.
118+
119+ ~your-urbit:dojo> |reset
108120
109−**`|start`** - Starts an app. Accepts an app name.
121+**`|start`** - Starts an app. Accepts an app name.
110122
111123 ~your-urbit:dojo> |start %curl
112124
113125## Manual
114126
115−<h3 class="first child">Sources and sinks</h3>
127+<h3 class="first child">
128+Sources and sinks
129+</h3>
116130
117−A dojo command is either a source or a sink. A source is just something that can be printed to your console or the result of some computation. A sink is an *effect*: a change to the filesystem, a network message, a change to your environment, or typed message to an app.
131+A dojo command is either a source or a sink. A source is just something
132+that can be printed to your console or the result of some computation. A
133+sink is an *effect*: a change to the filesystem, a network message, a
134+change to your environment, or typed message to an app.
118135
119−Sources can be chained together, but we can only produce one effect per command.
136+Sources can be chained together, but we can only produce one effect per
137+command.
120138
121139### Sinks
122140
@@ -129,7 +147,7 @@ Set any envronment variable:
129147
130148 44
131149
132−(There are a few special variables that the dojo expects. See below.)
150+(There are a few special variables that the dojo maintains. See below.)
133151
134152#### `:` - Send to app
135153
@@ -139,7 +157,7 @@ Send a `helm-hi` message to `hood`:
139157
140158 ~your-urbit:dojo> :hood &helm-hi 'hi'
141159
142−App usually expect marked data, so `&` is often used here.
160+App usually expect marked data, so `&` is often used here.
143161
144162#### `*` - Save in `%clay`
145163
@@ -147,11 +165,12 @@ Save a new `md` file in `web`:
147165
148166 ~your-urbit:dojo> *%/web/foo/md '# hello'
149167
150−The last component of the path is expected to be the mark (or mime type).
168+The last component of the path is expected to be the mark (or mime
169+type).
151170
152−#### `.` - Download to Unix
171+#### `.` - Export to Unix
153172
154−Download a noun to Unix with `.`:
173+Export a noun to Unix with `.`:
155174
156175 ~your-urbit:dojo> .foo/bar/baz (add 2 2)
157176
@@ -181,7 +200,7 @@ Use `_` to run a gate (or function):
181200 ~your-urbit:dojo> _|=({a/@} (mul a 3)) 3
182201 :: produces
183202 9
184− :: assign an arbitrary function to get the status code from an http request
203+ :: use a function to get the status code from an http request
185204 ~your-urbit:dojo> _|=({p/@ud q/* r/*} p) +http://google.com
186205 :: produces
187206 301
@@ -190,16 +209,18 @@ Use `_` to run a gate (or function):
190209
191210`+http[s]://example.com` - sends a GET request
192211
193−`+http[s]://example.com &json [%s 'hi']` - sends a POST request with the JSON `"hi"` in the body.
212+`+http[s]://example.com &json [%s 'hi']` - sends a POST request with the
213+JSON `"hi"` in the body.
194214
195−`-http[s]://example.com &json [%s 'hi']` - sends a PUT request with the JSON `"hi"` in the body.
215+`-http[s]://example.com &json [%s 'hi']` - sends a PUT request with the
216+JSON `"hi"` in the body.
196217
197−Note that the first of these is a source while the last two are
198−sinks.
218+Note that the first of these is a source while the last two are sinks.
199219
200220#### `+` - Generators
201221
202−Generators are simple hoon scripts loaded from the filesystem. They live in `gen/`.
222+Generators are simple hoon scripts loaded from the filesystem. They live
223+in `gen/`.
203224
204225Create a random moon (from any planet):
205226
@@ -207,9 +228,10 @@ Create a random moon (from any planet):
207228 :: produces
208229 "moon: ~docsun-tamtem-your-urbit; ticket: ~bartug-hodbyr-fognum-ralmud"
209230
210−### Variables
231+### Variables
211232
212−You can use `=` to set an environment variable in `:dojo`, but there are a few reserved names that have special uses.
233+You can use `=` to set an environment variable in `:dojo`, but there are
234+a few reserved names that have special uses.
213235
214236#### `dir`
215237
@@ -222,9 +244,10 @@ Current working `%clay` desk and revision. Read / write.
222244
223245 404/hoon docs/ dojo/hoon lib/ listen/hoon md static/md talk/ tree/main/
224246
225−#### `lib`
247+#### `lib`
226248
227−Current set of libraries (`/lib`) in your environment. Can also be set with `/+`. Read / write.
249+Current set of libraries (`/lib`) in your environment. Can also be set
250+with `/+`. Read / write.
228251
229252**Examples:**
230253
@@ -236,7 +259,8 @@ Current set of libraries (`/lib`) in your environment. Can also be set with `/+
236259
237260#### `sur`
238261
239−Current set of structures (`/sur`) in your environment. Can also be set with `/-`. Read / write.
262+Current set of structures (`/sur`) in your environment. Can also be set
263+with `/-`. Read / write.
240264
241265**Examples:**
242266
@@ -248,7 +272,7 @@ Current set of structures (`/sur`) in your environment. Can also be set with `/
248272
249273#### `now`
250274
251−The current (128-bit `@da`) time. Read-only.
275+The current (128-bit `@da`) time. Read-only.
252276
253277**Example:**
254278
@@ -258,7 +282,7 @@ The current (128-bit `@da`) time. Read-only.
258282
259283#### `our`
260284
261−The current urbit plot. Read-only.
285+The current urbit plot. Read-only.
262286
263287**Example:**
264288
@@ -268,7 +292,7 @@ The current urbit plot. Read-only.
268292
269293#### `eny`
270294
271−256 bits of entropy. Read-only.
295+256 bits of entropy. Read-only.
272296
273297**Example:**
274298
docs/using/urb.mdnew file+356
@@ -0,0 +1,356 @@
1+---
2+navhome: /docs
3+sort: 8
4+title: From Unix
5+---
6+
7+<div class="row">
8+<div class="col-md-8">
9+
10+# Using Urbit from Unix
11+
12+With `urb` at your Unix command line, you can execute hoon, run
13+dojo commands, and more. Additionally, with `fuse`, you can
14+inspect the urbit namespace.
15+
16+</div>
17+</div>
18+
19+## Installation
20+
21+These commands are in the a [separate
22+repo](https://github.com/urbit/urb). Clone this repo to get the
23+commands.
24+
25+You'll also need the `requests` and `fuse` libraries for python.
26+If you have `pip`, you can just run:
27+
28+```
29+pip install requests fuse-python
30+```
31+
32+Otherwise, on Ubuntu, run:
33+
34+```
35+apt-get install python-requests python-fuse
36+```
37+
38+Then you can either run the python commands from the git repo, or
39+put them somewhere in your path.
40+
41+## `urb`
42+
43+`urb` transfers data from a source to a sink. Examples of data
44+sources include literal data, a file, a URL, or some
45+tranformation of another source. Examples of data sinks are
46+stdout, output file, POST request, or dojo command.
47+
48+Here are some examples. This takes the literal data "hello
49+world" and sends it to stdout (the default sink).
50+
51+ urb --data 'hello world'
52+
53+Let's run some hoon code at the dojo.
54+
55+ urb --dojo '(add 2 2)'
56+
57+Let's convert a markdown file to html.
58+
59+ urb --data @@file.md -m md -m html
60+
61+Mount the `%home` desk. This syncs the `home` desk into the pier
62+directory.
63+
64+ urb --dojo '+hood/mount /=home=' --app hood
65+
66+### Sources
67+
68+Sources can be any of the following:
69+
70+- `-d, --dojo command` runs a dojo command. This is commonly
71+ naked hoon code, but it can also be a generator, or any of the
72+ other ways the dojo gets data.
73+
74+- `-D, --data text` is literal text data, as a cord.
75+
76+- `-c, --clay path` pulls data from Urbit's filesystem.
77+
78+- `-u, --url url` pulls data from a URL.
79+
80+- `-m, --mark mark source` converts the output from another source to
81+ a new 'mark' (datatype).
82+
83+- `-H, --hoon code source` transforms the output of another
84+ source by running it through some hoon code.
85+
86+- `[source-0 source-1 ...]`. Sources can be combined into tuples
87+ of different sources.
88+
89+Any of the arguments to a source (except in the "compound
90+sources" `--mark` and `--hoon`) can be replaced by `-` to
91+represent stdin or `@@filename` to pull data in from a Unix file.
92+Thus, `urb [-D @@file1 -D - -D @@file2]` is equivalent to Unix's
93+`cat file1 - file2`.
94+
95+Additionally, if no source is specified, `--data -` (stdin as
96+literal text data) is assumed.
97+
98+### Sinks
99+
100+- `-s, --stdout` outputs to stdout. This is the default.
101+
102+- `-f, --output-file path` writes to a unix file.
103+
104+- `-C, --output-clay path` writes to Urbit's filesystem.
105+
106+- `-U, --output-url url` sends a POST request with the data to
107+ the URL.
108+
109+- `-p, --app app` sends the data to an urbit app.
110+
111+- `-x, --command` outputs to a literal dojo command.
112+
113+## `fuse`
114+
115+Urbit's namespace is accessible through the `fuse` command.
116+`fuse` takes all the normal FUSE arguments, which you can see
117+with `fuse -h`. Generally, you just run `fuse MOUNT-POINT`.
118+
119+When accessing the namespace through `fuse`, everything is
120+read-only. If you want to write to Clay, mount a desk, as
121+described above.
122+
123+Let's look first in the Clay portion of the Urbit namespace.
124+Assume we've mounted to `./pt`.
125+
126+ $ ls ./pt/c/=/=/=
127+ app arvo gen lib mar ren sec sur web
128+ $ ls ./pt/c/=/=/=/arvo
129+ ames behn clay dill eyre ford gall hoon zuse
130+
131+Those `=`s aren't decorative. The first `=` means "current
132+ship", the second "current desk", and the third "current
133+revision". Let's try something a little more exciting.
134+
135+This runs the Unix `diff` command on the first and current
136+versions of the `app/gh/hoon` file, showing all the changes we've
137+made to the file.
138+
139+```
140+$ diff pt/c/=/=/{1,=}/app/gh/hoon
141+73c73,75
142+< (malt (turn issues |=(issue:gh [(rsh 3 2 (scot %ui number)) ~])))
143+---
144+> %- malt ^- (list {@ta $~})
145+> :- [%gh-list-issues ~]
146+> (turn issues |=(issue:gh [(rsh 3 2 (scot %ui number)) ~]))
147+92c94,101
148+< read-y=(read-get /issues)
149+---
150+> read-y=(read-static %gh-list-issues ~)
151+> sigh-x=sigh-list-issues-x
152+> sigh-y=sigh-list-issues-y
153+> ==
154+> ^- place :: /issues/mine/<mark>
155+> :* guard={$issues $mine @t $~}
156+> read-x=read-null
157+> read-y=|=(pax/path [ost %diff %arch `0vsen.tinel ~])
158+126c135
159+< ^- place :: /issues/by-repo/<user>/<repo>
160+---
161+> ^- place :: /issues/by-repo/<user>/<repo>/<number>
162+131c140,146
163+< read-y=(read-static ~)
164+---
165+> ^= read-y
166+> |= pax/path
167+> %. pax
168+> ?: ((sane %tas) -.+>+>.pax)
169+> (read-static ~)
170+> (read-static %gh-issue ~)
171+> ::
172+137a153,159
173+> sigh-y=sigh-strange
174+> ==
175+> ^- place :: /issues/by-repo/<u>/<r>/<n>/<mark>
176+> :* guard={$issues $by-repo @t @t @t @t $~}
177+> read-x=read-null
178+> read-y=|=(pax/path [ost %diff %arch `0vsen.tinel ~])
179+> sigh-x=sigh-strange
180+```
181+
182+Urbit's namespace is not just revisioned, but global. Here's a
183+diff of our version of `arvo/gall/hoon` compared to the one on
184+the `~bud` urbit.
185+
186+```
187+$ diff pt/c/{~bud,=}/=/=/arvo/gall/hoon
188+2d1
189+<
190+640a640,644
191+> =+ ?. ?=($x ren)
192+> [mar=%$ tyl=tyl]
193+> =+ `path`(flop tyl)
194+> ?> ?=(^ -)
195+> [mar=i tyl=(flop t)]
196+643c647
197+< ((slog leaf+"peek find fail" >tyl< ~) [~ ~])
198+---
199+> ((slog leaf+"peek find fail" >tyl< >mar< ~) [~ ~])
200+654a659,660
201+> ?. =(mar p.q.caz)
202+> [~ ~]
203+1308a1315,1316
204+> ?. ?=(^ tyl)
205+> ~
206+```
207+
208+Besides Clay, the namespace contains Gall apps. One common usage
209+of the app namespace is to expose APIs. For example, if you
210+start the `%gh` app (`|start %gh`), you can do things like `cat`
211+an issue from a repository.
212+
213+```
214+$ cat pt/g/=/gh/=/issues/by-repo/philipcmonktest/testing/7/txt
215+title: big news! (#7)
216+state: open
217+creator: philipcmonktest
218+created-at: 2016-03-24T22:27:33Z
219+assignee: philipcmonktest
220+labels: invalid, wontfix, help wanted
221+comments: 0
222+url: https://api.github.com/repos/philipcmonktest/testing/issues/7
223+
224+Yup, that's it. i mean, maybe it's a bit longer than that.
225+
226+But you get the point, right?
227+
228+Code `is` cool!
229+```
230+
231+Or all open issues for a repository.
232+
233+```
234+$ cat pt/g/=/gh/=/issues/by-repo/philipcmonktest/testing/txt
235+title: i found a bug! (#11)
236+state: open
237+creator: philipcmonktest
238+created-at: 2016-04-14T23:14:49Z
239+assignee: none
240+labels:
241+comments: 1
242+url: https://api.github.com/repos/philipcmonktest/testing/issues/11
243+
244+
245+----------------------------------------
246+title: more newz (#8)
247+state: open
248+creator: philipcmonktest
249+created-at: 2016-03-24T22:29:16Z
250+assignee: none
251+labels:
252+comments: 4
253+url: https://api.github.com/repos/philipcmonktest/testing/issues/8
254+
255+Yup, that's it. i mean, maybe it's a bit longer than that.
256+
257+But you get the point, right?
258+
259+Code `is` cool!
260+----------------------------------------
261+title: big news! (#7)
262+state: open
263+creator: philipcmonktest
264+created-at: 2016-03-24T22:27:33Z
265+assignee: philipcmonktest
266+labels: invalid, wontfix, help wanted
267+comments: 0
268+url: https://api.github.com/repos/philipcmonktest/testing/issues/7
269+
270+Yup, that's it. i mean, maybe it's a bit longer than that.
271+
272+But you get the point, right?
273+
274+Code `is` cool!
275+----------------------------------------
276+title: something different (#4)
277+state: open
278+creator: philipcmonktest
279+created-at: 2016-01-26T21:45:08Z
280+assignee: philipcmonktest
281+labels: duplicate, help wanted, question, bug
282+comments: 1
283+url: https://api.github.com/repos/philipcmonktest/testing/issues/4
284+```
285+
286+Don't like the textual format? How about we get the raw JSON
287+(and prettyprint it).
288+
289+```
290+$ cat pt/g/=/gh/=/issues/by-repo/philipcmonktest/testing/7/json | python -m json.tool
291+{
292+ "assignee": {
293+ "avatar_url": "https://avatars.githubusercontent.com/u/16787461?v=3",
294+ "events_url": "https://api.github.com/users/philipcmonktest/events{/privacy}",
295+ "followers_url": "https://api.github.com/users/philipcmonktest/followers",
296+ "following_url": "https://api.github.com/users/philipcmonktest/following{/other_user}",
297+ "gists_url": "https://api.github.com/users/philipcmonktest/gists{/gist_id}",
298+ "gravatar_id": "",
299+ "html_url": "https://github.com/philipcmonktest",
300+ "id": 16787461,
301+ "login": "philipcmonktest",
302+ "organizations_url": "https://api.github.com/users/philipcmonktest/orgs",
303+ "received_events_url": "https://api.github.com/users/philipcmonktest/received_events",
304+ "repos_url": "https://api.github.com/users/philipcmonktest/repos",
305+ "site_admin": false,
306+ "starred_url": "https://api.github.com/users/philipcmonktest/starred{/owner}{/repo}",
307+ "subscriptions_url": "https://api.github.com/users/philipcmonktest/subscriptions",
308+ "type": "User",
309+ "url": "https://api.github.com/users/philipcmonktest"
310+ },
311+ "body": "Yup, that's it. i mean, maybe it's a bit longer than that.\r\n\r\nBut you get the point, right?\r\n\r\nCode `is` cool!",
312+ "closed_at": null,
313+ "closed_by": null,
314+ "comments": 0,
315+ "comments_url": "https://api.github.com/repos/philipcmonktest/testing/issues/7/comments",
316+ "created_at": "2016-03-24T22:27:33Z",
317+ "events_url": "https://api.github.com/repos/philipcmonktest/testing/issues/7/events",
318+ "html_url": "https://github.com/philipcmonktest/testing/issues/7",
319+ "id": 143377108,
320+ "labels": [
321+ {
322+ "color": "ffffff",
323+ "name": "wontfix",
324+ "url": "https://api.github.com/repos/philipcmonktest/testing/labels/wontfix"
325+ }
326+ ],
327+ "labels_url": "https://api.github.com/repos/philipcmonktest/testing/issues/7/labels{/name}",
328+ "locked": false,
329+ "milestone": null,
330+ "number": 7,
331+ "repository_url": "https://api.github.com/repos/philipcmonktest/testing",
332+ "state": "open",
333+ "title": "big news!",
334+ "updated_at": "2016-03-24T22:27:33Z",
335+ "url": "https://api.github.com/repos/philipcmonktest/testing/issues/7",
336+ "user": {
337+ "avatar_url": "https://avatars.githubusercontent.com/u/16787461?v=3",
338+ "events_url": "https://api.github.com/users/philipcmonktest/events{/privacy}",
339+ "followers_url": "https://api.github.com/users/philipcmonktest/followers",
340+ "following_url": "https://api.github.com/users/philipcmonktest/following{/other_user}",
341+ "gists_url": "https://api.github.com/users/philipcmonktest/gists{/gist_id}",
342+ "gravatar_id": "",
343+ "html_url": "https://github.com/philipcmonktest",
344+ "id": 16787461,
345+ "login": "philipcmonktest",
346+ "organizations_url": "https://api.github.com/users/philipcmonktest/orgs",
347+ "received_events_url": "https://api.github.com/users/philipcmonktest/received_events",
348+ "repos_url": "https://api.github.com/users/philipcmonktest/repos",
349+ "site_admin": false,
350+ "starred_url": "https://api.github.com/users/philipcmonktest/starred{/owner}{/repo}",
351+ "subscriptions_url": "https://api.github.com/users/philipcmonktest/subscriptions",
352+ "type": "User",
353+ "url": "https://api.github.com/users/philipcmonktest"
354+ }
355+}
356+```
docs/using/web.md+11−2
@@ -25,8 +25,10 @@ We ship `tree` as compiled JavaScript on your Urbit, but the source lives in its
2525
2626Your Urbit runs a web server and can be found at either `http://localhost:8080/` (or `8081` if you're running other processes that might be occupying `8080`, you can determine which port your urbit is on by looking at your boot sequence — it's specified there), or `http://your-urbit.urbit.org/`.
2727
28+<span class="red">
2829(Make sure you have a desk mounted to unix, as covered in the
2930[filesystem walkthrough](/docs/using/filesystem)).
31+</span>
3032
3133To switch the desk you're serving from:
3234
@@ -38,7 +40,10 @@ To host a file on the web try putting the following in `/home/web/test.md` (from
3840
3941 This is a simple markdown file.
4042
41−Create the directory `/home/web/test/` and add two more markdown files in it.
43+Create the directory `/home/web/test/` and add two more markdown files in it.
44+
45+NOTE: Due to a bug in Urbit you may have to create the directory and the file in it in rapid
46+succession using something like `mkdir home/web/test && touch home/web/test/first.md`.
4247
4348Now modify `/home/web/test.md` to list the children using the `<list/>` JSX:
4449
@@ -47,6 +52,10 @@ Now modify `/home/web/test.md` to list the children using the `<list/>` JSX:
4752 This is a simple markdown file.
4853
4954 <div><list /></div>
55+
56+To view your file rendered using tree:
57+
58+ http://localhost:8080/test/
5059
5160To view your file as raw `md`:
5261
@@ -56,7 +65,7 @@ To view your file as raw `html`:
5665
5766 http://localhost:8080/test.html
5867
59−You may have noticed that we just created both `test.md` and `test/`. In Urbit, there is no distinction between a directory and a file. So, if you're adding files directly from unix, simply `mkdir test` and Urbit will treat the file and directory as the same entity.
68+You may have noticed that we just created both `test.md` and `test/`. In Urbit, there is no distinction between a directory and a file. So, if you're adding files directly from unix, simply `mkdir test` and Urbit will treat the file and directory as the same entity.
6069
6170You can use this feature to change your homepage at `your-urbit.urbit.org` with the page `/home/web.md`, where `home` is the current mounted desk. By default, `web.md` will display some info about your urbit, but you can customize it to your heart's content.
6271