on master help sign in
pandocify
195cd27Tobias Merkle
docs/arvo/basic.md+184−202
@@ -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,66 +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
42
43+Let's check out the code for Euler 1. First, the problem:
92
44
93−> Hoon is not generally whitespace sensitive, but we do have two
45+ If we list all the natural numbers below 10 that are multiples of
94−> different kinds of whitespace: a single space and a gap, which
46+ 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
95−> is two or more spaces or a linebreak. Tabs are taboo. Do not
47+
96−> use them. Really. For a more detailed explanation of when to
48+ Find the sum of all the multiples of 3 or 5 below 1000.
97−> use spaces vs. gaps, see the syntax section before the first
98−> exercises.
99
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.
100
94
101### Lines 1-11:
95### Lines 1-11:
102
96
@@ -106,82 +100,78 @@ Any line that begins with `::` is a comment.
106 :- %noun
100 :- %noun
107 =< (sum 1.000)
101 =< (sum 1.000)
108
102
109−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`
110−`++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
111−more detail later.
105+later.
112
106
113### How to form expressions
107### How to form expressions
114
108
115Hoon does not typically use reserved words to form expressions. Instead,
109Hoon does not typically use reserved words to form expressions. Instead,
116−expressions are formed with _runes_: digraphs of two
110+expressions are formed with *runes*: digraphs of two ASCII symbols. Each
117−ASCII symbols. Each rune takes a specific number of
118−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
119−that produce their own value (some runes take _N_ children, and are usually closed with `==`).
113+*N* children, and are usually closed with `==`).
120
114
121−For example, the rune `?:` from line 17 is the classic
115+For example, the rune `?:` from line 17 is the classic 'if-then-else'
122−'if-then-else' statement, and thus takes three children:
116+statement, and thus takes three children:
123
117
124 ?: (lth a b) :: if first child evals to true
118 ?: (lth a b) :: if first child evals to true
125 0 :: then produce result of second
119 0 :: then produce result of second
126 (add b $(b (add 3 b))) :: else, produce result of third
120 (add b $(b (add 3 b))) :: else, produce result of third
127
121
128−Since runes are such a fundamental structure in Hoon, we found
122+Since runes are such a fundamental structure in Hoon, we found ourselves
129−ourselves speaking them out loud frequently. It quickly grew
123+speaking them out loud frequently. It quickly grew cumbersome to have to
130−cumbersome to have to say "question mark, colon" to describe
124+say "question mark, colon" to describe `?:`. To alleviate this problem,
131−`?:`. 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
132−scheme: each ASCII glyph has a single-syllable pronunciation
133−phonetically designed to be both easily remembered and easily
126+single-syllable pronunciation phonetically designed to be both easily
134−pronounced in conjunction with the other glyphs (when forming a
127+remembered and easily pronounced in conjunction with the other glyphs
135−rune).
128+(when forming a rune).
136
129
137See the entire naming scheme below.
130See the entire naming scheme below.
138
131
139−```
140− ace [1 space] gal < pel (
132+ ace [1 space] gal < pel (
141− bar | gap [>1 space, \n] per )
133+ bar | gap [>1 space, \n] per )
142− bas \ gar > sel [
134+ bas \ gar > sel [
143− buc $ hax # sem ;
135+ buc $ hax # sem ;
144− cab _ hep - ser ]
136+ cab _ hep - ser ]
145− cen % kel { soq '
137+ cen % kel { soq '
146− col : ker } tar *
138+ col : ker } tar *
147− com , ket ^ tec `
139+ com , ket ^ tec `
148− doq " lus + tis =
140+ doq " lus + tis =
149− dot . pam & wut ?
141+ dot . pam & wut ?
150− fas / pat @ zap !
142+ fas / pat @ zap !
151−```
152
143
153Using this scheme, we would pronounce `?:` as 'wutcol'.
144Using this scheme, we would pronounce `?:` as 'wutcol'.
154
145
155−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`:
156
150
157`{$if p/twig q/twig r/twig} :: ?: if/then/else`
151`{$if p/twig q/twig r/twig} :: ?: if/then/else`
158
152
159−Instead of:
153+Instead of:
154+
155+ ?:(=(1 2) 'this is true' 'this is false')
156+ 'this is false'`
160
157
161−```
162−?:(=(1 2) 'this is true' 'this is false')
163−'this is false'`
164−```
165You can write:
158You can write:
166
159
167−```
168−if(=(1 2) 'this is true' 'this is false')
160+ if(=(1 2) 'this is true' 'this is false')
169−'this is false'
161+ 'this is false'
170−```
171
162
172### Lines 12-34
163### Lines 12-34
173
164
174−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
175−12-34 are wrapped in a `|%` ('barcen'), which produces a core.
166+wrapped in a `|%` ('barcen'), which produces a core. Cores are a
176−Cores are a fundamental datatype in Hoon, similar to a
167+fundamental datatype in Hoon, similar to a struct, class, or object. A
177−struct, class, or object. A core is just a map of names
178−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
179−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
180−the corresponding code. Since `|%` takes an arbitrary number of
170+name and the corresponding code. Since `|%` takes an arbitrary number of
181children, it needs to be closed with a `--`.
171children, it needs to be closed with a `--`.
182
172
183−> `++` ('luslus') is not technically a rune, since it is only used
173+> `++` ('luslus') is not technically a rune, since it is only used in
184−> in core syntax, as shown above.
174+> core syntax, as shown above.
185
175
186Let's step into each of the three arms within our core.
176Let's step into each of the three arms within our core.
187
177
@@ -192,19 +182,19 @@ Let's step into each of the three arms within our core.
192 (add (five a) (three a))
182 (add (five a) (three a))
193 --
183 --
194
184
195−`|=` ('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:
196
187
197−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
198− 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
199− number, denoted by `@`.
190+ by `@`.
200
191
201−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
202− function is called (in this case, with `(sum 1.000)`). This
193+ is called (in this case, with `(sum 1.000)`). This particular
203− particular function adds the results of evaluating the gates `++
194+ function adds the results of evaluating the gates `++ five` and
204− five` and `++three` with each of their respective input
195+ `++three` with each of their respective input parameters set to `a`.
205− parameters set to `a`.
206
196
207−### ++ three
197+### ++ three
208
198
209 ++ three
199 ++ three
210 |= a/@
200 |= a/@
@@ -214,27 +204,23 @@ Let's step into each of the three arms within our core.
214 0
204 0
215 (add b $(b (add 3 b)))
205 (add b $(b (add 3 b)))
216
206
217−As above, `++three` takes an integer argument, `a`, and then
207+As above, `++three` takes an integer argument, `a`, and then executes
218−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.
219−arguments.
209+
220−
221−Similarly, `=|` ('tisbar') pushes its first child, `b` into our
210+Similarly, `=|` ('tisbar') pushes its first child, `b` into our context
222−context (in other words, it declares a variable `b`) and executes
211+(in other words, it declares a variable `b`) and executes the remainder
223−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
224−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
225−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`.
226−
215+
227−> 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')
228−> Alternatively, use the irregular form `*`.
217+> followed by the type. Alternatively, use the irregular form `*`.
229−>
218+>
230−> ```
231−> > *@ :: produce the default value of atom @
219+> > *@ :: produce the default value of atom @
232−> 0
220+> 0
233−>
221+>
234−> > *@p :: produce the phonemic base of atom @
222+> > *@p :: produce the phonemic base of atom @
235−> ~zod
223+> ~zod
236−>
237−> ```
238
224
239So 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
240initialized to `0`.
226initialized to `0`.
@@ -242,20 +228,19 @@ initialized to `0`.
242One 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
243point. More on this later.
229point. More on this later.
244
230
245−`^-` ('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
246the code to an unsigned integer, `@u`.
232the code to an unsigned integer, `@u`.
247
233
248−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
249−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
250−rerunning the segment of the function following the `|-` with the
236+of the function following the `|-` with the value of `b` changed to `b`
251−value of `b` changed to `b` plus three.
237+plus three.
252
238
253−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
254−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
255−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
256−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
257−you recurse by an actual function call, then you have to specify
243+function call, then you have to specify every argument.
258−every argument.
259
244
260> If you're familiar with Clojure, `|-` is `loop` and `$()` is `recur`.
245> If you're familiar with Clojure, `|-` is `loop` and `$()` is `recur`.
261
246
@@ -263,19 +248,18 @@ every argument.
263
248
264Tweak your code to complete the following excercises.
249Tweak your code to complete the following excercises.
265
250
266−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
267−you will need to complete the excercises below. For these, please
252+will need to complete the excercises below. For these, please refer to
268−refer to our cheatsheat at the bottom.
253+our cheatsheat at the bottom.
269
254
270−1. Read and understand `++five` line by line.
255+1. Read and understand `++five` line by line.
271
256
272−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
273− 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`
274− `1.000` and `q` set to `2.000`.
259+ and `q` set to `2.000`.
275
260
276−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
277− return the string `'result < 1.000'`. If not,
262+ string `'result < 1.000'`. If not, return `'result >= 1.000'`.
278− return `'result >= 1.000'`.
279
263
280### Review
264### Review
281
265
@@ -290,39 +274,37 @@ refer to our cheatsheat at the bottom.
290
274
291### New material
275### New material
292
276
293−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.
294
282
295− In tallform, expressions are formed with either two spaces or
283+For more concise expressions, we use wideform, which is always a single
296− a line break separating both a rune from its children and each
284+line. Wideform can be used inside tallform expressions, but not vice
297− of its children from one another. We use tallform when writing
285+versa.
298− multiline expressions.
299
286
300− For more concise expressions, we use wideform, which is always
301− a single line. Wideform can be used inside tallform
302− expressions, but not vice versa.
303−
304− Wideform expressions are formed with a rune followed by `()`
287+Wideform expressions are formed with a rune followed by `()` containing
305− containing its children, all of which are separated by a
288+its children, all of which are separated by a single space. For example,
306− single space. For example, to make a cell of two elements:
289+to make a cell of two elements:
307
290
308 :-(a b)
291 :-(a b)
309
292
310− We've already seen wideform in action, for example with
293+We've already seen wideform in action, for example with
311− `=((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
312− of `.=`, which tests its two children for equality.
295+`.=`, which tests its two children for equality.
313
296
314− Surrounding a function with `()` is an irregular wide form
297+Surrounding a function with `()` is an irregular wide form syntax for
315− syntax for calling a function with _N_ arguments. More on this later.
298+calling a function with *N* arguments. More on this later.
316
299
317−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
318− `[a b]`, with two expressions separated by a single space.
301+ `[a b]`, with two expressions separated by a single space. While the
319− 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),
320− children (two), its irregular wide form can accept _N_ expressions:
303+ its irregular wide form can accept *N* expressions: `[a1..an]`
321− `[a1..an]`
322
304
323−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
324− atom formed from adjacent unicode bytes -- a "c string". To
306+ formed from adjacent unicode bytes -- a "c string". To produce a
325− 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
326− of an argument to a cord, use `@t`.
308+ argument to a cord, use `@t`.
327
309
328
310
docs/arvo/network.md+285−310
@@ -5,364 +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−> There is currently a bug where the `%argument` lines are
46+> There is currently a bug where the `%argument` lines are printed
50−> 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
51−> look exactly like this.
52−> `>=` means that a command was successfully received and
48+> this. `>=` means that a command was successfully received and
53> executed.
49> executed.
54
50
55−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
56−function. The important part of this code is the definition of
52+important part of this code is the definition of `++poke-noun`.
57−`++poke-noun`.
58
53
59Once 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
60−interact with it by sending it messages. The most
55+interact with it by sending it messages. The most straightforward way to
61−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
62−line, which we we did with `:echo 5` (`:[app-name]
63−[argument(s)]`).
57+`:echo 5` (`:[app-name] [argument(s)]`).
64−
58+
65−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
66−out with `~&` (sigpam). This is an unusual rune that formally "does
60+with `~&` ([sigpam](/hoon/twig/sig-hint/pam-dump/)). This is an unusual
67−nothing", but the interpreter detects it and printfs the first
61+rune that formally "does nothing", but the interpreter detects it and
68−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
69−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,
70−we'll get to the correct way later on.
64+but we'll get to the correct way later on.
71−
65+
72−But what does `++poke-noun` produce? Recall that `^-` casts to a
66+But what does `++poke-noun` produce? Recall that `^-` casts to a type.
73−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
74−function will be of type `{(list) _+>.$}`. But what does this
68+type `{(list) _+>.$}`. But what does this mean?
75−mean?
69+
76−
77−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
78−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
79−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
80−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`
81−`++poke-noun` produces is a list of messages, called
74+produces is a list of messages, called "moves". In this case, we don't
82−"moves". In this case, we don't actually want the system to do
83−anything, so we produce the empty list, `~` (in the `[~ +>.$]`
75+actually want the system to do anything, so we produce the empty list,
84−line).
76+`~` (in the `[~ +>.$]` line).
85−
77+
86−The second thing `++poke-noun` produces is our state. `+>.$`
78+The second thing `++poke-noun` produces is our state. `+>.$` refers to a
87−refers to a particular address in our subject where our formal
79+particular address in our subject where our formal app state is stored.
88−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 `+>.$`
89−but for now pretend that `+>.$` is a magic invocation that means
81+is a magic invocation that means "app state".
90−"app state".
82+
91−
83+Let's look at another example (edit your code in
92−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
93−number, and then print out the square of that number.
85+only accept a number, and then print out the square of that number.
94−
86+
95−```
96−/? 314
87+ /? 314
97−!:
88+ !:
98−|_ {bowl state=~}
89+ |_ {bowl state=~}
99−::
90+ ::
100−++ poke-atom
91+ ++ poke-atom
101− |= arg/@
92+ |= arg/@
102− ^- {(list) _+>.$}
93+ ^- {(list) _+>.$}
103− ~& [%square (mul arg arg)]
94+ ~& [%square (mul arg arg)]
104− [~ +>.$]
95+ [~ +>.$]
105−--
96+ --
106−```
97+
107−
108−A few things have changed. Firstly, we no longer accept
98+A few things have changed. Firstly, we no longer accept arbitrary nouns
109−arbitrary nouns because we can only square atoms (integers, in
99+because we can only square atoms (integers, in this case an unsigned
110−this case an unsigned one). Thus, our argument is now `arg/@`.
100+one). Thus, our argument is now `arg/@`. Secondly, it's `++poke-atom`
111−Secondly, it's `++poke-atom` rather than `++poke-noun`.
101+rather than `++poke-noun`.
112−
102+
113−# Intro to marks
103+Intro to marks
114−
104+==============
105+
115−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
116−`atom` are just two of arbitrarily many "marks". A mark is
107+of arbitrarily many "marks". A mark is fundamentally a type definition,
117−fundamentally a type definition, but accessible at the arvo
118−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`
119−have conversion routines to other marks, and some have diff,
109+directory. Some marks have conversion routines to other marks, and some
120−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
121mark to exist, however.
111mark to exist, however.
122
112
123−`noun` and `atom` are two predefined marks. In your `/mar`
113+`noun` and `atom` are two predefined marks. In your `/mar` directory,
124−directory, there are already many more, and you may add more
114+there are already many more, and you may add more at will. The type
125−at will. The type associated with `noun` is `*`, and the type
115+associated with `noun` is `*`, and the type associated with `atom` is
126−associated with `atom` is `@`.
116+`@`.
127
117
128−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
129−searches for the corresponding (`++poke-[mark]`) arm. Data
119+for the corresponding (`++poke-[mark]`) arm. Data constructed on the
130−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
131−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`
132−explicitly mark the data with `atom` using `&[mark]`. Try the following
122+using `&[mark]`. Try the following commands:
133−commands:
134
123
135−```
136−~fintud-macrep:dojo> |start %square
124+ ~fintud-macrep:dojo> |start %square
137−>=
125+ >=
138−~fintud-macrep:dojo> :examples-square 6
126+ ~fintud-macrep:dojo> :examples-square 6
139−gall: %square: no poke arm for noun
127+ gall: %square: no poke arm for noun
140−~fintud-macrep:dojo> :examples-square &atom 6
128+ ~fintud-macrep:dojo> :examples-square &atom 6
141−[%square 36]
129+ [%square 36]
142−>=
130+ >=
143−```
144
131
145−> Recall the bug where `%square` may get printed above the input
132+> Recall the bug where `%square` may get printed above the input line.
146−> line.
147
133
148−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,
149−pipeline, so we'll be getting quite used to them.
135+so we'll be getting quite used to them.
150
136
151**Exercise**:
137**Exercise**:
152
138
153−- 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
154− previous section).
140+ section).
155−
141+
156−# Sending a message to another urbit
142+Sending a message to another urbit
157−
143+==================================
144+
158−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`:
159−
146+
160−```
161−/? 314
147+ /? 314
162−|%
148+ |%
163− ++ move {bone term wire *}
149+ ++ move {bone term wire *}
164−--
150+ --
165−!:
151+ !:
166−|_ {bowl state=$~}
152+ |_ {bowl state=$~}
167−::
153+ ::
168−++ poke-urbit
154+ ++ poke-urbit
169− |= to/@p
155+ |= to/@p
170− ^- [(list move) _+>.$]
156+ ^- [(list move) _+>.$]
171− [[[ost %poke /sending [to %pong] %atom 'howdy'] ~] +>.$]
157+ [[[ost %poke /sending [to %pong] %atom 'howdy'] ~] +>.$]
172−::
158+ ::
173−++ poke-atom
159+ ++ poke-atom
174− |= arg/@
160+ |= arg/@
175− ^- (list move) _+>.$}
161+ ^- (list move) _+>.$}
176− ~& [%receiving (@t arg)]
162+ ~& [%receiving (@t arg)]
177− [~ +>.$]
163+ [~ +>.$]
178−::
164+ ::
179−++ coup |=(* [~ +>.$])
165+ ++ coup |=(* [~ +>.$])
180−--
166+ --
181−```
182
167
183Run it with these commands:
168Run it with these commands:
184
169
185−```
186−~fintud-macrep:dojo> |start %examples-pong
170+ ~fintud-macrep:dojo> |start %examples-pong
187−>=
171+ >=
188−~fintud-macrep:dojo> :pong &examples-urbit ~sampel-sipnym
172+ ~fintud-macrep:dojo> :pong &examples-urbit ~sampel-sipnym
189−>=
173+ >=
190−```
191
174
192−Replace `~sampel-sipnym` with another urbit. The easiest thing to
175+Replace `~sampel-sipnym` with another urbit. The easiest thing to do is
193−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
194−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
195see, on the foreign urbit, this output:
179see, on the foreign urbit, this output:
196
180
197−```
198−[%receiving 'howdy']
181+ [%receiving 'howdy']
199−```
200
182
201−Most of the code should be straightforward. In `++poke-atom`,
183+Most of the code should be straightforward. In `++poke-atom`, the only
202−the only new thing is the expression `(@t arg)`, which is the type `@t` being called as a function with argument `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
203−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" -- that is, a function whose domain is all nouns, and range is the given type (in this case, `@t`).
188+is, a function whose domain is all nouns, and range is the given type
189+(in this case, `@t`).
204
190
205−In simpler terms, if a clam is passed a value of its own
191+In simpler terms, if a clam is passed a value of its own type, it
206−type, it produces that value. Otherwise, it
192+produces that value. Otherwise, it produces the default value (aka the
207−produces the default value (aka the "bunt") of its type. Here we call
208−this `@t` function on the argument. This coerces the argument
193+"bunt") of its type. Here we call this `@t` function on the argument.
209−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
210−we're passed.
195+no matter what we're passed.
211
196
212−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
213−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"
214−`@p` (the "p" stands for "phonetic base").
199+stands for "phonetic base").
215
200
216Recall 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
217−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
218−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
219−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:
220−with one element:
221
205
222−```
223−[ost %poke /sending [to-urbit-address %pong] %atom 'howdy']
206+ [ost %poke /sending [to-urbit-address %pong] %atom 'howdy']
224−```
225
207
226### Moves
208### Moves
227
209
228−The general form of a move is
210+The general form of a move is `[bone term wire *]`.
229−
230−-arvo part---->
231−`[bone term wire *]`
232−
233−------------------------->app/vane-specific part of move
234
211
235Or, in pseudo-code:
212Or, in pseudo-code:
236
213
237−`["cause" sys-call/action tack-new-layer-on-cause action-specific
214+`["cause" sys-call/action tack-new-layer-on-cause action-specific information]`
238−information]`
239
215
240Let's walk through each of these elements step by step.
216Let's walk through each of these elements step by step.
241
217
242#### Bones ("cause")
218#### Bones ("cause")
243
219
244−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
245−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
246−`++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`.
247−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
248−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
249−reference to it (in the same way that a Unix file
250−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).
251−truly understand bones, we must understand ducts.
226+Thus, to truly understand bones, we must understand ducts.
252−
227+
253−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
254−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,
255−as a keystroke, network packet, file change, or timer event.
230+network packet, file change, or timer event. When arvo is given this
256−When arvo is given this event, it routes the event to appropriate
231+event, it routes the event to appropriate kernel module for handling.
257−kernel module for handling.
232+
258−
259−Sometimes, the module can immediately handle the event and
233+Sometimes, the module can immediately handle the event and produce any
260−produce any necessary results. For example, when we poked the
234+necessary results. For example, when we poked the `++poke-atom` arm
261−`++poke-atom` arm above, we poked %gall, our application server,
235+above, we poked %gall, our application server, which was able to respond
262−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,
263−cannot service the request itself, it sends instructions to another kernel
237+it sends instructions to another kernel module or application (the the
264−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
265−
239+that.
240+
266−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
267−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
268−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
269−handled it next. This process can continue indefinitely, adding
270−more and more layers onto the duct. When an entity finally
245+continue indefinitely, adding more and more layers onto the duct. When
271−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
272−is passed all the way back down.
247+the result is passed all the way back down.
273−
248+
274−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
275−that while in traditional call stacks a function call happens
250+while in traditional call stacks a function call happens synchronously
276−synchronously and returns exactly once. In arvo, multiple moves
251+and returns exactly once. In arvo, multiple moves can be sent at once,
277−can be sent at once, are evaluated asynchronously, and each
252+are evaluated asynchronously, and each one may be responded to zero or
278−one may be responded to zero or more times.
253+more times.
279
254
280The 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
281−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
282−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
283`ost`.
258`ost`.
284
259
285##### Wire ('tack on new layer to duct')
260##### Wire ('tack on new layer to duct')
286
261
287−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
288−before passing it along (or responding to it directly) anywhere. This
263+along (or responding to it directly) anywhere. This layer can have any
289−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
290−specific here, so we just use the wire `/sending`
291−(`/elem1/elem2/elemN` is one syntax used to create `++path`s and
265+use the wire `/sending` (`/elem1/elem2/elemN` is one syntax used to
292−`++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
293−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`
294−that the path `/sending` will be passed back to the response
268+wire, meaning that the path `/sending` will be passed back to the
295−handler as an argument. Although it's not required, it's
269+response handler as an argument. Although it's not required, it's
296−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
297−bug-handling purposes.
271+purposes.
298
272
299##### Term (sys-call)
273##### Term (sys-call)
300
274
301Each move also has a `term`, composed of lowercase ASCII and/or `-`.
275Each move also has a `term`, composed of lowercase ASCII and/or `-`.
302−This `term` has the sign `@tas`. In this case, out `term` is `%poke`,
276+This `term` has the sign `@tas`. In this case, out `term` is `%poke`,
303−which is the name of the particular kind of move we're sending.
277+which is the name of the particular kind of move we're sending. You can
304−You can always use `%poke` to message an app. Other common names
278+always use `%poke` to message an app. Other common names include
305−include `%warp`, to read from the filesystem; `%wait`, to
279+`%warp`, to read from the filesystem; `%wait`, to set a timer; and
306−set a timer; and `%them`, to send an http request.
280+`%them`, to send an http request.
307
281
308The move ends with `*` (that is, any noun) since each type of move takes
282The move ends with `*` (that is, any noun) since each type of move takes
309−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
310−(urbit and app) and marked data, then pokes the arm of the
284+app) and marked data, then pokes the arm of the corresponding mark on
311−corresponding mark on that app on that urbit
312−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
313−`%atom` is the mark`, and `'howdy'` is the data.
286+target urbit and app, `%atom` is the mark`, and`'howdy'\` is the data.
314−
287+
315−When arvo receives a `%poke` move, it calls the appropriate
288+When arvo receives a `%poke` move, it calls the appropriate `++poke`.
316−`++poke`. The same mechanism is used for sending messages
289+The same mechanism is used for sending messages between apps on the same
317−between apps on the same urbit as for sending messages between
290+urbit as for sending messages between apps on different urbits.
318−apps on different urbits.
291+
319−
320−> 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
321−> not entirely true: the `++coup` is called when we receive
293+> entirely true: the `++coup` is called when we receive acknowledgment
322−> acknowledgment that the `++poke` was called. We don't do
294+> that the `++poke` was called. We don't do anything with this
323−> anything with this information right now, but we could.
295+> information right now, but we could.
324
296
325**Exercises**:
297**Exercises**:
326
298
327−- 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
328− input over the network in the same way as `pong`.
300+ over the network in the same way as `pong`.
329−
301+
330−- Modify `examples-pong` to print out a message when it receives acknowledgement.
302+- Modify `examples-pong` to print out a message when it receives
331−
303+ acknowledgement.
304+
332−- 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`,
333− `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;
334− recurse; otherwise, poke `odd` with it. When `odd` recieves
307+ otherwise, poke `odd` with it. When `odd` recieves an atom, check
335− an atom, check whether it's equal to one. If so, terminate,
308+ whether it's equal to one. If so, terminate, printing "%success".
336− printing "%success". Otherwise, check whether it's odd. If
309+ Otherwise, check whether it's odd. If so, multiply it by three, add
337− so, multiply it by three, add one, and recurse; otherwise, poke
310+ one, and recurse; otherwise, poke `even` with it. When either app
338− `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
339− conjecture play out between the two apps. Sample output:
313+ between the two apps. Sample output:
340−
314+
341−```
315+<!-- -->
316+
342−~fintud-macrep:dojo> :even &atom 18
317+ ~fintud-macrep:dojo> :even &atom 18
343−[%even 18]
318+ [%even 18]
344−[%odd 9]
319+ [%odd 9]
345−[%even 28]
320+ [%even 28]
346−[%even 14]
321+ [%even 14]
347−[%odd 7]
322+ [%odd 7]
348−[%even 22]
323+ [%even 22]
349−[%odd 11]
324+ [%odd 11]
350−[%even 34]
325+ [%even 34]
351−[%odd 17]
326+ [%odd 17]
352−[%even 52]
327+ [%even 52]
353−[%even 26]
328+ [%even 26]
354−[%odd 13]
329+ [%odd 13]
355−[%even 40]
330+ [%even 40]
356−[%even 20]
331+ [%even 20]
357−[%even 10]
332+ [%even 10]
358−[%odd 5]
333+ [%odd 5]
359−[%even 16]
334+ [%even 16]
360−[%even 8]
335+ [%even 8]
361−[%even 4]
336+ [%even 4]
362−[%even 2]
337+ [%even 2]
363−%success
338+ %success
364−```
339+
365−
366−- Put `even` and `odd` on two separate urbits and pass the
340+- Put `even` and `odd` on two separate urbits and pass the messages
367− messages over the network. Post a link to a working solution
341+ over the network. Post a link to a working solution in :talk to
368− in :talk to receive a cookie.
342+ receive a cookie.
343+
docs/arvo/state.md+85−93
@@ -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, and you're free to name your state whatever you like. But
63+name your state whatever you like. But let's clarify a couple other
67−let's clarify a couple other things before we continue.
64+things before we continue.
68−
65+
69−First, `bowl` is a set of general global states. This set is
66+First, `bowl` is a set of general global states. This set is managed by
70−managed by the system. It includes things like `now` (the
67+the system. It includes things like `now` (the current time), `our` (our
71−current time), `our` (our urbit identity), and `eny` (256 bits
68+urbit identity), and `eny` (256 bits of guaranteed-fresh entropy). For
72−of guaranteed-fresh entropy). For the full list of things in
73−`++bowl`, search for `++ bowl` (note: two spaces) in
69+the full list of things in `++bowl`, search for `++ bowl` (note: two
74−`/arvo/zuse.hoon`.
70+spaces) in `/arvo/zuse.hoon`.
75−
71+
76−> This is, perhaps, the most common way to learn Hoon.
72+> This is, perhaps, the most common way to learn Hoon. The easiest way
77−> The easiest way to learn about an identifier you see in code
73+> to learn about an identifier you see in code is to search in
78−> is to search in `/arvo/zuse.hoon` and `/arvo/hoon.hoon` for it.
74+> `/arvo/zuse.hoon` and `/arvo/hoon.hoon` for it.\
79−> These "standard libraries" are usually simple to read. Since
75+> These "standard libraries" are usually simple to read. Since Urbit's
80−> Urbit's codebase is less than 15000 lines of code combined,
76+> codebase is less than 15000 lines of code combined, including the hoon
81−> including the hoon parser, the compiler, and the
82−> `/arvo` microkernel, you can usually use the code and its
77+> parser, the compiler, and the `/arvo` microkernel, you can usually use
83−> comments as a reference doc.
78+> the code and its comments as a reference doc.
84>
79>
80+> You can also read
85−> You can also read [zuse.hoon](https://github.com/urbit/arvo/blob/master/arvo/zuse.hoon) and [hoon.hoon](https://github.com/urbit/arvo/blob/master/arvo/hoon.hoon) in your browser.
81+> [zuse.hoon](https://github.com/urbit/arvo/blob/master/arvo/zuse.hoon)
86−
82+> and
83+> [hoon.hoon](https://github.com/urbit/arvo/blob/master/arvo/hoon.hoon)
84+> in your browser.
85+
87−The second thing we should clear up is this:
86+The second thing we should clear up is this: Urbit needs no "serialize
88−Urbit needs no "serialize to disk" step.
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.
91If you want to write to the Unix filesystem, you can, but it's not
89If 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 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 0.
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−87
@@ -5,103 +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−The first rune, `:-` (colhep, aka [:cons](/hoon/twig/col-cell/hep-cons/)),
17+The first rune, `:-` (colhep, aka
18+[:cons](/hoon/twig/col-cell/hep-cons/)), constructs the 2-element cell
18−constructs the 2-element cell that will be our program. The first element,
19+that will be our program. The first element, `%say`, tells the
19−`%say`, tells the interpreter what to produce--in this case a value.
20+interpreter what to produce--in this case a value.
20−
21+
21−The second element is `|=`, which we know produces a function.
22+The second element is `|=`, which we know produces a function. `|=`'s
22−`|=`'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 (`*`).
23−noun (`*`). Its second child is the remainder of the program.
24+Its second child is the remainder of the program.
24−
25+
25−Similarly, the rest of the program (which we construct
26+Similarly, the rest of the program (which we construct with another
26−with another `:-`) is a cell of the literal `%noun`, which tells
27+`:-`) is a cell of the literal `%noun`, which tells the shell that we're
27−the shell that we're producing a value of type `noun`, and the
28+producing a value of type `noun`, and the code that we run to actually
28−code that we run to actually produce our value of the type `noun`.
29+produce our value of the type `noun`.
29−
30+
30−`=<` (tisgal) 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
31−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
33+child. So in this case, we are running the expression
32−are running the expression `(sum [1.000 2.000])` against everything
34+`(sum [1.000 2.000])` against everything contained within the `|%`. In
33−contained within the `|%`. In Hoon, we call the code executed the
35+Hoon, we call the code executed the "formula" and its context the
34−"formula" and its context the "subject".
36+"subject".
35−
37+
36−```
37−::::::::::::::::::::::::::::::
38+ ::::::::::::::::::::::::::::::
38−=< (sum [1.000 2.000]) :: formula
39+ =< (sum [1.000 2.000]) :: formula
39−::::::::::::::::::::::::::::::
40+ ::::::::::::::::::::::::::::::
40−|% ::
41+ |% ::
41−++ three ::
42+ ++ three ::
42− |= a/@ ::
43+ |= a/@ ::
43− =| b/@ ::
44+ =| b/@ ::
44− |- ^- @u ::
45+ |- ^- @u ::
45− ?: (lth a b) ::
46+ ?: (lth a b) ::
46− 0 ::
47+ 0 ::
47− (add b $(b (add 3 b))) ::
48+ (add b $(b (add 3 b))) ::
48− ::
49+ ::
49−++ five ::
50+ ++ five ::
50− |= a/@ :: subject
51+ |= a/@ :: subject
51− =| b/@ ::
52+ =| b/@ ::
52− |- ^- @ ::
53+ |- ^- @ ::
53− ?: (lte a b) ::
54+ ?: (lte a b) ::
54− 0 ::
55+ 0 ::
55− ?: =((mod b 3) 0) ::
56+ ?: =((mod b 3) 0) ::
56− $(b (add b 5)) ::
57+ $(b (add b 5)) ::
57− (add b $(b (add b 5))) ::
58+ (add b $(b (add b 5))) ::
58− ::
59+ ::
59−++ sum ::
60+ ++ sum ::
60− |= a/@u ::
61+ |= a/@u ::
61− (add (five a) (three a)) ::
62+ (add (five a) (three a)) ::
62−-- ::
63+ -- ::
63−::::::::::::::::::::::::::::::
64+ ::::::::::::::::::::::::::::::
64−```
65+
65−
66−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
67−"context" in which expressions are executed. For example, in C
67+which expressions are executed. For example, in C this includes things
68−this includes things like the call stack, stack variables, and so
68+like the call stack, stack variables, and so on.
69−on.
69+
70−
71−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
72−Scheme allows a sort of reification of the context through
71+allows a sort of reification of the context through continutations, and
73−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
74−Hoon takes takes the concept one step further.
73+concept one step further.
75−
74+
76−Our starting subject is the [standard library](/hoon/library), which is defined in
75+Our starting subject is the [standard library](/hoon/library), which is
77−`/arvo/hoon.hoon` and `/arvo/zuse.hoon`. This is where functions
76+defined in `/arvo/hoon.hoon` and `/arvo/zuse.hoon`. This is where
78−like `add` are defined. When we define a core with `|%`, we
77+functions like `add` are defined. When we define a core with `|%`, we
79−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
80−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
81accessible.
80accessible.
82
81
83**Exercises**:
82**Exercises**:
84
83
85−- Pass `++sum` its arguments (`2.000` and `3.000`) from the
84+- Pass `++sum` its arguments (`2.000` and `3.000`) from the
86− commandline.
85+ commandline.
87
86
88−- 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
89− and call it `++add`, have it accept two arguments and procduce
88+ call it `++add`, have it accept two arguments and procduce 42
90− 42 (regardless of input). Change the `=<` line to `[(add 5 7)
89+ (regardless of input). Change the `=<` line to
91− (^add 5 7)]`. Can you recognize what's happening?
90+ `[(add 5 7) (^add 5 7)]`. Can you recognize what's happening?
92
91
93Cheatsheet:
92Cheatsheet:
94
93
95−- To pass arguments from the command line to a program, you
94+- To pass arguments from the command line to a program, you replace
96− replace the `*` in the first line of the boiler plate to
95+ the `*` in the first line of the boiler plate to
97− `{^ {{arg/TYPE ~} ~}}` where `TYPE` is replaced with the
96+ `{^ {{arg/TYPE ~} ~}}` where `TYPE` is replaced with the type of
98− type of argument you're expecting. Then `+euler1 a` from
97+ argument you're expecting. Then `+euler1 a` from the dojo sets `arg`
99− the dojo sets `arg` to `a`.
98+ to `a`.
100−- The empty list is `~`
99+- The empty list is `~`
101−- Lisp-style cons (construct a cell/prepend an element) is
100+- Lisp-style cons (construct a cell/prepend an element) is
102− `[new-element list]`
101+ `[new-element list]`
103−- For example, the first three positive integers are `[1 2 3
102+- For example, the first three positive integers are `[1 2 3 ~]`
104− ~]`
105−- `(gte a b)` tests whether `a` is greater than or equal to `b`.
103+- `(gte a b)` tests whether `a` is greater than or equal to `b`.
106−- `(mod a b)` runs the modulo operation on two atoms.
104+- `(mod a b)` runs the modulo operation on two atoms.
107−- 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−245
@@ -5,275 +5,264 @@ sort: 5
5title: Subscriptions
5title: Subscriptions
6---
6---
7
7
8−# Subscriptions
8+# Subscriptions
9−
9+
10−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
11−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
12−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
13−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
14−such a common pattern that it's built into arvo.
14+that it's built into arvo.
15−
15+
16−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`.
17−`:examples-source`:
17+First, `:examples-source`:
18−
18+
19−```
20−/? 314
19+ /? 314
21−!:
20+ !:
22−|%
21+ |%
23−++ move {bone $diff mark *}
22+ ++ move {bone $diff mark *}
24−--
23+ --
25−|_ {hid/bowl state/$~}
24+ |_ {hid/bowl state/$~}
26−++ poke-noun
25+ ++ poke-noun
27− |= arg/*
26+ |= arg/*
28− ^- {(list move) _+>.$}
27+ ^- {(list move) _+>.$}
29− :_ +>.$
28+ :_ +>.$
30− %+ turn (prey /the-path hid)
29+ %+ turn (prey /the-path hid)
31− |=({o/bone *} `move`[o %diff %noun arg])
30+ |=({o/bone *} `move`[o %diff %noun arg])
32−++ peer
31+ ++ peer
33− |= pax/path
32+ |= pax/path
34− ^- {(list move) _+>.$}
33+ ^- {(list move) _+>.$}
35− ~& [%subscribed-to pax=pax]
34+ ~& [%subscribed-to pax=pax]
36− [~ +>.$]
35+ [~ +>.$]
37−--
36+ --
38−```
39
37
40And secondly, `:examples-sink`:
38And secondly, `:examples-sink`:
41
39
42−```
43−/? 314
40+ /? 314
44−|%
41+ |%
45−++ move {bone card}
42+ ++ move {bone card}
46−++ card
43+ ++ card
47− $% {$peer wire {@p term} path}
44+ $% {$peer wire {@p term} path}
48− {$pull wire {@p term} $~}
45+ {$pull wire {@p term} $~}
49− ==
46+ ==
50−--
47+ --
51−!:
48+ !:
52−|_ {bowl available/?}
49+ |_ {bowl available/?}
53−++ poke-noun
50+ ++ poke-noun
54− |= arg/*
51+ |= arg/*
55− ^- {(list move) _+>.$}
52+ ^- {(list move) _+>.$}
56− ?: &(=(%on arg) available)
53+ ?: &(=(%on arg) available)
57− [[[ost %peer /subscribe [our %source] /the-path] ~] +>.$(available |)]
54+ [[[ost %peer /subscribe [our %source] /the-path] ~] +>.$(available |)]
58− ?: &(=(%off arg) !available)
55+ ?: &(=(%off arg) !available)
59− [[[ost %pull /subscribe [our %source] ~] ~] +>.$(available &)]
56+ [[[ost %pull /subscribe [our %source] ~] ~] +>.$(available &)]
60− ~& ?:(available %not-subscribed %subscribed)
57+ ~& ?:(available %not-subscribed %subscribed)
61− [~ +>.$]
58+ [~ +>.$]
62−++ diff-noun
59+ ++ diff-noun
63− |= {wir/wire arg/*}
60+ |= {wir/wire arg/*}
64− ^- {(list move) _+>.$}
61+ ^- {(list move) _+>.$}
65− ~& [%recieved-data arg]
62+ ~& [%recieved-data arg]
66− [~ +>.$]
63+ [~ +>.$]
67−++ reap
64+ ++ reap
68− |= {wir/wire error/(unit tang)}
65+ |= {wir/wire error/(unit tang)}
69− ^- {(list move) _+>.$}
66+ ^- {(list move) _+>.$}
70− ?~ error
67+ ?~ error
71− ~& %successfully-subscribed
68+ ~& %successfully-subscribed
72− [~ +>.$]
69+ [~ +>.$]
73− ~& [%subscription-failed error]
70+ ~& [%subscription-failed error]
74− [~ +>.$]
71+ [~ +>.$]
75−--
72+ --
76−```
77
73
78Cheat sheet:
74Cheat sheet:
79
75
80−- `&` (pam) can either be the boolean true (along with `%.y`, `0`), or
76+- `&` (pam) can either be the boolean true (as can `%.y`, `0`), or
77+ the irregular wide form of the `?&`
81− the irregular wide form of the `?&` ([wutpam](/hoon/twig/wut-test/pam-and)) rune, which computes the
78+ ([wutpam](/hoon/twig/wut-test/pam-and)) rune, which computes
82− logical `AND` operation on its two children.
79+ logical `AND` on its two children.
83−
80+
84−- 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
82+ `1`), or the irregular short for of `?|`
85− the irregular short for of `?|` ([wutbar](/hoon/twig/wut-test/bar-or)), which computes logical `OR` on
83+ ([wutbar](/hoon/twig/wut-test/bar-or)), which computes logical `OR`
86− its two children.
84+ on its two children.
87−
85+
86+- `!` is the irregular wide form of `?!`
88−- `!` is the irregular wide form of `?!` ([wutzap](/hoon/twig/wut-test/zap-not/)), which computes
87+ ([wutzap](/hoon/twig/wut-test/zap-not/)), which computes logical
89− logical `NOT` on its child.
88+ `NOT` on its child.
90−
89+
91−- `?~` ([wutsig](/hoon/twig/wut-test/sig-ifno/)) is basically an if-then-else that checks whether condition `p`
90+- `?~` ([wutsig](/hoon/twig/wut-test/sig-ifno/)) is basically an
91+ if-then-else that checks whether condition `p` is `~` (null). `?~`
92− is `~` (null). `?~` is slightly different from `?:(~ %tru %fal)` in that `?~`
92+ is slightly different from `?:(~ %tru %fal)` in that `?~` reduces to
93+ `?:($=(%type value) %tru %false)`. `$=`
93− reduces to `?:($=(%type value) %tru %false)`. `$=` ([buctis](/hoon/twig/buc-mold/tis-coat/)) tests whether
94+ ([buctis](/hoon/twig/buc-mold/tis-coat/)) tests whether value `q` is
94− value `q` is of type `p`.
95+ of type `p`.
95− <!--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
96− affects the type of the conditional value: XXexample-->
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 => |_`
97
119
98−- `:_` ([colcab](/hoon/twig/col-cell/cab-scon/)) is inverted `:-`: it accepts `p` and `q`, and produces `[q p]`.
99−
100−- `++bowl` is the type of the system state within our app. For example, it
101− includes things like `our`, the name of the host urbit, and `now`, the
102− current time.
103−
104−- `$%` ([buccen](/hoon/twig/buc-mold/cen-book/)) is a type constructor: it defines a new type, composed of `n`
105− types that it is passed. For example `$% @ * ^ ==` is the
106− type of either `@`, `*`, or a cell `^`. <!--XX this is a union, right?-->
107−
108−- You may have noticed the separate `|%` ([barcen](/hoon/twig/bar-core/cen-core/)) above the application
109− core `|_` ([barcab](/hoon/twig/bar-core/cab-door/). We usually put our types in another core on top of the
110− application core. We can access these type from our `|_`
111− because in `hoon.hoon` files, all cores are called against
112− each other. (The shorthand for 'called' is `=>`.) Thus, the
113− `|%` with the types is in the context of the `|_`, as it lies
114− above it: `hoon.hoon` `=> |% w types =>
115− |_`
116−
117−
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−
122−~fintud-macrep:dojo> |start %examples-source
123+ ~fintud-macrep:dojo> |start %examples-source
123−>=
124+ >=
124−~fintud-macrep:dojo> |start %examples-sink
125+ ~fintud-macrep:dojo> |start %examples-sink
125−>=
126+ >=
126−~fintud-macrep:dojo> :examples-sink %on
127+ ~fintud-macrep:dojo> :examples-sink %on
127−[%subscribed-to pax=/the-path]
128+ [%subscribed-to pax=/the-path]
128−%successfully-subscribed]
129+ %successfully-subscribed]
129−>=
130+ >=
130−~fintud-macrep:dojo> :examples-source 5
131+ ~fintud-macrep:dojo> :examples-source 5
131−[%received-data 5]
132+ [%received-data 5]
132−>=
133+ >=
133−~fintud-macrep:dojo> :examples-sink %off
134+ ~fintud-macrep:dojo> :examples-sink %off
134−>=
135+ >=
135−~fintud-macrep:dojo> :examples-source 6
136+ ~fintud-macrep:dojo> :examples-source 6
136−>=
137+ >=
137−~fintud-macrep:dojo> :examples-sink %on
138+ ~fintud-macrep:dojo> :examples-sink %on
138−[%subscribed-to pax=/the-path]
139+ [%subscribed-to pax=/the-path]
139−%successfully-subscribed]
140+ %successfully-subscribed]
140−>=
141+ >=
141−~fintud-macrep:dojo> :examples-source 7
142+ ~fintud-macrep:dojo> :examples-source 7
142−[%received-data 7]
143+ [%received-data 7]
143−>=
144+ >=
144−
145+
145−```
146−
147−###:examples-source
146+### :examples-source
148−
147+
149−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
150−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`,
151−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
152−out. Then we unsubscribe by poking `:examples-sink` with `%off`, and
152+by poking `:examples-sink` with `%off`, and `:examples-sink` stops
153−`:examples-sink` stops getting updates. We then resubscribe.
153+getting updates. We then resubscribe.
154
154
155There'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
156`:examples-source` first.
156`:examples-source` first.
157
157
158−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
159−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
160−subscription update, and its content is marked data which gall
160+its content is marked data which gall routes to our subscribers.
161−routes to our subscribers.
161+
162−
163−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
164−so far](/arvo/network). It's producing a result rather than calling other code
163+far](/arvo/network). It's producing a result rather than calling other
165−(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
166−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
167−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
168−move -- we won't receive anything in response to it.
167+receive anything in response to it.
169−
168+
170−Anyways, there're two functions inside the `|_`. We already know
169+Anyways, there're two functions inside the `|_`. We already know when
171−when `++poke-noun` is called. `++peer` is called when someone
170+`++poke-noun` is called. `++peer` is called when someone tries to
172−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
173−subscribe to an app; you subscribe to a path on that app. This
174−path comes in as the argument to `++peer`.
172+subscribe to a path on that app. This path comes in as the argument to
175−
173+`++peer`.
174+
176−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
177−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,
178−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
179−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
180−`sup` is of type `(map bone {@p path})`, which associates bones
179+`(map bone {@p path})`, which associates bones with the urbit who
181−with the urbit who subscribed, and which path they subscribed on.
180+subscribed, and which path they subscribed on. If you want to
182−If you want to communicate with your subscribers, send them messages along
181+communicate with your subscribers, send them messages along their bone.
183−their bone.
184
182
185`++poke-noun` "spams" the given arguement to all our subscribers.
183`++poke-noun` "spams" the given arguement to all our subscribers.
186−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
187−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
188−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.
189−than the second. Thus, we're producing our state unchanged.
187+Thus, we're producing our state unchanged.
190−
188+
191−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
192−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
193−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)`
194−`(prey /the-path hid)` and the function is the `|=` line right
192+and the function is the `|=` line right after it.
195−after it.
193+
196−
197−`++prey` is a standard library function defined in `zuse`. It
194+`++prey` is a standard library function defined in `zuse`. It takes a
198−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
199−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
200−"Prey" is short for "prefix".
197+for "prefix".
201−
198+
202−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,
203−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,
204−the bone, because we don't need to know their urbit or what exact
201+because we don't need to know their urbit or what exact path they
205−path they subscribed on. Thus, our transformer function takes
202+subscribed on. Thus, our transformer function takes `{o/bone *}` and
206−`{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`
207−that provides bone `o` with this subscription update: `[%noun
204+with this subscription update: `[%noun arg]`". This is fairly dense
208−arg]`". This is fairly dense code, but what it's doing is
209−straightforward.
205+code, but what it's doing is straightforward.
210−
206+
211−###:examples-sink
207+### :examples-sink
212−
208+
213−`:examples-source` should now make sense. `:examples-sink` is a little longer,
209+`:examples-source` should now make sense. `:examples-sink` is a little
214−but not much more complicated.
210+longer, but not much more complicated.
215−
211+
216−In `:examples-sink`, our definition of of `++move` is different. All
212+In `:examples-sink`, our definition of of `++move` is different. All
217−moves start with a `bone`, and we conventionally refer to the
213+moves start with a `bone`, and we conventionally refer to the second
218−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
219−that sends a card along a bone.
215+card along a bone.
220−
216+
221−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
222−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
223−"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
224−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
225−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
226−needs a path on that app to subscribe too. `%pull` doesn't need
227−this, because its semantics are to cancel any subscriptions
222+subscribe too. `%pull` doesn't need this, because its semantics are to
228−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
229−when you subscribed, then the cancellation will happen correctly.
224+are the same as when you subscribed, then the cancellation will happen
230−
225+correctly.
226+
231−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
232−we're already subscribed to `:examples-source`. We use `available/?`,
228+whether we're already subscribed to `:examples-source`. We use
233−where `?` is the sign of type boolean (similar to `*`, `@`), which defaults to true (that is, `0`).
229+`available/?`, where `?` is the sign of type boolean (similar to `*`,
234−
230+`@`), which defaults to true (that is, `0`).
231+
235−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
236−we're available. If so, we produce the move to subscribe to
233+available. If so, we produce the move to subscribe to
237`:examples-source`:
234`:examples-source`:
238
235
239−```
240−[ost %peer /subscribe [our %source] /the-path]
236+ [ost %peer /subscribe [our %source] /the-path]
241−```
242
237
243Also, we set available to false (`|`) with `+>.$(available |)`.
238Also, we set available to false (`|`) with `+>.$(available |)`.
244
239
245−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.
246−(i.e. `available` is false), then we unsubscribe from
241+`available` is false), then we unsubscribe from `:examples-source`:
247−`:examples-source`:
248
242
249−```
250−[ost %pull /subscribe [our %source] ~]
243+ [ost %pull /subscribe [our %source] ~]
251−```
252
244
253−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
254−as the one we originally subscribed on.
246+one we originally subscribed on.
255
247
256We also set `available` to true (`&`).
248We also set `available` to true (`&`).
257
249
258−If neither of these cases are true, then we print our
250+If neither of these cases are true, then we print our current
259−current subscription state.
251+subscription state.
260
252
261`++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
262−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
263−wire that we originally passed with the `%peer` subscription
255+we originally passed with the `%peer` subscription request along and the
264−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.
265−print out the data.
257+
266−
267−`++reap` is called when we receive an acknowledgment as to
258+`++reap` is called when we receive an acknowledgment as to whether the
268−whether the subscription was handled successfully. You can
259+subscription was handled successfully. You can remember that `++reap` is
269−remember that `++reap` is the counterpart to `++peer` as it's
270−pronounced like 'peer' backwards. Similarly, `coup` is
260+the counterpart to `++peer` as it's pronounced like 'peer' backwards.
271−similar to 'poke' backwards.
261+Similarly, `coup` is similar to 'poke' backwards.
272−
262+
273−Moving forward, `++reap` is given the wire we attempted to
263+Moving forward, `++reap` is given the wire we attempted to subscribe
274−subscribe over, possibly along with an error message in cases of
264+over, possibly along with an error message in cases of failure.
275−failure. `(unit type)` means "either `~` or `[~ type]`, which
265+`(unit type)` means "either `~` or `[~ type]`, which means it's used
276−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
277−`error` is `~`, then the subscription was successful and we tell
267+subscription was successful and we tell that to the user. Otherwise, we
278−that to the user. Otherwise, we print out the error message.
268+print out the error message.
279−