on master help sign in
Merge branch 'master' of http://github.com/urbit/docs
aa78b7cC. Guy Yarvin
docs.md+38−12
@@ -1,7 +1,7 @@
1---
1---
2anchor: none
2anchor: none
3footer: true
3footer: true
4−title: Develop
4+title: Documentation
5sort: 4
5sort: 4
6---
6---
7
7
@@ -10,21 +10,47 @@ sort: 4
10 <h1 class="blue i-b">Urbit docs</h1>
10 <h1 class="blue i-b">Urbit docs</h1>
11</div>
11</div>
12
12
13−Go to the [technical overview](about/overview) for a high-level
13+<div class="col-md-12 head">
14−architecture description. To install and run Urbit, read forward from the
15−[installation guide](using/install).
16
14
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+
17−To begin developing for Urbit, start by learning Hoon [syntax](hoon/syntax),
20+To begin developing for Urbit, start by learning Hoon [syntax](hoon/syntax),
18−then walk through the [Arvo tutorials](arvo). The examples and exercises
21+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.
22+in Arvo will teach you to build high-level programs and interact with the network.
20
23
21Dig into the mechanics of Urbit with [Core Hoon](hoon). Refer back
24Dig 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">
23
32
24−Registered academics are required to start with the [Nock definition](nock/definition)
33+<b>Source on GitHub</b>
25−and work upward from there.
34+<ul>
26−<br/>
35+<li><a href="https://github.com/urbit/urbit">Main repo</a></li>
27−<br/>
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>
28
54
29<div class="sections">
55<div class="sections">
30 <kids grid="true"></kids>
56 <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 @@
1---
1---
2navhome: /docs
2navhome: /docs
3−sort: 4
3+sort: 3
4---
4---
5
5
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.
7
11
8<list/>
12<list/>
docs/arvo/basic.md+28−21
@@ -2,20 +2,15 @@
2navhome: /docs
2navhome: /docs
3sort: 1
3sort: 1
4next: true
4next: true
5−title: Hoon refresher / crash course
5+title: Basic Hoon
6---
6---
7
7
8Basic Hoon
8Basic Hoon
9==========
9==========
10
10
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−
16Our goal is to get you programming interesting and useful things as soon
11Our goal is to get you programming interesting and useful things as soon
17as possible. To get there, we have to quickly cover some of the
12as 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
19programs: the first [Project Euler](https://projecteuler.net/) problem
14programs: the first [Project Euler](https://projecteuler.net/) problem
20and [fizzbuzz](https://en.wikipedia.org/wiki/Fizz_buzz).
15and [fizzbuzz](https://en.wikipedia.org/wiki/Fizz_buzz).
21
16
@@ -23,14 +18,24 @@ To run this code, you'll need an urbit, and will have to copy the
23[examples repo](https://github.com/urbit/examples) into it.
18[examples repo](https://github.com/urbit/examples) into it.
24
19
25If you haven't installed urbit yet, check out the [installation
20If you haven't installed urbit yet, check out the [installation
26−instructions](/docs/user/install). Once urbit is installed, take a look
21+instructions](/docs/using/install). Once urbit is installed, take a look
27−at the [basic operation](/docs/user/basic) of your urbit.
22+at the [basic operation](/docs/using/admin) of your urbit.
28
23
29If you haven't copied in the examples repo, running the following
24If you haven't copied in the examples repo, running the following
30commands from your urbit directory should do the trick:
25commands from your urbit directory should do the trick:
31
26
32−`$ cp -r {wherever-you've-pulled-to}/examples/gall/*/ 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/
33−`$ cp -r {wherever-you've-pulled-to}/examples/dojo/*/ arvo/`
37+$ cp -r {urbit-examples}/dojo/*/*/ {your-pier}/home/
38+```
34
39
35Run an example to ensure it worked:
40Run an example to ensure it worked:
36
41
@@ -157,13 +162,13 @@ Instead of:
157
162
158You can write:
163You can write:
159
164
160− if(=(1 2) 'this is true' 'this is false')
165+ :if(=(1 2) 'this is true' 'this is false')
161 'this is false'
166 'this is false'
162
167
163### Lines 12-34
168### Lines 12-34
164
169
165Now let's quickly walk through this code line-by-line. Lines 12-34 are
170Now 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
167fundamental datatype in Hoon, similar to a struct, class, or object. A
172fundamental datatype in Hoon, similar to a struct, class, or object. A
168core is just a map of names to any kind of code, whether it be functions
173core is just a map of names to any kind of code, whether it be functions
169or data. Each element in this map begins with a `++` followed by the
174or 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.
182 (add (five a) (three a))
187 (add (five a) (three a))
183 --
188 --
184
189
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
186takes two children:
191takes two children:
187
192
1881. A set of argument(s). In this case our argument set only contains
1931. A set of argument(s). In this case our argument set only contains
@@ -207,14 +212,14 @@ takes two children:
207As above, `++three` takes an integer argument, `a`, and then executes
212As above, `++three` takes an integer argument, `a`, and then executes
208the remainder of the code with `a` set to the actual arguments.
213the remainder of the code with `a` set to the actual arguments.
209
214
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
211(in other words, it declares a variable `b`) and executes the remainder
216(in other words, it declares a variable `b`) and executes the remainder
212of the code. However, `b` is not an argument; `=|` sets `b` to the
217of the code. However, `b` is not an argument; `=|` sets `b` to the
213default value of whatever type it is declared as. Since the default
218default value of whatever type it is declared as. Since the default
214value of an atom is `0`, b is set to `0`.
219value of an atom is `0`, b is set to `0`.
215
220
216−> To produce the default value of any given type, use `$*` ('buctar')
221+> To produce the default value of any given type, use `*` ('tar')
217−> followed by the type. Alternatively, use the irregular form `*`.
222+> followed by the type. This operaction is called *bunt*.
218>
223>
219> > *@ :: produce the default value of atom @
224> > *@ :: produce the default value of atom @
220> 0
225> 0
@@ -225,10 +230,10 @@ value of an atom is `0`, b is set to `0`.
225So now we have two variables: `a` is set to our input, and `b` is
230So now we have two variables: `a` is set to our input, and `b` is
226initialized to `0`.
231initialized to `0`.
227
232
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
229point. More on this later.
234point. More on this later.
230
235
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
232the code to an unsigned integer, `@u`.
237the code to an unsigned integer, `@u`.
233
238
234In pseudocode, the last three lines read like this: if `a` is less than
239In 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.
246
251
247**Exercises**:
252**Exercises**:
248
253
249−Tweak your code to complete the following excercises.
254+Tweak your code to complete the following exercises.
250
255
251There are a few runes and some syntax that we have yet to cover that you
256There 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
253our cheatsheat at the bottom.
258our cheatsheat at the bottom.
254
259
2551. Read and understand `++five` line by line.
2601. Read and understand `++five` line by line.
@@ -272,6 +277,8 @@ our cheatsheat at the bottom.
272 =(a b) test equality
277 =(a b) test equality
273 (function args ...) call function with args
278 (function args ...) call function with args
274
279
280+Lookup each of these expressions (and all others!) in the [Twig Expressions](../../hoon/twig/) definition.
281+
275### New material
282### New material
276
283
2771. There are two syntaxes for writing Hoon: tallform and wideform.
2841. 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
15`|merge`, there are no marks in sight.
15`|merge`, there are no marks in sight.
16
16
17We've used generators before, back in [Basic
17We'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
19to produce values -- we didn't pipe their results into apps. In
19to produce values -- we didn't pipe their results into apps. In
20the dojo cast, the role of a generator is to take a list of
20the dojo cast, the role of a generator is to take a list of
21arguments and produce a value, which is often, though not always,
21arguments and produce a value, which is often, though not always,
@@ -65,90 +65,33 @@ optionally specify the message as well.
65We'll need a new mark for our arguments. Let's call it
65We'll need a new mark for our arguments. Let's call it
66`examples-ping-message`.
66`examples-ping-message`.
67
67
68−<blockquote class="blockquote">
69−For app-specific marks, it's good style to prefix the name of
68+> 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
69+> the mark with the name of the app. Since many apps have
71−several such marks, subdirectories in `/mar` are rendered as
70+> several such marks, subdirectories in `/mar` are rendered as
72−`-`, so that `ping-message` is written in
71+> `-`, so that `ping-message` is written in
73−(/mar/examples/ping/message.hoon).
72+> (/mar/examples/ping/message.hoon).
74−</blockquote>
75
73
76```
74```
77−:: Up-ness monitor. Accepts atom url, 'on', or 'off'
78::
75::
79−:::: /hoon/up/examples/app
76+:::: /hoon/message/ping/examples/app
80 ::
77 ::
81/? 314
78/? 314
79+|_ {to/@p message/@t}
80+++ grab
82−|%
81+ |%
83−++ move {bone card}
82+ ++ noun {@p @t}
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−--
83+ --
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 _`. ::
142--
84--
143```
85```
144
86
145The app can easily be modified to use this (`/app/examples/ping.hoon`):
87The app can easily be modified to use this (`/app/examples/ping.hoon`):
146
88
147```
89```
90+:: Allows one ship to ping another with a string of text
148::
91::
149:::: /hoon/ping/examples/app
92:::: /hoon/ping/examples/app
150 ::
93 ::
151−/? 151
94+/? 314
152|%
95|%
153 ++ move {bone term wire *}
96 ++ move {bone term wire *}
154--
97--
@@ -174,8 +117,6 @@ The app can easily be modified to use this (`/app/examples/ping.hoon`):
174::
117::
175++ coup |=(* `+>)
118++ coup |=(* `+>)
176--
119--
177−
178−
179```
120```
180
121
181Now we can run this with:
122Now we can run this with:
@@ -197,7 +138,7 @@ to `:examples-ping`, let's put it in `/gen/examples/ping/send.hoon`:
197
138
198```
139```
199:- %say
140:- %say
200−|= {^ {{to/@p message/?($~ {text/@t $~})} $~}
141+|= {^ {to/@p message/?($~ {text/@t $~})} $~}
201[%examples-ping-message to ?~(message 'howdy' text.message)]
142[%examples-ping-message to ?~(message 'howdy' text.message)]
202```
143```
203
144
@@ -214,23 +155,21 @@ text and null.
214Secondly, `?~(a b c)` is a rune which means "if the `a` is null,
155Secondly, `?~(a b c)` is a rune which means "if the `a` is null,
215do `b`, else `c`". It is roughly equivalent to `?:(=(~ a) b c)`.
156do `b`, else `c`". It is roughly equivalent to `?:(=(~ a) b c)`.
216
157
217−<blockquote class="blockquote">
218−`?~(a b c)` is actually equivalent to `?:=(?=(~ a) b c)`,
158+> `?~(a b c)` is actually equivalent to `?:=(?=(~ a) b c)`,
219−which, although identical at run time, is subtly different at
159+> which, although identical at run time, is subtly different at
220−compile time. Specifically, using `?=` rather than `=` means
160+> compile time. Specifically, using `?=` rather than `=` means
221−that we're checking whether `a` is in the *type* of `~`, and so
161+> 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
162+> 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
163+> `c` case `a` is not null. Since `=` is purely a runtime value
224−check with no type implications, the compiler doesn't gain any
164+> check with no type implications, the compiler doesn't gain any
225−information.
165+> information.
226−
166+>
227−At any rate, this is the reason why we can refer to
167+> At any rate, this is the reason why we can refer to
228−`text.message` in the `c` clause. The compiler knows that
168+> `text.message` in the `c` clause. The compiler knows that
229−`message` is not null, so it must have `text` within it. If
169+> `message` is not null, so it must have `text` within it. If
230−you used `?:(=(~ message) 'howdy' text.message)` the compiler
170+> you used `?:(=(~ message) 'howdy' text.message)` the compiler
231−would complain that it doesn't know whether `message` has
171+> would complain that it doesn't know whether `message` has
232−`text` within it.
172+> `text` within it.
233−</blockquote>
234
173
235This is run as follows:
174This is run as follows:
236
175
docs/arvo/http.md+19−29
@@ -77,12 +77,10 @@ line, though.
77Firstly, there's two kinds of cards we're sending to arvo. A
77Firstly, there's two kinds of cards we're sending to arvo. A
78`%them` card makes an HTTP requrest out of a unit `hiss`.
78`%them` card makes an HTTP requrest out of a unit `hiss`.
79
79
80−<blockquote class="blockquote">
81−Recall that `++unit` means "maybe". Formally, "`(unit a)` is
80+> Recall that `++unit` means "maybe". Formally, "`(unit a)` is
82−either null or a pair of null and a value in `a`". Also recall
81+> 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
82+> 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 `?~`).
83+> verify that the unit is not null (for example with `?~`).
85−</blockquote>
86
84
87A `hiss` (all of the following terms are defined in `zuse`) is a
85A `hiss` (all of the following terms are defined in `zuse`) is a
88pair of a `purl` and a `moth`. A `purl` is a parsed url
86pair 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
96representing the body. If it's null, then no body is sent (as in
94representing the body. If it's null, then no body is sent (as in
97this case).
95this case).
98
96
99−<blockquote class="blockquote">
100−An octect stream is a pair of the length in bytes of the data
97+> 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
98+> plus the data itself. You can use `++taco` takes text and
102−turns it into an octet strem.
99+> turns it into an octet strem.
103−</blockquote>
104
100
105When you send this request, you can expect a `%thou` with the
101When you send this request, you can expect a `%thou` with the
106response, which we handle later on in `++thou-request`.
102response, which we handle later on in `++thou-request`.
@@ -108,11 +104,9 @@ response, which we handle later on in `++thou-request`.
108For `%wait`, you just pass a [`@da`]() (absolute date), and arvo will
104For `%wait`, you just pass a [`@da`]() (absolute date), and arvo will
109produce a `%wake` when the time comes.
105produce a `%wake` when the time comes.
110
106
111−<blockquote class="blockquote">
112−A timer is guaranteed to not be triggered before the given
107+> A timer is guaranteed to not be triggered before the given
113−time, but it's currently impossible to guarantee the timer will be
108+> time, but it's currently impossible to guarantee the timer will be
114−triggered at exactly the requested time.
109+> triggered at exactly the requested time.
115−</blockquote>
116
110
117Let's take a look at our state:
111Let's take a look at our state:
118
112
@@ -133,11 +127,9 @@ of `value`, but make the default value be `value`". Thus, our
133type is still a boolean, just like `?`, but the default value is
127type is still a boolean, just like `?`, but the default value is
134`|` (false).
128`|` (false).
135
129
136−<blockquote class="blockquote">
137−This is the same `_` used in `_+>.$`, which means "the same
130+> This is the same `_` used in `_+>.$`, which means "the same
138−type as the value "+>.$". In other words, the same type as our
131+> type as the value "+>.$". In other words, the same type as our
139−current context and state.
132+> current context and state.
140−</blockquote>
141
133
142Let's take a look at `++poke-cord`. When we're poked with a
134Let's take a look at `++poke-cord`. When we're poked with a
143cord, we first check whether it's `'off'`. If so, we set `on` to
135cord, 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
151target))` is the parsed url, `%get` is the HTTP method, `~`
143target))` is the parsed url, `%get` is the HTTP method, `~`
152means no extra headers, and another `~` means no body.
144means no extra headers, and another `~` means no body.
153
145
154−<blockquote class="blockquote">
155−Note the `~` at the end of the move. This is a convenient
146+> 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
147+> 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 ~]`,
148+> 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]`.
149+> `[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
150+> These may be mixed and matched to create various convoluted
160−structures and emojis.
151+> structures and emojis.
161−</blockquote>
162
152
163If the argument is neither 'off' nor 'on', then we assume it's an
153If the argument is neither 'off' nor 'on', then we assume it's an
164actual url, so we save it in `target`.
154actual 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
96
96
97A `%js` `pest` is `resolve`d as a `text/javascript` success `%this`.
97A `%js` `pest` is `resolve`d as a `text/javascript` success `%this`.
98
98
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
100`/~/on/{window.urb.poll}.json`, bringing us back to `%poll:process`.
100`/~/on/{window.urb.poll}.json`, bringing us back to `%poll:process`.
101
101
102In the case of a non-`%js` `/~/on/`, `%poll:process-parsed` turns into a
102In 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
167ensuring it is recorded for the session. The request parsed with `++need-body`
167ensuring it is recorded for the session. The request parsed with `++need-body`
168to a `[%auth %try {password}]` perk. `%get:process-auth` checks it against
168to a `[%auth %try {password}]` perk. `%get:process-auth` checks it against
169`++load-secret`, upon success updates the session with `++logon:ya`, and
169`++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
171this, the page is refreshed to retry the original request.
171this, the page is refreshed to retry the original request.
172
172
173## Post-authentication: app communication. [#auth-ok]
173## Post-authentication: app communication. [#auth-ok]
@@ -212,7 +212,7 @@ Upon receipt, the client realizes the long-poll isn't actually running, so that
212is started using `urb.poll`. At `/~/of/{ixor}`, perk
212is started using `urb.poll`. At `/~/of/{ixor}`, perk
213`[%view ixor ~ {sequence-number}]`, it is `process`ed by `++poll:ix` (the cyst
213`[%view ixor ~ {sequence-number}]`, it is `process`ed by `++poll:ix` (the cyst
214is retrieved by `++ire-ix` form global state, using the perk `ixor`): the
214is 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
216`++give-even`. After deleting the previous message in the queue and invoking
216`++give-even`. After deleting the previous message in the queue and invoking
217`++pass-took` to signal `%gall` of this occurrence, the data is annotated with
217`++pass-took` to signal `%gall` of this occurrence, the data is annotated with
218the source app+path `++subs-to-json`, and returned to the polling duct.
218the source app+path `++subs-to-json`, and returned to the polling duct.
docs/arvo/marks.md+5−3
@@ -5,6 +5,8 @@ sort: 6
5title: Marks
5title: Marks
6---
6---
7
7
8+# Marks
9+
8We've used predefined marks already, but we haven't yet created
10We've used predefined marks already, but we haven't yet created
9our own marks. Let's write a sample mark of our own, then chain
11our own marks. Let's write a sample mark of our own, then chain
10it together with some preexisting ones to have fun with type
12it 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:
28--
30--
29```
31```
30
32
31−Let's go through this line by line. `/? 314` is the required
33+`/? 314` is the required
32version number, just like in apps. After that everything's in a
34version number, just like in apps. After that everything's in a
33`|_`, which is a `|%` core, but with input arguments. In our
35`|_`, which is a `|%` core, but with input arguments. In our
34case, the argument is the marked data.
36case, the argument is the marked data.
35
37
36There are three possible top-level arms in the `|_` core,
38There are three possible top-level arms in the `|_` core,
37−`++grab`, `++grow`, and `++grad`. `++grad` is used for revision
39+`++grab`, `++grow`, and `++grad` (which is used for revision
38−controlv (it contains diff/patch logic), and is covered elsewhere. `++grab` specifies
40+control, covered elsewhere). `++grab` specifies
39functions to convert from another mark to the current mark.
41functions to convert from another mark to the current mark.
40`++grow` specifies how to convert from the current mark to
42`++grow` specifies how to convert from the current mark to
41another one.
43another 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
34the app, then you can poke it from the command line with the following
34the app, then you can poke it from the command line with the following
35commands:
35commands:
36
36
37− ~fintud-macrep:dojo> |start %echo
37+ ~fintud-macrep:dojo> |start %examples-echo
38+ 'prep'
38 >=
39 >=
39 ~fintud-macrep:dojo> :examples-echo 5
40 ~fintud-macrep:dojo> :examples-echo 5
40 [%argument 5]
41 [%argument 5]
@@ -57,7 +58,7 @@ do that is to poke it from the command line, which we we did with
57`:echo 5` (`:[app-name] [argument(s)]`).
58`:echo 5` (`:[app-name] [argument(s)]`).
58
59
59In this case, `++poke-noun` takes an argument `arg` and prints it out
60In 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
61rune that formally "does nothing", but the interpreter detects it and
62rune that formally "does nothing", but the interpreter detects it and
62printfs the first child, before executing the second as if the first
63printfs the first child, before executing the second as if the first
63didn't exist. This is a slightly hacky way of printing to the console,
64didn'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.
86
87
87 /? 314
88 /? 314
88 !:
89 !:
89− |_ {bowl state=~}
90+ |_ {bowl state/$~}
90 ::
91 ::
91 ++ poke-atom
92 ++ poke-atom
92 |= arg/@
93 |= arg/@
@@ -149,7 +150,7 @@ Let's write our first network message! Here's `/app/examples/pong.hoon`:
149 ++ move {bone term wire *}
150 ++ move {bone term wire *}
150 --
151 --
151 !:
152 !:
152− |_ {bowl state=$~}
153+ |_ {bowl state/$~}
153 ::
154 ::
154 ++ poke-urbit
155 ++ poke-urbit
155 |= to/@p
156 |= to/@p
@@ -169,7 +170,7 @@ Run it with these commands:
169
170
170 ~fintud-macrep:dojo> |start %examples-pong
171 ~fintud-macrep:dojo> |start %examples-pong
171 >=
172 >=
172− ~fintud-macrep:dojo> :pong &examples-urbit ~sampel-sipnym
173+ ~fintud-macrep:dojo> :examples-pong &urbit ~sampel-sipnym
173 >=
174 >=
174
175
175Replace `~sampel-sipnym` with another urbit. The easiest thing to do is
176Replace `~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.
220If you look up `++bone` in `hoon.hoon`, you'll see that it's a number
221If you look up `++bone` in `hoon.hoon`, you'll see that it's a number
221(`@ud`), and that it's an opaque reference to a duct. `++duct` in
222(`@ud`), and that it's an opaque reference to a duct. `++duct` in
222hoon.hoon is a list of `wire`s, where `++wire` is an alias for `++path`.
223hoon.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
224list of paths, and a bone is an opaque reference to it (in the same way
225list of paths, and a bone is an opaque reference to it (in the same way
225that a Unix file descriptor is an opaque reference to a file structure).
226that a Unix file descriptor is an opaque reference to a file structure).
226Thus, to truly understand bones, we must understand ducts.
227Thus, to truly understand bones, we must understand ducts.
@@ -234,7 +235,7 @@ Sometimes, the module can immediately handle the event and produce any
234necessary results. For example, when we poked the `++poke-atom` arm
235necessary results. For example, when we poked the `++poke-atom` arm
235above, we poked %gall, our application server, which was able to respond
236above, we poked %gall, our application server, which was able to respond
236to our poke directly. When the module cannot service the request itself,
237to 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
238%gall module) to do a specified action, and produces the result from
239%gall module) to do a specified action, and produces the result from
239that.
240that.
240
241
@@ -283,7 +284,7 @@ The move ends with `*` (that is, any noun) since each type of move takes
283different data. In our case, a `%poke` move takes a target (urbit and
284different data. In our case, a `%poke` move takes a target (urbit and
284app) and marked data, then pokes the arm of the corresponding mark on
285app) and marked data, then pokes the arm of the corresponding mark on
285that app on that urbit with that data. `[to-urbit-address %pong]` is the
286that 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.
287
288
288When arvo receives a `%poke` move, it calls the appropriate `++poke`.
289When arvo receives a `%poke` move, it calls the appropriate `++poke`.
289The same mechanism is used for sending messages between apps on the same
290The 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.
304
305
305- Write two apps, `even` and `odd`. When you pass an atom to `even`,
306- Write two apps, `even` and `odd`. When you pass an atom to `even`,
306 check whether it's even. If so, divide it by two and recurse;
307 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
308 whether it's equal to one. If so, terminate, printing "%success".
309 whether it's equal to one. If so, terminate, printing "%success".
309 Otherwise, check whether it's odd. If so, multiply it by three, add
310 Otherwise, check whether it's odd. If so, multiply it by three, add
310 one, and recurse; otherwise, poke `even` with it. When either app
311 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.
312 the end, you should be able to watch Collatz's conjecture play out
313 the end, you should be able to watch Collatz's conjecture play out
313 between the two apps. Sample output:
314 between the two apps. Sample output:
314
315
315−<!-- -->
316+```
316−
317− ~fintud-macrep:dojo> :even &atom 18
317+~fintud-macrep:dojo> :even &atom 18
318− [%even 18]
318+[%even 18]
319− [%odd 9]
319+[%odd 9]
320− [%even 28]
320+[%even 28]
321− [%even 14]
321+[%even 14]
322− [%odd 7]
322+[%odd 7]
323− [%even 22]
323+[%even 22]
324− [%odd 11]
324+[%odd 11]
325− [%even 34]
325+[%even 34]
326− [%odd 17]
326+[%odd 17]
327− [%even 52]
327+[%even 52]
328− [%even 26]
328+[%even 26]
329− [%odd 13]
329+[%odd 13]
330− [%even 40]
330+[%even 40]
331− [%even 20]
331+[%even 20]
332− [%even 10]
332+[%even 10]
333− [%odd 5]
333+[%odd 5]
334− [%even 16]
334+[%even 16]
335− [%even 8]
335+[%even 8]
336− [%even 4]
336+[%even 4]
337− [%even 2]
337+[%even 2]
338− %success
338+%success
339+```
339
340
340- Put `even` and `odd` on two separate urbits and pass the messages
341- Put `even` and `odd` on two separate urbits and pass the messages
341 over the network. Post a link to a working solution in :talk to
342 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
20 ++ poke-atom
20 ++ poke-atom
21 |= arg/@
21 |= arg/@
22 ^- {(list) _+>.$}
22 ^- {(list) _+>.$}
23− ?: =(arg 0)
24− [~ +>.$(state 0)]
25 ~& [%so-far (add state arg)]
23 ~& [%so-far (add state arg)]
26 [~ +>.$(state (add state arg))]
24 [~ +>.$(state (add state arg))]
27 --
25 --
@@ -99,6 +97,13 @@ ever go through the hassle of having to set up and write to a database.
99- Write an app that prints out the previous value you poked it with.
97- Write an app that prints out the previous value you poked it with.
100 Sample output:
98 Sample output:
101
99
100+```
102−\`\`\` \~fintud-macrep:dojo\> :examples-last 7 [%last 0] \>=
101+~fintud-macrep:dojo> :examples-last 7
102+[%last 0]
103+>=
103−\~fintud-macrep:dojo\> :examples-last [1 2 3][%last 7] \>=
104+~fintud-macrep:dojo> :examples-last [1 2 3]
105+[%last 7]
106+>=
104−\~fintud-macrep:dojo\> :examples-last 'howdy' [%last [1 2 3]]
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.
15 =< (sum [1.000 2.000])
15 =< (sum [1.000 2.000])
16
16
17The first rune, `:-` (colhep, aka
17The 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
19that will be our program. The first element, `%say`, tells the
19that will be our program. The first element, `%say`, tells the
20interpreter what to produce--in this case a value.
20interpreter what to produce--in this case a value.
21
21
@@ -28,7 +28,7 @@ Similarly, the rest of the program (which we construct with another
28producing a value of type `noun`, and the code that we run to actually
28producing a value of type `noun`, and the code that we run to actually
29produce our value of the type `noun`.
29produce our value of the type `noun`.
30
30
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
32children. The second child is the context against which we run the first
32children. The second child is the context against which we run the first
33child. So in this case, we are running the expression
33child. So in this case, we are running the expression
34`(sum [1.000 2.000])` against everything contained within the `|%`. In
34`(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
36"subject".
36"subject".
37
37
38 ::::::::::::::::::::::::::::::
38 ::::::::::::::::::::::::::::::
39− =< (sum [1.000 2.000]) :: formula
39+ =< (sum [1.000 2.000]) :: formula
40 ::::::::::::::::::::::::::::::
40 ::::::::::::::::::::::::::::::
41 |% ::
41 |% ::
42 ++ three ::
42 ++ three ::
@@ -58,8 +58,8 @@ Hoon, we call the code executed the "formula" and its context the
58 (add b $(b (add b 5))) ::
58 (add b $(b (add b 5))) ::
59 ::
59 ::
60 ++ sum ::
60 ++ sum ::
61− |= a/@u ::
61+ |= {a/@u b/@u} ::
62− (add (five a) (three a)) ::
62+ (add (five a) (three b)) ::
63 -- ::
63 -- ::
64 ::::::::::::::::::::::::::::::
64 ::::::::::::::::::::::::::::::
65
65
@@ -72,7 +72,7 @@ allows a sort of reification of the context through continutations, and
72some may see a parallel to Forth's stack, but Hoon takes takes the
72some may see a parallel to Forth's stack, but Hoon takes takes the
73concept one step further.
73concept one step further.
74
74
75−Our starting subject is the [standard library](/hoon/library), which is
75+Our starting subject is the [standard library](../../hoon/library), which is
76defined in `/arvo/hoon.hoon` and `/arvo/zuse.hoon`. This is where
76defined in `/arvo/hoon.hoon` and `/arvo/zuse.hoon`. This is where
77functions like `add` are defined. When we define a core with `|%`, we
77functions like `add` are defined. When we define a core with `|%`, we
78don't throw away the subject (i.e. the standard library); rather, we
78don't throw away the subject (i.e. the standard library); rather, we
@@ -93,7 +93,7 @@ Cheatsheet:
93
93
94- To pass arguments from the command line to a program, you replace
94- To pass arguments from the command line to a program, you replace
95 the `*` in the first line of the boiler plate to
95 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
97 argument you're expecting. Then `+euler1 a` from the dojo sets `arg`
97 argument you're expecting. Then `+euler1 a` from the dojo sets `arg`
98 to `a`.
98 to `a`.
99- The empty list is `~`
99- The empty list is `~`
docs/arvo/subscriptions.md+11−11
@@ -59,7 +59,7 @@ And secondly, `:examples-sink`:
59 ++ diff-noun
59 ++ diff-noun
60 |= {wir/wire arg/*}
60 |= {wir/wire arg/*}
61 ^- {(list move) _+>.$}
61 ^- {(list move) _+>.$}
62− ~& [%recieved-data arg]
62+ ~& [%received-data arg]
63 [~ +>.$]
63 [~ +>.$]
64 ++ reap
64 ++ reap
65 |= {wir/wire error/(unit tang)}
65 |= {wir/wire error/(unit tang)}
@@ -75,42 +75,42 @@ Cheat sheet:
75
75
76- `&` (pam) can either be the boolean true (as can `%.y`, `0`), or
76- `&` (pam) can either be the boolean true (as can `%.y`, `0`), or
77 the irregular wide form of the `?&`
77 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
79 logical `AND` on its two children.
79 logical `AND` on its two children.
80
80
81- Similar to `&`,`|` is either the boolean false (along with `%.n` and
81- Similar to `&`,`|` is either the boolean false (along with `%.n` and
82 `1`), or the irregular short for of `?|`
82 `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`
84 on its two children.
84 on its two children.
85
85
86- `!` is the irregular wide form of `?!`
86- `!` 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
88 `NOT` on its child.
88 `NOT` on its child.
89
89
90−- `?~` ([wutsig](/hoon/twig/wut-test/sig-ifno/)) is basically an
90+- `?~` ([wutsig](../../hoon/twig/wut-test/sig-ifno/)) is basically an
91 if-then-else that checks whether condition `p` is `~` (null). `?~`
91 if-then-else that checks whether condition `p` is `~` (null). `?~`
92 is slightly different from `?:(~ %tru %fal)` in that `?~` reduces to
92 is slightly different from `?:(~ %tru %fal)` in that `?~` reduces to
93 `?:($=(%type value) %tru %false)`. `$=`
93 `?:($=(%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
95 of type `p`.
95 of type `p`.
96 <!--One thing to watch out for in hoon: if you do `?~`, it
96 <!--One thing to watch out for in hoon: if you do `?~`, it
97 affects the type of the conditional value: XXexample-->
97 affects the type of the conditional value: XXexample-->
98
98
99−- `:_` ([colcab](/hoon/twig/col-cell/cab-scon/)) is inverted `:-`: it
99+- `:_` ([colcab](../../hoon/twig/col-cell/cab-scon/)) is inverted `:-`: it
100 accepts `p` and `q`, and produces `[q p]`.
100 accepts `p` and `q`, and produces `[q p]`.
101
101
102- `++bowl` is the type of the system state within our app. For
102- `++bowl` is the type of the system state within our app. For
103 example, it includes things like `our`, the name of the host urbit,
103 example, it includes things like `our`, the name of the host urbit,
104 and `now`, the current time.
104 and `now`, the current time.
105
105
106−- `$%` ([buccen](/hoon/twig/buc-mold/cen-book/)) is a type
106+- `$%` ([buccen](../../hoon/twig/buc-mold/cen-book/)) is a type
107 constructor: it defines a new type, composed of `n` types that it is
107 constructor: it defines a new type, composed of `n` types that it is
108 passed. For example `$% @ * ^ ==` is the type of either `@`,
108 passed. For example `$% @ * ^ ==` is the type of either `@`,
109 `*`, or a cell `^`. <!--XX this is a union, right?-->
109 `*`, or a cell `^`. <!--XX this is a union, right?-->
110
110
111- You may have noticed the separate `|%`
111- You may have noticed the separate `|%`
112− ([barcen](/hoon/twig/bar-core/cen-core/)) above the application core
112+ ([barcen](../../hoon/twig/bar-core/cen-core/)) above the application core
113− `|_` ([barcab](/hoon/twig/bar-core/cab-door/). We usually put our
113+ `|_` ([barcab](../../hoon/twig/bar-core/cab-door/). We usually put our
114 types in another core on top of the application core. We can access
114 types in another core on top of the application core. We can access
115 these type from our `|_` because in `hoon.hoon` files, all cores are
115 these type from our `|_` because in `hoon.hoon` files, all cores are
116 called against each other. (The shorthand for 'called' is `=>`.)
116 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
180subscribed, and which path they subscribed on. If you want to
180subscribed, and which path they subscribed on. If you want to
181communicate with your subscribers, send them messages along their bone.
181communicate with your subscribers, send them messages along their bone.
182
182
183−`++poke-noun` "spams" the given arguement to all our subscribers.
183+`++poke-noun` "spams" the given argument to all our subscribers.
184There's a few things we haven't seen before. Firstly, `:_(a b)` is the
184There's a few things we haven't seen before. Firstly, `:_(a b)` is the
185same as `[b a]`. It's just a convenient way of formatting things when
185same as `[b a]`. It's just a convenient way of formatting things when
186the first thing in a cell is much more complicated than the second.
186the 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
72result was 'click' with `?>`, which asserts that its first child
72result was 'click' with `?>`, which asserts that its first child
73is true.
73is true.
74
74
75−<blockquote class="blockquote">
76−Note the argument to `++json`is `jon/^json`. Why `^json`?
75+> Note the argument to `++json`is `jon/^json`. Why `^json`?
77−`++json` shadows the type definition, so if we want to refer to
76+> `++json` shadows the type definition, so if we want to refer to
78−the type, we have to prepend a `^`. This extends to multiple
77+> the type, we have to prepend a `^`. This extends to multiple
79−levels: `^^^foo` means the fourth most innermost instance of `foo`.
78+> levels: `^^^foo` means the fourth most innermost instance of `foo`.
80−
79+
81−`++jo` in `zuse` is a useful library for parsing complex json
80+> `++jo` in `zuse` is a useful library for parsing complex json
82−into hoon structures. In this case, the `:` between `so` and
81+> into hoon structures. In this case, the `:` between `so` and
83−`jo` means 'inside of', because `so` is an arm contained within
82+> `jo` means 'inside of', because `so` is an arm contained within
84−the core `jo`. Our case is actually simple enough that the
83+> the core `jo`. Our case is actually simple enough that the
85−`?>` line could have been `?> =([%s 'click'] jon)`.
84+> `?>` line could have been `?> =([%s 'click'] jon)`.
86−</blockquote>
87
85
88We can test this mark from the command line (don't forget to start your app with `|start %click`)
86We can test this mark from the command line (don't forget to start your app with `|start %click`)
89
87
@@ -115,11 +113,9 @@ And `/mar/clicks.hoon`:
115`clicks` is just an atom. We convert to json by creating an
113`clicks` is just an atom. We convert to json by creating an
116object with a single field "clicks" with our value.
114object with a single field "clicks" with our value.
117
115
118−<blockquote class="blockquote">
119−Be sure to checkout section 3bD, JSON and XML, in zuse.hoon
116+> 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
117+> `++joba` is just a function that takes a key-value pair and
121−produces a JSON object with one element.
118+> produces a JSON object with one element.
122−</blockquote>
123
119
124```
120```
125~fintud-macrep:dojo> &json &clicks 6
121~fintud-macrep:dojo> &json &clicks 6
@@ -149,7 +145,7 @@ the app from the command line.
149 `:click` and print out the subscription updates on the command
145 `:click` and print out the subscription updates on the command
150 line.
146 line.
151
147
152−#Frontend
148+# Frontend
153
149
154That's all that's needed for the back end. The front end is just
150That's all that's needed for the back end. The front end is just
155some "sail" html (Hoon markup for XML) and javascript. Here's `/web/click.hoon`:
151some "sail" html (Hoon markup for XML) and javascript. Here's `/web/click.hoon`:
docs/hoon.md+6−2
@@ -1,8 +1,12 @@
1---
1---
2navhome: /docs
2navhome: /docs
3−sort: 3
3+sort: 4
4---
4---
5
5
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.
7
11
8<list/>
12<list/>
docs/hoon/advanced.md+8−8
@@ -72,12 +72,12 @@ polymorphism relies on genericity.
72### Dry arms
72### Dry arms
73
73
74For a dry arm, we apply the Liskov substitution principle: we
74For 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
76test as in `:cast` or any type comparison (`nest`). Intuitively,
76test 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?"
78
78
79For a core `a`, if `p.a` fits in `q.q.a`, we can use arms on the
79For 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
81defined as `{$hold a(p q.q.a, p.q %gold) b}`.
81defined as `{$hold a(p q.q.a, p.q %gold) b}`.
82
82
83In other words, the subject of the arm computation is the
83In other words, the subject of the arm computation is the
@@ -89,7 +89,7 @@ call in most languages.
89
89
90Dry polymorphism works by substituting cores. Typically, the
90Dry polymorphism works by substituting cores. Typically, the
91the programmer uses one core as an interface definition, then
91the 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.
93
93
94For core `b` to nest within core `a`, the batteries of `a` and
94For core `b` to nest within core `a`, the batteries of `a` and
95`b` must have the same tree shape, and the product of each `b`
95`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
108any metal can be cast or converted to lead.
108any metal can be cast or converted to lead.
109
109
110A gold core `a` has a read-write payload; another core `b` that
110A 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
112core whose payload is mutually compatible (`+3.a` nests in `+3.b`,
112core whose payload is mutually compatible (`+3.a` nests in `+3.b`,
113`+3.b` nests in `+3.a`). Hence, *invariant*.
113`+3.b` nests in `+3.a`). Hence, *invariant*.
114
114
@@ -128,8 +128,8 @@ nests within `+6.a`. Hence, *covariant*.
128
128
129### Wet arms
129### Wet arms
130
130
131−For a wet arm, we ask: suppose this core was actually compiled
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
132+using `p` instead of `q.q`?" Would the Nock formula we generated
133for `q.q` actually work for a `p` payload?
133for `q.q` actually work for a `p` payload?
134
134
135A wet arm with twig `b` in core `a` produces the span `{$hold a
135A 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.
186If a name is in the `p.p` map, it's an alias. The map contains a
186If a name is in the `p.p` map, it's an alias. The map contains a
187`(unit twig)`; if the unit is full, the name resolves to that
187`(unit twig)`; if the unit is full, the name resolves to that
188twig (compiled against the `q` span). If the unit is empty,
188twig (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
190this means).
190this means).
191
191
192If a name is in the `q.p` map, it's a bridge. When we search for
192If 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.)
17## `sieve`: code in basic style
17## `sieve`: code in basic style
18
18
19A function that produces the list of primes less than or equal to
19A function that produces the list of primes less than or equal to
20−than its argument, an atom:
20+its argument, an atom:
21```
21```
22:gate thru/atom :: 1
22:gate thru/atom :: 1
23:cast (list atom) :: 2
23:cast (list atom) :: 2
@@ -313,7 +313,7 @@ Line `13` defines the `spot` mold, a 2D coordinate.
313 == :: 16
313 == :: 16
314```
314```
315
315
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.,
317output action), as a book (tagged union). There are two forms of
317output action), as a book (tagged union). There are two forms of
318`fact`: `[%tie ~]` (reporting a tie), and `[%win cord]`
318`fact`: `[%tie ~]` (reporting a tie), and `[%win cord]`
319(reporting that `'X'` or `'O'` won a game.
319(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
26 `'javacript'`, `'python'`.
26 `'javacript'`, `'python'`.
27
27
281. At the dojo, take the union of `s` and `l`. Delete
281. 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'`.
30
30
311. Create an alphabetized list of the members of the set created
311. Create an alphabetized list of the members of the set created
32 in the previous exercise.
32 in the previous exercise.
docs/hoon/exercises/fizzbuzz.md+2−2
@@ -28,8 +28,8 @@ comments: true
28 ```
28 ```
29
29
30 Modify this to produce "Fuzz" when the number is divisible by
30 Modify this to produce "Fuzz" when the number is divisible by
31− 7, "Fuzz" when divisible by 21, "FuzzFizz" when divisble by 35,
31+ 7, "Fuzz" when divisible by 21, "FuzzFizz" when divisible by 35,
32− and "FuzzFizzBuzz" when divisble by 105.
32+ and "FuzzFizzBuzz" when divisible by 105.
33
33
341. Modify FizzBuzz from the previous exercise to take both a
341. Modify FizzBuzz from the previous exercise to take both a
35 start and an end number.
35 start and an end number.
docs/hoon/library/2b.md+236−3
@@ -128,6 +128,113 @@ Examples
128
128
129
129
130
130
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+
131***
238***
132### `++levy`
239### `++levy`
133
240
@@ -650,7 +757,7 @@ Examples
650
757
651 > (snag 2 "asdf")
758 > (snag 2 "asdf")
652 ~~d
759 ~~d
653− > (snag 0 `(list ,@ud)`~[1 2 3 4])
760+ > (snag 0 `(list @ud)`~[1 2 3 4])
654 1
761 1
655
762
656
763
@@ -667,7 +774,7 @@ sorted according to `b`.
667Accepts
774Accepts
668-------
775-------
669
776
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.
671
778
672Produces
779Produces
673--------
780--------
@@ -766,7 +873,7 @@ Source
766Examples
873Examples
767--------
874--------
768
875
769− > (turn (limo [104 111 111 110 ~]) ,@t)
876+ > (turn (limo [104 111 111 110 ~]) @t)
770 <|h o o n|>
877 <|h o o n|>
771 > =a |=(a/@ (add a 4))
878 > =a |=(a/@ (add a 4))
772 > (turn (limo [1 2 3 4 ~]) a)
879 > (turn (limo [1 2 3 4 ~]) a)
@@ -774,6 +881,132 @@ Examples
774
881
775
882
776
883
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+
777***
1010***
778### `++weld`
1011### `++weld`
779
1012
docs/hoon/library/2h.md+44
@@ -461,6 +461,50 @@ Examples
461
461
462------------------------------------------------------------------------
462------------------------------------------------------------------------
463
463
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+
464### `+-tap:in`
508### `+-tap:in`
465
509
466Set to list
510Set to list
docs/hoon/library/2n.md+6−4
@@ -145,10 +145,12 @@ not.
145Source
145Source
146------
146------
147
147
148− ++ cury :: curry left
148+ ++ hard :: force coerce to span
149− |* {a/_|=(^ **) b/*}
149+ |* han/mold
150− |* c/_+<+.a
150+ |= fud/* ^- han
151− (a b c)
151+ ~| %hard
152+ =+ gol=(han fud)
153+ ?>(=(gol fud) gol)
152 ::
154 ::
153
155
154Examples
156Examples
docs/hoon/library/2q.md+2−2
@@ -147,9 +147,9 @@ Source
147Examples
147Examples
148--------
148--------
149
149
150− > `(list ,char)`"foobar"
150+ > `(list char)`"foobar"
151 "foobar"
151 "foobar"
152− > `(list ,@)`"foobar"
152+ > `(list @)`"foobar"
153 ~[102 111 111 98 97 114]
153 ~[102 111 111 98 97 114]
154
154
155
155
docs/hoon/library/4h.md+1−1
@@ -61,7 +61,7 @@ Examples
61Parse backslash
61Parse backslash
62
62
63Parses ASCII character 92, the backslash. Note the extra `\` in the calling of
63Parses 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
65character, `\`.
65character, `\`.
66
66
67Source
67Source
docs/hoon/library/zuse/core/epur.md+1−1
@@ -12,7 +12,7 @@ Parses an entire URL.
12Accepts
12Accepts
13-------
13-------
14
14
15−`a` is a [`++cord`](/doc/hoon/library/1#++cord).
15+`a` is a [`++cord`](/docs/hoon/library/1#++cord).
16
16
17Produces
17Produces
18--------
18--------
docs/hoon/library/zuse/core/yu.md+1−1
@@ -153,7 +153,7 @@ Examples
153Back-shifted leap second dates
153Back-shifted leap second dates
154
154
155Produces a [`++list`]() of absolute dates ([`@da`]()s) that represent the Urbit
155Produces 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).
157
157
158Produces
158Produces
159--------
159--------
docs/hoon/library/zuse/diff.md+1−1
@@ -227,7 +227,7 @@ Examples
227Find common
227Find common
228
228
229Finds a subsequence of repeated elements within two
229Finds 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]().
231
231
232Accepts
232Accepts
233-------
233-------
docs/hoon/library/zuse/gate/jesc.md+1−1
@@ -7,7 +7,7 @@ navhome: /docs
7
7
8Escape JSON character
8Escape JSON character
9
9
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`.
11
11
12Accepts
12Accepts
13-------
13-------
docs/hoon/library/zuse/gate/tope.md+1−1
@@ -24,7 +24,7 @@ A `++path`.
24 ^- path
24 ^- path
25 [(scot %p p.bem) q.bem (scot r.bem) (flop s.bem)]
25 [(scot %p p.bem) q.bem (scot r.bem) (flop s.bem)]
26
26
27−Parses a [`++beam`]() to a [`++path`](/doc/hoon/library/1#++path).
27+Parses a [`++beam`]() to a [`++path`](/docs/hoon/library/1#++path).
28
28
29 ~zod/try=/zop> (tope [~zod %main ud/1] /hook/down/sur)
29 ~zod/try=/zop> (tope [~zod %main ud/1] /hook/down/sur)
30 /~zod/main/1/sur/down/hook
30 /~zod/main/1/sur/down/hook
docs/hoon/reference.md+4
@@ -10,6 +10,10 @@ title: Twig reference
10
10
11<div class="book">
11<div class="book">
12
12
13+### [Atoms and strings](../twig/atom)
14+
15+### [Limbs and wings](../twig/limb)
16+
13## `$ buc` (mold)
17## `$ buc` (mold)
14
18
15<list src="../twig/buc-mold" dataPreview="true" className="runes" childIsFragment="true"></list>
19<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).
159 |= end/atom
159 |= end/atom
160 =/ count 1
160 =/ count 1
161 |- ^- (list tape)
161 |- ^- (list tape)
162− ?: =(100 count) ~
162+ ?: =(end count) ~
163 :_ $(count (add 1 count))
163 :_ $(count (add 1 count))
164 ?: =(0 (mod count 15))
164 ?: =(0 (mod count 15))
165 "FizzBuzz"
165 "FizzBuzz"
@@ -167,7 +167,7 @@ with the [original](../demo).
167 "Fizz"
167 "Fizz"
168 ?: =(0 (mod count 3))
168 ?: =(0 (mod count 3))
169 "Buzz"
169 "Buzz"
170− (text !>(count))
170+ (pave !>(count))
171```
171```
172
172
173## Tall regular form
173## Tall regular form
@@ -371,7 +371,7 @@ long names and/or kebab-case.
371
371
372If you came all this way to learn how to write apps, you're all
372If you came all this way to learn how to write apps, you're all
373set. This is about all you need to know to start getting your
373set. 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
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.
375+needed, but for now, move on to [Arvo](../../arvo) to continue learning.
376
376
377If, however, good enough is *not* enough, feel free to dive deeper:
377If, 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.
28The bulb is usually a tuple, sometimes a list or map. An element
28The bulb is usually a tuple, sometimes a list or map. An element
29of this structure is a *subexpression* or just *leg*.
29of this structure is a *subexpression* or just *leg*.
30
30
31−Usually a subexpression is itself a `twig`; sometimes it's an
31+Usually a subexpression is itself a `twig`; sometimes it's a
32`@tas` (symbol) or a `wing` (reference path).
32`@tas` (symbol) or a `wing` (reference path).
33
33
34## Moldy moss; woody seed
34## Moldy moss; woody seed
docs/hoon/twig/bar-core/cab-door.md+1−1
@@ -4,7 +4,7 @@ sort: 5
4
4
5---
5---
6
6
7−# `:door |_ "buccab"`
7+# `:door |_ "barcab"`
8
8
9`{$door p/moss q/(map term foot)}`: form a door, a many-armed core
9`{$door p/moss q/(map term foot)}`: form a door, a many-armed core
10with a sample.
10with a sample.
docs/hoon/twig/bar-core/dot-trap.md+3
@@ -52,3 +52,6 @@ A more interesting trap:
52
52
53Note that we can use `:moar()` or `$()` to recurse back into the
53Note that we can use `:moar()` or `$()` to recurse back into the
54trap, since it's a core with an `$` arm.
54trap, 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
21
21
22Regular: *1-fixed*.
22Regular: *1-fixed*.
23
23
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+
24## Examples
33## Examples
25
34
26A trivial loop doesn't even recurse:
35A 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).
32Genericity is a powerful and dangerous tool. Use gills only if
32Genericity is a powerful and dangerous tool. Use gills only if
33you think you know what you're doing.
33you think you know what you're doing.
34
34
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+
35## Examples
40## Examples
36
41
37Wet and dry gates in a nutshell:
42Wet and dry gates in a nutshell:
docs/hoon/twig/bar-core/tis-gate.md+6
@@ -24,6 +24,12 @@ Regular: *2-fixed*.
24
24
25## Discussion
25## Discussion
26
26
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+
27## Examples
33## Examples
28
34
29A trivial gate:
35A trivial gate:
docs/hoon/twig/buc-mold/hep-lamb.md+1−1
@@ -4,7 +4,7 @@ sort: 8
4
4
5---
5---
6
6
7−# `:lamb $-, "buchep"`
7+# `:lamb $- "buchep"`
8
8
9`{$lamb p/moss q/moss}`: mold which normalizes to an example gate.
9`{$lamb p/moss q/moss}`: mold which normalizes to an example gate.
10
10
docs/hoon/twig/tis-flow/bar-new.md+1−1
@@ -3,7 +3,7 @@ navhome: /docs
3sort: 5
3sort: 5
4---
4---
5
5
6−# `:new =| , "tisbar"`
6+# `:new =| "tisbar"`
7
7
8`{$new p/moss q/seed}`: combine a defaulted mold with the subject.
8`{$new p/moss q/seed}`: combine a defaulted mold with the subject.
9
9
docs/hoon/twig/wut-test/gar-sure.md+1−1
@@ -3,7 +3,7 @@ navhome: /docs
3sort: 11
3sort: 11
4---
4---
5
5
6−# `:sure ?< "wutgar"`
6+# `:sure ?> "wutgar"`
7
7
8`{$sure p/seed q/seed}`: positive assertion.
8`{$sure p/seed q/seed}`: positive assertion.
9
9
docs/hoon/twig/wut-test/lus-deft.md+1−1
@@ -3,7 +3,7 @@ navhome: /docs
3sort: 13
3sort: 13
4---
4---
5
5
6−# `:deft ?- "wutlus"`
6+# `:deft ?+ "wutlus"`
7
7
8`{$case p/wing q/seed r/(list (pair moss seed))}`: switch against
8`{$case p/wing q/seed r/(list (pair moss seed))}`: switch against
9a union, with a default.
9a union, with a default.
docs/hoon/twig/wut-test/zap-not.md+3−1
@@ -19,11 +19,13 @@ Produces the logical "not" of `p`.
19
19
20Regular: *1-fixed*.
20Regular: *1-fixed*.
21
21
22−Irregular: `!(foo)` is `?!(foo)`.
22+Irregular: `!foo` is `?!(foo)`.
23
23
24## Examples
24## Examples
25
25
26```
26```
27+~zod:dojo> ?!(.=(1 2))
28+%.y
27~zod:dojo> !&
29~zod:dojo> !&
28%.n
30%.n
29~zod:dojo> !|
31~zod:dojo> !|
docs/hoon/twig/zap-wild/gar-wrap.md+1−1
@@ -24,5 +24,5 @@ span-noun cell is generally called a `vase`.
24
24
25```
25```
26~zod:dojo> !>(1)
26~zod:dojo> !>(1)
27−[#t/@ud q=1]
27+[p=#t/@ud q=1]
28```
28```
docs/nock.md+4
@@ -6,4 +6,8 @@ title: Nock
6
6
7# Nock
7# Nock
8
8
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+
9<list/>
13<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
5
5
6# Using
6# Using
7
7
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+
8<list/>
12<list/>
docs/using/filesystem.md+91−86
@@ -1,24 +1,28 @@
1---
1---
2−navhome: /docs
2+navhome: '/docs'
3−next: true
3+next: True
4sort: 6
4sort: 6
5title: Filesystem
5title: Filesystem
6---
6---
7
7
8# Filesystem (`%clay`)
8# Filesystem (`%clay`)
9
9
10−<div class="row"> <div class="col-md-8">
10+<div class="row">
11
11
12−Urbit has its own revision-controlled filesystem, `%clay`. `%clay` is
12+<div class="col-md-8">
13−a typed, global, referentially transparent namespace. An easy way to
14−think about it is like typed `git` with continuous sync.
15
13
16−The most common way to use `%clay` is to mount a `%clay` node in a
14+Urbit has its own revision-controlled filesystem, `%clay`. `%clay` is a
17−Unix directory. The Urbit process will watch this directory and
15+typed, global, referentially transparent namespace. An easy way to think
18−automatically record edits as changes, Dropbox style. The mounted
16+about it is like typed `git` with continuous sync.
19−directory is always at the root of your pier directory.
20
17
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+
21−</div> </div>
23+</div>
24+
25+</div>
22
26
23## Quickstart
27## Quickstart
24
28
@@ -28,14 +32,13 @@ Create a `%sandbox` desk based on the `%home` desk:
28
32
29 |merge %sandbox ~your-urbit %home
33 |merge %sandbox ~your-urbit %home
30
34
31−Most of the time we want to use `%clay` from Unix.
35+Most of the time we want to use `%clay` from Unix.
32
36
33Mount the entire contents of your `sandbox` desk to Unix:
37Mount the entire contents of your `sandbox` desk to Unix:
34
38
35 ~your-urbit:dojo> |mount /=sandbox=
39 ~your-urbit:dojo> |mount /=sandbox=
36
40
37−To explore the filesystem from inside Urbit `+ls` and `+cat` are
41+To explore the filesystem from inside Urbit `+ls` and `+cat` are useful:
38−useful:
39
42
40 ~your-urbit:dojo> +ls /=sandbox=/web
43 ~your-urbit:dojo> +ls /=sandbox=/web
41
44
@@ -50,37 +53,41 @@ Sync from your friend `~some-ship`'s `%experiment` desk to your
50
53
51## Manual
54## Manual
52
55
53−<h3 class="first child">Paths</h3>
56+<h3 class="first child">
57+Paths
58+</h3>
54
59
55−A path in `%clay` is a list of URL-safe text, restricted to `[a
60+A path in `%clay` is a list of URL-safe text, restricted to
56−z]`,`[0 9]`, `.`, `-`, `_` and `~`. Formally this is a `(list knot)`
61+`[a z]`,`[0 9]`, `.`, `-`, `_` and `~`. Formally this is a `(list knot)`
57where each segment is a `@ta`.
62where each segment is a `@ta`.
58
63
59Paths can be expressed as either `/foo/bar/baz` or `[%foo %bar %baz]`.
64Paths can be expressed as either `/foo/bar/baz` or `[%foo %bar %baz]`.
60The first three segments of an urbit path are `/plot/desk/case`, for
65The first three segments of an urbit path are `/plot/desk/case`, for
61−example `/~doznec/home/1`.
66+example `/~dozbud/home/1`.
62
67
63#### Relative paths
68#### Relative paths
64
69
65Relative paths are expressed using `%` which is roughly equivalent to
70Relative paths are expressed using `%` which is roughly equivalent to
66−Unix `.`. `%%` is `..` and `%%%` is what you would expect `...` to
71+Unix `.`. `%%` is `..` and `%%%` is what you would expect `...` to be.
67−be. There are no local relative paths. `foo/bar` must be written
72+There are no local relative paths. `foo/bar` must be written
68`%/foo/bar`.
73`%/foo/bar`.
69
74
70#### Substitution
75#### Substitution
71
76
72If the default path is `/foo/bar/baz`, `/=/moo` means `/foo/moo`, and
77If the default path is `/foo/bar/baz`, `/=/moo` means `/foo/moo`, and
73−`/=/moo/=/goo` means `/foo/moo/baz/goo`. Also, instead of `/=/=/zoo`
78+`/=/moo/=/goo` means `/foo/moo/baz/goo`. Also, instead of `/=/=/zoo` or
74−or `/=/=/=/voo`, write `/==zoo` or `/===voo`.
79+`/=/=/=/voo`, write `/==zoo` or `/===voo`.
75
80
76−Most commonly this is used to avoid having to know the current
81+Most commonly this is used to avoid having to know the current revision
77−revision number in the `dojo`. Instead of writing
82+number in the `dojo`. Instead of writing
78`/~your-urbit/home/4/path/to/file` you can just write
83`/~your-urbit/home/4/path/to/file` you can just write
79`/=home=/path/to/file`.
84`/=home=/path/to/file`.
80
85
81### Revision-control
86### Revision-control
82
87
88+<h3 class="first child">
83−<h3 class="first child"><code>|mount clay-path [unix-name]</code></h3>
89+<code>|mount clay-path [unix-name]</code>
90+</h3>
84
91
85Mount the `clay-path` at the unix mount point `unix-name`.
92Mount the `clay-path` at the unix mount point `unix-name`.
86
93
@@ -108,44 +115,44 @@ Unmounts the path `%/web` from whatever name it was mounted as.
108
115
109Unmounts the Unix path `/generators`.
116Unmounts the Unix path `/generators`.
110
117
111−### `|merge desk beak [strategy]`
118+### `|merge desk beak[, =gem strategy]`
112
119
113Merges a `beak` into a `desk` using an optional merge `strategy`.
120Merges a `beak` into a `desk` using an optional merge `strategy`.
114
121
115−A `beak` is either a desk (`%home`), a plot-desk cell (`[~doznec
122+A `beak` is a ship-desk-case triple, encoded as a
116−%home]`), or a plot-desk-case (`/~doznec/home/2/web/md`)
123+path(`/~dozbud/home/2`)
117
124
118**Examples:**
125**Examples:**
119
126
120− |merge %home-work /=home= %fine
127+ |merge %home-work /=home=, =gem %fine
121
128
122Merge `/=home=` into `%home-work` using merge strategy `%fine`.
129Merge `/=home=` into `%home-work` using merge strategy `%fine`.
123
130
124− |merge %examples [~wacbex-ribmex %examples]
131+ |merge %examples ~wacbex-ribmex %examples
125
132
126Merge the `%examples` desk from `~waxbex-ribmex`
133Merge the `%examples` desk from `~waxbex-ribmex`
127
134
128### `|sync desk plot [plot-desk]`
135### `|sync desk plot [plot-desk]`
129
136
130Subscribe to continuous updates from remote `plot` on local `desk`.
137Subscribe to continuous updates from remote `plot` on local `desk`.
131−`plot-desk` can specify the remote `desk` name. When omitted it's
138+`plot-desk` can specify the remote `desk` name. When omitted it is
132−assumed to be the same as `desk`. Moons have `|sync %home ~parent
139+defaulted to being the same as `desk`. Non-comet urbits have
133−%kids` automatically set up (where `~parent` is the planet that issued
140+`|sync %home ~parent %kids` automatically set up (where `~parent` is the
134−the moon).
141+planet that issued a moon, the star that issued a planet, or the galaxy
142+that issued a star).
135
143
136**Examples:**
144**Examples:**
137
145
138− |sync %home-local ~doznec %home |sync %home ~doznec
146+ |sync %home-local ~dozbud %home |sync %home ~doznec
139
147
140### `|unsync desk plot [plot-desk]`
148### `|unsync desk plot [plot-desk]`
141
149
142Unsubscribe from updates from remote `plot` on local `desk` with
150Unsubscribe from updates from remote `plot` on local `desk` with
143−optional `plot-desk`. Arguments must match original `|sync` command
151+optional `plot-desk`. Arguments must match original `|sync` command.
144−exactly.
145
152
146Example:
153Example:
147
154
148− |unsync %home-local ~doznec %home
155+ |unsync %home-local ~dozbud %home
149
156
150### `|label desk name`
157### `|label desk name`
151
158
@@ -157,84 +164,82 @@ Example:
157
164
158### Merge strategies
165### Merge strategies
159
166
160−`%init` - Used if it's the first commit to a desk. Also can be
167+`%init` - Used if it's the first commit to a desk. Also can be used to
161−used to "reinitialize" a desk -- revision numbers keep going up,
168+"reinitialize" a desk -- revision numbers keep going up, but the new
162−but the new revision isn't necessarily a descendent of the
169+revision isn't necessarily a descendent of the previously-numbered
163−previously-numbered version.
170+version, allowing merges to be rerun.
164
171
165`%this` - Keep what's in Bob's desk, but join the ancestry.
172`%this` - Keep what's in Bob's desk, but join the ancestry.
166
173
167`%that` - take what's in Alice's desk, but join the ancestry. This is
174`%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
175+the reverse of `%this`. This is different from `%init` because the new
169−the new commit has both sides in its ancestry.
176+commit has both sides in its ancestry.
170
177
171`%fine` - "fast-forward" merge. This succeeds iff one head is in the
178`%fine` - "fast-forward" merge. This succeeds iff one head is in the
172ancestry of the other.
179ancestry of the other.
173
180
174−`%meet`, `%mate`, and `%meld` - find the most recent common ancestor
181+`%meet`, `%mate`, and `%meld` - find the most recent common ancestor to
175−to use as our merge base.
182+use as our merge base.
176
183
177A `%meet` merge only succeeds if the changes from the merge base to
184A `%meet` merge only succeeds if the changes from the merge base to
178−Alice's head (hereafter, "Alice's changes") are in different files
185+Alice's head (hereafter, "Alice's changes") are in different files than
179−than Bob's changes. In this case, the parents are both Alice's and
186+Bob's changes. In this case, the parents are both Alice's and Bob's
180−Bob's heads, and the data is the merge base plus Alice's changed files
187+heads, and the data is the merge base plus Alice's changed files plus
181−plus Bob's changed files.
188+Bob's changed files.
182
189
183A `%mate` merge attempts to merge changes to the same file when both
190A `%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,
191+Alice and Bob change it. If the merge is clean, we use it; otherwise, we
185−we fail. A merge between different types of changes -- for example,
192+fail. A merge between different types of changes -- for example,
186deleting a file vs changing it -- is always a conflict. If we succeed,
193deleting 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
194+the parents are both Alice's and Bob's heads, and the data is the merge
188−merge base plus Alice's changed files plus Bob's changed files plus
195+base plus Alice's changed files plus Bob's changed files plus the merged
189−the merged files.
196+files.
190
197
191A `%meld` merge will succeed even if there are conflicts. If there are
198A `%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
199+conflicts in a file, then we use the merge base's version of that file,
193−file, and we produce a set of files with conflicts. The parents are
200+and we produce a set of files with conflicts. The parents are both
194−both Alice's and Bob's heads, and the data is the merge base plus
201+Alice's and Bob's heads, and the data is the merge base plus Alice's
195−Alice's changed files plus Bob's changed files plus the successfully
202+changed files plus Bob's changed files plus the successfully merged
196−merged files plus the merge base's version of the conflicting files.
203+files plus the merge base's version of the conflicting files.
197−
204+
198−`%auto` - meta-strategy. Check to see if Bob's desk exists, and if it
205+`%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
206+doesn't we use an `%init` merge. Otherwise, we progressively try
200−`%fine`, `%meet`, and `%mate` until one succeeds. If none succeed, we
207+`%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
208+merge Bob's desk into a scratch desk. Then, we merge Alice's desk into
202−into the scratch desk with the `%meld` option to force the merge.
209+the scratch desk with the `%meld` option to force the merge. Finally, we
203−Finally, we annotate any conflicts, if we know how.
210+annotate any conflicts, if we know how.
204
211
205### Manipulation
212### Manipulation
206
213
207−<h3 class="first child"><code>|rm path</code></h3>
214+<h3 class="first child">
215+<code>|rm path</code>
216+</h3>
208
217
209−Remove the data at `path`. `path` must be a path to actual node, not
218+Remove the data at `path`. `path` must be a path to actual node, not a
210−a 'directory'
219+'directory'
211
220
212−### `|cp to from how`
221+### `|cp to from`
213
222
214−Copy the subtree `from` into the subtree `to`, committing it with the
223+Copy the file at `from` into the path `to`.
215−specified merge strategy `how`.
216
224
217−#### `|mv to from how`
225+#### `|mv to from`
218
226
219−Move the subtree `from` into the subtree `to`, committing it with the
227+Move the file at `from` into the path `to`.
220−specified merge strategy `how`.
221
228
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`
223doesn't happen unless the `|cp` succeeds.
230doesn't happen unless the `|cp` succeeds.
224
231
225### Generators
232### Generators
226
233
227−<h3 class="first child"><code>+cat path</code> / <code>+cal [path
234+<h3 class="first child">
228−...]</code></h3>
235+<code>+cat path [path ...]</code>
229−
236+</h3>
230−Similar to Unix `cat`. `+cat` takes a single `path`, `+cal` a list of
231−paths.
232
237
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.
234
240
235−### `+ls path` / `+ll [path ...]`
241+### `+ls path`
236
242
237−Similar to Unix `ls`. `+ls` takes a single `path`, `+ll` a list of
243+Similar to Unix `ls`. `+ls` takes a single `path`.
238−paths.
239
244
240Produces a list of names at the `path`.
245Produces a list of names at the `path`.
docs/using/layout.md+1−1
@@ -1,6 +1,6 @@
1---
1---
2navhome: /docs
2navhome: /docs
3−sort: 8
3+sort: 9
4title: Source layout
4title: Source layout
5---
5---
6
6
docs/using/messaging.md+127−43
@@ -1,33 +1,49 @@
1---
1---
2−navhome: /docs
2+navhome: '/docs'
3−next: true
3+next: True
4sort: 4
4sort: 4
5−title: Messaging (:talk)
5+title: 'Messaging (:talk)'
6---
6---
7
7
8# Messaging (`:talk`)
8# Messaging (`:talk`)
9
9
10<div class="row">
10<div class="row">
11+
11<div class="col-md-8">
12<div class="col-md-8">
12
13
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.
14
17
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.
16
20
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.
18
24
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.
20
30
21</div>
31</div>
32+
22</div>
33</div>
23
34
24## Quickstart
35## Quickstart
25
36
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.
27
41
28Let's join `/urbit-meta`:
42Let's join `/urbit-meta`:
29
43
44+Use `ctrl-x` to switch from `:dojo` to `:talk`, then:
45+
30− ~your-urbit: ;join ~doznec/urbit-meta
46+ ~your-urbit:talk> ;join ~dozbud/urbit-meta
31
47
32You'll see:
48You'll see:
33
49
@@ -35,14 +51,14 @@ You'll see:
35 ---------:talk| rules of /urbit-meta:
51 ---------:talk| rules of /urbit-meta:
36 ---------:talk| don't be rude
52 ---------:talk| don't be rude
37 ---------:talk| urbit-meta is politically correct and safe for work
53 ---------: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
39 ~your-urbit:talk>
55 ~your-urbit:talk>
40
56
41Post a line to `/urbit-meta`:
57Post a line to `/urbit-meta`:
42
58
43 ~your-urbit:talk> hello, world
59 ~your-urbit:talk> hello, world
44
60
45−You'll see, echoed back at you through `~doznec`:
61+You'll see, echoed back at you through `~dozbud`:
46
62
47 ~your-urbit> hello, world
63 ~your-urbit> hello, world
48
64
@@ -58,11 +74,18 @@ Now you and `~talsur-todres` can exchange messages directly.
58
74
59To set your audience back to `/urbit-meta`:
75To set your audience back to `/urbit-meta`:
60
76
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
62
82
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`).
64
86
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).
66
89
67Last, let's create a channel we can invite some friends to:
90Last, let's create a channel we can invite some friends to:
68
91
@@ -72,11 +95,18 @@ Now you can tell your friends to `;join ~your-urbit/my-channel`.
72
95
73## Manual
96## Manual
74
97
98+`:talk`'s design is similar in spirit to
75−`:talk`'s design is similar in spirit to [nntp](https://en.wikipedia.org/wiki/Network_News_Transfer_Protocol), the underlying protocol for Usenet.
99+[nntp](https://en.wikipedia.org/wiki/Network_News_Transfer_Protocol),
100+the underlying protocol for Usenet.
76
101
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.
78
105
106+There are four kinds of station: a write-only `%mailbox` for direct
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.
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.
80
110
81### Posts
111### Posts
82
112
@@ -84,33 +114,79 @@ For the time being a post is either a line, a URL or a command.
84
114
85#### Lines
115#### Lines
86
116
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`).
88
119
89−The `:talk` interface will let you keep typing past 64 bytes, but
120+The `:talk` interface will let you keep typing past 64 bytes, but insert
90−insert a Unicode bullet-point character in an appropriate space
121+a Unicode bullet-point character in an appropriate space in your post,
91−in your post, to show you the prospective linebreak. Your essay
122+to show you the prospective linebreak. Your essay will be posted in
92−will be posted in multiple lines.
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
93
131
94#### URLs
132#### URLs
95
133
96A URL is any valid URL.
134A URL is any valid URL.
97
135
136+ ~your-urbit:talk> http://example.com
137+
98### Commands
138### Commands
99
139
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.
101
175
102### Creating and managing stations
176### Creating and managing stations
103
177
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.
105
180
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.
107
183
108### Presence
184### Presence
109
185
110−You'll see presence notifications when people enter or leave
186+You'll see presence notifications when people enter or leave stations
111−stations you're subscribed to.
187+you're subscribed to.
112
188
113−`;who` - list everyone in all your stations
189+`;who` - list everyone in all your stations
114
190
115`;who station` - list everyone in that station
191`;who station` - list everyone in that station
116
192
@@ -120,13 +196,16 @@ Glyphs are assigned by station hash out of the following list
120
196
121 > = + - } ) , . " ' ^ $ % & @
197 > = + - } ) , . " ' ^ $ % & @
122
198
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.
124
201
125`;bind > /urbit-test` - assigns the `>` glyph to `/urbit-test`.
202`;bind > /urbit-test` - assigns the `>` glyph to `/urbit-test`.
126
203
127### Prefixes
204### Prefixes
128
205
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.
130
209
131`|` - Informational messages
210`|` - Informational messages
132
211
@@ -140,7 +219,8 @@ Received posts are prefixed with a glyph to let you know what the audience is.
140
219
141#### Prompt
220#### Prompt
142
221
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.
144
224
145Here we're talking to the station bound to `=`:
225Here we're talking to the station bound to `=`:
146
226
@@ -160,20 +240,21 @@ Here we're talking directly to `~dannum-mitryl`:
160
240
161`;%station` - Set audience to a station on your own ship
241`;%station` - Set audience to a station on your own ship
162
242
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.
164
245
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):
166
248
167−- if you manually locked the audience, that audience.
249+- if you manually locked the audience, that audience.
168−- if typing a post, the audience when you started typing.
250+- if typing a post, the audience when you started typing.
169−- if you activated a post, the post you activated.
251+- if you activated a post, the post you activated.
170−- audience of the last post received.
252+- audience of the last post received.
171−- audience of the last post sent.
253+- audience of the last post sent.
172
254
173−Clear any 'implicit' audience setting by moving your cursor to
255+Clear any 'implicit' audience setting by moving your cursor to the start
174−the start of the line and pressing backspace (whether the line is
256+of the line and pressing backspace (whether the line is empty or not).
175−empty or not). Posting a line clears the typing and activation
257+Posting a line clears the typing and activation configurations.
176−configurations.
177
258
178### Nicknames
259### Nicknames
179
260
@@ -191,4 +272,7 @@ configurations.
191
272
192`;unset noob` show urbit names instead of nicknames
273`;unset noob` show urbit names instead of nicknames
193
274
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 @@
1---
1---
2−navhome: /docs
2+navhome: '/docs'
3−next: true
3+next: True
4sort: 2
4sort: 2
5title: Setup
5title: Setup
6---
6---
7
7
8# Getting started
8# Getting started
9
9
10+On disk your urbit is an append-only log and a checkpoint. Or, in
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’.
11+simpler terms, a directory where we keep your urbit’s state. We call
12+this a ‘pier’.
11
13
12## Initialize
14## Initialize
13
15
14−To create an urbit, we need an identity. This identity
16+To create an urbit, we need an identity. This identity is both a network
15−is both a network address and a memorable name.
17+address and a memorable name.
16
18
17−You are probably creating one of two kinds of urbit: a 32-bit
19+You are probably creating one of two kinds of urbit: a 32-bit "planet"
18−"planet" or a 128-bit "comet." For a quick terminology guide
20+or a 128-bit "comet." For a quick terminology guide and high-level
19−and high-level refresher, refer to this [handy reference sheet](/about/terminology).
21+refresher, refer to this [handy reference sheet](/docs/about/glossary).
20
22
21If you have an Urbit invitation, you'll have a planet like
23If you have an Urbit invitation, you'll have a planet like
22−`~fintud-macrep` and `~fortyv-tombyt-tabsen-sonres`. To create
24+`~fintud-macrep` and `~fortyv-tombyt-tabsen-sonres`. To create your
23−your pier:
25+pier:
24
26
25 $ bin/urbit -w fintud-macrep -t fortyv-tombyt-tabsen-sonres
27 $ bin/urbit -w fintud-macrep -t fortyv-tombyt-tabsen-sonres
26
28
27−This will create a directory `fintud-macrep/` and begin building
29+This will create a directory `fintud-macrep/` and begin building your
28−your urbit. This may take a few minutes.
30+urbit. This may take a few minutes.
29
31
30−If you do not have a ticket, you can still make a 'comet', a wild
32+If you do not have a ticket, you can still make a 'comet', a wild urbit
31−urbit drifting through cyberspace. Pick your own directory name,
33+drifting through cyberspace. Pick your own directory name, it doesn't
32−it doesn't matter:
34+matter:
33
35
34 $ bin/urbit -c mycomet
36 $ bin/urbit -c mycomet
35
37
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.
37
40
38## Orientation
41## Orientation
39
42
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!
41
45
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:
43
48
44### Shell — `:dojo`
49### Shell — `:dojo`
45
50
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:
47
53
48 ~fitund-macrep:dojo> (add 2 2)
54 ~fitund-macrep:dojo> (add 2 2)
49
55
@@ -56,29 +62,30 @@ Good.
56
62
57### Messaging — `:talk`
63### Messaging — `:talk`
58
64
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:
60
67
61− ~fitund-macrep:talk() ;join ~doznec/urbit-meta
68+ ~fitund-macrep:talk() ;join ~dozbud/urbit-meta
62
69
63`:talk` is stateful, so your urbit will download a backlog.
70`:talk` is stateful, so your urbit will download a backlog.
64−`/urbit-meta` is the place to ask questions, get help and talk
71+`/urbit-meta` is the place to ask questions, get help and talk about
65−about anything Urbit-related.
72+anything Urbit-related.
66
73
67### Web — `:tree`
74### Web — `:tree`
68
75
69−Urbit is also accessible through the web. Try opening:
76+Urbit is also accessible through the web. Try opening:
70
77
71 http://localhost:8080/
78 http://localhost:8080/
72
79
73−in your favorite browser. You'll be prompted to use `+code`.
80+in your favorite browser. You'll be prompted to use `+code`. This page
74−This page was generated by `:tree`, the basic Urbit web
81+was generated by `:tree`, the basic Urbit web interface. You can also
75−interface. You can also access your urbit through
76−`http://fintud-macrep.urbit.org` (where `fintud-macrep` is your
82+access your urbit through `http://fintud-macrep.urbit.org` (where
77−planet name).
83+`fintud-macrep` is your planet name).
78
84
79### Filesystem — `%clay`
85### Filesystem — `%clay`
80
86
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:
82
89
83 ~fitund-macrep:dojo> |mount %
90 ~fitund-macrep:dojo> |mount %
84
91
@@ -89,10 +96,12 @@ This should produce:
89
96
90which indicates the command was processed.
97which indicates the command was processed.
91
98
99+`|mount %` will cause a `home/` directory to appear inside your pier
92−`|mount %` will cause a `home/` directory to appear inside your pier folder. Changes to these files are automatically synced into your urbit.
100+folder. Changes to these files are automatically synced into your urbit.
93
101
94## Learn more
102## Learn more
95
103
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>.
97
106
98To learn more about using the system, let's keep going:
107To learn more about using the system, let's keep going:
docs/using/shell.md+72−48
@@ -1,21 +1,22 @@
1---
1---
2−navhome: /docs
2+navhome: '/docs'
3−next: true
3+next: True
4sort: 5
4sort: 5
5−title: Shell (:dojo)
5+title: 'Shell (:dojo)'
6---
6---
7
7
8# Shell (`:dojo`)
8# Shell (`:dojo`)
9
9
10<div class="row">
10<div class="row">
11+
11<div class="col-md-8">
12<div class="col-md-8">
12
13
13−The `:dojo` is the place to quickly experiment with Urbit. On
14+The `:dojo` is the place to quickly experiment with Urbit. On the
14−the surface the `:dojo` is just a Hoon REPL. On the inside, the
15+surface the `:dojo` is just a Hoon REPL. On the inside, the `:dojo` is a
15−`:dojo` is a system for operating on and transforming data in
16+system for operating on and transforming data in Urbit.
16−Urbit.
17
17
18</div>
18</div>
19+
19</div>
20</div>
20
21
21## Quickstart
22## Quickstart
@@ -28,7 +29,7 @@ Evaluate a hoon expression:
28Tall form Hoon may require multiple lines:
29Tall form Hoon may require multiple lines:
29
30
30 ~your-urbit:dojo> %+ add
31 ~your-urbit:dojo> %+ add
31− ~your-urbit:dojo< 2
32+ ~your-urbit:dojo< 2
32 ~your-urbit:dojo< 2
33 ~your-urbit:dojo< 2
33
34
34Use `=var` to save a shell variable:
35Use `=var` to save a shell variable:
@@ -51,72 +52,89 @@ Run system commands from `:hood`, like `reload`, using `|`:
51
52
52 ~your-urbit:dojo> |reload %eyre
53 ~your-urbit:dojo> |reload %eyre
53
54
54−
55### Generators
55### Generators
56
56
57−**`+cat`** - Similar to Unix `cat`. Accepts a path.
57+**`+cat`** - Similar to Unix `cat`. Accepts a path.
58
58
59 ~your-urbit:dojo> +cat %/web/md
59 ~your-urbit:dojo> +cat %/web/md
60 ~your-urbit:dojo> +cat /~talsur-todres/home/2/web/notes/md
60 ~your-urbit:dojo> +cat /~talsur-todres/home/2/web/notes/md
61
61
62−**`+curl`** - Similar to Unix `curl`. Accepts a `tape`.
62+**`+curl`** - Similar to Unix `curl`. Accepts a `tape`.
63
63
64 ~your-urbit:dojo> +curl "http://nyt.com"
64 ~your-urbit:dojo> +curl "http://nyt.com"
65
65
66−**`+hello`** - Just prints the argument. Accepts a `@ta`.
66+**`+hello`** - Just prints the argument. Accepts a `@ta`.
67
67
68 ~your-urbit:dojo> +hello 'mars'
68 ~your-urbit:dojo> +hello 'mars'
69
69
70−**`+ls`** - Similar to Unix `ls`. Accepts a path.
70+**`+ls`** - Similar to Unix `ls`. Accepts a path.
71
71
72 ~your-urbit:dojo> +ls %/web
72 ~your-urbit:dojo> +ls %/web
73 ~your-urbit:dojo> +ls /~talsur-todres/home/2/web/notes
73 ~your-urbit:dojo> +ls /~talsur-todres/home/2/web/notes
74
74
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.
76
81
77−**`+solid`** - Compile the current state of the kernel and output a noun. Usually downloaded to a file in unix. No arguments.
78−
79 ~your-urbit:dojo> .urbit/pill +solid
82 ~your-urbit:dojo> .urbit/pill +solid
80
83
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`).
82
86
83 ~your-urbit:dojo> +ticket ~talsur-todres-your-urbit
87 ~your-urbit:dojo> +ticket ~talsur-todres-your-urbit
84
88
85−**`+tree`** - Generate a recursive directory listing. Takes a path.
89+**`+tree`** - Generate a recursive directory listing. Takes a path.
86
90
87 ~your-urbit:dojo> +tree %/web
91 ~your-urbit:dojo> +tree %/web
88
92
89### Hood
93### Hood
90
94
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`.
92
96
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`).
94
99
95− ~your-urbit:dojo> |hi ~doznec 'you there?'
100+ ~your-urbit:dojo> |hi ~dozbud "you there?"
96
101
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.
98
104
99 ~your-urbit:dojo> |link ~talsur-todres %octo
105 ~your-urbit:dojo> |link ~talsur-todres %octo
100
106
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.
102
109
110+ ~your-urbit:dojo> |mass
111+
103−**`|reload`** - Reloads a kernel module (vane) from source. Accepts any number of vane names.
112+**`|reload`** - Reloads a kernel module (vane) from source. Accepts any
113+number of vane names.
104
114
105 ~your-urbit:dojo> |reload %clay %eyre
115 ~your-urbit:dojo> |reload %clay %eyre
106
116
107−**`|reset`** - Reloads `hoon.hoon`. No arguments.
117+**`|reset`** - Reloads `hoon.hoon` and all modules. No arguments.
118+
119+ ~your-urbit:dojo> |reset
108
120
109−**`|start`** - Starts an app. Accepts an app name.
121+**`|start`** - Starts an app. Accepts an app name.
110
122
111 ~your-urbit:dojo> |start %curl
123 ~your-urbit:dojo> |start %curl
112
124
113## Manual
125## Manual
114
126
115−<h3 class="first child">Sources and sinks</h3>
127+<h3 class="first child">
128+Sources and sinks
129+</h3>
116
130
131+A dojo command is either a source or a sink. A source is just something
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.
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.
118
135
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.
120
138
121### Sinks
139### Sinks
122
140
@@ -129,7 +147,7 @@ Set any envronment variable:
129
147
130 44
148 44
131
149
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.)
133
151
134#### `:` - Send to app
152#### `:` - Send to app
135
153
@@ -139,7 +157,7 @@ Send a `helm-hi` message to `hood`:
139
157
140 ~your-urbit:dojo> :hood &helm-hi 'hi'
158 ~your-urbit:dojo> :hood &helm-hi 'hi'
141
159
142−App usually expect marked data, so `&` is often used here.
160+App usually expect marked data, so `&` is often used here.
143
161
144#### `*` - Save in `%clay`
162#### `*` - Save in `%clay`
145
163
@@ -147,11 +165,12 @@ Save a new `md` file in `web`:
147
165
148 ~your-urbit:dojo> *%/web/foo/md '# hello'
166 ~your-urbit:dojo> *%/web/foo/md '# hello'
149
167
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).
151
170
152−#### `.` - Download to Unix
171+#### `.` - Export to Unix
153
172
154−Download a noun to Unix with `.`:
173+Export a noun to Unix with `.`:
155
174
156 ~your-urbit:dojo> .foo/bar/baz (add 2 2)
175 ~your-urbit:dojo> .foo/bar/baz (add 2 2)
157
176
@@ -181,7 +200,7 @@ Use `_` to run a gate (or function):
181 ~your-urbit:dojo> _|=({a/@} (mul a 3)) 3
200 ~your-urbit:dojo> _|=({a/@} (mul a 3)) 3
182 :: produces
201 :: produces
183 9
202 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
185 ~your-urbit:dojo> _|=({p/@ud q/* r/*} p) +http://google.com
204 ~your-urbit:dojo> _|=({p/@ud q/* r/*} p) +http://google.com
186 :: produces
205 :: produces
187 301
206 301
@@ -190,16 +209,18 @@ Use `_` to run a gate (or function):
190
209
191`+http[s]://example.com` - sends a GET request
210`+http[s]://example.com` - sends a GET request
192
211
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.
194
214
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.
196
217
197−Note that the first of these is a source while the last two are
218+Note that the first of these is a source while the last two are sinks.
198−sinks.
199
219
200#### `+` - Generators
220#### `+` - Generators
201
221
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/`.
203
224
204Create a random moon (from any planet):
225Create a random moon (from any planet):
205
226
@@ -207,9 +228,10 @@ Create a random moon (from any planet):
207 :: produces
228 :: produces
208 "moon: ~docsun-tamtem-your-urbit; ticket: ~bartug-hodbyr-fognum-ralmud"
229 "moon: ~docsun-tamtem-your-urbit; ticket: ~bartug-hodbyr-fognum-ralmud"
209
230
210−### Variables
231+### Variables
211
232
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.
213
235
214#### `dir`
236#### `dir`
215
237
@@ -222,9 +244,10 @@ Current working `%clay` desk and revision. Read / write.
222
244
223 404/hoon docs/ dojo/hoon lib/ listen/hoon md static/md talk/ tree/main/
245 404/hoon docs/ dojo/hoon lib/ listen/hoon md static/md talk/ tree/main/
224
246
225−#### `lib`
247+#### `lib`
226
248
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.
228
251
229**Examples:**
252**Examples:**
230
253
@@ -236,7 +259,8 @@ Current set of libraries (`/lib`) in your environment. Can also be set with `/+
236
259
237#### `sur`
260#### `sur`
238
261
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.
240
264
241**Examples:**
265**Examples:**
242
266
@@ -248,7 +272,7 @@ Current set of structures (`/sur`) in your environment. Can also be set with `/
248
272
249#### `now`
273#### `now`
250
274
251−The current (128-bit `@da`) time. Read-only.
275+The current (128-bit `@da`) time. Read-only.
252
276
253**Example:**
277**Example:**
254
278
@@ -258,7 +282,7 @@ The current (128-bit `@da`) time. Read-only.
258
282
259#### `our`
283#### `our`
260
284
261−The current urbit plot. Read-only.
285+The current urbit plot. Read-only.
262
286
263**Example:**
287**Example:**
264
288
@@ -268,7 +292,7 @@ The current urbit plot. Read-only.
268
292
269#### `eny`
293#### `eny`
270
294
271−256 bits of entropy. Read-only.
295+256 bits of entropy. Read-only.
272
296
273**Example:**
297**Example:**
274
298
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
25
25
26Your 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/`.
26Your 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/`.
27
27
28+<span class="red">
28(Make sure you have a desk mounted to unix, as covered in the
29(Make sure you have a desk mounted to unix, as covered in the
29[filesystem walkthrough](/docs/using/filesystem)).
30[filesystem walkthrough](/docs/using/filesystem)).
31+</span>
30
32
31To switch the desk you're serving from:
33To switch the desk you're serving from:
32
34
@@ -38,7 +40,10 @@ To host a file on the web try putting the following in `/home/web/test.md` (from
38
40
39 This is a simple markdown file.
41 This is a simple markdown file.
40
42
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`.
42
47
43Now modify `/home/web/test.md` to list the children using the `<list/>` JSX:
48Now modify `/home/web/test.md` to list the children using the `<list/>` JSX:
44
49
@@ -47,6 +52,10 @@ Now modify `/home/web/test.md` to list the children using the `<list/>` JSX:
47 This is a simple markdown file.
52 This is a simple markdown file.
48
53
49 <div><list /></div>
54 <div><list /></div>
55+
56+To view your file rendered using tree:
57+
58+ http://localhost:8080/test/
50
59
51To view your file as raw `md`:
60To view your file as raw `md`:
52
61
@@ -56,7 +65,7 @@ To view your file as raw `html`:
56
65
57 http://localhost:8080/test.html
66 http://localhost:8080/test.html
58
67
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.
60
69
61You 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.
70You 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.
62
71