on master help sign in
cleaned system
6d16575Galen Wolfe-Pauly
docs/system/arvo/arvo.mddeleted−8
@@ -1,8 +0,0 @@
1−<div class="short">
2−
3−`%arvo`
4−=======
5−
6−Our operating system.
7−
8−</div>
docs/system/arvo/arvo/commentary.mddeleted−4
@@ -1,4 +0,0 @@
1−`%arvo` commentary
2−==================
3−
4−`%arvo` is our operating system.
docs/system/arvo/dill/commentary.mddeleted−5
@@ -1,5 +0,0 @@
1−Dill: Reference
2−===============
3−
4−Dill: Commentary
5−================
docs/system/arvo/gall/gall.mddeleted−5
@@ -1,5 +0,0 @@
1−Gall: Reference
2−===============
3−
4−Gall: Commentary
5−================
docs/system/arvo/time.mddeleted−21
@@ -1,21 +0,0 @@
1−<div class="short">
2−
3−`%time`
4−=======
5−
6−Our simple timer.
7−
8−It allows vanes and applications to set and timer events, which are
9−managed in a simple priority queue. `%time` produces effects to start
10−the unix timer, and when the requested `%time` passes, unix sends wake
11−events to `%time`, which time routes back to original sender. We don't
12−guarantee that a timer event will happen at exactly the `%time` it was
13−set for, or even that it'll be particularly close. A timer event is a
14−request to not be woken until after the given time.
15−
16−`%eyre` uses `%time` for timing out sessions, and `%clay` uses `%time`
17−for keeping track of time-specified file requests. `%ames` should
18−probably use `%time` to keep track of things like network timeouts and
19−retry timing, but it currently uses its own alarm system.
20−
21−</div>
docs/system/arvo/util.mddeleted−344
@@ -1,344 +0,0 @@
1−<div class="short">
2−
3−CLI Apps
4−========
5−
6−Our simple command-line applications.
7−
8−You can find them in `/main/app`.
9−
10−</div>
11−
12−------------------------------------------------------------------------
13−
14−### `:?begin`
15−
16−`~zod:dojo> :?begin [~ship-name [~valid-ticket-for-ship]]`
17−
18−Start a ship. `:?begin` collects all of the necessary information to
19−start an Urbit ship. Takes an option `[~ship-name]` or
20−`[~ship-name [~valid-ticket-for-ship]]` pair.
21−
22−------------------------------------------------------------------------
23−
24−### `+cat`
25−
26−`~zod:dojo> +cat /path/to/file [...]`
27−
28−"cat" a file. `+cat` either prints a file, or concatenates and then
29−prints multiple files to the terminal.
30−
31− ~zod:dojo> +cat %/spec/nock/5/txt
32− > +cat %/spec/nock/5/txt
33− /~zod/home/~2015.6.29..22.33.04..fc76/spec/nock/5/txt
34− A noun is an atom or a cell.
35− …
36−
37−------------------------------------------------------------------------
38−
39−### `|cp`
40−
41−`~zod:dojo> |cp /path/to/source /path/to/destination`
42−
43−Copy a file to a given location.
44−
45− ~zod:dojo> |cp %/spec/nock/5/txt %/try/6/txt
46− > |cp %/spec/nock/5/txt %/try/6/txt
47− + /~zod/home/2/try/6/txt
48− >=
49−
50−------------------------------------------------------------------------
51−
52−### `grep`
53−
54−<mark>GONE</mark>
55−
56−`~zod:dojo> :grep 'literal'`
57−"grep" a file or standard input. Currently only supports a literal cord,
58−but will eventuall support regular expressions.
59−
60−------------------------------------------------------------------------
61−
62−### `|hi`
63−
64−`~zod:dojo> |hi ~ship ["message"]`
65−
66−Send a ship a message which is empty by default, becoming their neighbor
67−in the process. Often used to ping ships to check connectivity.
68−
69−
70− ~zod:dojo> |hi ~doznec
71− > |hi ~doznec
72− ames: czar zod.urbit.org: ip .192.241.195.84
73− >=
74− hi ~doznec succesful
75− ; ~doznec is your neighbor
76− ; ~doznec is your neighbor
77−
78−and on ~doznec
79−
80− ~doznec:dojo>
81− < ~zod:
82− ; ~zod is your neighbor
83−
84−
85−send a message
86−
87− ~zod:dojo> |hi ~doznec "say something"
88− >=
89− hi ~doznec succesful
90−
91−and on ~doznec
92−
93− < ~zod: say something
94−
95−
96−------------------------------------------------------------------------
97−
98−### `:into`
99−
100−<mark>GONE</mark>
101−
102−`~zod:dojo> :into /path/to/file 'contents'`
103−
104−Write text to a file. If the specified file does not exist, create a
105−file by that name. If it does exist, replace its contents.
106−
107−
108−------------------------------------------------------------------------
109−
110−### `|label`
111−
112−<mark>GONE? returns file not found</mark>
113−
114−`~zod:dojo> |label %path %label`
115−
116−"label". Add a label to a change number.
117−
118− ~zod:dojo> |label %try %zebra
119− = new /~zod/try/3
120− ~zod:dojo> :ls /=try/zebra
121− readme
122−
123−Note that adding a label is part of the delta stream and creates a new
124−change number, `3`.
125−
126−
127−------------------------------------------------------------------------
128−
129−### `+ls`
130−
131−`~zod:dojo> :+ls path/to/directory`
132−
133−"ls". List files at a path. Unlike "ls" in Unix, the current path `%`
134−must be explicitly given (you cannot call `+ls` with no arguments to
135−display the files at the current path).
136−
137− ~zod:dojo> +ls %try
138− > +ls %/try/
139− readme/md
140−
141−------------------------------------------------------------------------
142−
143−### `|mount`
144−
145−`~zod:dojo> |mount /path/to/directory/version %mount-point`
146−
147−Your files are not synced to unix by default.
148−To sync a subtree to unix, run `|mount /path/to/directory %mount-point`.
149−This will sync it into `<pier>/<mount-point>.`
150−If you want to sync your whole home desk into f0/home, for example,
151−run `|mount % %home` You can also [`|unmount`]().
152−
153− ~zod:dojo> |mount /~zod/base/0 %base
154− > |mount /~zod/base %base
155− >=
156−
157−------------------------------------------------------------------------
158−
159−### `|mv`
160−
161−`~zod:dojo> |mv /path/to/source /path/to/destination`
162−
163−Move a file to a given location, creating a new revision of the source
164−that omits the moved file.
165−
166− ~zod:dojo> |mv %/try/6/txt %/try/7/txt
167− > |mv %/try/6/txt %/try/7/txt
168− + /~zod/home/3/try/7/txt
169− >=
170−
171−------------------------------------------------------------------------
172−
173−### `|reload`
174−
175−`~zod:dojo> |reload %vane-name [...]`
176−
177−Reload the standard library (zuse) and/or arvo vanes. If zuse is
178−reloaded, vanes depending on the changes must be reloaded as well. For
179−example `|reload %zuse %ford` is necessary to make use of changes in
180−application code or the REPL.
181−
182−Possible values for %vane-name see [Overview](overview "overview"):
183−
184− ~zod:dojo> |reload %zuse
185− [%tang /~zod/home/~2015.6.29..23.50.29..134d/arvo/zuse ~hillyx-salhet]
186− > |reload %zuse
187− >=
188−
189−------------------------------------------------------------------------
190−
191−### `|reset`
192−
193−`~zod:dojo> |reset`
194−
195−Reloads all vanes. See [`|reload`]() for reloading only or a specific vane.
196−
197− ~zod:dojo> |reset
198− [%vega-start /~zod/home/~2015.6.29..23.51.42..f335/arvo/hoon]
199− %vega-parsed
200− [%vega-compiled %163 163]
201− %hoon-load
202− [%tang /~zod/home/~2015.6.29..23.51.42..f335/arvo/zuse ~hillyx-salhet]
203− [%vane %a /~zod/home/~2015.6.29..23.51.42..f335/arvo/ames ~tilwyl-talren]
204− %ames-reload
205− [%vane %c /~zod/home/~2015.6.29..23.51.42..f335/arvo/clay ~molmur-panlus]
206− [%vane %d /~zod/home/~2015.6.29..23.51.42..f335/arvo/dill ~sicbet-miphes]
207− [%vane %e /~zod/home/~2015.6.29..23.51.42..f335/arvo/eyre ~solrux-sibnep]
208− [gub=30 hov=19 ged=18 ded=1 pox=1 ask=1 kes=1 ney=35 dop=1 liz=1 wup=1 sop=1 wix=1]
209− [%vane %f /~zod/home/~2015.6.29..23.51.42..f335/arvo/ford ~librem-sopseg]
210− [%vane %g /~zod/home/~2015.6.29..23.51.42..f335/arvo/gall ~sidsub-fasrev]
211− [%vane %t /~zod/home/~2015.6.29..23.51.42..f335/arvo/time ~ritwyn-lanrev]
212− > |reset
213− <<<reset>>>
214− >=
215−
216−------------------------------------------------------------------------
217−
218−### `|rm`
219−
220−`~zod:dojo> |rm /path/to/source`
221−
222−Remove a file.
223−
224− ~zod:dojo> |rm %/try/7/txt
225− >=
226−
227−------------------------------------------------------------------------
228−
229−### `+solid`
230−
231−`~zod:dojo> +solid`
232−
233−compiles a kernel into a new full urbit.pill
234−
235−------------------------------------------------------------------------
236−
237−### `|sync`
238−
239−`~zod:dojo> |sync %source-desk ~hidduc-posmeg %target-desk`
240−
241−Sets up a subscription to the source desk on the target ship name to the
242−target desk on your ship.
243−
244−------------------------------------------------------------------------
245−
246−### `+ticket`
247−
248−`~zod:dojo> +ticket ~ship-name`
249−
250−Creates a will for a ship. `+ticket` outputs the ticket for a Urbit
251−ship. Takes an option `[~ship-name]`. On destroyes this command creates
252−a yacht and takes the option \`[\~yacht-name-destroyer-name]
253−
254−------------------------------------------------------------------------
255−
256−### `:thumb`
257−
258−<mark>GONE</mark>
259−
260−`~zod:dojo> :thumb ~ship-name`
261−
262−Show the ships information. Only works if you issued a [`:hi`]
263−[\`\~ship-name] beforehand.
264−
265−This command is not avaible since the switch from batz to `%gall`!
266−
267−Use this for the time beeing: - will:
268−`~zod/try=> ((hard (unit gcos)) .^(%a /=gcos=/~ship-name))` - raw will:
269−`~zod/try=> ((hard will) .^(%a /=will=/~ship-name))`
270−
271−
272−------------------------------------------------------------------------
273−
274−### `|unmount`
275−
276−`~zod:dojo> |unmount /path/to/directory`
277−
278−Your files are not synced to unix by default.
279−To sync a subtree to unix, run `|mount`.
280−You can unmount with either `|unmount /path/to/directory`
281−or `|unmount %mount-point`.
282−
283− ~zod:dojo> |unmount %base
284− > |unmount %base
285− >=
286−
287−------------------------------------------------------------------------
288−
289−### `|unsync`
290−
291−`~zod:dojo> |unsync %source-desk ~hidduc-posmeg %target-desk`
292−
293−Cancels the subscription to the source desk on the target ship name to
294−the target desk on your ship.
295−
296−------------------------------------------------------------------------
297−
298−### `|verb`
299−
300−`~zod:dojo> |verb`
301−
302−Turn verbose arvo mode on/off.
303−
304−You'll see events, internal cards, and effects.
305−
306− [%unix p=%wake //temp]
307− [ %give
308− %t
309− %wake
310− ~[
311− /c/tyme
312− /g/a/~zod/._~~.58_~~.shell_~~.terminal__/w/drug/~zod/main
313− /g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/began/u
314− /g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/._~~.2_~~.shell_~~.terminal__/u/to-gan
315− /g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/._~~.shell_~~.terminal__/u/child/2/main
316− /g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/terminal/u/txt
317− /d/term-mess
318− //term/1
319− ]
320− ]
321− [ %give
322− %c
323− %writ
324− ~[
325− /g/a/~zod/._~~.58_~~.shell_~~.terminal__/w/drug/~zod
326− /g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/began/u
327− /g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/._~~.2_~~.shell_~~.terminal__/u/to-gan
328− /g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/._~~.shell_~~.terminal__/u/child/2/main
329− /g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/terminal/u/txt
330− /d/term-mess
331− //term/1
332− ]
333− ]
334− ...
335−
336−------------------------------------------------------------------------
337−
338−### `|ye`
339−
340−`~zod:dojo> |ye ["message"]`
341−
342−Send a message to all ships. Often used to announce a continuity breach.
343−
344−------------------------------------------------------------------------
docs/system/interpreter/u3.mddeleted−1570
@@ -1,1570 +0,0 @@
1−# u3: noun processing in C
2−
3−`u3` is the C library that makes Urbit work. If it wasn't called
4−`u3`, it might be called `libnoun` - it's a library for making
5−and storing nouns.
6−
7−What's a noun? A noun is either a cell or an atom. A cell is an
8−ordered pair of any two nouns. An atom is an unsigned integer of
9−any size.
10−
11−To the C programmer, this is not a terribly complicated data
12−structure, so why do you need a library for it?
13−
14−One: nouns have a well-defined computation kernel, Nock, whose
15−spec fits on a page and gzips to 340 bytes. But the only
16−arithmetic operation in Nock is increment. So it's nontrivial
17−to compute both efficiently and correctly.
18−
19−Two: `u3` is designed to support "permanent computing," ie, a
20−single-level store which is transparently snapshotted. This
21−implies a specialized memory-management model, etc, etc.
22−
23−(Does `u3` depend on the higher levels of Urbit, Arvo and Hoon?
24−Yes and no. `u3` expects you to load something shaped like an
25−Arvo kernel, and use it as an event-processing function. But you
26−don't need to use this feature if you don't want, and your kernel
27−doesn't have to be Arvo proper - just Arvo-compatible. Think of
28−`u3` as the BIOS and Arvo as the boot kernel. And there are no
29−dependencies at all between Hoon the language and `u3`.)
30−
31−## c3: C in Urbit
32−
33−Under `u3` is the simple `c3` layer, which is just how we write C
34−in Urbit.
35−
36−When writing C in u3, please of course follow the conventions of
37−the code around you as regards indentation, etc. It's especially
38−important that every function have a header comment, even if it
39−says nothing interesting.
40−
41−But some of our idiosyncrasies go beyond convention. Yes, we've
42−done awful things to C. Here's what we did and why we did.
43−
44−### c3: integer types
45−
46−First, it's generally acknowledged that underspecified integer
47−types are C's worst disaster. C99 fixed this, but the `stdint`
48−types are wordy and annoying. We've replaced them with:
49−
50− /* Good integers.
51− */
52− typedef uint64_t c3_d; // double-word
53− typedef int64_t c3_ds; // signed double-word
54− typedef uint32_t c3_w; // word
55− typedef int32_t c3_ws; // signed word
56− typedef uint16_t c3_s; // short
57− typedef int16_t c3_ss; // signed short
58− typedef uint8_t c3_y; // byte
59− typedef int8_t c3_ys; // signed byte
60− typedef uint8_t c3_b; // bit
61−
62− typedef uint8_t c3_t; // boolean
63− typedef uint8_t c3_o; // loobean
64− typedef uint8_t c3_g; // 5-bit atom for a 32-bit log.
65− typedef uint32_t c3_l; // little; 31-bit unsigned integer
66− typedef uint32_t c3_m; // mote; also c3_l; LSB first a-z 4-char string.
67−
68− /* Bad integers.
69− */
70− typedef char c3_c; // does not match int8_t or uint8_t
71− typedef int c3_i; // int - really bad
72− typedef uintptr_t c3_p; // pointer-length uint - really really bad
73− typedef intptr_t c3_ps; // pointer-length int - really really bad
74−
75−Some of these need explanation. A loobean is a Nock boolean -
76−Nock, for mysterious reasons, uses 0 as true (always say "yes")
77−and 1 as false (always say "no").
78−
79−Nock and/or Hoon cannot tell the difference between a short atom
80−and a long one, but at the `u3` level every atom under `2^31` is
81−direct. The `c3_l` type is useful to annotate this. A `c3_m` is
82−a *mote* - a string of up to 4 characters in a `c3_l`, least
83−significant byte first. A `c3_g` should be a 5-bit atom. Of
84−course, C cannot enforce these constraints, only document them.
85−
86−Use the "bad" - ie, poorly specified - integer types only when
87−interfacing with external code that expects them.
88−
89−An enormous number of motes are defined in `i/c/motes.h`. There
90−is no reason to delete motes that aren't being used, or even to
91−modularize the definitions. Keep them alphabetical, though.
92−
93−### c3: variables and variable naming
94−
95−The C3 style uses Hoon style TLV variable names, with a quasi
96−Hungarian syntax. This is weird, but works really well, as long
97−as what you're doing isn't hideously complicated. (Then it works
98−badly, but we shouldn't need anything hideous in u3.)
99−
100−A TLV variable name is a random pronounceable three-letter
101−string, sometimes with some vague relationship to its meaning,
102−but usually not. Usually CVC (consonant-vowel-consonant) is a
103−good choice.
104−
105−You should use TLVs much the way math people use Greek letters.
106−The same concept should in general get the same name across
107−different contexts. When you're working in a given area, you'll
108−tend to remember the binding from TLV to concept by sheer power
109−of associative memory. When you come back to it, it's not that
110−hard to relearn. And of course, when in doubt, comment it.
111−
112−Variables take pseudo-Hungarian suffixes, matching in general the
113−suffix of the integer type:
114−
115− c3_w wor_w; // 32-bit word
116−
117−Unlike in standard Hungarian, there is no change for pointer
118−variables. C structure variables take a `_u` suffix.
119−
120−### c3: loobeans
121−
122−The code (from `defs.h`) tells the story:
123−
124− # define c3y 0
125− # define c3n 1
126−
127− # define _(x) (c3y == (x))
128− # define __(x) ((x) ? c3y : c3n)
129− # define c3a(x, y) __(_(x) && _(y))
130− # define c3o(x, y) __(_(x) || _(y))
131−
132−In short, use `_()` to turn a loobean into a boolean, `__` to go
133−the other way. Use `!` as usual, `c3y` for yes and `c3n` for no,
134−`c3a` for and and `c3o` for or.
135−
136−## u3: land of nouns
137−
138−The division between `c3` and `u3` is that you could theoretically
139−imagine using `c3` as just a generic C environment. Anything to do
140−with nouns is in `u3`.
141−
142−### u3: a map of the system
143−
144−There are two kinds of symbols in `u3`: regular and irregular.
145−Regular symbols follow this pattern:
146−
147− prefix purpose .h .c
148− -------------------------------------------------------
149− u3a_ allocation i/n/a.h n/a.c
150− u3e_ persistence i/n/e.h n/e.c
151− u3h_ hashtables i/n/h.h n/h.c
152− u3i_ noun construction i/n/i.h n/i.c
153− u3j_ jet control i/n/j.h n/j.c
154− u3m_ system management i/n/m.h n/m.c
155− u3n_ nock computation i/n/n.h n/n.c
156− u3r_ noun access (error returns) i/n/r.h n/r.c
157− u3t_ profiling i/n/t.h n/t.c
158− u3v_ arvo i/n/v.h n/v.c
159− u3x_ noun access (error crashes) i/n/x.h n/x.c
160− u3z_ memoization i/n/z.h n/z.c
161− u3k[a-g] jets (transfer, C args) i/j/k.h j/[a-g]/*.c
162− u3q[a-g] jets (retain, C args) i/j/q.h j/[a-g]/*.c
163− u3w[a-g] jets (retain, nock core) i/j/w.h j/[a-g]/*.c
164−
165−Irregular symbols always start with `u3` and obey no other rules.
166−They're defined in `i/n/u.h`. Finally, `i/all.h` includes all
167−these headers (fast compilers, yay) and is all you need to
168−program in `u3`.
169−
170−### u3: noun internals
171−
172−A noun is a `u3_noun` - currently defined as a 32-bit `c3_w`.
173−
174−If your `u3_noun` is less than `(1 << 31)`, it's a direct atom.
175−Every unsigned integer between `0` and `0x7fffffff` inclusive is
176−its own noun.
177−
178−If bit `31` is set in a `u3_noun`, bit `30` is always set - this
179−bit is reserved. Bit `29` is `1` if the noun is a cell, `0` if
180−it's an atom. Bits `28` through `0` are a word pointer into the
181−loom - see below. The structures are:
182−
183− typedef struct {
184− c3_w mug_w;
185− c3_w len_w;
186− c3_w buf_w[0]; // actually [len_w]
187− } u3a_atom;
188−
189− typedef struct {
190− c3_w mug_w;
191− u3_noun hed;
192− u3_noun tel;
193− } u3a_cell;
194−
195−The only thing that should be mysterious here is `mug_w`, which
196−is a 31-bit lazily computed nonzero short hash (FNV currently,
197−soon Murmur3). If `mug_w` is 0, the hash is not yet computed.
198−We also hijack this field for various hacks, such as saving the
199−new address of a noun when copying over.
200−
201−Also, the value `0xffffffff` is `u3_none`, which is never a valid
202−noun. Use the type `u3_weak` to express that a noun variable may
203−be `u3_none`.
204−
205−### u3: reference counts
206−
207−The only really essential thing you need to know about `u3` is
208−how to handle reference counts. Everything else, you can skip
209−and just get to work.
210−
211−u3 deals with reference-counted, immutable, acyclic nouns.
212−Unfortunately, we are not Apple and can't build reference
213−counting into your C compiler, so you need to count by hand.
214−
215−Every allocated noun (or any allocation object, because our
216−allocator is general-purpose) contains a counter which counts the
217−number of references to it - typically variables with type
218−`u3_noun`. When this counter goes to 0, the noun is freed.
219−
220−To tell `u3` that you've added a reference to a noun, call the
221−function `u3a_gain()` or its shorthand `u3k()`. (For your
222−convenience, this function returns its argument.) To tell `u3`
223−that you've destroyed a reference, call `u3a_lose()` or `u3z()`.
224−
225−(If you screw up by decrementing the counter too much, `u3` will
226−dump core in horrible ways. If you screw up by incrementing it
227−too much, `u3` will leak memory. To check for memory leaks,
228−set the `bug_o` flag in `u3e_boot()` - eg, run `vere` with `-g`.
229−Memory leaks are difficult to debug - the best way to handle
230−leaks is just to revert to a version that didn't have them, and
231−look over your code again.)
232−
233−(You can gain or lose a direct atom. It does nothing.)
234−
235−### u3: reference protocols
236−
237−*THIS IS THE MOST CRITICAL SECTION IN THE `u3` DOCUMENTATION.*
238−
239−The key question when calling a C function in a refcounted world
240−is what the function will do to the noun refcounts - and, if the
241−function returns a noun, what it does to the return.
242−
243−There are two semantic patterns, `transfer` and `retain`. In
244−`transfer` semantics, the caller "gives" a use count to the
245−callee, which "gives back" any return. For instance, if I have
246−
247− {
248− u3_noun foo = u3i_string("foobar");
249− u3_noun bar;
250−
251− bar = u3f_futz(foo);
252− [...]
253− u3z(bar);
254− }
255−
256−Suppose `u3f_futz()` has `transfer` semantics. At `[...]`, my
257−code holds one reference to `bar` and zero references to `foo` -
258−which has been freed, unless it's part of `bar`. My code now
259−owns `bar` and gets to work with it until it's done, at which
260−point a `u3z()` is required.
261−
262−On the other hand, if `u3f_futz()` has `retain` semantics, we
263−need to write
264−
265− {
266− u3_noun foo = u3i_string("foobar");
267− u3_noun bar;
268−
269− bar = u3f_futz(foo);
270− [...]
271− u3z(foo);
272− }
273−
274−because calling `u3f_futz()` does not release our ownership of
275−`foo`, which we have to free ourselves.
276−
277−But if we free `bar`, we are making a great mistake, because our
278−reference to it is not in any way registered in the memory
279−manager (which cannot track references in C variables, of
280−course). It is normal and healthy to have these uncounted
281−C references, but they must be treated with care.
282−
283−The bottom line is that it's essential for the caller to know
284−the refcount semantics of any function which takes or returns a
285−noun. (In some unusual circumstances, different arguments or
286−returns in one function may be handled differently.)
287−
288−Broadly speaking, as a design question, retain semantics are more
289−appropriate for functions which inspect or query nouns. For
290−instance, `u3h()` (which takes the head of a noun) retains, so
291−that we can traverse a noun tree without constantly incrementing
292−and decrementing.
293−
294−Transfer semantics are more appropriate for functions which make
295−nouns, which is obviously what most functions do.
296−
297−In general, though, in most places it's not worth thinking about
298−what your function does. There is a convention for it, which
299−depends on where it is, not what it does. Follow the convention.
300−
301−### u3: reference conventions
302−
303−The `u3` convention is that, unless otherwise specified, *all
304−functions have transfer semantics* - with the exception of the
305−prefixes: `u3r`, `u3x`, `u3z`, `u3q` and `u3w`. Also, within
306−jet directories `a` through `f` (but not `g`), internal functions
307−retain (for historical reasons).
308−
309−If functions outside this set have retain semantics, they need to
310−be commented, both in the `.h` and `.c` file, with `RETAIN` in
311−all caps. Yes, it's this important.
312−
313−### u3: system architecture
314−
315−If you just want to tinker with some existing code, it might be
316−enough to understand the above. If not, it's probably worth
317−taking the time to look at `u3` as a whole.
318−
319−`u3` is designed to work as a persistent event processor.
320−Logically, it computes a function of the form
321−
322− f(event, old state) -> (actions, new state)
323−
324−Obviously almost any computing model - including, but not limited
325−to, Urbit - can be defined in this form. To create the illusion
326−of a computer that never loses state and never fails, we:
327−
328−- log every event externally before it goes into u3
329−- keep a single reference to a permanent state noun.
330−- can abort any event without damaging the permanent state.
331−- snapshot the permanent state periodically, and/or prune logs.
332−
333−### u3: the road model
334−
335−`u3` uses a memory design which I'm sure someone has invented
336−somewhere before, because it's not very clever, but I've never
337−seen it anywhere in particular.
338−
339−Every allocation starts with a solid block of memory, which `u3`
340−calls the `loom`. How do we allocate on the loom? You're
341−probably familiar with the Unix heap-stack design, in which the
342−stack grows downward and the heap (malloc arena) grows upward:
343−
344− 0 brk ffff
345− | heap | stack |
346− |------------#################################+++++++++++++|
347− | | |
348− 0 sp ffff
349−
350−A road is a normal heap-stack system, except that the heap
351−and stack can point in *either direction*. Therefore, inside
352−a road, we can nest another road in the *opposite direction*.
353−
354−When the opposite road completes, its heap is left on top of
355−the opposite heap's stack. It's no more than the normal
356−behavior of a stack machine for all subcomputations to push
357−their results on the stack.
358−
359−The performance tradeoff of "leaping" - reversing directions in
360−the road - is that if the outer computation wants to preserve the
361−results of the inner one, not just use them for temporary
362−purposes, it has to *copy them*.
363−
364−This is a trivial cost in some cases, a prohibitive cost in
365−others. The upside, of course, is that all garbage accrued
366−in the inner computation is discarded at zero cost.
367−
368−The goal of the road system is the ability to *layer* memory
369−models. If you are allocating on a road, you have no idea
370−how deep within a nested road system you are - in other words,
371−you have no idea exactly how durable your result may be.
372−But free space is never fragmented within a road.
373−
374−Roads do not reduce the generality or performance of a memory
375−system, since even the most complex GC system can be nested
376−within a road at no particular loss of performance - a road
377−is just a block of memory.
378−
379−Each road (`u3a_road` to be exact) uses four pointers: `rut` is
380−the bottom of the arena, `hat` the top of the arena, `mat` the
381−bottom of the stack, `cap` the top of the stack. (Bear in mind
382−that the road "stack" is not actually used as the C function-call
383−stack, though it probably should be.)
384−
385−A "north" road has the stack high and the heap low:
386−
387− 0 rut hat ffff
388− | | | |
389− |~~~~~~~~~~~~-------##########################+++++++$~~~~~|
390− | | | |
391− 0 cap mat ffff
392−
393−A "south" road is the other way around:
394−
395− 0 mat cap ffff
396− | | | |
397− |~~~~~~~~~~~~$++++++##########################--------~~~~~|
398− | | | |
399− 0 hat rut ffff
400−
401−Legend: `-` is durable storage (heap); `+` is temporary storage
402−(stack); `~` is deep storage (immutable); `$` is the allocation
403−frame `#` is free memory.
404−
405−Pointer restrictions: pointers stored in `+` can point anywhere.
406−Pointers in `-` can only point to `-` or `~`; pointers in `~`
407−only point to `~`.
408−
409−To "leap" is to create a new inner road in the `###` free space.
410−but in the reverse direction, so that when the inner road
411−"falls" (terminates), its durable storage is left on the
412−temporary storage of the outer road.
413−
414−`u3` keeps a global variable, `u3_Road` or its alias `u3R`, which
415−points to the current road. (If we ever run threads in inner
416−roads - see below - this will become a thread-local variable.)
417−Relative to `u3R`, `+` memory is called `junior` memory; `-`
418−memory is `normal` memory; `~` is `senior` memory.
419−
420−### u3: explaining the road model
421−
422−But... why?
423−
424−We're now ready to understand why the road system works so
425−logically with the event and persistence model.
426−
427−The key is that *we don't update refcounts in senior memory.*
428−A pointer from an inner road to an outer road is not counted.
429−Also, the outmost, or `surface` road, is the only part of the
430−image that gets checkpointed.
431−
432−So the surface road contains the entire durable state of `u3`.
433−When we process an event, or perform any kind of complicated or
434−interesting calculation, *we process it in an inner road*. If
435−its results are saved, they need to be copied.
436−
437−Since processing in an inner road does not touch surface memory,
438−(a) we can leave the surface road in a read-only state and not
439−mark its pages dirty; (b) we can abort an inner calculation
440−without screwing up the surface; and (c) because inner results
441−are copied onto the surface, the surface doesn't get fragmented.
442−
443−All of (a), (b) and (c) are needed for checkpointing to be easy.
444−It might be tractable otherwise, but easy is even better.
445−
446−Moreover, while the surface is most definitely single-threaded,
447−we could easily run multiple threads in multiple inner roads
448−(as long as the threads don't have pointers into each others'
449−memory, which they obviously shouldn't).
450−
451−Moreover, in future, we'll experiment more with adding road
452−control hints to the programmer's toolbox. Reference counting is
453−expensive. We hypothesize that in many - if not most - cases,
454−the programmer can identify procedural structures whose garbage
455−should be discarded in one step by copying the results. Then,
456−within the procedure, we can switch the allocator into `sand`
457−mode, and stop tracking references at all.
458−
459−### u3: rules for C programming
460−
461−There are two levels at which we program in C: (1) above the
462−interpreter; (2) within the interpreter or jets. These have
463−separate rules which need to be respected.
464−
465−### u3: rules above the interpreter
466−
467−In its relations with Unix, Urbit follows a strict rule of "call
468−me, I won't call you." We do of course call Unix system calls,
469−but only for the purpose of actually computing.
470−
471−Above Urbit, you are in a normal C/Unix programming environment
472−and can call anything in or out of Urbit. Note that when using
473−`u3`, you're always on the surface road, which is not thread-safe
474−by default. Generally speaking, `u3` is designed to support
475−event-oriented, single-threaded programming.
476−
477−If you need threads which create nouns, you could use
478−`u3m_hate()` and `u3m_love()` to run these threads in subroads.
479−You'd need to make the global road pointer, `u3R`, a thread-local
480−variable instead. This seems perfectly practical, but we haven't
481−done it because we haven't needed to.
482−
483−### u3: rules within the interpreter
484−
485−Within the interpreter, your code can run either in the surface
486−road or in a deep road. You can test this by testing
487−
488− (&u3H->rod_u == u3R)
489−
490−ie: does the pier's home road equal the current road pointer?
491−
492−Normally in this context you assume you're obeying the rules of
493−running on an inner road, ie, "deep memory." Remember, however,
494−that the interpreter *can* run on surface memory - but anything
495−you can do deep, you can do on the surface. The converse is by
496−no means the case.
497−
498−In deep memory, think of yourself as if in a signal handler.
499−Your execution context is extremely fragile and may be terminated
500−without warning or cleanup at any time (for instance, by ^C).
501−
502−For instance, you can't call `malloc` (or C++ `new`) in your C
503−code, because you don't have the right to modify data structures
504−at the global level, and will leave them in an inconsistent state
505−if your inner road gets terminated. (Instead, use our drop-in
506−replacements, `u3a_malloc()`, `u3a_free()`, `u3a_realloc()`.)
507−
508−A good example is the different meaning of `c3_assert()` inside
509−and outside the interpreter. At either layer, you can use
510−regular assert(), which will just kill your process. On the
511−surface, `c3_assert()` will just... kill your process.
512−
513−In deep execution, `c3_assert()` will issue an exception that
514−queues an error event, complete with trace stack, on the Arvo
515−event queue. Let's see how this happens.
516−
517−### u3: exceptions
518−
519−You produce an exception with
520−
521− /* u3m_bail(): bail out. Does not return.
522− **
523− ** Bail motes:
524− **
525− ** %exit :: semantic failure
526− ** %evil :: bad crypto
527− ** %intr :: interrupt
528− ** %fail :: execution failure
529− ** %foul :: assert failure
530− ** %need :: network block
531− ** %meme :: out of memory
532− ** %time :: timed out
533− ** %oops :: assertion failure
534− */
535− c3_i
536− u3m_bail(c3_m how_m);
537−
538−Broadly speaking, there are two classes of exception: internal
539−and external. An external exception begins in a Unix signal
540−handler. An internal exception begins with a call to longjmp()
541−on the main thread.
542−
543−There are also two kinds of exception: mild and severe. An
544−external exception is always severe. An internal exception is
545−normally mild, but some (like `c3__oops`, generated by
546−`c3_assert()`) are severe.
547−
548−Either way, exceptions come with a stack trace. The `u3` nock
549−interpreter is instrumented to retain stack trace hints and
550−produce them as a printable `(list tank)`.
551−
552−Mild exceptions are caught by the first virtualization layer and
553−returned to the caller, following the behavior of the Nock
554−virtualizer `++mock` (in `hoon.hoon`)
555−
556−Severe exceptions, or mild exceptions at the surface, terminate
557−the entire execution stack at any depth and send the cumulative
558−trace back to the `u3` caller.
559−
560−For instance, `vere` uses this trace to construct a `%crud`
561−event, which conveys our trace back toward the Arvo context where
562−it crashed. This lets any UI component anywhere, even on a
563−remote node, render the stacktrace as a consequence of the user's
564−action - even if its its direct cause was (for instance) a Unix
565−SIGINT or SIGALRM.
566−
567−### u3: C structures on the loom
568−
569−Normally, all data on the loom is nouns. Sometimes we break this
570−rule just a little, though - eg, in the `u3h` hashtables.
571−
572−To point to non-noun C structs on the loom, we use a `u3_post`,
573−which is just a loom word offset. A macro lets us declare this
574−as if it was a pointer:
575−
576− typedef c3_w u3_post;
577− #define u3p(type) u3_post
578−
579−Some may regard this as clever, others as pointless. Anyway, use
580−`u3to()` and `u3of()` to convert to and from pointers.
581−
582−When using C structs on the loom - generally a bad idea - make
583−sure anything which could be on the surface road is structurally
584−portable, eg, won't change size when the pointer size changes.
585−(Note also: we consider little-endian, rightly or wrongly, to
586−have won the endian wars.)
587−
588−## u3: API overview by prefix
589−
590−Let's run through the `u3` modules one by one. All public
591−functions are commented, but the comments may be cryptic.
592−
593−### u3m: main control
594−
595−To start `u3`, run
596−
597− /* u3m_boot(): start the u3 system.
598− */
599− void
600− u3m_boot(c3_o nuu_o, c3_o bug_o, c3_c* dir_c);
601−
602−`nuu_o` is `c3y` (yes, `0`) if you're creating a new pier,
603−`c3n` (no, `1`) if you're loading an existing one. `bug_o`
604−is `c3y` if you want to test the garbage-collector, `c3n`
605−otherwise. `dir_c` is the directory for the pier files.
606−
607−`u3m_boot()` expects an `urbit.pill` file to load the kernel
608−from. It will try first `$dir/.urb.urbit.pill`, then `U3_LIB`.
609−
610−Any significant computation with nouns, certainly anything Turing
611−complete, should be run (a) virtualized and (b) in an inner road.
612−These are slightly different things, but at the highest level we
613−bundle them together for your convenience, in `u3m_soft()`:
614−
615− /* u3m_soft(): system soft wrapper. unifies unix and nock errors.
616− **
617− ** Produces [%$ result] or [%error (list tank)].
618− */
619− u3_noun
620− u3m_soft(c3_w sec_w, u3_funk fun_f, u3_noun arg);
621−
622−`sec_w` is the number of seconds to time out the computation.
623−`fun_f` is a C function accepting `arg`.
624−
625−The result of `u3m_soft()` is a cell whose head is an atom. If
626−the head is `%$` - ie, `0` - the tail is the result of
627−`fun_f(arg)`. Otherwise, the head is a `term` (an atom which is
628−an LSB first string), and the tail is a `(list tank)` (a list of
629−`tank` printables - see `++tank` in `hoon.hoon`). Error terms
630−should be the same as the exception terms above.
631−
632−If you're confident that your computation won't fail, you can
633−use `u3m_soft_sure()`, `u3m_soft_slam()`, or `u3m_soft_nock()`
634−for C functions, Hoon function calls, and Nock invocations.
635−Caution - this returns just the result, and asserts globally.
636−
637−All the `u3m_soft` functions above work *only on the surface*.
638−Within the surface, virtualize with `u3m_soft_run()`. Note that
639−this takes a `fly` (a namespace gate), thus activating the `11`
640−super-operator in the nock virtualizer, `++mock`. When actually
641−using the `fly`, call `u3m_soft_esc()`. Don't do either unless
642−you know what you're doing!
643−
644−For descending into a subroad *without* Nock virtualization,
645−use `u3m_hate()` and `u3m_love` respectively. Hating enters
646−a subroad; loving leaves it, copying out a product noun.
647−
648−Other miscellaneous tools in `u3m`: `u3m_file()` loads a Unix
649−file as a Nock atom; `u3m_water()` measures the boundaries of
650−the loom in current use (ie, watermarks); and a variety of
651−prettyprinting routines, none perfect, are available, mainly for
652−debugging printfs: `u3m_pretty()`, `u3m_p()`, `u3m_tape()` and
653−`u3m_wall()`.
654−
655−It's sometimes nice to run a mark-and-sweep garbage collector,
656−`u3m_grab()`, which collects the world from a list of roots,
657−and asserts if it finds any leaks or incorrect refcounts. This
658−tool is for debugging and long-term maintenance only; refcounts
659−should never err.
660−
661−### u3j: jets
662−
663−The jet system, `u3j`, is what makes `u3` and `nock` in any sense
664−a useful computing environment. Except perhaps `u3a` (there is
665−really no such thing as a trivial allocator, though `u3a` is
666−dumber than most) - `u3j` is the most interesting code in `u3`.
667−
668−Let's consider the minor miracle of driver-to-battery binding
669−which lets `u3j` work - and decrement not be `O(n)` - without
670−violating the precisely defined semantics of pure Nock, *ever*.
671−
672−It's easy to assume that jets represent an architectural coupling
673−between Hoon language semantics and Nock interpreter internals.
674−Indeed such a coupling would be wholly wrongtious and un-Urbit.
675−But the jet system is not Hoon-specific. It is specific to nock
676−runtime systems that use a design pattern we call a `core`.
677−
678−#### u3j: core structure
679−
680−A core is no more than a cell `[code data]`, in which a `code` is
681−either a Nock formula or a cell of `code`s, and `data` is anything.
682−In a proper core, the subject each formula expects is the core
683−itself.
684−
685−Except for the arbitrary decision to make a core `[code data]`,
686−(or as we sometimes say, `[battery payload]`), instead of `[data
687−code]`, any high-level language transforming itself to Nock would
688−use this design.
689−
690−So jets are in fact fully general. Broadly speaking, the jet
691−system works by matching a C *driver* to a battery. When the
692−battery is invoked with Nock operator `9`, it must be found in
693−associative memory and linked to its driver. Then we link the
694−formula axis of the operation (`a` in `[9 a b]`) to a specific
695−function in the driver.
696−
697−To validate this jet binding, we need to know two things. One,
698−we need to know the C function actually is a perfect semantic
699−match for the Nock formula. This can be developed with driver
700−test flags, which work, and locked down with a secure formula
701−hash in the driver, which we haven't bothered with just yet.
702−(You could also try to develop a formal method for verifying
703−that C functions and Nock formulas are equivalent, but this is
704−a research problem for the future.)
705−
706−Two, we need to validate that the payload is appropriate for the
707−battery. We should note that jets are a Nock feature and have no
708−reference to Hoon. A driver which relies on the Hoon type system
709−to only pair it with valid payloads is a broken driver, and
710−breaks the Nock compliance of the system as a whole. So don't.
711−
712−Now, a casual observer might look at `[battery payload]` and
713−expect the simplest case of it to be `[formula subject]`. That
714−is: to execute a simple core whose battery is a single formula,
715−we compute
716−
717− nock(+.a -.a)
718−
719−Then, naturally, when we go from Hoon or a high-level language
720−containing functions down to Nock, `[function arguments]` turns
721−into `[formula subject]`. This seems like an obvious design, and
722−we mention it only because it is *completely wrong*.
723−
724−Rather, to execute a one-armed core like the above, we run
725−
726− nock(a -.a)
727−
728−and the normal structure of a `gate`, which is simply Urbitese
729−for "function," is:
730−
731− [formula [sample context]]
732−
733−where `sample` is Urbitese for "arguments" - and `context`, any
734−Lisper will at once recognize, is Urbitese for "environment."
735−
736−To `slam` or call the gate, we simply replace the default sample
737−with the caller's data, then nock the formula on the entire gate.
738−
739−What's in the context? Unlike in most dynamic languages, it is
740−not some secret system-level bag of tricks. Almost always it is
741−another core. This onion continues until at the bottom, there is
742−an atomic constant, conventionally is the kernel version number.
743−
744−Thus a (highly desirable) `static` core is one of the form
745−
746− [battery constant]
747− [battery static-core]
748−
749−ie, a solid stack of nested libraries without any dynamic data.
750−The typical gate will thus be, for example,
751−
752− [formula [sample [battery battery battery constant]]]
753−
754−but we would be most foolish to restrict the jet mechanism to
755−cores of this particular structure. We cannot constrain a
756−payload to be `[sample static-core]`, or even `[sample core]`.
757−Any such constraint would not be rich enough to handle Hoon,
758−let alone other languages.
759−
760−#### u3j: jet state
761−
762−There are two fundamental rules of computer science: (1) every
763−system is best understood through its state; (2) less state is
764−better than more state. Sadly, a pier has three different jet
765−state systems: `cold`, `warm` and `hot`. It needs all of them.
766−
767−Hot state is associated with this particular Unix process. The
768−persistent pier is portable not just between process and process,
769−but machine and machine or OS and OS. The set of jets loaded
770−into a pier may itself change (in theory, though not in the
771−present implementation) during the lifetime of the process. Hot
772−state is a pure C data structure.
773−
774−Cold state is associated with the logical execution history of
775−the pier. It consists entirely of nouns and ignores restarts.
776−
777−Warm state contains all dependencies between cold and hot
778−state. It consists of C structures allocated on the loom.
779−
780−Warm state is purely a function of cold and hot states, and
781−we can wipe and regenerate it at any time. On any restart where
782−the hot state might have changed, we clear the warm state
783−with `u3j_ream()`.
784−
785−There is only one hot state, the global jet dashboard
786−`u3j_Dash` or `u3D` for short. In the present implementation,
787−u3D is a static structure not modified at runtime, except for
788−numbering itself on process initialization. This structure -
789−which embeds function pointers to all the jets - is defined
790−in `j/tree.c`. The data structures:
791−
792− /* u3j_harm: driver arm.
793− */
794− typedef struct _u3j_harm {
795− c3_c* fcs_c; // `.axe` or name
796− u3_noun (*fun_f)(u3_noun); // compute or 0 / semitransfer
797− c3_o ice; // perfect (don't test)
798− c3_o tot; // total (never punts)
799− c3_o liv; // live (enabled)
800− } u3j_harm;
801−
802− /* u3j_core: C core driver.
803− */
804− typedef struct _u3j_core {
805− c3_c* cos_c; // control string
806− struct _u3j_harm* arm_u; // blank-terminated static list
807− struct _u3j_core* dev_u; // blank-terminated static list
808− struct _u3j_core* par_u; // dynamic parent pointer
809− c3_l jax_l; // dynamic jet index
810− } u3j_core;
811−
812− /* u3e_dash, u3_Dash, u3D: jet dashboard singleton
813− */
814− typedef struct _u3e_dash {
815− u3j_core* dev_u; // null-terminated static list
816− c3_l len_l; // ray_u filled length
817− c3_l all_l; // ray_u allocated length
818− u3j_core* ray_u; // dynamic driver array
819− } u3j_dash;
820−
821−Warm and cold state is *per road*. In other words, as we nest
822−roads, we also nest jet state. The jet state in the road is:
823−
824− struct { // jet dashboard
825− u3p(u3h_root) har_p; // warm state
826− u3_noun das; // cold state
827− } jed;
828−
829−In case you understand Hoon, `das` (cold state) is a `++dash`,
830−and `har_p` (warm state) is a map from battery to `++calx`:
831−
832− ++ bane ,@tas :: battery name
833− ++ bash ,@uvH :: label hash
834− ++ bosh ,@uvH :: local battery hash
835− ++ batt ,* :: battery
836− ++ calf ::
837− $: jax=,@ud :: hot core index
838− hap=(map ,@ud ,@ud) :: axis/hot arm index
839− lab=path :: label as path
840− jit=* :: arbitrary data
841− == ::
842− ++ calx (trel calf (pair bash cope) club) :: cached by battery
843− ++ clog (pair cope (map batt club)) :: identity record
844− ++ club (pair corp (map term nock)) :: battery pattern
845− ++ cope (trel bane axis (each bash noun)) :: core pattern
846− ++ core ,* :: core
847− ++ corp (each core batt) :: parent or static
848− ++ dash (map bash clog) :: jet system
849−
850−The driver index `jax` in a `++calx` is an index into `ray_u` in the
851−dashboard - ie, a pointer into hot state. This is why the warm
852−state has to be reset when we reload the pier in a new process.
853−
854−Why is jet state nested? Nock of course is a functional system,
855−so as we compute we don't explicitly create state. Jet state is
856−an exception to this principle (which works only because it can't
857−be semantically detected from Nock/Hoon) - but it can't violate
858−the fundamental rules of the allocation system.
859−
860−For instance, when we're on an inner road, we can't allocate on
861−an outer road, or point from an outer road to an inner. So if we
862−learn something - like a mapping from battery to jet - in the
863−inner road, we have to keep it in the inner road.
864−
865−Mitigating this problem, when we leave an inner road (with
866−`u3m_love()`), we call `u3j_reap()` to promote jet information in
867−the dying road. Reaping promotes anything we've learned about
868−any battery that either (a) already existed in the outer road, or
869−(b) is being saved to the outer road.
870−
871−#### u3j: jet binding
872−
873−Jet binding starts with a `%fast` hint. (In Hoon, this is
874−produced by the runes `~%`, for the general case, or `~/`
875−for simple functions.) To bind a jet, execute a formula of the
876−form:
877−
878− [10 [%fast clue-formula] core-formula]
879−
880−`core-formula` assembles the core to be jet-propelled.
881−`clue-formula` produces the hint information, or `++clue`
882−above, which we want to annotate it with.
883−
884−A clue is a triple of name, parent, and hooks:
885−
886− ++ clue (trel chum nock (list (pair term nock)))
887−
888−The name, or `++chum`, has a bunch of historical structure which
889−we don't need (cleaning these things up is tricky), but just gets
890−flattened into a term.
891−
892−The parent axis is a nock formula, but always reduces to a simple
893−axis, which is the address of this core's *parent*. Consider
894−again an ordinary gate
895−
896− [formula [sample context]]
897−
898−Typically the `context` is itself a library core, which itself
899−has a jet binding. If so, the parent axis of this gate is `7`.
900−
901−If the parent is already bound - and the parent *must* be already
902−bound, in this road or a road containing it - we can hook this core
903−bottom-up into a tree hierarchy. Normally the child core is
904−produced by an arm of the parent core, so this is not a problem -
905−we wouldn't have the child if we hadn't already made the parent.
906−
907−The clue also contains a list of *hooks*, named nock formulas on
908−the core. Usually these are arms, but they need not be. The
909−point is that we often want to call a core from C, in a situation
910−where we have no type or other source information. A common case
911−of this is a complex system in which we're mixing functions which
912−are jet-propelled with functions that aren't.
913−
914−In any case, all the information in the `%fast` hint goes to
915−`u3j_mine()`, which registers the battery in cold state (`das` in
916−`jed` in `u3R`), then warm state (`har_p` in `jed`).
917−
918−It's essential to understand that the `%fast` hint has to be,
919−well, fast - because we apply it whenever we build a core. For
920−instance, if the core is a Hoon gate - a function - we will call
921−`u3j_mine` every time the function is called.
922−
923−### u3j: the cold jet dashboard
924−
925−For even more fun, the jet tree is not actually a tree of
926−batteries. It's a tree of battery *labels*, where a label is
927−an [axis term] path from the root of the tree. (At the root,
928−if the core pattern is always followed properly, is a core whose
929−payload is an atomic constant, conventionally the Hoon version.)
930−
931−Under each of these labels, it's normal to have an arbitrary
932−number of different Nock batteries (not just multiple copies
933−of the same noun, a situation we *do* strive to avoid). For
934−instance, one might be compiled with debugging hints, one not.
935−
936−We might even have changed the semantics of the battery without
937−changing the label - so long as those semantics don't invalidate
938−any attached driver.
939−
940−et tree. For instance, it's normal to have
941−two equivalent Nock batteries at the same time in one pier: one
942−battery compiled with debugging hints, one not.
943−
944−Rather, the jet tree is a semantic hierarchy. The root of the
945−hierarchy is a constant, by convention the Hoon kernel version
946−because any normal jet-propelled core has, at the bottom of its
947−onion of libraries, the standard kernel. Thus if the core is
948−
949− [foo-battery [bar-battery [moo-battery 164]]]
950−
951−we can reverse the nesting to construct a hierarchical core
952−path. The static core
953−
954− 164/moo/bar/foo
955−
956−extends the static core `164/moo/bar` by wrapping the `foo`
957−battery (ie, in Hoon, `|%`) around it. With the core above,
958−you can compute `foo` stuff, `bar` stuff, and `moo` stuff.
959−Rocket science, not.
960−
961−Not all cores are static, of course - they may contain live data,
962−like the sample in a gate (ie, argument to a function). Once
963−again, it's important to remember that we track jet bindings not
964−by the core, which may not be static, but by the battery, which
965−is always static.
966−
967−(And if you're wondering how we can use a deep noun like a Nock
968−formula or battery as a key in a key-value table, remember
969−`mug_w`, the lazily computed short hash, in all boxed nouns.)
970−
971−In any case, `das`, the dashboard, is a map from `bash` to jet
972−location record (`++clog`). A `clog` in turn contains two kinds
973−of information: the `++cope`, or per-location noun; and a map of
974−batteries to a per-battery `++club`.
975−
976−The `cope` is a triple of `++bane` (battery name, right now just
977−a `term`); `++axis`, the axis, within *this* core, of the parent;
978−and `(each bash noun)`, which is either `[0 bash]` if the parent
979−is another core, or `[1 noun]`, for the constant noun (like
980−`164`) if there is no parent core.
981−
982−A `bash` is just the noun hash (`++sham`) of a `cope`, which
983−uniquely expresses the battery's hierarchical location without
984−depending on the actual formulas.
985−
986−The `club` contains a `++corp`, which we use to actually validate
987−the core. Obviously jet execution has to be perfectly compatible
988−with Nock. We search on the battery, but getting the battery
989−right is not enough - a typical battery is dependent on its
990−context. For example, your jet-propelled library function is
991−very likely to call `++dec` or other advanced kernel technology.
992−If you've replaced the kernel in your context with something
993−else, we need to detect this and not run the jet.
994−
995−There are two cases for a jet-propelled core - either the entire
996−core is a static constant, or it isn't. Hence the definition
997−of `corp`:
998−
999− ++ corp (each core batt) :: parent or static
1000−
1001−Ie, a `corp` is `[0 core]` or `[1 batt]`. If it's static -
1002−meaning that the jet only works with one specific core, ie, the
1003−parent axis of each location in the hierarchy is `3` - we can
1004−validate with a single comparison. Otherwise, we have to recurse
1005−upward by checking the parent.
1006−
1007−Note that there is at present no way to force a jet to depend on
1008−static *data*.
1009−
1010−### u3j: the warm jet dashboard
1011−
1012−We don't use the cold state to match jets as we call them. We
1013−use the cold state to register jets as we find them, and also to
1014−rebuild the warm state after the hot state is reset.
1015−
1016−What we actually use at runtime is the warm state, `jed->har_p`,
1017−which is a `u3h` (built-in hashtable), allocated on the loom,
1018−from battery to `++calx`.
1019−
1020−A `calx` is a triple of a `++calf`, a `[bash cope]` cell, and a
1021−`club`. The latter two are all straight from cold state.
1022−
1023−The `calf` contains warm data dependent on hot state. It's a
1024−quadruple: of `jax`, the hot driver index (in `ray_u` in
1025−`u3j_dash`); `hap`, a table from arm axis (ie, the axis of each
1026−formula within the battery) to driver arm index (into `arm_u` in
1027−`u3j_core`); `lab`, the complete label path; and `jit`, any
1028−other dynamic data that may speed up execution.
1029−
1030−We construct `hap`, when we create the calx, by iterating through
1031−the arms registered in the `u3j_core`. Note the way a `u3j_harm`
1032−declares itself, with the string `fcs_c` which can contain either
1033−an axis or a name. Most jetted cores are of course gates, which
1034−have one formula at one axis within the core: `fcs_c` is `".3"`.
1035−
1036−But we do often have fast cores with more complex arm structure,
1037−and it would be sad to have to manage their axes by hand. To use
1038−an `fcs_c` with a named arm, it's sufficient to make sure the
1039−name is bound to a formula `[0 axis]` in the hook table.
1040−
1041−`jit`, as its name suggests, is a stub where any sort of
1042−optimization data computed on battery registration might go. To
1043−use it, fill in the `_cj_jit()` function.
1044−
1045−### u3j: the hot dashboard
1046−
1047−Now it should be easy to see how we actually invoke jets. Every
1048−time we run a nock `9` instruction (pretty often, obviously), we
1049−have a core and an axis. We pass these to `u3j_kick()`, which
1050−will try to execute them.
1051−
1052−Because nouns with a reference count of 1 are precious,
1053−`u3j_kick()` has a tricky reference control definition. It
1054−reserves the right to return `u3_none` in the case where there is
1055−no driver, or the driver does not apply for this case; in this
1056−case, it retains argument `cor`. If it succeeds, though, it
1057−transfers `cor`.
1058−
1059−`u3j_kick()` searches for the battery (always the head of the
1060−core, of course) in the hot dashboard. If the battery is
1061−registered, it searches for the axis in `hap` in the `calx`.
1062−If it exists, the core matches a driver and the driver jets this
1063−arm. If not, we return `u3_none`.
1064−
1065−Otherwise, we call `fun_f` in our `u3j_harm`. This obeys the
1066−same protocol as `u3j_kick()`; it can refuse to function by
1067−returning `u3_none`, or consume the noun.
1068−
1069−Besides the actual function pointer `fun_f`, we have some flags
1070−in the `u3j_harm` which tell us how to call the arm function.
1071−
1072−If `ice` is yes (`&`, `0`), the jet is known to be perfect and we
1073−can just trust the product of `fun_f`. Otherwise, we need to run
1074−*both* the Nock arm and `fun_f`, and compare their results.
1075−
1076−(Note that while executing the C side of this test, we have to
1077−set `ice` to yes; on the Nock side, we have to set `liv` to no.
1078−Otherwise, many non-exponential functions become exponential.
1079−When auto-testing jets in this way, the principle is that the
1080−test is on the outermost layer of recursion.)
1081−
1082−(Note also that anyone who multi-threads this execution
1083−environment has a slight locking problem with these flags if arm
1084−testing is multi-threaded.)
1085−
1086−If `tot` is yes, (`&`, `0`), the arm function is *total* and has
1087−to return properly (though it can still return *u3_none*).
1088−Otherwise, it is *partial* and can `u3_cm_bail()` out with
1089−c3__punt. This feature has a cost: the jet runs in a subroad.
1090−
1091−Finally, if `liv` is no (`|`, 1), the jet is off and doesn't run.
1092−
1093−It should be easy to see how the tree of cores gets declared -
1094−precisely, in `j/dash.c`. We declare the hierarchy as a tree
1095−of `u3j_core` structures, each of which comes with a static list
1096−of arms `arm_u` and sub-cores `dev_u`.
1097−
1098−In `u3j_boot()`, we traverse the hierarchy, fill in parent
1099−pointers `par_u`, and enumerate all `u3j_core` structures
1100−into a single flat array `u3j_dash.ray_u`. Our hot state
1101−then appears ready for action.
1102−
1103−### u3j: jet functions
1104−
1105−At present, all drivers are compiled statically into `u3`. This is
1106−not a long-term permanent solution or anything. However, it will
1107−always be the case with a certain amount of core functionality.
1108−
1109−For instance, there are some jet functions that we need to call
1110−as part of loading the Arvo kernel - like `++cue` to unpack a
1111−noun from an atom. And obviously it makes sense, when jets are
1112−significant enough to compile into `u3`, to export their symbols
1113−in headers and the linker.
1114−
1115−There are three interface prefixes for standard jet functions:
1116−`u3k`, `u3q`, and `u3w`. All jets have `u3w` interfaces; most
1117−have `u3q`; some have `u3k`. Of course the actual logic is
1118−shared.
1119−
1120−`u3w` interfaces use the same protocol as `fun_f` above: the
1121−caller passes the entire core, which is retained if the function
1122−returns `u3_none`, transferred otherwise. Why? Again, use
1123−counts of 1 are special and precious for performance hackers.
1124−
1125−`u3q` interfaces break the core into C arguments, *retain* noun
1126−arguments, and *transfer* noun returns. `u3k` interfaces are the
1127−same, except with more use of `u3_none` and other simple C
1128−variations on the Hoon original, but *transfer* both arguments
1129−and returns. Generally, `u3k` are most convenient for new code.
1130−
1131−Following `u3k/q/w` is `[a-f]`, corresponding to the 6 logical
1132−tiers of the kernel, or `g` for user-level jets. Another letter
1133−is added for functions within subcores. The filename, under
1134−`j/`, follows the tier and the function name.
1135−
1136−For instance, `++add` is `u3wa_add(cor)`, `u3qa_add(a, b)`, or
1137−`u3ka_add(a, b)`, in `j/a/add.c`. `++get` in `++by` is
1138−`u3wdb_get(cor)`, `u3kdb_get(a, b)`, etc, in `j/d/by_get.c`.
1139−
1140−For historical reasons, all internal jet code in `j/[a-f]`
1141−*retains* noun arguments, and *transfers* noun results. Please
1142−do not do this in new `g` jets! The new standard protocol is to
1143−transfer both arguments and results.
1144−
1145−### u3a: allocation functions
1146−
1147−`u3a` allocates on the current road (u3R). Its internal
1148−structures are uninteresting and typical of a naive allocator.
1149−
1150−The two most-used `u3a` functions are `u3a_gain()` to add a
1151−reference count, and `u3a_lose()` to release one (and free the
1152−noun, if the use count is zero). For convenience, `u3a_gain()`
1153−returns its argument. The pair are generally abbreviated with
1154−the macros `u3k()` and `u3z()` respectively.
1155−
1156−Normally we create nouns through `u3i` functions, and don't call
1157−the `u3a` allocators directly. But if you do:
1158−
1159−One, there are *two* sets of allocators: the word-aligned
1160−allocators and the fully-aligned (ie, malloc compatible)
1161−allocators. For instance, on a typical OS X setup, malloc
1162−produces 16-byte aligned results - needed for some SSE
1163−instructions.
1164−
1165−These allocators are *not compatible*. For 32-bit alignment
1166−as used in nouns, call
1167−
1168− /* u3a_walloc(): allocate storage measured in words.
1169− */
1170− void*
1171− u3a_walloc(c3_w len_w);
1172−
1173− /* u3a_wfree(): free storage.
1174− */
1175− void
1176− u3a_wfree(void* lag_v);
1177−
1178− /* u3a_wealloc(): word realloc.
1179− */
1180− void*
1181− u3a_wealloc(void* lag_v, c3_w len_w);
1182−
1183−For full alignment, call:
1184−
1185− /* u3a_malloc(): aligned storage measured in bytes.
1186− */
1187− void*
1188− u3a_malloc(size_t len_i);
1189−
1190− /* u3a_realloc(): aligned realloc in bytes.
1191− */
1192− void*
1193− u3a_realloc(void* lag_v, size_t len_i);
1194−
1195− /* u3a_realloc2(): gmp-shaped realloc.
1196− */
1197− void*
1198− u3a_realloc2(void* lag_v, size_t old_i, size_t new_i);
1199−
1200− /* u3a_free(): free for aligned malloc.
1201− */
1202− void
1203− u3a_free(void* tox_v);
1204−
1205− /* u3a_free2(): gmp-shaped free.
1206− */
1207− void
1208− u3a_free2(void* tox_v, size_t siz_i);
1209−
1210−There are also a set of special-purpose allocators for building
1211−atoms. When building atoms, please remember that it's incorrect
1212−to have a high 0 word - the word length in the atom structure
1213−must be strictly correct.
1214−
1215−Of course, we don't always know how large our atom will be.
1216−Therefore, the standard way of building large atoms is to
1217−allocate a block of raw space with `u3a_slab()`, then chop off
1218−the end with `u3a_malt()` (which does the measuring itself)
1219−or `u3a_mint()` in case you've measured it yourself.
1220−
1221−Once again, *do not call `malloc()`* (or C++ `new`) within any
1222−code that may be run within a jet. This will cause rare sporadic
1223−corruption when we interrupt execution within a `malloc()`. We'd
1224−just override the symbol, but `libuv` uses `malloc()` across
1225−threads within its own synchronization primitives - for this to
1226−work with `u3a_malloc()`, we'd have to introduce our own locks on
1227−the surface-level road (which might be a viable solution).
1228−
1229−### u3n: nock execution
1230−
1231−The `u3n` routines execute Nock itself. On the inside, they have
1232−a surprising resemblance to the spec proper (the only interesting
1233−detail is how we handle tail-call elimination) and are, as one
1234−would expect, quite slow. (There is no such thing as a fast tree
1235−interpreter.)
1236−
1237−There is only one Nock, but there are lots of ways to call it.
1238−(Remember that all `u3n` functions *transfer* C arguments and
1239−returns.)
1240−
1241−The simplest interpreter, `u3n_nock_on(u3_noun bus, u3_noun fol)`
1242−invokes Nock on `bus` (the subject) and `fol` (the formula).
1243−(Why is it`[subject formula]`, not `[formula subject]`? The same
1244−reason `0` is true and `1` is false.)
1245−
1246−A close relative is `u3n_slam_on(u3_noun gat, u3_noun sam)`,
1247−which slams a *gate* (`gat`) on a sample (`sam`). (In a normal
1248−programming language which didn't talk funny and was retarded,
1249−`u3n_slam_on()` would call a function on an argument.) We could
1250−write it most simply as:
1251−
1252− u3_noun
1253− u3n_slam_on(u3_noun gat, u3_noun sam)
1254− {
1255− u3_noun pro = u3n_nock_on
1256− (u3nc(u3k(u3h(gat)),
1257− u3nc(sam, u3k(u3t(u3t(gat))))),
1258− u3k(u3h(gat)));
1259− u3z(gat);
1260− return pro;
1261− }
1262−
1263−Simpler is `u3n_kick_on(u3_noun gat)`, which slams a gate (or,
1264−more generally, a *trap* - because sample structure is not even
1265−needed here) without changing its sample:
1266−
1267− u3_noun
1268− u3n_kick_on(u3_noun gat, u3_noun sam)
1269− {
1270− return u3n_nock_on(gat, u3k(u3h(gat)));
1271− }
1272−
1273−The `_on` functions in `u3n` are all defined as pure Nock. But
1274−actually, even though we say we don't extend Nock, we do. But we
1275−don't. But we do.
1276−
1277−Note that `u3` has a well-developed error handling system -
1278−`u3m_bail()` to throw an exception, `u3m_soft_*` to catch one.
1279−But Nock has no exception model at all. That's okay - all it
1280−means if that if an `_on` function bails, the exception is an
1281−exception in the caller.
1282−
1283−However, `u3`'s exception handling happens to match a convenient
1284−virtual super-Nock in `hoon.hoon`, the infamous `++mock`. Of
1285−course, Nock is slow, and `mock` is Nock in Nock, so it is
1286−(logically) super-slow. Then again, so is decrement.
1287−
1288−With the power of `u3`, we nest arbitrary layers of `mock`
1289−without any particular performance cost. Moreover, we simply
1290−treat Nock proper as a special case of `mock`. (More precisely,
1291−the internal VM loop is `++mink` and the error compiler is
1292−`++mook`. But we call the whole sandbox system `mock`.)
1293−
1294−The nice thing about `mock` functions is that (by executing
1295−within `u3m_soft_run()`, which as you may recall uses a nested
1296−road) they provide both exceptions and the namespace operator -
1297−`.^` in Hoon, which becomes operator `11` in `mock`.
1298−
1299−`11` requires a namespace function, or `fly`, which produces a
1300−`++unit` - `~` (`0`) for no binding, or `[0 value]`. The sample
1301−to a `fly` is a `++path`, just a list of text `span`.
1302−
1303−`mock` functions produce a `++toon`. Fully elaborated:
1304−
1305− ++ noun ,* :: any noun
1306− ++ path (list ,@ta) :: namespace path
1307− ++ span ,@ta :: text-atom (ASCII)
1308− ++ toon $% [%0 p=noun] :: success
1309− [%1 p=(list path)] :: blocking paths
1310− [%2 p=(list tank)] :: stack trace
1311− == ::
1312− ++ tank :: printable
1313− $% [%leaf p=tape] :: flat text
1314− $: %palm :: backstep list
1315− p=[p=tape q=tape r=tape s=tape] :: mid cap open close
1316− q=(list tank) :: contents
1317− == ::
1318− $: %rose :: straight list
1319− p=[p=tape q=tape r=tape] :: mid open close
1320− q=(list tank) :: contents
1321− == ::
1322− ==
1323−
1324−(Note that `tank` is overdesigned and due for replacement.)
1325−
1326−What does a `toon` mean? Either your computation succeded (`[0
1327−noun]`, or could not finish because it blocked on one or more
1328−global paths (`[1 (list path)]`), or it exited with a stack trace
1329−(`[2 (list tank)]`).
1330−
1331−Note that of all the `u3` exceptions, only `%exit` is produced
1332−deterministically by the Nock definition. Therefore, only
1333−`%exit` produces a `2` result. Any other argument to
1334−`u3m_bail()` will unwind the virtualization stack all the way to
1335−the top - or to be more exact, to `u3m_soft_top()`.
1336−
1337−In any case, the simplest `mock` functions are `u3n_nock_un()`
1338−and `u3n_slam_un()`. These provide exception control without
1339−any namespace change, as you can see by the code:
1340−
1341− /* u3n_nock_un(): produce .*(bus fol), as ++toon.
1342− */
1343− u3_noun
1344− u3n_nock_un(u3_noun bus, u3_noun fol)
1345− {
1346− u3_noun fly = u3nt(u3nt(11, 0, 6), 0, 0); // |=(a=* .^(a))
1347−
1348− return u3n_nock_in(fly, bus, fol);
1349− }
1350−
1351− /* u3n_slam_un(): produce (gat sam), as ++toon.
1352− */
1353− u3_noun
1354− u3n_slam_un(u3_noun gat, u3_noun sam)
1355− {
1356− u3_noun fly = u3nt(u3nt(11, 0, 6), 0, 0); // |=(a=* .^(a))
1357−
1358− return u3n_slam_in(fly, gat, sam);
1359− }
1360−
1361−The `fly` is added as the first argument to `u3n_nock_in()` and
1362−`u3n_slam_in()`. Of course, logically, `fly` executes in the
1363−caller's exception layer. (Maintaining this illusion is slightly
1364−nontrivial.) Finally, `u3n_nock_an()` is a sandbox with a null
1365−namespace.
1366−
1367−### u3e: persistence
1368−
1369−The only `u3e` function you should need to call is `u3e_save()`,
1370−which saves the loom. As it can be restored on any platform,
1371−please make sure you don't have any state in the loom that is
1372−bound to your process or architecture - except for exceptions
1373−like the warm jet state, which is actively purged on reboot.
1374−
1375−### u3r: reading nouns (weak)
1376−
1377−As befits accessors they don't make anything, `u3r` noun reading
1378−functions always retain their arguments and their returns. They
1379−never bail; rather, when they don't work, they return a `u3_weak`
1380−result.
1381−
1382−Most of these functions are straightforward and do only what
1383−their comments say. A few are interesting enough to discuss.
1384−
1385−`u3r_at()` is the familiar tree fragment function, `/` from the
1386−Nock spec. For taking complex nouns apart, `u3r_mean()` is a
1387−relatively funky way of deconstructing nouns with a varargs list
1388−of `axis`, `u3_noun *`. For cells, triples, etc, decompose with
1389−`u3r_cell()`, `u3r_trel()`, etc. For the tagged equivalents, use
1390−`u3r_pq()` and friends.
1391−
1392−`u3r_sing(u3_noun a, u3_noun b)` (true if `a` and `b` are a
1393−*single* noun) are interesting because it uses mugs to help it
1394−out. Clearly, different nouns may have the same mug, but the
1395−same nouns cannot have a different mug. It's important to
1396−understand the performance characteristics of `u3r_sing()`:
1397−the worst possible case is a comparison of duplicate nouns,
1398−which have the same value but were created separately. In this
1399−case, the tree is traversed
1400−
1401−`u3r_sung()` is a deeply funky and frightening version of
1402−`u3r_sing()` that unifies pointers to the duplicate nouns it
1403−finds, freeing the second copy. Obviously, do not use
1404−`u3r_sung()` when you have live, but not reference counted, noun
1405−references from C - if they match a noun with a refcount of 1
1406−that gets freed, bad things happen.
1407−
1408−It's important to remember that `u3r_mug()`, which produces a
1409−31-bit, nonzero insecure hash, uses the `mug_w` slot in any boxed
1410−noun as a lazy cache. There are a number of variants of
1411−`u3r_mug()` that can get you out of building unneeded nouns.
1412−
1413−### u3x: reading nouns (bail)
1414−
1415−`u3x` functions are like `u3r` functions, but instead of
1416−returning `u3_none` when (for instance) we try to take the head
1417−of an atom, they bail with `%exit`. In other words, they do what
1418−the same operation would do in Nock.
1419−
1420−### u3h: hash tables.
1421−
1422−We can of course use the Hoon `map` structure as an associative
1423−array. This is a balanced treap and reasonably fast. However,
1424−it's considerably inferior to a custom structure like an HAMT
1425−(hash array-mapped trie). We use `u3_post` to allocate HAMT
1426−structures on the loom.
1427−
1428−(Our HAMT implements the classic Bagwell algorithm which depends
1429−on the `gcc` standard directive `__builtin_popcount()`. On a CPU
1430−which doesn't support popcount or an equivalent instruction, some
1431−other design would probably be preferable.)
1432−
1433−There's no particular rocket science in the API. `u3h_new()`
1434−creates a hashtable; `u3h_free()` destroys one; `u3h_put()`
1435−inserts, `u3h_get()` retrieves. You can transform values in a
1436−hashtable with `u3h_walk()`.
1437−
1438−The only funky function is `u3h_gut()`, which unifies keys with
1439−`u3r_sung()`. As with all cases of `u3r_sung()`, this must be
1440−used with extreme caution.
1441−
1442−### u3z: memoization
1443−
1444−Connected to the `~+` rune in Hoon, via the Nock `%memo` hint,
1445−the memoization facility is a general-purpose cache.
1446−
1447−(It's also used for partial memoization - a feature that'll
1448−probably be removed, in which conservative worklist algorithms
1449−(which would otherwise be exponential) memoize everything in the
1450−subject *except* the worklist. This is used heavily in the Hoon
1451−compiler jets (j/f/*.c). Unfortunately, it's probably not
1452−possible to make this work perfectly in that it can't be abused
1453−to violate Nock, so we'll probably remove it at a later date,
1454−instead making `++ut` keep its own monadic cache.)
1455−
1456−Each `u3z` function comes with a `c3_m` mote which disambiguates
1457−the function mapping key to value. For Nock itself, use 0. For
1458−extra speed, small tuples are split out in C; thus, find with
1459−
1460− u3_weak u3z_find(c3_m, u3_noun);
1461− u3_weak u3z_find_2(c3_m, u3_noun, u3_noun);
1462− u3_weak u3z_find_3(c3_m, u3_noun, u3_noun, u3_noun);
1463− u3_weak u3z_find_4(c3_m, u3_noun, u3_noun, u3_noun, u3_noun);
1464−
1465−and save with
1466−
1467− u3_noun u3z_save(c3_m, u3_noun, u3_noun);
1468− u3_noun u3z_save_2(c3_m, u3_noun, u3_noun, u3_noun);
1469− u3_noun u3z_save_3(c3_m, u3_noun, u3_noun, u3_noun, u3_noun);
1470− u3_noun u3z_save_4(c3_m, u3_noun, u3_noun, u3_noun, u3_noun, u3_noun);
1471−
1472−where the value is the last argument. To eliminate duplicate
1473−nouns, there is also
1474−
1475− u3_noun
1476− u3z_uniq(u3_noun);
1477−
1478−`u3z` functions retain keys and transfer values.
1479−
1480−The `u3z` cache, built on `u3h` hashes, is part of the current
1481−road, and goes away when it goes away. (In future, we may wish
1482−to promote keys/values which outlive the road, as we do with jet
1483−state.) There is no cache reclamation at present, so be careful.
1484−
1485−### u3t: tracing and profiling.
1486−
1487−TBD.
1488−
1489−### u3v: the Arvo kernel
1490−
1491−An Arvo kernel - or at least, a core that compiles with the Arvo
1492−interface - is part of the global `u3` state. What is an Arvo
1493−core? Slightly pseudocoded:
1494−
1495− ++ arvo
1496− |%
1497− ++ come |= [yen=@ ova=(list ovum) nyf=pone] :: 11
1498− ^- [(list ovum) _+>]
1499− !!
1500− ++ keep |= [now=@da hap=path] :: 4
1501− ^- (unit ,@da)
1502− !!
1503− ++ load |= [yen=@ ova=(list ovum) nyf=pane] :: 86
1504− ^- [(list ovum) _+>]
1505− !!
1506− ++ peek |= [now=@da path] :: 87
1507− ^- (unit)
1508− !!
1509− ++ poke |= [now=@da ovo=ovum] :: 42
1510− ^- [(list ovum) _+>]
1511− !!
1512− ++ wish |= txt=@ta :: 20
1513− ^- *
1514− !!
1515− --
1516− ++ card ,[p=@tas q=*] :: typeless card
1517− ++ ovum ,[p=wire q=card] :: Arvo event
1518− ++ wire path :: event cause
1519−
1520−This is the Arvo ABI in a very real sense. Arvo is a core with
1521−these six arms. To use these arms, we hardcode the axis of the
1522−formula (`11`, `4`, `86`, etc) into the C code that calls Arvo,
1523−because otherwise we'd need type metadata - which we can get, by
1524−calling Arvo.
1525−
1526−It's important to understand the Arvo event/action structure, or
1527−`++ovum`. An `ovum` is a `card`, which is any `[term noun]`
1528−cell, and a `++wire`, a `path` which indicates the location of
1529−the event. At the Unix level, the `wire` corresponds to a system
1530−module or context. For input events, this is the module that
1531−caused the event; for output actions, it's the module that
1532−performs the action.
1533−
1534−`++poke` sends Arvo an event `ovum`, producing a cell of action
1535−ova and a new Arvo core.
1536−
1537−`++peek` dereferences the Arvo namespace. It takes a date and a
1538−key, and produces `~` (`0`) or `[~ value]`.
1539−
1540−`++keep` asks Arvo the next time it wants to be woken up, for the
1541−given `wire`. (This input will probably be eliminated in favor
1542−of a single global timer.)
1543−
1544−`++wish` compiles a string of Hoon source. While just a
1545−convenience, it's a very convenient convenience.
1546−
1547−`++come` and `++load` are used by Arvo to reset itself (more
1548−precisely, to shift the Arvo state from an old kernel to a new
1549−one); there is no need to call them from C.
1550−
1551−Now that we understand the Arvo kernel interface, let's look at
1552−the `u3v` API. As usual, all the functions in `u3v` are
1553−commented, but unfortunately it's hard to describe this API as
1554−clean at present. The problem is that `u3v` remains design
1555−coupled to the old `vere` event handling code written for `u2`.
1556−But let's describe the functions you should be calling, assuming
1557−you're not writing the next event system. There are only two.
1558−
1559−`u3v_wish(str_c)` wraps the `++wish` functionality in a cache
1560−(which is read-only unless you're on the surface road).
1561−
1562−`u3v_do()` uses `wish` to provide a convenient interface for
1563−calling Hoon kernel functions by name. Even more conveniently,
1564−we tend to call `u3v_do()` with these convenient aliases:
1565−
1566− #define u3do(txt_c, arg) u3v_do(txt_c, arg)
1567− #define u3dc(txt_c, a, b) u3v_do(txt_c, u3nc(a, b))
1568− #define u3dt(txt_c, a, b, c) u3v_do(txt_c, u3nt(a, b, c))
1569− #define u3dq(txt_c, a, b, c, d) u3v_do(txt_c, u3nt(a, b, c, d))
1570−