on master help sign in
Merge pull request #33 from asgardiator/master

Monday Madness

commit7dfce6942cea7ad7972962ff6d4d74e4593b277c authorGalen Wolfe-Pauly <galen@office-for.com> dateThu 9 Jun 2016, 15:26 (10 years ago) parent4fb70f5195cd27
7 files changed+895−957
docs/arvo/basic.md+185−211 docs/arvo/network.md+290−320 docs/arvo/state.md+87−95 docs/arvo/subject.md+86−85 docs/arvo/subscriptions.md+234−243 docs/hoon/syntax.md+9 docs/using/setup.md+4−3
docs/arvo/basic.md+185−211
@@ -5,29 +5,29 @@ next: true
55title: Hoon refresher / crash course
66---
77
8−# Basic Hoon
8+Basic Hoon
9+==========
910
10−This recapitulates material you've already learned in [Hoon](/docs/hoon/).
11−It will be a very abrupt tutorial if you don't know Hoon already,
12−but it may be enough in and of itself. If you don't find it obvious at first
13−glance, try working up from Hoon.
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.
1415
15−Our goal is to get you programming interesting and useful things
16−as soon as possible. To get there, we have to quickly cover some
17−of the fundamentals of hoon. To do this, we'll walk through two
18−simple programs: the first [Project
19−Euler](https://projecteuler.net/) problem and
20−[fizzbuzz](https://en.wikipedia.org/wiki/Fizz_buzz).
16+Our goal is to get you programming interesting and useful things as soon
17+as 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
19+programs: the first [Project Euler](https://projecteuler.net/) problem
20+and [fizzbuzz](https://en.wikipedia.org/wiki/Fizz_buzz).
2121
22−To run this code, you'll need an urbit, and will have to copy the [examples repo](https://github.com/urbit/examples) into it.
22+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.
2324
24−If you haven't installed
25−urbit yet, check out the [installation
26−instructions](/docs/user/install). Once urbit is
27−installed, take a look at the [basic
28−operation](/docs/user/basic) of your urbit.
25+If you haven't installed urbit yet, check out the [installation
26+instructions](/docs/user/install). Once urbit is installed, take a look
27+at the [basic operation](/docs/user/basic) of your urbit.
2928
30−If you haven't copied in the examples repo, running the following commands from your urbit directory should do the trick:
29+If you haven't copied in the examples repo, running the following
30+commands from your urbit directory should do the trick:
3131
3232`$ cp -r {wherever-you've-pulled-to}/examples/gall/*/ arvo/`
3333`$ cp -r {wherever-you've-pulled-to}/examples/dojo/*/ arvo/`
@@ -37,68 +37,60 @@ Run an example to ensure it worked:
3737 ~fintud-macrep:dojo> +examples-euler1
3838 233.168
3939
40−## Euler 1
41−
42−Let's check out the code for Euler 1. First, the problem:
43−
44−```
45−If we list all the natural numbers below 10 that are multiples of
46−3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
47−
48−Find the sum of all the multiples of 3 or 5 below 1000.
49−```
50−
51−Here is the hoon solution (which should be in your pier directory
52−under `/gen/examples/euler1`):
53−
54−```
55−:: project euler 1
56−:: https://projecteuler.net/problem=1
57−:: run in dojo with +examples-euler1
58−::
59−:::: /hoon/euler1/examples/gen
60− ::
61−:- %say |= *
62−:- %noun
63−=< (sum 1.000)
64−::
65−:::: ~sivtyv-barnel
66− ::
67−|%
68−++ three
69− |= a/@
70− =| b/@
71− |- ^- @u
72− ?: (lth a b)
73− 0
74− (add b $(b (add 3 b)))
75−
76−++ five
77− |= a/@
78− =| b/@
79− |- ^- @
80− ?: (lte a b)
81− 0
82− ?: =((mod b 3) 0)
83− $(b (add b 5))
84− (add b $(b (add b 5)))
85−
86−++ sum
87− |= a/@u
88− (add (five a) (three a))
89−--
90−```
91−
92−
93−<blockquote class="blockquote">
94−Hoon is not generally whitespace sensitive, but we do have two
95−different kinds of whitespace: a single space and a gap, which
96−is two or more spaces or a linebreak. Tabs are taboo. Do not
97−use them. Really. For a more detailed explanation of when to
98−use spaces vs. gaps, see the syntax section before the first
99−excercises.
100−</blockquote>
40+Euler 1
41+-------
10142
43+Let's check out the code for Euler 1. First, the problem:
44+
45+ If we list all the natural numbers below 10 that are multiples of
46+ 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
47+
48+ Find the sum of all the multiples of 3 or 5 below 1000.
49+
50+Here is the hoon solution (which should be in your pier directory under
51+`/gen/examples/euler1`):
52+
53+ :: project euler 1
54+ :: https://projecteuler.net/problem=1
55+ :: run in dojo with +examples-euler1
56+ ::
57+ :::: /hoon/euler1/examples/gen
58+ ::
59+ :- %say |= *
60+ :- %noun
61+ =< (sum 1.000)
62+ ::
63+ :::: ~sivtyv-barnel
64+ ::
65+ |%
66+ ++ three
67+ |= a/@
68+ =| b/@
69+ |- ^- @u
70+ ?: (lth a b)
71+ 0
72+ (add b $(b (add 3 b)))
73+
74+ ++ five
75+ |= a/@
76+ =| b/@
77+ |- ^- @
78+ ?: (lte a b)
79+ 0
80+ ?: =((mod b 3) 0)
81+ $(b (add b 5))
82+ (add b $(b (add b 5)))
83+
84+ ++ sum
85+ |= a/@u
86+ (add (five a) (three a))
87+ --
88+
89+> Hoon is not generally whitespace sensitive, but we do have two
90+> different kinds of whitespace: a single space and a gap, which is two
91+> or more spaces or a linebreak. Tabs are taboo. Do not use them.
92+> Really. For a more detailed explanation of when to use spaces vs.
93+> gaps, see the syntax section before the first exercises.
10294
10395### Lines 1-11:
10496
@@ -108,84 +100,78 @@ Any line that begins with `::` is a comment.
108100 :- %noun
109101 =< (sum 1.000)
110102
111−All you need to know about the lines above is that they call the
112−`++sum` function with an argument of `1.000`. We'll cover them in
113−more detail later.
103+All you need to know about the lines above is that they call the `++sum`
104+function with an argument of `1.000`. We'll cover them in more detail
105+later.
114106
115107### How to form expressions
116108
117109Hoon does not typically use reserved words to form expressions. Instead,
118−expressions are formed with _runes_: digraphs of two
119−ASCII symbols. Each rune takes a specific number of
120−children, either expressions formed by other runes or literals
121−that produce their own value (some runes take _N_ children, and are usually closed with `==`).
110+expressions are formed with *runes*: digraphs of two ASCII symbols. Each
111+rune takes a specific number of children, either expressions formed by
112+other runes or literals that produce their own value (some runes take
113+*N* children, and are usually closed with `==`).
122114
123−For example, the rune `?:` from line 17 is the classic
124−'if-then-else' statement, and thus takes three children:
115+For example, the rune `?:` from line 17 is the classic 'if-then-else'
116+statement, and thus takes three children:
125117
126118 ?: (lth a b) :: if first child evals to true
127119 0 :: then produce result of second
128120 (add b $(b (add 3 b))) :: else, produce result of third
129121
130−Since runes are such a fundamental structure in Hoon, we found
131−ourselves speaking them out loud frequently. It quickly grew
132−cumbersome to have to say "question mark, colon" to describe
133−`?:`. To alleviate this problem, we came up with our own naming
134−scheme: each ASCII glyph has a single-syllable pronunciation
135−phonetically designed to be both easily remembered and easily
136−pronounced in conjunction with the other glyphs (when forming a
137−rune).
122+Since runes are such a fundamental structure in Hoon, we found ourselves
123+speaking them out loud frequently. It quickly grew cumbersome to have to
124+say "question mark, colon" to describe `?:`. To alleviate this problem,
125+we came up with our own naming scheme: each ASCII glyph has a
126+single-syllable pronunciation phonetically designed to be both easily
127+remembered and easily pronounced in conjunction with the other glyphs
128+(when forming a rune).
138129
139130See the entire naming scheme below.
140131
141−```
142− ace [1 space] gal < pel (
143− bar | gap [>1 space, \n] per )
144− bas \ gar > sel [
145− buc $ hax # sem ;
146− cab _ hep - ser ]
147− cen % kel { soq '
148− col : ker } tar *
149− com , ket ^ tec `
150− doq " lus + tis =
151− dot . pam & wut ?
152− fas / pat @ zap !
153−```
132+ ace [1 space] gal < pel (
133+ bar | gap [>1 space, \n] per )
134+ bas \ gar > sel [
135+ buc $ hax # sem ;
136+ cab _ hep - ser ]
137+ cen % kel { soq '
138+ col : ker } tar *
139+ com , ket ^ tec `
140+ doq " lus + tis =
141+ dot . pam & wut ?
142+ fas / pat @ zap !
154143
155144Using this scheme, we would pronounce `?:` as 'wutcol'.
156145
157−For those who prefer to use reserved words to form expressions, you can substitute any rune with that rune's keyword, which you can find in `++twig` in `/arvo/hoon.hoon`. For example, here's the code for `?:` in `++twig`:
146+For those who prefer to use reserved words to form expressions, you can
147+substitute any rune with that rune's keyword, which you can find in
148+`++twig` in `/arvo/hoon.hoon`. For example, here's the code for `?:` in
149+`++twig`:
158150
159151`{$if p/twig q/twig r/twig} :: ?: if/then/else`
160152
161−Instead of:
153+Instead of:
154+
155+ ?:(=(1 2) 'this is true' 'this is false')
156+ 'this is false'`
162157
163−```
164−?:(=(1 2) 'this is true' 'this is false')
165−'this is false'`
166−```
167158You can write:
168159
169−```
170−if(=(1 2) 'this is true' 'this is false')
171−'this is false'
172−```
160+ if(=(1 2) 'this is true' 'this is false')
161+ 'this is false'
173162
174163### Lines 12-34
175164
176−Now let's quickly walk through this code line-by-line. Lines
177−12-34 are wrapped in a `|%` ('barcen'), which produces a core.
178−Cores are a fundamental datatype in Hoon, similar to a
179−struct, class, or object. A core is just a map of names
180−to any kind of code, whether it be functions or data. Each
181−element in this map begins with a `++` followed by the name and
182−the corresponding code. Since `|%` takes an arbitrary number of
165+Now 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
167+fundamental datatype in Hoon, similar to a struct, class, or object. A
168+core is just a map of names to any kind of code, whether it be functions
169+or data. Each element in this map begins with a `++` followed by the
170+name and the corresponding code. Since `|%` takes an arbitrary number of
183171children, it needs to be closed with a `--`.
184172
185−<blockquote class="blockquote">
186−`++` ('luslus') is not technically a rune, since it is only used
187−in core syntax, as shown above.
188−</blockquote>
173+> `++` ('luslus') is not technically a rune, since it is only used in
174+> core syntax, as shown above.
189175
190176Let's step into each of the three arms within our core.
191177
@@ -196,19 +182,19 @@ Let's step into each of the three arms within our core.
196182 (add (five a) (three a))
197183 --
198184
199−`|=` ('bartis') produces a function, much like a lambda in lisp. It takes two children:
185+`|=` ('bartis') produces a function, much like a lambda in lisp. It
186+takes two children:
200187
201−1. A set of argument(s). In this case our argument set only
202− contains one: `a`, which is required to be an atom or natural
203− number, denoted by `@`.
188+1. A set of argument(s). In this case our argument set only contains
189+ one: `a`, which is required to be an atom or natural number, denoted
190+ by `@`.
204191
205−1. The body of the function itself, which is executed when the
206− function is called (in this case, with `(sum 1.000)`). This
207− particular function adds the results of evaluating the gates `++
208− five` and `++three` with each of their respective input
209− parameters set to `a`.
192+2. The body of the function itself, which is executed when the function
193+ is called (in this case, with `(sum 1.000)`). This particular
194+ function adds the results of evaluating the gates `++ five` and
195+ `++three` with each of their respective input parameters set to `a`.
210196
211−### ++ three
197+### ++ three
212198
213199 ++ three
214200 |= a/@
@@ -218,29 +204,23 @@ Let's step into each of the three arms within our core.
218204 0
219205 (add b $(b (add 3 b)))
220206
221−As above, `++three` takes an integer argument, `a`, and then
222−executes the remainder of the code with `a` set to the actual
223−arguments.
207+As above, `++three` takes an integer argument, `a`, and then executes
208+the remainder of the code with `a` set to the actual arguments.
224209
225−Similarly, `=|` ('tisbar') pushes its first child, `b` into our
226−context (in other words, it declares a variable `b`) and executes
227−the remainder of the code. However, `b` is not an argument; `=|`
228−sets `b` to the default value of whatever type it is declared as.
229−Since the default value of an atom is `0`, b is set to `0`.
210+Similarly, `=|` ('tisbar') pushes its first child, `b` into our context
211+(in other words, it declares a variable `b`) and executes the remainder
212+of the code. However, `b` is not an argument; `=|` sets `b` to the
213+default value of whatever type it is declared as. Since the default
214+value of an atom is `0`, b is set to `0`.
230215
231−<blockquote class="blockquote">
232−To produce the default value of any given type, use `$*` ('buctar') followed by the type.
233−Alternatively, use the irregular form `*`.
234−
235−```
236− > *@ :: produce the default value of atom @
237− 0
238−
239− > *@p :: produce the phonemic base of atom @
240− ~zod
241−
242−```
243−</blockquote>
216+> To produce the default value of any given type, use `$*` ('buctar')
217+> followed by the type. Alternatively, use the irregular form `*`.
218+>
219+> > *@ :: produce the default value of atom @
220+> 0
221+>
222+> > *@p :: produce the phonemic base of atom @
223+> ~zod
244224
245225So now we have two variables: `a` is set to our input, and `b` is
246226initialized to `0`.
@@ -248,42 +228,38 @@ initialized to `0`.
248228One way to think about `|-` ('barhep') is that it lays down a recursion
249229point. More on this later.
250230
251−`^-` ('kethep') is just a cast that sets the result of the remainder of
231+`^-` ('kethep') is just a cast that sets the result of the remainder of
252232the code to an unsigned integer, `@u`.
253233
254−In pseudocode, the last three lines read like this: if `a` is
255−less than `b`, produce zero. Else, add `b` to the result of
256−rerunning the segment of the function following the `|-` with the
257−value of `b` changed to `b` plus three.
234+In pseudocode, the last three lines read like this: if `a` is less than
235+`b`, produce zero. Else, add `b` to the result of rerunning the segment
236+of the function following the `|-` with the value of `b` changed to `b`
237+plus three.
258238
259−The only thing that should look completely unfamiliar to you here
260−is the `$(b (add 3 b))`, which causes us to recurse back to our
261−last recursion point with the value of `b` set to `(add 3 b)`.
262−Note that we only specify what changes (`b` in this case). If
263−you recurse by an actual function call, then you have to specify
264−every argument.
239+The only thing that should look completely unfamiliar to you here is the
240+`$(b (add 3 b))`, which causes us to recurse back to our last recursion
241+point with the value of `b` set to `(add 3 b)`. Note that we only
242+specify what changes (`b` in this case). If you recurse by an actual
243+function call, then you have to specify every argument.
265244
266−<blockquote class="blockquote">
267−If you're familiar with Clojure, `|-` is `loop` and `$()` is `recur`.
268−</blockquote>
245+> If you're familiar with Clojure, `|-` is `loop` and `$()` is `recur`.
269246
270247**Exercises**:
271248
272249Tweak your code to complete the following excercises.
273250
274−There are a few runes and some syntax that we have yet to cover that
275−you will need to complete the excercises below. For these, please
276−refer to our cheatsheat at the bottom.
251+There 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
253+our cheatsheat at the bottom.
277254
278−1. Read and understand `++five` line by line.
255+1. Read and understand `++five` line by line.
279256
280−1. Change `++sum` to accept two variables, `a` and `b`. Pass `a`
281− to `three` and `b` to `five`. Then run the code with `a` set to
282− `1.000` and `q` set to `2.000`.
257+2. Change `++sum` to accept two variables, `a` and `b`. Pass `a` to
258+ `three` and `b` to `five`. Then run the code with `a` set to `1.000`
259+ and `q` set to `2.000`.
283260
284−1. Check if this new result is under one thousand. If it is,
285− return the string `'result < 1.000'`. If not,
286− return `'result >= 1.000'`.
261+3. Check if this new result is under one thousand. If it is, return the
262+ string `'result < 1.000'`. If not, return `'result >= 1.000'`.
287263
288264### Review
289265
@@ -298,39 +274,37 @@ refer to our cheatsheat at the bottom.
298274
299275### New material
300276
301−1. There are two syntaxes for writing Hoon: tallform and wideform.
277+1. There are two syntaxes for writing Hoon: tallform and wideform.
278+
279+In tallform, expressions are formed with either two spaces or a line
280+break separating both a rune from its children and each of its children
281+from one another. We use tallform when writing multiline expressions.
302282
303− In tallform, expressions are formed with either two spaces or
304− a line break separating both a rune from its children and each
305− of its children from one another. We use tallform when writing
306− multiline expressions.
283+For more concise expressions, we use wideform, which is always a single
284+line. Wideform can be used inside tallform expressions, but not vice
285+versa.
307286
308− For more concise expressions, we use wideform, which is always
309− a single line. Wideform can be used inside tallform
310− expressions, but not vice versa.
311−
312− Wideform expressions are formed with a rune followed by `()`
313− containing its children, all of which are separated by a
314− single space. For example, to make a cell of two elements:
287+Wideform expressions are formed with a rune followed by `()` containing
288+its children, all of which are separated by a single space. For example,
289+to make a cell of two elements:
315290
316291 :-(a b)
317292
318− We've already seen wideform in action, for example with
319− `=((mod b 3) 0)`. In this case, `=` is actually an irregular form
320− of `.=`, which tests its two children for equality.
293+We've already seen wideform in action, for example with
294+`=((mod b 3) 0)`. In this case, `=` is actually an irregular form of
295+`.=`, which tests its two children for equality.
321296
322− Surrounding a function with `()` is an irregular wide form
323− syntax for calling a function with _N_ arguments. More on this later.
297+Surrounding a function with `()` is an irregular wide form syntax for
298+calling a function with *N* arguments. More on this later.
324299
325−1. `:-` makes a cell of values. The irregular wide form of this is
326− `[a b]`, with two expressions separated by a single space.
327− While the regular form of this rune takes a fixed number of
328− children (two), its irregular wide form can accept _N_ expressions:
329− `[a1..an]`
300+1. `:-` makes a cell of values. The irregular wide form of this is
301+ `[a b]`, with two expressions separated by a single space. While the
302+ regular form of this rune takes a fixed number of children (two),
303+ its irregular wide form can accept *N* expressions: `[a1..an]`
330304
331−2. Cords are one datatype for text in Hoon. They're just a big
332− atom formed from adjacent unicode bytes -- a "c string". To
333− produce a cord, enclose text within single quotes. To set the type
334− of an argument to a cord, use `@t`.
305+2. Cords are one datatype for text in Hoon. They're just a big atom
306+ formed from adjacent unicode bytes -- a "c string". To produce a
307+ cord, enclose text within single quotes. To set the type of an
308+ argument to a cord, use `@t`.
335309
336310
docs/arvo/network.md+290−320
@@ -5,369 +5,339 @@ sort: 3
55title: Network messages
66---
77
8−# Network messages
9−
10−Now we've learned enough hoon to do more interesting things.
11−Let's get our planets to talk to each other.
12−
13−All we've written up until now are just shell
14−commands that produce a value and then disappear. To listen for and receive messages from other planets, we'll need an app. Let's look at a very simple one:
15−
16−```
17−:: There is no love that is not an echo
18−::
19−:::: /hoon/echo/examples/app
20− ::
21−/? 314
22−!:
23−|_ {bowl state/$~}
24−++ poke-noun
25− |= arg/*
26− ^- {(list) _+>.$}
27− ~& [%argument arg]
28− [~ +>.$]
29−--
30−```
31−
32−
33−This is a very simple app that does only one thing. If you poke
34−it with a value, it prints that value out. To try this out, you
35−have to start the app, then you can poke it from the command line
36−with the following commands:
37−
38−```
39−~fintud-macrep:dojo> |start %echo
40−>=
41−~fintud-macrep:dojo> :examples-echo 5
42−[%argument 5]
43−>=
44−~fintud-macrep:dojo> :examples-echo [1 2]
45−[%argument [1 2]]
46−>=
47−```
48−
49−<blockquote class="blockquote">
50−There is currently a bug where the `%argument` lines are
51−printed *above* the line you entered, so your output may not
52−look exactly like this.
53−`>=` means that a command was successfully received and
54−executed.
55−</blockquote>
56−
57−Most of the app code should be simple enough to guess its
58−function. The important part of this code is the definition of
59−`++poke-noun`.
8+Network messages
9+================
10+
11+Now we've learned enough Hoon to do more interesting things. Let's get
12+our planets to talk to each other.
13+
14+All we've written up until now are just shell commands that produce a
15+value and then disappear. To listen for and receive messages from other
16+planets, we'll need an app. Let's look at a very simple one:
17+
18+ :: There is no love that is not an echo
19+ ::
20+ :::: /hoon/echo/examples/app
21+ ::
22+ /? 314
23+ !:
24+ |_ {bowl state/$~}
25+ ++ poke-noun
26+ |= arg/*
27+ ^- {(list) _+>.$}
28+ ~& [%argument arg]
29+ [~ +>.$]
30+ --
31+
32+This is a very simple app that does only one thing. If you poke it with
33+a value, it prints that value out. To try this out, you have to start
34+the app, then you can poke it from the command line with the following
35+commands:
36+
37+ ~fintud-macrep:dojo> |start %echo
38+ >=
39+ ~fintud-macrep:dojo> :examples-echo 5
40+ [%argument 5]
41+ >=
42+ ~fintud-macrep:dojo> :examples-echo [1 2]
43+ [%argument [1 2]]
44+ >=
45+
46+> There is currently a bug where the `%argument` lines are printed
47+> *above* the line you entered, so your output may not look exactly like
48+> this. `>=` means that a command was successfully received and
49+> executed.
50+
51+Most of the app code should be simple enough to guess its function. The
52+important part of this code is the definition of `++poke-noun`.
6053
6154Once an app starts, it's always running in the background and you
62−interact with it by sending it messages. The most
63−straightforward way to do that is to poke it from the command
64−line, which we we did with `:echo 5` (`:[app-name]
65−[argument(s)]).
66−
67−In this case, `++poke-noun` takes an argument `arg` and prints it
68−out with `~&`. This is an unusual rune that formally "does
69−nothing", but the interpreter detects it and printfs the first
70−child, before executing the second as if the first didn't exist.
71−This is a slightly hacky way of printing to the console, but
72−we'll get to the correct way later on.
73−
74−But what does `++poke-noun` produce? Recall that `^-` casts to a
75−type. In this case, it's declaring that end result of the
76−function will be of type `{(list) _+>.$}`. But what does this
77−mean?
78−
79−The phrase to remember is "a list of moves and our state". Urbit
80−is a message passing system, so whenever we want to do something that
81−interacts with the rest of the system, we send a message. Thus, a
82−move is arvo's equivalent of a syscall. The first thing that
83−`++poke-noun` produces is a list of messages, called
84−"moves". In this case, we don't actually want the system to do
85−anything, so we produce the empty list, `~` (in the `[~ +>.$]`
86−line).
87−
88−The second thing `++poke-noun` produces is our state. `+>.$`
89−refers to a particular address in our subject where our formal
90−app state is stored. It'll become clear why this is later on,
91−but for now pretend that `+>.$` is a magic invocation that means
92−"app state".
93−
94−Let's look at another example (edit your code in `/app/examples/echo/hoon` to reflect the code below). Say we want to only accept a
95−number, and then print out the square of that number.
96−
97−```
98−/? 314
99−!:
100−|_ {bowl state=~}
101−::
102−++ poke-atom
103− |= arg/@
104− ^- {(list) _+>.$}
105− ~& [%square (mul arg arg)]
106− [~ +>.$]
107−--
108−```
109−
110−A few things have changed. Firstly, we no longer accept
111−arbitrary nouns because we can only square atoms (integers, in
112−this case an unsigned one). Thus, our argument is now `arg/@`.
113−Secondly, it's `++poke-atom` rather than `++poke-noun`.
114−
115−# Intro to marks
116−
117−Are there other `++poke`s? Yes. In fact, `noun` and
118−`atom` are just two of arbitrarily many "marks". A mark is
119−fundamentally a type definition, but accessible at the arvo
120−level. Each mark is defined in the `/mar` directory. Some marks
121−have conversion routines to other marks, and some have diff,
122−patch, and merge algorithms. None of these are required for a
55+interact with it by sending it messages. The most straightforward way to
56+do that is to poke it from the command line, which we we did with
57+`:echo 5` (`:[app-name] [argument(s)]`).
58+
59+In 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+rune that formally "does nothing", but the interpreter detects it and
62+printfs the first child, before executing the second as if the first
63+didn't exist. This is a slightly hacky way of printing to the console,
64+but we'll get to the correct way later on.
65+
66+But what does `++poke-noun` produce? Recall that `^-` casts to a type.
67+In this case, it's declaring that end result of the function will be of
68+type `{(list) _+>.$}`. But what does this mean?
69+
70+The phrase to remember is "a list of moves and our state". Urbit is a
71+message passing system, so whenever we want to do something that
72+interacts with the rest of the system, we send a message. Thus, a move
73+is arvo's equivalent of a syscall. The first thing that `++poke-noun`
74+produces is a list of messages, called "moves". In this case, we don't
75+actually want the system to do anything, so we produce the empty list,
76+`~` (in the `[~ +>.$]` line).
77+
78+The second thing `++poke-noun` produces is our state. `+>.$` refers to a
79+particular address in our subject where our formal app state is stored.
80+It'll become clear why this is later on, but for now pretend that `+>.$`
81+is a magic invocation that means "app state".
82+
83+Let's look at another example (edit your code in
84+`/app/examples/echo/hoon` to reflect the code below). Say we want to
85+only accept a number, and then print out the square of that number.
86+
87+ /? 314
88+ !:
89+ |_ {bowl state=~}
90+ ::
91+ ++ poke-atom
92+ |= arg/@
93+ ^- {(list) _+>.$}
94+ ~& [%square (mul arg arg)]
95+ [~ +>.$]
96+ --
97+
98+A few things have changed. Firstly, we no longer accept arbitrary nouns
99+because we can only square atoms (integers, in this case an unsigned
100+one). Thus, our argument is now `arg/@`. Secondly, it's `++poke-atom`
101+rather than `++poke-noun`.
102+
103+Intro to marks
104+==============
105+
106+Are there other `++poke`s? Yes. In fact, `noun` and `atom` are just two
107+of arbitrarily many "marks". A mark is fundamentally a type definition,
108+but accessible at the arvo level. Each mark is defined in the `/mar`
109+directory. Some marks have conversion routines to other marks, and some
110+have diff, patch, and merge algorithms. None of these are required for a
123111mark to exist, however.
124112
125−`noun` and `atom` are two of dozens of predefined marks (that will
126−already be in your `/mar` directory), and the
127−user may add more at will. The type associated with `noun` is
128−`*`, and the type associated with `atom` is `@`.
113+`noun` and `atom` are two predefined marks. In your `/mar` directory,
114+there are already many more, and you may add more at will. The type
115+associated with `noun` is `*`, and the type associated with `atom` is
116+`@`.
129117
130−When we poke an app from anywhere, we do so with a mark that
131−searches for the corresponding (`++poke-[mark]`) arm. Data
132−constructed on the command line is by default marked with `noun`.
133−In this case, the app is expecting an atom, so we have to
134−explicitly mark the data with `atom` using `&[mark]`. Try the following
135−commands:
118+When we poke an app from anywhere, we do so with a mark that searches
119+for the corresponding (`++poke-[mark]`) arm. Data constructed on the
120+command line is by default marked with `noun`. In this case, the app is
121+expecting an atom, so we have to explicitly mark the data with `atom`
122+using `&[mark]`. Try the following commands:
136123
137−```
138−~fintud-macrep:dojo> |start %square
139−>=
140−~fintud-macrep:dojo> :examples-square 6
141−gall: %square: no poke arm for noun
142−~fintud-macrep:dojo> :examples-square &atom 6
143−[%square 36]
144−>=
145−```
124+ ~fintud-macrep:dojo> |start %square
125+ >=
126+ ~fintud-macrep:dojo> :examples-square 6
127+ gall: %square: no poke arm for noun
128+ ~fintud-macrep:dojo> :examples-square &atom 6
129+ [%square 36]
130+ >=
146131
147−> Recall the bug where `%square` may get printed above the input
148−> line.
132+> Recall the bug where `%square` may get printed above the input line.
149133
150−Marks are powerful, and they're the backbone of urbit's data
151−pipeline, so we'll be getting quite used to them.
134+Marks are powerful, and they're the backbone of Urbit's data pipeline,
135+so we'll be getting quite used to them.
152136
153137**Exercise**:
154138
155−- Write an app that computes fizzbuzz on its input (as in the
156− previous section).
157−
158−# Sending a message to another ship
159−
160−Let's write our first network message! Here's `/app/examples/pong.hoon`:
161−
162−```
163−/? 314
164−|%
165− ++ move {bone term wire *}
166−--
167−!:
168−|_ {bowl state=$~}
169−::
170−++ poke-urbit
171− |= to/@p
172− ^- [(list move) _+>.$]
173− [[[ost %poke /sending [to %pong] %atom 'howdy'] ~] +>.$]
174−::
175−++ poke-atom
176− |= arg/@
177− ^- (list move) _+>.$}
178− ~& [%receiving (@t arg)]
179− [~ +>.$]
180−::
181−++ coup |=(* [~ +>.$])
182−--
183−```
139+- Write an app that computes fizzbuzz on its input (as in the previous
140+ section).
141+
142+Sending a message to another urbit
143+==================================
144+
145+Let's write our first network message! Here's `/app/examples/pong.hoon`:
146+
147+ /? 314
148+ |%
149+ ++ move {bone term wire *}
150+ --
151+ !:
152+ |_ {bowl state=$~}
153+ ::
154+ ++ poke-urbit
155+ |= to/@p
156+ ^- [(list move) _+>.$]
157+ [[[ost %poke /sending [to %pong] %atom 'howdy'] ~] +>.$]
158+ ::
159+ ++ poke-atom
160+ |= arg/@
161+ ^- (list move) _+>.$}
162+ ~& [%receiving (@t arg)]
163+ [~ +>.$]
164+ ::
165+ ++ coup |=(* [~ +>.$])
166+ --
184167
185168Run it with these commands:
186169
187−```
188−~fintud-macrep:dojo> |start %examples-pong
189−>=
190−~fintud-macrep:dojo> :pong &examples-urbit ~sampel-sipnym
191−>=
192−```
170+ ~fintud-macrep:dojo> |start %examples-pong
171+ >=
172+ ~fintud-macrep:dojo> :pong &examples-urbit ~sampel-sipnym
173+ >=
193174
194−Replace `~sampel-sipnym` with another urbit. The easiest thing to
195−do is to start a moon, a sub-identity of your urbit. If you don't know how to start a moon, see [the user admin section](/docs/using/admin/) Don't
196−forget to start the `%examples-pong` app on that urbit too. You should
175+Replace `~sampel-sipnym` with another urbit. The easiest thing to do is
176+to start a moon, a sub-identity of your urbit. If you don't know how to
177+start a moon, see [the user admin section](/docs/using/admin/). Don't
178+forget to start the `%examples-pong` app on that urbit, too. You should
197179see, on the foreign urbit, this output:
198180
199−```
200−[%receiving 'howdy']
201−```
181+ [%receiving 'howdy']
202182
203−Most of the code should be straightforward. In `++poke-atom`,
204−the only new thing is the expression `(@t arg)`. As we already
205−know, `@t` is the type of "cord" text strings. In Hoon, when types are called as functions, they serve as a validator function (called a "clam" in hoon) -- that is, a function whose domain is all nouns and range is the given type.
183+Most of the code should be straightforward. In `++poke-atom`, the only
184+new thing is the expression `(@t arg)`, which is the type `@t` being
185+called as a function with argument `arg`. As we already know, `@t` is
186+the type of "cord" text strings. In Hoon, when types are called as
187+functions, they serve as a validator function called a "clam" -- that
188+is, a function whose domain is all nouns, and range is the given type
189+(in this case, `@t`).
206190
207−In simpler terms, if a validator function is passed a value that
208−falls within its type, that value is produced. Otherwise, it
209−produces the default value (aka the "bunt") of its type. Here we call
210−this `@t` function on the argument. This coerces the argument
211−to text, so that we can print it out prettily no matter what
212−we're passed.
191+In simpler terms, if a clam is passed a value of its own type, it
192+produces that value. Otherwise, it produces the default value (aka the
193+"bunt") of its type. Here we call this `@t` function on the argument.
194+This coerces the argument to text, so that we can print it out prettily
195+no matter what we're passed.
213196
214−The more interesting part is in `++poke-urbit`. The `urbit` mark
215−is an urbit identity, and the hoon type associated with it is
216−`@p` (the "p" stands for "phonetic base").
197+The more interesting part is in `++poke-urbit`. The `urbit` mark is an
198+urbit identity, and the Hoon type associated with it is `@p` (the "p"
199+stands for "phonetic base").
217200
218201Recall that in a `++poke` arm we produce "a list of moves and our
219−state". Until now, we've left the list of moves empty, since we
220−haven't wanted to tell arvo to do anything in particular. Now we
221−want to send a message to another urbit. Thus, we produce a list
222−with one element:
202+state". Until now, we've left the list of moves empty, since we haven't
203+wanted to tell arvo to do anything in particular. Now we want to send a
204+message to another urbit. Thus, we produce a list with one element:
223205
224−```
225−[ost %poke /sending [to-urbit-address %pong] %atom 'howdy']
226−```
206+ [ost %poke /sending [to-urbit-address %pong] %atom 'howdy']
227207
228208### Moves
229209
230−The general form of a move is
231−
232−-arvo part---->
233−`[bone term wire *]`
234−
235−------------------------->app/vane-specific part of move
210+The general form of a move is `[bone term wire *]`.
236211
237212Or, in pseudo-code:
238213
239−`["cause" sys-call/action tack-new-layer-on-cause action-specific
240−information]`
214+`["cause" sys-call/action tack-new-layer-on-cause action-specific information]`
241215
242216Let's walk through each of these elements step by step.
243217
244218#### Bones ("cause")
245219
246−If you look up `++bone` in `hoon.hoon`, you'll see that it's a
247−number (`@ud`), and that it's an opaque reference to a duct.
248−`++duct` in hoon.hoon is a list of `wire`s, where `++wire` is an
249−alias for `++path`. `++path` is a list of `++span`s, which are ASCII
250−text. Thus, a duct is a list of paths, and a bone is an opaque
251−reference to it (in the same way that a Unix file
252−descriptor is an opaque reference to a file structure). Thus, to
253−truly understand bones, we must understand ducts.
254−
255−A duct is stack of causes, again, represented as paths, which are
256−called wires. At the bottom of every duct is a unix event, such
257−as a keystroke, network packet, file change, or timer event.
258−When arvo is given this event, it routes the event to appropriate
259−kernel module for handling.
260−
261−Sometimes, the module can immediately handle the event and
262−produce any necessary results. For example, when we poked the
263−`++poke-atom` arm above, we poked %gall, our application server,
264−which was able to respond to our poke directly. When the module
265−cannot service the request itself, it sends instructions to another kernel
266−module or application (the the %gall module) to do a specified action, and produces the result from that.
267−
268−Furthermore, when one module sends a message to another kernel module or application, it also sends along the duct it was given
269−with its new wire tacked onto the end. Now the duct has two entries,
270−with the unix even on the bottom and the kernel module that
271−handled it next. This process can continue indefinitely, adding
272−more and more layers onto the duct. When an entity finally
273−produces a result, a layer is popped off the duct, and the result
274−is passed all the way back down.
275−
276−In effect, a duct is an arvo-level call stack. It's worth noting
277−that while in traditional call stacks a function call happens
278−synchronously and returns exactly once. In arvo, multiple moves
279−can be sent at once, are evaluated asynchronously, and each
280−one may be responded to zero or more times.
220+If 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+hoon.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+list of paths, and a bone is an opaque reference to it (in the same way
225+that a Unix file descriptor is an opaque reference to a file structure).
226+Thus, to truly understand bones, we must understand ducts.
227+
228+A duct is stack of causes, again, represented as paths, which are called
229+wires. At the bottom of every duct is a unix event, such as a keystroke,
230+network packet, file change, or timer event. When arvo is given this
231+event, it routes the event to appropriate kernel module for handling.
232+
233+Sometimes, the module can immediately handle the event and produce any
234+necessary results. For example, when we poked the `++poke-atom` arm
235+above, we poked %gall, our application server, which was able to respond
236+to our poke directly. When the module cannot service the request itself,
237+it sends instructions to another kernel module or application (the the
238+%gall module) to do a specified action, and produces the result from
239+that.
240+
241+Furthermore, when one module sends a message to another kernel module or
242+application, it also sends along the duct it was given with its new wire
243+tacked onto the end. Now the duct has two entries, with the unix even on
244+the bottom and the kernel module that handled it next. This process can
245+continue indefinitely, adding more and more layers onto the duct. When
246+an entity finally produces a result, a layer is popped off the duct, and
247+the result is passed all the way back down.
248+
249+In effect, a duct is an arvo-level call stack. It's worth noting that
250+while in traditional call stacks a function call happens synchronously
251+and returns exactly once. In arvo, multiple moves can be sent at once,
252+are evaluated asynchronously, and each one may be responded to zero or
253+more times.
281254
282255The point to take home is that whatever caused `++poke-urbit` to be
283−called is also the root cause for the network message we're
284−trying to send. Thus, we say to send the network message along the given bone
256+called is also the root cause for the network message we're trying to
257+send. Thus, we say to send the network message along the given bone
285258`ost`.
286259
287260##### Wire ('tack on new layer to duct')
288261
289−Of course, we have to push a new layer onto our duct
290−before passing it along (or responding to it directly) anywhere. This
291−layer can have any data we want in it, but we don't need anything
292−specific here, so we just use the wire `/sending`
293−(`/elem1/elem2/elem n` is one syntax used to create `++path`s and
294−`++wire`s of n elements). If we were expecting a response (which
295−we're not), it would come back along the `/sending` wire, meaning
296−that the path `/sending` will be passed back to the response
297−handler as an argument. Although it's not required, it's
298−generally a good idea to make the wire human-readable for
299−bug-handling purposes.
262+Of course, we have to push a new layer onto our duct before passing it
263+along (or responding to it directly) anywhere. This layer can have any
264+data we want in it, but we don't need anything specific here, so we just
265+use the wire `/sending` (`/elem1/elem2/elemN` is one syntax used to
266+create `++path`s and `++wire`s of N elements). If we were expecting a
267+response (which we're not), it would come back along the `/sending`
268+wire, meaning that the path `/sending` will be passed back to the
269+response handler as an argument. Although it's not required, it's
270+generally a good idea to make the wire human-readable for bug-handling
271+purposes.
300272
301273##### Term (sys-call)
302274
303−Looking back at the general form of a move, there is a
304−`term`--which is text composed lowercase ascii and `-`, and has
305−the sign of `@tas`-- which in this case is `%poke`. This is the
306−name of the particular kind of move we're sending. If you think
307−of a move as a syscall (which you should), then this `term` is
308−the name of the syscall. Common ones include: `%poke`, to
309−message an app; `%warp`, to read from the filesystem; `%wait`, to
310−set a timer; and `%them`, to send an http request.
311−
312−The general form ends with `*` (a noun) since each type of move takes
313−different data. In our case, a `%poke` move takes a target
314−(urbit and app) and marked data and pokes the arm of the
315−corresponding mark on that app on that urbit
316−with that data. `[to-urbit-address %pong]` is the target urbit and app,
317−`%atom` is the mark`, and `'howdy'` is the data.
318−
319−When arvo receives a `%poke` move, it calls the appropriate
320−`++poke`. The same mechanism is used for sending messages
321−between apps on the same urbit as for sending messages between
322−apps on different urbits.
323−
324−<blockquote class="blockquote">
325−We said earlier that we're not expecting a response. This is
326−not entirely true: the `++coup` is called when we receive
327−acknowledgment that the `++poke` was called. We don't do
328−anything with this information right now, but we could.
329−</blockquote>
275+Each move also has a `term`, composed of lowercase ASCII and/or `-`.
276+This `term` has the sign `@tas`. In this case, out `term` is `%poke`,
277+which is the name of the particular kind of move we're sending. You can
278+always use `%poke` to message an app. Other common names include
279+`%warp`, to read from the filesystem; `%wait`, to set a timer; and
280+`%them`, to send an http request.
281+
282+The move ends with `*` (that is, any noun) since each type of move takes
283+different data. In our case, a `%poke` move takes a target (urbit and
284+app) and marked data, then pokes the arm of the corresponding mark on
285+that 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+
288+When arvo receives a `%poke` move, it calls the appropriate `++poke`.
289+The same mechanism is used for sending messages between apps on the same
290+urbit as for sending messages between apps on different urbits.
291+
292+> We said earlier that we're not expecting a response. This is not
293+> entirely true: the `++coup` is called when we receive acknowledgment
294+> that the `++poke` was called. We don't do anything with this
295+> information right now, but we could.
330296
331297**Exercises**:
332298
333−- Extend either of the apps in the first two exercises to accept
334− input over the network in the same way as `pong`.
335−
336−- Modify `examples-pong` to print out a message when it receives acknowledgement.
337−
338−- Write two apps, `even` and `odd`. When you pass an atom to
339− `even`, check whether it's even. If so, divide it by two and
340− recurse; otherwise, poke `odd` with it. When `odd` recieves
341− an atom, check whether it's equal to one. If so, terminate,
342− printing "%success". Otherwise, check whether it's odd. If
343− so, multiply it by three, add one, and recurse; otherwise, poke
344− `even` with it. When either app receives a number, print it out along with the name of the app. In the end, you should be able to watch Collatz's
345− conjecture play out between the two apps. Sample output:
346−
347−```
348−~fintud-macrep:dojo> :even &atom 18
349−[%even 18]
350−[%odd 9]
351−[%even 28]
352−[%even 14]
353−[%odd 7]
354−[%even 22]
355−[%odd 11]
356−[%even 34]
357−[%odd 17]
358−[%even 52]
359−[%even 26]
360−[%odd 13]
361−[%even 40]
362−[%even 20]
363−[%even 10]
364−[%odd 5]
365−[%even 16]
366−[%even 8]
367−[%even 4]
368−[%even 2]
369−%success
370−```
371−
372−- Put `even` and `odd` on two separate ships and pass the
373− messages over the network.
299+- Extend either of the apps in the first two exercises to accept input
300+ over the network in the same way as `pong`.
301+
302+- Modify `examples-pong` to print out a message when it receives
303+ acknowledgement.
304+
305+- 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+ otherwise, poke `odd` with it. When `odd` recieves an atom, check
308+ 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+ one, and recurse; otherwise, poke `even` with it. When either app
311+ receives a number, print it out along with the name of the app. In
312+ the end, you should be able to watch Collatz's conjecture play out
313+ between the two apps. Sample output:
314+
315+<!-- -->
316+
317+ ~fintud-macrep:dojo> :even &atom 18
318+ [%even 18]
319+ [%odd 9]
320+ [%even 28]
321+ [%even 14]
322+ [%odd 7]
323+ [%even 22]
324+ [%odd 11]
325+ [%even 34]
326+ [%odd 17]
327+ [%even 52]
328+ [%even 26]
329+ [%odd 13]
330+ [%even 40]
331+ [%even 20]
332+ [%even 10]
333+ [%odd 5]
334+ [%even 16]
335+ [%even 8]
336+ [%even 4]
337+ [%even 2]
338+ %success
339+
340+- 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+ receive a cookie.
343+
docs/arvo/state.md+87−95
@@ -5,108 +5,100 @@ sort: 4
55title: State
66---
77
8−# State
9−
10−In the last section we built a few small apps that sent moves.
11−These apps were entirely stateless, however. Most useful apps
12−require some amount of state. Let's build a trivial stateful
13−app. It'll keep a running the sum of all the atoms we poke it with.
14−Here's `app/examples/sum.hoon`:
15−
16−```
17−/? 314
18−!:
19−|_ {bowl state/@}
20−++ poke-atom
21− |= arg/@
22− ^- {(list) _+>.$}
23− ?: =(arg 0)
24− [~ +>.$(state 0)]
25− ~& [%so-far (add state arg)]
26− [~ +>.$(state (add state arg))]
27−--
28−```
8+State
9+=====
10+
11+In the last section we built a few small apps that sent moves. These
12+apps were entirely stateless, however. Most useful apps require some
13+amount of state. Let's build a trivial stateful app. It'll keep a
14+running the sum of all the atoms we poke it with. Here's
15+`app/examples/sum.hoon`:
16+
17+ /? 314
18+ !:
19+ |_ {bowl state/@}
20+ ++ poke-atom
21+ |= arg/@
22+ ^- {(list) _+>.$}
23+ ?: =(arg 0)
24+ [~ +>.$(state 0)]
25+ ~& [%so-far (add state arg)]
26+ [~ +>.$(state (add state arg))]
27+ --
2928
3029We can start it with `|start %examples-sum`, and then run it:
3130
32−```
33−~fintud-macrep:dojo> :examples-sum &atom 5
34−[%so-far 5]
35−>=
36−~fintud-macrep:dojo> :examples-sum &atom 2
37−[%so-far 7]
38−>=
39−~fintud-macrep:dojo> :examples-sum &atom 15
40−[%so-far 22]
41−>=
42−```
43−
44−We can see that app state is being saved, but when, where, and
45−how?
46−
47−The state is stored as the second thing in the `|_` line. In our
48−case, it's simply an atom named `state`. We change it by
49−producing as our state not with `+>.$` (as before), but with `+>.$(state (add state arg))`. We've seen all these parts before, but you might not
50−recognize them.
31+ ~fintud-macrep:dojo> :examples-sum &atom 5
32+ [%so-far 5]
33+ >=
34+ ~fintud-macrep:dojo> :examples-sum &atom 2
35+ [%so-far 7]
36+ >=
37+ ~fintud-macrep:dojo> :examples-sum &atom 15
38+ [%so-far 22]
39+ >=
40+
41+We can see that app state is being saved, but when, where, and how?
42+
43+The state is stored as the second thing in the `|_` line. In our case,
44+it's simply an atom named `state`. We change it by producing as our
45+state not with `+>.$` (as before), but with
46+`+>.$(state (add state arg))`. We've seen all these parts before, but
47+you might not recognize them.
5148
5249Recall in the first chapter that we recursed with the expression
53−`$(b (add 3 b))`. This meant "produce `$` with `b` changed to
54−`(add 3 b)`. Similarly, `+>.$(state (add state arg))` means
55−"produce `+>.$` (i.e. our context, which contains our state) with
56−`state` changed to `(add state arg)`.
57−
58−At a high level, then, when we handle state, we do it explicitly.
59−It's passed in and produced explicitly. In Unix systems,
60−application state is just a block of memory, which you need to
61−serialize to disk if you want to keep it around for very long.
62−
63−In urbit, app state is a single (usually complex) value. In our
64−example, we have very simple state, so we defined `state=@`,
65−meaning that our state is an atom. Of course, `state` is just a
66−name we're assigning to it, and you're free to use whatever name
67−you want.
68−
69−There are at least two points you may be wondering about. First, `bowl` is a set of general global state that is managed by the system. It
70−includes things like `now` (current time), `our` (our urbit
71−identity), and `eny` (256 bits of guaranteed-fresh entropy). For
72−the full list of things in `++bowl`, search for `++ bowl` (note
73−the double space) in `/arvo/zuse.hoon`.
74−
75−<blockquote class="blockquote">
76−This is a very common technique in learning hoon. While
77−documentation exists, often the easiest way to learn about an
78−identifier you see in code is to search in `/arvo/zuse.hoon`
79−and `/arvo/hoon.hoon` for it. These are our two "standard
80−libraries", and they're usually not hard to read. Since
81−urbit's codebase is relatively small (those two files are less
82−than 15000 lines of code combined, and besides the standard
83−library they include the hoon parser and compiler, plus the
84−/arvo microkernel), you can usually use the code and the
85−comments as reference doc.
86−</blockquote>
87−
88−The second thing is that urbit needs no "serialize to disk" step.
89−Everything you produce in the app state is persistent across
90−calls to the app, restarts of the urbit, and even power failure.
91−If you want to write to the filesystem, you can, but it's not
92−needed for persistence. Urbit has transactional events, which
93−makes it an [ACID operating system](https://en.wikipedia.org/wiki/ACID). Thus, you don't have to
94−worry about persistence when programming in urbit or to ever go
95−through the hassle of having to set up and write to a database.
50+`$(b (add 3 b))`. This meant "produce `$` with `b` changed to
51+`(add 3 b)`. Similarly, `+>.$(state (add state arg))` means "produce
52+`+>.$` (i.e. our context, which contains our state) with `state` changed
53+to `(add state arg)`.
54+
55+At a high level, then, when we handle state, we do it explicitly. It's
56+passed in and produced explicitly. In Unix systems, application state is
57+just a block of memory, which you need to serialize to disk if you want
58+to keep it around for very long.
59+
60+In Urbit, app state is a single (usually complex) value. In our example,
61+we have very simple state, so we defined `state=@`, meaning that our
62+state is an atom. Of course, `state` is just a name, and you're free to
63+name your state whatever you like. But let's clarify a couple other
64+things before we continue.
65+
66+First, `bowl` is a set of general global states. This set is managed by
67+the system. It includes things like `now` (the current time), `our` (our
68+urbit identity), and `eny` (256 bits of guaranteed-fresh entropy). For
69+the full list of things in `++bowl`, search for `++ bowl` (note: two
70+spaces) in `/arvo/zuse.hoon`.
71+
72+> This is, perhaps, the most common way to learn Hoon. The easiest way
73+> to learn about an identifier you see in code is to search in
74+> `/arvo/zuse.hoon` and `/arvo/hoon.hoon` for it.\
75+> These "standard libraries" are usually simple to read. Since Urbit's
76+> codebase is less than 15000 lines of code combined, including the hoon
77+> parser, the compiler, and the `/arvo` microkernel, you can usually use
78+> the code and its comments as a reference doc.
79+>
80+> You can also read
81+> [zuse.hoon](https://github.com/urbit/arvo/blob/master/arvo/zuse.hoon)
82+> and
83+> [hoon.hoon](https://github.com/urbit/arvo/blob/master/arvo/hoon.hoon)
84+> in your browser.
85+
86+The second thing we should clear up is this: Urbit needs no "serialize
87+to disk" step. Everything you produce in the app state is persistent
88+across calls to the app, restarts of the urbit, and even power failure.
89+If you want to write to the Unix filesystem, you can, but it's not
90+needed for persistence. Urbit has transactional events, which makes it
91+an [ACID operating system](https://en.wikipedia.org/wiki/ACID). Thus,
92+you don't have to worry about persistence when programming in Urbit, or
93+ever go through the hassle of having to set up and write to a database.
9694
9795**Exercises**:
9896
99−- Modify `:examples-sum` to reset the counter when you poke it with zero.
97+- Modify `:examples-sum` to reset the counter when you poke it with 0.
10098
101−- Write an app that prints out the previous value you poked it
102− with. Sample output:
99+- Write an app that prints out the previous value you poked it with.
100+ Sample output:
103101
104−```
105−~fintud-macrep:dojo> :examples-last 7
106−[%last 0]
107−>=
108−~fintud-macrep:dojo> :examples-last [1 2 3]
109−[%last 7]
110−>=
111−~fintud-macrep:dojo> :examples-last 'howdy'
112−[%last [1 2 3]]
102+\`\`\` \~fintud-macrep:dojo\> :examples-last 7 [%last 0] \>=
103+\~fintud-macrep:dojo\> :examples-last [1 2 3][%last 7] \>=
104+\~fintud-macrep:dojo\> :examples-last 'howdy' [%last [1 2 3]]
docs/arvo/subject.md+86−85
@@ -5,101 +5,102 @@ next: true
55title: The subject
66---
77
8−# The subject
8+The subject
9+===========
910
10−Now we're going to cover the boiler plate that we skimmed over
11−earlier.
11+Now we're going to cover the boiler plate that we skimmed over earlier.
1212
1313 :- %say |= *
1414 :- %noun
1515 =< (sum [1.000 2.000])
16−
17−This program is a cell of two elements: the first, `%say`, tells
18−the interpreter what to produce--in this case a value.
19−
20−The second element is `|=`, which we know produces a function.
21−`|=`'s first child is its argument(s), which in this case is any
22−noun (`*`). Its second child is the remainder of the program.
23−
24−Similarly, the rest of the program is a cell of the literal
25−`%noun`, which tells the shell that we're producing a value of
26−type `noun`, and the code that we run to actually produce our value of the type `noun`.
27−
28−`=<` is a rune that takes two children. The second child is the
29−context against which we run the first child. So in this case, we
30−are running the expression `(sum 1.000)` against everything
31−contained within the `|%`. In Hoon, we call the code executed the
32−"formula" and its context the "subject".
33−
34−```
35−::::::::::::::::::::::::::::::
36−=< (sum 1.000) :: formula
37−::::::::::::::::::::::::::::::
38−|% ::
39−++ three ::
40− |= a/@ ::
41− =| b/@ ::
42− |- ^- @u ::
43− ?: (lth a b) ::
44− 0 ::
45− (add b $(b (add 3 b))) ::
46− ::
47−++ five ::
48− |= a/@ :: subject
49− =| b/@ ::
50− |- ^- @ ::
51− ?: (lte a b) ::
52− 0 ::
53− ?: =((mod b 3) 0) ::
54− $(b (add b 5)) ::
55− (add b $(b (add b 5))) ::
56− ::
57−++ sum ::
58− |= a/@u ::
59− (add (five a) (three a)) ::
60−-- ::
61−::::::::::::::::::::::::::::::
62−```
63−
64−In nearly every language there is a similar concept of a
65−"context" in which expressions are executed. For example, in C
66−this includes things like the call stack, stack variables, and so
67−on.
68−
69−Hoon is unique in that this context is a first-class value.
70−Scheme allows a sort of reification of the context through
71−continutations, and some may see a parallel to Forth's stack, but
72−Hoon takes takes the concept one step further.
73−
74−Our starting subject is the standard library, which is defined in
75−`/arvo/hoon.hoon` and `/arvo/zuse.hoon`. This is where functions
76−like `add` are defined. When we define a core with `|%`, we
77−don't throw away the subject (i.e. the standard library); rather,
78−we stack the new core on top of the old subject so that both are
16+
17+The first rune, `:-` (colhep, aka
18+[:cons](/hoon/twig/col-cell/hep-cons/)), constructs the 2-element cell
19+that will be our program. The first element, `%say`, tells the
20+interpreter what to produce--in this case a value.
21+
22+The second element is `|=`, which we know produces a function. `|=`'s
23+first child is its argument(s), which in this case is any noun (`*`).
24+Its second child is the remainder of the program.
25+
26+Similarly, the rest of the program (which we construct with another
27+`:-`) is a cell of the literal `%noun`, which tells the shell that we're
28+producing a value of type `noun`, and the code that we run to actually
29+produce our value of the type `noun`.
30+
31+`=<` ([tisgal](/hoon/twig/tis-flow/gal-rap/)) is a rune that takes two
32+children. The second child is the context against which we run the first
33+child. So in this case, we are running the expression
34+`(sum [1.000 2.000])` against everything contained within the `|%`. In
35+Hoon, we call the code executed the "formula" and its context the
36+"subject".
37+
38+ ::::::::::::::::::::::::::::::
39+ =< (sum [1.000 2.000]) :: formula
40+ ::::::::::::::::::::::::::::::
41+ |% ::
42+ ++ three ::
43+ |= a/@ ::
44+ =| b/@ ::
45+ |- ^- @u ::
46+ ?: (lth a b) ::
47+ 0 ::
48+ (add b $(b (add 3 b))) ::
49+ ::
50+ ++ five ::
51+ |= a/@ :: subject
52+ =| b/@ ::
53+ |- ^- @ ::
54+ ?: (lte a b) ::
55+ 0 ::
56+ ?: =((mod b 3) 0) ::
57+ $(b (add b 5)) ::
58+ (add b $(b (add b 5))) ::
59+ ::
60+ ++ sum ::
61+ |= a/@u ::
62+ (add (five a) (three a)) ::
63+ -- ::
64+ ::::::::::::::::::::::::::::::
65+
66+In nearly every language there is a similar concept of a "context" in
67+which expressions are executed. For example, in C this includes things
68+like the call stack, stack variables, and so on.
69+
70+Hoon is unique in that this context is a first-class value. Scheme
71+allows a sort of reification of the context through continutations, and
72+some may see a parallel to Forth's stack, but Hoon takes takes the
73+concept one step further.
74+
75+Our starting subject is the [standard library](/hoon/library), which is
76+defined in `/arvo/hoon.hoon` and `/arvo/zuse.hoon`. This is where
77+functions like `add` are defined. When we define a core with `|%`, we
78+don't throw away the subject (i.e. the standard library); rather, we
79+stack the new core on top of the old subject so that both are
7980accessible.
8081
8182**Exercises**:
8283
83−- Pass `++sum` its arguments (`2000` and `3000`) from the
84− commandline.
84+- Pass `++sum` its arguments (`2.000` and `3.000`) from the
85+ commandline.
8586
86−- Comment out all of the arms of the `|%`. Now add another arm
87− and call it `++add`, have it accept two arguments and procduce
88− 42 (regardless of input). Change the `=<` line to `[(add 5 7)
89− (^add 5 7)]`. Can you recognize what's happening?
87+- Comment out all of the arms of the `|%`. Now add another arm and
88+ call it `++add`, have it accept two arguments and procduce 42
89+ (regardless of input). Change the `=<` line to
90+ `[(add 5 7) (^add 5 7)]`. Can you recognize what's happening?
9091
9192Cheatsheet:
9293
93−- To pass arguments from the command line to a program, you
94− replace the `*` in the first line of the boiler plate to
95− `{^ {{arg/TYPE ~} ~}}` where `TYPE` is replaced with the
96− type of argument you're expecting. Then `+euler1 a` from
97− the dojo sets `arg` to `a`.
98−- The empty list is `~`
99−- Lisp-style cons (construct a cell/prepend an element) is
100− `[new-element list]`
101−- For example, the first three positive integers are `[1 2 3
102− ~]`
103−- `gte` tests whether `a` is greater than or equal to `b`.
104−- `mod` runs the modulo operation on two atoms.
105−- See the basic math section in `/arvo/hoon.hoon` for more info.
94+- To pass arguments from the command line to a program, you replace
95+ the `*` in the first line of the boiler plate to
96+ `{^ {{arg/TYPE ~} ~}}` where `TYPE` is replaced with the type of
97+ argument you're expecting. Then `+euler1 a` from the dojo sets `arg`
98+ to `a`.
99+- The empty list is `~`
100+- Lisp-style cons (construct a cell/prepend an element) is
101+ `[new-element list]`
102+- For example, the first three positive integers are `[1 2 3 ~]`
103+- `(gte a b)` tests whether `a` is greater than or equal to `b`.
104+- `(mod a b)` runs the modulo operation on two atoms.
105+- See the basic math section in `/arvo/hoon.hoon` for more info.
106+
docs/arvo/subscriptions.md+234−243
@@ -5,273 +5,264 @@ sort: 5
55title: Subscriptions
66---
77
8−We've dealt fairly extensively with "poke" messages to an app,
9−but these are somewhat limited. A poke is a one-way message, but
10−more often we want to subscribe to updates from another app. You
11−could build a subscription model out of one-way pokes, but it's
12−such a common pattern that it's built into arvo.
13−
14−Let's take a look at two apps, `:examples-source` and `:examples-sink`. First,
15−`:examples-source`:
16−
17−```
18−/? 314
19−!:
20−|%
21−++ move {bone $diff mark *}
22−--
23−|_ {hid/bowl state/$~}
24−++ poke-noun
25− |= arg/*
26− ^- {(list move) _+>.$}
27− :_ +>.$
28− %+ turn (prey /the-path hid)
29− |=({o/bone *} `move`[o %diff %noun arg])
30−++ peer
31− |= pax/path
32− ^- {(list move) _+>.$}
33− ~& [%subscribed-to pax=pax]
34− [~ +>.$]
35−--
36−```
8+# Subscriptions
9+
10+We've dealt fairly extensively with "poke" messages to an app, but these
11+are somewhat limited. A poke is a one-way message, but more often we
12+want to subscribe to updates from another app. You could build a
13+subscription model out of one-way pokes, but it's such a common pattern
14+that it's built into arvo.
15+
16+Let's take a look at two apps, `:examples-source` and `:examples-sink`.
17+First, `:examples-source`:
18+
19+ /? 314
20+ !:
21+ |%
22+ ++ move {bone $diff mark *}
23+ --
24+ |_ {hid/bowl state/$~}
25+ ++ poke-noun
26+ |= arg/*
27+ ^- {(list move) _+>.$}
28+ :_ +>.$
29+ %+ turn (prey /the-path hid)
30+ |=({o/bone *} `move`[o %diff %noun arg])
31+ ++ peer
32+ |= pax/path
33+ ^- {(list move) _+>.$}
34+ ~& [%subscribed-to pax=pax]
35+ [~ +>.$]
36+ --
3737
3838And secondly, `:examples-sink`:
3939
40−```
41−/? 314
42−|%
43−++ move {bone card}
44−++ card
45− $% {$peer wire {@p term} path}
46− {$pull wire {@p term} $~}
47− ==
48−--
49−!:
50−|_ {bowl available/?}
51−++ poke-noun
52− |= arg/*
53− ^- {(list move) _+>.$}
54− ?: &(=(%on arg) available)
55− [[[ost %peer /subscribe [our %source] /the-path] ~] +>.$(available |)]
56− ?: &(=(%off arg) !available)
57− [[[ost %pull /subscribe [our %source] ~] ~] +>.$(available &)]
58− ~& ?:(available %not-subscribed %subscribed)
59− [~ +>.$]
60−++ diff-noun
61− |= {wir/wire arg/*}
62− ^- {(list move) _+>.$}
63− ~& [%recieved-data arg]
64− [~ +>.$]
65−++ reap
66− |= {wir/wire error/(unit tang)}
67− ^- {(list move) _+>.$}
68− ?~ error
69− ~& %successfully-subscribed
70− [~ +>.$]
71− ~& [%subscription-failed error]
72− [~ +>.$]
73−--
74−```
40+ /? 314
41+ |%
42+ ++ move {bone card}
43+ ++ card
44+ $% {$peer wire {@p term} path}
45+ {$pull wire {@p term} $~}
46+ ==
47+ --
48+ !:
49+ |_ {bowl available/?}
50+ ++ poke-noun
51+ |= arg/*
52+ ^- {(list move) _+>.$}
53+ ?: &(=(%on arg) available)
54+ [[[ost %peer /subscribe [our %source] /the-path] ~] +>.$(available |)]
55+ ?: &(=(%off arg) !available)
56+ [[[ost %pull /subscribe [our %source] ~] ~] +>.$(available &)]
57+ ~& ?:(available %not-subscribed %subscribed)
58+ [~ +>.$]
59+ ++ diff-noun
60+ |= {wir/wire arg/*}
61+ ^- {(list move) _+>.$}
62+ ~& [%recieved-data arg]
63+ [~ +>.$]
64+ ++ reap
65+ |= {wir/wire error/(unit tang)}
66+ ^- {(list move) _+>.$}
67+ ?~ error
68+ ~& %successfully-subscribed
69+ [~ +>.$]
70+ ~& [%subscription-failed error]
71+ [~ +>.$]
72+ --
7573
7674Cheat sheet:
7775
78−```
79−- `&` can either be the boolean true (along with `%.y`, `0`), or
80− the irregular wide form of the `$&` rune, which computes the
81− logical 'and' operation on its two children.
82−
83−- Similar to `&`,`|` is either the boolean false (along with `%.n` and `1`), or
84− the irregular short for of `?|`, which computes the logical 'or' operation on
85− its two children
86−
87−- `!` is the irregular wide form of `?!`, which computes the logical `not` on
88− its child.
89−
90−- `?~` is basically an if-then-else statement that checks whether condition `p`
91− is `~` (null). `?~` is slightly different to `?:(~ %tru %fal) in that it
92− reduces to ?:($=(%type value) %tru %false). `$=` tests whether value `q`
93− falls within type `p`. One thing to watch out for in hoon: if you do `?~`, it
94− affects the type of the conditional value: XXexample
95−
96−- `:_` is just an inverted `:-`: all it does is accept children `p` and `q` and
97− produce an inverted tuple of the two, `[q p]`.
98−
99−- `++bowl` is the type of our system state within our app. For example, it
100− includes things like `our`, the ship name of the host, and `now`, the
101− current time.
102−
103−- `$%` is a type constructor that defines a type composed of `n`
104− types that it is passed. For example `$% @ * ^ ==` is the
105− type of either `@`, `*`, or a cell `^`. XX this a union, right?
106−
107−- You may have noticed the separate `|%` above the application
108− core `|_`. We usually put our types in another core on top of the
109− application core. We can access these type from our `|_`
110− because in hoon.hoon files, all cores are =>'ed (called) against
111− each other. Thus the `|%` with the types is in the context of
112− the `|_`, as it lies above it: hoon.hoon `=> |% w types =>
113− |_`
114−
115−
116−```
76+- `&` (pam) can either be the boolean true (as can `%.y`, `0`), or
77+ the irregular wide form of the `?&`
78+ ([wutpam](/hoon/twig/wut-test/pam-and)) rune, which computes
79+ logical `AND` on its two children.
80+
81+- Similar to `&`,`|` is either the boolean false (along with `%.n` and
82+ `1`), or the irregular short for of `?|`
83+ ([wutbar](/hoon/twig/wut-test/bar-or)), which computes logical `OR`
84+ on its two children.
85+
86+- `!` is the irregular wide form of `?!`
87+ ([wutzap](/hoon/twig/wut-test/zap-not/)), which computes logical
88+ `NOT` on its child.
89+
90+- `?~` ([wutsig](/hoon/twig/wut-test/sig-ifno/)) is basically an
91+ if-then-else that checks whether condition `p` is `~` (null). `?~`
92+ is slightly different from `?:(~ %tru %fal)` in that `?~` reduces to
93+ `?:($=(%type value) %tru %false)`. `$=`
94+ ([buctis](/hoon/twig/buc-mold/tis-coat/)) tests whether value `q` is
95+ of type `p`.
96+ <!--One thing to watch out for in hoon: if you do `?~`, it
97+ affects the type of the conditional value: XXexample-->
98+
99+- `:_` ([colcab](/hoon/twig/col-cell/cab-scon/)) is inverted `:-`: it
100+ accepts `p` and `q`, and produces `[q p]`.
101+
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,
104+ and `now`, the current time.
105+
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
108+ passed. For example `$% @ * ^ ==` is the type of either `@`,
109+ `*`, or a cell `^`. <!--XX this is a union, right?-->
110+
111+- You may have noticed the separate `|%`
112+ ([barcen](/hoon/twig/bar-core/cen-core/)) above the application core
113+ `|_` ([barcab](/hoon/twig/bar-core/cab-door/). We usually put our
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
116+ called against each other. (The shorthand for 'called' is `=>`.)
117+ Thus, the `|%` with the types is in the context of the `|_`, as it
118+ lies above it: `hoon.hoon` `=> |% w types => |_`
117119
118120Here's some sample output of the two working together:
119121
120−```
121−~fintud-macrep:dojo> |start %examples-source
122−>=
123−~fintud-macrep:dojo> |start %examples-sink
124−>=
125−~fintud-macrep:dojo> :examples-sink %on
126−[%subscribed-to pax=/the-path]
127−%successfully-subscribed]
128−>=
129−~fintud-macrep:dojo> :examples-source 5
130−[%received-data 5]
131−>=
132−~fintud-macrep:dojo> :examples-sink %off
133−>=
134−~fintud-macrep:dojo> :examples-source 6
135−>=
136−~fintud-macrep:dojo> :examples-sink %on
137−[%subscribed-to pax=/the-path]
138−%successfully-subscribed]
139−>=
140−~fintud-macrep:dojo> :examples-source 7
141−[%received-data 7]
142−>=
143−```
144−
145−###:examples-source
146−
147−Hopefully you can get a sense for what's happening here. When we
148−poke `:examples-sink` with `%on`, `:examples-sink` subscribes to `:examples-source`, and so
149−whenever we poke `:examples-source`, `:examples-sink` gets the update and prints it
150−out. Then we unsubscribe by poking `:examples-sink` with `%off`, and
151−`:examples-sink` stops getting updates. We then resubscribe.
122+
123+ ~fintud-macrep:dojo> |start %examples-source
124+ >=
125+ ~fintud-macrep:dojo> |start %examples-sink
126+ >=
127+ ~fintud-macrep:dojo> :examples-sink %on
128+ [%subscribed-to pax=/the-path]
129+ %successfully-subscribed]
130+ >=
131+ ~fintud-macrep:dojo> :examples-source 5
132+ [%received-data 5]
133+ >=
134+ ~fintud-macrep:dojo> :examples-sink %off
135+ >=
136+ ~fintud-macrep:dojo> :examples-source 6
137+ >=
138+ ~fintud-macrep:dojo> :examples-sink %on
139+ [%subscribed-to pax=/the-path]
140+ %successfully-subscribed]
141+ >=
142+ ~fintud-macrep:dojo> :examples-source 7
143+ [%received-data 7]
144+ >=
145+
146+### :examples-source
147+
148+Hopefully you can get a sense for what's happening here. When we poke
149+`:examples-sink` with `%on`, `:examples-sink` subscribes to
150+`:examples-source`, and so whenever we poke `:examples-source`,
151+`:examples-sink` gets the update and prints it out. Then we unsubscribe
152+by poking `:examples-sink` with `%off`, and `:examples-sink` stops
153+getting updates. We then resubscribe.
152154
153155There's a fair bit going on in this code. Let's look at
154156`:examples-source` first.
155157
156−Our definition of `move` is fairly specific, since we're only
157−going to sending one kind of move. The `%diff` move is a
158−subscription update, and its content is marked data which gall
159−routes to our subscribers.
160−
161−This is a slightly different kind of move than we've dealt with
162−so far. It's producing a result rather than calling other code
163−(i.e. it's a return rather than a function call), so if you
164−recall the discussion of ducts, a layer gets popped off the duct
165−rather than added to it. This is why no wire is needed for the
166−move -- we won't receive anything in response to it.
167−
168−Anyways, there're two functions inside the `|_`. We already know
169−when `++poke-noun` is called. `++peer` is called when someone
170−tries to subscribe to our app. Of course, you don't just
171−subscribe to an app; you subscribe to a path on that app. This
172−path comes in as the argument to `++peer`.
173−
174−In our case, we don't care what path you subscribed on, and all
175−we do is print out that you subscribed. Arvo keeps track of your
176−subscriptions, so you don't have to. You can access your
177−subscribers by looking at `sup` in the bowl that's passed in.
178−`sup` is of type `(map bone {@p path})`, which associates bones
179−with the urbit who subscribed, and which path they subscribed on.
180−If you want to communicate with your subscribers, send them messages along
181−their bone.
158+Our definition of `move` is fairly specific, since we're only going to
159+sending one kind of move. The `%diff` move is a subscription update, and
160+its content is marked data which gall routes to our subscribers.
161+
162+This is a slightly different kind of move than [we've dealt with so
163+far](/arvo/network). It's producing a result rather than calling other
164+code (i.e. it's a return rather than a function call), so if you recall
165+the discussion of ducts, a layer gets popped off the duct rather than
166+added to it. This is why no wire is needed for the move -- we won't
167+receive anything in response to it.
168+
169+Anyways, there're two functions inside the `|_`. We already know when
170+`++poke-noun` is called. `++peer` is called when someone tries to
171+subscribe to our app. Of course, you don't just subscribe to an app; you
172+subscribe to a path on that app. This path comes in as the argument to
173+`++peer`.
174+
175+In our case, we don't care what path you subscribed on, and all we do is
176+print out that you subscribed. Arvo keeps track of your subscriptions,
177+so you don't have to. You can access your subscribers by looking at
178+`sup` in the bowl that's passed in. `sup` is of type
179+`(map bone {@p path})`, which associates bones with the urbit who
180+subscribed, and which path they subscribed on. If you want to
181+communicate with your subscribers, send them messages along their bone.
182182
183183`++poke-noun` "spams" the given arguement to all our subscribers.
184−There's a few things we haven't seen before. Firstly, `:_(a b)`
185−is the same as `[b a]`. It's just a convenient way of formatting
186−things when the first thing in a cell is much more complicated
187−than the second. Thus, we're producing our state unchanged.
188−
189−Our list of moves is the result of a call to `++turn`. `++turn`
190−is what many languages call "map" -- it runs a function on every
191−item in a list and collects the results in a list. The list is
192−`(prey /the-path hid)` and the function is the `|=` line right
193−after it.
194−
195−`++prey` is a standard library function defined in `zuse`. It
196−takes a path and a bowl and gives you a list of the subscribers
197−who are subscribed on a path that begins with the given path.
198−"Prey" is short for "prefix".
199−
200−Now we have the list of relevant subscribers. This a list of
201−triples, `{bone @p path}`, where the only thing we really need is
202−the bone because we don't care what urbit they are or what exact
203−path they subscribed on. Thus, our transformer function takes
204−`{o/bone *}` and produces `[o %diff %noun arg]`, which is a move
205−that provides bone `o` with this subscription update: `[%noun
206−arg]`". This is fairly dense code, but what it's doing is
207−straightforward.
208−
209−###:examples-sink
210−
211−`:examples-source` should now make sense. `:examples-sink` is a little longer,
212−but not much more complicated.
213−
214−In `:examples-sink`, our definition of of `++move` is different. All
215−moves start with a `bone`, and we conventionally refer to the
216−second half as the "card", so that we can say a move is an action
217−that sends a card along a bone.
218−
219−We have two kinds of cards here: we `%peer` to start a
220−subscription, and we `%pull` to stop it. Both of these are
221−"forward" moves that may receive a response, so they need a wire
222−to tack onto the duct before they pass it on. They also need a
223−target, which is a pair of an urbit and an app name. Additionally, `%peer`
224−needs a path on that app to subscribe too. `%pull` doesn't need
225−this, because its semantics are to cancel any subscriptions
226−coming over this duct. If your bone and wire are the same as
227−when you subscribed, then the cancellation will happen correctly.
228−
229−The only state we need for `:examples-sink` is a boolean to indicate whether
230−we're already subscribed to `:examples-source`. We use `available/?`,
231−where `?` is the sign of type boolean (similar to `*`, `@`) (which defaults to true).
232−
233−In `++poke-noun` we check our input to see both if it's `%on` and
234−we're available. If so, we produce the move to subscribe to
184+There's a few things we haven't seen before. Firstly, `:_(a b)` is the
185+same as `[b a]`. It's just a convenient way of formatting things when
186+the first thing in a cell is much more complicated than the second.
187+Thus, we're producing our state unchanged.
188+
189+Our list of moves is the result of a call to `++turn`. `++turn` is what
190+many languages call "map" -- it runs a function on every item in a list
191+and collects the results in a list. The list is `(prey /the-path hid)`
192+and the function is the `|=` line right after it.
193+
194+`++prey` is a standard library function defined in `zuse`. It takes a
195+path and a bowl and gives you a list of the subscribers who are
196+subscribed on a path that begins with the given path. "Prey" is short
197+for "prefix".
198+
199+Now we have the list of relevant subscribers. This a list of triples,
200+`{bone @p path}`, where the only thing we really need is the bone,
201+because we don't need to know their urbit or what exact path they
202+subscribed on. Thus, our transformer function takes `{o/bone *}` and
203+produces `[o %diff %noun arg]`, which is a move that provides bone `o`
204+with this subscription update: `[%noun arg]`". This is fairly dense
205+code, but what it's doing is straightforward.
206+
207+### :examples-sink
208+
209+`:examples-source` should now make sense. `:examples-sink` is a little
210+longer, but not much more complicated.
211+
212+In `:examples-sink`, our definition of of `++move` is different. All
213+moves start with a `bone`, and we conventionally refer to the second
214+half as the "card", so that we can say a move is an action that sends a
215+card along a bone.
216+
217+We have two kinds of cards here: we `%peer` to start a subscription, and
218+we `%pull` to stop it. Both of these are "forward" moves that may
219+receive a response, so they need a wire to tack onto the duct before
220+they pass it on. They also need a target, which is a pair of an urbit
221+and an app name. Additionally, `%peer` needs a path on that app to
222+subscribe too. `%pull` doesn't need this, because its semantics are to
223+cancel any subscriptions coming over this duct. If your bone and wire
224+are the same as when you subscribed, then the cancellation will happen
225+correctly.
226+
227+The only state we need for `:examples-sink` is a boolean to indicate
228+whether we're already subscribed to `:examples-source`. We use
229+`available/?`, where `?` is the sign of type boolean (similar to `*`,
230+`@`), which defaults to true (that is, `0`).
231+
232+In `++poke-noun` we check our input to see both if it's `%on` and we're
233+available. If so, we produce the move to subscribe to
235234`:examples-source`:
236235
237−```
238−[ost %peer /subscribe [our %source] /the-path]
239−```
236+ [ost %peer /subscribe [our %source] /the-path]
240237
241238Also, we set available to false (`|`) with `+>.$(available |)`.
242239
243−Otherwise, if our input is `%off` and we're already subscribed
244−(i.e. `available` is false), then we unsubscribe from
245−`:examples-source`:
240+Otherwise, if our input is `%off` and we're already subscribed (i.e.
241+`available` is false), then we unsubscribe from `:examples-source`:
246242
247−```
248−[ost %pull /subscribe [our %source] ~]
249−```
243+ [ost %pull /subscribe [our %source] ~]
250244
251−It's important to send over the same bone and wire (`/subscribe`)
252−as the one we originally subscribed on.
245+It's important to send over the same bone and wire (`/subscribe`) as the
246+one we originally subscribed on.
253247
254248We also set `available` to true (`&`).
255249
256−If neither of these cases are true, then we just print out our
257−current subscription state and do nothing.
250+If neither of these cases are true, then we print our current
251+subscription state.
258252
259253`++diff-noun` is called when we get a `%diff` update along a
260−subscription with a mark of `noun`. `++diff-noun` is given the
261−wire that we originally passed with the `%peer` subscription
262−request along and the data we got back. In our case we just
263−print out the data.
264−
265−`++reap` is called when we receive an acknowledgment as to
266−whether the subscription was handled successfully. You can
267−remember that `++reap` is the counterpart to `++peer` as it's
268−almost spelled the same as 'peer' backwards. Similarly, `coup` is
269−similar to 'poke' backwards.
270−
271−Moving forward, `++reap` is given the wire we attempted to
272−subscribe over, possibly along with an error message in cases of
273−failure. `(unit type)` means "either `~` or `[~ type]`, which
274−means it's used like Haskell's "maybe" or C's nullability. If
275−`error` is `~`, then the subscription was successful and we tell
276−that to the user. Otherwise, we print out the error message.
277−
254+subscription with a mark of `noun`. `++diff-noun` is given the wire that
255+we originally passed with the `%peer` subscription request along and the
256+data we got back. In our case we just print out the data.
257+
258+`++reap` is called when we receive an acknowledgment as to whether the
259+subscription was handled successfully. You can remember that `++reap` is
260+the counterpart to `++peer` as it's pronounced like 'peer' backwards.
261+Similarly, `coup` is similar to 'poke' backwards.
262+
263+Moving forward, `++reap` is given the wire we attempted to subscribe
264+over, possibly along with an error message in cases of failure.
265+`(unit type)` means "either `~` or `[~ type]`, which means it's used
266+like Haskell's "maybe" or C's nullability. If `error` is `~`, then the
267+subscription was successful and we tell that to the user. Otherwise, we
268+print out the error message.
docs/hoon/syntax.md+9
@@ -366,3 +366,12 @@ simple and elegant problem*.
366366Given an ugly or complex problem, lapidary naming is a liability,
367367no matter the excellence of the programmer. When in doubt, use
368368long names and/or kebab-case.
369+
370+## Freedom
371+
372+If you came all this way to learn how to write apps, you're all
373+set. This is about all you need to know to start getting your
374+hands dirty. Refer back here or to the [standard library](/hoon/library) when
375+needed, but for now, move on to [Arvo](/arvo) to continue learning.
376+
377+If, however, good enough is *not* enough, feel free to dive deeper:
docs/using/setup.md+4−3
@@ -11,11 +11,12 @@ On disk your urbit is an append-only log and a checkpoint. Or, in simpler terms
1111
1212## Initialize
1313
14−To create an urbit, we need an identity, called a "ship." A ship
14+To create an urbit, we need an identity. This identity
1515is both a network address and a memorable name.
1616
17−You are probably creating one of two kinds of ship, a 32-bit
18−"planet" or a 128-bit "comet."
17+You are probably creating one of two kinds of urbit: a 32-bit
18+"planet" or a 128-bit "comet." For a quick terminology guide
19+and high-level refresher, refer to this [handy reference sheet](/about/terminology).
1920
2021If you have an Urbit invitation, you'll have a planet like
2122`~fintud-macrep` and `~fortyv-tombyt-tabsen-sonres`. To create