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