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