on master help sign in
Adding back forgotten vere docs
commit847c5e46198728f1c0e5d38c7f95b6622b71f370 authorjoshuareagan <joshuareagan@gmail.com> dateMon 24 Sep 2018, 10:40 (8 years ago) parente5863d1
5 files changed+2447
docs/vere/api.umd+1043 docs/vere/c.umd+117 docs/vere/jetting.umd+761 docs/vere/nouns.umd+480 docs/vere/runtime.umd+46
docs/vere/api.umdnew file+1043
@@ -0,0 +1,1043 @@
1+:- :~ navhome/'/docs/'
2+ sort/'4'
3+ next/'true'
4+ title/'API overview by prefix'
5+ ==
6+;>
7+
8+## u3: API overview by prefix
9+
10+Let's run through the `u3` modules one by one. All public
11+functions are commented, but the comments may be cryptic.
12+
13+### u3m: main control
14+
15+To start `u3`, run
16+
17+```
18+/* u3m_boot(): start the u3 system.
19+*/
20+ void
21+ u3m_boot(c3_o nuu_o, c3_o bug_o, c3_c* dir_c);
22+```
23+
24+`nuu_o` is `c3y` (yes, `0`) if you're creating a new pier,
25+`c3n` (no, `1`) if you're loading an existing one. `bug_o`
26+is `c3y` if you want to test the garbage-collector, `c3n`
27+otherwise. `dir_c` is the directory for the pier files.
28+
29+`u3m_boot()` expects an `urbit.pill` file to load the kernel
30+from. It will try first `$dir/.urb.urbit.pill`, then `U3_LIB`.
31+
32+Any significant computation with nouns, certainly anything Turing
33+complete, should be run (a) virtualized and (b) in an inner road.
34+These are slightly different things, but at the highest level we
35+bundle them together for your convenience, in `u3m_soft()`:
36+
37+```
38+/* u3m_soft(): system soft wrapper. unifies unix and nock errors.
39+**
40+** Produces [%$ result] or [%error (list tank)].
41+*/
42+ u3_noun
43+ u3m_soft(c3_w sec_w, u3_funk fun_f, u3_noun arg);
44+```
45+
46+`sec_w` is the number of seconds to time out the computation.
47+`fun_f` is a C function accepting `arg`.
48+
49+The result of `u3m_soft()` is a cell whose head is an atom. If
50+the head is `%$` - ie, `0` - the tail is the result of
51+`fun_f(arg)`. Otherwise, the head is a `term` (an atom which is
52+an LSB first string), and the tail is a `(list tank)` (a list of
53+`tank` printables - see `++tank` in `hoon.hoon`). Error terms
54+should be the same as the exception terms above.
55+
56+If you're confident that your computation won't fail, you can
57+use `u3m_soft_sure()`, `u3m_soft_slam()`, or `u3m_soft_nock()`
58+for C functions, Hoon function calls, and Nock invocations.
59+Caution - this returns just the result, and asserts globally.
60+
61+All the `u3m_soft` functions above work *only on the surface*.
62+Within the surface, virtualize with `u3m_soft_run()`. Note that
63+this takes a `fly` (a namespace gate), thus activating the `11`
64+super-operator in the nock virtualizer, `++mock`. When actually
65+using the `fly`, call `u3m_soft_esc()`. Don't do either unless
66+you know what you're doing!
67+
68+For descending into a subroad *without* Nock virtualization,
69+use `u3m_hate()` and `u3m_love` respectively. Hating enters
70+a subroad; loving leaves it, copying out a product noun.
71+
72+Other miscellaneous tools in `u3m`: `u3m_file()` loads a Unix
73+file as a Nock atom; `u3m_water()` measures the boundaries of
74+the loom in current use (ie, watermarks); and a variety of
75+prettyprinting routines, none perfect, are available, mainly for
76+debugging printfs: `u3m_pretty()`, `u3m_p()`, `u3m_tape()` and
77+`u3m_wall()`.
78+
79+It's sometimes nice to run a mark-and-sweep garbage collector,
80+`u3m_grab()`, which collects the world from a list of roots,
81+and asserts if it finds any leaks or incorrect refcounts. This
82+tool is for debugging and long-term maintenance only; refcounts
83+should never err.
84+
85+### u3j: jets
86+
87+The jet system, `u3j`, is what makes `u3` and `nock` in any sense
88+a useful computing environment. Except perhaps `u3a` (there is
89+really no such thing as a trivial allocator, though `u3a` is
90+dumber than most) - `u3j` is the most interesting code in `u3`.
91+
92+Let's consider the minor miracle of driver-to-battery binding
93+which lets `u3j` work - and decrement not be `O(n)` - without
94+violating the precisely defined semantics of pure Nock, *ever*.
95+
96+It's easy to assume that jets represent an architectural coupling
97+between Hoon language semantics and Nock interpreter internals.
98+Indeed such a coupling would be wholly wrongtious and un-Urbit.
99+But the jet system is not Hoon-specific. It is specific to nock
100+runtime systems that use a design pattern we call a `core`.
101+
102+#### u3j: core structure
103+
104+A core is no more than a cell `[code data]`, in which a `code` is
105+either a Nock formula or a cell of `code`s, and `data` is anything.
106+In a proper core, the subject each formula expects is the core
107+itself.
108+
109+Except for the arbitrary decision to make a core `[code data]`,
110+(or as we sometimes say, `[battery payload]`), instead of `[data
111+code]`, any high-level language transforming itself to Nock would
112+use this design.
113+
114+So jets are in fact fully general. Broadly speaking, the jet
115+system works by matching a C *driver* to a battery. When the
116+battery is invoked with Nock operator `9`, it must be found in
117+associative memory and linked to its driver. Then we link the
118+formula axis of the operation (`a` in `[9 a b]`) to a specific
119+function in the driver.
120+
121+To validate this jet binding, we need to know two things. One,
122+we need to know the C function actually is a perfect semantic
123+match for the Nock formula. This can be developed with driver
124+test flags, which work, and locked down with a secure formula
125+hash in the driver, which we haven't bothered with just yet.
126+(You could also try to develop a formal method for verifying
127+that C functions and Nock formulas are equivalent, but this is
128+a research problem for the future.)
129+
130+Two, we need to validate that the payload is appropriate for the
131+battery. We should note that jets are a Nock feature and have no
132+reference to Hoon. A driver which relies on the Hoon type system
133+to only pair it with valid payloads is a broken driver, and
134+breaks the Nock compliance of the system as a whole. So don't.
135+
136+Now, a casual observer might look at `[battery payload]` and
137+expect the simplest case of it to be `[formula subject]`. That
138+is: to execute a simple core whose battery is a single formula,
139+we compute
140+
141+```
142+nock(+.a -.a)
143+```
144+
145+Then, naturally, when we go from Hoon or a high-level language
146+containing functions down to Nock, `[function arguments]` turns
147+into `[formula subject]`. This seems like an obvious design, and
148+we mention it only because it is *completely wrong*.
149+
150+Rather, to execute a one-armed core like the above, we run
151+
152+```
153+nock(a -.a)
154+```
155+
156+and the normal structure of a `gate`, which is simply Urbitese
157+for "function," is:
158+
159+```
160+[formula [sample context]]
161+```
162+
163+where `sample` is Urbitese for "arguments" - and `context`, any
164+Lisper will at once recognize, is Urbitese for "environment."
165+
166+To `slam` or call the gate, we simply replace the default sample
167+with the caller's data, then nock the formula on the entire gate.
168+
169+What's in the context? Unlike in most dynamic languages, it is
170+not some secret system-level bag of tricks. Almost always it is
171+another core. This onion continues until at the bottom, there is
172+an atomic constant, conventionally is the kernel version number.
173+
174+Thus a (highly desirable) `static` core is one of the form
175+
176+```
177+[battery constant]
178+[battery static-core]
179+```
180+
181+ie, a solid stack of nested libraries without any dynamic data.
182+The typical gate will thus be, for example,
183+
184+```
185+[formula [sample [battery battery battery constant]]]
186+```
187+
188+but we would be most foolish to restrict the jet mechanism to
189+cores of this particular structure. We cannot constrain a
190+payload to be `[sample static-core]`, or even `[sample core]`.
191+Any such constraint would not be rich enough to handle Hoon,
192+let alone other languages.
193+
194+#### u3j: jet state
195+
196+There are two fundamental rules of computer science: (1) every
197+system is best understood through its state; (2) less state is
198+better than more state. Sadly, a pier has three different jet
199+state systems: `cold`, `warm` and `hot`. It needs all of them.
200+
201+Hot state is associated with this particular Unix process. The
202+persistent pier is portable not just between process and process,
203+but machine and machine or OS and OS. The set of jets loaded
204+into a pier may itself change (in theory, though not in the
205+present implementation) during the lifetime of the process. Hot
206+state is a pure C data structure.
207+
208+Cold state is associated with the logical execution history of
209+the pier. It consists entirely of nouns and ignores restarts.
210+
211+Warm state contains all dependencies between cold and hot
212+state. It consists of C structures allocated on the loom.
213+
214+Warm state is purely a function of cold and hot states, and
215+we can wipe and regenerate it at any time. On any restart where
216+the hot state might have changed, we clear the warm state
217+with `u3j_ream()`.
218+
219+There is only one hot state, the global jet dashboard
220+`u3j_Dash` or `u3D` for short. In the present implementation,
221+u3D is a static structure not modified at runtime, except for
222+numbering itself on process initialization. This structure -
223+which embeds function pointers to all the jets - is defined
224+in `j/tree.c`. The data structures:
225+
226+```
227+ /* u3j_harm: driver arm.
228+ */
229+ typedef struct _u3j_harm {
230+ c3_c* fcs_c; // `.axe` or name
231+ u3_noun (*fun_f)(u3_noun); // compute or 0 / semitransfer
232+ c3_o ice; // perfect (don't test)
233+ c3_o tot; // total (never punts)
234+ c3_o liv; // live (enabled)
235+ } u3j_harm;
236+
237+ /* u3j_core: C core driver.
238+ */
239+ typedef struct _u3j_core {
240+ c3_c* cos_c; // control string
241+ struct _u3j_harm* arm_u; // blank-terminated static list
242+ struct _u3j_core* dev_u; // blank-terminated static list
243+ struct _u3j_core* par_u; // dynamic parent pointer
244+ c3_l jax_l; // dynamic jet index
245+ } u3j_core;
246+
247+ /* u3e_dash, u3_Dash, u3D: jet dashboard singleton
248+ */
249+ typedef struct _u3e_dash {
250+ u3j_core* dev_u; // null-terminated static list
251+ c3_l len_l; // ray_u filled length
252+ c3_l all_l; // ray_u allocated length
253+ u3j_core* ray_u; // dynamic driver array
254+ } u3j_dash;
255+```
256+
257+Warm and cold state is *per road*. In other words, as we nest
258+roads, we also nest jet state. The jet state in the road is:
259+
260+```
261+ struct { // jet dashboard
262+ u3p(u3h_root) har_p; // warm state
263+ u3_noun das; // cold state
264+ } jed;
265+```
266+
267+In case you understand Hoon, `das` (cold state) is a `++dash`,
268+and `har_p` (warm state) is a map from battery to `++calx`:
269+
270+```
271+ ++ bane ,@tas :: battery name
272+ ++ bash ,@uvH :: label hash
273+ ++ bosh ,@uvH :: local battery hash
274+ ++ batt ,* :: battery
275+ ++ calf ::
276+ $: jax=,@ud :: hot core index
277+ hap=(map ,@ud ,@ud) :: axis/hot arm index
278+ lab=path :: label as path
279+ jit=* :: arbitrary data
280+ == ::
281+ ++ calx (trel calf (pair bash cope) club) :: cached by battery
282+ ++ clog (pair cope (map batt club)) :: identity record
283+ ++ club (pair corp (map term nock)) :: battery pattern
284+ ++ cope (trel bane axis (each bash noun)) :: core pattern
285+ ++ core ,* :: core
286+ ++ corp (each core batt) :: parent or static
287+ ++ dash (map bash clog) :: jet system
288+```
289+
290+The driver index `jax` in a `++calx` is an index into `ray_u` in the
291+dashboard - ie, a pointer into hot state. This is why the warm
292+state has to be reset when we reload the pier in a new process.
293+
294+Why is jet state nested? Nock of course is a functional system,
295+so as we compute we don't explicitly create state. Jet state is
296+an exception to this principle (which works only because it can't
297+be semantically detected from Nock/Hoon) - but it can't violate
298+the fundamental rules of the allocation system.
299+
300+For instance, when we're on an inner road, we can't allocate on
301+an outer road, or point from an outer road to an inner. So if we
302+learn something - like a mapping from battery to jet - in the
303+inner road, we have to keep it in the inner road.
304+
305+Mitigating this problem, when we leave an inner road (with
306+`u3m_love()`), we call `u3j_reap()` to promote jet information in
307+the dying road. Reaping promotes anything we've learned about
308+any battery that either (a) already existed in the outer road, or
309+(b) is being saved to the outer road.
310+
311+#### u3j: jet binding
312+
313+Jet binding starts with a `%fast` hint. (In Hoon, this is
314+produced by the runes `~%`, for the general case, or `~/`
315+for simple functions.) To bind a jet, execute a formula of the
316+form:
317+
318+```
319+[10 [%fast clue-formula] core-formula]
320+```
321+
322+`core-formula` assembles the core to be jet-propelled.
323+`clue-formula` produces the hint information, or `++clue`
324+above, which we want to annotate it with.
325+
326+A clue is a triple of name, parent, and hooks:
327+
328+```
329+++ clue (trel chum nock (list (pair term nock)))
330+```
331+
332+The name, or `++chum`, has a bunch of historical structure which
333+we don't need (cleaning these things up is tricky), but just gets
334+flattened into a term.
335+
336+The parent axis is a nock formula, but always reduces to a simple
337+axis, which is the address of this core's *parent*. Consider
338+again an ordinary gate
339+
340+```
341+[formula [sample context]]
342+```
343+
344+Typically the `context` is itself a library core, which itself
345+has a jet binding. If so, the parent axis of this gate is `7`.
346+
347+If the parent is already bound - and the parent *must* be already
348+bound, in this road or a road containing it - we can hook this core
349+bottom-up into a tree hierarchy. Normally the child core is
350+produced by an arm of the parent core, so this is not a problem -
351+we wouldn't have the child if we hadn't already made the parent.
352+
353+The clue also contains a list of *hooks*, named nock formulas on
354+the core. Usually these are arms, but they need not be. The
355+point is that we often want to call a core from C, in a situation
356+where we have no type or other source information. A common case
357+of this is a complex system in which we're mixing functions which
358+are jet-propelled with functions that aren't.
359+
360+In any case, all the information in the `%fast` hint goes to
361+`u3j_mine()`, which registers the battery in cold state (`das` in
362+`jed` in `u3R`), then warm state (`har_p` in `jed`).
363+
364+It's essential to understand that the `%fast` hint has to be,
365+well, fast - because we apply it whenever we build a core. For
366+instance, if the core is a Hoon gate - a function - we will call
367+`u3j_mine` every time the function is called.
368+
369+### u3j: the cold jet dashboard
370+
371+For even more fun, the jet tree is not actually a tree of
372+batteries. It's a tree of battery *labels*, where a label is
373+an [axis term] path from the root of the tree. (At the root,
374+if the core pattern is always followed properly, is a core whose
375+payload is an atomic constant, conventionally the Hoon version.)
376+
377+Under each of these labels, it's normal to have an arbitrary
378+number of different Nock batteries (not just multiple copies
379+of the same noun, a situation we *do* strive to avoid). For
380+instance, one might be compiled with debugging hints, one not.
381+
382+We might even have changed the semantics of the battery without
383+changing the label - so long as those semantics don't invalidate
384+any attached driver.
385+
386+For instance, it's normal to have two equivalent Nock batteries
387+at the same time in one pier: one battery compiled with
388+debugging hints, one not.
389+
390+Rather, the jet tree is a semantic hierarchy. The root of the
391+hierarchy is a constant, by convention the Hoon kernel version
392+because any normal jet-propelled core has, at the bottom of its
393+onion of libraries, the standard kernel. Thus if the core is
394+
395+```
396+[foo-battery [bar-battery [moo-battery 164]]]
397+```
398+
399+we can reverse the nesting to construct a hierarchical core
400+path. The static core
401+
402+```
403+164/moo/bar/foo
404+```
405+
406+extends the static core `164/moo/bar` by wrapping the `foo`
407+battery (ie, in Hoon, `|%`) around it. With the core above,
408+you can compute `foo` stuff, `bar` stuff, and `moo` stuff.
409+Rocket science, not.
410+
411+Not all cores are static, of course - they may contain live data,
412+like the sample in a gate (ie, argument to a function). Once
413+again, it's important to remember that we track jet bindings not
414+by the core, which may not be static, but by the battery, which
415+is always static.
416+
417+(And if you're wondering how we can use a deep noun like a Nock
418+formula or battery as a key in a key-value table, remember
419+`mug_w`, the lazily computed short hash, in all boxed nouns.)
420+
421+In any case, `das`, the dashboard, is a map from `bash` to jet
422+location record (`++clog`). A `clog` in turn contains two kinds
423+of information: the `++cope`, or per-location noun; and a map of
424+batteries to a per-battery `++club`.
425+
426+The `cope` is a triple of `++bane` (battery name, right now just
427+a `term`); `++axis`, the axis, within *this* core, of the parent;
428+and `(each bash noun)`, which is either `[0 bash]` if the parent
429+is another core, or `[1 noun]`, for the constant noun (like
430+`164`) if there is no parent core.
431+
432+A `bash` is just the noun hash (`++sham`) of a `cope`, which
433+uniquely expresses the battery's hierarchical location without
434+depending on the actual formulas.
435+
436+The `club` contains a `++corp`, which we use to actually validate
437+the core. Obviously jet execution has to be perfectly compatible
438+with Nock. We search on the battery, but getting the battery
439+right is not enough - a typical battery is dependent on its
440+context. For example, your jet-propelled library function is
441+very likely to call `++dec` or other advanced kernel technology.
442+If you've replaced the kernel in your context with something
443+else, we need to detect this and not run the jet.
444+
445+There are two cases for a jet-propelled core - either the entire
446+core is a static constant, or it isn't. Hence the definition
447+of `corp`:
448+
449+```
450+++ corp (each core batt) :: parent or static
451+```
452+
453+Ie, a `corp` is `[0 core]` or `[1 batt]`. If it's static -
454+meaning that the jet only works with one specific core, ie, the
455+parent axis of each location in the hierarchy is `3` - we can
456+validate with a single comparison. Otherwise, we have to recurse
457+upward by checking the parent.
458+
459+Note that there is at present no way to force a jet to depend on
460+static *data*.
461+
462+### u3j: the warm jet dashboard
463+
464+We don't use the cold state to match jets as we call them. We
465+use the cold state to register jets as we find them, and also to
466+rebuild the warm state after the hot state is reset.
467+
468+What we actually use at runtime is the warm state, `jed->har_p`,
469+which is a `u3h` (built-in hashtable), allocated on the loom,
470+from battery to `++calx`.
471+
472+A `calx` is a triple of a `++calf`, a `[bash cope]` cell, and a
473+`club`. The latter two are all straight from cold state.
474+
475+The `calf` contains warm data dependent on hot state. It's a
476+quadruple: of `jax`, the hot driver index (in `ray_u` in
477+`u3j_dash`); `hap`, a table from arm axis (ie, the axis of each
478+formula within the battery) to driver arm index (into `arm_u` in
479+`u3j_core`); `lab`, the complete label path; and `jit`, any
480+other dynamic data that may speed up execution.
481+
482+We construct `hap`, when we create the calx, by iterating through
483+the arms registered in the `u3j_core`. Note the way a `u3j_harm`
484+declares itself, with the string `fcs_c` which can contain either
485+an axis or a name. Most jetted cores are of course gates, which
486+have one formula at one axis within the core: `fcs_c` is `".3"`.
487+
488+But we do often have fast cores with more complex arm structure,
489+and it would be sad to have to manage their axes by hand. To use
490+an `fcs_c` with a named arm, it's sufficient to make sure the
491+name is bound to a formula `[0 axis]` in the hook table.
492+
493+`jit`, as its name suggests, is a stub where any sort of
494+optimization data computed on battery registration might go. To
495+use it, fill in the `_cj_jit()` function.
496+
497+### u3j: the hot dashboard
498+
499+Now it should be easy to see how we actually invoke jets. Every
500+time we run a nock `9` instruction (pretty often, obviously), we
501+have a core and an axis. We pass these to `u3j_kick()`, which
502+will try to execute them.
503+
504+Because nouns with a reference count of 1 are precious,
505+`u3j_kick()` has a tricky reference control definition. It
506+reserves the right to return `u3_none` in the case where there is
507+no driver, or the driver does not apply for this case; in this
508+case, it retains argument `cor`. If it succeeds, though, it
509+transfers `cor`.
510+
511+`u3j_kick()` searches for the battery (always the head of the
512+core, of course) in the hot dashboard. If the battery is
513+registered, it searches for the axis in `hap` in the `calx`.
514+If it exists, the core matches a driver and the driver jets this
515+arm. If not, we return `u3_none`.
516+
517+Otherwise, we call `fun_f` in our `u3j_harm`. This obeys the
518+same protocol as `u3j_kick()`; it can refuse to function by
519+returning `u3_none`, or consume the noun.
520+
521+Besides the actual function pointer `fun_f`, we have some flags
522+in the `u3j_harm` which tell us how to call the arm function.
523+
524+If `ice` is yes (`&`, `0`), the jet is known to be perfect and we
525+can just trust the product of `fun_f`. Otherwise, we need to run
526+*both* the Nock arm and `fun_f`, and compare their results.
527+
528+(Note that while executing the C side of this test, we have to
529+set `ice` to yes; on the Nock side, we have to set `liv` to no.
530+Otherwise, many non-exponential functions become exponential.
531+When auto-testing jets in this way, the principle is that the
532+test is on the outermost layer of recursion.)
533+
534+(Note also that anyone who multi-threads this execution
535+environment has a slight locking problem with these flags if arm
536+testing is multi-threaded.)
537+
538+If `tot` is yes, (`&`, `0`), the arm function is *total* and has
539+to return properly (though it can still return *u3_none*).
540+Otherwise, it is *partial* and can `u3_cm_bail()` out with
541+c3__punt. This feature has a cost: the jet runs in a subroad.
542+
543+Finally, if `liv` is no (`|`, 1), the jet is off and doesn't run.
544+
545+It should be easy to see how the tree of cores gets declared -
546+precisely, in `j/dash.c`. We declare the hierarchy as a tree
547+of `u3j_core` structures, each of which comes with a static list
548+of arms `arm_u` and sub-cores `dev_u`.
549+
550+In `u3j_boot()`, we traverse the hierarchy, fill in parent
551+pointers `par_u`, and enumerate all `u3j_core` structures
552+into a single flat array `u3j_dash.ray_u`. Our hot state
553+then appears ready for action.
554+
555+### u3j: jet functions
556+
557+At present, all drivers are compiled statically into `u3`. This is
558+not a long-term permanent solution or anything. However, it will
559+always be the case with a certain amount of core functionality.
560+
561+For instance, there are some jet functions that we need to call
562+as part of loading the Arvo kernel - like `++cue` to unpack a
563+noun from an atom. And obviously it makes sense, when jets are
564+significant enough to compile into `u3`, to export their symbols
565+in headers and the linker.
566+
567+There are three interface prefixes for standard jet functions:
568+`u3k`, `u3q`, and `u3w`. All jets have `u3w` interfaces; most
569+have `u3q`; some have `u3k`. Of course the actual logic is
570+shared.
571+
572+`u3w` interfaces use the same protocol as `fun_f` above: the
573+caller passes the entire core, which is retained if the function
574+returns `u3_none`, transferred otherwise. Why? Again, use
575+counts of 1 are special and precious for performance hackers.
576+
577+`u3q` interfaces break the core into C arguments, *retain* noun
578+arguments, and *transfer* noun returns. `u3k` interfaces are the
579+same, except with more use of `u3_none` and other simple C
580+variations on the Hoon original, but *transfer* both arguments
581+and returns. Generally, `u3k` are most convenient for new code.
582+
583+Following `u3k/q/w` is `[a-f]`, corresponding to the 6 logical
584+tiers of the kernel, or `g` for user-level jets. Another letter
585+is added for functions within subcores. The filename, under
586+`j/`, follows the tier and the function name.
587+
588+For instance, `++add` is `u3wa_add(cor)`, `u3qa_add(a, b)`, or
589+`u3ka_add(a, b)`, in `j/a/add.c`. `++get` in `++by` is
590+`u3wdb_get(cor)`, `u3kdb_get(a, b)`, etc, in `j/d/by_get.c`.
591+
592+For historical reasons, all internal jet code in `j/[a-f]`
593+*retains* noun arguments, and *transfers* noun results. Please
594+do not do this in new `g` jets! The new standard protocol is to
595+transfer both arguments and results.
596+
597+### u3a: allocation functions
598+
599+`u3a` allocates on the current road (u3R). Its internal
600+structures are uninteresting and typical of a naive allocator.
601+
602+The two most-used `u3a` functions are `u3a_gain()` to add a
603+reference count, and `u3a_lose()` to release one (and free the
604+noun, if the use count is zero). For convenience, `u3a_gain()`
605+returns its argument. The pair are generally abbreviated with
606+the macros `u3k()` and `u3z()` respectively.
607+
608+Normally we create nouns through `u3i` functions, and don't call
609+the `u3a` allocators directly. But if you do:
610+
611+One, there are *two* sets of allocators: the word-aligned
612+allocators and the fully-aligned (ie, malloc compatible)
613+allocators. For instance, on a typical OS X setup, malloc
614+produces 16-byte aligned results - needed for some SSE
615+instructions.
616+
617+These allocators are *not compatible*. For 32-bit alignment
618+as used in nouns, call
619+
620+```
621+ /* u3a_walloc(): allocate storage measured in words.
622+ */
623+ void*
624+ u3a_walloc(c3_w len_w);
625+
626+ /* u3a_wfree(): free storage.
627+ */
628+ void
629+ u3a_wfree(void* lag_v);
630+
631+ /* u3a_wealloc(): word realloc.
632+ */
633+ void*
634+ u3a_wealloc(void* lag_v, c3_w len_w);
635+```
636+
637+For full alignment, call:
638+
639+```
640+ /* u3a_malloc(): aligned storage measured in bytes.
641+ */
642+ void*
643+ u3a_malloc(size_t len_i);
644+
645+ /* u3a_realloc(): aligned realloc in bytes.
646+ */
647+ void*
648+ u3a_realloc(void* lag_v, size_t len_i);
649+
650+ /* u3a_realloc2(): gmp-shaped realloc.
651+ */
652+ void*
653+ u3a_realloc2(void* lag_v, size_t old_i, size_t new_i);
654+
655+ /* u3a_free(): free for aligned malloc.
656+ */
657+ void
658+ u3a_free(void* tox_v);
659+
660+ /* u3a_free2(): gmp-shaped free.
661+ */
662+ void
663+ u3a_free2(void* tox_v, size_t siz_i);
664+```
665+
666+There are also a set of special-purpose allocators for building
667+atoms. When building atoms, please remember that it's incorrect
668+to have a high 0 word - the word length in the atom structure
669+must be strictly correct.
670+
671+Of course, we don't always know how large our atom will be.
672+Therefore, the standard way of building large atoms is to
673+allocate a block of raw space with `u3a_slab()`, then chop off
674+the end with `u3a_malt()` (which does the measuring itself)
675+or `u3a_mint()` in case you've measured it yourself.
676+
677+Once again, *do not call `malloc()`* (or C++ `new`) within any
678+code that may be run within a jet. This will cause rare sporadic
679+corruption when we interrupt execution within a `malloc()`. We'd
680+just override the symbol, but `libuv` uses `malloc()` across
681+threads within its own synchronization primitives - for this to
682+work with `u3a_malloc()`, we'd have to introduce our own locks on
683+the surface-level road (which might be a viable solution).
684+
685+### u3n: nock execution
686+
687+The `u3n` routines execute Nock itself. On the inside, they have
688+a surprising resemblance to the spec proper (the only interesting
689+detail is how we handle tail-call elimination) and are, as one
690+would expect, quite slow. (There is no such thing as a fast tree
691+interpreter.)
692+
693+There is only one Nock, but there are lots of ways to call it.
694+(Remember that all `u3n` functions *transfer* C arguments and
695+returns.)
696+
697+The simplest interpreter, `u3n_nock_on(u3_noun bus, u3_noun fol)`
698+invokes Nock on `bus` (the subject) and `fol` (the formula).
699+(Why is it`[subject formula]`, not `[formula subject]`? The same
700+reason `0` is true and `1` is false.)
701+
702+A close relative is `u3n_slam_on(u3_noun gat, u3_noun sam)`,
703+which slams a *gate* (`gat`) on a sample (`sam`). (In a normal
704+programming language which didn't talk funny and was retarded,
705+`u3n_slam_on()` would call a function on an argument.) We could
706+write it most simply as:
707+
708+```
709+ u3_noun
710+ u3n_slam_on(u3_noun gat, u3_noun sam)
711+ {
712+ u3_noun pro = u3n_nock_on
713+ (u3nc(u3k(u3h(gat)),
714+ u3nc(sam, u3k(u3t(u3t(gat))))),
715+ u3k(u3h(gat)));
716+ u3z(gat);
717+ return pro;
718+ }
719+```
720+
721+Simpler is `u3n_kick_on(u3_noun gat)`, which slams a gate (or,
722+more generally, a *trap* - because sample structure is not even
723+needed here) without changing its sample:
724+
725+```
726+ u3_noun
727+ u3n_kick_on(u3_noun gat, u3_noun sam)
728+ {
729+ return u3n_nock_on(gat, u3k(u3h(gat)));
730+ }
731+```
732+
733+The `_on` functions in `u3n` are all defined as pure Nock. But
734+actually, even though we say we don't extend Nock, we do. But we
735+don't. But we do.
736+
737+Note that `u3` has a well-developed error handling system -
738+`u3m_bail()` to throw an exception, `u3m_soft_*` to catch one.
739+But Nock has no exception model at all. That's okay - all it
740+means if that if an `_on` function bails, the exception is an
741+exception in the caller.
742+
743+However, `u3`'s exception handling happens to match a convenient
744+virtual super-Nock in `hoon.hoon`, the infamous `++mock`. Of
745+course, Nock is slow, and `mock` is Nock in Nock, so it is
746+(logically) super-slow. Then again, so is decrement.
747+
748+With the power of `u3`, we nest arbitrary layers of `mock`
749+without any particular performance cost. Moreover, we simply
750+treat Nock proper as a special case of `mock`. (More precisely,
751+the internal VM loop is `++mink` and the error compiler is
752+`++mook`. But we call the whole sandbox system `mock`.)
753+
754+The nice thing about `mock` functions is that (by executing
755+within `u3m_soft_run()`, which as you may recall uses a nested
756+road) they provide both exceptions and the namespace operator -
757+`.^` in Hoon, which becomes operator `11` in `mock`.
758+
759+`11` requires a namespace function, or `fly`, which produces a
760+`++unit` - `~` (`0`) for no binding, or `[0 value]`. The sample
761+to a `fly` is a `++path`, just a list of text `span`.
762+
763+`mock` functions produce a `++toon`. Fully elaborated:
764+
765+```
766+ ++ noun ,* :: any noun
767+ ++ path (list ,@ta) :: namespace path
768+ ++ span ,@ta :: text-atom (ASCII)
769+ ++ toon $% [%0 p=noun] :: success
770+ [%1 p=(list path)] :: blocking paths
771+ [%2 p=(list tank)] :: stack trace
772+ == ::
773+ ++ tank :: printable
774+ $% [%leaf p=tape] :: flat text
775+ $: %palm :: backstep list
776+ p=[p=tape q=tape r=tape s=tape] :: mid cap open close
777+ q=(list tank) :: contents
778+ == ::
779+ $: %rose :: straight list
780+ p=[p=tape q=tape r=tape] :: mid open close
781+ q=(list tank) :: contents
782+ == ::
783+ ==
784+```
785+
786+(Note that `tank` is overdesigned and due for replacement.)
787+
788+What does a `toon` mean? Either your computation succeded (`[0
789+noun]`, or could not finish because it blocked on one or more
790+global paths (`[1 (list path)]`), or it exited with a stack trace
791+(`[2 (list tank)]`).
792+
793+Note that of all the `u3` exceptions, only `%exit` is produced
794+deterministically by the Nock definition. Therefore, only
795+`%exit` produces a `2` result. Any other argument to
796+`u3m_bail()` will unwind the virtualization stack all the way to
797+the top - or to be more exact, to `u3m_soft_top()`.
798+
799+In any case, the simplest `mock` functions are `u3n_nock_un()`
800+and `u3n_slam_un()`. These provide exception control without
801+any namespace change, as you can see by the code:
802+
803+```
804+ /* u3n_nock_un(): produce .*(bus fol), as ++toon.
805+ */
806+ u3_noun
807+ u3n_nock_un(u3_noun bus, u3_noun fol)
808+ {
809+ u3_noun fly = u3nt(u3nt(11, 0, 6), 0, 0); // |=(a=* .^(a))
810+
811+ return u3n_nock_in(fly, bus, fol);
812+ }
813+
814+ /* u3n_slam_un(): produce (gat sam), as ++toon.
815+ */
816+ u3_noun
817+ u3n_slam_un(u3_noun gat, u3_noun sam)
818+ {
819+ u3_noun fly = u3nt(u3nt(11, 0, 6), 0, 0); // |=(a=* .^(a))
820+
821+ return u3n_slam_in(fly, gat, sam);
822+ }
823+```
824+
825+The `fly` is added as the first argument to `u3n_nock_in()` and
826+`u3n_slam_in()`. Of course, logically, `fly` executes in the
827+caller's exception layer. (Maintaining this illusion is slightly
828+nontrivial.) Finally, `u3n_nock_an()` is a sandbox with a null
829+namespace.
830+
831+### u3e: persistence
832+
833+The only `u3e` function you should need to call is `u3e_save()`,
834+which saves the loom. As it can be restored on any platform,
835+please make sure you don't have any state in the loom that is
836+bound to your process or architecture - except for exceptions
837+like the warm jet state, which is actively purged on reboot.
838+
839+### u3r: reading nouns (weak)
840+
841+As befits accessors they don't make anything, `u3r` noun reading
842+functions always retain their arguments and their returns. They
843+never bail; rather, when they don't work, they return a `u3_weak`
844+result.
845+
846+Most of these functions are straightforward and do only what
847+their comments say. A few are interesting enough to discuss.
848+
849+`u3r_at()` is the familiar tree fragment function, `/` from the
850+Nock spec. For taking complex nouns apart, `u3r_mean()` is a
851+relatively funky way of deconstructing nouns with a varargs list
852+of `axis`, `u3_noun *`. For cells, triples, etc, decompose with
853+`u3r_cell()`, `u3r_trel()`, etc. For the tagged equivalents, use
854+`u3r_pq()` and friends.
855+
856+`u3r_sing(u3_noun a, u3_noun b)` (true if `a` and `b` are a
857+*single* noun) are interesting because it uses mugs to help it
858+out. Clearly, different nouns may have the same mug, but the
859+same nouns cannot have a different mug. It's important to
860+understand the performance characteristics of `u3r_sing()`:
861+the worst possible case is a comparison of duplicate nouns,
862+which have the same value but were created separately. In this
863+case, the tree is traversed
864+
865+`u3r_sung()` is a deeply funky and frightening version of
866+`u3r_sing()` that unifies pointers to the duplicate nouns it
867+finds, freeing the second copy. Obviously, do not use
868+`u3r_sung()` when you have live, but not reference counted, noun
869+references from C - if they match a noun with a refcount of 1
870+that gets freed, bad things happen.
871+
872+It's important to remember that `u3r_mug()`, which produces a
873+31-bit, nonzero insecure hash, uses the `mug_w` slot in any boxed
874+noun as a lazy cache. There are a number of variants of
875+`u3r_mug()` that can get you out of building unneeded nouns.
876+
877+### u3x: reading nouns (bail)
878+
879+`u3x` functions are like `u3r` functions, but instead of
880+returning `u3_none` when (for instance) we try to take the head
881+of an atom, they bail with `%exit`. In other words, they do what
882+the same operation would do in Nock.
883+
884+### u3h: hash tables.
885+
886+We can of course use the Hoon `map` structure as an associative
887+array. This is a balanced treap and reasonably fast. However,
888+it's considerably inferior to a custom structure like an HAMT
889+(hash array-mapped trie). We use `u3_post` to allocate HAMT
890+structures on the loom.
891+
892+(Our HAMT implements the classic Bagwell algorithm which depends
893+on the `gcc` standard directive `__builtin_popcount()`. On a CPU
894+which doesn't support popcount or an equivalent instruction, some
895+other design would probably be preferable.)
896+
897+There's no particular rocket science in the API. `u3h_new()`
898+creates a hashtable; `u3h_free()` destroys one; `u3h_put()`
899+inserts, `u3h_get()` retrieves. You can transform values in a
900+hashtable with `u3h_walk()`.
901+
902+The only funky function is `u3h_gut()`, which unifies keys with
903+`u3r_sung()`. As with all cases of `u3r_sung()`, this must be
904+used with extreme caution.
905+
906+### u3z: memoization
907+
908+Connected to the `~+` rune in Hoon, via the Nock `%memo` hint,
909+the memoization facility is a general-purpose cache.
910+
911+(It's also used for partial memoization - a feature that'll
912+probably be removed, in which conservative worklist algorithms
913+(which would otherwise be exponential) memoize everything in the
914+subject *except* the worklist. This is used heavily in the Hoon
915+compiler jets (j/f/*.c). Unfortunately, it's probably not
916+possible to make this work perfectly in that it can't be abused
917+to violate Nock, so we'll probably remove it at a later date,
918+instead making `++ut` keep its own monadic cache.)
919+
920+Each `u3z` function comes with a `c3_m` mote which disambiguates
921+the function mapping key to value. For Nock itself, use 0. For
922+extra speed, small tuples are split out in C; thus, find with
923+
924+```
925+ u3_weak u3z_find(c3_m, u3_noun);
926+ u3_weak u3z_find_2(c3_m, u3_noun, u3_noun);
927+ u3_weak u3z_find_3(c3_m, u3_noun, u3_noun, u3_noun);
928+ u3_weak u3z_find_4(c3_m, u3_noun, u3_noun, u3_noun, u3_noun);
929+```
930+
931+and save with
932+
933+```
934+ u3_noun u3z_save(c3_m, u3_noun, u3_noun);
935+ u3_noun u3z_save_2(c3_m, u3_noun, u3_noun, u3_noun);
936+ u3_noun u3z_save_3(c3_m, u3_noun, u3_noun, u3_noun, u3_noun);
937+ u3_noun u3z_save_4(c3_m, u3_noun, u3_noun, u3_noun, u3_noun, u3_noun);
938+```
939+
940+where the value is the last argument. To eliminate duplicate
941+nouns, there is also
942+
943+```
944+ u3_noun
945+ u3z_uniq(u3_noun);
946+```
947+
948+`u3z` functions retain keys and transfer values.
949+
950+The `u3z` cache, built on `u3h` hashes, is part of the current
951+road, and goes away when it goes away. (In future, we may wish
952+to promote keys/values which outlive the road, as we do with jet
953+state.) There is no cache reclamation at present, so be careful.
954+
955+### u3t: tracing and profiling.
956+
957+TBD.
958+
959+### u3v: the Arvo kernel
960+
961+An Arvo kernel - or at least, a core that compiles with the Arvo
962+interface - is part of the global `u3` state. What is an Arvo
963+core? Slightly pseudocoded:
964+
965+```
966+ ++ arvo
967+ |%
968+ ++ come |/ {yen/@ ova/(list ovum) nyf/pone} :: 11
969+ ^- {(list ovum) _+>}
970+ !!
971+ ++ keep |/ {now/@da hap/path} :: 4
972+ ^- (unit ,@da)
973+ !!
974+ ++ load |/ {yen/@ ova/(list ovum) nyf/pane} :: 86
975+ ^- {(list ovum) _+>}
976+ !!
977+ ++ peek |/ {now/@da path} :: 87
978+ ^- (unit)
979+ !!
980+ ++ poke |/ {now/@da ovo/ovum} :: 42
981+ ^- {(list ovum) _+>}
982+ !!
983+ ++ wish |/ txt/@ta :: 20
984+ ^- *
985+ !!
986+ --
987+ ++ card {p/@tas q/*} :: typeless card
988+ ++ ovum {p/wire q/card} :: Arvo event
989+ ++ wire path :: event cause
990+```
991+
992+This is the Arvo ABI in a very real sense. Arvo is a core with
993+these six arms. To use these arms, we hardcode the axis of the
994+formula (`11`, `4`, `86`, etc) into the C code that calls Arvo,
995+because otherwise we'd need type metadata - which we can get, by
996+calling Arvo.
997+
998+It's important to understand the Arvo event/action structure, or
999+`++ovum`. An `ovum` is a `card`, which is any `[term noun]`
1000+cell, and a `++wire`, a `path` which indicates the location of
1001+the event. At the Unix level, the `wire` corresponds to a system
1002+module or context. For input events, this is the module that
1003+caused the event; for output actions, it's the module that
1004+performs the action.
1005+
1006+`++poke` sends Arvo an event `ovum`, producing a cell of action
1007+ova and a new Arvo core.
1008+
1009+`++peek` dereferences the Arvo namespace. It takes a date and a
1010+key, and produces `~` (`0`) or `[~ value]`.
1011+
1012+`++keep` asks Arvo the next time it wants to be woken up, for the
1013+given `wire`. (This input will probably be eliminated in favor
1014+of a single global timer.)
1015+
1016+`++wish` compiles a string of Hoon source. While just a
1017+convenience, it's a very convenient convenience.
1018+
1019+`++come` and `++load` are used by Arvo to reset itself (more
1020+precisely, to shift the Arvo state from an old kernel to a new
1021+one); there is no need to call them from C.
1022+
1023+Now that we understand the Arvo kernel interface, let's look at
1024+the `u3v` API. As usual, all the functions in `u3v` are
1025+commented, but unfortunately it's hard to describe this API as
1026+clean at present. The problem is that `u3v` remains design
1027+coupled to the old `vere` event handling code written for `u2`.
1028+But let's describe the functions you should be calling, assuming
1029+you're not writing the next event system. There are only two.
1030+
1031+`u3v_wish(str_c)` wraps the `++wish` functionality in a cache
1032+(which is read-only unless you're on the surface road).
1033+
1034+`u3v_do()` uses `wish` to provide a convenient interface for
1035+calling Hoon kernel functions by name. Even more conveniently,
1036+we tend to call `u3v_do()` with these convenient aliases:
1037+
1038+```
1039+ #define u3do(txt_c, arg) u3v_do(txt_c, arg)
1040+ #define u3dc(txt_c, a, b) u3v_do(txt_c, u3nc(a, b))
1041+ #define u3dt(txt_c, a, b, c) u3v_do(txt_c, u3nt(a, b, c))
1042+ #define u3dq(txt_c, a, b, c, d) u3v_do(txt_c, u3nt(a, b, c, d))
1043+```
docs/vere/c.umdnew file+117
@@ -0,0 +1,117 @@
1+:- :~ navhome/'/docs/'
2+ sort/'2'
3+ next/'true'
4+ title/'C in Urbit'
5+ ==
6+;>
7+
8+## c3: C in Urbit
9+
10+Under `u3` is the simple `c3` layer, which is just how we write C
11+in Urbit.
12+
13+When writing C in u3, please of course follow the conventions of
14+the code around you as regards indentation, etc. It's especially
15+important that every function have a header comment, even if it
16+says nothing interesting.
17+
18+But some of our idiosyncrasies go beyond convention. Yes, we've
19+done awful things to C. Here's what we did and why we did.
20+
21+### c3: integer types
22+
23+First, it's generally acknowledged that underspecified integer
24+types are C's worst disaster. C99 fixed this, but the `stdint`
25+types are wordy and annoying. We've replaced them with:
26+
27+```
28+ /* Good integers.
29+ */
30+ typedef uint64_t c3_d; // double-word
31+ typedef int64_t c3_ds; // signed double-word
32+ typedef uint32_t c3_w; // word
33+ typedef int32_t c3_ws; // signed word
34+ typedef uint16_t c3_s; // short
35+ typedef int16_t c3_ss; // signed short
36+ typedef uint8_t c3_y; // byte
37+ typedef int8_t c3_ys; // signed byte
38+ typedef uint8_t c3_b; // bit
39+
40+ typedef uint8_t c3_t; // boolean
41+ typedef uint8_t c3_o; // loobean
42+ typedef uint8_t c3_g; // 5-bit atom for a 32-bit log.
43+ typedef uint32_t c3_l; // little; 31-bit unsigned integer
44+ typedef uint32_t c3_m; // mote; also c3_l; LSB first a-z 4-char string.
45+
46+ /* Bad integers.
47+ */
48+ typedef char c3_c; // does not match int8_t or uint8_t
49+ typedef int c3_i; // int - really bad
50+ typedef uintptr_t c3_p; // pointer-length uint - really really bad
51+ typedef intptr_t c3_ps; // pointer-length int - really really bad
52+```
53+
54+Some of these need explanation. A loobean is a Nock boolean -
55+Nock, for mysterious reasons, uses 0 as true (always say "yes")
56+and 1 as false (always say "no").
57+
58+Nock and/or Hoon cannot tell the difference between a short atom
59+and a long one, but at the `u3` level every atom under `2^31` is
60+direct. The `c3_l` type is useful to annotate this. A `c3_m` is
61+a *mote* - a string of up to 4 characters in a `c3_l`, least
62+significant byte first. A `c3_g` should be a 5-bit atom. Of
63+course, C cannot enforce these constraints, only document them.
64+
65+Use the "bad" - ie, poorly specified - integer types only when
66+interfacing with external code that expects them.
67+
68+An enormous number of motes are defined in `i/c/motes.h`. There
69+is no reason to delete motes that aren't being used, or even to
70+modularize the definitions. Keep them alphabetical, though.
71+
72+### c3: variables and variable naming
73+
74+The C3 style uses Hoon style TLV variable names, with a quasi
75+Hungarian syntax. This is weird, but works really well, as long
76+as what you're doing isn't hideously complicated. (Then it works
77+badly, but we shouldn't need anything hideous in u3.)
78+
79+A TLV variable name is a random pronounceable three-letter
80+string, sometimes with some vague relationship to its meaning,
81+but usually not. Usually CVC (consonant-vowel-consonant) is a
82+good choice.
83+
84+You should use TLVs much the way math people use Greek letters.
85+The same concept should in general get the same name across
86+different contexts. When you're working in a given area, you'll
87+tend to remember the binding from TLV to concept by sheer power
88+of associative memory. When you come back to it, it's not that
89+hard to relearn. And of course, when in doubt, comment it.
90+
91+Variables take pseudo-Hungarian suffixes, matching in general the
92+suffix of the integer type:
93+
94+```
95+c3_w wor_w; // 32-bit word
96+```
97+
98+Unlike in standard Hungarian, there is no change for pointer
99+variables. C structure variables take a `_u` suffix.
100+
101+### c3: loobeans
102+
103+The code (from `defs.h`) tells the story:
104+
105+```
106+ # define c3y 0
107+ # define c3n 1
108+
109+ # define _(x) (c3y == (x))
110+ # define __(x) ((x) ? c3y : c3n)
111+ # define c3a(x, y) __(_(x) && _(y))
112+ # define c3o(x, y) __(_(x) || _(y))
113+```
114+
115+In short, use `_()` to turn a loobean into a boolean, `__` to go
116+the other way. Use `!` as usual, `c3y` for yes and `c3n` for no,
117+`c3a` for and and `c3o` for or.
docs/vere/jetting.umdnew file+761
@@ -0,0 +1,761 @@
1+:- :~ navhome/'/docs/'
2+ sort/'5'
3+ title/'Writing Jets'
4+ ==
5+;>
6+
7+# How to write a jet
8+
9+A guide for new Urbit developers.
10+
11+Problem statement: coder A has written some hoon, and you - coder B - need to jet it.
12+
13+Preconditions:
14+
15+- You have a pill `jetted.pill`, located in ~/tlon.
16+- You have an example of hoon code that, executed in dojo, does the right thing.
17+
18+## Get all the source code you need.
19+
20+The source code you will need to modify lives in two different repos:
21+urbit and arvo. The urbit repo has the source code for the
22+interpreter / personal server, written in C. The arvo repo has the
23+operating system, written in hoon. Since you're jetting the hoon, you
24+need to modify both.
25+
26+For simplicity, I'm going to assume that you are doing all of your
27+development in ~/tlon. This saves the bother of writing nonsense like
28+the/path/to/your/sandbox, and also means that one can copy-and-paste
29+these instructions straight into a terminal with zero editing. Do
30+your development elsewhere, if you like, and make a symbolic link.
31+
32++ mkdir ~/tlon
33++ cd ~/tlon
34++ git clone https://github.com/urbit/urbit
35++ cd urbit
36++ git fetch
37++ git checkout <branch> # optional
38++ scripts/bootstrap
39++ cd ..
40++ git clone https://github.com/urbit/arvo
41++ cd arvo
42++ git fetch
43++ git checkout <branch> # optional
44++ cd ..
45+
46+## Add new subprojects / libraries to urbit, if necessary
47+
48+If we have a complicated hoon function that, say, computes square
49+roots, we need to speed it up, and there is an open source library
50+libsquareroots, adding libsquareroots to our build might solve 90% of
51+our problems.
52+
53+If this describes your task, read this section. If not, skip to the next section - none of this is necessary.
54+
55++ have someone with github.com/urbit repo privileges fork libsquareroots into github.com/urbit
56++ fork this new repo github.com/urbit/libsquareroots
57++ cd ~tlon/urbit/subprojects
58++ git submodule add <url>
59++ edit ~tlon/urbit/subprojects/meson.build
60+ - add a line `<foo>_dep = dependency('<foo>', version: '>=0.1.0', fallback: ['<foo>', '<foo>_dep'])`
61+ - add `<foo>_dep` to the list of dependencies at the bottom of the file. Remember to use a comma.
62+
63++ generate a meson.build for the new subproject: cd subprojects/<new directory>; meson wrap promote subprojects/secp256k1
64++ edit the meson.build until it works ("works" is defined as "in the top level ~/tlon/urbit invoking scripts/build builds the library and links it into the urbit executable")
65++ git add meson.build ; git commit -m"now builds with meson for Tlon" .
66++ cd .. ; git add .gitmodules ; git commit -m"added submodule" .
67++ test the whole thing by
68+ + cd /tmp
69+ + rm -rf urbit
70+ + git clone https://github.com/<yourname>/urbit
71+ + cd urbit
72+ + scripts/bootstrap
73+ + verify that the new submodule is present
74+ + scripts/build
75+ + verify that the urbit executable is built and linked to the new library
76++ submit a pull request from your copy of <libsquareroots> to the urbit copy
77++ submit a pull request from your copy of urbit to the urbit copy
78+
79+
80+### If the submodule is modified
81+
82+The steps above add a submodule to the urbit repo. Or, more specifically, they add a specific version of the submodule to the repo.
83+
84+If the submodule has commits made to it (perhaps, the urbit repo will not track those new commits. XXXX)
85+
86+## Edit the source code
87+
88+There are several things you're going to do:
89+
90++ hint the hoon code, so that the urbit interpreter will know to look for C code
91++ for each jet you want you're going to declare two functions in two .h files (one takes the arguments as separate arguments, one takes them as one big tree)
92++ then implement the two C functions in a single .c file
93++ register the new C jet functions so the urbit interpretter knows the names / function pointers of the C funcs
94+
95+### Edit the Hoon Source code
96+
97+Let's edit the hoon source code first.
98+
99+There are multiple runes to do hinting, but we're going to concentrate
100+on three. All hinting runes start with a tilda ("sig"). A mnemonic
101+is "we're signalling some information to the interpretter".
102+
103++ ~/ sigfas: simple jet registration, using defaults for some arguments
104++ ~% sigcen: more complicated jet registration, specifying all arguments
105++ ~& sigpam: debugging printf
106+
107+Feel free to use ~& liberally! (Just remove them when you're done).
108+
109+Let's use the three to jet some code. Starting with this example:
110+
111+```
112+ ++ aaa
113+ ...
114+ ++ bbb
115+ ++ ccc
116+ |= dat=@
117+ ^- pont
118+ =+ x=(end 3 w a)
119+ =+ y=:(add (pow x 3) (mul a x) b)
120+ =+ s=(rsh 3 32 dat)
121+ :- x
122+ ?: =(0x2 s) y
123+ ?: =(0x3 s) y
124+ ~| [`@ux`s `@ux`dat]
125+ !!
126+```
127+
128+our steps are:
129+
130++ add a line under `++ aaa` like this: `~% %aaa ..is ~`
131++ add a line under `++ bbb` like this: `~/ %bbb`
132++ add a line under `++ ccc` like this: `~/ %ccc`
133+
134+What we're doing here is hinting `ccc`, and then adding a string of
135+hints up the enclosing tree of arms. Each of these hints is
136+implemented w the simple / minimalist `~/` rune, which takes one
137+argument: the symbol that should be used to label the hint (these
138+symbols will be used later in the C code to match up C code with hoon code).
139+
140+The top hint (for `aaa`) uses the more verbose `~%` hint syntax, which
141+specifies two additional fields: `...is` means "parent jet can not be
142+determined by context, so use 'is' as the parent" ("is" is the name of a system-supplied jet).
143+
144+[ N.B. saying " `is` is the parent " is a quick-and-dirty lie. The
145+fuller version is: `+is` is an arm of the Arvo core, so `..is` is a
146+reference to the entire Arvo core. The whole Arvo core is hinted with
147+the jet label `%hex`, which is used as the parent for all the
148+top-level jet hints in %zuse. ]
149+
150+When hinting your own code, make sure to hint each nesting arm.
151+Skipping any one will result in the jet code not being run.
152+
153+Note that you do not need to provide C implementations for everything
154+you hint. In this above example we hint aaa, bbb, and ccc - even if
155+our intent is only to jet ccc.
156+
157+### Edit the C Source code (overview)
158+
159+Having hinted our hoon, we now need to write the matching C code. If
160+we don't, there isn't a problem - hinting code merely tells the
161+interpretter to look for a jet, but if a jet is not found, the hoon
162+still runs just fine.
163+
164+There are two distinct tasks to be done in C:
165+
166++ write the jet
167++ register the jet
168+
169+For each jet you will write one u3we() function and one u3qe() function.
170+
171+### Edit the C Source code to add registration
172+
173+* edit the header file `include/jets/w.h` to have a declaration for each of your u3we() functions. Every u3we() function looks the same, e.g.
174+
175+```
176+u3_noun u3we_xxx(u3_noun);
177+```
178+
179+* edit the header file `~/tlon/urbit/include/jets/q.h` to have a declaration for your u3qe() function. u3qe() functions can differ from each other, taking distinct numbers of u3_nouns and/or u3_atoms, e.g
180+
181+```
182+ u3_noun u3qe_yyy(u3_atom, u3_atom);
183+ u3_noun u3qe_zzz(u3_noun, u3_noun, u3_atom, u3_atom);
184+```
185+
186+* create a new .c file to hold your jets (both the u3we_() and u3qe_() functions go in the same file). For example, ~/tlon/urbit/jets/e/secp.c
187+(The choice of subdirectory under 'jets' (a through g) is XXX )
188+The new file should have three things:
189++ \#include "all.h"
190++ the new u3we() function
191++ the new u3qe() function
192+
193+* edit ~/tlon/urbit/jets/tree.c to register jet
194+
195+In the hoon code we hinted some leaf node functions (`ccc` in our example) and then hinted each parent node up to the root `aaa`).
196+
197+We need to replicate this structure in C. Here's example C code to jet our above example Hoon:
198+
199+```
200+ // 1: register a C func u3we_ccc()
201+ static u3j_harm _143_hex_hobo_reco_d[] =
202+ {
203+ {".2", u3we_ccc, c3y},
204+ {}
205+ };
206+
207+ // 2: that implements a jet for hoon arm 'ccc'
208+ static u3j_core _143_hex_hobo_bbb_d[] =
209+ {
210+ { "ccc", _143_hex_hobo_ccc_d },
211+ {}
212+ };
213+
214+ // 3: ... that is inside a hoon arm 'bbb'
215+ static u3j_core _143_hex_hobo_hobo_d[] =
216+ {
217+ { "bbb", 0, _143_hex_hobo_bbb_d },
218+ {}
219+ };
220+
221+ // 4: ... that is inside a hoon arm 'aaa'
222+ static u3j_core _143_hex_d[] =
223+ { { "down", 0, _143_hex_down_d },
224+ { "lore", _143_hex_lore_a },
225+ { "loss", _143_hex_loss_a },
226+ { "lune", _143_hex_lune_a },
227+ { "coed", 0, _143_hex_coed_d },
228+ { "aes", 0, _143_hex_aes_d },
229+ { "hmac", 0, _143_hex_hmac_d },
230+ { "aaa", 0, _143_hex_hobo_d },
231+ {}
232+ };
233+
234+```
235+
236+There are 4 things steps here. Let's look at each in turn.
237+
238+Section 1 names the C function that we want to invoke: 'u3we_ccc()'.
239+The precise manner in which it does this is by putting entries in an
240+array of 'u3j_harm's. The first one specifies the jet; the second one
241+is empty and serves as a termination to the array, similar to how a C
242+string is null terminated with a zero. The jet registration supplies
243+two fields {".2", u3we_secp}, but this does not initialize all of the
244+fields of u3j_harm. Other fields can be specified.
245+
246+The first field, with value ".2" in this example, is "arm 2".
247+
248+[ N.B. ".2" labels the axis of the arm in the core. With a %fast hint
249+(~/), we're hinting a gate, so the relevant arm formula is always just
250+the entire battery at +2. I assume the jet dashboard is flexible
251+enough to hint arms at different axes, but I've never seen it done. ]
252+
253+The second field, with value u3we_secp in this example, is a function
254+pointer (to the C implementation of the jet).
255+
256+The third field (absent here) is a flag to turn on verification of C
257+jet vs hoon at run time. It can take value c3n (which means verify at run time) or c3y
258+(which means don't verify). If not present, it is set to don't verify.
259+
260+[N.B. The use of the flags seems inverted. Why is c3y ("yes") used to
261+turn OFF verification? A: because the flag is actually "is the jet
262+already known to be perfect?" ]
263+
264+There are additional flags; see ~/tlon/urbit/include/noun/jets.h
265+
266+
267+Section 2 associated the previous jet registration with the name
268+"ccc". Note that this is the symbol used in the Hoon hint! Note also
269+that we again have a "null terminated" (metaphorically) list, ending with `{}`.
270+
271+Section 3 references structure built in step 2 and slots it under
272+`bbb` (again, note that this is exactly the same symbol used in the
273+hinting in Hoon).
274+
275+The line in section 2
276+```
277+ { "ccc", _143_hex_hobo_ccc_a },
278+```
279+
280+looks very similar to the line in section 3
281+```
282+ { "bbb", 0, _143_hex_hobo_bbb_d },
283+```
284+
285+But note that the line in section 2 fill in the first 2 fields in the
286+struct, and the line in section 3 fills in the first three fields.
287+Section 2 is registering an array of u3j_harm, i.e. is registering an actual C
288+jet.
289+
290+Section 3 is specifying 0 for the array of u3j_harm and is instead
291+specifying an array of u3j_core, i.e. it is registering nesting of
292+another core which is not a leaf node.
293+
294+Section 4 is much like section 3, but it's the root of this particular
295+tree. Section 4 is also an example of how a given node in the
296+jet-registration tree may have multiple children.
297+
298+Using this example you should be able to register jets whether your
299+nesting is 2 layers deep, 3 (like this example), or more. You should
300+also be able to register multiple jets at the same nesting level (e.g.
301+a function u3we_ddd() which is a sibling of u3we_ccc() inside data structure _143_hex_hobo_reco_d[] ).
302+
303+### Edit the C source code to add the u3we_() function
304+
305+There are two C functions per jet, because separation of concerns is a good thing.
306+
307+The first C function - named u3we_something() - unpacks arguments from
308+the Hoon code and gets them ready.
309+
310+The second C function - named u3qe_something() - takes those arguments
311+and actually performs the operations that parallel the hoon code being
312+jetted.
313+
314+Let's write the u3we_() function.
315+
316+Your function is going to accept one argument, of type u3_noun. This
317+is the same type as a hoon noun ('*').
318+
319+This one argument is the payload.
320+
321+The payload is a tree, obviously.
322+
323+The payload consists of (on the right branch) the context (you'd think
324+of "global variables and available methods", if analogies to other
325+programming languages were allowed!) and on the left branch the
326+sample (the arguments to this particular function call).
327+
328+Your u3we_() function does one thing: unpack the sample from 'cor',
329+sanity check them, and pass them in to the u3qe_() function.
330+
331+To unpack the sample
332+
333+We use the function u3r_mean() to do this, thusly:
334+
335+```
336+ u3_noun arg_a, arg_b, arg_c ... ;
337+
338+ u3r_mean(cor,
339+ axis_a, & arg_a,
340+ axis_b, & arg_b,
341+ axis_c, & arg_c
342+ ...
343+ 0)
344+```
345+
346+If we want to to assign the data located at axis 3 of cor to arg_a, we'd set axis_a = 3.
347+
348+u3r_mean() takes varargs, so we can pass in as many axis /
349+return-argument pairs as we wish, terminated with a 0.
350+
351+When pulling arguments out of a hoon remember that Nock and Hoon store
352+lists as skinny right-descending trees (because a linked list is a
353+degenerate case of a tree).
354+
355+The quick way to figure out axis locations is to remember that we
356+start with axis 1, and left children have axis 2n and right children
357+have axis 2n+1.
358+
359+If one argument is passed in, it is found at axis 1.
360+
361+If we have two arguments, axis 1 holds pointers to the first argument
362+in the left child at axis 2 (when n is 1, 2n = 2 ) and the second
363+arguments in the right child at axis 3 (when n is 1, 2n+1 is 3).
364+
365+If we have three arguments, axis 1 holds pointers to the first
366+argument in the left child at axis 2 (when n is 1, 2n = 2 ) and to the
367+next cell at 3, which doesn't contain an argument, but points to
368+argument 2 in the left child at axis 6 (when n is 3, 2n = 6) and to
369+argument 3 in the right child at axis 7 (when n is 3, 2n + 1 = 7).
370+
371+Note that there are #defines to help you specify the axises you want.
372+They are in include/noun/xtract.h
373+
374+If the sample has one item, that one item it is located at the axis
375+specified by the #define u3x_sam_1.
376+
377+If the sample has 2 items, they are located at the axis specified by
378+the #defines u3x_sam_2 and u3x_sam_3.
379+
380+If the sample has 3 items, they are located at the axis specified by
381+the #defines u3x_sam_2, u3x_sam_6, and u3x_sam_7.
382+
383+etc.
384+
385+If you have four arguments and want to tease them out and verify them, you could use code like this
386+
387+N.B. in our fprintf()s we're using both \n and \r to achieve line feed
388+(move cursor down one line) and carriage return (move it to the left),
389+because Urbit uses ncurses to control the screen and it changes the
390+default behavior you may be used to (where \n accomplishes both).
391+```
392+ c3_o ret;
393+ u3_noun sample;
394+ ret = u3r_mean(cor, u3x_sam_1, &sample, 0);
395+ fprintf(stderr, "ret = %i\n\r", ret); // we want ret = 0 = yes
396+ u3m_p("sample", sample); // pretty print the entire sample
397+
398+ ret = u3r_mean(cor, u3x_sam_2, &sample, 0);
399+ fprintf(stderr, "ret = %i\n\r", ret);
400+ u3m_p("2: ", sample);
401+
402+ ret = u3r_mean(cor, u3x_sam_6, &sample, 0);
403+ fprintf(stderr, "ret = %i\n\r", ret);
404+ u3m_p("6: ", sample);
405+
406+ ret = u3r_mean(cor, u3x_sam_14, &sample, 0);
407+ fprintf(stderr, "ret = %i\n\r", ret);
408+ u3m_p("14: ", sample);
409+
410+ ret = u3r_mean(cor, u3x_sam_15, &sample, 0);
411+ fprintf(stderr, "ret = %i\n\r", ret);
412+ u3m_p("15: ", sample);
413+```
414+
415+If the hoon that you're jetting looks like this
416+```
417+ ++ make-k
418+ ~/ %make-k
419+ =, mimes:html
420+ |= [aaa=@ bbb=@ ccc=@]
421+```
422+In the C code you'd fetch them out of the payload with
423+```
424+ u3r_mean(cor,
425+ u3x_sam_2, & arg_aaa,
426+ u3x_sam_5, & arg_bbb,
427+ u3x_sam_6, & arg_ccc
428+ ...
429+ 0)
430+```
431+If you're confident, go ahead and write code. If you want to inspect
432+your arguments to see what's going on, you can pretty print the
433+sample.
434+
435+You could - IN THEORY - inspect / pretty-print the noun by calling
436+```
437+ u3m_p("description", cor); :: DO NOT DO THIS !!!
438+```
439+...but you don't want to do this, because, recall, cor contains the
440+entire context - the whole enchilada.
441+
442+Do instead, perhaps,
443+```
444+ c3_o ret;
445+ u3_noun sample;
446+
447+ ret = u3r_mean(sample, u3x_sam_1, &sample, 0);
448+ fprintf(stderr, "ret = %i\n\r", ret); // we want ret = 0 = yes
449+ u3m_p("sample", sample); // pretty print the entire sample
450+```
451+
452+After our C function pulls out the arguments it needs to type check them.
453+
454+If arg_a is supposed to be a atom, trust but verify:
455+```
456+ u3ud(arg_a); // checks for atomicity; alias for u3a_is_atom()
457+```
458+If it's supposed to be a cell:
459+```
460+ u3du(arg_a); // checks for cell-ness
461+```
462+There are other tests you might need to use
463+```
464+ u3a_is_cat()
465+ u3a_is_dog()
466+
467+ u3a_is_pug()
468+ u3a_is_pom()
469+```
470+All of these rests return Hoon loobeans (yes/no vs true / false), so
471+check return values vs c3n / c3y. If any of these u3_mean(), u3ud()
472+etc return u3n you have an error and should return
473+```
474+ return u3m_bail(c3__exit);
475+```
476+otherwise pass the arguments into your "inner" jet function and return the results of that.
477+
478+### Edit the C source code to add the u3qe_() function
479+
480+The u3qe_() function is the "real" jet - the C code that replaces the hoon.
481+
482+First, you may need to massage your inputs a bit to get them into types that you can use.
483+
484+You have received a bunch of u3_nouns or u3_atoms, but you presumably want to do
485+things in a native C / non-Hoon manner: computing w raw integers, etc.
486+
487+A u3_noun will want to be further diassembled into atoms. XXX
488+
489+A u3_atom represents a simple number, but the implementation may or
490+may not be simple. If the value held in the atom is 31 bits or less,
491+it's stored directly in the atom. If the value is 32 bits the atom
492+holds a pointer into the loom where the actual value is stored. ( see https://urbit.org/docs/vere/nouns/ )
493+
494+You don't want to get bogged down in the details of this - you just
495+want to get data out of your atoms.
496+
497+If you know that the data fits in 32 bits or less, you can use
498+```
499+ u3r_word(c3_w a_w, u3_atom b);
500+```
501+
502+If it is longer than 32 bits, use
503+```
504+ u3r_words(c3_w a_w, c3_w b_w, c3_w* c_w, u3_atom d);
505+```
506+
507+or
508+```
509+ u3r_bytes(c3_w a_w, c3_w b_w, c3_y* c_y, u3_atom d)
510+```
511+
512+(N.B. You may want to use u3r_bytes regardless, as
513+
514+The actual meat of the function is up to you. What is it supposed to do?
515+
516+Now we move on to return semantics.
517+
518+First, you can transfer raw values into nouns using
519+```
520+ u3_noun u3i_words(c3_w a_w, const c3_w* b_w)
521+```
522+and you can build cells out of nouns using
523+```
524+ u3nc(); // pair
525+ u3nt(); // triple
526+ u3nq(); // quad
527+
528+```
529+There are two facets here: (i) data format, (ii) memory allocation.
530+
531+Regarding data format, if the hoon is expected to return a single atom (e.g. if the hoon looks like this
532+```
533+ ++ make-k
534+ ~/ %make-k
535+ |= [has=@uvI prv=@] :: <---- input parguments
536+ ^- @ :: <---- return value is a single value of type '@' (atom)
537+ ...
538+```
539+then your C code - at least when you're stubbing it out - can do something like
540+```
541+ return(123);
542+```
543+Or, if you want to create an atom more formally, you can build it like this
544+```
545+ // this variable is on the stack and will disappear
546+ unsigned char nonce32[32];
547+
548+ // this allocates an indirect (> 31 bits) atom in the loom,
549+ // does appropriate reference count, and returns the 32 bit handle to the atom
550+ u3_noun nonce = u3i_words(8, (const c3_w*) nonce32);
551+
552+ // this returns the 32 bit handle to the atom
553+ return(nonce);
554+```
555+If, on the other hand, your hoon looks like
556+```
557+ ++ ecdsa-raw-sign :: generate signature
558+ ~/ %ecdsa-raw-sign
559+ |= [has=@uvI prv=@]
560+ ^- [v=@ r=@ s=@]
561+ ...
562+```
563+ending your C code with
564+```
565+ return(123);
566+```
567+is wrong and will result in a dojo error because you are returning a single atom, instead of a list of three atoms.
568+
569+Instead do one of these:
570+```
571+ return(u3nc(a, b)); // for two atoms
572+ return(u3nt(a, b, c)); // for three atoms
573+ return(u3nq(a, b, c, d)); // for four atoms
574+```
575+If you need to return a longer list, you can compose your own. Look
576+at the definitions of these three functions and you will see that they
577+are just recursive calls to the cell constructor u3i_cell() e.g.
578+```
579+ u3i_cell(a, u3i_cell(b, u3i_cell(c, d));
580+```
581+
582+XXX more here about memory model, allocation, ownership
583+
584+
585+
586+## Compile the C code
587+
588+You've edited C code; now you need to compile it to build a new urbit executable!
589+
590+
591++ cd ~/tlon/urbit
592++ rm -rf build
593++ configure: choose one of
594+ + meson configure -Dbuildtype=release build
595+ + meson configure -Dbuildtype=debugoptimized build
596+ + meson configure -Dbuildtype=debug build
597+
598+Note that debugoptimized builds run slower than release builds, and debug builds run slower yet. Booting a debug builkd of urbit may take several minutes. [ N.B. compiler flags -O2 vs -O3 ]
599++ scripts/build
600+
601+## Compile the Hoon code into a pill
602+
603+You've compiled the Hoon code. Now you need to compile it.
604+
605+Wait, compile? Isn't Hoon that one types at the dojo prompt interpretted, or compiled on the fly?
606+
607+Yes. But.
608+
609+When the urbit executable runs the first thing it does is load the
610+complete arvo operating system. That step is much faster if it can
611+load a "jam"-ed "pill", where all of the hoon has already been parsed
612+from text file into Hoon abstract syntax tree, and then compiled from
613+the hoon into the Nock equivalent.
614+
615+Note that this means that if you edit hoon.hoon, zuse.hoon, arvo.hoon,
616+vane/ames.hoon, etc. and then restart the urbit executable **YOU ARE
617+NOT RUNNING YOUR NEW CODE**.
618+
619+The only way to run the new code is to follow the following process:
620+
621++ start up urbit, tell it to be a fake zod (act as a galaxy and disconnect from the rest of the network) and have it know where your edited arvo files are (although not execute them, as discussed above):
622+ + rm -rf ~/zod
623+ + rm -rf ~/tlon/mypill.pill
624+ + ~/tlon/urbit/build/urbit -FI zod -A ~/bus/tlon/arvo/ -c zod
625+
626+This should take < 90 seconds.
627+
628++ If you accidentally exit urbit you can restart it XXX
629++ inside your urbit, from the dojo command line, load the hoon files and compile them into a pill file:
630+ + .pill +solid
631+
632+This should take < 90 seconds.
633+
634++ examine the output. Expect to see something like this
635+ ```
636+ %solid-start
637+ %solid-loaded
638+ %solid-parsed
639+ %solid-compiled
640+ %solid-arvo
641+ [%solid-kernel 0x6aa7.627e]
642+ %arvo-assembly
643+ [%solid-veer p=%$ q=/zuse]
644+ [%tang /~zod/home/~2018.7.25..20.47.51..0027/sys/zuse ~mondyr-rovmes]
645+ ```
646+ + if, on the contrary, you see anything like this:
647+ ```
648+ syntax error
649+ {3,356 7}
650+ /~zod/home/~2018.7.25..20.47.51..0027/sys/zuse
651+ ```
652+ you have an error. In this case the error is on line 3,356, character 7 of file ~/tlon/arvo/sys/zuse.hoon.
653+
654+
655+ + the urbit executable will not reload the .hoon files as you edit them. Neither `|reset` nor `.pill +solid` will make edits visible. Instead do this:
656+ + in dojo: `|mount /=base=`
657+ + in dojo: `|autoload %.y`
658+ + at the command line : `ln -s ~/tlon/arvo/sys/zuse.hoon ~/zod/base/sys/zuse.hoon ` (make changes to both arguments of the ln command if you're editing, say, base/sys/vane/ford.hoon)
659+
660+This does three things: it makes urbit's file system mount your own, it makes urbit scan its own filesystem for changes and load them automatically, and it keeps your zuse.hoon
661+
662+Make a change to the hoon file. In dojo you should see `<<sync>>`. If you do not, one of the above steps was done incorrectly. If you do see this, it will be followed by any compile errors.
663+
664++ Edit the hoon and try again. Keep iterating until the hoon compiles.
665++ exit urbit with control-D
666++ save the pill file
667+ + cp ~/zod/.urb/put.pill ~/tlon/mypill.pill
668+
669+[ N.B. another take on explaining the above:
670+
671+Here's some things to note about the pill (and -A):
672+
673+An urbit has to boot into the Arvo kernel -- a nock core with a
674+particular interface. It'd be possible to make some ad-hoc procedure
675+to initialize Arvo, but it would be a pretty drastic layering
676+violation and couple urbit to all sorts of internal implementation
677+details of Arvo and Hoon. In contrast, the pill is basically a
678+serialized, declarative set of steps to initialize Arvo.
679+
680+Right now, the boot process is something of a hack, and the pill is
681+basically a snapshot of a pristine Arvo kernel. In the future (see
682++metal or +brass), the pill will contain something like:
683+
684++ a boot formula
685++ the hoon compiler as nock
686++ the hoon compiler as source
687++ arvo as source
688++ the vanes as source
689++ userspace as source (ie, an initial %clay sync)
690+
691+For now, when you boot a ship that's not a galaxy, the initial %clay
692+filesystem is synced in from the parent ship. When you boot a galaxy,
693+you need to pass in a path to a copy of the Arvo repository so that
694+the %clay filesystem can be initialized without recourse to another
695+ship.
696+
697+Hopefully this helps to demystify these startup procedures.
698+
699+]
700+
701+
702+## Run the compiled C / compiled Hoon pill
703+
704++ type `cd ~`
705++ type `rm -rf zod`
706++ type `~/tlon/urbit/build/urbit -FI zod -A ~/tlon/arvo/ -B ~/tlon/mypill.pill -c zod`.
707+
708+N.B. booting should not take more than about 90 seconds. If it
709+goes longer than that you might have created a 'poison pill', which
710+hangs things. Try booting without the -B flag, and/or reverting
711+your hoon changes, generating a new pill based on that, and
712+launching urbit with the known-clean pill. If these steps and boot
713+in < 90 seconds, but a boot with a pill created from your own hoon
714+does not, you have a hoon bug of some sort.
715+
716+Hoon bugs that disable booting can be as simple as the wrong number
717+of spaces. Many, but not all of them, will result in compile
718+errors during the `.pill +solid` step. If your booting takes > 90
719+seconds, abort it, and look at your hoon. Do a git diff, and
720+remove half the edits. Run through the entire process again. If
721+booting from the pill still hangs, remove half of what remains. Do
722+a binary search to find the precise error.
723+
724++ inside dojo: `|reset`
725++ You now have created a galaxy fakezod, on its own detached network, running your own strange variant of the OS.
726++ inside dojo: `(make-k:secp256k1:secp:crypto `@uvI`12 33)` # or whatever command runs the hoon you're jetting
727++ do your development work
728++ If you happen to exit, you can restart with `urbit -FI zod zod`
729+
730+To expand:
731+* F means "fake"
732+* I means "run as galaxy zod"
733+* the final argument is the unix directory holding the files for the galaxy
734+
735+## Run the jetted code and compare to the non jetted code
736+
737+You are now running your jetted code in a fake zod.
738+
739+It would be convenient to fire up a second urbit in a terminal next to your fake zod, this one using non-jetted hoon.
740+
741+Then you can run identical commands in each, in parallel, and confirm that they do the same thing.
742+
743++ edit ~/tlon/urbit/jets/e/secp.c (or whatever) to include `fprintf(stderr, "*** u3we_sign 2\n");` (or similar) in your jetted functions. This will let us verify that the jets exist and are running.
744++ `cd ~/tlon/ubit ; scripts/build `
745+
746++ `cp ~/tlon/arvo ~/tlon/arvo_nojet`
747+
748++ edit ~/tlon/arvo_nojet/sys/zuse_nojetting.hoon to remove jetting
749+
750++ Because we can not run two instances of the same fake galaxy on the same machine (their ports would conflict), we need to pick a new galaxy name. Galaxy names are not arbitrary. You may not name your galaxy "mygalaxy", "withjet", "withoutjet", or anything like that. Galaxy names are restricted to the range 0-255, converted into pronounceable syllables. 'Zod' is just the pronunciation of '0' ( to see this, in a dojo, cast ~zod to an untyped atom thusly: `@`~zod). Let's pick 1 as our new galaxy id. Use dojo to convert this into a urbit name: `@p`1 yields ~nec.
751+
752++ Open a new terminal. In that terminal: `cd ~ ; rm -rf nec ; ~/tlon/urbit/build/urbit -FI nec -A ~/tlon/arvo_nojetting/ -c nec`
753++ This should take < 90 seconds.
754++ inside your urbit, from the dojo command line, load the hoon files and compile them into a pill file: `.pill +solid`
755++ This should take < 90 seconds.
756++ exit urbit with control-D
757++ save the pill file
758++ type `cp ~/nec/.urb/put.pill ~/tlon/mypill_nojetting.pill `
759++ type `cd ~`
760++ type `rm -rf nec`
761++ type `~/tlon/urbit/build/urbit -FI nec -A ~/tlon/arvo_nojetting/ -B ~/tlon/mypill_nojetting.pill -c nec`
docs/vere/nouns.umdnew file+480
@@ -0,0 +1,480 @@
1+:- :~ navhome/'/docs/'
2+ sort/'3'
3+ next/'true'
4+ title/'Land of Nouns'
5+ ==
6+;>
7+
8+## u3: Land of nouns
9+
10+The division between `c3` and `u3` is that you could theoretically
11+imagine using `c3` as just a generic C environment. Anything to do
12+with nouns is in `u3`.
13+
14+### u3: a map of the system
15+
16+There are two kinds of symbols in `u3`: regular and irregular.
17+Regular symbols follow this pattern:
18+
19+```
20+ prefix purpose .h .c
21+ -------------------------------------------------------
22+ u3a_ allocation i/n/a.h n/a.c
23+ u3e_ persistence i/n/e.h n/e.c
24+ u3h_ hashtables i/n/h.h n/h.c
25+ u3i_ noun construction i/n/i.h n/i.c
26+ u3j_ jet control i/n/j.h n/j.c
27+ u3m_ system management i/n/m.h n/m.c
28+ u3n_ nock computation i/n/n.h n/n.c
29+ u3r_ noun access (error returns) i/n/r.h n/r.c
30+ u3t_ profiling i/n/t.h n/t.c
31+ u3v_ arvo i/n/v.h n/v.c
32+ u3x_ noun access (error crashes) i/n/x.h n/x.c
33+ u3z_ memoization i/n/z.h n/z.c
34+ u3k[a-g] jets (transfer, C args) i/j/k.h j/[a-g]/*.c
35+ u3q[a-g] jets (retain, C args) i/j/q.h j/[a-g]/*.c
36+ u3w[a-g] jets (retain, nock core) i/j/w.h j/[a-g]/*.c
37+```
38+
39+Irregular symbols always start with `u3` and obey no other rules.
40+They're defined in `i/n/u.h`. Finally, `i/all.h` includes all
41+these headers (fast compilers, yay) and is all you need to
42+program in `u3`.
43+
44+### u3: noun internals
45+
46+A noun is a `u3_noun` - currently defined as a 32-bit `c3_w`.
47+
48+If your `u3_noun` is less than `(1 << 31)`, it's a direct atom.
49+Every unsigned integer between `0` and `0x7fffffff` inclusive is
50+its own noun.
51+
52+If bit `31` is set in a `u3_noun`, bit `30` is always set - this
53+bit is reserved. Bit `29` is `1` if the noun is a cell, `0` if
54+it's an atom. Bits `28` through `0` are a word pointer into the
55+loom - see below. The structures are:
56+
57+```
58+ typedef struct {
59+ c3_w mug_w;
60+ c3_w len_w;
61+ c3_w buf_w[0]; // actually [len_w]
62+ } u3a_atom;
63+
64+ typedef struct {
65+ c3_w mug_w;
66+ u3_noun hed;
67+ u3_noun tel;
68+ } u3a_cell;
69+```
70+
71+The only thing that should be mysterious here is `mug_w`, which
72+is a 31-bit lazily computed nonzero short hash (FNV currently,
73+soon Murmur3). If `mug_w` is 0, the hash is not yet computed.
74+We also hijack this field for various hacks, such as saving the
75+new address of a noun when copying over.
76+
77+Also, the value `0xffffffff` is `u3_none`, which is never a valid
78+noun. Use the type `u3_weak` to express that a noun variable may
79+be `u3_none`.
80+
81+### u3: reference counts
82+
83+The only really essential thing you need to know about `u3` is
84+how to handle reference counts. Everything else, you can skip
85+and just get to work.
86+
87+u3 deals with reference-counted, immutable, acyclic nouns.
88+Unfortunately, we are not Apple and can't build reference
89+counting into your C compiler, so you need to count by hand.
90+
91+Every allocated noun (or any allocation object, because our
92+allocator is general-purpose) contains a counter which counts the
93+number of references to it - typically variables with type
94+`u3_noun`. When this counter goes to 0, the noun is freed.
95+
96+To tell `u3` that you've added a reference to a noun, call the
97+function `u3a_gain()` or its shorthand `u3k()`. (For your
98+convenience, this function returns its argument.) To tell `u3`
99+that you've destroyed a reference, call `u3a_lose()` or `u3z()`.
100+
101+(If you screw up by decrementing the counter too much, `u3` will
102+dump core in horrible ways. If you screw up by incrementing it
103+too much, `u3` will leak memory. To check for memory leaks,
104+set the `bug_o` flag in `u3e_boot()` - eg, run `vere` with `-g`.
105+Memory leaks are difficult to debug - the best way to handle
106+leaks is just to revert to a version that didn't have them, and
107+look over your code again.)
108+
109+(You can gain or lose a direct atom. It does nothing.)
110+
111+### u3: reference protocols
112+
113+*THIS IS THE MOST CRITICAL SECTION IN THE `u3` DOCUMENTATION.*
114+
115+The key question when calling a C function in a refcounted world
116+is what the function will do to the noun refcounts - and, if the
117+function returns a noun, what it does to the return.
118+
119+There are two semantic patterns, `transfer` and `retain`. In
120+`transfer` semantics, the caller "gives" a use count to the
121+callee, which "gives back" any return. For instance, if I have
122+
123+```
124+ {
125+ u3_noun foo = u3i_string("foobar");
126+ u3_noun bar;
127+
128+ bar = u3f_futz(foo);
129+ [...]
130+ u3z(bar);
131+ }
132+```
133+
134+Suppose `u3f_futz()` has `transfer` semantics. At `[...]`, my
135+code holds one reference to `bar` and zero references to `foo` -
136+which has been freed, unless it's part of `bar`. My code now
137+owns `bar` and gets to work with it until it's done, at which
138+point a `u3z()` is required.
139+
140+On the other hand, if `u3f_futz()` has `retain` semantics, we
141+need to write
142+
143+```
144+ {
145+ u3_noun foo = u3i_string("foobar");
146+ u3_noun bar;
147+
148+ bar = u3f_futz(foo);
149+ [...]
150+ u3z(foo);
151+ }
152+```
153+
154+because calling `u3f_futz()` does not release our ownership of
155+`foo`, which we have to free ourselves.
156+
157+But if we free `bar`, we are making a great mistake, because our
158+reference to it is not in any way registered in the memory
159+manager (which cannot track references in C variables, of
160+course). It is normal and healthy to have these uncounted
161+C references, but they must be treated with care.
162+
163+The bottom line is that it's essential for the caller to know
164+the refcount semantics of any function which takes or returns a
165+noun. (In some unusual circumstances, different arguments or
166+returns in one function may be handled differently.)
167+
168+Broadly speaking, as a design question, retain semantics are more
169+appropriate for functions which inspect or query nouns. For
170+instance, `u3h()` (which takes the head of a noun) retains, so
171+that we can traverse a noun tree without constantly incrementing
172+and decrementing.
173+
174+Transfer semantics are more appropriate for functions which make
175+nouns, which is obviously what most functions do.
176+
177+In general, though, in most places it's not worth thinking about
178+what your function does. There is a convention for it, which
179+depends on where it is, not what it does. Follow the convention.
180+
181+### u3: reference conventions
182+
183+The `u3` convention is that, unless otherwise specified, *all
184+functions have transfer semantics* - with the exception of the
185+prefixes: `u3r`, `u3x`, `u3z`, `u3q` and `u3w`. Also, within
186+jet directories `a` through `f` (but not `g`), internal functions
187+retain (for historical reasons).
188+
189+If functions outside this set have retain semantics, they need to
190+be commented, both in the `.h` and `.c` file, with `RETAIN` in
191+all caps. Yes, it's this important.
192+
193+### u3: system architecture
194+
195+If you just want to tinker with some existing code, it might be
196+enough to understand the above. If not, it's probably worth
197+taking the time to look at `u3` as a whole.
198+
199+`u3` is designed to work as a persistent event processor.
200+Logically, it computes a function of the form
201+
202+```
203+ f(event, old state) -> (actions, new state)
204+```
205+
206+Obviously almost any computing model - including, but not limited
207+to, Urbit - can be defined in this form. To create the illusion
208+of a computer that never loses state and never fails, we:
209+
210+- log every event externally before it goes into u3
211+- keep a single reference to a permanent state noun.
212+- can abort any event without damaging the permanent state.
213+- snapshot the permanent state periodically, and/or prune logs.
214+
215+### u3: the road model
216+
217+`u3` uses a memory design which I'm sure someone has invented
218+somewhere before, because it's not very clever, but I've never
219+seen it anywhere in particular.
220+
221+Every allocation starts with a solid block of memory, which `u3`
222+calls the `loom`. How do we allocate on the loom? You're
223+probably familiar with the Unix heap-stack design, in which the
224+stack grows downward and the heap (malloc arena) grows upward:
225+
226+```
227+ 0 brk ffff
228+ | heap | stack |
229+ |------------#################################+++++++++++++|
230+ | | |
231+ 0 sp ffff
232+```
233+
234+A road is a normal heap-stack system, except that the heap
235+and stack can point in *either direction*. Therefore, inside
236+a road, we can nest another road in the *opposite direction*.
237+
238+When the opposite road completes, its heap is left on top of
239+the opposite heap's stack. It's no more than the normal
240+behavior of a stack machine for all subcomputations to push
241+their results on the stack.
242+
243+The performance tradeoff of "leaping" - reversing directions in
244+the road - is that if the outer computation wants to preserve the
245+results of the inner one, not just use them for temporary
246+purposes, it has to *copy them*.
247+
248+This is a trivial cost in some cases, a prohibitive cost in
249+others. The upside, of course, is that all garbage accrued
250+in the inner computation is discarded at zero cost.
251+
252+The goal of the road system is the ability to *layer* memory
253+models. If you are allocating on a road, you have no idea
254+how deep within a nested road system you are - in other words,
255+you have no idea exactly how durable your result may be.
256+But free space is never fragmented within a road.
257+
258+Roads do not reduce the generality or performance of a memory
259+system, since even the most complex GC system can be nested
260+within a road at no particular loss of performance - a road
261+is just a block of memory.
262+
263+Each road (`u3a_road` to be exact) uses four pointers: `rut` is
264+the bottom of the arena, `hat` the top of the arena, `mat` the
265+bottom of the stack, `cap` the top of the stack. (Bear in mind
266+that the road "stack" is not actually used as the C function-call
267+stack, though it probably should be.)
268+
269+A "north" road has the stack high and the heap low:
270+
271+```
272+ 0 rut hat ffff
273+ | | | |
274+ |~~~~~~~~~~~~-------##########################+++++++$~~~~~|
275+ | | | |
276+ 0 cap mat ffff
277+```
278+
279+A "south" road is the other way around:
280+
281+```
282+ 0 mat cap ffff
283+ | | | |
284+ |~~~~~~~~~~~~$++++++##########################--------~~~~~|
285+ | | | |
286+ 0 hat rut ffff
287+```
288+
289+Legend: `-` is durable storage (heap); `+` is temporary storage
290+(stack); `~` is deep storage (immutable); `$` is the allocation
291+frame `#` is free memory.
292+
293+Pointer restrictions: pointers stored in `+` can point anywhere.
294+Pointers in `-` can only point to `-` or `~`; pointers in `~`
295+only point to `~`.
296+
297+To "leap" is to create a new inner road in the `###` free space.
298+but in the reverse direction, so that when the inner road
299+"falls" (terminates), its durable storage is left on the
300+temporary storage of the outer road.
301+
302+`u3` keeps a global variable, `u3_Road` or its alias `u3R`, which
303+points to the current road. (If we ever run threads in inner
304+roads - see below - this will become a thread-local variable.)
305+Relative to `u3R`, `+` memory is called `junior` memory; `-`
306+memory is `normal` memory; `~` is `senior` memory.
307+
308+### u3: explaining the road model
309+
310+But... why?
311+
312+We're now ready to understand why the road system works so
313+logically with the event and persistence model.
314+
315+The key is that *we don't update refcounts in senior memory.*
316+A pointer from an inner road to an outer road is not counted.
317+Also, the outmost, or `surface` road, is the only part of the
318+image that gets checkpointed.
319+
320+So the surface road contains the entire durable state of `u3`.
321+When we process an event, or perform any kind of complicated or
322+interesting calculation, *we process it in an inner road*. If
323+its results are saved, they need to be copied.
324+
325+Since processing in an inner road does not touch surface memory,
326+(a) we can leave the surface road in a read-only state and not
327+mark its pages dirty; (b) we can abort an inner calculation
328+without screwing up the surface; and (c) because inner results
329+are copied onto the surface, the surface doesn't get fragmented.
330+
331+All of (a), (b) and (c) are needed for checkpointing to be easy.
332+It might be tractable otherwise, but easy is even better.
333+
334+Moreover, while the surface is most definitely single-threaded,
335+we could easily run multiple threads in multiple inner roads
336+(as long as the threads don't have pointers into each others'
337+memory, which they obviously shouldn't).
338+
339+Moreover, in future, we'll experiment more with adding road
340+control hints to the programmer's toolbox. Reference counting is
341+expensive. We hypothesize that in many - if not most - cases,
342+the programmer can identify procedural structures whose garbage
343+should be discarded in one step by copying the results. Then,
344+within the procedure, we can switch the allocator into `sand`
345+mode, and stop tracking references at all.
346+
347+### u3: rules for C programming
348+
349+There are two levels at which we program in C: (1) above the
350+interpreter; (2) within the interpreter or jets. These have
351+separate rules which need to be respected.
352+
353+### u3: rules above the interpreter
354+
355+In its relations with Unix, Urbit follows a strict rule of "call
356+me, I won't call you." We do of course call Unix system calls,
357+but only for the purpose of actually computing.
358+
359+Above Urbit, you are in a normal C/Unix programming environment
360+and can call anything in or out of Urbit. Note that when using
361+`u3`, you're always on the surface road, which is not thread-safe
362+by default. Generally speaking, `u3` is designed to support
363+event-oriented, single-threaded programming.
364+
365+If you need threads which create nouns, you could use
366+`u3m_hate()` and `u3m_love()` to run these threads in subroads.
367+You'd need to make the global road pointer, `u3R`, a thread-local
368+variable instead. This seems perfectly practical, but we haven't
369+done it because we haven't needed to.
370+
371+### u3: rules within the interpreter
372+
373+Within the interpreter, your code can run either in the surface
374+road or in a deep road. You can test this by testing
375+
376+```
377+ (&u3H->rod_u == u3R)
378+```
379+
380+ie: does the pier's home road equal the current road pointer?
381+
382+Normally in this context you assume you're obeying the rules of
383+running on an inner road, ie, "deep memory." Remember, however,
384+that the interpreter *can* run on surface memory - but anything
385+you can do deep, you can do on the surface. The converse is by
386+no means the case.
387+
388+In deep memory, think of yourself as if in a signal handler.
389+Your execution context is extremely fragile and may be terminated
390+without warning or cleanup at any time (for instance, by `ctrl-c`).
391+
392+For instance, you can't call `malloc` (or C++ `new`) in your C
393+code, because you don't have the right to modify data structures
394+at the global level, and will leave them in an inconsistent state
395+if your inner road gets terminated. (Instead, use our drop-in
396+replacements, `u3a_malloc()`, `u3a_free()`, `u3a_realloc()`.)
397+
398+A good example is the different meaning of `c3_assert()` inside
399+and outside the interpreter. At either layer, you can use
400+regular assert(), which will just kill your process. On the
401+surface, `c3_assert()` will just... kill your process.
402+
403+In deep execution, `c3_assert()` will issue an exception that
404+queues an error event, complete with trace stack, on the Arvo
405+event queue. Let's see how this happens.
406+
407+### u3: exceptions
408+
409+You produce an exception with
410+
411+```
412+ /* u3m_bail(): bail out. Does not return.
413+ **
414+ ** Bail motes:
415+ **
416+ ** %exit :: semantic failure
417+ ** %evil :: bad crypto
418+ ** %intr :: interrupt
419+ ** %fail :: execution failure
420+ ** %foul :: assert failure
421+ ** %need :: network block
422+ ** %meme :: out of memory
423+ ** %time :: timed out
424+ ** %oops :: assertion failure
425+ */
426+ c3_i
427+ u3m_bail(c3_m how_m);
428+```
429+
430+Broadly speaking, there are two classes of exception: internal
431+and external. An external exception begins in a Unix signal
432+handler. An internal exception begins with a call to longjmp()
433+on the main thread.
434+
435+There are also two kinds of exception: mild and severe. An
436+external exception is always severe. An internal exception is
437+normally mild, but some (like `c3__oops`, generated by
438+`c3_assert()`) are severe.
439+
440+Either way, exceptions come with a stack trace. The `u3` nock
441+interpreter is instrumented to retain stack trace hints and
442+produce them as a printable `(list tank)`.
443+
444+Mild exceptions are caught by the first virtualization layer and
445+returned to the caller, following the behavior of the Nock
446+virtualizer `++mock` (in `hoon.hoon`)
447+
448+Severe exceptions, or mild exceptions at the surface, terminate
449+the entire execution stack at any depth and send the cumulative
450+trace back to the `u3` caller.
451+
452+For instance, `vere` uses this trace to construct a `%crud`
453+event, which conveys our trace back toward the Arvo context where
454+it crashed. This lets any UI component anywhere, even on a
455+remote node, render the stacktrace as a consequence of the user's
456+action - even if its its direct cause was (for instance) a Unix
457+SIGINT or SIGALRM.
458+
459+### u3: C structures on the loom
460+
461+Normally, all data on the loom is nouns. Sometimes we break this
462+rule just a little, though - eg, in the `u3h` hashtables.
463+
464+To point to non-noun C structs on the loom, we use a `u3_post`,
465+which is just a loom word offset. A macro lets us declare this
466+as if it was a pointer:
467+
468+```
469+ typedef c3_w u3_post;
470+ #define u3p(type) u3_post
471+```
472+
473+Some may regard this as clever, others as pointless. Anyway, use
474+`u3to()` and `u3of()` to convert to and from pointers.
475+
476+When using C structs on the loom - generally a bad idea - make
477+sure anything which could be on the surface road is structurally
478+portable, eg, won't change size when the pointer size changes.
479+(Note also: we consider little-endian, rightly or wrongly, to
480+have won the endian wars.)
docs/vere/runtime.umdnew file+46
@@ -0,0 +1,46 @@
1+:- :~ navhome/'/docs/'
2+ sort/'1'
3+ next/'true'
4+ title/'C Runtime System'
5+ ==
6+;>
7+
8+# C runtime system
9+
10+The Urbit interpreter is built on a Nock runtime system written
11+in C, `u3`. This section is a relatively complete description.
12+
13+You should keep reading if (a) you're planning to work on the
14+Urbit interpreter; (b) you're a language implementation geek; or
15+(c) you don't really understand anything until you've seen the
16+actual structs.
17+
18+## u3: Noun processing in C
19+
20+`u3` is the C library that makes Urbit work. If it wasn't called
21+`u3`, it might be called `libnoun` - it's a library for making
22+and storing nouns.
23+
24+What's a noun? A noun is either a cell or an atom. A cell is an
25+ordered pair of any two nouns. An atom is an unsigned integer of
26+any size.
27+
28+To the C programmer, this is not a terribly complicated data
29+structure, so why do you need a library for it?
30+
31+One: nouns have a well-defined computation kernel, Nock, whose
32+spec fits on a page and gzips to 340 bytes. But the only
33+arithmetic operation in Nock is increment. So it's nontrivial
34+to compute both efficiently and correctly.
35+
36+Two: `u3` is designed to be a "solid-state interpreter," ie, a
37+single-level store which is transparently snapshotted. This
38+implies a specialized memory-management model, etc, etc.
39+
40+(Does `u3` depend on the higher levels of Urbit, Arvo and Hoon?
41+Yes and no. `u3` expects you to load something shaped like an
42+Arvo kernel, and use it as an event-processing function. But you
43+don't need to use this feature if you don't want, and your kernel
44+doesn't have to be Arvo proper - just Arvo-compatible. Think of
45+`u3` as the BIOS and Arvo as the boot kernel. And there are no
46+dependencies at all between Hoon the language and `u3`.)