on master help sign in
Run pandoc recursively over docs

Result from running this pandoc bash script recursively over all of the docs: ``` shopt -s globstar for file in **/*.md do pandoc --atx-headers --columns=80 --normalize --standalone --tab-stop=4 -f markdown-footnotes-inline_notes-pandoc_title_block+yaml_metadata_block-mmd_title_block-table_captions-implicit_figures-simple_tables-grid_tables-pipe_tables-citations-raw_tex+raw_html-tex_math_dollars-tex_math_single_backslash-tex_math_double_backslash-latex_macros-fenced_code_blocks-fenced_code_attributes+backtick_code_blocks-inline_code_attributes+markdown_in_html_blocks-native_divs-native_spans-bracketed_spans-markdown_attribute-escaped_line_breaks-link_attributes-mmd_link_attributes-autolink_bare_uris-fancy_lists-lists_without_preceding_blankline-startnum-definition_lists-compact_definition_lists-example_lists-all_symbols_escapable-angle_brackets_escapable-intraword_underscores+blank_before_blockquote+blank_before_header-strikeout-superscript-subscript-hard_line_breaks-ignore_line_breaks-east_asian_line_breaks-literate_haskell-abbreviations-emoji-auto_identifiers-ascii_identifiers-header_attributes-mmd_header_identifiers-implicit_header_references-line_blocks-epub_html_exts-shortcut_reference_links -t markdown-footnotes-inline_notes-pandoc_title_block+yaml_metadata_block-mmd_title_block-table_captions-implicit_figures-simple_tables-multiline_tables-grid_tables-pipe_tables-citations-raw_tex+raw_html-tex_math_dollars-tex_math_single_backslash-tex_math_double_backslash-latex_macros-fenced_code_blocks-fenced_code_attributes-backtick_code_blocks-inline_code_attributes+markdown_in_html_blocks-native_divs-native_spans-bracketed_spans-markdown_attribute+escaped_line_breaks-link_attributes-mmd_link_attributes-autolink_bare_uris+fancy_lists-lists_without_preceding_blankline-startnum-definition_lists-compact_definition_lists-example_lists-all_symbols_escapable-angle_brackets_escapable-intraword_underscores+blank_before_blockquote+blank_before_header-strikeout-superscript-subscript-hard_line_breaks-ignore_line_breaks-east_asian_line_breaks-literate_haskell-abbreviations-emoji-auto_identifiers-ascii_identifiers-header_attributes-mmd_header_identifiers-implicit_header_references-line_blocks-epub_html_exts-shortcut_reference_links $file -o $file done ```

commit105bd25f8b2057baaf98f4706286b8be1b21a6a1 authorKeaton Dunsford <keaton@tlon.io> dateMon 11 Sep 2017, 16:56 (9 years ago) parente8d0bb1
323 files changed+19651−24133
docs.md+55−34 docs/about.md+1−1 docs/about/contributing.md+15−14 docs/about/glossary.md+93−109 docs/about/objections.md+453−170 docs/about/overview.md+47−58 docs/about/runtime.md+794−923 docs/arvo.md+3−2 docs/arvo/api.md+425−456 docs/arvo/basic.md+103−113 docs/arvo/generators.md+76−86 docs/arvo/http.md+192−208 docs/arvo/internals.md+90−102 docs/arvo/internals/ames.md+15−18 docs/arvo/internals/ames/commentary.md+690−769 docs/arvo/internals/behn.md+12−14 docs/arvo/internals/clay.md+13−16 docs/arvo/internals/clay/architecture.md+295−349 docs/arvo/internals/clay/commentary.md+724−811 docs/arvo/internals/dill.md+16−18 docs/arvo/internals/eyre.md+14−13 docs/arvo/internals/eyre/commentary.md+50−45 docs/arvo/internals/eyre/specification.md+355−189 docs/arvo/internals/ford.md+47−55 docs/arvo/internals/ford/commentary.md+852−956 docs/arvo/internals/ford/runes.md+228−225 docs/arvo/internals/gall.md+57−71 docs/arvo/marks.md+82−102 docs/arvo/network.md+183−202 docs/arvo/security-driver.md+215−255 docs/arvo/state.md+62−69 docs/arvo/subject.md+36−43 docs/arvo/subscriptions.md+116−129 docs/arvo/web-apps.md+212−229 docs/byte.md+3−2 docs/byte/0.md+157−199 docs/byte/1.md+222−252 docs/byte/2.md+287−342 docs/community-docs.md+20−21 docs/community-projects.md+15−19 docs/community-projects/nock-implementations.md+2−2 docs/community-projects/nock-implementations/clojure.md+117−118 docs/community-projects/nock-implementations/csharp.md+377−379 docs/community-projects/nock-implementations/groovy.md+177−178 docs/community-projects/nock-implementations/haskell.md+56−57 docs/community-projects/nock-implementations/hoon.md+47−49 docs/community-projects/nock-implementations/javascript.md+355−357 docs/community-projects/nock-implementations/python.md+75−77 docs/community-projects/nock-implementations/ruby.md+130−131 docs/community-projects/nock-implementations/scala.md+68−69 docs/community-projects/nock-implementations/scheme.md+112−113 docs/community-projects/nock-implementations/swift.md+317−319 docs/community-projects/string-processing.md+6−8 docs/community-projects/talkbot.md+4−13 docs/community-projects/yint.md+4−13 docs/hoon.md+3−3 docs/hoon/advanced.md+140−159 docs/hoon/basic.md+123−139 docs/hoon/concepts.md+134−154 docs/hoon/demo.md+43−47 docs/hoon/examples.md+453−512 docs/hoon/exercises.md+6−7 docs/hoon/exercises/data-structures.md+30−40 docs/hoon/exercises/fizzbuzz.md+25−28 docs/hoon/exercises/life.md+94−110 docs/hoon/exercises/lists.md+22−27 docs/hoon/exercises/math.md+12−17 docs/hoon/irregular.md+114−95 docs/hoon/library.md+1−1 docs/hoon/library/1a.md+65−123 docs/hoon/library/1b.md+21−37 docs/hoon/library/1c.md+51−103 docs/hoon/library/2a.md+75−141 docs/hoon/library/2b.md+191−347 docs/hoon/library/2c.md+74−150 docs/hoon/library/2d.md+25−49 docs/hoon/library/2e.md+22−41 docs/hoon/library/2f.md+29−63 docs/hoon/library/2g.md+1−2 docs/hoon/library/2h.md+77−152 docs/hoon/library/2i.md+46−55 docs/hoon/library/2j.md+17−24 docs/hoon/library/2k.md+46−84 docs/hoon/library/2l.md+1−2 docs/hoon/library/2m.md+1−2 docs/hoon/library/2n.md+26−54 docs/hoon/library/2o.md+21−44 docs/hoon/library/2p.md+30−52 docs/hoon/library/2q.md+49−85 docs/hoon/library/3a.md+116−205 docs/hoon/library/3b.md+1−2 docs/hoon/library/3c.md+99−167 docs/hoon/library/3d.md+13−31 docs/hoon/library/3e.md+4−8 docs/hoon/library/3f.md+108−182 docs/hoon/library/3g.md+49−96 docs/hoon/library/4a.md+30−52 docs/hoon/library/4b.md+97−190 docs/hoon/library/4c.md+33−66 docs/hoon/library/4d.md+14−27 docs/hoon/library/4e.md+70−136 docs/hoon/library/4f.md+148−286 docs/hoon/library/4g.md+24−47 docs/hoon/library/4h.md+110−210 docs/hoon/library/4i.md+1−2 docs/hoon/library/4j.md+310−545 docs/hoon/library/4k.md+138−267 docs/hoon/library/4l.md+75−157 docs/hoon/library/4m.md+57−111 docs/hoon/library/4n.md+54−97 docs/hoon/library/4o.md+107−182 docs/hoon/library/5a.md+1−2 docs/hoon/library/5b.md+1−2 docs/hoon/library/5c.md+1−2 docs/hoon/library/5d.md+1−2 docs/hoon/library/5e.md+1−2 docs/hoon/library/5f.md+31−61 docs/hoon/library/5g.md+1−1 docs/hoon/library/zuse.md+1−1 docs/hoon/library/zuse/core/crua.md+1−6 docs/hoon/library/zuse/core/epur.md+107−213 docs/hoon/library/zuse/core/fu.md+2−5 docs/hoon/library/zuse/core/jo.md+131−239 docs/hoon/library/zuse/core/poja.md+114−209 docs/hoon/library/zuse/core/poxa.md+50−99 docs/hoon/library/zuse/core/poxo.md+25−52 docs/hoon/library/zuse/core/yu.md+23−35 docs/hoon/library/zuse/diff.md+82−143 docs/hoon/library/zuse/gate/clan.md+5−12 docs/hoon/library/zuse/gate/dawn.md+7−14 docs/hoon/library/zuse/gate/daws.md+5−12 docs/hoon/library/zuse/gate/deal.md+5−12 docs/hoon/library/zuse/gate/deft.md+7−14 docs/hoon/library/zuse/gate/dust.md+5−12 docs/hoon/library/zuse/gate/earl.md+5−12 docs/hoon/library/zuse/gate/earn.md+20−38 docs/hoon/library/zuse/gate/fain.md+7−14 docs/hoon/library/zuse/gate/feel.md+6−14 docs/hoon/library/zuse/gate/file.md+6−14 docs/hoon/library/zuse/gate/foal.md+7−14 docs/hoon/library/zuse/gate/fray.md+7−14 docs/hoon/library/zuse/gate/fuel.md+5−12 docs/hoon/library/zuse/gate/furl.md+7−14 docs/hoon/library/zuse/gate/glam.md+4−10 docs/hoon/library/zuse/gate/glon.md+4−10 docs/hoon/library/zuse/gate/gnom.md+4−10 docs/hoon/library/zuse/gate/jape.md+5−12 docs/hoon/library/zuse/gate/jesc.md+7−13 docs/hoon/library/zuse/gate/joba.md+5−12 docs/hoon/library/zuse/gate/jobe.md+5−12 docs/hoon/library/zuse/gate/jone.md+5−12 docs/hoon/library/zuse/gate/lead.md+6−14 docs/hoon/library/zuse/gate/mang.md+7−15 docs/hoon/library/zuse/gate/meat.md+5−12 docs/hoon/library/zuse/gate/moon.md+6−14 docs/hoon/library/zuse/gate/mung.md+7−14 docs/hoon/library/zuse/gate/perk.md+16−23 docs/hoon/library/zuse/gate/pojo.md+5−12 docs/hoon/library/zuse/gate/saxo.md+6−13 docs/hoon/library/zuse/gate/scanf.md+17−19 docs/hoon/library/zuse/gate/sein.md+5−10 docs/hoon/library/zuse/gate/sifo.md+5−12 docs/hoon/library/zuse/gate/stud.md+5−12 docs/hoon/library/zuse/gate/taco.md+4−10 docs/hoon/library/zuse/gate/tact.md+7−14 docs/hoon/library/zuse/gate/tame.md+7−14 docs/hoon/library/zuse/gate/tell.md+7−14 docs/hoon/library/zuse/gate/tome.md+6−13 docs/hoon/library/zuse/gate/tope.md+3−7 docs/hoon/library/zuse/gate/txml.md+5−11 docs/hoon/library/zuse/gate/unt.md+5−12 docs/hoon/library/zuse/gate/urld.md+5−12 docs/hoon/library/zuse/gate/urle.md+7−15 docs/hoon/library/zuse/mold/udal.md+3−7 docs/hoon/library/zuse/mold/udon.md+1−4 docs/hoon/library/zuse/mold/umph.md+1−4 docs/hoon/library/zuse/mold/unce.md+1−2 docs/hoon/library/zuse/mold/upas.md+1−4 docs/hoon/library/zuse/mold/urge.md+1−4 docs/hoon/library/zuse/rsa.md+24−26 docs/hoon/mission.md+28−34 docs/hoon/reference.md+11−12 docs/hoon/syntax.md+228−262 docs/hoon/troubleshooting.md+97−120 docs/hoon/twig.md+44−50 docs/hoon/twig/atom.md+3−6 docs/hoon/twig/atom/knit.md+9−17 docs/hoon/twig/atom/path.md+9−11 docs/hoon/twig/atom/rock.md+12−16 docs/hoon/twig/atom/sand.md+40−43 docs/hoon/twig/bar-core.md+14−16 docs/hoon/twig/bar-core/cab-door.md+46−60 docs/hoon/twig/bar-core/cen-core.md+26−32 docs/hoon/twig/bar-core/col-gasp.md+7−12 docs/hoon/twig/bar-core/dot-trap.md+41−54 docs/hoon/twig/bar-core/hep-loop.md+27−40 docs/hoon/twig/bar-core/ket-cork.md+26−36 docs/hoon/twig/bar-core/sig-port.md+6−15 docs/hoon/twig/bar-core/tar-gill.md+38−48 docs/hoon/twig/bar-core/tis-gate.md+29−43 docs/hoon/twig/bar-core/wut-tray.md+12−20 docs/hoon/twig/buc-mold.md+34−39 docs/hoon/twig/buc-mold/base.md+15−18 docs/hoon/twig/buc-mold/cab-shoe.md+20−28 docs/hoon/twig/buc-mold/cen-book.md+21−25 docs/hoon/twig/buc-mold/col-bank.md+18−23 docs/hoon/twig/buc-mold/hep-lamb.md+16−25 docs/hoon/twig/buc-mold/ket-bush.md+20−26 docs/hoon/twig/buc-mold/pat-claw.md+21−25 docs/hoon/twig/buc-mold/tis-coat.md+14−23 docs/hoon/twig/buc-mold/wut-pick.md+20−26 docs/hoon/twig/cen-call.md+3−5 docs/hoon/twig/cen-call/cab-keep.md+26−35 docs/hoon/twig/cen-call/dot-lace.md+10−19 docs/hoon/twig/cen-call/hep-call.md+22−33 docs/hoon/twig/cen-call/ket-calq.md+11−19 docs/hoon/twig/cen-call/lus-calt.md+11−19 docs/hoon/twig/cen-call/sig-open.md+11−18 docs/hoon/twig/cen-call/tar-bake.md+20−27 docs/hoon/twig/cen-call/tis-make.md+22−26 docs/hoon/twig/col-cell.md+3−5 docs/hoon/twig/col-cell/cab-scon.md+7−15 docs/hoon/twig/col-cell/hep-cons.md+15−17 docs/hoon/twig/col-cell/ket-conq.md+18−26 docs/hoon/twig/col-cell/lus-cont.md+16−24 docs/hoon/twig/col-cell/sig-conl.md+35−45 docs/hoon/twig/col-cell/tar-conp.md+48−56 docs/hoon/twig/dot-nock.md+1−2 docs/hoon/twig/dot-nock/ket-wish.md+6−6 docs/hoon/twig/dot-nock/lus-bump.md+11−13 docs/hoon/twig/dot-nock/tar-nock.md+29−33 docs/hoon/twig/dot-nock/tis-same.md+15−19 docs/hoon/twig/dot-nock/wut-deep.md+11−15 docs/hoon/twig/ket-cast.md+5−6 docs/hoon/twig/ket-cast/bar-iron.md+14−20 docs/hoon/twig/ket-cast/hep-cast.md+31−40 docs/hoon/twig/ket-cast/lus-like.md+7−11 docs/hoon/twig/ket-cast/sig-burn.md+10−14 docs/hoon/twig/ket-cast/tis-name.md+15−17 docs/hoon/twig/ket-cast/wut-lead.md+13−20 docs/hoon/twig/limb.md+10−11 docs/hoon/twig/limb/limb.md+31−41 docs/hoon/twig/limb/wing.md+18−21 docs/hoon/twig/sem-make.md+1−2 docs/hoon/twig/sem-make/col-wad.md+26−36 docs/hoon/twig/sem-make/fas-nub.md+6−11 docs/hoon/twig/sem-make/sem-fry.md+23−41 docs/hoon/twig/sem-make/sig-dip.md+29−36 docs/hoon/twig/sig-hint.md+2−4 docs/hoon/twig/sig-hint/bar-show.md+8−12 docs/hoon/twig/sig-hint/buc-poll.md+5−9 docs/hoon/twig/sig-hint/cab-lurk.md+8−12 docs/hoon/twig/sig-hint/cen-fast.md+38−45 docs/hoon/twig/sig-hint/fas-funk.md+12−18 docs/hoon/twig/sig-hint/gal-thin.md+16−21 docs/hoon/twig/sig-hint/gar-hint.md+18−27 docs/hoon/twig/sig-hint/lus-memo.md+9−15 docs/hoon/twig/sig-hint/pam-dump.md+9−13 docs/hoon/twig/sig-hint/tis-ddup.md+10−13 docs/hoon/twig/sig-hint/wut-warn.md+13−17 docs/hoon/twig/sig-hint/zap-peep.md+13−17 docs/hoon/twig/tis-flow.md+15−17 docs/hoon/twig/tis-flow/bar-new.md+21−30 docs/hoon/twig/tis-flow/col-fix.md+17−25 docs/hoon/twig/tis-flow/dot-set.md+22−30 docs/hoon/twig/tis-flow/fas-var.md+35−52 docs/hoon/twig/tis-flow/gal-rap.md+9−15 docs/hoon/twig/tis-flow/gar-per.md+11−15 docs/hoon/twig/tis-flow/hep-nip.md+19−27 docs/hoon/twig/tis-flow/ket-sip.md+22−32 docs/hoon/twig/tis-flow/lus-pin.md+17−25 docs/hoon/twig/tis-flow/sem-rev.md+16−24 docs/hoon/twig/tis-flow/sig-tow.md+27−31 docs/hoon/twig/tis-flow/tar-aka.md+27−31 docs/hoon/twig/wut-test.md+13−15 docs/hoon/twig/wut-test/bar-or.md+20−30 docs/hoon/twig/wut-test/col-if.md+17−23 docs/hoon/twig/wut-test/dot-lest.md+29−37 docs/hoon/twig/wut-test/gal-deny.md+9−18 docs/hoon/twig/wut-test/gar-sure.md+9−17 docs/hoon/twig/wut-test/hep-case.md+50−63 docs/hoon/twig/wut-test/ket-ifcl.md+22−30 docs/hoon/twig/wut-test/lus-deft.md+43−53 docs/hoon/twig/wut-test/pam-and.md+19−29 docs/hoon/twig/wut-test/pat-ifat.md+22−30 docs/hoon/twig/wut-test/sig-ifno.md+17−26 docs/hoon/twig/wut-test/tis-fits.md+17−23 docs/hoon/twig/wut-test/zap-not.md+21−29 docs/hoon/twig/zap-wild.md+1−2 docs/hoon/twig/zap-wild/gar-wrap.md+7−11 docs/hoon/twig/zap-wild/tis-code.md+14−18 docs/hoon/twig/zap-wild/wut-need.md+16−20 docs/hoon/twig/zap-wild/zap-fail.md+6−10 docs/nock.md+3−2 docs/nock/definition.md+105−119 docs/nock/example.md+159−243 docs/nock/explanation.md+265−386 docs/nock/implementations.md+179−179 docs/nock/implementations/c.md+176−178 docs/nock/implementations/clojure.md+117−118 docs/nock/implementations/csharp.md+377−379 docs/nock/implementations/groovy.md+177−178 docs/nock/implementations/haskell.md+56−57 docs/nock/implementations/hoon.md+47−49 docs/nock/implementations/javascript.md+355−357 docs/nock/implementations/python.md+75−77 docs/nock/implementations/ruby.md+130−131 docs/nock/implementations/scala.md+68−69 docs/nock/implementations/scheme.md+112−113 docs/nock/implementations/swift.md+317−319 docs/using.md+3−2 docs/using/admin.md+49−21 docs/using/filesystem.md+70−86 docs/using/install.md+38−34 docs/using/layout.md+32−19 docs/using/messaging.md+61−72 docs/using/setup.md+31−37 docs/using/shell.md+38−48 docs/using/urb.md+255−282 docs/using/web.md+188−118 docs/using/web/blog.md+27−32 docs/using/web/comments.md+13−15 docs/using/web/static.md+23−26
docs.md+55−34
@@ -1,67 +1,88 @@
11---
22anchor: none
3−footer: true
4−title: Docs
3+footer: True
54sort: 4
5+title: Docs
66---
77
88<div class="lead">
99 <div class="logo inverse"></div>
1010 <h1 class="blue i-b">Urbit docs</h1>
11−</div>
1211
12+</div>
1313<div class="col-md-12 head">
14−
1514<div class="col-md-10">
15+**Urbit** is a secure peer-to-peer network of personal servers, built on a
16+clean-slate system software stack.
1617
17−**Urbit** is a secure peer-to-peer network of personal servers, built on a clean-slate system software stack.
18+Check out the [technical overview](about/overview) for a high-level architecture
19+description. To install and run Urbit, head to the Using section, starting with
20+the [installation guide](using/install) and continuing forward.
1821
19−Check out the [technical overview](about/overview) for a high-level
20−architecture description. To install and run Urbit, head to the Using section, starting with the [installation guide](using/install) and continuing forward.
22+To begin developing for Urbit, start by walking through
23+[Urbytes](https://urbit.org/docs/byte/0). After that, delve into Hoon
24+[syntax](hoon/syntax) directly, then walk through the [Arvo tutorials](arvo).
25+The examples and exercises in Arvo will teach you to build high-level programs
26+and interact with the network.
2127
22−To begin developing for Urbit, start by walking through [Urbytes](https://urbit.org/docs/byte/0). After that, delve into Hoon [syntax](hoon/syntax) directly, then walk through the [Arvo tutorials](arvo). The examples and exercises in Arvo will teach you to build high-level programs and interact with the network.
28+Dig into the mechanics of Urbit with [Core Hoon](hoon). Refer back there for
29+pure-code exercises and functions in the [standard library](hoon/library).
2330
24−Dig into the mechanics of Urbit with [Core Hoon](hoon). Refer back
25−there for pure-code exercises and functions in the [standard library](hoon/library).
26−
27−Anyone obsessed with math, theory, fundamentals of computation,
28−etc, should start with the [Nock definition](nock/definition) and work upward from there.
31+Anyone obsessed with math, theory, fundamentals of computation, etc, should
32+start with the [Nock definition](nock/definition) and work upward from there.
2933
3034</div>
31−
3235</div>
33−
3436<div class="col-md-12 head">
35−
3637<div class="col-md-4">
37−
3838<b>Community & contact</b>
3939<ul>
40−<li>Chat with us on <a href="https://urbit.org/stream"><code>:talk</code></a></li>
41−<li>Our discussion forum <a href="http://urbit.org/fora"><code>fora</code></a></li>
42−<li>On Twitter <a href="https://twitter.com/urbit">@urbit</a></li>
43−<li>Or email us at <a href="mailto:urbit@urbit.org">urbit@urbit.org</a></li>
40+<li>
41+Chat with us on <a href="https://urbit.org/stream"><code>:talk</code></a>
42+</li>
43+<li>
44+Our discussion forum <a href="http://urbit.org/fora"><code>fora</code></a>
45+</li>
46+<li>
47+On Twitter <a href="https://twitter.com/urbit">@urbit</a>
48+</li>
49+<li>
50+Or email us at <a href="mailto:urbit@urbit.org">urbit@urbit.org</a>
51+</li>
4452</ul>
45−
4653</div>
47−
4854<div class="col-md-4">
49−
5055<b>Source code on <a href="https://github.com/urbit">GitHub</a></b>
5156<ul>
52−<li><a href="https://github.com/urbit/urbit"><code>vere</code></a> - Urbit's VM</li>
53−<li><a href="https://github.com/urbit/arvo"><code>arvo</code></a> - Urbit's OS</li>
54−<li><a href="https://github.com/urbit/tree"><code>tree</code></a> - Urbit's web publishing UI</li>
55−<li><a href="https://github.com/urbit/talk"><code>talk</code></a> - Urbit's web chat</li>
56−<li><a href="https://github.com/urbit/sole"><code>sole</code></a> - Urbit's web console</li>
57−<li><a href="https://github.com/urbit/examples"><code>examples</code></a> - Hoon, Arvo and Tree</li>
58−<li><a href="https://github.com/urbit/docs"><code>docs</code></a> - The repo for these docs</li>
57+<li>
58+<a href="https://github.com/urbit/urbit"><code>vere</code></a> - Urbit's VM
59+</li>
60+<li>
61+<a href="https://github.com/urbit/arvo"><code>arvo</code></a> - Urbit's OS
62+</li>
63+<li>
64+<a href="https://github.com/urbit/tree"><code>tree</code></a> - Urbit's web
65+publishing UI
66+</li>
67+<li>
68+<a href="https://github.com/urbit/talk"><code>talk</code></a> - Urbit's web chat
69+</li>
70+<li>
71+<a href="https://github.com/urbit/sole"><code>sole</code></a> - Urbit's web
72+console
73+</li>
74+<li>
75+<a href="https://github.com/urbit/examples"><code>examples</code></a> - Hoon,
76+Arvo and Tree
77+</li>
78+<li>
79+<a href="https://github.com/urbit/docs"><code>docs</code></a> - The repo for
80+these docs
81+</li>
5982</ul>
60−
6183</div>
62−
6384</div>
64−
6585<div class="sections">
6686 <kids grid="true"></kids>
87+
6788</div>
docs/about.md+1−1
@@ -1,5 +1,5 @@
11---
2−navhome: /docs/
2+navhome: '/docs/'
33sort: 3
44---
55
docs/about/contributing.md+15−14
@@ -7,24 +7,25 @@ title: Contributing to Urbit
77
88# Contributing to Urbit
99
10−It's always a good day for pull requests! We gladly accept submissions
11−for improving our [code](https://github.com/urbit/urbit/) and
10+It's always a good day for pull requests! We gladly accept submissions for
11+improving our [code](https://github.com/urbit/urbit/) and
1212[documentation](https://github.com/urbit/docs/) alike.
1313
1414## Code guidelines
1515
1616Our official guide to contributing can be found
17−[here](https://github.com/urbit/urbit/blob/master/CONTRIBUTING.md),
18−which is most useful for large and low-level changes. For simpler
19−revisions, refer to [Hoon Syntax](../../hoon/syntax) for an in-depth guide to
20−good Hoon. Alternatively, [browse the
17+[here](https://github.com/urbit/urbit/blob/master/CONTRIBUTING.md), which is
18+most useful for large and low-level changes. For simpler revisions, refer to
19+[Hoon Syntax](../../hoon/syntax) for an in-depth guide to good Hoon.
20+Alternatively, [browse the
2121source](https://github.com/urbit/arvo/blob/master/arvo/hoon.hoon).
2222
2323## Docs guidelines
2424
2525For documentation pull requests, if you are making a brand new page, you'll want
26−it to conform to our general documentation standards. Acquire [pandoc](http://pandoc.org)
27−and make sure to format your edited files with the following flags:
26+it to conform to our general documentation standards. Acquire
27+[pandoc](http://pandoc.org) and make sure to format your edited files with the
28+following flags:
2829
2930 $ pandoc --standalone \
3031 --from=markdown+yaml_metadata_block \
@@ -33,13 +34,13 @@ and make sure to format your edited files with the following flags:
3334 input.md
3435
3536If you are editing an existing page, reformatting the entire page with pandoc
36−will make the diff hard to read. Instead, just make sure that your edits generally
37−conform to the style of the existing docs around it. For example, you'll notice
38−that the paragraphs mostly wrap at column 80.
37+will make the diff hard to read. Instead, just make sure that your edits
38+generally conform to the style of the existing docs around it. For example,
39+you'll notice that the paragraphs mostly wrap at column 80.
3940
40−**Note:** If you have an old version of Pandoc, it may convert the
41−terminating `---` in YAML metadata to `...`, which is grounds for termination.
42−Run the following one-liner to atone.
41+**Note:** If you have an old version of Pandoc, it may convert the terminating
42+`---` in YAML metadata to `...`, which is grounds for termination. Run the
43+following one-liner to atone.
4344
4445 $ sed '1,/^$/ s/^\.\.\./---/g' input.md > output.md
4546
docs/about/glossary.md+93−109
@@ -7,17 +7,17 @@ title: Urbit glossary
77
88# Urbit Glossary
99
10−Urbit is renowned for its exotic terminology. Here's a simple overview
11−from the strange words in.
10+Urbit is renowned for its exotic terminology. Here's a simple overview from the
11+strange words in.
1212
13−As Dijkstra put it: "The purpose of abstraction is not to be vague, but
14−to create a new semantic level in which one can be absolutely precise."
13+As Dijkstra put it: "The purpose of abstraction is not to be vague, but to
14+create a new semantic level in which one can be absolutely precise."
1515
1616## Ships
1717
18−An Urbit *ship* is a cryptographic title on a *will* signed by private
19−key, a human-memorable name, and a packet routing address. Ships are
20−classed by the number of bits in their address:
18+An Urbit *ship* is a cryptographic title on a *will* signed by private key, a
19+human-memorable name, and a packet routing address. Ships are classed by the
20+number of bits in their address:
2121
2222 Size Name Parent Object Example
2323 ----- ------ ------ ------ -------
@@ -31,31 +31,29 @@ Any ship can be called an "urbit."
3131
3232> A summary [here](http://urbit.org/posts/address-space/).
3333
34−An Urbit identity is a string like `~firbyr-napbes`. It means nothing,
35−but it's easy to remember and say out loud. `~firbyr-napbes` is actually
36−just a 32-bit number, like an IP address, that we turn into a
37−human-memorable string.
34+An Urbit identity is a string like `~firbyr-napbes`. It means nothing, but it's
35+easy to remember and say out loud. `~firbyr-napbes` is actually just a 32-bit
36+number, like an IP address, that we turn into a human-memorable string.
3837
39−Technically, an urbit is a secure digital identity that you own and
40−control with a cryptographic key, like a Bitcoin wallet. As in Bitcoin,
41−the supply of urbits is mathematically limited. This keeps the network
42−friendly, by making spam and abuse expensive.
38+Technically, an urbit is a secure digital identity that you own and control with
39+a cryptographic key, like a Bitcoin wallet. As in Bitcoin, the supply of urbits
40+is mathematically limited. This keeps the network friendly, by making spam and
41+abuse expensive.
4342
44−An urbit name is just a number; smaller numbers make shorter names.
45−Shorter names are easier to remember, so they're more valuable. So
46−urbits are classified by the number of bits in their name. (A ship name
47−is just a scrambled base-256 representation of the number.)
43+An urbit name is just a number; smaller numbers make shorter names. Shorter
44+names are easier to remember, so they're more valuable. So urbits are classified
45+by the number of bits in their name. (A ship name is just a scrambled base-256
46+representation of the number.)
4847
49−A 32-bit urbit (like `~firbyr-napbes`) is called a *planet.* A 16-bit
50−urbit (like `~pollev)` is a *star.* An 8-bit ship (like `~mun`) is a
51−*galaxy.* A planet is an identity for an independent, adult human. Stars
52−and galaxies are network infrastructure.
48+A 32-bit urbit (like `~firbyr-napbes`) is called a *planet.* A 16-bit urbit
49+(like `~pollev)` is a *star.* An 8-bit ship (like `~mun`) is a *galaxy.* A
50+planet is an identity for an independent, adult human. Stars and galaxies are
51+network infrastructure.
5352
54−Each planet or star is launched by its *parent,* the star or galaxy
55−whose number is its bottom half. So the planet `~firbyr-napbes`,
56−`0xdead.beef` or `3.735.928.559`, is the child of `~pollev`, `0xbeef` or
57−`48.879`, whose parent is `~mun`, `0xef`, `239`. The parent of `~mun`
58−and all galaxies is `~zod`, `0`.
53+Each planet or star is launched by its *parent,* the star or galaxy whose number
54+is its bottom half. So the planet `~firbyr-napbes`, `0xdead.beef` or
55+`3.735.928.559`, is the child of `~pollev`, `0xbeef` or `48.879`, whose parent
56+is `~mun`, `0xef`, `239`. The parent of `~mun` and all galaxies is `~zod`, `0`.
5957
6058### Nock
6159
@@ -64,32 +62,30 @@ and all galaxies is `~zod`, `0`.
6462- *noun*: an *atom* or a *cell*
6563- *atom*: any natural number
6664- *cell*: any ordered pair of nouns
67−- *subject*: a noun - the data against which a `formula` is
68− evaluated
65+- *subject*: a noun - the data against which a `formula` is evaluated
6966- *formula*: a noun - a function at the Nock level
70−- *product*: a noun - the result of evaluating a formula against a
71− subject
67+- *product*: a noun - the result of evaluating a formula against a subject
7268
7369*See [Nock definition](../../nock/definition/).*
7470
7571### Hoon
7672
77−> Hoon is a strict, higher-order typed functional language that compiles
78−> itself to Nock.
73+> Hoon is a strict, higher-order typed functional language that compiles itself
74+> to Nock.
7975
8076###### span: an inferred type
8177
82−A *span* defines a set (finite or infinite) of nouns and ascribes some
83−semantics to it. There is no Hoon syntax for a span; it is always
84−produced as the inferred range of an expression (*twig*).
78+A *span* defines a set (finite or infinite) of nouns and ascribes some semantics
79+to it. There is no Hoon syntax for a span; it is always produced as the inferred
80+range of an expression (*twig*).
8581
8682*See [basic types](../../hoon/basic/#-type-span-and-mold).*
8783
8884###### core: a code-data cell
8985
9086The code (*battery*) is the head, the data (*payload*) is the tail. All
91−code-data structures in normal languages (functions, objects, modules,
92−etc) become *core*s in Hoon.
87+code-data structures in normal languages (functions, objects, modules, etc)
88+become *core*s in Hoon.
9389
9490- *battery*: the code of a core, a tree of *arms*
9591- *payload*: the data in a core
@@ -98,29 +94,27 @@ etc) become *core*s in Hoon.
9894
9995###### arm: a named, functionally-computed attribute of a core
10096
101−The *twig* of each arm is compiled to a Nock formula, with the
102−enclosing `core` itself as the subject.
97+The *twig* of each arm is compiled to a Nock formula, with the enclosing `core`
98+itself as the subject.
10399
104100There are two kinds of arms: *dry* and *wet*. Most arms are dry.
105101
106102- *dry*: normal, `++`, polymorphic by means of *variance*
107103
108−For a dry arm, we ask, is the new payload compatible with the old
109−payload (against which the core was compiled)?
104+For a dry arm, we ask, is the new payload compatible with the old payload
105+(against which the core was compiled)?
110106
111107- *wet*: unusual, `+-`, polymorphic by means of *genericity*
112108
113−A wet arm uses the twig as a macro. We create a new type analysis
114−path, which works as if we expanded the callee with the caller's
115−context.
109+A wet arm uses the twig as a macro. We create a new type analysis path, which
110+works as if we expanded the callee with the caller's context.
116111
117112*See [advanced types](/hoon/advanced)*.
118113
119114###### metal: a variance model
120115
121−Every core has a *metal* which defines its variance model (ie, the
122−properties of the span of a compatible core). The default is `gold`
123−(invariant).
116+Every core has a *metal* which defines its variance model (ie, the properties of
117+the span of a compatible core). The default is `gold` (invariant).
124118
125119- `gold`: *invariant*
126120- `lead`: *bivariant*
@@ -131,9 +125,8 @@ properties of the span of a compatible core). The default is `gold`
131125
132126###### gate: a function/lambda/closure
133127
134−A *gate* is a core with one arm. To call a gate on an argument,
135−replace the sample (at [tree
136−address](../../hoon/twig/limb/limb/) `+6` in the core) with the
128+A *gate* is a core with one arm. To call a gate on an argument, replace the
129+sample (at [tree address](../../hoon/twig/limb/limb/) `+6` in the core) with the
137130argument, and then compute the arm.
138131
139132The payload of a gate has a shape of `{sample context}`.
@@ -141,51 +134,46 @@ The payload of a gate has a shape of `{sample context}`.
141134- *sample*: the argument tuple
142135- *context*: the subject in which the gate was defined
143136
144−*See [basic types](../../hoon/basic/#-core-p-span-q-map-term-span),
145−[`%-` or `:call`](../../hoon/twig/cen-call/hep-call/) (the `twig` for
146−calling a `gate`).*
137+*See [basic types](../../hoon/basic/#-core-p-span-q-map-term-span), [`%-` or
138+`:call`](../../hoon/twig/cen-call/hep-call/) (the `twig` for calling a `gate`).*
147139
148140###### mold: a type constructor / validator
149141
150−A *mold* is an idempotent gate (function), accepting any noun, and
151−producing a range with a useful span.
142+A *mold* is an idempotent gate (function), accepting any noun, and producing a
143+range with a useful span.
152144
153−- *bunt*: the value a mold produces when normalizing its default
154− sample
145+- *bunt*: the value a mold produces when normalizing its default sample
155146- *icon*: the span of the mold's range
156147
157148*See [mold twigs](/hoon/twig/buc-mold/).*
158149
159150###### atom
160151
161−A Hoon *atom* span describes a Nock atom, with two additional pieces
162−of metadata: an *aura*, and an optional constant.
152+A Hoon *atom* span describes a Nock atom, with two additional pieces of
153+metadata: an *aura*, and an optional constant.
163154
164155An atom span is *warm* or *cold* based on whether the constant exists.
165156
166157- *warm*: if the constant is `~` (null), any atom is in the span
167−- *cold*: if the constant is `[~ atom]`, its only legal value is
168− `atom`.
158+- *cold*: if the constant is `[~ atom]`, its only legal value is `atom`.
169159
170160*See [basic types](../../hoon/basic/#-atom-p-term-q-unit-atom)*
171161
172162###### aura: a soft atom type
173163
174−*aura* is a name for an atom type. It represents the structure of an
175−atom in a string beginning with `@`. An aura may represent units,
176−print format, or other semantics. Its constraints on the value of an
177−atom aren't enforced in any way.
164+*aura* is a name for an atom type. It represents the structure of an atom in a
165+string beginning with `@`. An aura may represent units, print format, or other
166+semantics. Its constraints on the value of an atom aren't enforced in any way.
178167
179−Two auras are compatible if one is a prefix of the other. You can
180−change any aura into any other aura by casting through the empty
181−aura, `@`. The standard library has molds which alias many common
182−auras.
168+Two auras are compatible if one is a prefix of the other. You can change any
169+aura into any other aura by casting through the empty aura, `@`. The standard
170+library has molds which alias many common auras.
183171
184172Some common auras and their aliases:
185173
186−- *term* (`@tas`): a symbol - an atomic ASCII string which obeys
187− symbol rules: lowercase and digit only, infix hyphen ("kebab-case"),
188− first character must be lowercase alphabetic.
174+- *term* (`@tas`): a symbol - an atomic ASCII string which obeys symbol rules:
175+ lowercase and digit only, infix hyphen ("kebab-case"), first character must
176+ be lowercase alphabetic.
189177- *cord* (`@t`): UTF-8 text, least-significant-byte first
190178- *char* (`@tD`): a character, a single unicode byte (for multi-byte
191179 characters and codepoints, see `@c`)
@@ -194,70 +182,66 @@ Some common auras and their aliases:
194182
195183###### twig: a Hoon expression
196184
197−A *twig* is a Hoon expression. Specifically, twig is the mold for the
198−noun that a Hoon source expression compiles to. A twig is always a cell.
185+A *twig* is a Hoon expression. Specifically, twig is the mold for the noun that
186+a Hoon source expression compiles to. A twig is always a cell.
199187
200−A twig has one of two forms: `{twig twig}`, which produces the ordered
201−pair of the two twigs, or a cell `{stem bulb}`, where `stem` is an
202−atomic symbol.
188+A twig has one of two forms: `{twig twig}`, which produces the ordered pair of
189+the two twigs, or a cell `{stem bulb}`, where `stem` is an atomic symbol.
203190
204191- *stem*: an atomic symbol (`@tas`) - the name of a twig.
205192- *bulb*: The mold of the twig's contents.
206193
207−Most twigs have a *regular form*, beginning with a *sigil* which is
208−either a *keyword* or a *rune*. Some twigs also have a syntactic
209−*irregular form*; a few have *only* an *irregular form*.
194+Most twigs have a *regular form*, beginning with a *sigil* which is either a
195+*keyword* or a *rune*. Some twigs also have a syntactic *irregular form*; a few
196+have *only* an *irregular form*.
210197
211198- *sigil*: a *keyword* or *rune* used to begin a twig
212199- *keyword*: the value of a stem, prefixed with `:`.
213200- *rune*: a pair of ASCII symbols used to begin a twig.
214201
215202For example, the stem `%if` becomes the keyword
216−[`:if`](../../hoon/twig/wut-test/col-if/), with the rune `?:`. The first
217−symbol in a rune represents a family of related `twig`s. For example,
218−the [`?` family](../../hoon/twig/wut-test/) are all conditionals.
203+[`:if`](../../hoon/twig/wut-test/col-if/), with the rune `?:`. The first symbol
204+in a rune represents a family of related `twig`s. For example, the [`?`
205+family](../../hoon/twig/wut-test/) are all conditionals.
219206
220−The keyword or rune forms are up to the programmer's choice. Most
221−existing code uses runes, but the keyword form makes the learning path
222−easier.
207+The keyword or rune forms are up to the programmer's choice. Most existing code
208+uses runes, but the keyword form makes the learning path easier.
223209
224210A regular twig has two syntactic forms, *tall* and *flat*:
225211
226−- *tall*: multiple lines, no parentheses, two or more spaces between
227− tokens
212+- *tall*: multiple lines, no parentheses, two or more spaces between tokens
228213- *flat*: one line, parentheses, one space between tokens
229214
230−Tall twigs can contain flat ones, but not vice versa. All irregular
231−forms are flat.
215+Tall twigs can contain flat ones, but not vice versa. All irregular forms are
216+flat.
232217
233218*See [twig concept](../../hoon/concepts/#-twig-expression),
234219[expressions](../../hoon/twig/), and [syntax](../../hoon/syntax/)*.
235220
236221###### limb: attribute or variable reference
237222
238−To resolve a *limb* named "foo", the subject is searched depth-first,
239−head-first for either a face named "foo" or a core with an arm of
240−"foo". If a face is found, the result is a leg, if a core is
241−found, the result is the product of the arm.
223+To resolve a *limb* named "foo", the subject is searched depth-first, head-first
224+for either a face named "foo" or a core with an arm of "foo". If a face is
225+found, the result is a leg, if a core is found, the result is the product of the
226+arm.
242227
243228- *leg*: a subexpression, or subtree of the subject.
244−- *wing*: a list of limbs, searched from right to left (`a.b` means
245− `b` within `a`).
229+- *wing*: a list of limbs, searched from right to left (`a.b` means `b` within
230+ `a`).
246231
247232*See [Limbs and wings](../../hoon/twig/limb)*
248233
249234###### slot: a tree addressing scheme
250235
251−Every cell has a head and a tail, each of which may be either an atom or
252−a cell. Therefore every noun is a binary tree. `+1` or `.` resolves to
253−the whole cell (technically this would work against an atom as well).
254−The head of `+n` is `+2n`, the tail is `+(2n+1)`.
236+Every cell has a head and a tail, each of which may be either an atom or a cell.
237+Therefore every noun is a binary tree. `+1` or `.` resolves to the whole cell
238+(technically this would work against an atom as well). The head of `+n` is
239+`+2n`, the tail is `+(2n+1)`.
255240
256241###### face: a labeled subtree
257242
258−Hoon has no scope or symbol-table; there is only the subject. To
259−"declare" a "variable" is to construct a new subject:
260−`[name=value old-subject]`.
243+Hoon has no scope or symbol-table; there is only the subject. To "declare" a
244+"variable" is to construct a new subject: `[name=value old-subject]`.
261245
262246A *face* is a span that wraps a name (`@tas`) around another span.
263247
@@ -265,8 +249,8 @@ A *face* is a span that wraps a name (`@tas`) around another span.
265249
266250###### nest: type compatibility test
267251
268−*nest* is an internal function on two spans, which produces yes if the
269−set of nouns in the second span is provably a subset of the first.
252+*nest* is an internal function on two spans, which produces yes if the set of
253+nouns in the second span is provably a subset of the first.
270254
271255*See [advanced types](../../hoon/advanced/)*.
272256
@@ -274,5 +258,5 @@ set of nouns in the second span is provably a subset of the first.
274258
275259`0` (`%.y`) is *yes*, `1` (`%.n`) is *no*.
276260
277−> Why? It's fresh, it's different, it's new. And it's annoying. And it
278−> keeps you on your toes. And it's also just intuitively right.
261+> Why? It's fresh, it's different, it's new. And it's annoying. And it keeps you
262+> on your toes. And it's also just intuitively right.
docs/about/objections.md+453−170
@@ -7,262 +7,545 @@ title: Common objections to Urbit
77
88# Common objections to Urbit
99
10−"We choose to go to the moon, not because it is easy, but because it is hard." -- John F. Kennedy
11−
12−We're strong believers in crowdsourced criticism. We've heard a lot of great objections from all kinds of directions. Surely there's more out there -- if you think of a reason Urbit can't work, and it's not listed here, please add it in a comment at the bottom, post it somewhere and send us a link, etc, etc.
13−
14−## Urbit is a total scamcoin. It's 100% premined.
15−
16−Like a cryptocurrency, Urbit is a digital title. But Urbit is digital land, not digital money. If you assess it as a currency, it's a lousy currency. If you assess a cat as a dog, it's a lousy dog.
17−
18−In real-world economics, the crucial distinction between land and money is that land (a) has intrinsic utility and (b) is non-fungible.
19−
20−Because of (b) alone, frictionless transactions in land are impossible. A blockchain is only needed to ensure zero-cost high-frequency transactions. So digital land doesn't need a blockchain. Which means it doesn't need mining.
21−
22−Of course, just because a digital title system doesn't need mining, doesn't mean it can't distribute an initial allocation by proof-of-work -- or by any other arbitrary method which is careful not to benefit the system's own developers. Could we give away the Urbit address space randomly? Sure. But why?
23−
24−Probably the purest design is the "proof-of-burn" initial allocation used by some coins. By any standard, proof-of-burn is technically beautiful and results in an extraordinary level of ethical independence. We can't help but admire it.
25−
26−But any altcoin or metacoin is just way less work than Urbit. An altcoin can afford to burn even its creation energy, capturing no value at all from its seigniorage. Your altcoin doesn't have a clean-slate OS to fund, and no one started building it in 2002.
27−
28−Ethically, what makes "premining" feel wrong is that the creators of the currency are rewarded disproportionately for their effort. The scamcoin is a get-rich-quick scheme, vaguely pyramid-shaped. Nothing about Urbit matches this pattern at all.
29−
30−To put it bluntly, Galen drives a 2004 Saab and Curtis drives a moldy '99 Cougar covered with raven shit. And we both love cars. We also have kids. And our spouses are more skeptical of Urbit than anyone else could ever be. (Our next startup definitely *will* be a get-rich-quick scheme, though.)
31−
32−Curtis created Urbit. So by the [homesteading principle](https://en.wikipedia.org/wiki/Homestead_principle), he started out owning all of it. But by now, Urbit's 8-bit galaxies have already been distributed among [57 separate individuals](). Curtis owns 4 -- or 24, counting his whole family. (Some of whom he still owes money.)
33−
34−Tlon, the corporation which still runs Urbit development, has 95. (Without Tlon, there is basically no Arvo.) 50 are reserved for a hypothetical Urbit Foundation. Tlon employees have another 16.
35−
36−The rest of the galaxies belong to donors, investors, contributors, contest winners, and just random people who were in the right place at the right time. One is a Silicon Valley tycoon. Another is an Orthodox nun in a monastery in Greece. A couple are ex-Tlon employees who might totally hate us. There is nothing they all have in common, which is sort of the point.
37−
38−This property distribution looks a lot like land ownership in the real world -- complex and asymmetrical. That's no accident. If you have a problem living in New York because New York's real estate is not distributed equally among its residents, you may have a similar problem with Urbit. The reality is that Urbit, like New York, wasn't born yesterday and comes with a complex ownership history which we couldn't possibly change, even if we wanted to.
39−
40−Also, even in Manhattan you can just sleep in your van, and in Urbit you can always make your own comet. But people can't be prevented from thinking this means you're a weirdo.
41−
42−## Urbit isn't even really decentralized! It has a government!
43−
44−TLDR: yeah. But at least it's not the DAO.
45−
46−Real TLDR: it's technically impossible for Urbit to be decentralized at this stage of its life. Urbit is designed to achieve decentralization, not be born with it.
47−
48−A young network can't afford to be decentralized. It has to act as a unit. Because it has no network effect, it needs every scrap of efficiency it can get. Right now, Urbit needs a central government about ten times over.
49−
50−As we found out with the DAO, if a network isn't ready to be decentralized, its developers shouldn't even try. If Ethereum is hard-forked to roll back the DAO (which looks like the most probable result), it acknowledges that it both has a central government, and needs a central government. Decentralization is good. Pretend decentralization -- "decentralization theater" -- is harmful, and not a effective path to actual decentralization.
51−
52−Urbit did not have to get hacked to realize that a decentralized network can only be bootstrapped by a central government. It's part of Urbit's basic design. For example, by default your urbit upgrades its OS automatically (like an "evergreen" browser) with signed network updates. Whoever signs these updates is a central government by definition.
53−
54−But the test of a free software project is whether it can fork. So long as the unity of the PKI and the protocol is maintained, Urbit development can fork easily without disrupting the network. Any stress will fragment this central government, and as it fragments it grows more limited and stable.
55−
56−Urbit is designed to govern itself collectively by address space ownership -- effectively, "proof of stake." Any arbitrary power, will tend to fracture along these property lines. For instance, our hot updates are sent through the galaxy hierarchy; in a development fork, active galaxies would pick sides. This would actually be awesome for Urbit.
57−
58−By fragmenting the galaxy space into 57 separate partitions, we've created a global property map which is much more likely to splinter further, than reunite.
59−
60−In the long run, every galaxy should have a separate owner, who is a human being rather than a corporation. Combining galaxy holdings is regarded as creepy, and damages the value of both galaxies. Splitting up any remaining clumps is meritorious.
61−
62−The technical goal of Urbit is to create a network which, *if it actually takes over the world*, inevitably becomes decentralized. Even if Urbit takes over the world, nobody takes over the world. World domination must be technically implausible.
63−
64−This is the goal of all the new "web3" decentralized systems. If IPFS, Sandstorm or Ethereum takes over the world, nobody takes over the world. (The same is almost true of the Internet -- though it wouldn't be that surprising if a time traveler from 2116 revealed that ICANN had become a planetary government.)
65−
66−Urbit, by starting out as a centralized network, just reduces the technical problem to match the actual goal. Only long-term decentralization matters.
67−
68−It's very important that Urbit in 2116 be fully decentralized. For Urbit in 2016, pretending to be decentralized would be a joke at best, and a hoax at worst. And of course, no one can DAO us -- since the property system is still just a central registry.
10+"We choose to go to the moon, not because it is easy, but because it is hard."
11+-- John F. Kennedy
12+
13+We're strong believers in crowdsourced criticism. We've heard a lot of great
14+objections from all kinds of directions. Surely there's more out there -- if you
15+think of a reason Urbit can't work, and it's not listed here, please add it in a
16+comment at the bottom, post it somewhere and send us a link, etc, etc.
17+
18+## Urbit is a total scamcoin. It's 100% premined.
19+
20+Like a cryptocurrency, Urbit is a digital title. But Urbit is digital land, not
21+digital money. If you assess it as a currency, it's a lousy currency. If you
22+assess a cat as a dog, it's a lousy dog.
23+
24+In real-world economics, the crucial distinction between land and money is that
25+land (a) has intrinsic utility and (b) is non-fungible.
26+
27+Because of (b) alone, frictionless transactions in land are impossible. A
28+blockchain is only needed to ensure zero-cost high-frequency transactions. So
29+digital land doesn't need a blockchain. Which means it doesn't need mining.
30+
31+Of course, just because a digital title system doesn't need mining, doesn't mean
32+it can't distribute an initial allocation by proof-of-work -- or by any other
33+arbitrary method which is careful not to benefit the system's own developers.
34+Could we give away the Urbit address space randomly? Sure. But why?
35+
36+Probably the purest design is the "proof-of-burn" initial allocation used by
37+some coins. By any standard, proof-of-burn is technically beautiful and results
38+in an extraordinary level of ethical independence. We can't help but admire it.
39+
40+But any altcoin or metacoin is just way less work than Urbit. An altcoin can
41+afford to burn even its creation energy, capturing no value at all from its
42+seigniorage. Your altcoin doesn't have a clean-slate OS to fund, and no one
43+started building it in 2002.
44+
45+Ethically, what makes "premining" feel wrong is that the creators of the
46+currency are rewarded disproportionately for their effort. The scamcoin is a
47+get-rich-quick scheme, vaguely pyramid-shaped. Nothing about Urbit matches this
48+pattern at all.
49+
50+To put it bluntly, Galen drives a 2004 Saab and Curtis drives a moldy '99 Cougar
51+covered with raven shit. And we both love cars. We also have kids. And our
52+spouses are more skeptical of Urbit than anyone else could ever be. (Our next
53+startup definitely *will* be a get-rich-quick scheme, though.)
54+
55+Curtis created Urbit. So by the [homesteading
56+principle](https://en.wikipedia.org/wiki/Homestead_principle), he started out
57+owning all of it. But by now, Urbit's 8-bit galaxies have already been
58+distributed among [57 separate individuals](). Curtis owns 4 -- or 24, counting
59+his whole family. (Some of whom he still owes money.)
60+
61+Tlon, the corporation which still runs Urbit development, has 95. (Without Tlon,
62+there is basically no Arvo.) 50 are reserved for a hypothetical Urbit
63+Foundation. Tlon employees have another 16.
64+
65+The rest of the galaxies belong to donors, investors, contributors, contest
66+winners, and just random people who were in the right place at the right time.
67+One is a Silicon Valley tycoon. Another is an Orthodox nun in a monastery in
68+Greece. A couple are ex-Tlon employees who might totally hate us. There is
69+nothing they all have in common, which is sort of the point.
70+
71+This property distribution looks a lot like land ownership in the real world --
72+complex and asymmetrical. That's no accident. If you have a problem living in
73+New York because New York's real estate is not distributed equally among its
74+residents, you may have a similar problem with Urbit. The reality is that Urbit,
75+like New York, wasn't born yesterday and comes with a complex ownership history
76+which we couldn't possibly change, even if we wanted to.
77+
78+Also, even in Manhattan you can just sleep in your van, and in Urbit you can
79+always make your own comet. But people can't be prevented from thinking this
80+means you're a weirdo.
81+
82+## Urbit isn't even really decentralized! It has a government!
83+
84+TLDR: yeah. But at least it's not the DAO.
85+
86+Real TLDR: it's technically impossible for Urbit to be decentralized at this
87+stage of its life. Urbit is designed to achieve decentralization, not be born
88+with it.
89+
90+A young network can't afford to be decentralized. It has to act as a unit.
91+Because it has no network effect, it needs every scrap of efficiency it can get.
92+Right now, Urbit needs a central government about ten times over.
93+
94+As we found out with the DAO, if a network isn't ready to be decentralized, its
95+developers shouldn't even try. If Ethereum is hard-forked to roll back the DAO
96+(which looks like the most probable result), it acknowledges that it both has a
97+central government, and needs a central government. Decentralization is good.
98+Pretend decentralization -- "decentralization theater" -- is harmful, and not a
99+effective path to actual decentralization.
100+
101+Urbit did not have to get hacked to realize that a decentralized network can
102+only be bootstrapped by a central government. It's part of Urbit's basic design.
103+For example, by default your urbit upgrades its OS automatically (like an
104+"evergreen" browser) with signed network updates. Whoever signs these updates is
105+a central government by definition.
106+
107+But the test of a free software project is whether it can fork. So long as the
108+unity of the PKI and the protocol is maintained, Urbit development can fork
109+easily without disrupting the network. Any stress will fragment this central
110+government, and as it fragments it grows more limited and stable.
111+
112+Urbit is designed to govern itself collectively by address space ownership --
113+effectively, "proof of stake." Any arbitrary power, will tend to fracture along
114+these property lines. For instance, our hot updates are sent through the galaxy
115+hierarchy; in a development fork, active galaxies would pick sides. This would
116+actually be awesome for Urbit.
117+
118+By fragmenting the galaxy space into 57 separate partitions, we've created a
119+global property map which is much more likely to splinter further, than reunite.
120+
121+In the long run, every galaxy should have a separate owner, who is a human being
122+rather than a corporation. Combining galaxy holdings is regarded as creepy, and
123+damages the value of both galaxies. Splitting up any remaining clumps is
124+meritorious.
125+
126+The technical goal of Urbit is to create a network which, *if it actually takes
127+over the world*, inevitably becomes decentralized. Even if Urbit takes over the
128+world, nobody takes over the world. World domination must be technically
129+implausible.
130+
131+This is the goal of all the new "web3" decentralized systems. If IPFS, Sandstorm
132+or Ethereum takes over the world, nobody takes over the world. (The same is
133+almost true of the Internet -- though it wouldn't be that surprising if a time
134+traveler from 2116 revealed that ICANN had become a planetary government.)
135+
136+Urbit, by starting out as a centralized network, just reduces the technical
137+problem to match the actual goal. Only long-term decentralization matters.
138+
139+It's very important that Urbit in 2116 be fully decentralized. For Urbit in
140+2016, pretending to be decentralized would be a joke at best, and a hoax at
141+worst. And of course, no one can DAO us -- since the property system is still
142+just a central registry.
69143
70144## {Sandstorm, IPFS, Ethereum, ...} is way ahead of Urbit.
71145
72−In general, web3 (next distributed web) solutions don't compete with each other. They support each other. Concretely, they are all part of each others' network effect.
146+In general, web3 (next distributed web) solutions don't compete with each other.
147+They support each other. Concretely, they are all part of each others' network
148+effect.
73149
74−IPFS, Sandstorm, Ethereum, ZeroTier, and Urbit can all take over the world at the same time. None of them competes with the others. They enable each other. For instance, IPFS is not a computer; Urbit will be a great computer to use IPFS from; IPFS is a great CDN for Urbit. Moar IPFS now!
150+IPFS, Sandstorm, Ethereum, ZeroTier, and Urbit can all take over the world at
151+the same time. None of them competes with the others. They enable each other.
152+For instance, IPFS is not a computer; Urbit will be a great computer to use IPFS
153+from; IPFS is a great CDN for Urbit. Moar IPFS now!
75154
76−The closest thing to a competitor that Urbit has is Sandstorm. Sandstorm, which by the way rocks, is also a personal server.
155+The closest thing to a competitor that Urbit has is Sandstorm. Sandstorm, which
156+by the way rocks, is also a personal server.
77157
78−But Sandstorm and Urbit compete in the way that, on the PC, the OS and the browser compete. In theory, the OS could solve the problems that the browser solves; or the browser could be the OS. In practice, Windows is a great OS to run a browser on.
158+But Sandstorm and Urbit compete in the way that, on the PC, the OS and the
159+browser compete. In theory, the OS could solve the problems that the browser
160+solves; or the browser could be the OS. In practice, Windows is a great OS to
161+run a browser on.
79162
80−Similarly, a world in which Sandstorm takes off is an awesome world for Urbit, because everyone who has a Sandstorm instance has a great platform for running Urbit on. (Although Sandstorm could still work on its UDP capabilities.)
163+Similarly, a world in which Sandstorm takes off is an awesome world for Urbit,
164+because everyone who has a Sandstorm instance has a great platform for running
165+Urbit on. (Although Sandstorm could still work on its UDP capabilities.)
81166
82−Urbit on Sandstorm will be a sort of "double-hulled" personal server, even safer and more friendly than either system alone. And Sandstorm is not its own P2P network, like Urbit.
167+Urbit on Sandstorm will be a sort of "double-hulled" personal server, even safer
168+and more friendly than either system alone. And Sandstorm is not its own P2P
169+network, like Urbit.
83170
84171## Urbit doesn't have enough planets for every human being.
85172
86−A planet is a tool, not a toy. Like a car, it's a device for a responsible and civilized adult. There aren't 4 billion cars in the world, nor 4 billion responsible adults.
173+A planet is a tool, not a toy. Like a car, it's a device for a responsible and
174+civilized adult. There aren't 4 billion cars in the world, nor 4 billion
175+responsible adults.
87176
88−And limiting the supply of anything doesn't create a shortage. It sets a price. Ideally, in the long run, we think a planet should cost about $10. This could be off by an order of magnitude either way, and it wouldn't be the end of the world.
177+And limiting the supply of anything doesn't create a shortage. It sets a price.
178+Ideally, in the long run, we think a planet should cost about $10. This could be
179+off by an order of magnitude either way, and it wouldn't be the end of the
180+world.
89181
90−If a planet costs $10, that means you paid $10 to get a planet. A planet with no reputation has a positive reputation, because someone paid $10 for it and hasn't yet done anything wrong. Positive default reputation is the single quality that makes a social network social.
182+If a planet costs $10, that means you paid $10 to get a planet. A planet with no
183+reputation has a positive reputation, because someone paid $10 for it and hasn't
184+yet done anything wrong. Positive default reputation is the single quality that
185+makes a social network social.
91186
92−There is always a tradeoff between free speech and free beer. Urbit will always choose free speech.
187+There is always a tradeoff between free speech and free beer. Urbit will always
188+choose free speech.
93189
94190## Cloud computing is inherently non-private.
95191
96−TLDR: a general-purpose cloud computer is much, much more private than a special-purpose cloud computer. In general, a VM is secure against corporations but not governments.
97−
98−One reason we want the decentralized Internet is that we're tired of giant corporations spying on us. Think about it this way: Amazon is Netflix's main competitor. And yet, Netflix runs its whole operation on AWS. Why is Netflix sure that Amazon won't spy on it?
99−
100−A general-purpose virtual machine is special from a privacy standpoint, just because it's commercially realistic to design terms of service that prevent the host from peeking and poking at the customer's machine. Crossing this moat is technically nontrivial and can't possibly happen by any reasonable accident. No hosting contract could contemplate it.
101−
102−Whereas when your cloud computer is a special-purpose machine -- just a database row on some corporation's mainframe -- there is no way these services can promise not to handle your data. Handling your data is *what they do*. On a special-purpose server, the concept of privacy is not even defined.
103−
104−Where even a general-purpose server falls down is where the user has a sovereign adversary, which can secretly violate explicit or implicit hosting contracts. Users with a sovereign adversary must rely only on their own physical security. However, most users don't have a sovereign adversary. And those who do maximize their "herd immunity" if they can use the same protocols as those who don't.
105−
106−Also, the portability of a cloud server image is critical. Of course, since Urbit is formally specified, it's trivially portable. In fact, one strategy against sovereign adversaries may be continuous rotation between hosts, like an MX missile.
192+TLDR: a general-purpose cloud computer is much, much more private than a
193+special-purpose cloud computer. In general, a VM is secure against corporations
194+but not governments.
195+
196+One reason we want the decentralized Internet is that we're tired of giant
197+corporations spying on us. Think about it this way: Amazon is Netflix's main
198+competitor. And yet, Netflix runs its whole operation on AWS. Why is Netflix
199+sure that Amazon won't spy on it?
200+
201+A general-purpose virtual machine is special from a privacy standpoint, just
202+because it's commercially realistic to design terms of service that prevent the
203+host from peeking and poking at the customer's machine. Crossing this moat is
204+technically nontrivial and can't possibly happen by any reasonable accident. No
205+hosting contract could contemplate it.
206+
207+Whereas when your cloud computer is a special-purpose machine -- just a database
208+row on some corporation's mainframe -- there is no way these services can
209+promise not to handle your data. Handling your data is *what they do*. On a
210+special-purpose server, the concept of privacy is not even defined.
211+
212+Where even a general-purpose server falls down is where the user has a sovereign
213+adversary, which can secretly violate explicit or implicit hosting contracts.
214+Users with a sovereign adversary must rely only on their own physical security.
215+However, most users don't have a sovereign adversary. And those who do maximize
216+their "herd immunity" if they can use the same protocols as those who don't.
217+
218+Also, the portability of a cloud server image is critical. Of course, since
219+Urbit is formally specified, it's trivially portable. In fact, one strategy
220+against sovereign adversaries may be continuous rotation between hosts, like an
221+MX missile.
107222
108223## "Jets" are, like, a total hoax.
109224
110−TLDR: like, all of computing is a hoax. You can't compare a hoax to nothing. You can only compare it to all the other hoaxes.
111−
112−A "jet" is a sort of software device driver in Urbit. Urbit is precisely defined in terms of an interpreter that fits on a T-shirt, Nock. But a naive implementation of Nock is nowhere near practical, because Nock has only one integer operation: increment. For example, to decrement a number in Nock, you increment a counter up to the number under it.
113−
114−The only way an efficient Nock interpreter can work is to recognize algorithms like decrement, and implement them non-naively. By far the easiest way to do this is not to analyze arbitrary code as it's being executed, but to register and match well-known implementations in the standard library. No one should be writing their own decrement.
115−
116−But the semantics of the interpreter, *so long as the jet and the jet harness are defined correctly*, are exactly those of Nock. We are not extending or changing Nock in any way. We are just taking a shortcut in certain cases we understand perfectly.
117−
118−It's not at all unprecedented to have implementations much more complex than the corresponding specification. The x86 instruction set is relatively simple; the complexity of its decoding and execution path in a modern CPU is enormous. This path may well have "peephole optimizations" that replace matched algorithms, and if it doesn't the modern C compiler does.
119−
120−So jets are *morally* defensible. The fact remains, however, that a Nock interpreter without jets is completely useless. And there is not even an informal document that tells you what jets you need for a reasonably efficient Urbit. (This last, we can agree, should be corrected.)
121−
122−The correct way to think about jets is not to compare them to a perfect interpreter implemented by unicorns. Jets are a combined replacement for two other techniques in language implementation: intrinsics and a foreign-function interface.
123−
124−Compared to both intrinsics and an FFI, your jets have one key disadvantage: they need to be specified in pure code. You may not have this executable specification, which means you need to write it. Is this really so bad for your development process? An executable specification? Which can be trivially tested against the efficient implementation?
125−
126−Compared to intrinsics, jets give you true separation between mechanism and policy; only the interpreter, not the programmer and not the compiler, needs to know what's accelerated.
127−
128−Compared to an FFI, jets preclude I/O, so can be trivially sandboxed. Except that the programmer needs to mark routines which may benefit from optimization with a hint, here too we separate mechanism (efficient implementation) from policy.
129−
130−Yes, formal verification of jet equivalence is desirable. However, in the real world, many specifications, including quite complex ones, are tested into equivalence by brute force.
131−
132−Urbit has some jet abuses. The equivalence between our markdown parser in Hoon and the CommonMark C library is super dubious. It should be taken out and shot.
133−
134−However, the miscomputation resulting from a minor jet discrepancy is not a security hole or even fatal. It effectively means the event history does not match the current state. The way to resolve this conflict is for the current state to win, and the event history to be discarded -- not abnormal anyway. See the next question.
225+TLDR: like, all of computing is a hoax. You can't compare a hoax to nothing. You
226+can only compare it to all the other hoaxes.
227+
228+A "jet" is a sort of software device driver in Urbit. Urbit is precisely defined
229+in terms of an interpreter that fits on a T-shirt, Nock. But a naive
230+implementation of Nock is nowhere near practical, because Nock has only one
231+integer operation: increment. For example, to decrement a number in Nock, you
232+increment a counter up to the number under it.
233+
234+The only way an efficient Nock interpreter can work is to recognize algorithms
235+like decrement, and implement them non-naively. By far the easiest way to do
236+this is not to analyze arbitrary code as it's being executed, but to register
237+and match well-known implementations in the standard library. No one should be
238+writing their own decrement.
239+
240+But the semantics of the interpreter, *so long as the jet and the jet harness
241+are defined correctly*, are exactly those of Nock. We are not extending or
242+changing Nock in any way. We are just taking a shortcut in certain cases we
243+understand perfectly.
244+
245+It's not at all unprecedented to have implementations much more complex than the
246+corresponding specification. The x86 instruction set is relatively simple; the
247+complexity of its decoding and execution path in a modern CPU is enormous. This
248+path may well have "peephole optimizations" that replace matched algorithms, and
249+if it doesn't the modern C compiler does.
250+
251+So jets are *morally* defensible. The fact remains, however, that a Nock
252+interpreter without jets is completely useless. And there is not even an
253+informal document that tells you what jets you need for a reasonably efficient
254+Urbit. (This last, we can agree, should be corrected.)
255+
256+The correct way to think about jets is not to compare them to a perfect
257+interpreter implemented by unicorns. Jets are a combined replacement for two
258+other techniques in language implementation: intrinsics and a foreign-function
259+interface.
260+
261+Compared to both intrinsics and an FFI, your jets have one key disadvantage:
262+they need to be specified in pure code. You may not have this executable
263+specification, which means you need to write it. Is this really so bad for your
264+development process? An executable specification? Which can be trivially tested
265+against the efficient implementation?
266+
267+Compared to intrinsics, jets give you true separation between mechanism and
268+policy; only the interpreter, not the programmer and not the compiler, needs to
269+know what's accelerated.
270+
271+Compared to an FFI, jets preclude I/O, so can be trivially sandboxed. Except
272+that the programmer needs to mark routines which may benefit from optimization
273+with a hint, here too we separate mechanism (efficient implementation) from
274+policy.
275+
276+Yes, formal verification of jet equivalence is desirable. However, in the real
277+world, many specifications, including quite complex ones, are tested into
278+equivalence by brute force.
279+
280+Urbit has some jet abuses. The equivalence between our markdown parser in Hoon
281+and the CommonMark C library is super dubious. It should be taken out and shot.
282+
283+However, the miscomputation resulting from a minor jet discrepancy is not a
284+security hole or even fatal. It effectively means the event history does not
285+match the current state. The way to resolve this conflict is for the current
286+state to win, and the event history to be discarded -- not abnormal anyway. See
287+the next question.
135288
136289## Urbit needs an infinitely extending packet/event log.
137290
138291TLDR: no, it doesn't.
139292
140−We can prune the event log because the Urbit transition function doesn't have any access to the event history -- just the current state and the current event.
293+We can prune the event log because the Urbit transition function doesn't have
294+any access to the event history -- just the current state and the current event.
141295
142−Urbit defines the semantics of a complete event log. It doesn't and can't require an implementation to maintain the whole log. It can maintain a checkpoint and the log since that checkpoint. The current implementation of Urbit keeps the whole log, but the next release will optionally prune it.
296+Urbit defines the semantics of a complete event log. It doesn't and can't
297+require an implementation to maintain the whole log. It can maintain a
298+checkpoint and the log since that checkpoint. The current implementation of
299+Urbit keeps the whole log, but the next release will optionally prune it.
143300
144301## Urbit will never be able to call any existing code.
145302
146−TLDR: neither will Javascript. And dear Unix, the browser does not miss interacting with your `$LD_LIBRARY_PATH` at all.
303+TLDR: neither will Javascript. And dear Unix, the browser does not miss
304+interacting with your `$LD_LIBRARY_PATH` at all.
147305
148−You can't talk to the OS or use system libraries from Javascript. Therefore, there is no point in having any kind of gateway, compatibility bridge, native methods, or other interface between Javascript and C.
306+You can't talk to the OS or use system libraries from Javascript. Therefore,
307+there is no point in having any kind of gateway, compatibility bridge, native
308+methods, or other interface between Javascript and C.
149309
150−When in doubt, remember that Urbit is "the browser for the server side." It plays by the same general rules. Isolation means isolation.
310+When in doubt, remember that Urbit is "the browser for the server side." It
311+plays by the same general rules. Isolation means isolation.
151312
152−## There's no way Urbit will ever be adopted. It's too weird.
313+## There's no way Urbit will ever be adopted. It's too weird.
153314
154−TLDR: Urbit adoption is designed to be driven by ordinary end users. Urbit isn't ready for ordinary end users yet. We're working on it -- come help.
315+TLDR: Urbit adoption is designed to be driven by ordinary end users. Urbit isn't
316+ready for ordinary end users yet. We're working on it -- come help.
155317
156−Right now, Urbit is a developer tool. Or rather, a developer toy -- since the only thing it's useful for is developing Urbit. It also could be a much better toy. We're working on that too.
318+Right now, Urbit is a developer tool. Or rather, a developer toy -- since the
319+only thing it's useful for is developing Urbit. It also could be a much better
320+toy. We're working on that too.
157321
158−But it's absolutely wrong to think of Urbit being adopted as a developer tool in the conventional sense. If you think this is almost impossible, you're right.
322+But it's absolutely wrong to think of Urbit being adopted as a developer tool in
323+the conventional sense. If you think this is almost impossible, you're right.
159324
160−If we look at the way most successful platforms are adopted, they're not adopted for their own virtues. They're adopted because they're part of a larger solution. It's very hard to displace a native component of an existing platform. Urbit is not trying to do this.
325+If we look at the way most successful platforms are adopted, they're not adopted
326+for their own virtues. They're adopted because they're part of a larger
327+solution. It's very hard to displace a native component of an existing platform.
328+Urbit is not trying to do this.
161329
162−C is a better language than Pascal, but it didn't beat Pascal because it's a better language. C beat Pascal because C was the native language of Unix, and people wanted to program in Unix. People don't use Javascript because Javascript is a great language, but because it's the native language of the browser. Replacing the native language of a platform may be doable -- but it's incredibly hard.
330+C is a better language than Pascal, but it didn't beat Pascal because it's a
331+better language. C beat Pascal because C was the native language of Unix, and
332+people wanted to program in Unix. People don't use Javascript because Javascript
333+is a great language, but because it's the native language of the browser.
334+Replacing the native language of a platform may be doable -- but it's incredibly
335+hard.
163336
164−Hoon is not competing with C, or even Haskell, as a Unix programming language. The only reason to program in Hoon is that it's the native language of Urbit. Urbit is not competing with node.js or Rails as a Web backend. The only reason to run Urbit is to run Urbit.
337+Hoon is not competing with C, or even Haskell, as a Unix programming language.
338+The only reason to program in Hoon is that it's the native language of Urbit.
339+Urbit is not competing with node.js or Rails as a Web backend. The only reason
340+to run Urbit is to run Urbit.
165341
166−Nock is cool, but it only gets adopted if Hoon gets adopted. Hoon is cool, but it only gets adopted if Urbit gets adopted. Urbit only gets adopted if it's useful as a personal server for human beings -- most of whom won't be Hoon programmers, or programmers at all.
342+Nock is cool, but it only gets adopted if Hoon gets adopted. Hoon is cool, but
343+it only gets adopted if Urbit gets adopted. Urbit only gets adopted if it's
344+useful as a personal server for human beings -- most of whom won't be Hoon
345+programmers, or programmers at all.
167346
168−## Hoon is too weird. No one will be able to program in it.
347+## Hoon is too weird. No one will be able to program in it.
169348
170−TLDR: Hoon is ridiculously simple. Our documentation and tooling are just immature.
349+TLDR: Hoon is ridiculously simple. Our documentation and tooling are just
350+immature.
171351
172−It's pretty fair to assume that (a) functional programming is hard and weird, (b) Hoon is weird even for a functional language, so (c) Hoon must be hard-squared.
352+It's pretty fair to assume that (a) functional programming is hard and weird,
353+(b) Hoon is weird even for a functional language, so (c) Hoon must be
354+hard-squared.
173355
174−Actually, Hoon is weird even for a functional language because it's an attempt to remove the hardest things about functional programming: category theory, lazy evaluation, and gratuitous abstraction. To know a language is to know what the compiler is doing; all the semantics of the Hoon compiler fit in 2000 lines of code.
356+Actually, Hoon is weird even for a functional language because it's an attempt
357+to remove the hardest things about functional programming: category theory, lazy
358+evaluation, and gratuitous abstraction. To know a language is to know what the
359+compiler is doing; all the semantics of the Hoon compiler fit in 2000 lines of
360+code.
175361
176−It's too easy for us to wind up living in Isaac Asimov's Trantor, a world in which everything got invented thousands of years ago and the idea of new technology is just weird and scary. History isn't over yet, and nor is technical history.
362+It's too easy for us to wind up living in Isaac Asimov's Trantor, a world in
363+which everything got invented thousands of years ago and the idea of new
364+technology is just weird and scary. History isn't over yet, and nor is technical
365+history.
177366
178−New things are harder to learn than old things. We ask smart high-school students to learn calculus. Think about how much harder it was for Newton and Leibniz to invent calculus, or for their first students to pick it up.
367+New things are harder to learn than old things. We ask smart high-school
368+students to learn calculus. Think about how much harder it was for Newton and
369+Leibniz to invent calculus, or for their first students to pick it up.
179370
180−Most of the difference is just the collective certainty that our society conveys to a high-school student that calculus is learnable. When you're learning Urbit, you don't have this collective knowledge; so you don't have the confidence that the problem is solvable. Confidence makes a huge difference. Moreover, any bug or glitch in the developer experience destroys this confidence and takes a long time to heal.
371+Most of the difference is just the collective certainty that our society conveys
372+to a high-school student that calculus is learnable. When you're learning Urbit,
373+you don't have this collective knowledge; so you don't have the confidence that
374+the problem is solvable. Confidence makes a huge difference. Moreover, any bug
375+or glitch in the developer experience destroys this confidence and takes a long
376+time to heal.
181377
182−Yes, we know: Hoon remains quite hard to learn. Again, we have no reason to think this problem isn't solvable. Public enlightenment remains our main priority.
378+Yes, we know: Hoon remains quite hard to learn. Again, we have no reason to
379+think this problem isn't solvable. Public enlightenment remains our main
380+priority.
183381
184382## Urbit programmers are stuck with Hoon.
185383
186384TLDR: patience, grasshopper.
187385
188−There's quite a straightforward way to implement any perfectly specified language with a reliable interpreter in Hoon. First, write an interpreter for that language in Hoon. Second, jet that intepreter function with the existing implementation.
386+There's quite a straightforward way to implement any perfectly specified
387+language with a reliable interpreter in Hoon. First, write an interpreter for
388+that language in Hoon. Second, jet that intepreter function with the existing
389+implementation.
189390
190−It is not clear that Javascript is *quite* well-defined enough for this treatment. But Lua probably is.
391+It is not clear that Javascript is *quite* well-defined enough for this
392+treatment. But Lua probably is.
191393
192394## Ordinary users will never be able to manage an Urbit server.
193395
194−TLDR: Urbit's technical simplicity has always been designed to drive human usability. But the polish is the last thing that goes on. So we can't evaluate this claim right now.
396+TLDR: Urbit's technical simplicity has always been designed to drive human
397+usability. But the polish is the last thing that goes on. So we can't evaluate
398+this claim right now.
195399
196−Right now, Urbit is only for geeks. You already need to be able to wrangle a Unix machine to run it. What's the point?
400+Right now, Urbit is only for geeks. You already need to be able to wrangle a
401+Unix machine to run it. What's the point?
197402
198−This Urbit isn't the real Urbit. It's an early milestone on the way to the real Urbit.
403+This Urbit isn't the real Urbit. It's an early milestone on the way to the real
404+Urbit.
199405
200−The real Urbit -- for normal human beings -- is a hosted service. Getting a planet is as easy as signing up for Facebook. Probably many users will think of it as another web account. They might not even know it can run more apps than the ones they use.
406+The real Urbit -- for normal human beings -- is a hosted service. Getting a
407+planet is as easy as signing up for Facebook. Probably many users will think of
408+it as another web account. They might not even know it can run more apps than
409+the ones they use.
201410
202−A deterministic, persistent cloud computer is something different from a traditional server. Normally when we think of a server in the cloud, we think of it like a live animal -- a creature that needs to be cared for, fed, and herded. A file in the cloud is more like a rock -- you can forget about it for ten years.
411+A deterministic, persistent cloud computer is something different from a
412+traditional server. Normally when we think of a server in the cloud, we think of
413+it like a live animal -- a creature that needs to be cared for, fed, and herded.
414+A file in the cloud is more like a rock -- you can forget about it for ten
415+years.
203416
204−An urbit is a general-purpose computer, but it doesn't even have the concept of a reboot. It upgrades itself. If you don't feed it any packets for ten years, then turn it back on, it will spend a day or two upgrading itself, then be back to normal. Maybe it's something in between a rock and an animal -- a cactus?
417+An urbit is a general-purpose computer, but it doesn't even have the concept of
418+a reboot. It upgrades itself. If you don't feed it any packets for ten years,
419+then turn it back on, it will spend a day or two upgrading itself, then be back
420+to normal. Maybe it's something in between a rock and an animal -- a cactus?
205421
206−Another huge difference versus an Internet server is that we're confident that Urbit's limited supply of identities will make it easy to keep abusers off the network. So far, so good -- but of course, no one abuses a young network.
422+Another huge difference versus an Internet server is that we're confident that
423+Urbit's limited supply of identities will make it easy to keep abusers off the
424+network. So far, so good -- but of course, no one abuses a young network.
207425
208−The bottom line is that managing your urbit has to be as easy as managing your iPhone. Normally, it consists of deciding what apps you want to be running, and how much you trust them. Resources can't be free, so sometimes you have to play memory police. Humans have shown that they can handle these tasks.
426+The bottom line is that managing your urbit has to be as easy as managing your
427+iPhone. Normally, it consists of deciding what apps you want to be running, and
428+how much you trust them. Resources can't be free, so sometimes you have to play
429+memory police. Humans have shown that they can handle these tasks.
209430
210−Our '70s OSes and networks, which were great designs in their day and have matured into excellent industrial tools, give us a totally misleading impression of how hard it should be to manage a general-purpose computer. Computing isn't scary or dangerous. Unix and the Internet are scary and dangerous. That's fine for an industrial tool, but not a personal tool.
431+Our '70s OSes and networks, which were great designs in their day and have
432+matured into excellent industrial tools, give us a totally misleading impression
433+of how hard it should be to manage a general-purpose computer. Computing isn't
434+scary or dangerous. Unix and the Internet are scary and dangerous. That's fine
435+for an industrial tool, but not a personal tool.
211436
212437## Urbit has no killer app.
213438
214439TLDR: the killer app is personal API aggregation.
215440
216−It's a truism that any new platform has to be fundamentally much better at solving some problem than the mature platform it seeks to replace.
217−
218−We can look at Urbit's killer app from two perspectives: as a developer, and as a user.
219−
220−From the developer's perspective, Urbit's advantage is that it's a network stack which provides exactly-once delivery of typed, validated, transactional, encrypted and authenticated messages. The difference between an Urbit API and a REST API is like the difference between a paved road and a dirt road. On the other hand, you do need to learn a new functional language.
221−
222−From the user's perspective, there's one task that any personal server can perform, that can't be performed by any Web service: unrestricted API aggregation.
223−
224−Well before Urbit is ready to *replace* any conventional web services, it should be ready to *command* them in place by API. (Or if needed, by scraping.) If all you care about is being in control of your own data, it's fine to leave it in the hands of these services, as you have the API secrets to get it out.
225−
226−Managing a set of security connections to your existing services is one of the first important tasks of a modern personal server. This is a stateful task that typically requires both a durable API key and a temporary OAuth token. APIs change all the time, so connection maintenance also requires evergreen updates.
227−
228−The origin of this API key will vary, but usually the best way to set it is BYOK: the user registers their own urbit as an "app." And the neat thing about having your own API keys, for multiple services, on a single general-purpose computer, is that none of these services really has any practical way to control what you do with your own data.
229−
230−Terms of service which constrain the use of data (as opposed to the abuse of the service) simply aren't realistic and will no longer apply. This enables a variety of novel user experiences which aren't implementable as traditional web services, and also aren't available via conventional third-party API aggregators.
231−
232−Also, since Urbit is after all quite immature, it doesn't make much sense to restrict this security state to code within Urbit. The Urbit interpreter `vere` runs as a Unix daemon that implements the FUSE user-level filesystem protocol, and maps the data on your services into the Unix filesystem. For example, one of our demos lets you `ls` your Github issues.
233−
234−So it's straightforward to build, for instance, a Python app that uses Urbit as a gateway to mash up a bunch of web services. As a Unix programmer, you might even just regard Urbit as a generic Web API gateway daemon, without worrying about its internals.
235−
236−We have other ideas for initial killer apps. But this, we feel, is the best one. API libraries for `npm` et al abound. Stateful, self-updating, generic API aggregators with FUSE integration, also integrated with a reactive web server, are more rare. So perhaps there's a small niche here.
441+It's a truism that any new platform has to be fundamentally much better at
442+solving some problem than the mature platform it seeks to replace.
443+
444+We can look at Urbit's killer app from two perspectives: as a developer, and as
445+a user.
446+
447+From the developer's perspective, Urbit's advantage is that it's a network stack
448+which provides exactly-once delivery of typed, validated, transactional,
449+encrypted and authenticated messages. The difference between an Urbit API and a
450+REST API is like the difference between a paved road and a dirt road. On the
451+other hand, you do need to learn a new functional language.
452+
453+From the user's perspective, there's one task that any personal server can
454+perform, that can't be performed by any Web service: unrestricted API
455+aggregation.
456+
457+Well before Urbit is ready to *replace* any conventional web services, it should
458+be ready to *command* them in place by API. (Or if needed, by scraping.) If all
459+you care about is being in control of your own data, it's fine to leave it in
460+the hands of these services, as you have the API secrets to get it out.
461+
462+Managing a set of security connections to your existing services is one of the
463+first important tasks of a modern personal server. This is a stateful task that
464+typically requires both a durable API key and a temporary OAuth token. APIs
465+change all the time, so connection maintenance also requires evergreen updates.
466+
467+The origin of this API key will vary, but usually the best way to set it is
468+BYOK: the user registers their own urbit as an "app." And the neat thing about
469+having your own API keys, for multiple services, on a single general-purpose
470+computer, is that none of these services really has any practical way to control
471+what you do with your own data.
472+
473+Terms of service which constrain the use of data (as opposed to the abuse of the
474+service) simply aren't realistic and will no longer apply. This enables a
475+variety of novel user experiences which aren't implementable as traditional web
476+services, and also aren't available via conventional third-party API
477+aggregators.
478+
479+Also, since Urbit is after all quite immature, it doesn't make much sense to
480+restrict this security state to code within Urbit. The Urbit interpreter `vere`
481+runs as a Unix daemon that implements the FUSE user-level filesystem protocol,
482+and maps the data on your services into the Unix filesystem. For example, one of
483+our demos lets you `ls` your Github issues.
484+
485+So it's straightforward to build, for instance, a Python app that uses Urbit as
486+a gateway to mash up a bunch of web services. As a Unix programmer, you might
487+even just regard Urbit as a generic Web API gateway daemon, without worrying
488+about its internals.
489+
490+We have other ideas for initial killer apps. But this, we feel, is the best one.
491+API libraries for `npm` et al abound. Stateful, self-updating, generic API
492+aggregators with FUSE integration, also integrated with a reactive web server,
493+are more rare. So perhaps there's a small niche here.
237494
238495## Urbit is sneered at by brilliant talking horses.
239496
240−It's difficult to categorize this [brilliant essay of Fare's](http://ngnghm.github.io/blog/2016/06/11/chapter-10-houyhnhnms-vs-martians/) in a single bullet point. So I've saved it for last.
497+It's difficult to categorize this [brilliant essay of
498+Fare's](http://ngnghm.github.io/blog/2016/06/11/chapter-10-houyhnhnms-vs-martians/)
499+in a single bullet point. So I've saved it for last.
241500
242−We've already addressed the point most commonly made by others: that jets are a sham. It's not always trivial to decode this critique, which is quite abstract. But Fare' makes a few other points.
501+We've already addressed the point most commonly made by others: that jets are a
502+sham. It's not always trivial to decode this critique, which is quite abstract.
503+But Fare' makes a few other points.
243504
244505### Event-sourcing and/or caching is a pattern, not a layer
245506
246−Fare' is perfectly right that "one size does not fit all" in persistence. Generally, Urbit uses event-sourced persistence.
507+Fare' is perfectly right that "one size does not fit all" in persistence.
508+Generally, Urbit uses event-sourced persistence.
247509
248−But it has multiple layers of event-sourcing: in the definition of Urbit itself; in the application sandbox vane (Gall), and in the application itself. Urbit also has a completely orthogonal revision control system (Clay).
510+But it has multiple layers of event-sourcing: in the definition of Urbit itself;
511+in the application sandbox vane (Gall), and in the application itself. Urbit
512+also has a completely orthogonal revision control system (Clay).
249513
250−And there is not a single cache across the whole system, though arguably there should be; for instance, the functional build system (Ford, which Fare' the master of build systems might appreciate) has its own internal cache.
514+And there is not a single cache across the whole system, though arguably there
515+should be; for instance, the functional build system (Ford, which Fare' the
516+master of build systems might appreciate) has its own internal cache.
251517
252−It is a common mistake to confuse a design pattern with a layer or feature, and equally fatal whichever direction you fail.
518+It is a common mistake to confuse a design pattern with a layer or feature, and
519+equally fatal whichever direction you fail.
253520
254521### Let's be clear about why DSLs suck
255522
256−DSLs suck not because they are difficult to newbies in the base language. DSLs suck because every time a programmer, even one *experienced* in the base language, comes into a new codebase or project, she has to learn a new custom language.
523+DSLs suck not because they are difficult to newbies in the base language. DSLs
524+suck because every time a programmer, even one *experienced* in the base
525+language, comes into a new codebase or project, she has to learn a new custom
526+language.
257527
258−You need enormous wins to justify this cost. It's the goal of the base language designer to preempt these wins, creating a language which is almost never so tiresome and full of boilerplate that it requires a DSL or template layer.
528+You need enormous wins to justify this cost. It's the goal of the base language
529+designer to preempt these wins, creating a language which is almost never so
530+tiresome and full of boilerplate that it requires a DSL or template layer.
259531
260−Hoon is almost entirely made of macros -- but they are internal, fixed, built-in macros (with no gensyms). This fixed set of macros is essentially enough. Occasionally we want to add one or two. But we never, ever pine for context-dependent macros.
532+Hoon is almost entirely made of macros -- but they are internal, fixed, built-in
533+macros (with no gensyms). This fixed set of macros is essentially enough.
534+Occasionally we want to add one or two. But we never, ever pine for
535+context-dependent macros.
261536
262537### Determinism is not consensus, and is not constraining
263538
264−Fare' is totally right that an urbit's data is meant for itself alone. In fact, an urbit has the right to compute incorrectly if it wants. We go to considerable lengths to ensure that you can't gain any particular advantage by incorrect computing.
539+Fare' is totally right that an urbit's data is meant for itself alone. In fact,
540+an urbit has the right to compute incorrectly if it wants. We go to considerable
541+lengths to ensure that you can't gain any particular advantage by incorrect
542+computing.
265543
266−The whole point of Nock is that it's so low-level that there is no conceivable advantage in upgrading it. Divergence is just pointless. This is not a question of network integrity, just of practical standardization.
544+The whole point of Nock is that it's so low-level that there is no conceivable
545+advantage in upgrading it. Divergence is just pointless. This is not a question
546+of network integrity, just of practical standardization.
267547
268−This consistency stops at Nock. Without anyone violating the correctness of their lifecycle functions, anyone or everyone in Urbit could replace Hoon with Javascript. Determinism does not cramp Urbit's semantic style in any way, shape or form.
548+This consistency stops at Nock. Without anyone violating the correctness of
549+their lifecycle functions, anyone or everyone in Urbit could replace Hoon with
550+Javascript. Determinism does not cramp Urbit's semantic style in any way, shape
551+or form.
docs/about/overview.md+47−58
@@ -1,88 +1,77 @@
11---
2−navhome: /docs/
3−next: true
2+navhome: '/docs/'
3+next: True
44sort: 1
55title: Technical overview
66---
77
88# Technical overview
99
10−Urbit is a clean-slate system software stack defined as a
11−deterministic computer. An encrypted P2P network, `%ames`, runs
12−on a functional operating system, Arvo, written in a strict,
13−typed functional language, Hoon, which compiles itself to a
14−combinator interpreter, Nock, whose spec gzips to 340 bytes.
10+Urbit is a clean-slate system software stack defined as a deterministic
11+computer. An encrypted P2P network, `%ames`, runs on a functional operating
12+system, Arvo, written in a strict, typed functional language, Hoon, which
13+compiles itself to a combinator interpreter, Nock, whose spec gzips to 340
14+bytes.
1515
1616## Architectural overview
1717
18−A deterministic computer? Urbit's state is a pure function of
19−its event history. In practice it uses a memory checkpoint and
20−an append-only log. Every event is a transaction; Urbit is an
21−ACID database and a single-level store. Urbit runs on Unix now,
22−but it's easy to imagine on a hypervisor or even bare metal.
18+A deterministic computer? Urbit's state is a pure function of its event history.
19+In practice it uses a memory checkpoint and an append-only log. Every event is a
20+transaction; Urbit is an ACID database and a single-level store. Urbit runs on
21+Unix now, but it's easy to imagine on a hypervisor or even bare metal.
2322
24−A purely functional OS? Urbit is pure -- no code inside it can
25−make system calls or otherwise affect the underlying platform.
26−Instead, the top-level event function defines an I/O protocol.
27−It maps an input event and the current state to a list of output
28−actions and the subsequent state. In Hoon:
23+A purely functional OS? Urbit is pure -- no code inside it can make system calls
24+or otherwise affect the underlying platform. Instead, the top-level event
25+function defines an I/O protocol. It maps an input event and the current state
26+to a list of output actions and the subsequent state. In Hoon:
2927
30−```
31−$-([event state] [(list action) state])
32−```
28+ $-([event state] [(list action) state])
3329
3430### Nock
3531
36−Nock is a sort of nano-Lisp without syntax, symbols or lambdas.
37−Most Lisps are one-layer: they create a practical language by
38−extending a theoretically simple interpreter. The abstraction is
39−simple and the implementation is practical; there is no actual
40−codebase both simple and practical. Hoon and Nock are two
41−layers: Hoon compiles itself to pure Nock. Since Urbit is
42−defined in Nock, not Hoon, we can upgrade Hoon over the air.
32+Nock is a sort of nano-Lisp without syntax, symbols or lambdas. Most Lisps are
33+one-layer: they create a practical language by extending a theoretically simple
34+interpreter. The abstraction is simple and the implementation is practical;
35+there is no actual codebase both simple and practical. Hoon and Nock are two
36+layers: Hoon compiles itself to pure Nock. Since Urbit is defined in Nock, not
37+Hoon, we can upgrade Hoon over the air.
4338
44−The Nock data model is especially trivial. A *noun* is an atom
45−or a cell. An atom is any unsigned integer. A cell is an
46−ordered pair of nouns. Nouns are acyclic and expose no pointer
47−equality test.
39+The Nock data model is especially trivial. A *noun* is an atom or a cell. An
40+atom is any unsigned integer. A cell is an ordered pair of nouns. Nouns are
41+acyclic and expose no pointer equality test.
4842
4943### Hoon
5044
51−Hoon is a strict combinator language that avoids mathematical
52−theory and notation. It aims at a mechanical, imperative feel.
53−Hoon uses ASCII digraphs instead of keywords; there are no
54−user-level macros. The type system infers only forward and does
55−not use unification, but is not much weaker than Haskell's. The
45+Hoon is a strict combinator language that avoids mathematical theory and
46+notation. It aims at a mechanical, imperative feel. Hoon uses ASCII digraphs
47+instead of keywords; there are no user-level macros. The type system infers only
48+forward and does not use unification, but is not much weaker than Haskell's. The
5649compiler and inference engine is about 2000 lines of Hoon.
5750
5851### Arvo
5952
60−Arvo is an event-driven OS written in Hoon. It can upgrade
61−itself and everything inside it over the network. The Arvo
62−kernel proper is 500 lines of Hoon, which implements a typed
63−event system with explicit call-stack structure. Arvo ships
64−with modules that provide P2P networking (`%ames`), a revision-
65−control system (`%clay`), a web client/server (`%eyre`), a
66−functional build system (`%ford`), and an application engine
67−`(%gall)`.
53+Arvo is an event-driven OS written in Hoon. It can upgrade itself and everything
54+inside it over the network. The Arvo kernel proper is 500 lines of Hoon, which
55+implements a typed event system with explicit call-stack structure. Arvo ships
56+with modules that provide P2P networking (`%ames`), a revision- control system
57+(`%clay`), a web client/server (`%eyre`), a functional build system (`%ford`),
58+and an application engine `(%gall)`.
6859
6960### Ames
7061
71−Ames, the Urbit network, is an encrypted P2P protocol over UDP.
72−Its address space is semi-decentralized; 64-bit addresses are
73−hierarchically distributed, 128-bit addresses are self-created.
74−Addresses (or *plots*) are rendered in a phonemic syntax for
75−memorability. The scarcity of short plots helps control spam and
76−other Sybil attacks. The short plot hierarchy is also reused as
77−a supernode routing system for NAT traversal.
62+Ames, the Urbit network, is an encrypted P2P protocol over UDP. Its address
63+space is semi-decentralized; 64-bit addresses are hierarchically distributed,
64+128-bit addresses are self-created. Addresses (or *plots*) are rendered in a
65+phonemic syntax for memorability. The scarcity of short plots helps control spam
66+and other Sybil attacks. The short plot hierarchy is also reused as a supernode
67+routing system for NAT traversal.
7868
7969### Dojo and talk
8070
81−Urbit ships with two default applications: a REPL or shell
82−`:dojo`, and a distributed user-level message-bus `:talk`.
83−`:talk` under the hood resembles NNTP; to the user, it looks like
84−a self-hosted Slack or persistent IRC.
71+Urbit ships with two default applications: a REPL or shell `:dojo`, and a
72+distributed user-level message-bus `:talk`. `:talk` under the hood resembles
73+NNTP; to the user, it looks like a self-hosted Slack or persistent IRC.
8574
86−The full Urbit stack (compiler, standard library, kernel,
87−modules, and applications) is about 25,000 lines of Hoon.
88−Urbit is patent-free and MIT licensed.
75+The full Urbit stack (compiler, standard library, kernel, modules, and
76+applications) is about 25,000 lines of Hoon. Urbit is patent-free and MIT
77+licensed.
docs/about/runtime.md+794−923
@@ -1,67 +1,60 @@
11---
2−navhome: /docs/
2+navhome: '/docs/'
33sort: 2
44title: C runtime system
55---
66
77# C runtime system
88
9−The Urbit interpreter is built on a Nock runtime system written
10−in C, `u3`. This document is a relatively complete description
9+The Urbit interpreter is built on a Nock runtime system written in C, `u3`. This
10+document is a relatively complete description
1111
12−You should keep reading if (a) you're planning to work on the
13−Urbit interpreter; (b) you're a language implementation geek; or
14−(c) you don't really understand anything until you've seen the
15−actual structs.
12+You should keep reading if (a) you're planning to work on the Urbit interpreter;
13+(b) you're a language implementation geek; or (c) you don't really understand
14+anything until you've seen the actual structs.
1615
1716## u3: noun processing in C
1817
19−`u3` is the C library that makes Urbit work. If it wasn't called
20−`u3`, it might be called `libnoun` - it's a library for making
21−and storing nouns.
18+`u3` is the C library that makes Urbit work. If it wasn't called `u3`, it might
19+be called `libnoun` - it's a library for making and storing nouns.
2220
23−What's a noun? A noun is either a cell or an atom. A cell is an
24−ordered pair of any two nouns. An atom is an unsigned integer of
25−any size.
21+What's a noun? A noun is either a cell or an atom. A cell is an ordered pair of
22+any two nouns. An atom is an unsigned integer of any size.
2623
27−To the C programmer, this is not a terribly complicated data
28−structure, so why do you need a library for it?
24+To the C programmer, this is not a terribly complicated data structure, so why
25+do you need a library for it?
2926
30−One: nouns have a well-defined computation kernel, Nock, whose
31−spec fits on a page and gzips to 340 bytes. But the only
32−arithmetic operation in Nock is increment. So it's nontrivial
33−to compute both efficiently and correctly.
27+One: nouns have a well-defined computation kernel, Nock, whose spec fits on a
28+page and gzips to 340 bytes. But the only arithmetic operation in Nock is
29+increment. So it's nontrivial to compute both efficiently and correctly.
3430
35−Two: `u3` is designed to be a "solid-state interpreter," ie, a
36−single-level store which is transparently snapshotted. This
37−implies a specialized memory-management model, etc, etc.
31+Two: `u3` is designed to be a "solid-state interpreter," ie, a single-level
32+store which is transparently snapshotted. This implies a specialized
33+memory-management model, etc, etc.
3834
39−(Does `u3` depend on the higher levels of Urbit, Arvo and Hoon?
40−Yes and no. `u3` expects you to load something shaped like an
41−Arvo kernel, and use it as an event-processing function. But you
42−don't need to use this feature if you don't want, and your kernel
43−doesn't have to be Arvo proper - just Arvo-compatible. Think of
44−`u3` as the BIOS and Arvo as the boot kernel. And there are no
35+(Does `u3` depend on the higher levels of Urbit, Arvo and Hoon? Yes and no. `u3`
36+expects you to load something shaped like an Arvo kernel, and use it as an
37+event-processing function. But you don't need to use this feature if you don't
38+want, and your kernel doesn't have to be Arvo proper - just Arvo-compatible.
39+Think of `u3` as the BIOS and Arvo as the boot kernel. And there are no
4540dependencies at all between Hoon the language and `u3`.)
4641
4742## c3: C in Urbit
4843
49−Under `u3` is the simple `c3` layer, which is just how we write C
50−in Urbit.
44+Under `u3` is the simple `c3` layer, which is just how we write C in Urbit.
5145
52−When writing C in u3, please of course follow the conventions of
53−the code around you as regards indentation, etc. It's especially
54−important that every function have a header comment, even if it
55−says nothing interesting.
46+When writing C in u3, please of course follow the conventions of the code around
47+you as regards indentation, etc. It's especially important that every function
48+have a header comment, even if it says nothing interesting.
5649
57−But some of our idiosyncrasies go beyond convention. Yes, we've
58−done awful things to C. Here's what we did and why we did.
50+But some of our idiosyncrasies go beyond convention. Yes, we've done awful
51+things to C. Here's what we did and why we did.
5952
6053### c3: integer types
6154
62−First, it's generally acknowledged that underspecified integer
63−types are C's worst disaster. C99 fixed this, but the `stdint`
64−types are wordy and annoying. We've replaced them with:
55+First, it's generally acknowledged that underspecified integer types are C's
56+worst disaster. C99 fixed this, but the `stdint` types are wordy and annoying.
57+We've replaced them with:
6558
6659 /* Good integers.
6760 */
@@ -88,50 +81,47 @@ types are wordy and annoying. We've replaced them with:
8881 typedef uintptr_t c3_p; // pointer-length uint - really really bad
8982 typedef intptr_t c3_ps; // pointer-length int - really really bad
9083
91−Some of these need explanation. A loobean is a Nock boolean -
92−Nock, for mysterious reasons, uses 0 as true (always say "yes")
93−and 1 as false (always say "no").
84+Some of these need explanation. A loobean is a Nock boolean - Nock, for
85+mysterious reasons, uses 0 as true (always say "yes") and 1 as false (always say
86+"no").
9487
95−Nock and/or Hoon cannot tell the difference between a short atom
96−and a long one, but at the `u3` level every atom under `2^31` is
97−direct. The `c3_l` type is useful to annotate this. A `c3_m` is
98−a *mote* - a string of up to 4 characters in a `c3_l`, least
99−significant byte first. A `c3_g` should be a 5-bit atom. Of
88+Nock and/or Hoon cannot tell the difference between a short atom and a long one,
89+but at the `u3` level every atom under `2^31` is direct. The `c3_l` type is
90+useful to annotate this. A `c3_m` is a *mote* - a string of up to 4 characters
91+in a `c3_l`, least significant byte first. A `c3_g` should be a 5-bit atom. Of
10092course, C cannot enforce these constraints, only document them.
10193
102−Use the "bad" - ie, poorly specified - integer types only when
103−interfacing with external code that expects them.
94+Use the "bad" - ie, poorly specified - integer types only when interfacing with
95+external code that expects them.
10496
105−An enormous number of motes are defined in `i/c/motes.h`. There
106−is no reason to delete motes that aren't being used, or even to
107−modularize the definitions. Keep them alphabetical, though.
97+An enormous number of motes are defined in `i/c/motes.h`. There is no reason to
98+delete motes that aren't being used, or even to modularize the definitions. Keep
99+them alphabetical, though.
108100
109101### c3: variables and variable naming
110102
111−The C3 style uses Hoon style TLV variable names, with a quasi
112−Hungarian syntax. This is weird, but works really well, as long
113−as what you're doing isn't hideously complicated. (Then it works
114−badly, but we shouldn't need anything hideous in u3.)
103+The C3 style uses Hoon style TLV variable names, with a quasi Hungarian syntax.
104+This is weird, but works really well, as long as what you're doing isn't
105+hideously complicated. (Then it works badly, but we shouldn't need anything
106+hideous in u3.)
115107
116−A TLV variable name is a random pronounceable three-letter
117−string, sometimes with some vague relationship to its meaning,
118−but usually not. Usually CVC (consonant-vowel-consonant) is a
119−good choice.
108+A TLV variable name is a random pronounceable three-letter string, sometimes
109+with some vague relationship to its meaning, but usually not. Usually CVC
110+(consonant-vowel-consonant) is a good choice.
120111
121−You should use TLVs much the way math people use Greek letters.
122−The same concept should in general get the same name across
123−different contexts. When you're working in a given area, you'll
124−tend to remember the binding from TLV to concept by sheer power
125−of associative memory. When you come back to it, it's not that
126−hard to relearn. And of course, when in doubt, comment it.
112+You should use TLVs much the way math people use Greek letters. The same concept
113+should in general get the same name across different contexts. When you're
114+working in a given area, you'll tend to remember the binding from TLV to concept
115+by sheer power of associative memory. When you come back to it, it's not that
116+hard to relearn. And of course, when in doubt, comment it.
127117
128−Variables take pseudo-Hungarian suffixes, matching in general the
129−suffix of the integer type:
118+Variables take pseudo-Hungarian suffixes, matching in general the suffix of the
119+integer type:
130120
131121 c3_w wor_w; // 32-bit word
132122
133−Unlike in standard Hungarian, there is no change for pointer
134−variables. C structure variables take a `_u` suffix.
123+Unlike in standard Hungarian, there is no change for pointer variables. C
124+structure variables take a `_u` suffix.
135125
136126### c3: loobeans
137127
@@ -145,20 +135,19 @@ The code (from `defs.h`) tells the story:
145135 # define c3a(x, y) __(_(x) && _(y))
146136 # define c3o(x, y) __(_(x) || _(y))
147137
148−In short, use `_()` to turn a loobean into a boolean, `__` to go
149−the other way. Use `!` as usual, `c3y` for yes and `c3n` for no,
150−`c3a` for and and `c3o` for or.
138+In short, use `_()` to turn a loobean into a boolean, `__` to go the other way.
139+Use `!` as usual, `c3y` for yes and `c3n` for no, `c3a` for and and `c3o` for
140+or.
151141
152142## u3: land of nouns
153143
154−The division between `c3` and `u3` is that you could theoretically
155−imagine using `c3` as just a generic C environment. Anything to do
156−with nouns is in `u3`.
144+The division between `c3` and `u3` is that you could theoretically imagine using
145+`c3` as just a generic C environment. Anything to do with nouns is in `u3`.
157146
158147### u3: a map of the system
159148
160−There are two kinds of symbols in `u3`: regular and irregular.
161−Regular symbols follow this pattern:
149+There are two kinds of symbols in `u3`: regular and irregular. Regular symbols
150+follow this pattern:
162151
163152 prefix purpose .h .c
164153 -------------------------------------------------------
@@ -178,23 +167,20 @@ Regular symbols follow this pattern:
178167 u3q[a-g] jets (retain, C args) i/j/q.h j/[a-g]/*.c
179168 u3w[a-g] jets (retain, nock core) i/j/w.h j/[a-g]/*.c
180169
181−Irregular symbols always start with `u3` and obey no other rules.
182−They're defined in `i/n/u.h`. Finally, `i/all.h` includes all
183−these headers (fast compilers, yay) and is all you need to
184−program in `u3`.
170+Irregular symbols always start with `u3` and obey no other rules. They're
171+defined in `i/n/u.h`. Finally, `i/all.h` includes all these headers (fast
172+compilers, yay) and is all you need to program in `u3`.
185173
186174### u3: noun internals
187175
188176A noun is a `u3_noun` - currently defined as a 32-bit `c3_w`.
189177
190−If your `u3_noun` is less than `(1 << 31)`, it's a direct atom.
191−Every unsigned integer between `0` and `0x7fffffff` inclusive is
192−its own noun.
178+If your `u3_noun` is less than `(1 << 31)`, it's a direct atom. Every unsigned
179+integer between `0` and `0x7fffffff` inclusive is its own noun.
193180
194−If bit `31` is set in a `u3_noun`, bit `30` is always set - this
195−bit is reserved. Bit `29` is `1` if the noun is a cell, `0` if
196−it's an atom. Bits `28` through `0` are a word pointer into the
197−loom - see below. The structures are:
181+If bit `31` is set in a `u3_noun`, bit `30` is always set - this bit is
182+reserved. Bit `29` is `1` if the noun is a cell, `0` if it's an atom. Bits `28`
183+through `0` are a word pointer into the loom - see below. The structures are:
198184
199185 typedef struct {
200186 c3_w mug_w;
@@ -208,57 +194,53 @@ loom - see below. The structures are:
208194 u3_noun tel;
209195 } u3a_cell;
210196
211−The only thing that should be mysterious here is `mug_w`, which
212−is a 31-bit lazily computed nonzero short hash (FNV currently,
213−soon Murmur3). If `mug_w` is 0, the hash is not yet computed.
214−We also hijack this field for various hacks, such as saving the
215−new address of a noun when copying over.
197+The only thing that should be mysterious here is `mug_w`, which is a 31-bit
198+lazily computed nonzero short hash (FNV currently, soon Murmur3). If `mug_w` is
199+0, the hash is not yet computed. We also hijack this field for various hacks,
200+such as saving the new address of a noun when copying over.
216201
217−Also, the value `0xffffffff` is `u3_none`, which is never a valid
218−noun. Use the type `u3_weak` to express that a noun variable may
219−be `u3_none`.
202+Also, the value `0xffffffff` is `u3_none`, which is never a valid noun. Use the
203+type `u3_weak` to express that a noun variable may be `u3_none`.
220204
221205### u3: reference counts
222206
223−The only really essential thing you need to know about `u3` is
224−how to handle reference counts. Everything else, you can skip
225−and just get to work.
207+The only really essential thing you need to know about `u3` is how to handle
208+reference counts. Everything else, you can skip and just get to work.
226209
227−u3 deals with reference-counted, immutable, acyclic nouns.
228−Unfortunately, we are not Apple and can't build reference
229−counting into your C compiler, so you need to count by hand.
210+u3 deals with reference-counted, immutable, acyclic nouns. Unfortunately, we are
211+not Apple and can't build reference counting into your C compiler, so you need
212+to count by hand.
230213
231−Every allocated noun (or any allocation object, because our
232−allocator is general-purpose) contains a counter which counts the
233−number of references to it - typically variables with type
234−`u3_noun`. When this counter goes to 0, the noun is freed.
214+Every allocated noun (or any allocation object, because our allocator is
215+general-purpose) contains a counter which counts the number of references to it
216+- typically variables with type `u3_noun`. When this counter goes to 0, the noun
217+is freed.
235218
236−To tell `u3` that you've added a reference to a noun, call the
237−function `u3a_gain()` or its shorthand `u3k()`. (For your
238−convenience, this function returns its argument.) To tell `u3`
239−that you've destroyed a reference, call `u3a_lose()` or `u3z()`.
219+To tell `u3` that you've added a reference to a noun, call the function
220+`u3a_gain()` or its shorthand `u3k()`. (For your convenience, this function
221+returns its argument.) To tell `u3` that you've destroyed a reference, call
222+`u3a_lose()` or `u3z()`.
240223
241−(If you screw up by decrementing the counter too much, `u3` will
242−dump core in horrible ways. If you screw up by incrementing it
243−too much, `u3` will leak memory. To check for memory leaks,
244−set the `bug_o` flag in `u3e_boot()` - eg, run `vere` with `-g`.
245−Memory leaks are difficult to debug - the best way to handle
246−leaks is just to revert to a version that didn't have them, and
247−look over your code again.)
224+(If you screw up by decrementing the counter too much, `u3` will dump core in
225+horrible ways. If you screw up by incrementing it too much, `u3` will leak
226+memory. To check for memory leaks, set the `bug_o` flag in `u3e_boot()` - eg,
227+run `vere` with `-g`. Memory leaks are difficult to debug - the best way to
228+handle leaks is just to revert to a version that didn't have them, and look over
229+your code again.)
248230
249−(You can gain or lose a direct atom. It does nothing.)
231+(You can gain or lose a direct atom. It does nothing.)
250232
251233### u3: reference protocols
252234
253235*THIS IS THE MOST CRITICAL SECTION IN THE `u3` DOCUMENTATION.*
254236
255−The key question when calling a C function in a refcounted world
256−is what the function will do to the noun refcounts - and, if the
257−function returns a noun, what it does to the return.
237+The key question when calling a C function in a refcounted world is what the
238+function will do to the noun refcounts - and, if the function returns a noun,
239+what it does to the return.
258240
259−There are two semantic patterns, `transfer` and `retain`. In
260−`transfer` semantics, the caller "gives" a use count to the
261−callee, which "gives back" any return. For instance, if I have
241+There are two semantic patterns, `transfer` and `retain`. In `transfer`
242+semantics, the caller "gives" a use count to the callee, which "gives back" any
243+return. For instance, if I have
262244
263245 {
264246 u3_noun foo = u3i_string("foobar");
@@ -269,14 +251,12 @@ callee, which "gives back" any return. For instance, if I have
269251 u3z(bar);
270252 }
271253
272−Suppose `u3f_futz()` has `transfer` semantics. At `[...]`, my
273−code holds one reference to `bar` and zero references to `foo` -
274−which has been freed, unless it's part of `bar`. My code now
275−owns `bar` and gets to work with it until it's done, at which
276−point a `u3z()` is required.
254+Suppose `u3f_futz()` has `transfer` semantics. At `[...]`, my code holds one
255+reference to `bar` and zero references to `foo` - which has been freed, unless
256+it's part of `bar`. My code now owns `bar` and gets to work with it until it's
257+done, at which point a `u3z()` is required.
277258
278−On the other hand, if `u3f_futz()` has `retain` semantics, we
279−need to write
259+On the other hand, if `u3f_futz()` has `retain` semantics, we need to write
280260
281261 {
282262 u3_noun foo = u3i_string("foobar");
@@ -287,75 +267,71 @@ need to write
287267 u3z(foo);
288268 }
289269
290−because calling `u3f_futz()` does not release our ownership of
291−`foo`, which we have to free ourselves.
270+because calling `u3f_futz()` does not release our ownership of `foo`, which we
271+have to free ourselves.
292272
293−But if we free `bar`, we are making a great mistake, because our
294−reference to it is not in any way registered in the memory
295−manager (which cannot track references in C variables, of
296−course). It is normal and healthy to have these uncounted
297−C references, but they must be treated with care.
273+But if we free `bar`, we are making a great mistake, because our reference to it
274+is not in any way registered in the memory manager (which cannot track
275+references in C variables, of course). It is normal and healthy to have these
276+uncounted C references, but they must be treated with care.
298277
299−The bottom line is that it's essential for the caller to know
300−the refcount semantics of any function which takes or returns a
301−noun. (In some unusual circumstances, different arguments or
302−returns in one function may be handled differently.)
278+The bottom line is that it's essential for the caller to know the refcount
279+semantics of any function which takes or returns a noun. (In some unusual
280+circumstances, different arguments or returns in one function may be handled
281+differently.)
303282
304−Broadly speaking, as a design question, retain semantics are more
305−appropriate for functions which inspect or query nouns. For
306−instance, `u3h()` (which takes the head of a noun) retains, so
307−that we can traverse a noun tree without constantly incrementing
308−and decrementing.
283+Broadly speaking, as a design question, retain semantics are more appropriate
284+for functions which inspect or query nouns. For instance, `u3h()` (which takes
285+the head of a noun) retains, so that we can traverse a noun tree without
286+constantly incrementing and decrementing.
309287
310−Transfer semantics are more appropriate for functions which make
311−nouns, which is obviously what most functions do.
288+Transfer semantics are more appropriate for functions which make nouns, which is
289+obviously what most functions do.
312290
313−In general, though, in most places it's not worth thinking about
314−what your function does. There is a convention for it, which
315−depends on where it is, not what it does. Follow the convention.
291+In general, though, in most places it's not worth thinking about what your
292+function does. There is a convention for it, which depends on where it is, not
293+what it does. Follow the convention.
316294
317295### u3: reference conventions
318−
319−The `u3` convention is that, unless otherwise specified, *all
320−functions have transfer semantics* - with the exception of the
321−prefixes: `u3r`, `u3x`, `u3z`, `u3q` and `u3w`. Also, within
322−jet directories `a` through `f` (but not `g`), internal functions
323−retain (for historical reasons).
324296
325−If functions outside this set have retain semantics, they need to
326−be commented, both in the `.h` and `.c` file, with `RETAIN` in
327−all caps. Yes, it's this important.
297+The `u3` convention is that, unless otherwise specified, *all functions have
298+transfer semantics* - with the exception of the prefixes: `u3r`, `u3x`, `u3z`,
299+`u3q` and `u3w`. Also, within jet directories `a` through `f` (but not `g`),
300+internal functions retain (for historical reasons).
301+
302+If functions outside this set have retain semantics, they need to be commented,
303+both in the `.h` and `.c` file, with `RETAIN` in all caps. Yes, it's this
304+important.
328305
329306### u3: system architecture
330307
331−If you just want to tinker with some existing code, it might be
332−enough to understand the above. If not, it's probably worth
333−taking the time to look at `u3` as a whole.
308+If you just want to tinker with some existing code, it might be enough to
309+understand the above. If not, it's probably worth taking the time to look at
310+`u3` as a whole.
334311
335−`u3` is designed to work as a persistent event processor.
336−Logically, it computes a function of the form
312+`u3` is designed to work as a persistent event processor. Logically, it computes
313+a function of the form
337314
338315 f(event, old state) -> (actions, new state)
339316
340−Obviously almost any computing model - including, but not limited
341−to, Urbit - can be defined in this form. To create the illusion
342−of a computer that never loses state and never fails, we:
317+Obviously almost any computing model - including, but not limited to, Urbit -
318+can be defined in this form. To create the illusion of a computer that never
319+loses state and never fails, we:
343320
344−- log every event externally before it goes into u3
345−- keep a single reference to a permanent state noun.
346−- can abort any event without damaging the permanent state.
347−- snapshot the permanent state periodically, and/or prune logs.
321+- log every event externally before it goes into u3
322+- keep a single reference to a permanent state noun.
323+- can abort any event without damaging the permanent state.
324+- snapshot the permanent state periodically, and/or prune logs.
348325
349326### u3: the road model
350327
351−`u3` uses a memory design which I'm sure someone has invented
352−somewhere before, because it's not very clever, but I've never
353−seen it anywhere in particular.
328+`u3` uses a memory design which I'm sure someone has invented somewhere before,
329+because it's not very clever, but I've never seen it anywhere in particular.
354330
355−Every allocation starts with a solid block of memory, which `u3`
356−calls the `loom`. How do we allocate on the loom? You're
357−probably familiar with the Unix heap-stack design, in which the
358−stack grows downward and the heap (malloc arena) grows upward:
331+Every allocation starts with a solid block of memory, which `u3` calls the
332+`loom`. How do we allocate on the loom? You're probably familiar with the Unix
333+heap-stack design, in which the stack grows downward and the heap (malloc arena)
334+grows upward:
359335
360336 0 brk ffff
361337 | heap | stack |
@@ -363,40 +339,35 @@ stack grows downward and the heap (malloc arena) grows upward:
363339 | | |
364340 0 sp ffff
365341
366−A road is a normal heap-stack system, except that the heap
367−and stack can point in *either direction*. Therefore, inside
368−a road, we can nest another road in the *opposite direction*.
342+A road is a normal heap-stack system, except that the heap and stack can point
343+in *either direction*. Therefore, inside a road, we can nest another road in the
344+*opposite direction*.
369345
370−When the opposite road completes, its heap is left on top of
371−the opposite heap's stack. It's no more than the normal
372−behavior of a stack machine for all subcomputations to push
373−their results on the stack.
346+When the opposite road completes, its heap is left on top of the opposite heap's
347+stack. It's no more than the normal behavior of a stack machine for all
348+subcomputations to push their results on the stack.
374349
375−The performance tradeoff of "leaping" - reversing directions in
376−the road - is that if the outer computation wants to preserve the
377−results of the inner one, not just use them for temporary
378−purposes, it has to *copy them*.
350+The performance tradeoff of "leaping" - reversing directions in the road - is
351+that if the outer computation wants to preserve the results of the inner one,
352+not just use them for temporary purposes, it has to *copy them*.
379353
380−This is a trivial cost in some cases, a prohibitive cost in
381−others. The upside, of course, is that all garbage accrued
382−in the inner computation is discarded at zero cost.
354+This is a trivial cost in some cases, a prohibitive cost in others. The upside,
355+of course, is that all garbage accrued in the inner computation is discarded at
356+zero cost.
383357
384−The goal of the road system is the ability to *layer* memory
385−models. If you are allocating on a road, you have no idea
386−how deep within a nested road system you are - in other words,
387−you have no idea exactly how durable your result may be.
358+The goal of the road system is the ability to *layer* memory models. If you are
359+allocating on a road, you have no idea how deep within a nested road system you
360+are - in other words, you have no idea exactly how durable your result may be.
388361But free space is never fragmented within a road.
389362
390−Roads do not reduce the generality or performance of a memory
391−system, since even the most complex GC system can be nested
392−within a road at no particular loss of performance - a road
393−is just a block of memory.
363+Roads do not reduce the generality or performance of a memory system, since even
364+the most complex GC system can be nested within a road at no particular loss of
365+performance - a road is just a block of memory.
394366
395−Each road (`u3a_road` to be exact) uses four pointers: `rut` is
396−the bottom of the arena, `hat` the top of the arena, `mat` the
397−bottom of the stack, `cap` the top of the stack. (Bear in mind
398−that the road "stack" is not actually used as the C function-call
399−stack, though it probably should be.)
367+Each road (`u3a_road` to be exact) uses four pointers: `rut` is the bottom of
368+the arena, `hat` the top of the arena, `mat` the bottom of the stack, `cap` the
369+top of the stack. (Bear in mind that the road "stack" is not actually used as
370+the C function-call stack, though it probably should be.)
400371
401372A "north" road has the stack high and the heap low:
402373
@@ -414,125 +385,112 @@ A "south" road is the other way around:
414385 | | | |
415386 0 hat rut ffff
416387
417−Legend: `-` is durable storage (heap); `+` is temporary storage
418−(stack); `~` is deep storage (immutable); `$` is the allocation
419−frame `#` is free memory.
388+Legend: `-` is durable storage (heap); `+` is temporary storage (stack); `~` is
389+deep storage (immutable); `$` is the allocation frame `#` is free memory.
420390
421−Pointer restrictions: pointers stored in `+` can point anywhere.
422−Pointers in `-` can only point to `-` or `~`; pointers in `~`
423−only point to `~`.
391+Pointer restrictions: pointers stored in `+` can point anywhere. Pointers in `-`
392+can only point to `-` or `~`; pointers in `~` only point to `~`.
424393
425−To "leap" is to create a new inner road in the `###` free space.
426−but in the reverse direction, so that when the inner road
427−"falls" (terminates), its durable storage is left on the
428−temporary storage of the outer road.
394+To "leap" is to create a new inner road in the `###` free space. but in the
395+reverse direction, so that when the inner road "falls" (terminates), its durable
396+storage is left on the temporary storage of the outer road.
429397
430−`u3` keeps a global variable, `u3_Road` or its alias `u3R`, which
431−points to the current road. (If we ever run threads in inner
432−roads - see below - this will become a thread-local variable.)
433−Relative to `u3R`, `+` memory is called `junior` memory; `-`
434−memory is `normal` memory; `~` is `senior` memory.
398+`u3` keeps a global variable, `u3_Road` or its alias `u3R`, which points to the
399+current road. (If we ever run threads in inner roads - see below - this will
400+become a thread-local variable.) Relative to `u3R`, `+` memory is called
401+`junior` memory; `-` memory is `normal` memory; `~` is `senior` memory.
435402
436403### u3: explaining the road model
437404
438405But... why?
439406
440−We're now ready to understand why the road system works so
441−logically with the event and persistence model.
442−
443−The key is that *we don't update refcounts in senior memory.*
444−A pointer from an inner road to an outer road is not counted.
445−Also, the outmost, or `surface` road, is the only part of the
446−image that gets checkpointed.
447−
448−So the surface road contains the entire durable state of `u3`.
449−When we process an event, or perform any kind of complicated or
450−interesting calculation, *we process it in an inner road*. If
451−its results are saved, they need to be copied.
452−
453−Since processing in an inner road does not touch surface memory,
454−(a) we can leave the surface road in a read-only state and not
455−mark its pages dirty; (b) we can abort an inner calculation
456−without screwing up the surface; and (c) because inner results
457−are copied onto the surface, the surface doesn't get fragmented.
458−
459−All of (a), (b) and (c) are needed for checkpointing to be easy.
460−It might be tractable otherwise, but easy is even better.
461−
462−Moreover, while the surface is most definitely single-threaded,
463−we could easily run multiple threads in multiple inner roads
464−(as long as the threads don't have pointers into each others'
465−memory, which they obviously shouldn't).
466−
467−Moreover, in future, we'll experiment more with adding road
468−control hints to the programmer's toolbox. Reference counting is
469−expensive. We hypothesize that in many - if not most - cases,
470−the programmer can identify procedural structures whose garbage
471−should be discarded in one step by copying the results. Then,
472−within the procedure, we can switch the allocator into `sand`
473−mode, and stop tracking references at all.
407+We're now ready to understand why the road system works so logically with the
408+event and persistence model.
409+
410+The key is that *we don't update refcounts in senior memory.* A pointer from an
411+inner road to an outer road is not counted. Also, the outmost, or `surface`
412+road, is the only part of the image that gets checkpointed.
413+
414+So the surface road contains the entire durable state of `u3`. When we process
415+an event, or perform any kind of complicated or interesting calculation, *we
416+process it in an inner road*. If its results are saved, they need to be copied.
417+
418+Since processing in an inner road does not touch surface memory, (a) we can
419+leave the surface road in a read-only state and not mark its pages dirty; (b) we
420+can abort an inner calculation without screwing up the surface; and (c) because
421+inner results are copied onto the surface, the surface doesn't get fragmented.
422+
423+All of (a), (b) and (c) are needed for checkpointing to be easy. It might be
424+tractable otherwise, but easy is even better.
425+
426+Moreover, while the surface is most definitely single-threaded, we could easily
427+run multiple threads in multiple inner roads (as long as the threads don't have
428+pointers into each others' memory, which they obviously shouldn't).
429+
430+Moreover, in future, we'll experiment more with adding road control hints to the
431+programmer's toolbox. Reference counting is expensive. We hypothesize that in
432+many - if not most - cases, the programmer can identify procedural structures
433+whose garbage should be discarded in one step by copying the results. Then,
434+within the procedure, we can switch the allocator into `sand` mode, and stop
435+tracking references at all.
474436
475437### u3: rules for C programming
476438
477−There are two levels at which we program in C: (1) above the
478−interpreter; (2) within the interpreter or jets. These have
479−separate rules which need to be respected.
439+There are two levels at which we program in C: (1) above the interpreter; (2)
440+within the interpreter or jets. These have separate rules which need to be
441+respected.
480442
481443### u3: rules above the interpreter
482444
483−In its relations with Unix, Urbit follows a strict rule of "call
484−me, I won't call you." We do of course call Unix system calls,
485−but only for the purpose of actually computing.
445+In its relations with Unix, Urbit follows a strict rule of "call me, I won't
446+call you." We do of course call Unix system calls, but only for the purpose of
447+actually computing.
486448
487−Above Urbit, you are in a normal C/Unix programming environment
488−and can call anything in or out of Urbit. Note that when using
489−`u3`, you're always on the surface road, which is not thread-safe
490−by default. Generally speaking, `u3` is designed to support
491−event-oriented, single-threaded programming.
449+Above Urbit, you are in a normal C/Unix programming environment and can call
450+anything in or out of Urbit. Note that when using `u3`, you're always on the
451+surface road, which is not thread-safe by default. Generally speaking, `u3` is
452+designed to support event-oriented, single-threaded programming.
492453
493−If you need threads which create nouns, you could use
494−`u3m_hate()` and `u3m_love()` to run these threads in subroads.
495−You'd need to make the global road pointer, `u3R`, a thread-local
496−variable instead. This seems perfectly practical, but we haven't
497−done it because we haven't needed to.
454+If you need threads which create nouns, you could use `u3m_hate()` and
455+`u3m_love()` to run these threads in subroads. You'd need to make the global
456+road pointer, `u3R`, a thread-local variable instead. This seems perfectly
457+practical, but we haven't done it because we haven't needed to.
498458
499459### u3: rules within the interpreter
500460
501−Within the interpreter, your code can run either in the surface
502−road or in a deep road. You can test this by testing
461+Within the interpreter, your code can run either in the surface road or in a
462+deep road. You can test this by testing
503463
504464 (&u3H->rod_u == u3R)
505465
506466ie: does the pier's home road equal the current road pointer?
507467
508−Normally in this context you assume you're obeying the rules of
509−running on an inner road, ie, "deep memory." Remember, however,
510−that the interpreter *can* run on surface memory - but anything
511−you can do deep, you can do on the surface. The converse is by
512−no means the case.
468+Normally in this context you assume you're obeying the rules of running on an
469+inner road, ie, "deep memory." Remember, however, that the interpreter *can* run
470+on surface memory - but anything you can do deep, you can do on the surface. The
471+converse is by no means the case.
513472
514−In deep memory, think of yourself as if in a signal handler.
515−Your execution context is extremely fragile and may be terminated
516−without warning or cleanup at any time (for instance, by `ctrl-c`).
473+In deep memory, think of yourself as if in a signal handler. Your execution
474+context is extremely fragile and may be terminated without warning or cleanup at
475+any time (for instance, by `ctrl-c`).
517476
518−For instance, you can't call `malloc` (or C++ `new`) in your C
519−code, because you don't have the right to modify data structures
520−at the global level, and will leave them in an inconsistent state
521−if your inner road gets terminated. (Instead, use our drop-in
522−replacements, `u3a_malloc()`, `u3a_free()`, `u3a_realloc()`.)
477+For instance, you can't call `malloc` (or C++ `new`) in your C code, because you
478+don't have the right to modify data structures at the global level, and will
479+leave them in an inconsistent state if your inner road gets terminated.
480+(Instead, use our drop-in replacements, `u3a_malloc()`, `u3a_free()`,
481+`u3a_realloc()`.)
523482
524−A good example is the different meaning of `c3_assert()` inside
525−and outside the interpreter. At either layer, you can use
526−regular assert(), which will just kill your process. On the
527−surface, `c3_assert()` will just... kill your process.
483+A good example is the different meaning of `c3_assert()` inside and outside the
484+interpreter. At either layer, you can use regular assert(), which will just kill
485+your process. On the surface, `c3_assert()` will just... kill your process.
528486
529−In deep execution, `c3_assert()` will issue an exception that
530−queues an error event, complete with trace stack, on the Arvo
531−event queue. Let's see how this happens.
487+In deep execution, `c3_assert()` will issue an exception that queues an error
488+event, complete with trace stack, on the Arvo event queue. Let's see how this
489+happens.
532490
533491### u3: exceptions
534492
535−You produce an exception with
493+You produce an exception with
536494
537495 /* u3m_bail(): bail out. Does not return.
538496 **
@@ -551,82 +509,75 @@ You produce an exception with
551509 c3_i
552510 u3m_bail(c3_m how_m);
553511
554−Broadly speaking, there are two classes of exception: internal
555−and external. An external exception begins in a Unix signal
556−handler. An internal exception begins with a call to longjmp()
557−on the main thread.
512+Broadly speaking, there are two classes of exception: internal and external. An
513+external exception begins in a Unix signal handler. An internal exception begins
514+with a call to longjmp() on the main thread.
558515
559−There are also two kinds of exception: mild and severe. An
560−external exception is always severe. An internal exception is
561−normally mild, but some (like `c3__oops`, generated by
562−`c3_assert()`) are severe.
516+There are also two kinds of exception: mild and severe. An external exception is
517+always severe. An internal exception is normally mild, but some (like
518+`c3__oops`, generated by `c3_assert()`) are severe.
563519
564−Either way, exceptions come with a stack trace. The `u3` nock
565−interpreter is instrumented to retain stack trace hints and
566−produce them as a printable `(list tank)`.
520+Either way, exceptions come with a stack trace. The `u3` nock interpreter is
521+instrumented to retain stack trace hints and produce them as a printable
522+`(list tank)`.
567523
568−Mild exceptions are caught by the first virtualization layer and
569−returned to the caller, following the behavior of the Nock
570−virtualizer `++mock` (in `hoon.hoon`)
524+Mild exceptions are caught by the first virtualization layer and returned to the
525+caller, following the behavior of the Nock virtualizer `++mock` (in `hoon.hoon`)
571526
572−Severe exceptions, or mild exceptions at the surface, terminate
573−the entire execution stack at any depth and send the cumulative
574−trace back to the `u3` caller.
527+Severe exceptions, or mild exceptions at the surface, terminate the entire
528+execution stack at any depth and send the cumulative trace back to the `u3`
529+caller.
575530
576−For instance, `vere` uses this trace to construct a `%crud`
577−event, which conveys our trace back toward the Arvo context where
578−it crashed. This lets any UI component anywhere, even on a
579−remote node, render the stacktrace as a consequence of the user's
580−action - even if its its direct cause was (for instance) a Unix
581−SIGINT or SIGALRM.
531+For instance, `vere` uses this trace to construct a `%crud` event, which conveys
532+our trace back toward the Arvo context where it crashed. This lets any UI
533+component anywhere, even on a remote node, render the stacktrace as a
534+consequence of the user's action - even if its its direct cause was (for
535+instance) a Unix SIGINT or SIGALRM.
582536
583537### u3: C structures on the loom
584538
585−Normally, all data on the loom is nouns. Sometimes we break this
586−rule just a little, though - eg, in the `u3h` hashtables.
539+Normally, all data on the loom is nouns. Sometimes we break this rule just a
540+little, though - eg, in the `u3h` hashtables.
587541
588−To point to non-noun C structs on the loom, we use a `u3_post`,
589−which is just a loom word offset. A macro lets us declare this
590−as if it was a pointer:
542+To point to non-noun C structs on the loom, we use a `u3_post`, which is just a
543+loom word offset. A macro lets us declare this as if it was a pointer:
591544
592545 typedef c3_w u3_post;
593546 #define u3p(type) u3_post
594547
595−Some may regard this as clever, others as pointless. Anyway, use
596−`u3to()` and `u3of()` to convert to and from pointers.
548+Some may regard this as clever, others as pointless. Anyway, use `u3to()` and
549+`u3of()` to convert to and from pointers.
597550
598−When using C structs on the loom - generally a bad idea - make
599−sure anything which could be on the surface road is structurally
600−portable, eg, won't change size when the pointer size changes.
601−(Note also: we consider little-endian, rightly or wrongly, to
602−have won the endian wars.)
551+When using C structs on the loom - generally a bad idea - make sure anything
552+which could be on the surface road is structurally portable, eg, won't change
553+size when the pointer size changes. (Note also: we consider little-endian,
554+rightly or wrongly, to have won the endian wars.)
603555
604556## u3: API overview by prefix
605557
606−Let's run through the `u3` modules one by one. All public
607−functions are commented, but the comments may be cryptic.
558+Let's run through the `u3` modules one by one. All public functions are
559+commented, but the comments may be cryptic.
608560
609561### u3m: main control
610562
611−To start `u3`, run
563+To start `u3`, run
612564
613565 /* u3m_boot(): start the u3 system.
614566 */
615567 void
616568 u3m_boot(c3_o nuu_o, c3_o bug_o, c3_c* dir_c);
617569
618−`nuu_o` is `c3y` (yes, `0`) if you're creating a new pier,
619−`c3n` (no, `1`) if you're loading an existing one. `bug_o`
620−is `c3y` if you want to test the garbage-collector, `c3n`
621−otherwise. `dir_c` is the directory for the pier files.
570+`nuu_o` is `c3y` (yes, `0`) if you're creating a new pier, `c3n` (no, `1`) if
571+you're loading an existing one. `bug_o` is `c3y` if you want to test the
572+garbage-collector, `c3n` otherwise. `dir_c` is the directory for the pier files.
622573
623−`u3m_boot()` expects an `urbit.pill` file to load the kernel
624−from. It will try first `$dir/.urb.urbit.pill`, then `U3_LIB`.
574+`u3m_boot()` expects an `urbit.pill` file to load the kernel from. It will try
575+first `$dir/.urb.urbit.pill`, then `U3_LIB`.
625576
626−Any significant computation with nouns, certainly anything Turing
627−complete, should be run (a) virtualized and (b) in an inner road.
628−These are slightly different things, but at the highest level we
629−bundle them together for your convenience, in `u3m_soft()`:
577+Any significant computation with nouns, certainly anything Turing complete,
578+should be run (a) virtualized and (b) in an inner road. These are slightly
579+different things, but at the highest level we bundle them together for your
580+convenience, in `u3m_soft()`:
630581
631582 /* u3m_soft(): system soft wrapper. unifies unix and nock errors.
632583 **
@@ -635,175 +586,160 @@ bundle them together for your convenience, in `u3m_soft()`:
635586 u3_noun
636587 u3m_soft(c3_w sec_w, u3_funk fun_f, u3_noun arg);
637588
638−`sec_w` is the number of seconds to time out the computation.
639−`fun_f` is a C function accepting `arg`.
640−
641−The result of `u3m_soft()` is a cell whose head is an atom. If
642−the head is `%$` - ie, `0` - the tail is the result of
643−`fun_f(arg)`. Otherwise, the head is a `term` (an atom which is
644−an LSB first string), and the tail is a `(list tank)` (a list of
645−`tank` printables - see `++tank` in `hoon.hoon`). Error terms
646−should be the same as the exception terms above.
647−
648−If you're confident that your computation won't fail, you can
649−use `u3m_soft_sure()`, `u3m_soft_slam()`, or `u3m_soft_nock()`
650−for C functions, Hoon function calls, and Nock invocations.
651−Caution - this returns just the result, and asserts globally.
652−
653−All the `u3m_soft` functions above work *only on the surface*.
654−Within the surface, virtualize with `u3m_soft_run()`. Note that
655−this takes a `fly` (a namespace gate), thus activating the `11`
656−super-operator in the nock virtualizer, `++mock`. When actually
657−using the `fly`, call `u3m_soft_esc()`. Don't do either unless
658−you know what you're doing!
659−
660−For descending into a subroad *without* Nock virtualization,
661−use `u3m_hate()` and `u3m_love` respectively. Hating enters
662−a subroad; loving leaves it, copying out a product noun.
663−
664−Other miscellaneous tools in `u3m`: `u3m_file()` loads a Unix
665−file as a Nock atom; `u3m_water()` measures the boundaries of
666−the loom in current use (ie, watermarks); and a variety of
667−prettyprinting routines, none perfect, are available, mainly for
668−debugging printfs: `u3m_pretty()`, `u3m_p()`, `u3m_tape()` and
669−`u3m_wall()`.
670−
671−It's sometimes nice to run a mark-and-sweep garbage collector,
672−`u3m_grab()`, which collects the world from a list of roots,
673−and asserts if it finds any leaks or incorrect refcounts. This
674−tool is for debugging and long-term maintenance only; refcounts
675−should never err.
589+`sec_w` is the number of seconds to time out the computation. `fun_f` is a C
590+function accepting `arg`.
591+
592+The result of `u3m_soft()` is a cell whose head is an atom. If the head is `%$`
593+- ie, `0` - the tail is the result of `fun_f(arg)`. Otherwise, the head is a
594+`term` (an atom which is an LSB first string), and the tail is a `(list tank)`
595+(a list of `tank` printables - see `++tank` in `hoon.hoon`). Error terms should
596+be the same as the exception terms above.
597+
598+If you're confident that your computation won't fail, you can use
599+`u3m_soft_sure()`, `u3m_soft_slam()`, or `u3m_soft_nock()` for C functions, Hoon
600+function calls, and Nock invocations. Caution - this returns just the result,
601+and asserts globally.
602+
603+All the `u3m_soft` functions above work *only on the surface*. Within the
604+surface, virtualize with `u3m_soft_run()`. Note that this takes a `fly` (a
605+namespace gate), thus activating the `11` super-operator in the nock
606+virtualizer, `++mock`. When actually using the `fly`, call `u3m_soft_esc()`.
607+Don't do either unless you know what you're doing!
608+
609+For descending into a subroad *without* Nock virtualization, use `u3m_hate()`
610+and `u3m_love` respectively. Hating enters a subroad; loving leaves it, copying
611+out a product noun.
612+
613+Other miscellaneous tools in `u3m`: `u3m_file()` loads a Unix file as a Nock
614+atom; `u3m_water()` measures the boundaries of the loom in current use (ie,
615+watermarks); and a variety of prettyprinting routines, none perfect, are
616+available, mainly for debugging printfs: `u3m_pretty()`, `u3m_p()`, `u3m_tape()`
617+and `u3m_wall()`.
618+
619+It's sometimes nice to run a mark-and-sweep garbage collector, `u3m_grab()`,
620+which collects the world from a list of roots, and asserts if it finds any leaks
621+or incorrect refcounts. This tool is for debugging and long-term maintenance
622+only; refcounts should never err.
676623
677624### u3j: jets
678625
679−The jet system, `u3j`, is what makes `u3` and `nock` in any sense
680−a useful computing environment. Except perhaps `u3a` (there is
681−really no such thing as a trivial allocator, though `u3a` is
682−dumber than most) - `u3j` is the most interesting code in `u3`.
626+The jet system, `u3j`, is what makes `u3` and `nock` in any sense a useful
627+computing environment. Except perhaps `u3a` (there is really no such thing as a
628+trivial allocator, though `u3a` is dumber than most) - `u3j` is the most
629+interesting code in `u3`.
683630
684−Let's consider the minor miracle of driver-to-battery binding
685−which lets `u3j` work - and decrement not be `O(n)` - without
686−violating the precisely defined semantics of pure Nock, *ever*.
631+Let's consider the minor miracle of driver-to-battery binding which lets `u3j`
632+work - and decrement not be `O(n)` - without violating the precisely defined
633+semantics of pure Nock, *ever*.
687634
688−It's easy to assume that jets represent an architectural coupling
689−between Hoon language semantics and Nock interpreter internals.
690−Indeed such a coupling would be wholly wrongtious and un-Urbit.
691−But the jet system is not Hoon-specific. It is specific to nock
692−runtime systems that use a design pattern we call a `core`.
635+It's easy to assume that jets represent an architectural coupling between Hoon
636+language semantics and Nock interpreter internals. Indeed such a coupling would
637+be wholly wrongtious and un-Urbit. But the jet system is not Hoon-specific. It
638+is specific to nock runtime systems that use a design pattern we call a `core`.
693639
694640#### u3j: core structure
695641
696−A core is no more than a cell `[code data]`, in which a `code` is
697−either a Nock formula or a cell of `code`s, and `data` is anything.
698−In a proper core, the subject each formula expects is the core
699−itself.
700−
701−Except for the arbitrary decision to make a core `[code data]`,
702−(or as we sometimes say, `[battery payload]`), instead of `[data
703−code]`, any high-level language transforming itself to Nock would
704−use this design.
705−
706−So jets are in fact fully general. Broadly speaking, the jet
707−system works by matching a C *driver* to a battery. When the
708−battery is invoked with Nock operator `9`, it must be found in
709−associative memory and linked to its driver. Then we link the
710−formula axis of the operation (`a` in `[9 a b]`) to a specific
642+A core is no more than a cell `[code data]`, in which a `code` is either a Nock
643+formula or a cell of `code`s, and `data` is anything. In a proper core, the
644+subject each formula expects is the core itself.
645+
646+Except for the arbitrary decision to make a core `[code data]`, (or as we
647+sometimes say, `[battery payload]`), instead of `[data code]`, any high-level
648+language transforming itself to Nock would use this design.
649+
650+So jets are in fact fully general. Broadly speaking, the jet system works by
651+matching a C *driver* to a battery. When the battery is invoked with Nock
652+operator `9`, it must be found in associative memory and linked to its driver.
653+Then we link the formula axis of the operation (`a` in `[9 a b]`) to a specific
711654function in the driver.
712655
713−To validate this jet binding, we need to know two things. One,
714−we need to know the C function actually is a perfect semantic
715−match for the Nock formula. This can be developed with driver
716−test flags, which work, and locked down with a secure formula
717−hash in the driver, which we haven't bothered with just yet.
718−(You could also try to develop a formal method for verifying
719−that C functions and Nock formulas are equivalent, but this is
720−a research problem for the future.)
721−
722−Two, we need to validate that the payload is appropriate for the
723−battery. We should note that jets are a Nock feature and have no
724−reference to Hoon. A driver which relies on the Hoon type system
725−to only pair it with valid payloads is a broken driver, and
726−breaks the Nock compliance of the system as a whole. So don't.
727−
728−Now, a casual observer might look at `[battery payload]` and
729−expect the simplest case of it to be `[formula subject]`. That
730−is: to execute a simple core whose battery is a single formula,
731−we compute
656+To validate this jet binding, we need to know two things. One, we need to know
657+the C function actually is a perfect semantic match for the Nock formula. This
658+can be developed with driver test flags, which work, and locked down with a
659+secure formula hash in the driver, which we haven't bothered with just yet. (You
660+could also try to develop a formal method for verifying that C functions and
661+Nock formulas are equivalent, but this is a research problem for the future.)
662+
663+Two, we need to validate that the payload is appropriate for the battery. We
664+should note that jets are a Nock feature and have no reference to Hoon. A driver
665+which relies on the Hoon type system to only pair it with valid payloads is a
666+broken driver, and breaks the Nock compliance of the system as a whole. So
667+don't.
668+
669+Now, a casual observer might look at `[battery payload]` and expect the simplest
670+case of it to be `[formula subject]`. That is: to execute a simple core whose
671+battery is a single formula, we compute
732672
733673 nock(+.a -.a)
734674
735−Then, naturally, when we go from Hoon or a high-level language
736−containing functions down to Nock, `[function arguments]` turns
737−into `[formula subject]`. This seems like an obvious design, and
738−we mention it only because it is *completely wrong*.
675+Then, naturally, when we go from Hoon or a high-level language containing
676+functions down to Nock, `[function arguments]` turns into `[formula subject]`.
677+This seems like an obvious design, and we mention it only because it is
678+*completely wrong*.
739679
740680Rather, to execute a one-armed core like the above, we run
741681
742682 nock(a -.a)
743683
744−and the normal structure of a `gate`, which is simply Urbitese
745−for "function," is:
684+and the normal structure of a `gate`, which is simply Urbitese for "function,"
685+is:
746686
747687 [formula [sample context]]
748688
749−where `sample` is Urbitese for "arguments" - and `context`, any
750−Lisper will at once recognize, is Urbitese for "environment."
689+where `sample` is Urbitese for "arguments" - and `context`, any Lisper will at
690+once recognize, is Urbitese for "environment."
751691
752−To `slam` or call the gate, we simply replace the default sample
753−with the caller's data, then nock the formula on the entire gate.
692+To `slam` or call the gate, we simply replace the default sample with the
693+caller's data, then nock the formula on the entire gate.
754694
755−What's in the context? Unlike in most dynamic languages, it is
756−not some secret system-level bag of tricks. Almost always it is
757−another core. This onion continues until at the bottom, there is
758−an atomic constant, conventionally is the kernel version number.
695+What's in the context? Unlike in most dynamic languages, it is not some secret
696+system-level bag of tricks. Almost always it is another core. This onion
697+continues until at the bottom, there is an atomic constant, conventionally is
698+the kernel version number.
759699
760700Thus a (highly desirable) `static` core is one of the form
761701
762702 [battery constant]
763703 [battery static-core]
764704
765−ie, a solid stack of nested libraries without any dynamic data.
766−The typical gate will thus be, for example,
705+ie, a solid stack of nested libraries without any dynamic data. The typical gate
706+will thus be, for example,
767707
768708 [formula [sample [battery battery battery constant]]]
769709
770−but we would be most foolish to restrict the jet mechanism to
771−cores of this particular structure. We cannot constrain a
772−payload to be `[sample static-core]`, or even `[sample core]`.
773−Any such constraint would not be rich enough to handle Hoon,
774−let alone other languages.
710+but we would be most foolish to restrict the jet mechanism to cores of this
711+particular structure. We cannot constrain a payload to be
712+`[sample static-core]`, or even `[sample core]`. Any such constraint would not
713+be rich enough to handle Hoon, let alone other languages.
775714
776715#### u3j: jet state
777716
778−There are two fundamental rules of computer science: (1) every
779−system is best understood through its state; (2) less state is
780−better than more state. Sadly, a pier has three different jet
781−state systems: `cold`, `warm` and `hot`. It needs all of them.
717+There are two fundamental rules of computer science: (1) every system is best
718+understood through its state; (2) less state is better than more state. Sadly, a
719+pier has three different jet state systems: `cold`, `warm` and `hot`. It needs
720+all of them.
782721
783−Hot state is associated with this particular Unix process. The
784−persistent pier is portable not just between process and process,
785−but machine and machine or OS and OS. The set of jets loaded
786−into a pier may itself change (in theory, though not in the
787−present implementation) during the lifetime of the process. Hot
788−state is a pure C data structure.
722+Hot state is associated with this particular Unix process. The persistent pier
723+is portable not just between process and process, but machine and machine or OS
724+and OS. The set of jets loaded into a pier may itself change (in theory, though
725+not in the present implementation) during the lifetime of the process. Hot state
726+is a pure C data structure.
789727
790−Cold state is associated with the logical execution history of
791−the pier. It consists entirely of nouns and ignores restarts.
728+Cold state is associated with the logical execution history of the pier. It
729+consists entirely of nouns and ignores restarts.
792730
793−Warm state contains all dependencies between cold and hot
794−state. It consists of C structures allocated on the loom.
731+Warm state contains all dependencies between cold and hot state. It consists of
732+C structures allocated on the loom.
795733
796−Warm state is purely a function of cold and hot states, and
797−we can wipe and regenerate it at any time. On any restart where
798−the hot state might have changed, we clear the warm state
799−with `u3j_ream()`.
734+Warm state is purely a function of cold and hot states, and we can wipe and
735+regenerate it at any time. On any restart where the hot state might have
736+changed, we clear the warm state with `u3j_ream()`.
800737
801−There is only one hot state, the global jet dashboard
802−`u3j_Dash` or `u3D` for short. In the present implementation,
803−u3D is a static structure not modified at runtime, except for
804−numbering itself on process initialization. This structure -
805−which embeds function pointers to all the jets - is defined
806−in `j/tree.c`. The data structures:
738+There is only one hot state, the global jet dashboard `u3j_Dash` or `u3D` for
739+short. In the present implementation, u3D is a static structure not modified at
740+runtime, except for numbering itself on process initialization. This structure -
741+which embeds function pointers to all the jets - is defined in `j/tree.c`. The
742+data structures:
807743
808744 /* u3j_harm: driver arm.
809745 */
@@ -834,16 +770,16 @@ in `j/tree.c`. The data structures:
834770 u3j_core* ray_u; // dynamic driver array
835771 } u3j_dash;
836772
837−Warm and cold state is *per road*. In other words, as we nest
838−roads, we also nest jet state. The jet state in the road is:
773+Warm and cold state is *per road*. In other words, as we nest roads, we also
774+nest jet state. The jet state in the road is:
839775
840776 struct { // jet dashboard
841777 u3p(u3h_root) har_p; // warm state
842778 u3_noun das; // cold state
843779 } jed;
844780
845−In case you understand Hoon, `das` (cold state) is a `++dash`,
846−and `har_p` (warm state) is a map from battery to `++calx`:
781+In case you understand Hoon, `das` (cold state) is a `++dash`, and `har_p` (warm
782+state) is a map from battery to `++calx`:
847783
848784 ++ bane ,@tas :: battery name
849785 ++ bash ,@uvH :: label hash
@@ -863,323 +799,288 @@ and `har_p` (warm state) is a map from battery to `++calx`:
863799 ++ corp (each core batt) :: parent or static
864800 ++ dash (map bash clog) :: jet system
865801
866−The driver index `jax` in a `++calx` is an index into `ray_u` in the
867−dashboard - ie, a pointer into hot state. This is why the warm
868−state has to be reset when we reload the pier in a new process.
802+The driver index `jax` in a `++calx` is an index into `ray_u` in the dashboard -
803+ie, a pointer into hot state. This is why the warm state has to be reset when we
804+reload the pier in a new process.
869805
870−Why is jet state nested? Nock of course is a functional system,
871−so as we compute we don't explicitly create state. Jet state is
872−an exception to this principle (which works only because it can't
873−be semantically detected from Nock/Hoon) - but it can't violate
874−the fundamental rules of the allocation system.
806+Why is jet state nested? Nock of course is a functional system, so as we compute
807+we don't explicitly create state. Jet state is an exception to this principle
808+(which works only because it can't be semantically detected from Nock/Hoon) -
809+but it can't violate the fundamental rules of the allocation system.
875810
876−For instance, when we're on an inner road, we can't allocate on
877−an outer road, or point from an outer road to an inner. So if we
878−learn something - like a mapping from battery to jet - in the
879−inner road, we have to keep it in the inner road.
811+For instance, when we're on an inner road, we can't allocate on an outer road,
812+or point from an outer road to an inner. So if we learn something - like a
813+mapping from battery to jet - in the inner road, we have to keep it in the inner
814+road.
880815
881−Mitigating this problem, when we leave an inner road (with
882−`u3m_love()`), we call `u3j_reap()` to promote jet information in
883−the dying road. Reaping promotes anything we've learned about
884−any battery that either (a) already existed in the outer road, or
885−(b) is being saved to the outer road.
816+Mitigating this problem, when we leave an inner road (with `u3m_love()`), we
817+call `u3j_reap()` to promote jet information in the dying road. Reaping promotes
818+anything we've learned about any battery that either (a) already existed in the
819+outer road, or (b) is being saved to the outer road.
886820
887821#### u3j: jet binding
888822
889−Jet binding starts with a `%fast` hint. (In Hoon, this is
890−produced by the runes `~%`, for the general case, or `~/`
891−for simple functions.) To bind a jet, execute a formula of the
892−form:
823+Jet binding starts with a `%fast` hint. (In Hoon, this is produced by the runes
824+`~%`, for the general case, or `~/` for simple functions.) To bind a jet,
825+execute a formula of the form:
893826
894827 [10 [%fast clue-formula] core-formula]
895828
896−`core-formula` assembles the core to be jet-propelled.
897−`clue-formula` produces the hint information, or `++clue`
898−above, which we want to annotate it with.
829+`core-formula` assembles the core to be jet-propelled. `clue-formula` produces
830+the hint information, or `++clue` above, which we want to annotate it with.
899831
900832A clue is a triple of name, parent, and hooks:
901833
902834 ++ clue (trel chum nock (list (pair term nock)))
903835
904−The name, or `++chum`, has a bunch of historical structure which
905−we don't need (cleaning these things up is tricky), but just gets
906−flattened into a term.
836+The name, or `++chum`, has a bunch of historical structure which we don't need
837+(cleaning these things up is tricky), but just gets flattened into a term.
907838
908−The parent axis is a nock formula, but always reduces to a simple
909−axis, which is the address of this core's *parent*. Consider
910−again an ordinary gate
839+The parent axis is a nock formula, but always reduces to a simple axis, which is
840+the address of this core's *parent*. Consider again an ordinary gate
911841
912842 [formula [sample context]]
913843
914−Typically the `context` is itself a library core, which itself
915−has a jet binding. If so, the parent axis of this gate is `7`.
844+Typically the `context` is itself a library core, which itself has a jet
845+binding. If so, the parent axis of this gate is `7`.
916846
917−If the parent is already bound - and the parent *must* be already
918−bound, in this road or a road containing it - we can hook this core
919−bottom-up into a tree hierarchy. Normally the child core is
920−produced by an arm of the parent core, so this is not a problem -
921−we wouldn't have the child if we hadn't already made the parent.
847+If the parent is already bound - and the parent *must* be already bound, in this
848+road or a road containing it - we can hook this core bottom-up into a tree
849+hierarchy. Normally the child core is produced by an arm of the parent core, so
850+this is not a problem - we wouldn't have the child if we hadn't already made the
851+parent.
922852
923−The clue also contains a list of *hooks*, named nock formulas on
924−the core. Usually these are arms, but they need not be. The
925−point is that we often want to call a core from C, in a situation
926−where we have no type or other source information. A common case
927−of this is a complex system in which we're mixing functions which
928−are jet-propelled with functions that aren't.
853+The clue also contains a list of *hooks*, named nock formulas on the core.
854+Usually these are arms, but they need not be. The point is that we often want to
855+call a core from C, in a situation where we have no type or other source
856+information. A common case of this is a complex system in which we're mixing
857+functions which are jet-propelled with functions that aren't.
929858
930−In any case, all the information in the `%fast` hint goes to
931−`u3j_mine()`, which registers the battery in cold state (`das` in
932−`jed` in `u3R`), then warm state (`har_p` in `jed`).
859+In any case, all the information in the `%fast` hint goes to `u3j_mine()`, which
860+registers the battery in cold state (`das` in `jed` in `u3R`), then warm state
861+(`har_p` in `jed`).
933862
934−It's essential to understand that the `%fast` hint has to be,
935−well, fast - because we apply it whenever we build a core. For
936−instance, if the core is a Hoon gate - a function - we will call
937−`u3j_mine` every time the function is called.
863+It's essential to understand that the `%fast` hint has to be, well, fast -
864+because we apply it whenever we build a core. For instance, if the core is a
865+Hoon gate - a function - we will call `u3j_mine` every time the function is
866+called.
938867
939868### u3j: the cold jet dashboard
940869
941−For even more fun, the jet tree is not actually a tree of
942−batteries. It's a tree of battery *labels*, where a label is
943−an [axis term] path from the root of the tree. (At the root,
944−if the core pattern is always followed properly, is a core whose
945−payload is an atomic constant, conventionally the Hoon version.)
870+For even more fun, the jet tree is not actually a tree of batteries. It's a tree
871+of battery *labels*, where a label is an \[axis term\] path from the root of the
872+tree. (At the root, if the core pattern is always followed properly, is a core
873+whose payload is an atomic constant, conventionally the Hoon version.)
946874
947−Under each of these labels, it's normal to have an arbitrary
948−number of different Nock batteries (not just multiple copies
949−of the same noun, a situation we *do* strive to avoid). For
950−instance, one might be compiled with debugging hints, one not.
875+Under each of these labels, it's normal to have an arbitrary number of different
876+Nock batteries (not just multiple copies of the same noun, a situation we *do*
877+strive to avoid). For instance, one might be compiled with debugging hints, one
878+not.
951879
952−We might even have changed the semantics of the battery without
953−changing the label - so long as those semantics don't invalidate
954−any attached driver.
880+We might even have changed the semantics of the battery without changing the
881+label - so long as those semantics don't invalidate any attached driver.
955882
956−For instance, it's normal to have two equivalent Nock batteries
957−at the same time in one pier: one battery compiled with
958−debugging hints, one not.
883+For instance, it's normal to have two equivalent Nock batteries at the same time
884+in one pier: one battery compiled with debugging hints, one not.
959885
960−Rather, the jet tree is a semantic hierarchy. The root of the
961−hierarchy is a constant, by convention the Hoon kernel version
962−because any normal jet-propelled core has, at the bottom of its
963−onion of libraries, the standard kernel. Thus if the core is
886+Rather, the jet tree is a semantic hierarchy. The root of the hierarchy is a
887+constant, by convention the Hoon kernel version because any normal jet-propelled
888+core has, at the bottom of its onion of libraries, the standard kernel. Thus if
889+the core is
964890
965891 [foo-battery [bar-battery [moo-battery 164]]]
966892
967−we can reverse the nesting to construct a hierarchical core
968−path. The static core
893+we can reverse the nesting to construct a hierarchical core path. The static
894+core
969895
970896 164/moo/bar/foo
971897
972−extends the static core `164/moo/bar` by wrapping the `foo`
973−battery (ie, in Hoon, `|%`) around it. With the core above,
974−you can compute `foo` stuff, `bar` stuff, and `moo` stuff.
975−Rocket science, not.
976−
977−Not all cores are static, of course - they may contain live data,
978−like the sample in a gate (ie, argument to a function). Once
979−again, it's important to remember that we track jet bindings not
980−by the core, which may not be static, but by the battery, which
981−is always static.
982−
983−(And if you're wondering how we can use a deep noun like a Nock
984−formula or battery as a key in a key-value table, remember
985−`mug_w`, the lazily computed short hash, in all boxed nouns.)
986−
987−In any case, `das`, the dashboard, is a map from `bash` to jet
988−location record (`++clog`). A `clog` in turn contains two kinds
989−of information: the `++cope`, or per-location noun; and a map of
990−batteries to a per-battery `++club`.
991−
992−The `cope` is a triple of `++bane` (battery name, right now just
993−a `term`); `++axis`, the axis, within *this* core, of the parent;
994−and `(each bash noun)`, which is either `[0 bash]` if the parent
995−is another core, or `[1 noun]`, for the constant noun (like
996−`164`) if there is no parent core.
997−
998−A `bash` is just the noun hash (`++sham`) of a `cope`, which
999−uniquely expresses the battery's hierarchical location without
1000−depending on the actual formulas.
1001−
1002−The `club` contains a `++corp`, which we use to actually validate
1003−the core. Obviously jet execution has to be perfectly compatible
1004−with Nock. We search on the battery, but getting the battery
1005−right is not enough - a typical battery is dependent on its
1006−context. For example, your jet-propelled library function is
1007−very likely to call `++dec` or other advanced kernel technology.
1008−If you've replaced the kernel in your context with something
1009−else, we need to detect this and not run the jet.
1010−
1011−There are two cases for a jet-propelled core - either the entire
1012−core is a static constant, or it isn't. Hence the definition
1013−of `corp`:
898+extends the static core `164/moo/bar` by wrapping the `foo` battery (ie, in
899+Hoon, `|%`) around it. With the core above, you can compute `foo` stuff, `bar`
900+stuff, and `moo` stuff. Rocket science, not.
901+
902+Not all cores are static, of course - they may contain live data, like the
903+sample in a gate (ie, argument to a function). Once again, it's important to
904+remember that we track jet bindings not by the core, which may not be static,
905+but by the battery, which is always static.
906+
907+(And if you're wondering how we can use a deep noun like a Nock formula or
908+battery as a key in a key-value table, remember `mug_w`, the lazily computed
909+short hash, in all boxed nouns.)
910+
911+In any case, `das`, the dashboard, is a map from `bash` to jet location record
912+(`++clog`). A `clog` in turn contains two kinds of information: the `++cope`, or
913+per-location noun; and a map of batteries to a per-battery `++club`.
914+
915+The `cope` is a triple of `++bane` (battery name, right now just a `term`);
916+`++axis`, the axis, within *this* core, of the parent; and `(each bash noun)`,
917+which is either `[0 bash]` if the parent is another core, or `[1 noun]`, for the
918+constant noun (like `164`) if there is no parent core.
919+
920+A `bash` is just the noun hash (`++sham`) of a `cope`, which uniquely expresses
921+the battery's hierarchical location without depending on the actual formulas.
922+
923+The `club` contains a `++corp`, which we use to actually validate the core.
924+Obviously jet execution has to be perfectly compatible with Nock. We search on
925+the battery, but getting the battery right is not enough - a typical battery is
926+dependent on its context. For example, your jet-propelled library function is
927+very likely to call `++dec` or other advanced kernel technology. If you've
928+replaced the kernel in your context with something else, we need to detect this
929+and not run the jet.
930+
931+There are two cases for a jet-propelled core - either the entire core is a
932+static constant, or it isn't. Hence the definition of `corp`:
1014933
1015934 ++ corp (each core batt) :: parent or static
1016935
1017−Ie, a `corp` is `[0 core]` or `[1 batt]`. If it's static -
1018−meaning that the jet only works with one specific core, ie, the
1019−parent axis of each location in the hierarchy is `3` - we can
1020−validate with a single comparison. Otherwise, we have to recurse
1021−upward by checking the parent.
936+Ie, a `corp` is `[0 core]` or `[1 batt]`. If it's static - meaning that the jet
937+only works with one specific core, ie, the parent axis of each location in the
938+hierarchy is `3` - we can validate with a single comparison. Otherwise, we have
939+to recurse upward by checking the parent.
1022940
1023−Note that there is at present no way to force a jet to depend on
1024−static *data*.
941+Note that there is at present no way to force a jet to depend on static *data*.
1025942
1026943### u3j: the warm jet dashboard
1027944
1028−We don't use the cold state to match jets as we call them. We
1029−use the cold state to register jets as we find them, and also to
1030−rebuild the warm state after the hot state is reset.
945+We don't use the cold state to match jets as we call them. We use the cold state
946+to register jets as we find them, and also to rebuild the warm state after the
947+hot state is reset.
1031948
1032−What we actually use at runtime is the warm state, `jed->har_p`,
1033−which is a `u3h` (built-in hashtable), allocated on the loom,
1034−from battery to `++calx`.
949+What we actually use at runtime is the warm state, `jed->har_p`, which is a
950+`u3h` (built-in hashtable), allocated on the loom, from battery to `++calx`.
1035951
1036−A `calx` is a triple of a `++calf`, a `[bash cope]` cell, and a
1037−`club`. The latter two are all straight from cold state.
952+A `calx` is a triple of a `++calf`, a `[bash cope]` cell, and a `club`. The
953+latter two are all straight from cold state.
1038954
1039−The `calf` contains warm data dependent on hot state. It's a
1040−quadruple: of `jax`, the hot driver index (in `ray_u` in
1041−`u3j_dash`); `hap`, a table from arm axis (ie, the axis of each
1042−formula within the battery) to driver arm index (into `arm_u` in
1043−`u3j_core`); `lab`, the complete label path; and `jit`, any
1044−other dynamic data that may speed up execution.
955+The `calf` contains warm data dependent on hot state. It's a quadruple: of
956+`jax`, the hot driver index (in `ray_u` in `u3j_dash`); `hap`, a table from arm
957+axis (ie, the axis of each formula within the battery) to driver arm index (into
958+`arm_u` in `u3j_core`); `lab`, the complete label path; and `jit`, any other
959+dynamic data that may speed up execution.
1045960
1046−We construct `hap`, when we create the calx, by iterating through
1047−the arms registered in the `u3j_core`. Note the way a `u3j_harm`
1048−declares itself, with the string `fcs_c` which can contain either
1049−an axis or a name. Most jetted cores are of course gates, which
1050−have one formula at one axis within the core: `fcs_c` is `".3"`.
961+We construct `hap`, when we create the calx, by iterating through the arms
962+registered in the `u3j_core`. Note the way a `u3j_harm` declares itself, with
963+the string `fcs_c` which can contain either an axis or a name. Most jetted cores
964+are of course gates, which have one formula at one axis within the core: `fcs_c`
965+is `".3"`.
1051966
1052−But we do often have fast cores with more complex arm structure,
1053−and it would be sad to have to manage their axes by hand. To use
1054−an `fcs_c` with a named arm, it's sufficient to make sure the
1055−name is bound to a formula `[0 axis]` in the hook table.
967+But we do often have fast cores with more complex arm structure, and it would be
968+sad to have to manage their axes by hand. To use an `fcs_c` with a named arm,
969+it's sufficient to make sure the name is bound to a formula `[0 axis]` in the
970+hook table.
1056971
1057−`jit`, as its name suggests, is a stub where any sort of
1058−optimization data computed on battery registration might go. To
1059−use it, fill in the `_cj_jit()` function.
972+`jit`, as its name suggests, is a stub where any sort of optimization data
973+computed on battery registration might go. To use it, fill in the `_cj_jit()`
974+function.
1060975
1061976### u3j: the hot dashboard
1062977
1063−Now it should be easy to see how we actually invoke jets. Every
1064−time we run a nock `9` instruction (pretty often, obviously), we
1065−have a core and an axis. We pass these to `u3j_kick()`, which
1066−will try to execute them.
978+Now it should be easy to see how we actually invoke jets. Every time we run a
979+nock `9` instruction (pretty often, obviously), we have a core and an axis. We
980+pass these to `u3j_kick()`, which will try to execute them.
1067981
1068−Because nouns with a reference count of 1 are precious,
1069−`u3j_kick()` has a tricky reference control definition. It
1070−reserves the right to return `u3_none` in the case where there is
1071−no driver, or the driver does not apply for this case; in this
1072−case, it retains argument `cor`. If it succeeds, though, it
982+Because nouns with a reference count of 1 are precious, `u3j_kick()` has a
983+tricky reference control definition. It reserves the right to return `u3_none`
984+in the case where there is no driver, or the driver does not apply for this
985+case; in this case, it retains argument `cor`. If it succeeds, though, it
1073986transfers `cor`.
1074987
1075−`u3j_kick()` searches for the battery (always the head of the
1076−core, of course) in the hot dashboard. If the battery is
1077−registered, it searches for the axis in `hap` in the `calx`.
1078−If it exists, the core matches a driver and the driver jets this
1079−arm. If not, we return `u3_none`.
988+`u3j_kick()` searches for the battery (always the head of the core, of course)
989+in the hot dashboard. If the battery is registered, it searches for the axis in
990+`hap` in the `calx`. If it exists, the core matches a driver and the driver jets
991+this arm. If not, we return `u3_none`.
1080992
1081−Otherwise, we call `fun_f` in our `u3j_harm`. This obeys the
1082−same protocol as `u3j_kick()`; it can refuse to function by
1083−returning `u3_none`, or consume the noun.
993+Otherwise, we call `fun_f` in our `u3j_harm`. This obeys the same protocol as
994+`u3j_kick()`; it can refuse to function by returning `u3_none`, or consume the
995+noun.
1084996
1085−Besides the actual function pointer `fun_f`, we have some flags
1086−in the `u3j_harm` which tell us how to call the arm function.
997+Besides the actual function pointer `fun_f`, we have some flags in the
998+`u3j_harm` which tell us how to call the arm function.
1087999
1088−If `ice` is yes (`&`, `0`), the jet is known to be perfect and we
1089−can just trust the product of `fun_f`. Otherwise, we need to run
1090−*both* the Nock arm and `fun_f`, and compare their results.
1000+If `ice` is yes (`&`, `0`), the jet is known to be perfect and we can just trust
1001+the product of `fun_f`. Otherwise, we need to run *both* the Nock arm and
1002+`fun_f`, and compare their results.
10911003
1092−(Note that while executing the C side of this test, we have to
1093−set `ice` to yes; on the Nock side, we have to set `liv` to no.
1094−Otherwise, many non-exponential functions become exponential.
1095−When auto-testing jets in this way, the principle is that the
1096−test is on the outermost layer of recursion.)
1004+(Note that while executing the C side of this test, we have to set `ice` to yes;
1005+on the Nock side, we have to set `liv` to no. Otherwise, many non-exponential
1006+functions become exponential. When auto-testing jets in this way, the principle
1007+is that the test is on the outermost layer of recursion.)
10971008
1098−(Note also that anyone who multi-threads this execution
1099−environment has a slight locking problem with these flags if arm
1100−testing is multi-threaded.)
1009+(Note also that anyone who multi-threads this execution environment has a slight
1010+locking problem with these flags if arm testing is multi-threaded.)
11011011
1102−If `tot` is yes, (`&`, `0`), the arm function is *total* and has
1103−to return properly (though it can still return *u3_none*).
1104−Otherwise, it is *partial* and can `u3_cm_bail()` out with
1105−c3__punt. This feature has a cost: the jet runs in a subroad.
1012+If `tot` is yes, (`&`, `0`), the arm function is *total* and has to return
1013+properly (though it can still return \*u3\_none*). Otherwise, it is*partial\*
1014+and can `u3_cm_bail()` out with c3\_\_punt. This feature has a cost: the jet
1015+runs in a subroad.
11061016
11071017Finally, if `liv` is no (`|`, 1), the jet is off and doesn't run.
11081018
1109−It should be easy to see how the tree of cores gets declared -
1110−precisely, in `j/dash.c`. We declare the hierarchy as a tree
1111−of `u3j_core` structures, each of which comes with a static list
1112−of arms `arm_u` and sub-cores `dev_u`.
1019+It should be easy to see how the tree of cores gets declared - precisely, in
1020+`j/dash.c`. We declare the hierarchy as a tree of `u3j_core` structures, each of
1021+which comes with a static list of arms `arm_u` and sub-cores `dev_u`.
11131022
1114−In `u3j_boot()`, we traverse the hierarchy, fill in parent
1115−pointers `par_u`, and enumerate all `u3j_core` structures
1116−into a single flat array `u3j_dash.ray_u`. Our hot state
1117−then appears ready for action.
1023+In `u3j_boot()`, we traverse the hierarchy, fill in parent pointers `par_u`, and
1024+enumerate all `u3j_core` structures into a single flat array `u3j_dash.ray_u`.
1025+Our hot state then appears ready for action.
11181026
11191027### u3j: jet functions
11201028
1121−At present, all drivers are compiled statically into `u3`. This is
1122−not a long-term permanent solution or anything. However, it will
1123−always be the case with a certain amount of core functionality.
1124−
1125−For instance, there are some jet functions that we need to call
1126−as part of loading the Arvo kernel - like `++cue` to unpack a
1127−noun from an atom. And obviously it makes sense, when jets are
1128−significant enough to compile into `u3`, to export their symbols
1129−in headers and the linker.
1130−
1131−There are three interface prefixes for standard jet functions:
1132−`u3k`, `u3q`, and `u3w`. All jets have `u3w` interfaces; most
1133−have `u3q`; some have `u3k`. Of course the actual logic is
1134−shared.
1135−
1136−`u3w` interfaces use the same protocol as `fun_f` above: the
1137−caller passes the entire core, which is retained if the function
1138−returns `u3_none`, transferred otherwise. Why? Again, use
1139−counts of 1 are special and precious for performance hackers.
1140−
1141−`u3q` interfaces break the core into C arguments, *retain* noun
1142−arguments, and *transfer* noun returns. `u3k` interfaces are the
1143−same, except with more use of `u3_none` and other simple C
1144−variations on the Hoon original, but *transfer* both arguments
1145−and returns. Generally, `u3k` are most convenient for new code.
1146−
1147−Following `u3k/q/w` is `[a-f]`, corresponding to the 6 logical
1148−tiers of the kernel, or `g` for user-level jets. Another letter
1149−is added for functions within subcores. The filename, under
1150−`j/`, follows the tier and the function name.
1151−
1152−For instance, `++add` is `u3wa_add(cor)`, `u3qa_add(a, b)`, or
1153−`u3ka_add(a, b)`, in `j/a/add.c`. `++get` in `++by` is
1154−`u3wdb_get(cor)`, `u3kdb_get(a, b)`, etc, in `j/d/by_get.c`.
1155−
1156−For historical reasons, all internal jet code in `j/[a-f]`
1157−*retains* noun arguments, and *transfers* noun results. Please
1158−do not do this in new `g` jets! The new standard protocol is to
1159−transfer both arguments and results.
1029+At present, all drivers are compiled statically into `u3`. This is not a
1030+long-term permanent solution or anything. However, it will always be the case
1031+with a certain amount of core functionality.
1032+
1033+For instance, there are some jet functions that we need to call as part of
1034+loading the Arvo kernel - like `++cue` to unpack a noun from an atom. And
1035+obviously it makes sense, when jets are significant enough to compile into `u3`,
1036+to export their symbols in headers and the linker.
1037+
1038+There are three interface prefixes for standard jet functions: `u3k`, `u3q`, and
1039+`u3w`. All jets have `u3w` interfaces; most have `u3q`; some have `u3k`. Of
1040+course the actual logic is shared.
1041+
1042+`u3w` interfaces use the same protocol as `fun_f` above: the caller passes the
1043+entire core, which is retained if the function returns `u3_none`, transferred
1044+otherwise. Why? Again, use counts of 1 are special and precious for performance
1045+hackers.
1046+
1047+`u3q` interfaces break the core into C arguments, *retain* noun arguments, and
1048+*transfer* noun returns. `u3k` interfaces are the same, except with more use of
1049+`u3_none` and other simple C variations on the Hoon original, but *transfer*
1050+both arguments and returns. Generally, `u3k` are most convenient for new code.
1051+
1052+Following `u3k/q/w` is `[a-f]`, corresponding to the 6 logical tiers of the
1053+kernel, or `g` for user-level jets. Another letter is added for functions within
1054+subcores. The filename, under `j/`, follows the tier and the function name.
1055+
1056+For instance, `++add` is `u3wa_add(cor)`, `u3qa_add(a, b)`, or `u3ka_add(a, b)`,
1057+in `j/a/add.c`. `++get` in `++by` is `u3wdb_get(cor)`, `u3kdb_get(a, b)`, etc,
1058+in `j/d/by_get.c`.
1059+
1060+For historical reasons, all internal jet code in `j/[a-f]` *retains* noun
1061+arguments, and *transfers* noun results. Please do not do this in new `g` jets!
1062+The new standard protocol is to transfer both arguments and results.
11601063
11611064### u3a: allocation functions
11621065
1163−`u3a` allocates on the current road (u3R). Its internal
1164−structures are uninteresting and typical of a naive allocator.
1066+`u3a` allocates on the current road (u3R). Its internal structures are
1067+uninteresting and typical of a naive allocator.
11651068
1166−The two most-used `u3a` functions are `u3a_gain()` to add a
1167−reference count, and `u3a_lose()` to release one (and free the
1168−noun, if the use count is zero). For convenience, `u3a_gain()`
1169−returns its argument. The pair are generally abbreviated with
1170−the macros `u3k()` and `u3z()` respectively.
1069+The two most-used `u3a` functions are `u3a_gain()` to add a reference count, and
1070+`u3a_lose()` to release one (and free the noun, if the use count is zero). For
1071+convenience, `u3a_gain()` returns its argument. The pair are generally
1072+abbreviated with the macros `u3k()` and `u3z()` respectively.
11711073
1172−Normally we create nouns through `u3i` functions, and don't call
1173−the `u3a` allocators directly. But if you do:
1074+Normally we create nouns through `u3i` functions, and don't call the `u3a`
1075+allocators directly. But if you do:
11741076
1175−One, there are *two* sets of allocators: the word-aligned
1176−allocators and the fully-aligned (ie, malloc compatible)
1177−allocators. For instance, on a typical OS X setup, malloc
1178−produces 16-byte aligned results - needed for some SSE
1077+One, there are *two* sets of allocators: the word-aligned allocators and the
1078+fully-aligned (ie, malloc compatible) allocators. For instance, on a typical OS
1079+X setup, malloc produces 16-byte aligned results - needed for some SSE
11791080instructions.
11801081
1181−These allocators are *not compatible*. For 32-bit alignment
1182−as used in nouns, call
1082+These allocators are *not compatible*. For 32-bit alignment as used in nouns,
1083+call
11831084
11841085 /* u3a_walloc(): allocate storage measured in words.
11851086 */
@@ -1223,48 +1124,41 @@ For full alignment, call:
12231124 void
12241125 u3a_free2(void* tox_v, size_t siz_i);
12251126
1226−There are also a set of special-purpose allocators for building
1227−atoms. When building atoms, please remember that it's incorrect
1228−to have a high 0 word - the word length in the atom structure
1229−must be strictly correct.
1230−
1231−Of course, we don't always know how large our atom will be.
1232−Therefore, the standard way of building large atoms is to
1233−allocate a block of raw space with `u3a_slab()`, then chop off
1234−the end with `u3a_malt()` (which does the measuring itself)
1235−or `u3a_mint()` in case you've measured it yourself.
1236−
1237−Once again, *do not call `malloc()`* (or C++ `new`) within any
1238−code that may be run within a jet. This will cause rare sporadic
1239−corruption when we interrupt execution within a `malloc()`. We'd
1240−just override the symbol, but `libuv` uses `malloc()` across
1241−threads within its own synchronization primitives - for this to
1242−work with `u3a_malloc()`, we'd have to introduce our own locks on
1243−the surface-level road (which might be a viable solution).
1127+There are also a set of special-purpose allocators for building atoms. When
1128+building atoms, please remember that it's incorrect to have a high 0 word - the
1129+word length in the atom structure must be strictly correct.
1130+
1131+Of course, we don't always know how large our atom will be. Therefore, the
1132+standard way of building large atoms is to allocate a block of raw space with
1133+`u3a_slab()`, then chop off the end with `u3a_malt()` (which does the measuring
1134+itself) or `u3a_mint()` in case you've measured it yourself.
1135+
1136+Once again, *do not call `malloc()`* (or C++ `new`) within any code that may be
1137+run within a jet. This will cause rare sporadic corruption when we interrupt
1138+execution within a `malloc()`. We'd just override the symbol, but `libuv` uses
1139+`malloc()` across threads within its own synchronization primitives - for this
1140+to work with `u3a_malloc()`, we'd have to introduce our own locks on the
1141+surface-level road (which might be a viable solution).
12441142
12451143### u3n: nock execution
12461144
1247−The `u3n` routines execute Nock itself. On the inside, they have
1248−a surprising resemblance to the spec proper (the only interesting
1249−detail is how we handle tail-call elimination) and are, as one
1250−would expect, quite slow. (There is no such thing as a fast tree
1251−interpreter.)
1252−
1253−There is only one Nock, but there are lots of ways to call it.
1254−(Remember that all `u3n` functions *transfer* C arguments and
1255−returns.)
1256−
1257−The simplest interpreter, `u3n_nock_on(u3_noun bus, u3_noun fol)`
1258−invokes Nock on `bus` (the subject) and `fol` (the formula).
1259−(Why is it`[subject formula]`, not `[formula subject]`? The same
1260−reason `0` is true and `1` is false.)
1261−
1262−A close relative is `u3n_slam_on(u3_noun gat, u3_noun sam)`,
1263−which slams a *gate* (`gat`) on a sample (`sam`). (In a normal
1264−programming language which didn't talk funny and was retarded,
1265−`u3n_slam_on()` would call a function on an argument.) We could
1266−write it most simply as:
1267−
1145+The `u3n` routines execute Nock itself. On the inside, they have a surprising
1146+resemblance to the spec proper (the only interesting detail is how we handle
1147+tail-call elimination) and are, as one would expect, quite slow. (There is no
1148+such thing as a fast tree interpreter.)
1149+
1150+There is only one Nock, but there are lots of ways to call it. (Remember that
1151+all `u3n` functions *transfer* C arguments and returns.)
1152+
1153+The simplest interpreter, `u3n_nock_on(u3_noun bus, u3_noun fol)` invokes Nock
1154+on `bus` (the subject) and `fol` (the formula). (Why is it`[subject formula]`,
1155+not `[formula subject]`? The same reason `0` is true and `1` is false.)
1156+
1157+A close relative is `u3n_slam_on(u3_noun gat, u3_noun sam)`, which slams a
1158+*gate* (`gat`) on a sample (`sam`). (In a normal programming language which
1159+didn't talk funny and was retarded, `u3n_slam_on()` would call a function on an
1160+argument.) We could write it most simply as:
1161+
12681162 u3_noun
12691163 u3n_slam_on(u3_noun gat, u3_noun sam)
12701164 {
@@ -1276,9 +1170,9 @@ write it most simply as:
12761170 return pro;
12771171 }
12781172
1279−Simpler is `u3n_kick_on(u3_noun gat)`, which slams a gate (or,
1280−more generally, a *trap* - because sample structure is not even
1281−needed here) without changing its sample:
1173+Simpler is `u3n_kick_on(u3_noun gat)`, which slams a gate (or, more generally, a
1174+*trap* - because sample structure is not even needed here) without changing its
1175+sample:
12821176
12831177 u3_noun
12841178 u3n_kick_on(u3_noun gat, u3_noun sam)
@@ -1286,37 +1180,34 @@ needed here) without changing its sample:
12861180 return u3n_nock_on(gat, u3k(u3h(gat)));
12871181 }
12881182
1289−The `_on` functions in `u3n` are all defined as pure Nock. But
1290−actually, even though we say we don't extend Nock, we do. But we
1291−don't. But we do.
1183+The `_on` functions in `u3n` are all defined as pure Nock. But actually, even
1184+though we say we don't extend Nock, we do. But we don't. But we do.
12921185
1293−Note that `u3` has a well-developed error handling system -
1294−`u3m_bail()` to throw an exception, `u3m_soft_*` to catch one.
1295−But Nock has no exception model at all. That's okay - all it
1296−means if that if an `_on` function bails, the exception is an
1297−exception in the caller.
1186+Note that `u3` has a well-developed error handling system - `u3m_bail()` to
1187+throw an exception, `u3m_soft_*` to catch one. But Nock has no exception model
1188+at all. That's okay - all it means if that if an `_on` function bails, the
1189+exception is an exception in the caller.
12981190
1299−However, `u3`'s exception handling happens to match a convenient
1300−virtual super-Nock in `hoon.hoon`, the infamous `++mock`. Of
1301−course, Nock is slow, and `mock` is Nock in Nock, so it is
1302−(logically) super-slow. Then again, so is decrement.
1191+However, `u3`'s exception handling happens to match a convenient virtual
1192+super-Nock in `hoon.hoon`, the infamous `++mock`. Of course, Nock is slow, and
1193+`mock` is Nock in Nock, so it is (logically) super-slow. Then again, so is
1194+decrement.
13031195
1304−With the power of `u3`, we nest arbitrary layers of `mock`
1305−without any particular performance cost. Moreover, we simply
1306−treat Nock proper as a special case of `mock`. (More precisely,
1307−the internal VM loop is `++mink` and the error compiler is
1308−`++mook`. But we call the whole sandbox system `mock`.)
1196+With the power of `u3`, we nest arbitrary layers of `mock` without any
1197+particular performance cost. Moreover, we simply treat Nock proper as a special
1198+case of `mock`. (More precisely, the internal VM loop is `++mink` and the error
1199+compiler is `++mook`. But we call the whole sandbox system `mock`.)
13091200
1310−The nice thing about `mock` functions is that (by executing
1311−within `u3m_soft_run()`, which as you may recall uses a nested
1312−road) they provide both exceptions and the namespace operator -
1313−`.^` in Hoon, which becomes operator `11` in `mock`.
1201+The nice thing about `mock` functions is that (by executing within
1202+`u3m_soft_run()`, which as you may recall uses a nested road) they provide both
1203+exceptions and the namespace operator - `.^` in Hoon, which becomes operator
1204+`11` in `mock`.
13141205
1315−`11` requires a namespace function, or `fly`, which produces a
1316−`++unit` - `~` (`0`) for no binding, or `[0 value]`. The sample
1317−to a `fly` is a `++path`, just a list of text `span`.
1206+`11` requires a namespace function, or `fly`, which produces a `++unit` - `~`
1207+(`0`) for no binding, or `[0 value]`. The sample to a `fly` is a `++path`, just
1208+a list of text `span`.
13181209
1319−`mock` functions produce a `++toon`. Fully elaborated:
1210+`mock` functions produce a `++toon`. Fully elaborated:
13201211
13211212 ++ noun ,* :: any noun
13221213 ++ path (list ,@ta) :: namespace path
@@ -1339,20 +1230,18 @@ to a `fly` is a `++path`, just a list of text `span`.
13391230
13401231(Note that `tank` is overdesigned and due for replacement.)
13411232
1342−What does a `toon` mean? Either your computation succeded (`[0
1343−noun]`, or could not finish because it blocked on one or more
1344−global paths (`[1 (list path)]`), or it exited with a stack trace
1345−(`[2 (list tank)]`).
1233+What does a `toon` mean? Either your computation succeded (`[0 noun]`, or could
1234+not finish because it blocked on one or more global paths (`[1 (list path)]`),
1235+or it exited with a stack trace (`[2 (list tank)]`).
13461236
1347−Note that of all the `u3` exceptions, only `%exit` is produced
1348−deterministically by the Nock definition. Therefore, only
1349−`%exit` produces a `2` result. Any other argument to
1350−`u3m_bail()` will unwind the virtualization stack all the way to
1351−the top - or to be more exact, to `u3m_soft_top()`.
1237+Note that of all the `u3` exceptions, only `%exit` is produced deterministically
1238+by the Nock definition. Therefore, only `%exit` produces a `2` result. Any other
1239+argument to `u3m_bail()` will unwind the virtualization stack all the way to the
1240+top - or to be more exact, to `u3m_soft_top()`.
13521241
1353−In any case, the simplest `mock` functions are `u3n_nock_un()`
1354−and `u3n_slam_un()`. These provide exception control without
1355−any namespace change, as you can see by the code:
1242+In any case, the simplest `mock` functions are `u3n_nock_un()` and
1243+`u3n_slam_un()`. These provide exception control without any namespace change,
1244+as you can see by the code:
13561245
13571246 /* u3n_nock_un(): produce .*(bus fol), as ++toon.
13581247 */
@@ -1374,104 +1263,92 @@ any namespace change, as you can see by the code:
13741263 return u3n_slam_in(fly, gat, sam);
13751264 }
13761265
1377−The `fly` is added as the first argument to `u3n_nock_in()` and
1378−`u3n_slam_in()`. Of course, logically, `fly` executes in the
1379−caller's exception layer. (Maintaining this illusion is slightly
1380−nontrivial.) Finally, `u3n_nock_an()` is a sandbox with a null
1381−namespace.
1266+The `fly` is added as the first argument to `u3n_nock_in()` and `u3n_slam_in()`.
1267+Of course, logically, `fly` executes in the caller's exception layer.
1268+(Maintaining this illusion is slightly nontrivial.) Finally, `u3n_nock_an()` is
1269+a sandbox with a null namespace.
13821270
13831271### u3e: persistence
13841272
1385−The only `u3e` function you should need to call is `u3e_save()`,
1386−which saves the loom. As it can be restored on any platform,
1387−please make sure you don't have any state in the loom that is
1388−bound to your process or architecture - except for exceptions
1389−like the warm jet state, which is actively purged on reboot.
1273+The only `u3e` function you should need to call is `u3e_save()`, which saves the
1274+loom. As it can be restored on any platform, please make sure you don't have any
1275+state in the loom that is bound to your process or architecture - except for
1276+exceptions like the warm jet state, which is actively purged on reboot.
13901277
13911278### u3r: reading nouns (weak)
13921279
1393−As befits accessors they don't make anything, `u3r` noun reading
1394−functions always retain their arguments and their returns. They
1395−never bail; rather, when they don't work, they return a `u3_weak`
1396−result.
1397−
1398−Most of these functions are straightforward and do only what
1399−their comments say. A few are interesting enough to discuss.
1400−
1401−`u3r_at()` is the familiar tree fragment function, `/` from the
1402−Nock spec. For taking complex nouns apart, `u3r_mean()` is a
1403−relatively funky way of deconstructing nouns with a varargs list
1404−of `axis`, `u3_noun *`. For cells, triples, etc, decompose with
1405−`u3r_cell()`, `u3r_trel()`, etc. For the tagged equivalents, use
1406−`u3r_pq()` and friends.
1407−
1408−`u3r_sing(u3_noun a, u3_noun b)` (true if `a` and `b` are a
1409−*single* noun) are interesting because it uses mugs to help it
1410−out. Clearly, different nouns may have the same mug, but the
1411−same nouns cannot have a different mug. It's important to
1412−understand the performance characteristics of `u3r_sing()`:
1413−the worst possible case is a comparison of duplicate nouns,
1414−which have the same value but were created separately. In this
1415−case, the tree is traversed
1416−
1417−`u3r_sung()` is a deeply funky and frightening version of
1418−`u3r_sing()` that unifies pointers to the duplicate nouns it
1419−finds, freeing the second copy. Obviously, do not use
1420−`u3r_sung()` when you have live, but not reference counted, noun
1421−references from C - if they match a noun with a refcount of 1
1422−that gets freed, bad things happen.
1423−
1424−It's important to remember that `u3r_mug()`, which produces a
1425−31-bit, nonzero insecure hash, uses the `mug_w` slot in any boxed
1426−noun as a lazy cache. There are a number of variants of
1427−`u3r_mug()` that can get you out of building unneeded nouns.
1280+As befits accessors they don't make anything, `u3r` noun reading functions
1281+always retain their arguments and their returns. They never bail; rather, when
1282+they don't work, they return a `u3_weak` result.
1283+
1284+Most of these functions are straightforward and do only what their comments say.
1285+A few are interesting enough to discuss.
1286+
1287+`u3r_at()` is the familiar tree fragment function, `/` from the Nock spec. For
1288+taking complex nouns apart, `u3r_mean()` is a relatively funky way of
1289+deconstructing nouns with a varargs list of `axis`, `u3_noun *`. For cells,
1290+triples, etc, decompose with `u3r_cell()`, `u3r_trel()`, etc. For the tagged
1291+equivalents, use `u3r_pq()` and friends.
1292+
1293+`u3r_sing(u3_noun a, u3_noun b)` (true if `a` and `b` are a *single* noun) are
1294+interesting because it uses mugs to help it out. Clearly, different nouns may
1295+have the same mug, but the same nouns cannot have a different mug. It's
1296+important to understand the performance characteristics of `u3r_sing()`: the
1297+worst possible case is a comparison of duplicate nouns, which have the same
1298+value but were created separately. In this case, the tree is traversed
1299+
1300+`u3r_sung()` is a deeply funky and frightening version of `u3r_sing()` that
1301+unifies pointers to the duplicate nouns it finds, freeing the second copy.
1302+Obviously, do not use `u3r_sung()` when you have live, but not reference
1303+counted, noun references from C - if they match a noun with a refcount of 1 that
1304+gets freed, bad things happen.
1305+
1306+It's important to remember that `u3r_mug()`, which produces a 31-bit, nonzero
1307+insecure hash, uses the `mug_w` slot in any boxed noun as a lazy cache. There
1308+are a number of variants of `u3r_mug()` that can get you out of building
1309+unneeded nouns.
14281310
14291311### u3x: reading nouns (bail)
14301312
1431−`u3x` functions are like `u3r` functions, but instead of
1432−returning `u3_none` when (for instance) we try to take the head
1433−of an atom, they bail with `%exit`. In other words, they do what
1434−the same operation would do in Nock.
1313+`u3x` functions are like `u3r` functions, but instead of returning `u3_none`
1314+when (for instance) we try to take the head of an atom, they bail with `%exit`.
1315+In other words, they do what the same operation would do in Nock.
14351316
14361317### u3h: hash tables.
14371318
1438−We can of course use the Hoon `map` structure as an associative
1439−array. This is a balanced treap and reasonably fast. However,
1440−it's considerably inferior to a custom structure like an HAMT
1441−(hash array-mapped trie). We use `u3_post` to allocate HAMT
1442−structures on the loom.
1319+We can of course use the Hoon `map` structure as an associative array. This is a
1320+balanced treap and reasonably fast. However, it's considerably inferior to a
1321+custom structure like an HAMT (hash array-mapped trie). We use `u3_post` to
1322+allocate HAMT structures on the loom.
14431323
1444−(Our HAMT implements the classic Bagwell algorithm which depends
1445−on the `gcc` standard directive `__builtin_popcount()`. On a CPU
1446−which doesn't support popcount or an equivalent instruction, some
1447−other design would probably be preferable.)
1324+(Our HAMT implements the classic Bagwell algorithm which depends on the `gcc`
1325+standard directive `__builtin_popcount()`. On a CPU which doesn't support
1326+popcount or an equivalent instruction, some other design would probably be
1327+preferable.)
14481328
1449−There's no particular rocket science in the API. `u3h_new()`
1450−creates a hashtable; `u3h_free()` destroys one; `u3h_put()`
1451−inserts, `u3h_get()` retrieves. You can transform values in a
1452−hashtable with `u3h_walk()`.
1329+There's no particular rocket science in the API. `u3h_new()` creates a
1330+hashtable; `u3h_free()` destroys one; `u3h_put()` inserts, `u3h_get()`
1331+retrieves. You can transform values in a hashtable with `u3h_walk()`.
14531332
1454−The only funky function is `u3h_gut()`, which unifies keys with
1455−`u3r_sung()`. As with all cases of `u3r_sung()`, this must be
1456−used with extreme caution.
1333+The only funky function is `u3h_gut()`, which unifies keys with `u3r_sung()`. As
1334+with all cases of `u3r_sung()`, this must be used with extreme caution.
14571335
14581336### u3z: memoization
14591337
1460−Connected to the `~+` rune in Hoon, via the Nock `%memo` hint,
1461−the memoization facility is a general-purpose cache.
1338+Connected to the `~+` rune in Hoon, via the Nock `%memo` hint, the memoization
1339+facility is a general-purpose cache.
14621340
1463−(It's also used for partial memoization - a feature that'll
1464−probably be removed, in which conservative worklist algorithms
1465−(which would otherwise be exponential) memoize everything in the
1466−subject *except* the worklist. This is used heavily in the Hoon
1467−compiler jets (j/f/*.c). Unfortunately, it's probably not
1468−possible to make this work perfectly in that it can't be abused
1469−to violate Nock, so we'll probably remove it at a later date,
1470−instead making `++ut` keep its own monadic cache.)
1341+(It's also used for partial memoization - a feature that'll probably be removed,
1342+in which conservative worklist algorithms (which would otherwise be exponential)
1343+memoize everything in the subject *except* the worklist. This is used heavily in
1344+the Hoon compiler jets (j/f/\*.c). Unfortunately, it's probably not possible to
1345+make this work perfectly in that it can't be abused to violate Nock, so we'll
1346+probably remove it at a later date, instead making `++ut` keep its own monadic
1347+cache.)
14711348
1472−Each `u3z` function comes with a `c3_m` mote which disambiguates
1473−the function mapping key to value. For Nock itself, use 0. For
1474−extra speed, small tuples are split out in C; thus, find with
1349+Each `u3z` function comes with a `c3_m` mote which disambiguates the function
1350+mapping key to value. For Nock itself, use 0. For extra speed, small tuples are
1351+split out in C; thus, find with
14751352
14761353 u3_weak u3z_find(c3_m, u3_noun);
14771354 u3_weak u3z_find_2(c3_m, u3_noun, u3_noun);
@@ -1485,18 +1362,18 @@ and save with
14851362 u3_noun u3z_save_3(c3_m, u3_noun, u3_noun, u3_noun, u3_noun);
14861363 u3_noun u3z_save_4(c3_m, u3_noun, u3_noun, u3_noun, u3_noun, u3_noun);
14871364
1488−where the value is the last argument. To eliminate duplicate
1489−nouns, there is also
1365+where the value is the last argument. To eliminate duplicate nouns, there is
1366+also
14901367
14911368 u3_noun
14921369 u3z_uniq(u3_noun);
14931370
14941371`u3z` functions retain keys and transfer values.
1495−
1496−The `u3z` cache, built on `u3h` hashes, is part of the current
1497−road, and goes away when it goes away. (In future, we may wish
1498−to promote keys/values which outlive the road, as we do with jet
1499−state.) There is no cache reclamation at present, so be careful.
1372+
1373+The `u3z` cache, built on `u3h` hashes, is part of the current road, and goes
1374+away when it goes away. (In future, we may wish to promote keys/values which
1375+outlive the road, as we do with jet state.) There is no cache reclamation at
1376+present, so be careful.
15001377
15011378### u3t: tracing and profiling.
15021379
@@ -1504,9 +1381,8 @@ TBD.
15041381
15051382### u3v: the Arvo kernel
15061383
1507−An Arvo kernel - or at least, a core that compiles with the Arvo
1508−interface - is part of the global `u3` state. What is an Arvo
1509−core? Slightly pseudocoded:
1384+An Arvo kernel - or at least, a core that compiles with the Arvo interface - is
1385+part of the global `u3` state. What is an Arvo core? Slightly pseudocoded:
15101386
15111387 ++ arvo
15121388 |%
@@ -1533,54 +1409,49 @@ core? Slightly pseudocoded:
15331409 ++ ovum {p/wire q/card} :: Arvo event
15341410 ++ wire path :: event cause
15351411
1536−This is the Arvo ABI in a very real sense. Arvo is a core with
1537−these six arms. To use these arms, we hardcode the axis of the
1538−formula (`11`, `4`, `86`, etc) into the C code that calls Arvo,
1539−because otherwise we'd need type metadata - which we can get, by
1540−calling Arvo.
1412+This is the Arvo ABI in a very real sense. Arvo is a core with these six arms.
1413+To use these arms, we hardcode the axis of the formula (`11`, `4`, `86`, etc)
1414+into the C code that calls Arvo, because otherwise we'd need type metadata -
1415+which we can get, by calling Arvo.
15411416
1542−It's important to understand the Arvo event/action structure, or
1543−`++ovum`. An `ovum` is a `card`, which is any `[term noun]`
1544−cell, and a `++wire`, a `path` which indicates the location of
1545−the event. At the Unix level, the `wire` corresponds to a system
1546−module or context. For input events, this is the module that
1547−caused the event; for output actions, it's the module that
1548−performs the action.
1417+It's important to understand the Arvo event/action structure, or `++ovum`. An
1418+`ovum` is a `card`, which is any `[term noun]` cell, and a `++wire`, a `path`
1419+which indicates the location of the event. At the Unix level, the `wire`
1420+corresponds to a system module or context. For input events, this is the module
1421+that caused the event; for output actions, it's the module that performs the
1422+action.
15491423
1550−`++poke` sends Arvo an event `ovum`, producing a cell of action
1551−ova and a new Arvo core.
1424+`++poke` sends Arvo an event `ovum`, producing a cell of action ova and a new
1425+Arvo core.
15521426
1553−`++peek` dereferences the Arvo namespace. It takes a date and a
1554−key, and produces `~` (`0`) or `[~ value]`.
1427+`++peek` dereferences the Arvo namespace. It takes a date and a key, and
1428+produces `~` (`0`) or `[~ value]`.
15551429
1556−`++keep` asks Arvo the next time it wants to be woken up, for the
1557−given `wire`. (This input will probably be eliminated in favor
1558−of a single global timer.)
1430+`++keep` asks Arvo the next time it wants to be woken up, for the given `wire`.
1431+(This input will probably be eliminated in favor of a single global timer.)
15591432
1560−`++wish` compiles a string of Hoon source. While just a
1561−convenience, it's a very convenient convenience.
1433+`++wish` compiles a string of Hoon source. While just a convenience, it's a very
1434+convenient convenience.
15621435
1563−`++come` and `++load` are used by Arvo to reset itself (more
1564−precisely, to shift the Arvo state from an old kernel to a new
1565−one); there is no need to call them from C.
1436+`++come` and `++load` are used by Arvo to reset itself (more precisely, to shift
1437+the Arvo state from an old kernel to a new one); there is no need to call them
1438+from C.
15661439
1567−Now that we understand the Arvo kernel interface, let's look at
1568−the `u3v` API. As usual, all the functions in `u3v` are
1569−commented, but unfortunately it's hard to describe this API as
1570−clean at present. The problem is that `u3v` remains design
1571−coupled to the old `vere` event handling code written for `u2`.
1572−But let's describe the functions you should be calling, assuming
1573−you're not writing the next event system. There are only two.
1440+Now that we understand the Arvo kernel interface, let's look at the `u3v` API.
1441+As usual, all the functions in `u3v` are commented, but unfortunately it's hard
1442+to describe this API as clean at present. The problem is that `u3v` remains
1443+design coupled to the old `vere` event handling code written for `u2`. But let's
1444+describe the functions you should be calling, assuming you're not writing the
1445+next event system. There are only two.
15741446
1575−`u3v_wish(str_c)` wraps the `++wish` functionality in a cache
1576−(which is read-only unless you're on the surface road).
1447+`u3v_wish(str_c)` wraps the `++wish` functionality in a cache (which is
1448+read-only unless you're on the surface road).
15771449
1578−`u3v_do()` uses `wish` to provide a convenient interface for
1579−calling Hoon kernel functions by name. Even more conveniently,
1580−we tend to call `u3v_do()` with these convenient aliases:
1450+`u3v_do()` uses `wish` to provide a convenient interface for calling Hoon kernel
1451+functions by name. Even more conveniently, we tend to call `u3v_do()` with these
1452+convenient aliases:
15811453
15821454 #define u3do(txt_c, arg) u3v_do(txt_c, arg)
15831455 #define u3dc(txt_c, a, b) u3v_do(txt_c, u3nc(a, b))
15841456 #define u3dt(txt_c, a, b, c) u3v_do(txt_c, u3nt(a, b, c))
15851457 #define u3dq(txt_c, a, b, c, d) u3v_do(txt_c, u3nt(a, b, c, d))
1586−
docs/arvo.md+3−2
@@ -1,11 +1,12 @@
11---
2−navhome: /docs/
2+navhome: '/docs/'
33sort: 4
44---
55
66# Arvo
77
8−Fast, pragmatic tutorials which show you how to build simple programs in Hoon and Arvo.
8+Fast, pragmatic tutorials which show you how to build simple programs in Hoon
9+and Arvo.
910
1011If you learn by getting things done, not by exploring fundamentals, start here.
1112
docs/arvo/api.md+425−456
@@ -1,38 +1,34 @@
11---
2−navhome: /docs/
3−next: true
2+navhome: '/docs/'
3+next: True
44sort: 21
55title: API Connectors
66---
77
88# API Connectors
99
10−Most people have lots of data stored in online services, many of
11−which have APIs. API connectors allow the user to access this
12−data from within their Urbit.
10+Most people have lots of data stored in online services, many of which have
11+APIs. API connectors allow the user to access this data from within their Urbit.
1312
14−A security driver allows the user to make authenticated requests
15−to the service's API, but the user still needs to know the API
16−and send and receive JSON. An API connector puts a layer of
17−porcelain over this to allow the user easier control over their
18−data.
13+A security driver allows the user to make authenticated requests to the
14+service's API, but the user still needs to know the API and send and receive
15+JSON. An API connector puts a layer of porcelain over this to allow the user
16+easier control over their data.
1917
20−Each connector should perform two basic functions. First, it
21−should expose a tree of the data in the service that's accessible
22−through `.^` and FUSE. Second, it should expose event streams as
23−actions occur in the service. Let's take a look at how the `%gh`
24−app accomplishes both for Github.
18+Each connector should perform two basic functions. First, it should expose a
19+tree of the data in the service that's accessible through `.^` and FUSE. Second,
20+it should expose event streams as actions occur in the service. Let's take a
21+look at how the `%gh` app accomplishes both for Github.
2522
26−After starting `%gh` (`|start %gh`), let's look at the root of
27−the tree that `%gh` exposes:
23+After starting `%gh` (`|start %gh`), let's look at the root of the tree that
24+`%gh` exposes:
2825
2926 ~your-urbit:dojo> .^(arch %gy /=gh=)
3027 [fil=~ dir={[p=~.issues q=~]}]
3128
32−`%gh` is currently a skeleton -- it contains examples of all the
33−functionality necessary for a connector, but many endpoints
34−aren't implemented. As we can see here, only issues are
35−implemented. We can explore this tree:
29+`%gh` is currently a skeleton -- it contains examples of all the functionality
30+necessary for a connector, but many endpoints aren't implemented. As we can see
31+here, only issues are implemented. We can explore this tree:
3632
3733 ~your-urbit:dojo> .^(arch %gy /=gh=/issues)
3834 [fil=~ dir={[p=~.by-repo q=~] [p=~.mine q=~]}]
@@ -45,58 +41,50 @@ And eventually:
4541 login.user:.^(issue:gh %gx /=gh=/issues/by-repo/philipcmonktest/testing/7)
4642 'philipcmonktest'
4743
48−The other thing an API connector needs to do is expose event
49−streams. One straightforward way to use this capacity is with
50−the `:pipe` app:
44+The other thing an API connector needs to do is expose event streams. One
45+straightforward way to use this capacity is with the `:pipe` app:
5146
5247 :pipe|connect %gh /listen/philipcmonktest/testing/issues/'issue_comment' %public
5348
54−Now creating an issue results in the following message in your
55−`%public` `:talk` channel:
49+Now creating an issue results in the following message in your `%public` `:talk`
50+channel:
5651
5752 ~your-urbit[philipcmonktest@github]: opened issue #11: i found a bug!
5853
59−You'll also get notifications of issue status changes and
60−comments.
54+You'll also get notifications of issue status changes and comments.
6155
62−As is often the case, the best way to write an API connector is
63−to copy an existing one and modify it. We'll dissect the Github
64−connector here. This code is in `/=home=/app/gh/hoon`, and it's
65−also reproduced at the bottom of this page (in case the code
66−drifts out of sync with this doc).
56+As is often the case, the best way to write an API connector is to copy an
57+existing one and modify it. We'll dissect the Github connector here. This code
58+is in `/=home=/app/gh/hoon`, and it's also reproduced at the bottom of this page
59+(in case the code drifts out of sync with this doc).
6760
6861We'll go over the two parts to an API connector (one-time reading vs listening
6962for events) separately.
7063
7164## Reading
7265
73−A connector exposes a tree of data. Every read request has a
74−`care`, which is generally either `%x` or `%y. `%x` is a request
75−for a particular piece of data, while `%y` is a request for a
76−directory listing. Roughly, `%x` means Unix `cat` and `%y` means
77−Unix `ls`.
78−
79−> Sometimes you wish to expose a tree where a part of the path
80−> can't be enumerated. For example, a `%y` of `/issues/by-repo`
81−> "should" produce a list of all Github users, but we don't do
82−> that because it's too long. Instead, we just produce our own
83−> username (from the `web.plan` file). You can still access
84−> repos from other users, you just don't see them in the
85−> directory listing.
86−
87−The usual flow for implementing this tree of data makes heavy use
88−of the `connector` library. This library is well documented in
89−the source, so check out `/=home=/lib/connector/hoon`.
90−
91−The `connector` library needs to be initialized with definitions
92−of `move` and `sub-result` (all the types of data that can be
93−returned by a place). This can just be a line at the top of the
94−main core:
66+A connector exposes a tree of data. Every read request has a `care`, which is
67+generally either `%x` or
68+`%y.`%x`is a request for a particular piece of data, while`%y`is a request for a directory listing. Roughly,`%x`means Unix`cat`and`%y`means Unix`ls\`.
69+
70+> Sometimes you wish to expose a tree where a part of the path can't be
71+> enumerated. For example, a `%y` of `/issues/by-repo` "should" produce a list
72+> of all Github users, but we don't do that because it's too long. Instead, we
73+> just produce our own username (from the `web.plan` file). You can still access
74+> repos from other users, you just don't see them in the directory listing.
75+
76+The usual flow for implementing this tree of data makes heavy use of the
77+`connector` library. This library is well documented in the source, so check out
78+`/=home=/lib/connector/hoon`.
79+
80+The `connector` library needs to be initialized with definitions of `move` and
81+`sub-result` (all the types of data that can be returned by a place). This can
82+just be a line at the top of the main core:
9583
9684 =+ connector=(connector move sub-result) :: Set up connector library
9785
98−Most of the Github-specific logic is in `++places`, which is a
99−list of all the places we can request. A place consists of:
86+Most of the Github-specific logic is in `++places`, which is a list of all the
87+places we can request. A place consists of:
10088
10189 ++ place
10290 $: guard/mold
@@ -106,421 +94,402 @@ list of all the places we can request. A place consists of:
10694 sigh-y/$-(jon/json (unit arch))
10795 ==
10896
109−- `guard`, the type of the paths we should match. For example,
110− to match `/issues/<user>/<repo>` use `{$issues @t @t $~}`.
111−
112−- `read-x`, called when someone tries to read the place with
113− `care` `%x`. Should produce a single move, usually either a
114− `%diff` response if we can immediately answer or a `%hiss`
115− http request if we need to make a request to the api. See the
116− `++read-*` functions in `++helpers` for some common handlers.
117−
118−- `read-y`, same as `read-x` except with care `%y`.
119−
120−- `sigh-x`, called when an http response comes back on this
121− place. You're given the json of the result, and you should
122− produce either a result or null. Null represents an error.
123− If you didn't create an http request in `read-x`, then this
124− should never be called. Use `++sigh-strange` from `++helpers`
125− to unconditionally signal an error.
126−
127−- `sigh-y`, same as `sigh-x` except with care `%y`. Note that a
128− `%y` request must produce an arch, unlike a `%x` request,
129− which may produce data of any mark.
130−
131−Filling out the list of places is a lot of grunt work, but most
132−places are fairly straightforward, and the `++read-*` helper
133−functions are useful. Check out the library source for more
134−information on those.
135−
136−Besides the list of places, we just need to handle the flow of
137−control. `++peek` and `++peer-scry` are the interface we expose
138−to the rest of the system while `++sigh-httr` and `++sigh-tang`
139−are used to handle responses when we make HTTP requests.
140−
141−- `++peek` should usually just produce `~`. If there are cases
142− where we can respond directly to a `.^` request without
143− blocking on anything, we could do it here, but it's generally
144− not worth the hassle since the same logic should be duplicated
145− in `++peer-scry`.
146−
147−- `++peer-scry` is where the actual handling for a read request
148− goes. In general, we just need to call `++read` from the
149− `connector` library with the bone, list of places, care, and
150− path. This will match the path to the appropriate place and
151− run either `++read-x` or `++read-y`, depending on the care.
152−
153−- If `++read-x` or `++read-y` made a successful API request, then
154− the response will come back on `++sigh-httr`. Here, we just
155− need to parse out the wire and call `++sigh` from the
156− `connector` library with the list of places, care, path, and
157− HTTP result. This will match the path to the appropriate place
158− and run either `++sigh-x` or `++sigh-y`, depending on the care.
159−
160−- If `++read-x` or `++read-y` made an API request that failed,
161− then we'll get a stack trace in `++sigh-tang`. Here, we just
162− print it out and move on.
163−
164−That's really all there is to the reading portion of API
165−connectors.
166−
167−One of the most accessbile ways to jump into Arvo programming is
168−to just add more places to an existing API connector. It's
169−useful, small in scope, and comes in bite-sized chunks since most
170−places are less than ten lines of code.
97+- `guard`, the type of the paths we should match. For example, to match
98+ `/issues/<user>/<repo>` use `{$issues @t @t $~}`.
99+
100+- `read-x`, called when someone tries to read the place with `care` `%x`.
101+ Should produce a single move, usually either a `%diff` response if we can
102+ immediately answer or a `%hiss` http request if we need to make a request to
103+ the api. See the `++read-*` functions in `++helpers` for some common
104+ handlers.
105+
106+- `read-y`, same as `read-x` except with care `%y`.
107+
108+- `sigh-x`, called when an http response comes back on this place. You're
109+ given the json of the result, and you should produce either a result or
110+ null. Null represents an error. If you didn't create an http request in
111+ `read-x`, then this should never be called. Use `++sigh-strange` from
112+ `++helpers` to unconditionally signal an error.
113+
114+- `sigh-y`, same as `sigh-x` except with care `%y`. Note that a `%y` request
115+ must produce an arch, unlike a `%x` request, which may produce data of any
116+ mark.
117+
118+Filling out the list of places is a lot of grunt work, but most places are
119+fairly straightforward, and the `++read-*` helper functions are useful. Check
120+out the library source for more information on those.
121+
122+Besides the list of places, we just need to handle the flow of control. `++peek`
123+and `++peer-scry` are the interface we expose to the rest of the system while
124+`++sigh-httr` and `++sigh-tang` are used to handle responses when we make HTTP
125+requests.
126+
127+- `++peek` should usually just produce `~`. If there are cases where we can
128+ respond directly to a `.^` request without blocking on anything, we could do
129+ it here, but it's generally not worth the hassle since the same logic should
130+ be duplicated in `++peer-scry`.
131+
132+- `++peer-scry` is where the actual handling for a read request goes. In
133+ general, we just need to call `++read` from the `connector` library with the
134+ bone, list of places, care, and path. This will match the path to the
135+ appropriate place and run either `++read-x` or `++read-y`, depending on the
136+ care.
137+
138+- If `++read-x` or `++read-y` made a successful API request, then the response
139+ will come back on `++sigh-httr`. Here, we just need to parse out the wire
140+ and call `++sigh` from the `connector` library with the list of places,
141+ care, path, and HTTP result. This will match the path to the appropriate
142+ place and run either `++sigh-x` or `++sigh-y`, depending on the care.
143+
144+- If `++read-x` or `++read-y` made an API request that failed, then we'll get
145+ a stack trace in `++sigh-tang`. Here, we just print it out and move on.
146+
147+That's really all there is to the reading portion of API connectors.
148+
149+One of the most accessbile ways to jump into Arvo programming is to just add
150+more places to an existing API connector. It's useful, small in scope, and comes
151+in bite-sized chunks since most places are less than ten lines of code.
171152
172153## Listening
173154
174−Listening for events is fairly service-specific. In some
175−services, we poll for changes. The Twitter connector has an
176−example of this, but note that it predates the `connector`
177−library and is thus more complicated than it needs to be, and the
178−interface it exposes isn't standard. In Github, we power our
179−event streams with webhooks.
180−
181−For Github, when someone subscribes to
182−`/listen/<user>/<repo>/<events...>`, we want to produce
183−well-typed results when they occur.
184−
185−We only want to create one webhook per event, so in our state we
186−have `hook`, which is a map of event names to the set of bones
187−which are subscribed to that event. We must always keep this
188−up-to-date.
189−
190−Flow of control starts in `++peer-listen`, where we just call
191−`++listen`. In `++listen`, for each event in the list of events,
192−we check to see if we have that hook set up (by checking whether
193−it exists in `hook`). If so, we call `++update-hook` to add the
194−current bone to the set of listeners. Otherwise, we call
195−`++create-hook`, which sends a request to Github to set up the
196−new webhook. We also create an entry in `hook` with the current
197−bone.
155+Listening for events is fairly service-specific. In some services, we poll for
156+changes. The Twitter connector has an example of this, but note that it predates
157+the `connector` library and is thus more complicated than it needs to be, and
158+the interface it exposes isn't standard. In Github, we power our event streams
159+with webhooks.
198160
199−When we created the webhook, we told Github to send the event to
200−`/~/to/gh/gh-<event>.json?anon&wire=/`. This turns into a poke.
201−Let's parse out this url. The first `gh` is the app name to
202−poke. The next portion, `gh-<event>` is the mark to convert the
203−JSON to. For example, when the "issues" event fires, it'll get
204−converted to mark `gh-issues`. This mark has a conversion
205−routine from `json` to the `issues` type, which is defined in the
206−`gh` structure (`/=home=/sur/gh/hoon`). Once this conversion
207−happens, the `gh` app will get poked with the correctly marked
208−data in `++poke`.
161+For Github, when someone subscribes to `/listen/<user>/<repo>/<events...>`, we
162+want to produce well-typed results when they occur.
163+
164+We only want to create one webhook per event, so in our state we have `hook`,
165+which is a map of event names to the set of bones which are subscribed to that
166+event. We must always keep this up-to-date.
209167
210−In `++poke`, we check `hook` to find the subscribers to the event
211−that was fired, and we update them.
168+Flow of control starts in `++peer-listen`, where we just call `++listen`. In
169+`++listen`, for each event in the list of events, we check to see if we have
170+that hook set up (by checking whether it exists in `hook`). If so, we call
171+`++update-hook` to add the current bone to the set of listeners. Otherwise, we
172+call `++create-hook`, which sends a request to Github to set up the new webhook.
173+We also create an entry in `hook` with the current bone.
212174
213−That's really all there is to it. Webhook flow isn't well
214−standardized, so even if your chosen service is powered by
215−webhooks, your listening code might look rather different. The
216−point is to expose the correct interface.
175+When we created the webhook, we told Github to send the event to
176+`/~/to/gh/gh-<event>.json?anon&wire=/`. This turns into a poke. Let's parse out
177+this url. The first `gh` is the app name to poke. The next portion, `gh-<event>`
178+is the mark to convert the JSON to. For example, when the "issues" event fires,
179+it'll get converted to mark `gh-issues`. This mark has a conversion routine from
180+`json` to the `issues` type, which is defined in the `gh` structure
181+(`/=home=/sur/gh/hoon`). Once this conversion happens, the `gh` app will get
182+poked with the correctly marked data in `++poke`.
217183
184+In `++poke`, we check `hook` to find the subscribers to the event that was
185+fired, and we update them.
186+
187+That's really all there is to it. Webhook flow isn't well standardized, so even
188+if your chosen service is powered by webhooks, your listening code might look
189+rather different. The point is to expose the correct interface.
218190
219191## Github API Connector Code
220192
221−In case the code in `/=home=/app/gh/hoon` drifts out of sync with
222−this doc:
223−
224−```
225−:: This is a connector for the Github API v3.
226−::
227−:: You can interact with this in a few different ways:
228−::
229−:: - .^({type} %gx /=gh={/endpoint}) to read data or
230−:: .^(arch %gy /=gh={/endpoint}) to explore the possible
231−:: endpoints.
232−::
233−:: - subscribe to /listen/{owner}/{repo}/{events...} for
234−:: webhook-powered event notifications. For event list, see
235−:: https://developer.github.com/webhooks/.
236−::
237−:: This is written with the standard structure for api
238−:: connectors, as described in lib/connector.hoon.
239−::
240−/? 314
241−/- gh, plan-acct
242−/+ gh-parse, connector
243−::
244−!:
245−=> |%
246− ++ move (pair bone card)
247− ++ card
248− $% {$diff sub-result}
249− {$them wire (unit hiss)}
250− {$hiss wire {$~ $~} $httr {$hiss hiss}}
251− ==
193+In case the code in `/=home=/app/gh/hoon` drifts out of sync with this doc:
194+
195+ :: This is a connector for the Github API v3.
252196 ::
253− :: Types of results we produce to subscribers.
197+ :: You can interact with this in a few different ways:
254198 ::
255− ++ sub-result
256− $% {$arch arch}
257− {$gh-issue issue:gh}
258− {$gh-list-issues (list issue:gh)}
259− {$gh-issues issues:gh}
260− {$gh-issue-comment issue-comment:gh}
261− {$json json}
262− {$null $~}
263− ==
199+ :: - .^({type} %gx /=gh={/endpoint}) to read data or
200+ :: .^(arch %gy /=gh={/endpoint}) to explore the possible
201+ :: endpoints.
264202 ::
265− :: Types of webhooks we expect.
203+ :: - subscribe to /listen/{owner}/{repo}/{events...} for
204+ :: webhook-powered event notifications. For event list, see
205+ :: https://developer.github.com/webhooks/.
266206 ::
267− ++ hook-response
268− $% {$gh-issues issues:gh}
269− {$gh-issue-comment issue-comment:gh}
270− ==
271− --
272−=+ connector=(connector move sub-result) :: Set up connector library
273−::
274−|_ $: hid/bowl
275− hook/(map @t {id/@t listeners/(set bone)}) :: map events to listeners
276− ==
277−:: ++ prep _`. :: Clear state when code changes
278−::
279−:: List of endpoints
280−::
281−++ places
282− |= wir/wire
283− ^- (list place:connector)
284− =+ (helpers:connector ost.hid wir "https://api.github.com")
285− => |% :: gh-specific helpers
286− ++ sigh-list-issues-x
287− |= jon/json
288− %+ bind ((ar:jo issue:gh-parse) jon)
289− |= issues/(list issue:gh)
290− gh-list-issues+issues
291− ::
292− ++ sigh-list-issues-y
293− |= jon/json
294− %+ bind ((ar:jo issue:gh-parse) jon)
295− |= issues/(list issue:gh)
296− :- `(shax (jam issues))
297− (malt (turn issues |=(issue:gh [(rsh 3 2 (scot %ui number)) ~])))
298− --
299− :~ ^- place :: /
300− :* guard=$~
301− read-x=read-null
302− read-y=(read-static %issues ~)
303− sigh-x=sigh-strange
304− sigh-y=sigh-strange
305− ==
306− ^- place :: /issues
307− :* guard={$issues $~}
308− read-x=read-null
309− read-y=(read-static %mine %by-repo ~)
310− sigh-x=sigh-strange
311− sigh-y=sigh-strange
312− ==
313− ^- place :: /issues/mine
314− :* guard={$issues $mine $~}
315− read-x=(read-get /issues)
316− read-y=(read-get /issues)
317− sigh-x=sigh-list-issues-x
318− sigh-y=sigh-list-issues-y
319− ==
320− ^- place :: /issues/by-repo
321− :* guard={$issues $by-repo $~}
322− read-x=read-null
323− ^= read-y
324− |= pax/path
325− =+ /(scot %p our.hid)/home/(scot %da now.hid)/web/plan
326− =+ .^({* acc/(map knot plan-acct)} %cx -)
207+ :: This is written with the standard structure for api
208+ :: connectors, as described in lib/connector.hoon.
209+ ::
210+ /? 314
211+ /- gh, plan-acct
212+ /+ gh-parse, connector
213+ ::
214+ !:
215+ => |%
216+ ++ move (pair bone card)
217+ ++ card
218+ $% {$diff sub-result}
219+ {$them wire (unit hiss)}
220+ {$hiss wire {$~ $~} $httr {$hiss hiss}}
221+ ==
327222 ::
328− ((read-static usr:(~(got by acc) %github) ~) pax)
329− sigh-x=sigh-strange
330− sigh-y=sigh-strange
331− ==
332− ^- place :: /issues/by-repo/<user>
333− :* guard={$issues $by-repo @t $~}
334− read-x=read-null
335− read-y=|=(pax/path (get /users/[-.+>.pax]/repos))
336− sigh-x=sigh-strange
337− ^= sigh-y
338− |= jon/json
339− %+ bind ((ar:jo repository:gh-parse) jon)
340− |= repos/(list repository:gh)
341− [~ (malt (turn repos |=(repository:gh [name ~])))]
342− ==
343− ^- place :: /issues/by-repo/<user>/<repo>
344− :* guard={$issues $by-repo @t @t $~}
345− read-x=|=(pax/path (get /repos/[-.+>.pax]/[-.+>+.pax]/issues))
346− read-y=|=(pax/path (get /repos/[-.+>.pax]/[-.+>+.pax]/issues))
347− sigh-x=sigh-list-issues-x
348− sigh-y=sigh-list-issues-y
349− ==
350− ^- place :: /issues/by-repo/<user>/<repo>
351− :* guard={$issues $by-repo @t @t @t $~}
352− ^= read-x
353− |=(pax/path (get /repos/[-.+>.pax]/[-.+>+.pax]/issues/[-.+>+>.pax]))
223+ :: Types of results we produce to subscribers.
354224 ::
355− read-y=(read-static ~)
356− ^= sigh-x
357− |= jon/json
358− %+ bind (issue:gh-parse jon)
359− |= issue/issue:gh
360− gh-issue+issue
225+ ++ sub-result
226+ $% {$arch arch}
227+ {$gh-issue issue:gh}
228+ {$gh-list-issues (list issue:gh)}
229+ {$gh-issues issues:gh}
230+ {$gh-issue-comment issue-comment:gh}
231+ {$json json}
232+ {$null $~}
233+ ==
361234 ::
362− sigh-y=sigh-strange
363− ==
364− ==
365−::
366−:: When a peek on a path blocks, ford turns it into a peer on
367−:: /scry/{care}/{path}. You can also just peer to this
368−:: directly.
369−::
370−:: We hand control to ++scry.
371−::
372−++ peer-scry
373− |= pax/path
374− ^- {(list move) _+>.$}
375− ?> ?=({care *} pax)
376− :_ +>.$ :_ ~
377− (read:connector ost.hid (places %read pax) i.pax t.pax)
378−::
379−:: HTTP response. We make sure the response is good, then
380−:: produce the result (as JSON) to whoever sent the request.
381−::
382−++ sigh-httr
383− |= {way/wire res/httr}
384− ^- {(list move) _+>.$}
385− ?. ?=({$read care @ *} way)
386− ~& res=res
387− [~ +>.$]
388− =* style i.way
389− =* ren i.t.way
390− =* pax t.t.way
391− :_ +>.$ :_ ~
392− :+ ost.hid %diff
393− (sigh:connector (places ren style pax) ren pax res)
394−::
395−:: HTTP error. We just print it out, though maybe we should
396−:: also produce a result so that the request doesn't hang?
397−::
398−++ sigh-tang
399− |= {way/wire tan/tang}
400− ^- {(list move) _+>.$}
401− %- (slog >%gh-sigh-tang< tan)
402− [[ost.hid %diff null+~]~ +>.$]
403−::
404−:: We can't actually give the response to pretty much anything
405−:: without blocking, so we just block unconditionally.
406−::
407−++ peek
408− |= {ren/@tas tyl/path}
409− ^- (unit (unit (pair mark *)))
410− ~ ::``noun/[ren tyl]
411−::
412−::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
413−:: Webhook-powered event streams (/listen) ::
414−::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
415−::
416−:: To listen to a webhook-powered stream of events, subscribe
417−:: to /listen/<user>/<repo>/<events...>
418−::
419−:: We hand control to ++listen.
420−::
421−++ peer-listen
422− |= pax/path
423− ^- {(list move) _+>.$}
424− ?. ?=({@ @ *} pax)
425− ~& [%bad-listen-path pax]
426− [~ +>.$]
427− (listen pax)
428−::
429−:: This core handles event subscription requests by starting or
430−:: updating the webhook flow for each event.
431−::
432−++ listen
433− |= pax/path
434− =| mow/(list move)
435− =< abet:listen
436− |%
437− ++ abet :: Resolve core.
438− ^- {(list move) _+>.$}
439− [(flop mow) +>.$]
440− ::
441− ++ send-hiss :: Send a hiss
442− |= hiz/hiss
443− ^+ +>
444− =+ wir=`wire`[%x %listen pax]
445− +>.$(mow [[ost.hid %hiss wir `~ %httr [%hiss hiz]] mow])
446− ::
447− :: Create or update a webhook to listen for a set of events.
448− ::
449− ++ listen
450− ^+ .
451− =+ pax=pax :: TMI-proofing
452− ?> ?=({@ @ *} pax)
453− =+ events=t.t.pax
454− |- ^+ +>+.$
455− ?~ events
456− +>+.$
457− ?: (~(has by hook) i.events)
458− $(+>+ (update-hook i.events), events t.events)
459− $(+>+ (create-hook i.events), events t.events)
460− ::
461− :: Set up a webhook.
462− ::
463− ++ create-hook
464− |= event/@t
465− ^+ +>
466− ?> ?=({@ @ *} pax)
467− =+ clean-event=`tape`(turn (trip event) |=(a/@tD ?:(=('_' a) '-' a)))
468− =. hook
469− %+ ~(put by hook) (crip clean-event)
470− =+ %+ fall
471− (~(get by hook) (crip clean-event))
472− *{id/@t listeners/(set bone)}
473− [id (~(put in listeners) ost.hid)]
474− %- send-hiss
475− :* %+ scan
476− =+ [(trip i.pax) (trip i.t.pax)]
477− "https://api.github.com/repos/{-<}/{->}/hooks"
478− auri:epur
479− %post ~ ~
480− %- taco %- crip %- pojo %- jobe :~
481− name+s+%web
482− active+b+&
483− events+a+~[s+event] ::(turn `(list ,@t)`t.t.pax |=(a=@t s/a))
484− :- %config
485− %- jobe :~
486− =+ =+ clean-event
487− "http://107.170.195.5:8443/~/to/gh/gh-{-}.json?anon&wire=/"
488− [%url s+(crip -)]
489− [%'content_type' s+%json]
235+ :: Types of webhooks we expect.
236+ ::
237+ ++ hook-response
238+ $% {$gh-issues issues:gh}
239+ {$gh-issue-comment issue-comment:gh}
240+ ==
241+ --
242+ =+ connector=(connector move sub-result) :: Set up connector library
243+ ::
244+ |_ $: hid/bowl
245+ hook/(map @t {id/@t listeners/(set bone)}) :: map events to listeners
246+ ==
247+ :: ++ prep _`. :: Clear state when code changes
248+ ::
249+ :: List of endpoints
250+ ::
251+ ++ places
252+ |= wir/wire
253+ ^- (list place:connector)
254+ =+ (helpers:connector ost.hid wir "https://api.github.com")
255+ => |% :: gh-specific helpers
256+ ++ sigh-list-issues-x
257+ |= jon/json
258+ %+ bind ((ar:jo issue:gh-parse) jon)
259+ |= issues/(list issue:gh)
260+ gh-list-issues+issues
261+ ::
262+ ++ sigh-list-issues-y
263+ |= jon/json
264+ %+ bind ((ar:jo issue:gh-parse) jon)
265+ |= issues/(list issue:gh)
266+ :- `(shax (jam issues))
267+ (malt (turn issues |=(issue:gh [(rsh 3 2 (scot %ui number)) ~])))
268+ --
269+ :~ ^- place :: /
270+ :* guard=$~
271+ read-x=read-null
272+ read-y=(read-static %issues ~)
273+ sigh-x=sigh-strange
274+ sigh-y=sigh-strange
275+ ==
276+ ^- place :: /issues
277+ :* guard={$issues $~}
278+ read-x=read-null
279+ read-y=(read-static %mine %by-repo ~)
280+ sigh-x=sigh-strange
281+ sigh-y=sigh-strange
282+ ==
283+ ^- place :: /issues/mine
284+ :* guard={$issues $mine $~}
285+ read-x=(read-get /issues)
286+ read-y=(read-get /issues)
287+ sigh-x=sigh-list-issues-x
288+ sigh-y=sigh-list-issues-y
289+ ==
290+ ^- place :: /issues/by-repo
291+ :* guard={$issues $by-repo $~}
292+ read-x=read-null
293+ ^= read-y
294+ |= pax/path
295+ =+ /(scot %p our.hid)/home/(scot %da now.hid)/web/plan
296+ =+ .^({* acc/(map knot plan-acct)} %cx -)
297+ ::
298+ ((read-static usr:(~(got by acc) %github) ~) pax)
299+ sigh-x=sigh-strange
300+ sigh-y=sigh-strange
301+ ==
302+ ^- place :: /issues/by-repo/<user>
303+ :* guard={$issues $by-repo @t $~}
304+ read-x=read-null
305+ read-y=|=(pax/path (get /users/[-.+>.pax]/repos))
306+ sigh-x=sigh-strange
307+ ^= sigh-y
308+ |= jon/json
309+ %+ bind ((ar:jo repository:gh-parse) jon)
310+ |= repos/(list repository:gh)
311+ [~ (malt (turn repos |=(repository:gh [name ~])))]
312+ ==
313+ ^- place :: /issues/by-repo/<user>/<repo>
314+ :* guard={$issues $by-repo @t @t $~}
315+ read-x=|=(pax/path (get /repos/[-.+>.pax]/[-.+>+.pax]/issues))
316+ read-y=|=(pax/path (get /repos/[-.+>.pax]/[-.+>+.pax]/issues))
317+ sigh-x=sigh-list-issues-x
318+ sigh-y=sigh-list-issues-y
490319 ==
320+ ^- place :: /issues/by-repo/<user>/<repo>
321+ :* guard={$issues $by-repo @t @t @t $~}
322+ ^= read-x
323+ |=(pax/path (get /repos/[-.+>.pax]/[-.+>+.pax]/issues/[-.+>+>.pax]))
324+ ::
325+ read-y=(read-static ~)
326+ ^= sigh-x
327+ |= jon/json
328+ %+ bind (issue:gh-parse jon)
329+ |= issue/issue:gh
330+ gh-issue+issue
331+ ::
332+ sigh-y=sigh-strange
333+ ==
334+ ==
335+ ::
336+ :: When a peek on a path blocks, ford turns it into a peer on
337+ :: /scry/{care}/{path}. You can also just peer to this
338+ :: directly.
339+ ::
340+ :: We hand control to ++scry.
341+ ::
342+ ++ peer-scry
343+ |= pax/path
344+ ^- {(list move) _+>.$}
345+ ?> ?=({care *} pax)
346+ :_ +>.$ :_ ~
347+ (read:connector ost.hid (places %read pax) i.pax t.pax)
348+ ::
349+ :: HTTP response. We make sure the response is good, then
350+ :: produce the result (as JSON) to whoever sent the request.
351+ ::
352+ ++ sigh-httr
353+ |= {way/wire res/httr}
354+ ^- {(list move) _+>.$}
355+ ?. ?=({$read care @ *} way)
356+ ~& res=res
357+ [~ +>.$]
358+ =* style i.way
359+ =* ren i.t.way
360+ =* pax t.t.way
361+ :_ +>.$ :_ ~
362+ :+ ost.hid %diff
363+ (sigh:connector (places ren style pax) ren pax res)
364+ ::
365+ :: HTTP error. We just print it out, though maybe we should
366+ :: also produce a result so that the request doesn't hang?
367+ ::
368+ ++ sigh-tang
369+ |= {way/wire tan/tang}
370+ ^- {(list move) _+>.$}
371+ %- (slog >%gh-sigh-tang< tan)
372+ [[ost.hid %diff null+~]~ +>.$]
373+ ::
374+ :: We can't actually give the response to pretty much anything
375+ :: without blocking, so we just block unconditionally.
376+ ::
377+ ++ peek
378+ |= {ren/@tas tyl/path}
379+ ^- (unit (unit (pair mark *)))
380+ ~ ::``noun/[ren tyl]
381+ ::
382+ ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
383+ :: Webhook-powered event streams (/listen) ::
384+ ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
385+ ::
386+ :: To listen to a webhook-powered stream of events, subscribe
387+ :: to /listen/<user>/<repo>/<events...>
388+ ::
389+ :: We hand control to ++listen.
390+ ::
391+ ++ peer-listen
392+ |= pax/path
393+ ^- {(list move) _+>.$}
394+ ?. ?=({@ @ *} pax)
395+ ~& [%bad-listen-path pax]
396+ [~ +>.$]
397+ (listen pax)
398+ ::
399+ :: This core handles event subscription requests by starting or
400+ :: updating the webhook flow for each event.
401+ ::
402+ ++ listen
403+ |= pax/path
404+ =| mow/(list move)
405+ =< abet:listen
406+ |%
407+ ++ abet :: Resolve core.
408+ ^- {(list move) _+>.$}
409+ [(flop mow) +>.$]
410+ ::
411+ ++ send-hiss :: Send a hiss
412+ |= hiz/hiss
413+ ^+ +>
414+ =+ wir=`wire`[%x %listen pax]
415+ +>.$(mow [[ost.hid %hiss wir `~ %httr [%hiss hiz]] mow])
416+ ::
417+ :: Create or update a webhook to listen for a set of events.
418+ ::
419+ ++ listen
420+ ^+ .
421+ =+ pax=pax :: TMI-proofing
422+ ?> ?=({@ @ *} pax)
423+ =+ events=t.t.pax
424+ |- ^+ +>+.$
425+ ?~ events
426+ +>+.$
427+ ?: (~(has by hook) i.events)
428+ $(+>+ (update-hook i.events), events t.events)
429+ $(+>+ (create-hook i.events), events t.events)
430+ ::
431+ :: Set up a webhook.
432+ ::
433+ ++ create-hook
434+ |= event/@t
435+ ^+ +>
436+ ?> ?=({@ @ *} pax)
437+ =+ clean-event=`tape`(turn (trip event) |=(a/@tD ?:(=('_' a) '-' a)))
438+ =. hook
439+ %+ ~(put by hook) (crip clean-event)
440+ =+ %+ fall
441+ (~(get by hook) (crip clean-event))
442+ *{id/@t listeners/(set bone)}
443+ [id (~(put in listeners) ost.hid)]
444+ %- send-hiss
445+ :* %+ scan
446+ =+ [(trip i.pax) (trip i.t.pax)]
447+ "https://api.github.com/repos/{-<}/{->}/hooks"
448+ auri:epur
449+ %post ~ ~
450+ %- taco %- crip %- pojo %- jobe :~
451+ name+s+%web
452+ active+b+&
453+ events+a+~[s+event] ::(turn `(list ,@t)`t.t.pax |=(a=@t s/a))
454+ :- %config
455+ %- jobe :~
456+ =+ =+ clean-event
457+ "http://107.170.195.5:8443/~/to/gh/gh-{-}.json?anon&wire=/"
458+ [%url s+(crip -)]
459+ [%'content_type' s+%json]
460+ ==
461+ ==
462+ ==
463+ ::
464+ :: Add current bone to the list of subscribers for this event.
465+ ::
466+ ++ update-hook
467+ |= event/@t
468+ ^+ +>
469+ =+ hok=(~(got by hook) event)
470+ %_ +>.$
471+ hook
472+ %+ ~(put by hook) event
473+ hok(listeners (~(put in listeners.hok) ost.hid))
491474 ==
492− ==
493− ::
494− :: Add current bone to the list of subscribers for this event.
495− ::
496− ++ update-hook
497− |= event/@t
498− ^+ +>
499− =+ hok=(~(got by hook) event)
500− %_ +>.$
501− hook
502− %+ ~(put by hook) event
503− hok(listeners (~(put in listeners.hok) ost.hid))
504− ==
505− --
506−::
507−:: Pokes that aren't caught in more specific arms are handled
508−:: here. These should be only from webhooks firing, so if we
509−:: get any mark that we shouldn't get from a webhook, we reject
510−:: it. Otherwise, we spam out the event to everyone who's
511−:: listening for that event.
512−::
513−++ poke
514− |= response/hook-response
515− ^- {(list move) _+>.$}
516− =+ hook-data=(~(get by hook) (rsh 3 3 -.response))
517− ?~ hook-data
518− ~& [%strange-hook hook response]
519− [~ +>.$]
520− :: ~& response=response
521− :_ +>.$
522− %+ turn (~(tap in listeners.u.hook-data))
523− |= ost/bone
524− [ost %diff response]
525−--
526−```
475+ --
476+ ::
477+ :: Pokes that aren't caught in more specific arms are handled
478+ :: here. These should be only from webhooks firing, so if we
479+ :: get any mark that we shouldn't get from a webhook, we reject
480+ :: it. Otherwise, we spam out the event to everyone who's
481+ :: listening for that event.
482+ ::
483+ ++ poke
484+ |= response/hook-response
485+ ^- {(list move) _+>.$}
486+ =+ hook-data=(~(get by hook) (rsh 3 3 -.response))
487+ ?~ hook-data
488+ ~& [%strange-hook hook response]
489+ [~ +>.$]
490+ :: ~& response=response
491+ :_ +>.$
492+ %+ turn (~(tap in listeners.u.hook-data))
493+ |= ost/bone
494+ [ost %diff response]
495+ --
docs/arvo/basic.md+103−113
@@ -1,49 +1,43 @@
11---
2−navhome: /docs/
2+navhome: '/docs/'
3+next: True
34sort: 11
4−next: true
55title: Basic Hoon
66---
77
8−Basic Hoon
9−==========
8+# Basic Hoon
109
11−Our goal is to get you programming interesting and useful things as soon
12−as possible. To get there, we have to quickly cover some of the
13−fundamentals of [Hoon](/docs/hoon/). To do this, we'll walk through two simple
14−programs: the first [Project Euler](https://projecteuler.net/) problem
15−and [fizzbuzz](https://en.wikipedia.org/wiki/Fizz_buzz).
10+Our goal is to get you programming interesting and useful things as soon as
11+possible. To get there, we have to quickly cover some of the fundamentals of
12+[Hoon](/docs/hoon/). To do this, we'll walk through two simple programs: the
13+first [Project Euler](https://projecteuler.net/) problem and
14+[fizzbuzz](https://en.wikipedia.org/wiki/Fizz_buzz).
1615
17−To run this code, you'll need an urbit, and will have to copy the
18−[examples repo](https://github.com/urbit/examples) into it.
16+To run this code, you'll need an urbit, and will have to copy the [examples
17+repo](https://github.com/urbit/examples) into it.
1918
2019If you haven't installed urbit yet, check out the [installation
21−instructions](/docs/using/install). Once urbit is installed, take a look
22−at the [basic operation](/docs/using/admin) of your urbit.
20+instructions](/docs/using/install). Once urbit is installed, take a look at the
21+[basic operation](/docs/using/admin) of your urbit.
2322
24−If you haven't copied in the examples repo, running the following
25−commands from your urbit directory should do the trick:
23+If you haven't copied in the examples repo, running the following commands from
24+your urbit directory should do the trick:
2625
2726Make sure you've mounted your `%home` desk:
2827
29−```
30−~fintud-macrep:dojo> |mount %
31−```
28+ ~fintud-macrep:dojo> |mount %
3229
3330Then, copy the example into it
3431
35−```
36−$ cp -r {urbit-examples}/gall/*/* {your-pier}/home/
37−$ cp -r {urbit-examples}/dojo/*/* {your-pier}/home/
38−```
32+ $ cp -r {urbit-examples}/gall/*/* {your-pier}/home/
33+ $ cp -r {urbit-examples}/dojo/*/* {your-pier}/home/
3934
4035Run an example to ensure it worked:
4136
4237 ~fintud-macrep:dojo> +examples-euler1
4338 233.168
4439
45−Euler 1
46−-------
40+## Euler 1
4741
4842Let's check out the code for Euler 1. First, the problem:
4943
@@ -91,11 +85,11 @@ Here is the hoon solution (which should be in your pier directory under
9185 (add (five a) (three a))
9286 --
9387
94−> Hoon is not generally whitespace sensitive, but we do have two
95−> different kinds of whitespace: a single space and a gap, which is two
96−> or more spaces or a linebreak. Tabs are taboo. Do not use them.
97−> Really. For a more detailed explanation of when to use spaces vs.
98−> gaps, see the syntax section before the first exercises.
88+> Hoon is not generally whitespace sensitive, but we do have two different kinds
89+> of whitespace: a single space and a gap, which is two or more spaces or a
90+> linebreak. Tabs are taboo. Do not use them. Really. For a more detailed
91+> explanation of when to use spaces vs. gaps, see the syntax section before the
92+> first exercises.
9993
10094### Lines 1-11:
10195
@@ -106,31 +100,29 @@ Any line that begins with `::` is a comment.
106100 =< (sum 1.000)
107101
108102All you need to know about the lines above is that they call the `++sum`
109−function with an argument of `1.000`. We'll cover them in more detail
110−later.
103+function with an argument of `1.000`. We'll cover them in more detail later.
111104
112105### How to form expressions
113106
114107Hoon does not typically use reserved words to form expressions. Instead,
115−expressions are formed with *runes*: digraphs of two ASCII symbols. Each
116−rune takes a specific number of children, either expressions formed by
117−other runes or literals that produce their own value (some runes take
118−*N* children, and are usually closed with `==`).
108+expressions are formed with *runes*: digraphs of two ASCII symbols. Each rune
109+takes a specific number of children, either expressions formed by other runes or
110+literals that produce their own value (some runes take *N* children, and are
111+usually closed with `==`).
119112
120−For example, the rune `?:` from line 18 is the classic 'if-then-else'
121−statement, and thus takes three children:
113+For example, the rune `?:` from line 18 is the classic 'if-then-else' statement,
114+and thus takes three children:
122115
123116 ?: (lth a b) :: if first child evals to true
124117 0 :: then produce result of second
125118 (add b $(b (add 3 b))) :: else, produce result of third
126119
127120Since runes are such a fundamental structure in Hoon, we found ourselves
128−speaking them out loud frequently. It quickly grew cumbersome to have to
129−say "question mark, colon" to describe `?:`. To alleviate this problem,
130−we came up with our own naming scheme: each ASCII glyph has a
131−single-syllable pronunciation phonetically designed to be both easily
132−remembered and easily pronounced in conjunction with the other glyphs
133−(when forming a rune).
121+speaking them out loud frequently. It quickly grew cumbersome to have to say
122+"question mark, colon" to describe `?:`. To alleviate this problem, we came up
123+with our own naming scheme: each ASCII glyph has a single-syllable pronunciation
124+phonetically designed to be both easily remembered and easily pronounced in
125+conjunction with the other glyphs (when forming a rune).
134126
135127See the entire naming scheme below.
136128
@@ -150,9 +142,8 @@ See the entire naming scheme below.
150142Using this scheme, we would pronounce `?:` as 'wutcol'.
151143
152144For those who prefer to use reserved words to form expressions, you can
153−substitute any rune with that rune's keyword, which you can find in
154−`++twig` in `/arvo/hoon.hoon`. For example, here's the code for `?:` in
155−`++twig`:
145+substitute any rune with that rune's keyword, which you can find in `++twig` in
146+`/arvo/hoon.hoon`. For example, here's the code for `?:` in `++twig`:
156147
157148`{$if p/twig q/twig r/twig} :: ?: if/then/else`
158149
@@ -168,16 +159,16 @@ You can write:
168159
169160### Lines 13-35
170161
171−Now let's quickly walk through this code line-by-line. Lines 13-35 are
172−wrapped in a `|%` ('[barcen](../../hoon/twig/bar-core/cen-core/)'), which produces a core. Cores are a
173−fundamental datatype in Hoon, similar to a struct, class, or object. A
174−core is just a map of names to any kind of code, whether it be functions
175−or data. Each element in this map begins with a `++` followed by the
162+Now let's quickly walk through this code line-by-line. Lines 13-35 are wrapped
163+in a `|%` ('[barcen](../../hoon/twig/bar-core/cen-core/)'), which produces a
164+core. Cores are a fundamental datatype in Hoon, similar to a struct, class, or
165+object. A core is just a map of names to any kind of code, whether it be
166+functions or data. Each element in this map begins with a `++` followed by the
176167name and the corresponding code. Since `|%` takes an arbitrary number of
177168children, it needs to be closed with a `--`.
178169
179−> `++` ('luslus') is not technically a rune, since it is only used in
180−> core syntax, as shown above.
170+> `++` ('luslus') is not technically a rune, since it is only used in core
171+> syntax, as shown above.
181172
182173Let's step into each of the three arms within our core.
183174
@@ -188,17 +179,16 @@ Let's step into each of the three arms within our core.
188179 (add (five a) (three a))
189180 --
190181
191−`|=` ('[bartis](../../hoon/twig/bar-core/tis-gate/)') produces a function, much like a lambda in lisp. It
192−takes two children:
182+`|=` ('[bartis](../../hoon/twig/bar-core/tis-gate/)') produces a function, much
183+like a lambda in lisp. It takes two children:
193184
194−1. A set of argument(s). In this case our argument set only contains
195− one: `a`, which is required to be an atom or natural number, denoted
196− by `@`.
185+1. A set of argument(s). In this case our argument set only contains one: `a`,
186+ which is required to be an atom or natural number, denoted by `@`.
197187
198−2. The body of the function itself, which is executed when the function
199− is called (in this case, with `(sum 1.000)`). This particular
200− function adds the results of evaluating the gates `++ five` and
201− `++three` with each of their respective input parameters set to `a`.
188+2. The body of the function itself, which is executed when the function is
189+ called (in this case, with `(sum 1.000)`). This particular function adds the
190+ results of evaluating the gates `++ five` and `++three` with each of their
191+ respective input parameters set to `a`.
202192
203193### ++ three
204194
@@ -210,17 +200,17 @@ takes two children:
210200 0
211201 (add b $(b (add 3 b)))
212202
213−As above, `++three` takes an integer argument, `a`, and then executes
214−the remainder of the code with `a` set to the actual arguments.
203+As above, `++three` takes an integer argument, `a`, and then executes the
204+remainder of the code with `a` set to the actual arguments.
215205
216−Similarly, `=|` ('[tisbar](../../hoon/twig/tis-flow/bar-new/)') pushes its first child, `b` into our context
217−(in other words, it declares a variable `b`) and executes the remainder
218−of the code. However, `b` is not an argument; `=|` sets `b` to the
219−default value of whatever type it is declared as. Since the default
206+Similarly, `=|` ('[tisbar](../../hoon/twig/tis-flow/bar-new/)') pushes its first
207+child, `b` into our context (in other words, it declares a variable `b`) and
208+executes the remainder of the code. However, `b` is not an argument; `=|` sets
209+`b` to the default value of whatever type it is declared as. Since the default
220210value of an atom is `0`, b is set to `0`.
221211
222−> To produce the default value of any given type, use `*` ('tar')
223−> followed by the type. This operaction is called *bunt*.
212+> To produce the default value of any given type, use `*` ('tar') followed by
213+> the type. This operaction is called *bunt*.
224214>
225215> > *@ :: produce the default value of atom @
226216> 0
@@ -228,25 +218,24 @@ value of an atom is `0`, b is set to `0`.
228218> > *@p :: produce the phonemic base of atom @
229219> ~zod
230220
231−So now we have two variables: `a` is set to our input, and `b` is
232−initialized to `0`.
221+So now we have two variables: `a` is set to our input, and `b` is initialized to
222+`0`.
233223
234−One way to think about `|-` ('[barhep](../../hoon/twig/bar-core/hep-loop/)') is that it lays down a recursion
235−point. More on this later.
224+One way to think about `|-` ('[barhep](../../hoon/twig/bar-core/hep-loop/)') is
225+that it lays down a recursion point. More on this later.
236226
237−`^-` ('[kethep](../../hoon/core/ket-cast/hep-cast/)') is just a cast that sets the result of the remainder of
238−the code to an unsigned integer, `@u`.
227+`^-` ('[kethep](../../hoon/core/ket-cast/hep-cast/)') is just a cast that sets
228+the result of the remainder of the code to an unsigned integer, `@u`.
239229
240−In pseudocode, the last three lines read like this: if `a` is less than
241−`b`, produce zero. Else, add `b` to the result of rerunning the segment
242−of the function following the `|-` with the value of `b` changed to `b`
243−plus three.
230+In pseudocode, the last three lines read like this: if `a` is less than `b`,
231+produce zero. Else, add `b` to the result of rerunning the segment of the
232+function following the `|-` with the value of `b` changed to `b` plus three.
244233
245234The only thing that should look completely unfamiliar to you here is the
246−`$(b (add 3 b))`, which causes us to recurse back to our last recursion
247−point with the value of `b` set to `(add 3 b)`. Note that we only
248−specify what changes (`b` in this case). If you recurse by an actual
249−function call, then you have to specify every argument.
235+`$(b (add 3 b))`, which causes us to recurse back to our last recursion point
236+with the value of `b` set to `(add 3 b)`. Note that we only specify what changes
237+(`b` in this case). If you recurse by an actual function call, then you have to
238+specify every argument.
250239
251240> If you're familiar with Clojure, `|-` is `loop` and `$()` is `recur`.
252241
@@ -254,18 +243,18 @@ function call, then you have to specify every argument.
254243
255244Tweak your code to complete the following exercises.
256245
257−There are a few runes and some syntax that we have yet to cover that you
258−will need to complete the exercises below. For these, please refer to
259−our cheatsheat at the bottom.
246+There are a few runes and some syntax that we have yet to cover that you will
247+need to complete the exercises below. For these, please refer to our cheatsheat
248+at the bottom.
260249
2612501. Read and understand `++five` line by line.
262251
263−2. Change `++sum` to accept two variables, `a` and `b`. Pass `a` to
264− `three` and `b` to `five`. Then run the code with `a` set to `1.000`
265− and `b` set to `2.000`.
252+2. Change `++sum` to accept two variables, `a` and `b`. Pass `a` to `three` and
253+ `b` to `five`. Then run the code with `a` set to `1.000` and `b` set to
254+ `2.000`.
266255
267−3. Check if this new result is under one thousand. If it is, return the
268− string `'result < 1.000'`. If not, return `'result >= 1.000'`.
256+3. Check if this new result is under one thousand. If it is, return the string
257+ `'result < 1.000'`. If not, return `'result >= 1.000'`.
269258
270259### Review
271260
@@ -278,39 +267,40 @@ our cheatsheat at the bottom.
278267 =(a b) test equality
279268 (function args ...) call function with args
280269
281−Lookup each of these expressions (and all others!) in the [Twig Expressions](../../hoon/twig/) definition.
270+Lookup each of these expressions (and all others!) in the [Twig
271+Expressions](../../hoon/twig/) definition.
282272
283273### New material
284274
2852751. There are two syntaxes for writing Hoon: tallform and wideform.
286276
287− In tallform, expressions are formed with either two spaces or a line
288− break separating both a rune from its children and each of its children
289− from one another. We use tallform when writing multiline expressions.
277+ In tallform, expressions are formed with either two spaces or a line break
278+ separating both a rune from its children and each of its children from one
279+ another. We use tallform when writing multiline expressions.
290280
291281 For more concise expressions, we use wideform, which is always a single
292− line. Wideform can be used inside tallform expressions, but not vice
293− versa.
282+ line. Wideform can be used inside tallform expressions, but not vice versa.
294283
295− Wideform expressions are formed with a rune followed by `()` containing
296− its children, all of which are separated by a single space. For example,
297− to make a cell of two elements, use `:-(a b)`.
284+ Wideform expressions are formed with a rune followed by `()` containing its
285+ children, all of which are separated by a single space. For example, to make
286+ a cell of two elements, use `:-(a b)`.
298287
299− We've already seen wideform in action, for example with
300− `=((mod b 3) 0)`. In this case, `=` is actually an irregular form of
301− `.=`, which tests its two children for equality.
288+ We've already seen wideform in action, for example with `=((mod b 3) 0)`. In
289+ this case, `=` is actually an irregular form of `.=`, which tests its two
290+ children for equality.
302291
303292 Surrounding a function with `()` is an irregular wide form syntax for
304293 calling a function with *N* arguments. More on this later.
305294
306−2. For a set of multiple arguments following `|=` ('[bartis](../../hoon/twig/bar-core/tis-gate/)'), use `{` 'kel' and `}` 'ker.' For example: `{a/@u b/@u}`.
295+2. For a set of multiple arguments following `|=`
296+ ('[bartis](../../hoon/twig/bar-core/tis-gate/)'), use `{` 'kel' and `}`
297+ 'ker.' For example: `{a/@u b/@u}`.
307298
308−3. `:-` makes a cell of values. The irregular wide form of this is
309− `[a b]`, with two expressions separated by a single space. While the
310− regular form of this rune takes a fixed number of children (two),
311− its irregular wide form can accept *N* expressions: `[a1..an]`.
299+3. `:-` makes a cell of values. The irregular wide form of this is `[a b]`,
300+ with two expressions separated by a single space. While the regular form of
301+ this rune takes a fixed number of children (two), its irregular wide form
302+ can accept *N* expressions: `[a1..an]`.
312303
313−4. Cords are one datatype for text in Hoon. They're just a big atom
314− formed from adjacent unicode bytes -- a "c string". To produce a
315− cord, enclose text within single quotes. To set the type of an
316− argument to a cord, use `@t`.
304+4. Cords are one datatype for text in Hoon. They're just a big atom formed from
305+ adjacent unicode bytes -- a "c string". To produce a cord, enclose text
306+ within single quotes. To set the type of an argument to a cord, use `@t`.
docs/arvo/generators.md+76−86
@@ -7,66 +7,60 @@ title: Using generators with apps
77
88# Generators
99
10−Up until now we've poked apps directly. This requires the user to
11−specify the mark, and it requires the app to accept the arguments in a
12−way that's convenient for users to input. This is the "plumbing" way to
13−interact with apps. Generators are the "porcelain" layer. This is why
14−when you run a command like `+ls` or `|merge`, there are no marks in
15−sight.
16−
17−We've used generators before, back in [Basic
18−Operation](/docs/using/admin). At that point, we just used the
19−generators to produce values -- we didn't pipe their results into apps.
20−In the dojo cast, the role of a generator is to take a list of arguments
21−and produce a value, which is often, though not always, piped into an
22−app. Generators are pure, stateless functions, and they cannot send
10+Up until now we've poked apps directly. This requires the user to specify the
11+mark, and it requires the app to accept the arguments in a way that's convenient
12+for users to input. This is the "plumbing" way to interact with apps. Generators
13+are the "porcelain" layer. This is why when you run a command like `+ls` or
14+`|merge`, there are no marks in sight.
15+
16+We've used generators before, back in [Basic Operation](/docs/using/admin). At
17+that point, we just used the generators to produce values -- we didn't pipe
18+their results into apps. In the dojo cast, the role of a generator is to take a
19+list of arguments and produce a value, which is often, though not always, piped
20+into an app. Generators are pure, stateless functions, and they cannot send
2321moves.
2422
25−`+ls` and `+cat` are commonly-used generators that produce a directory
26−listing and print out a file, respectively. These are useful in
27−themselves, so we generally don't pipe the results into an app.
23+`+ls` and `+cat` are commonly-used generators that produce a directory listing
24+and print out a file, respectively. These are useful in themselves, so we
25+generally don't pipe the results into an app.
2826
29−Another generator is `+hood/merge`. Try running `+hood/merge` with the
30−normal arguments for `|merge`:
27+Another generator is `+hood/merge`. Try running `+hood/merge` with the normal
28+arguments for `|merge`:
3129
3230 ~fintud-macrep:dojo> +hood/merge %home our %they
3331 [syd=%home her=~fintud-macrep sud=%they gem=%auto]
3432 ~fintud-macrep:dojo> +hood/merge %home our %they, =gem %this
3533 [syd=%home her=~fintud-macrep sud=%they gem=%auto]
3634
37−This didn't run any merge, it just constructed the command that, if sent
38−to `:hood`, would run it. Note first that, even though it's not printed,
39−this value has mark `kiln-merge`. Also, the merge strategy `gem=%auto`
40−was added automatically. Optional arguments are straightforward with
41−generators.
42−
43−In general, generators are prepended by either `+` or `|`. The general
44−form is `+generator`, but often generators are created specifically to
45−work with a single app, they're usually placed in a subdirectory of gen
46−and run with `|`. Thus, if `my-generator` generator is made for use with
47−`:my-app`, then `my-generator` is put in
48−`/gen/my-app/my-generator.hoon`, and can be run directly with
49−`+my-app/my-generator <args>`. If you want to pipe the result into
50−`:my-app`, then run `:my-app +my-app/my-generator <args>`. Because this
51−pattern is so common, this can be abbreviated to
52−`:my-app|my-generator <args>`. Because most built-in commands are
53−generators for the `:hood` app, `:hood|generator <args>` can be
54−shortened to `|generator <args>`.
55−
56−Let's write a generator for a modified version of `:examples-pong` from
57−the chapter on [Network Messages](/docs/arvo/system/network). Recall
58−that `:examples-pong` takes an urbit address, which is of mark `urbit`,
59−and sends that urbit the message `'howdy'`. First--without a
60−generator--let's make `:examples-ping` that does the same, except that
61−it lets the user optionally specify the message as well.
62−
63−We'll need a new mark for our arguments. Let's call it
64−`examples-ping-message`.
65−
66−> For app-specific marks, it's good style to prefix the name of the mark
67−> with the name of the app. Since many apps have several such marks,
68−> subdirectories in `/mar` are rendered as `-`, so that `ping-message`
69−> is written in (/mar/examples/ping/message.hoon).
35+This didn't run any merge, it just constructed the command that, if sent to
36+`:hood`, would run it. Note first that, even though it's not printed, this value
37+has mark `kiln-merge`. Also, the merge strategy `gem=%auto` was added
38+automatically. Optional arguments are straightforward with generators.
39+
40+In general, generators are prepended by either `+` or `|`. The general form is
41+`+generator`, but often generators are created specifically to work with a
42+single app, they're usually placed in a subdirectory of gen and run with `|`.
43+Thus, if `my-generator` generator is made for use with `:my-app`, then
44+`my-generator` is put in `/gen/my-app/my-generator.hoon`, and can be run
45+directly with `+my-app/my-generator <args>`. If you want to pipe the result into
46+`:my-app`, then run `:my-app +my-app/my-generator <args>`. Because this pattern
47+is so common, this can be abbreviated to `:my-app|my-generator <args>`. Because
48+most built-in commands are generators for the `:hood` app,
49+`:hood|generator <args>` can be shortened to `|generator <args>`.
50+
51+Let's write a generator for a modified version of `:examples-pong` from the
52+chapter on [Network Messages](/docs/arvo/system/network). Recall that
53+`:examples-pong` takes an urbit address, which is of mark `urbit`, and sends
54+that urbit the message `'howdy'`. First--without a generator--let's make
55+`:examples-ping` that does the same, except that it lets the user optionally
56+specify the message as well.
57+
58+We'll need a new mark for our arguments. Let's call it `examples-ping-message`.
59+
60+> For app-specific marks, it's good style to prefix the name of the mark with
61+> the name of the app. Since many apps have several such marks, subdirectories
62+> in `/mar` are rendered as `-`, so that `ping-message` is written in
63+> (/mar/examples/ping/message.hoon).
7064
7165 ::
7266 :::: /hoon/message/ping/examples/app
@@ -119,43 +113,40 @@ Now we can run this with:
119113 ~fintud-macrep:dojo> :examples-ping &examples-ping-message [~sampel-sipnym 'heyya']
120114 >=
121115
122−And on `~sampel-sipnym`, assuming it's running `:examples-ping` as well,
123−we see `[%receiving 'heyya']`.
116+And on `~sampel-sipnym`, assuming it's running `:examples-ping` as well, we see
117+`[%receiving 'heyya']`.
124118
125−This is an annoying way to invoke the app, though. The `[]` are
126−mandatory, and optional arguments are hard. Let's make a generator,
127−`+examples-send` to make everything nicer. Since it's specific to
128−`:examples-ping`, let's put it in `/gen/examples/ping/send.hoon`:
119+This is an annoying way to invoke the app, though. The `[]` are mandatory, and
120+optional arguments are hard. Let's make a generator, `+examples-send` to make
121+everything nicer. Since it's specific to `:examples-ping`, let's put it in
122+`/gen/examples/ping/send.hoon`:
129123
130124 :- %say
131125 |= {^ {to/@p message/?($~ {text/@t $~})} $~}
132126 [%examples-ping-message to ?~(message 'howdy' text.message)]
133127
134−A couple of new things here. Firstly, `message/?($~ {text/@t $~})`
135−should be read as "the message is either null or a pair of text and
136−null". Generator argument lists are always null-terminated, which makes
137−it convenient to accept lists in tail position (which are particularly
138−annoying without generators). `?(a b)` is the irregular form of
139−`$?(a b)`, which is a union type. Thus, `?(a b)` means the type of
140−anything that's in either `a` or `b`. Thus, in our case,
141−`?(~ [text=@t ~])` is either null or a pair of text and null.
142−
143−Secondly, `?~(a b c)` is a rune which means "if the `a` is null, do `b`,
144−else `c`". It is roughly equivalent to `?:(=(~ a) b c)`.
145−
146−> `?~(a b c)` is actually equivalent to `?:=(?=(~ a) b c)`, which,
147−> although identical at run time, is subtly different at compile time.
148−> Specifically, using `?=` rather than `=` means that we're checking
149−> whether `a` is in the *type* of `~`, and so the compiler knows that in
150−> the `b` case `a` is null, and in the `c` case `a` is not null. Since
151−> `=` is purely a runtime value check with no type implications, the
152−> compiler doesn't gain any information.
128+A couple of new things here. Firstly, `message/?($~ {text/@t $~})` should be
129+read as "the message is either null or a pair of text and null". Generator
130+argument lists are always null-terminated, which makes it convenient to accept
131+lists in tail position (which are particularly annoying without generators).
132+`?(a b)` is the irregular form of `$?(a b)`, which is a union type. Thus,
133+`?(a b)` means the type of anything that's in either `a` or `b`. Thus, in our
134+case, `?(~ [text=@t ~])` is either null or a pair of text and null.
135+
136+Secondly, `?~(a b c)` is a rune which means "if the `a` is null, do `b`, else
137+`c`". It is roughly equivalent to `?:(=(~ a) b c)`.
138+
139+> `?~(a b c)` is actually equivalent to `?:=(?=(~ a) b c)`, which, although
140+> identical at run time, is subtly different at compile time. Specifically,
141+> using `?=` rather than `=` means that we're checking whether `a` is in the
142+> *type* of `~`, and so the compiler knows that in the `b` case `a` is null, and
143+> in the `c` case `a` is not null. Since `=` is purely a runtime value check
144+> with no type implications, the compiler doesn't gain any information.
153145>
154−> At any rate, this is the reason why we can refer to `text.message` in
155−> the `c` clause. The compiler knows that `message` is not null, so it
156−> must have `text` within it. If you used
157−> `?:(=(~ message) 'howdy' text.message)` the compiler would complain
158−> that it doesn't know whether `message` has `text` within it.
146+> At any rate, this is the reason why we can refer to `text.message` in the `c`
147+> clause. The compiler knows that `message` is not null, so it must have `text`
148+> within it. If you used `?:(=(~ message) 'howdy' text.message)` the compiler
149+> would complain that it doesn't know whether `message` has `text` within it.
159150
160151This is run as follows:
161152
@@ -169,10 +160,9 @@ Which causes `~sampel-sipnym` to print `[%receiving 'howdy']` and
169160
170161**Exercises**:
171162
172−- Create a generator for `:examples-sum` from
173− [State](/docs/arvo/state) so that you can run `:examples-sum|add 5`
174− to add numbers to it.
163+- Create a generator for `:examples-sum` from [State](/docs/arvo/state) so
164+ that you can run `:examples-sum|add 5` to add numbers to it.
175165
176166- Create a generator for `:examples-click` from [Web
177− Apps](/docs/arvo/web-apps) so that you can run
178− `:examples-click|poke` to poke it.
167+ Apps](/docs/arvo/web-apps) so that you can run `:examples-click|poke` to
168+ poke it.
docs/arvo/http.md+192−208
@@ -1,230 +1,214 @@
11---
2−navhome: /docs/
3−next: false
2+navhome: '/docs/'
3+next: False
44sort: 19
55title: HTTP requests and timers
66---
77
88# Writing an HTTP request
99
10−There's a variety of arvo services we haven't touched on yet.
11−Let's figure out how to make HTTP requests and set timers.
12−
13−Let's build an uptime-monitoring system. It'll ping a web
14−service periodically and print out an error when the response
15−code isn't 2xx. Here's `app/up.hoon`:
16−
17−```
18−:: Up-ness monitor. Accepts atom url, 'on', or 'off'
19−::
20−:::: /hoon/up/examples/app
21− ::
22−/? 314
23−|%
24−++ move {bone card}
25−++ card
26− $% {$hiss wire unit-iden/$~ mark/$httr cage/{mark/$purl vase/purl}}
27− {$wait wire @da}
28− ==
29−++ action
30− $% {$on $~} :: enable polling('on')
31− {$off $~} :: disable polling('off)
32− {$target p/cord} :: set poll target('http://...')
33− ==
34−--
35−|_ {hid/bowl on/_| in-progress/_| target/@t}
36−++ poke-atom
37− |= url-or-command/@t ^- (quip move +>)
38− =+ ^- act/action
39− ?: ?=($on url-or-command) [%on ~]
40− ?: ?=($off url-or-command) [%off ~]
41− [%target url-or-command]
42− ?- -.act
43− $target [~ +>.$(target p.act)]
44− $off [~ +>.$(on |)]
45− $on
46− :- ?: |(on in-progress) ~
47− [ost.hid %hiss /request ~ %httr %purl (need (epur target))]~
48− +>.$(on &, in-progress &)
49− ==
50−++ sigh-httr
51− |= {wir/wire code/@ud headers/mess body/(unit octs)}
52− ~& 'arrive here'
53− ^- {(list move) _+>.$}
54− ?: &((gte code 200) (lth code 300))
55− ~& [%all-is-well code]
56− :_ +>.$
57− [ost.hid %wait /timer (add ~s10 now.hid)]~
58− ~& [%we-have-a-problem code]
59− ~& [%headers headers]
60− ~& [%body body]
61− :_ +>.$
62− [ost.hid %wait /timer (add ~s10 now.hid)]~
63−++ wake-timer
64− |= {wir/wire $~} ^- (quip move +>)
65− ?: on
66− :_ +>.$
67− [ost.hid %hiss /request ~ %httr %purl (need (epur target))]~
68− [~ +>.$(in-progress |)]
69−::
70−++ prep ~& target _`. :: computed when the source file changes;
71−-- :: here it prints target then resets our state
72−```
73−
74−There's some fancy stuff going on here. We'll go through it line by
75−line, though.
76−
77−There's two kinds of cards we're sending to arvo. A `%hiss` move tells
78−`%eyre` to make an HTTP request. It expects a `(unit iden)`, which will
79−be null here because we aren't doing any authentication; a mark, in this
80−case the http request mark `&httr`; and some data in the form of a
81−`cage`, which is a `{mark vase}`. This is confusing, so the mold in the
82−code quoted above includes a bunch of otherwise unnecessary faces for
83−the purpose of illustration. Compare: `{$hiss p/(unit iden) q/mark
84−r/cage}` from `zuse`.
85−
86−> You can grep zuse.hoon and arvo.hoon for most of these definitions.
87−> However, beware the ambiguity surrounding "hiss": there's ++hiss in
88−> section 3bI of `zuse` ("Arvo structures"), and there's `%hiss` the
89−> move that is sent to %eyre to make our HTTP request happen. Here we're
90−> talking about the latter. See `++kiss-eyre` in `zuse`.
91−
92−> Recall that `++unit` means "maybe". Formally, "`(unit a)` is
93−> either null or a pair of null and a value in `a`". Also recall
94−> that to pull a value out of a unit (`u.unit`), you must first
95−> verify that the unit is not null (for example with `?~`). See
96−> `++need`.
97−
98−A `purl` is a parsed url structure, which can be created with `++epur`,
99−which is a function that takes a url as text and parses it into a `(unit
100−purl)`. Thus, the result is null if and only if the url is malformed.
101−'Purl' is also the mark which will be applied to this result.
102−
103−When you send this request, you can expect a `%sigh` with the
104−response, which we handle later on in `++sigh-httr`.
105−
106−For `%wait`, you just pass a [`@da`]() (absolute date), and arvo will
107−produce a `%wake` when the time comes.
108−
109−> A timer is guaranteed to not be triggered before the given
110−> time, but it's currently impossible to guarantee the timer will be
111−> triggered at exactly the requested time.
10+There's a variety of arvo services we haven't touched on yet. Let's figure out
11+how to make HTTP requests and set timers.
12+
13+Let's build an uptime-monitoring system. It'll ping a web service periodically
14+and print out an error when the response code isn't 2xx. Here's `app/up.hoon`:
15+
16+ :: Up-ness monitor. Accepts atom url, 'on', or 'off'
17+ ::
18+ :::: /hoon/up/examples/app
19+ ::
20+ /? 314
21+ |%
22+ ++ move {bone card}
23+ ++ card
24+ $% {$hiss wire unit-iden/$~ mark/$httr cage/{mark/$purl vase/purl}}
25+ {$wait wire @da}
26+ ==
27+ ++ action
28+ $% {$on $~} :: enable polling('on')
29+ {$off $~} :: disable polling('off)
30+ {$target p/cord} :: set poll target('http://...')
31+ ==
32+ --
33+ |_ {hid/bowl on/_| in-progress/_| target/@t}
34+ ++ poke-atom
35+ |= url-or-command/@t ^- (quip move +>)
36+ =+ ^- act/action
37+ ?: ?=($on url-or-command) [%on ~]
38+ ?: ?=($off url-or-command) [%off ~]
39+ [%target url-or-command]
40+ ?- -.act
41+ $target [~ +>.$(target p.act)]
42+ $off [~ +>.$(on |)]
43+ $on
44+ :- ?: |(on in-progress) ~
45+ [ost.hid %hiss /request ~ %httr %purl (need (epur target))]~
46+ +>.$(on &, in-progress &)
47+ ==
48+ ++ sigh-httr
49+ |= {wir/wire code/@ud headers/mess body/(unit octs)}
50+ ~& 'arrive here'
51+ ^- {(list move) _+>.$}
52+ ?: &((gte code 200) (lth code 300))
53+ ~& [%all-is-well code]
54+ :_ +>.$
55+ [ost.hid %wait /timer (add ~s10 now.hid)]~
56+ ~& [%we-have-a-problem code]
57+ ~& [%headers headers]
58+ ~& [%body body]
59+ :_ +>.$
60+ [ost.hid %wait /timer (add ~s10 now.hid)]~
61+ ++ wake-timer
62+ |= {wir/wire $~} ^- (quip move +>)
63+ ?: on
64+ :_ +>.$
65+ [ost.hid %hiss /request ~ %httr %purl (need (epur target))]~
66+ [~ +>.$(in-progress |)]
67+ ::
68+ ++ prep ~& target _`. :: computed when the source file changes;
69+ -- :: here it prints target then resets our state
70+
71+There's some fancy stuff going on here. We'll go through it line by line,
72+though.
73+
74+There's two kinds of cards we're sending to arvo. A `%hiss` move tells `%eyre`
75+to make an HTTP request. It expects a `(unit iden)`, which will be null here
76+because we aren't doing any authentication; a mark, in this case the http
77+request mark `&httr`; and some data in the form of a `cage`, which is a
78+`{mark vase}`. This is confusing, so the mold in the code quoted above includes
79+a bunch of otherwise unnecessary faces for the purpose of illustration. Compare:
80+`{$hiss p/(unit iden) q/mark r/cage}` from `zuse`.
81+
82+> You can grep zuse.hoon and arvo.hoon for most of these definitions. However,
83+> beware the ambiguity surrounding "hiss": there's ++hiss in section 3bI of
84+> `zuse` ("Arvo structures"), and there's `%hiss` the move that is sent to %eyre
85+> to make our HTTP request happen. Here we're talking about the latter. See
86+> `++kiss-eyre` in `zuse`.
87+
88+> Recall that `++unit` means "maybe". Formally, "`(unit a)` is either null or a
89+> pair of null and a value in `a`". Also recall that to pull a value out of a
90+> unit (`u.unit`), you must first verify that the unit is not null (for example
91+> with `?~`). See `++need`.
92+
93+A `purl` is a parsed url structure, which can be created with `++epur`, which is
94+a function that takes a url as text and parses it into a `(unit purl)`. Thus,
95+the result is null if and only if the url is malformed. 'Purl' is also the mark
96+which will be applied to this result.
97+
98+When you send this request, you can expect a `%sigh` with the response, which we
99+handle later on in `++sigh-httr`.
100+
101+For `%wait`, you just pass a [`@da`]() (absolute date), and arvo will produce a
102+`%wake` when the time comes.
103+
104+> A timer is guaranteed to not be triggered before the given time, but it's
105+> currently impossible to guarantee the timer will be triggered at exactly the
106+> requested time.
112107
113108Let's take a look at our state:
114109
115−```
116−|_ {hid/bowl on/_| in-progress=_| target/@t}
117−```
110+ |_ {hid/bowl on/_| in-progress=_| target/@t}
118111
119−We have three pieces of app-specific state. `target` is the url
120−we're monitoring. `on` and `in-progress` are booleans
121−representing, respectively, whether or not we're supposed to keep
122−monitoring and whether or not we're in the middle of a request.
112+We have three pieces of app-specific state. `target` is the url we're
113+monitoring. `on` and `in-progress` are booleans representing, respectively,
114+whether or not we're supposed to keep monitoring and whether or not we're in the
115+middle of a request.
123116
124−The type of booleans is usually written as `?`, which is a union
125−of `&` (true) and `|` false. This type defaults to `&` (true). In our
126−case, we want both of these to default to `|` (false). Because
127−of that, we use `_|` as the type. `_value` means "take the type
128−of `value`, but make the default value be `value`". Thus, our
129−type is still a boolean, just like `?`, but the default value is
130−`|` (false).
117+The type of booleans is usually written as `?`, which is a union of `&` (true)
118+and `|` false. This type defaults to `&` (true). In our case, we want both of
119+these to default to `|` (false). Because of that, we use `_|` as the type.
120+`_value` means "take the type of `value`, but make the default value be
121+`value`". Thus, our type is still a boolean, just like `?`, but the default
122+value is `|` (false).
131123
132−> This is the same `_` used in `_+>.$`, which means "the same
133−> type as the value "+>.$". In other words, the same type as our
134−> current context and state.
124+> This is the same `_` used in `_+>.$`, which means "the same type as the value
125+> "+&gt;.$". In other words, the same type as our current context and state.
135126
136−Let's take a look at `++poke-atom`. When we're poked with an atom, we
137−first check whether the atom is `'off'`. If so, we set our state
138−variable `on` to false.
127+Let's take a look at `++poke-atom`. When we're poked with an atom, we first
128+check whether the atom is `'off'`. If so, we set our state variable `on` to
129+false.
139130
140−If not, we check whether the atom is `'on'`. If so, we set `on` and
141−`in-progress` to true. If it was already either on or in progress, then
142−we don't take any other immediate action. If it was both off and not in
143−progress, then we send an HTTP request.
131+If not, we check whether the atom is `'on'`. If so, we set `on` and
132+`in-progress` to true. If it was already either on or in progress, then we don't
133+take any other immediate action. If it was both off and not in progress, then we
134+send an HTTP request.
144135
145−If the argument is neither 'off' nor 'on', then we assume it's an
146−actual url, so we save it in `target`.
136+If the argument is neither 'off' nor 'on', then we assume it's an actual url, so
137+we save it in `target`.
147138
148139Here's the move that sends the HTTP request:
149−```
150−[ost.hid %hiss /request ~ %httr %purl (need (epur target))]
151−```
152−
153−> Remember, we are expected to produce a *list* of moves. Note the `~`
154−> after the move in the full example. This is a convenient shortcut for
155−> creating a list of a single element. It's part of a small family of
156−> such shortcuts. `~[a b c]` is `[a b c ~]`, `[a b c]~` is `[[a b c]
157−> ~]` and `\`[a b c]` is `[~ a b c]`. These may be mixed and matched to
158−> create various convoluted structures and emojis.
159−
160−The correspondence between this move and `{bone card}` can be hard to
161−visualize on one line. Here it is more pedantically:
162−
163−```
164−:* bone=ost.hid :: the move
165− term=%hiss
166− wire=/request
167− unit-iden=~
168− mark=%httr
169− cage=[%purl (need (epur target))]
170−==
171−```
172−
173−When the HTTP response comes back, we handle it with
174−`++sigh-httr`, which, along with the wire the request was sent
175−on, takes the status code, the response headers, and the response
176−body.
177−
178−We check whether the status code is between 200 and 300. If so,
179−all is well, and we print a message saying so. We start the
180−timer for ten seconds after the present time.
181−
182−If we got a bad status code, then we print out the entire
183−response and start the timer again.
184−
185−After ten seconds, arvo will give us a `%wake` event, which will
186−be handled in `++wake-timer`. If we're still supposed to keep
187−monitoring, we send the same HTTP request as before. Otherwise,
188−we set `in-progress` to false.
140+
141+ [ost.hid %hiss /request ~ %httr %purl (need (epur target))]
142+
143+> Remember, we are expected to produce a *list* of moves. Note the `~` after the
144+> move in the full example. This is a convenient shortcut for creating a list of
145+> a single element. It's part of a small family of such shortcuts. `~[a b c]` is
146+> `[a b c ~]`, `[a b c]~` is `[[a b c] ~]` and `\`\[a b c\]`is`\[~ a b c\]\`.
147+> These may be mixed and matched to create various convoluted structures and
148+> emojis.
149+
150+The correspondence between this move and `{bone card}` can be hard to visualize
151+on one line. Here it is more pedantically:
152+
153+ :* bone=ost.hid :: the move
154+ term=%hiss
155+ wire=/request
156+ unit-iden=~
157+ mark=%httr
158+ cage=[%purl (need (epur target))]
159+ ==
160+
161+When the HTTP response comes back, we handle it with `++sigh-httr`, which, along
162+with the wire the request was sent on, takes the status code, the response
163+headers, and the response body.
164+
165+We check whether the status code is between 200 and 300. If so, all is well, and
166+we print a message saying so. We start the timer for ten seconds after the
167+present time.
168+
169+If we got a bad status code, then we print out the entire response and start the
170+timer again.
171+
172+After ten seconds, arvo will give us a `%wake` event, which will be handled in
173+`++wake-timer`. If we're still supposed to keep monitoring, we send the same
174+HTTP request as before. Otherwise, we set `in-progress` to false.
189175
190176Let's try it out:
191177
192−```
193−~fintud-macrep:dojo> |start %up
194−>=
195−~fintud-macrep:dojo> :examples-up &atom 'http://www.google.com'
196−>=
197−[%all-is-well 200]
198−[%all-is-well 200]
199−~fintud-macrep:dojo> :examples-up &atom 'http://example.com'
200−>=
201−[%all-is-well 200]
202−~fintud-macrep:dojo> :examples-up &atom 'http://google.com'
203−>=
204−[%we-have-a-problem 301]
205−[ %headers
206− ~[
207− [p='X-Frame-Options' q='SAMEORIGIN']
208− [p='X-XSS-Protection' q='1; mode=block']
209− [p='Content-Length' q='219']
210− [p='Server' q='gws']
211− [p='Cache-Control' q='public, max-age=2592000']
212− [p='Expires' q='Sun, 10 Jan 2016 23:45:05 GMT']
213− [p='Date' q='Fri, 11 Dec 2015 23:45:05 GMT']
214− [p='Content-Type' q='text/html; charset=UTF-8']
215− [p='Location' q='http://www.google.com/']
216− ]
217−]
218−[ %body
219− [ ~
220− [ p=219
221− q
222− \/'<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">\0a<TITLE>301 Moved</TI\/
223− TLE></HEAD><BODY>\0a<H1>301 Moved</H1>\0aThe document has moved\0a<A HREF="http://www.google.com/">her
224− e</A>.\0d\0a</BODY></HTML>\0d\0a'
225− \/ \/
178+ ~fintud-macrep:dojo> |start %up
179+ >=
180+ ~fintud-macrep:dojo> :examples-up &atom 'http://www.google.com'
181+ >=
182+ [%all-is-well 200]
183+ [%all-is-well 200]
184+ ~fintud-macrep:dojo> :examples-up &atom 'http://example.com'
185+ >=
186+ [%all-is-well 200]
187+ ~fintud-macrep:dojo> :examples-up &atom 'http://google.com'
188+ >=
189+ [%we-have-a-problem 301]
190+ [ %headers
191+ ~[
192+ [p='X-Frame-Options' q='SAMEORIGIN']
193+ [p='X-XSS-Protection' q='1; mode=block']
194+ [p='Content-Length' q='219']
195+ [p='Server' q='gws']
196+ [p='Cache-Control' q='public, max-age=2592000']
197+ [p='Expires' q='Sun, 10 Jan 2016 23:45:05 GMT']
198+ [p='Date' q='Fri, 11 Dec 2015 23:45:05 GMT']
199+ [p='Content-Type' q='text/html; charset=UTF-8']
200+ [p='Location' q='http://www.google.com/']
201+ ]
202+ ]
203+ [ %body
204+ [ ~
205+ [ p=219
206+ q
207+ \/'<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">\0a<TITLE>301 Moved</TI\/
208+ TLE></HEAD><BODY>\0a<H1>301 Moved</H1>\0aThe document has moved\0a<A HREF="http://www.google.com/">her
209+ e</A>.\0d\0a</BODY></HTML>\0d\0a'
210+ \/ \/
211+ ]
212+ ]
226213 ]
227− ]
228−]
229−~fintud-macrep:dojo> :up &atom 'off'
230−```
214+ ~fintud-macrep:dojo> :up &atom 'off'
docs/arvo/internals.md+90−102
@@ -1,5 +1,5 @@
11---
2−navhome: /docs/
2+navhome: '/docs/'
33sort: 22
44---
55
@@ -9,27 +9,25 @@ Arvo is composed of modules called vanes:
99
1010<list dataPreview="true"></list>
1111
12−<hr></hr>
12+<hr>
13+</hr>
14+At a high level `%arvo` takes a mess of unix io events and turns them into
15+something clean and structured for the programmer.
1316
14−At a high level `%arvo` takes a mess of unix io events and turns them
15−into something clean and structured for the programmer.
17+`%arvo` is designed to avoid the usual state of complex event networks: event
18+spaghetti. We keep track of every event's cause so that we have a clear causal
19+chain for every computation. At the bottom of every chain is a unix io event,
20+such as a network request, terminal input, file sync, or timer event. We push
21+every step in the path the request takes onto the chain until we get to the
22+terminal cause of the computation. Then we use this causal stack to route
23+results back to the caller.
1624
17−`%arvo` is designed to avoid the usual state of complex event networks:
18−event spaghetti. We keep track of every event's cause so that we have a
19−clear causal chain for every computation. At the bottom of every chain
20−is a unix io event, such as a network request, terminal input, file
21−sync, or timer event. We push every step in the path the request takes
22−onto the chain until we get to the terminal cause of the computation.
23−Then we use this causal stack to route results back to the caller.
25+## `++ducts`
2426
25−`++ducts`
26−---------
27−
28−The `%arvo` causal stack is called a `++duct`. This is represented
29−simply as a list of paths, where each path represents a step in the
30−causal chain. The first element in the path is the first letter of
31−whichever vane handled that step in the computation, or the empty span
32−for unix.
27+The `%arvo` causal stack is called a `++duct`. This is represented simply as a
28+list of paths, where each path represents a step in the causal chain. The first
29+element in the path is the first letter of whichever vane handled that step in
30+the computation, or the empty span for unix.
3331
3432Here's a duct that was recently observed in the wild:
3533
@@ -41,108 +39,98 @@ Here's a duct that was recently observed in the wild:
4139 //term/1
4240 ]
4341
44−This is the duct the timer vane receives when "timer" sample app asks
45−the timer vane to set a timer. This is also the duct over which the
46−response is produced at the specified time. Unix sent a terminal
47−keystroke event (enter), and arvo routed it to %dill(our terminal),
48−which passed it on to the %gall app terminal, which sent it to shell,
49−its child, which created a new child (with process id 4), which on
50−startup asked the timer vane to set a timer.
51−
52−The timer vane saves this duct, so that when the specified time arrives
53−and unix sends a wakeup event to the timer vane, it can produce the
54−response on the same duct. This response is routed to the place we
55−popped off the top of the duct, i.e. the time app. This app produces the
56−text "ding", which falls down to the shell, which drops it through to
57−the terminal. Terminal drops this down to dill, which converts it into
58−an effect that unix will recognize as a request to print "ding" to the
59−screen. When dill produces this, the last path in the duct has an
60−initial element of the empty span, so this is routed to unix, which
61−applies the effects.
42+This is the duct the timer vane receives when "timer" sample app asks the timer
43+vane to set a timer. This is also the duct over which the response is produced
44+at the specified time. Unix sent a terminal keystroke event (enter), and arvo
45+routed it to %dill(our terminal), which passed it on to the %gall app terminal,
46+which sent it to shell, its child, which created a new child (with process id
47+4), which on startup asked the timer vane to set a timer.
48+
49+The timer vane saves this duct, so that when the specified time arrives and unix
50+sends a wakeup event to the timer vane, it can produce the response on the same
51+duct. This response is routed to the place we popped off the top of the duct,
52+i.e. the time app. This app produces the text "ding", which falls down to the
53+shell, which drops it through to the terminal. Terminal drops this down to dill,
54+which converts it into an effect that unix will recognize as a request to print
55+"ding" to the screen. When dill produces this, the last path in the duct has an
56+initial element of the empty span, so this is routed to unix, which applies the
57+effects.
6258
6359This is a call stack, with a crucial feature: the stack is a first-class
64−citizen. You can respond over a duct zero, one, or many times. You can
65−save ducts for later use. There are definitely parallels to Scheme-style
60+citizen. You can respond over a duct zero, one, or many times. You can save
61+ducts for later use. There are definitely parallels to Scheme-style
6662continuations, but simpler and with more structure.
6763
68−Making Moves
69−------------
64+## Making Moves
7065
71−If ducts are a call stack, then how do we make calls and produce
72−results? Arvo processes "moves" which are a combination of message data
73−and metadata. There are two types of moves. A `%pass` move is analogous
74−to a call:
66+If ducts are a call stack, then how do we make calls and produce results? Arvo
67+processes "moves" which are a combination of message data and metadata. There
68+are two types of moves. A `%pass` move is analogous to a call:
7569
7670 [duct %pass return-path=path vane-name=@tD data=card]
7771
78−Arvo pushes the return path (preceded by the first letter of the vane
79−name) onto the duct and sends the given data, a card, to the vane we
80−specified. Any response will come along the same duct with the path
81−`return-path`.
72+Arvo pushes the return path (preceded by the first letter of the vane name) onto
73+the duct and sends the given data, a card, to the vane we specified. Any
74+response will come along the same duct with the path `return-path`.
8275
8376A `%give` move is analogous to a return:
8477
8578 [duct %give data=card]
8679
87−Arvo pops the top path off the duct and sends the given card back to the
88−caller.
80+Arvo pops the top path off the duct and sends the given card back to the caller.
8981
90−Vanes
91−-----
82+## Vanes
9283
93−As shown above, we use arvo proper to route and control the flow of
94−moves. However, arvo proper is rarely directly responsible for
95−processing the event data that directly causes the desired outcome of a
96−move. This event data is contained within a card, which is simply a
97−`(pair term noun)`. Instead, arvo proper passes the card off to one of
98−its vanes, which each present an interface to clients for a particular
99−well-defined, stable, and general-purpose piece of functionality.
84+As shown above, we use arvo proper to route and control the flow of moves.
85+However, arvo proper is rarely directly responsible for processing the event
86+data that directly causes the desired outcome of a move. This event data is
87+contained within a card, which is simply a `(pair term noun)`. Instead, arvo
88+proper passes the card off to one of its vanes, which each present an interface
89+to clients for a particular well-defined, stable, and general-purpose piece of
90+functionality.
10091
101−As of this writing, we have seven vanes, which each provide the
102−following services:
92+As of this writing, we have seven vanes, which each provide the following
93+services:
10394
104−- `%ames` name of both our network and the vane that communicates over
105− it
95+- `%ames` name of both our network and the vane that communicates over it
10696- `%clay` version-controlled, referentially- transparent, and global
10797 filesystem
108−- `%dill` terminal driver. Unix sends keyboard events to `%dill` from
109− either the console or telnet, and `%dill` produces terminal output.
110−- `%eyre` http server. Unix sends http messages to `%eyre`, and
111− `%eyre` produces http messages in response
98+- `%dill` terminal driver. Unix sends keyboard events to `%dill` from either
99+ the console or telnet, and `%dill` produces terminal output.
100+- `%eyre` http server. Unix sends http messages to `%eyre`, and `%eyre`
101+ produces http messages in response
112102- `%ford` handles resources and publishing
113−- `%gall` manages our userspace applications.. `%gall` keeps state and
114− manages subscribers
103+- `%gall` manages our userspace applications.. `%gall` keeps state and manages
104+ subscribers
115105- `%time` a simple timer
116106
117−Cards
118−-----
119−
120−Cards are the vane-specific portion of a move. Each vane defines a
121−protocol for interacting with other vanes (via arvo) by defining four
122−types of cards: kisses, gifts, notes, and signs.
123−
124−When one vane is `%pass`ed a card in its `++kiss`, arvo activates the
125−`++call` gate with the card as its argument. To produce a result, the
126−vane `%give`s one of the cards defined in its `++gift`. If the vane
127−needs to request something of another vane, it `%pass`es it a `++note`
128−card. When that other vane returns a result, arvo activates the `++take`
129−gate of the initial vane with one of the cards defined in its `++sign`.
130−
131−In other words, there are only four ways of seeing a move: (1) as a
132−request seen by the caller, which is a ++note. (2) that same request as
133−seen by the callee, a `++kiss`. (3) the response to that first request
134−as seen by the callee, a `++gift`. (4) the response to the first request
135−as seen by the caller, a `++sign`.
136−
137−When a `++kiss` card is passed to a vane, arvo calls its `++call` gate,
138−passing it both the card and its duct. This gate must be defined in
139−every vane. It produces two things in the following order: a list of
140−moves and a possibly-modified copy of its context. The moves are used to
141−interact with other vanes, while the new context allows the vane to save
142−its state. The next time arvo activates the vane it will have this
143−context as its subject.
144−
145−This overview has detailed how to pass a card to a particular vane. To
146−see the cards each vane can be `%pass`ed as a `++kiss` or return as a
147−`++gift` (as well as the semantics tied to them), each vane's public
148−interface is explained in detail in its respective overview.
107+## Cards
108+
109+Cards are the vane-specific portion of a move. Each vane defines a protocol for
110+interacting with other vanes (via arvo) by defining four types of cards: kisses,
111+gifts, notes, and signs.
112+
113+When one vane is `%pass`ed a card in its `++kiss`, arvo activates the `++call`
114+gate with the card as its argument. To produce a result, the vane `%give`s one
115+of the cards defined in its `++gift`. If the vane needs to request something of
116+another vane, it `%pass`es it a `++note` card. When that other vane returns a
117+result, arvo activates the `++take` gate of the initial vane with one of the
118+cards defined in its `++sign`.
119+
120+In other words, there are only four ways of seeing a move: (1) as a request seen
121+by the caller, which is a ++note. (2) that same request as seen by the callee, a
122+`++kiss`. (3) the response to that first request as seen by the callee, a
123+`++gift`. (4) the response to the first request as seen by the caller, a
124+`++sign`.
125+
126+When a `++kiss` card is passed to a vane, arvo calls its `++call` gate, passing
127+it both the card and its duct. This gate must be defined in every vane. It
128+produces two things in the following order: a list of moves and a
129+possibly-modified copy of its context. The moves are used to interact with other
130+vanes, while the new context allows the vane to save its state. The next time
131+arvo activates the vane it will have this context as its subject.
132+
133+This overview has detailed how to pass a card to a particular vane. To see the
134+cards each vane can be `%pass`ed as a `++kiss` or return as a `++gift` (as well
135+as the semantics tied to them), each vane's public interface is explained in
136+detail in its respective overview.
docs/arvo/internals/ames.md+15−18
@@ -1,28 +1,25 @@
11---
2−navhome: /docs/
2+navhome: '/docs/'
33sort: 1
44---
55
6−`%ames`
7−=======
6+# `%ames`
87
98Our networking protocol.
109
11−`%ames` is the name of both our network and the vane that communicates
12−over it. When Unix receives a packet over the correct UDP port, it pipes
13−it straight into `%ames` for handling. Also, all packets sent over the
14−`%ames` network are sent by the `%ames` vane. Apps and vanes may use
15−`%ames` to directly send messages to other ships. In general, apps use
16−gall and clay to communicate with other ships rather than using `%ames`
17−directly, but this isn't a requirement. Of course, gall and clay use
18−`%ames` behind the scenes to communicate across the network. These are
19−the only two vanes that use `%ames`.
10+`%ames` is the name of both our network and the vane that communicates over it.
11+When Unix receives a packet over the correct UDP port, it pipes it straight into
12+`%ames` for handling. Also, all packets sent over the `%ames` network are sent
13+by the `%ames` vane. Apps and vanes may use `%ames` to directly send messages to
14+other ships. In general, apps use gall and clay to communicate with other ships
15+rather than using `%ames` directly, but this isn't a requirement. Of course,
16+gall and clay use `%ames` behind the scenes to communicate across the network.
17+These are the only two vanes that use `%ames`.
2018
21−`%ames` includes several significant components. Although the actual
22−crypto algorithms are defined in zuse, they're used extensively in
23−`%ames` for encrypting and decrypting packets. Congestion control and
24−routing is handled entirely in `%ames`. Finally, the actual `%ames`
25−protocol itself, including how to route incoming packets to the correct
26−vane or app, is defined in `%ames`.
19+`%ames` includes several significant components. Although the actual crypto
20+algorithms are defined in zuse, they're used extensively in `%ames` for
21+encrypting and decrypting packets. Congestion control and routing is handled
22+entirely in `%ames`. Finally, the actual `%ames` protocol itself, including how
23+to route incoming packets to the correct vane or app, is defined in `%ames`.
2724
2825<list></list>
docs/arvo/internals/ames/commentary.md+690−769
@@ -1,80 +1,69 @@
11---
2−navhome: /docs/
2+navhome: '/docs/'
33---
44
5−
6−`%ames` commentary
7−==================
5+# `%ames` commentary
86
97`%ames` is our networking protocol.
108
11−First we give commentary on the code, the algorithms involved, and the
12−protocol. We trace through the code touched when a packet is sent,
13−received, acknowledged, and that acknowledgment applied. This is fairly
14−comprehensive, and contains many implementation details, but if you
15−understand this, then you understand `%ames`.
16−
17−If you've scrolled down this page, you may be intimidated by the amount
18−of Hoon code, especially if you are new to the language. Don't be afraid
19−of it, you don't have to read any of it if you don't want to -- every
20−interesting action the code takes is explained in plain English. In
21−fact, if you are new to the language, this may be a good learning
22−opportunity. Even if you don't understand every line of Hoon code,
23−you'll hopefully be able to follow most lines. By the time you've worked
24−through this, you'll have seen many common patterns and best practices.
25−Hoon, much more than other languages, is best learned by reading and
26−understanding large quantities of existing code. In this way, it is
27−similar to learning a natural language. All of this code is in
28−`arvo/ames.hoon`.
9+First we give commentary on the code, the algorithms involved, and the protocol.
10+We trace through the code touched when a packet is sent, received, acknowledged,
11+and that acknowledgment applied. This is fairly comprehensive, and contains many
12+implementation details, but if you understand this, then you understand `%ames`.
13+
14+If you've scrolled down this page, you may be intimidated by the amount of Hoon
15+code, especially if you are new to the language. Don't be afraid of it, you
16+don't have to read any of it if you don't want to -- every interesting action
17+the code takes is explained in plain English. In fact, if you are new to the
18+language, this may be a good learning opportunity. Even if you don't understand
19+every line of Hoon code, you'll hopefully be able to follow most lines. By the
20+time you've worked through this, you'll have seen many common patterns and best
21+practices. Hoon, much more than other languages, is best learned by reading and
22+understanding large quantities of existing code. In this way, it is similar to
23+learning a natural language. All of this code is in `arvo/ames.hoon`.
2924
3025After the commentary, we have reference documentation for all the data
31−structures that are specific to `%ames`. If you see a data structure or
32−a variable used that you don't recognize, search for it in the code, and
33−it's very likely defined in one of these data structures. We recommend
34−that another tab is kept open for easy access to the data structure
35−reference documentation. The code for these is split between
36−`arvo/ames.hoon` and `arvo/zuse.hoon`.
26+structures that are specific to `%ames`. If you see a data structure or a
27+variable used that you don't recognize, search for it in the code, and it's very
28+likely defined in one of these data structures. We recommend that another tab is
29+kept open for easy access to the data structure reference documentation. The
30+code for these is split between `arvo/ames.hoon` and `arvo/zuse.hoon`.
3731
38−The Lifecycle of a Packet (or, How a Packet Becomes Law)
39−--------------------------------------------------------
32+## The Lifecycle of a Packet (or, How a Packet Becomes Law)
4033
4134Here, we will trace a packet as it makes its way through ames. There are
42−actually two pathways through ames: the legacy path through `%want`, and
43−the modern way, entered through `%wont`, with full end-to-end
44−acknowledgments. Here we will only trace the modern way, though much of
45−the path is the same for both.
35+actually two pathways through ames: the legacy path through `%want`, and the
36+modern way, entered through `%wont`, with full end-to-end acknowledgments. Here
37+we will only trace the modern way, though much of the path is the same for both.
4638
47−When an app (or a vane) wishes to send a packet to another ship, it must
48−send a `%wont` card:
39+When an app (or a vane) wishes to send a packet to another ship, it must send a
40+`%wont` card:
4941
5042 [%wont p=sock q=path r=*] :: e2e send message
5143
52−This card takes three arguments. The `p` is a `sock`, that is, a pair of
53−two ships, the first of which is the sender and the second is the
54−receiver. But wait, you ask, why do I get to decide who is the sender?
55−Can I fake like I'm someone else? The reason is that there are
56−potentially multiple ships on the same pier, and the kernel can send a
57−message from any of them. If you attempt to send a message from a ship
58−not on your pier, then ames will refuse to send it. If you hack around
59−in your own copy of ames to go ahead and send it anyway, then the other
60−ship will reject it because your key is bad. Only send messages from
44+This card takes three arguments. The `p` is a `sock`, that is, a pair of two
45+ships, the first of which is the sender and the second is the receiver. But
46+wait, you ask, why do I get to decide who is the sender? Can I fake like I'm
47+someone else? The reason is that there are potentially multiple ships on the
48+same pier, and the kernel can send a message from any of them. If you attempt to
49+send a message from a ship not on your pier, then ames will refuse to send it.
50+If you hack around in your own copy of ames to go ahead and send it anyway, then
51+the other ship will reject it because your key is bad. Only send messages from
6152yourself.
6253
63−The `q` is a path, representing the place on the other side that you
64−want to receive your message. It is approximately equivalent to a port
65−number. Messages on the same path are guaranteed to arrive in the same
66−order as they were sent. No such guarantees are made across paths.
54+The `q` is a path, representing the place on the other side that you want to
55+receive your message. It is approximately equivalent to a port number. Messages
56+on the same path are guaranteed to arrive in the same order as they were sent.
57+No such guarantees are made across paths.
6758
68−The `r` is the actual data that you are sending. As the type implies,
69−this can be an arbitrary noun, and it will be transferred to the
70−receiver exactly as-is, in a well-typed way. Of course, this is data
71−that is sent over the wire, so be careful not to send anything too
72−massive unless you're willing to wait.
59+The `r` is the actual data that you are sending. As the type implies, this can
60+be an arbitrary noun, and it will be transferred to the receiver exactly as-is,
61+in a well-typed way. Of course, this is data that is sent over the wire, so be
62+careful not to send anything too massive unless you're willing to wait.
7363
74−But enough about the interface. Grepping in ames.hoon for `%wont`, we
75−find that it appears in exactly two places: at its definition in
76−`++kiss`, and in `++knob`, where it is handled. We see that we go
77−directly into `++wise:am`.
64+But enough about the interface. Grepping in ames.hoon for `%wont`, we find that
65+it appears in exactly two places: at its definition in `++kiss`, and in
66+`++knob`, where it is handled. We see that we go directly into `++wise:am`.
7867
7968 ++ wise :: wise:am
8069 |= [soq=sock hen=duct cha=path val=* ete=?] :: send a statement
@@ -82,20 +71,19 @@ directly into `++wise:am`.
8271 zork:zank:(wool:(ho:(um p.soq) q.soq) hen cha val ete)
8372
8473The inputs to this gate are exactly the sort of thing you'd expect. In
85−particular, everything in the `%wont` gate is here plus the calling duct
86−so that we know where to send the acknowledgment and `ete` to determine
87−if we're going to do the modern end-to-end acknowledgments.
74+particular, everything in the `%wont` gate is here plus the calling duct so that
75+we know where to send the acknowledgment and `ete` to determine if we're going
76+to do the modern end-to-end acknowledgments.
8877
89−The actual line of code looks intimidating, but it's really not all that
90−bad. Working from the inside out, the call to `++um` sets up our
91−domestic server, and the call to `++ho` sets up our knowledge about the
92−neighbor we're sending to. From the outside, `++zork` and `++zank` just
93−apply the changes made to our `++um` and `++am` cores, respectively. If
94−you're familiar with the common idiom of `++abet`, that's all this is.
95−The code predates the widespread usage of that name.
78+The actual line of code looks intimidating, but it's really not all that bad.
79+Working from the inside out, the call to `++um` sets up our domestic server, and
80+the call to `++ho` sets up our knowledge about the neighbor we're sending to.
81+From the outside, `++zork` and `++zank` just apply the changes made to our
82+`++um` and `++am` cores, respectively. If you're familiar with the common idiom
83+of `++abet`, that's all this is. The code predates the widespread usage of that
84+name.
9685
97−The interesting part, then, is in `++wool:ho:um:am`. Let's look at the
98−code.
86+The interesting part, then, is in `++wool:ho:um:am`. Let's look at the code.
9987
10088 ++ wool :: wool:ho:um:am
10189 |= [hen=duct cha=path val=* ete=?] :: send a statement
@@ -114,36 +102,33 @@ code.
114102 [%bund q.cov cha sex val]
115103 [%bond q.cov cha sex val]
116104
117−This is slightly more complicated, but it's still not all that bad. Our
118−inputs, at least, are fairly obvious.
105+This is slightly more complicated, but it's still not all that bad. Our inputs,
106+at least, are fairly obvious.
119107
120−If you glance at the code for a second, you'll see that
121−`++wind:ho:um:am` seems to be able to send a message, or `++meal`, given
122−a `++soup`. This gate, then, just sets up the things we need to for
123−`++wind` to do its job.
108+If you glance at the code for a second, you'll see that `++wind:ho:um:am` seems
109+to be able to send a message, or `++meal`, given a `++soup`. This gate, then,
110+just sets up the things we need to for `++wind` to do its job.
124111
125−We first get `rol`, which is a `++rill`, that is, a particular outbound
126−stream. This stream is specific to the path on which we're sending. If
127−the path hasn't been used before, then we create it. We let `sex` be the
128−number of messages we've already sent on this path.
112+We first get `rol`, which is a `++rill`, that is, a particular outbound stream.
113+This stream is specific to the path on which we're sending. If the path hasn't
114+been used before, then we create it. We let `sex` be the number of messages
115+we've already sent on this path.
129116
130−Then, we update the outbound stream by incrementing the number of
131−messages sent and placing an entry in `san.rol` that associates the
132−message number with the `duct` that sent the message. This allows us to
133−give the acknowledgment to the one who sent the message.
117+Then, we update the outbound stream by incrementing the number of messages sent
118+and placing an entry in `san.rol` that associates the message number with the
119+`duct` that sent the message. This allows us to give the acknowledgment to the
120+one who sent the message.
134121
135−We let `cov` be the current life of our crypto and our neighbor's
136−crypto. At the moment, we only need our neighbor's life, which we put
137−into the meal.
122+We let `cov` be the current life of our crypto and our neighbor's crypto. At the
123+moment, we only need our neighbor's life, which we put into the meal.
138124
139−Finally, we call `++wind:ho:um:am` with the `++soup` of the path and
140−message number and the `++meal` of the payload itself. For end-to-end
141−acknowledged messages, we use `%bund`.
125+Finally, we call `++wind:ho:um:am` with the `++soup` of the path and message
126+number and the `++meal` of the payload itself. For end-to-end acknowledged
127+messages, we use `%bund`.
142128
143129 [%bund p=life q=path r=@ud s=*] :: e2e message
144130
145−Looking at how we create the `%bund`, we can easily see what each field
146−is for.
131+Looking at how we create the `%bund`, we can easily see what each field is for.
147132
148133Following the trail a little further, we go to `++wind:ho:um:am`.
149134
@@ -156,13 +141,13 @@ Following the trail a little further, we go to `++wind:ho:um:am`.
156141 (busk xong:diz feh)
157142
158143`++wind` does three things: it (1) encodes the message into a list of
159−possibly-encrypted packets, (2) puts the message into the packet pump,
160−and (3) sends any packets that are ready to be sent. Yes, our nice
161−little linear run of each gate calling exactly one other interesting
162−gate is over. We'll go in order here.
144+possibly-encrypted packets, (2) puts the message into the packet pump, and (3)
145+sends any packets that are ready to be sent. Yes, our nice little linear run of
146+each gate calling exactly one other interesting gate is over. We'll go in order
147+here.
163148
164−`++zuul:lax:as:go` is the what converts a `++meal` into a list of
165−actual, 1KB packets.
149+`++zuul:lax:as:go` is the what converts a `++meal` into a list of actual, 1KB
150+packets.
166151
167152 ++ zuul :: zuul:lax:as:go
168153 |= [now=@da ham=meal] :: encode message
@@ -172,33 +157,32 @@ actual, 1KB packets.
172157 ++ weft :: fragment message
173158 ++ wisp :: generate message
174159
175−For organizational purposes, `++zuul` constructs an internal core with
176−three arms. `++wasp` encodes the meal into an atom with no encryption.
177−`++wisp` encodes a meal with possible encryption (else it simply calls
178−`++wasp`). `++weft` takes the result of `++wisp` and splits it into
179−actual packets.
160+For organizational purposes, `++zuul` constructs an internal core with three
161+arms. `++wasp` encodes the meal into an atom with no encryption. `++wisp`
162+encodes a meal with possible encryption (else it simply calls `++wasp`).
163+`++weft` takes the result of `++wisp` and splits it into actual packets.
180164
181165 ++ wasp :: null security
182166 ^-([p=skin q=@] [%none (jam ham)])
183167
184−This simply jams the meal, wrapping it with the `skin` of `%none`,
185−meaning no encryption.
168+This simply jams the meal, wrapping it with the `skin` of `%none`, meaning no
169+encryption.
186170
187171Since `++wisp` is a little long, we'll go through it line-by-line.
188172
189173 ++ wisp :: generate message
190174 ^- [[p=skin q=@] q=_..wisp]
191175
192−`++wisp` produces a pair of a `skin` and an atom, which is the meal
193−encoded as a single atom and possibly encrypted.
176+`++wisp` produces a pair of a `skin` and an atom, which is the meal encoded as a
177+single atom and possibly encrypted.
194178
195179 ?: =(%carp -.ham)
196180 [wasp ..wisp]
197181
198−If the meal that we're encoding is a `%carp`, then we don't encrypt it.
199−A `%carp` meal is a partial meal, used when a message is more than 1KB.
200−Since the entire message is already encrypted, we don't need to encrypt
201−each packet individually again.
182+If the meal that we're encoding is a `%carp`, then we don't encrypt it. A
183+`%carp` meal is a partial meal, used when a message is more than 1KB. Since the
184+entire message is already encrypted, we don't need to encrypt each packet
185+individually again.
202186
203187 ?: !=(~ yed.caq.dur)
204188 ?> ?=(^ yed.caq.dur)
@@ -208,31 +192,29 @@ each packet individually again.
208192 p.u.yed.caq.dur
209193 (en:r:cluy q.u.yed.caq.dur (jam ham))
210194
211−If we have a symmetric key set up with this neighbor, then we simply use
212−it. The skin `%fast` is used to indicate a symmetric key.
195+If we have a symmetric key set up with this neighbor, then we simply use it. The
196+skin `%fast` is used to indicate a symmetric key.
213197
214198 ?: &(=(~ lew.wod.dur) |(=(%back -.ham) =(%buck -.ham)))
215199 [wasp ..wisp]
216200
217−If we do not yet have our neighbor's will, then there is no way that we
218−can seal the message so that only they may read it. If what we're
219−sending is an acknowledgment, then we go ahead and just send it in the
220−clear.
201+If we do not yet have our neighbor's will, then there is no way that we can seal
202+the message so that only they may read it. If what we're sending is an
203+acknowledgment, then we go ahead and just send it in the clear.
221204
222205 =^ tuy +>.$
223206 ?:(=(~ lew.wod.dur) [*code +>.$] (griz now))
224207
225−If we don't have our neighbor's will, then we "encrypt" with a key of 0.
226−If we do have their will, then we generate a new symmetric key that we
227−will propose.
208+If we don't have our neighbor's will, then we "encrypt" with a key of 0. If we
209+do have their will, then we generate a new symmetric key that we will propose.
228210
229211 :_ ..wisp
230212 =+ yig=sen
231213 =+ bil=law.saf :: XX send whole will
232214 =+ hom=(jam ham)
233215
234−`yig` will be the life and engine for our current crypto. `bil` is our
235−will. `hom` is the meal encoded as a single atom.
216+`yig` will be the life and engine for our current crypto. `bil` is our will.
217+`hom` is the meal encoded as a single atom.
236218
237219 ?: =(~ lew.wod.dur)
238220 :- %open
@@ -241,9 +223,8 @@ will. `hom` is the meal encoded as a single atom.
241223 bil
242224 (sign:as:q.yig tuy hom)
243225
244−If we do not have our neighbor's will, then we send our current life
245−along with our will and the message. The message itself is "signed" with
246−a key of 0.
226+If we do not have our neighbor's will, then we send our current life along with
227+our will and the message. The message itself is "signed" with a key of 0.
247228
248229 :- %full
249230 =+ cay=cluy
@@ -253,9 +234,9 @@ a key of 0.
253234 (seal:as:q.yig pub:ex:r.cay tuy hom)
254235 -- :: --zuul:lax:as:go
255236
256−If we do have our neighbor's will, then we send our perception of their
257−current life, our current life, our will, and the message. The message
258−is sealed with their public key so that only they can read our message.
237+If we do have our neighbor's will, then we send our perception of their current
238+life, our current life, our will, and the message. The message is sealed with
239+their public key so that only they can read our message.
259240
260241Once we have the message encoded as an atom, `++weft` goes to work.
261242
@@ -271,23 +252,23 @@ aforementioned `++wisp` to get the message as an atom.
271252 =+ wit=(met 13 q.gim)
272253 ?< =(0 wit)
273254
274−`wit` is the number of 1KB (2\^13 bit) blocks in the message. We assert
275−that there is at least one block.
255+`wit` is the number of 1KB (2\\^13 bit) blocks in the message. We assert that
256+there is at least one block.
276257
277258 ?: =(1 wit)
278259 =+ yup=(spit [our her] p.gim q.gim)
279260 [yup ~]
280261
281−If there is exactly one block, then we just call `++spit` to turn the
282−message into a packet. We'll explain what `++spit` does momentarily.
262+If there is exactly one block, then we just call `++spit` to turn the message
263+into a packet. We'll explain what `++spit` does momentarily.
283264
284265 =+ ruv=(rip 13 q.gim)
285266 =+ gom=(shaf %thug q.gim)
286267 =+ inx=0
287268
288−If there is more than one block, then we rip it into blocks in `ruv`.
289−`gom` is a hash of the message, used as an id. `inx` is the number of
290−packets we've already made.
269+If there is more than one block, then we rip it into blocks in `ruv`. `gom` is a
270+hash of the message, used as an id. `inx` is the number of packets we've already
271+made.
291272
292273 |- ^- (list rock)
293274 ?~ ruv ~
@@ -298,8 +279,8 @@ packets we've already made.
298279 :- vie
299280 $(ruv t.ruv, inx +(inx))
300281
301−Here we package each block into a packet with `++spit` and produce the
302−list of packets.
282+Here we package each block into a packet with `++spit` and produce the list of
283+packets.
303284
304285 ++ spit :: cake to packet
305286 |= kec=cake ^- @
@@ -321,32 +302,30 @@ list of packets.
321302 ==
322303 (lsh 5 1 bod)
323304
324−This is how we turn a message into a real packet. This has the
325−definition of the packet format.
305+This is how we turn a message into a real packet. This has the definition of the
306+packet format.
326307
327308`wim` is the length of the sending ship, and `dum` is the length of the
328309receiving ship. There are only five possibilities for each of those,
329−corresponding to carriers, cruisers, destroyers, yachts, and submarines.
330−These are encoded in `yax` and `qax` as 0, 0, 1, 2, and 3, respectively.
331−Thus, `wix` and `vix` are the number of bytes that must be reserved for
332−the ship names in a packet.
333−
334−Next, we construct `bod` by simply concatenating the sending ship, the
335−receiving ship, and the body of the message. Then, we get the encryption
336−mechanism from `++skin`, which may be a 0, 1, 2, or 3, and put it in
337−`tay`.
338−
339−Next, we concatenate together, bit by bit, some final metadata. We use
340−three bits for our protocol number, which is incremented modulo eight
341−when there is a continuity breach or the protocol changes. We use the
342−final twenty bits of a hash of the body (which, we suppose, makes it a
343−twenty bit hash) for error-checking. We use two bits to tell how much
344−room is used in the body for the sending ship, and another two bits for
345−the receiving ship. Finally, we use five bits to store the encryption
346−type. Note that since there are only two bits worth of encryption types,
347−there are three unused bits here. This adds up to 32 bits of header
348−data. Finally, we concatenate this onto the front of the packet. Thus,
349−we can summarize the packet header format as follows.
310+corresponding to carriers, cruisers, destroyers, yachts, and submarines. These
311+are encoded in `yax` and `qax` as 0, 0, 1, 2, and 3, respectively. Thus, `wix`
312+and `vix` are the number of bytes that must be reserved for the ship names in a
313+packet.
314+
315+Next, we construct `bod` by simply concatenating the sending ship, the receiving
316+ship, and the body of the message. Then, we get the encryption mechanism from
317+`++skin`, which may be a 0, 1, 2, or 3, and put it in `tay`.
318+
319+Next, we concatenate together, bit by bit, some final metadata. We use three
320+bits for our protocol number, which is incremented modulo eight when there is a
321+continuity breach or the protocol changes. We use the final twenty bits of a
322+hash of the body (which, we suppose, makes it a twenty bit hash) for
323+error-checking. We use two bits to tell how much room is used in the body for
324+the sending ship, and another two bits for the receiving ship. Finally, we use
325+five bits to store the encryption type. Note that since there are only two bits
326+worth of encryption types, there are three unused bits here. This adds up to 32
327+bits of header data. Finally, we concatenate this onto the front of the packet.
328+Thus, we can summarize the packet header format as follows.
350329
351330 0 1 2 3
352331 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
@@ -354,15 +333,14 @@ we can summarize the packet header format as follows.
354333 |Proto| Hash of Body |yax|qax| Crypto |
355334 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
356335
357−After this, there are `yax` bits of the sender name, `qax` bits of the
358−receiver name, and up to 8192 bits of data. Thus, the maximum size of a
359−packet is achieved in a message between two submarines with 8192 bits of
360−data. This will require 32+128+128+8192 = 8480 bits, or 1060 bytes.
336+After this, there are `yax` bits of the sender name, `qax` bits of the receiver
337+name, and up to 8192 bits of data. Thus, the maximum size of a packet is
338+achieved in a message between two submarines with 8192 bits of data. This will
339+require 32+128+128+8192 = 8480 bits, or 1060 bytes.
361340
362341This concludes our discussion of `++zuul:lax:as:go`. If you recall from
363−`++wind:ho:um:am`, the list of packets from `++zuul` is passed into
364−`++whap:pu` to update the packet pump and get any packets that can be
365−sent immediately.
342+`++wind:ho:um:am`, the list of packets from `++zuul` is passed into `++whap:pu`
343+to update the packet pump and get any packets that can be sent immediately.
366344
367345 ++ whap :: whap:pu
368346 |= [now=@da gom=soup wyv=(list rock)] :: send a message
@@ -379,16 +357,15 @@ sent immediately.
379357 ==
380358 (harv now)
381359
382−First, we put into `pyz` the id for this message and the number of its
383−packets that have not yet been acknowledged, which is of course the
384−total number of packets since we haven't even sent the packets.
360+First, we put into `pyz` the id for this message and the number of its packets
361+that have not yet been acknowledged, which is of course the total number of
362+packets since we haven't even sent the packets.
385363
386−For every packet, we change three things in the state (`++shed`) of our
387−packet pump: (1) we increment `nus`, the number of packets sent; (2) we
388−put the packet number into `diq` keyed by a hash of the packet; and (3)
389−we put the packet into the packet queue, with the basic metadata of its
390−id `gom`, 0 transmissions, not live yet, last sent in the year 2000, and
391−the packet itself.
364+For every packet, we change three things in the state (`++shed`) of our packet
365+pump: (1) we increment `nus`, the number of packets sent; (2) we put the packet
366+number into `diq` keyed by a hash of the packet; and (3) we put the packet into
367+the packet queue, with the basic metadata of its id `gom`, 0 transmissions, not
368+live yet, last sent in the year 2000, and the packet itself.
392369
393370Finally, we harvest the packet pump.
394371
@@ -402,17 +379,17 @@ Finally, we harvest the packet pump.
402379 =< abet =< apse
403380 |%
404381
405−`++harv` contains a core for most of its work. The meat is in `++apse`.
406−First, though, it sets itself up. If there aren't any packets in the
407−queue, then we simply do nothing except set `rtn`, our next timeout, to
408−nil because we don't have any packets that may need to be retransmitted.
409−If we have more live (that is, sent and unacknowledged) packets than our
410−window size, then we don't do anything.
382+`++harv` contains a core for most of its work. The meat is in `++apse`. First,
383+though, it sets itself up. If there aren't any packets in the queue, then we
384+simply do nothing except set `rtn`, our next timeout, to nil because we don't
385+have any packets that may need to be retransmitted. If we have more live (that
386+is, sent and unacknowledged) packets than our window size, then we don't do
387+anything.
411388
412−Otherwise, we let `wid` be the width of our remaining packet window, and
413−we initialize `rub` to nil. `rub` will be the list of packets that are
414−ready to be sent. We then call `++apse` and pass the result to `++abet`.
415−`++apse` decides which packets are ready to be sent.
389+Otherwise, we let `wid` be the width of our remaining packet window, and we
390+initialize `rub` to nil. `rub` will be the list of packets that are ready to be
391+sent. We then call `++apse` and pass the result to `++abet`. `++apse` decides
392+which packets are ready to be sent.
416393
417394 ++ apse
418395 ^+ .
@@ -432,20 +409,19 @@ ready to be sent. We then call `++apse` and pass the result to `++abet`.
432409 lys.q.n.puq now
433410 ==
434411
435−If there are no remaining packets to send, or if we've filled the packet
436−window, do nothing. We call `++rigt` and `++left` to process the left
437−and right branches of the packet queue.
412+If there are no remaining packets to send, or if we've filled the packet window,
413+do nothing. We call `++rigt` and `++left` to process the left and right branches
414+of the packet queue.
438415
439−Now we assert that the queue is not empty, and we again check that we
440−haven't filled the packet window. We will operate on the head of the
441−queue. If the packet is live, then do nothing. Otherwise, we go ahead
442−and send it.
416+Now we assert that the queue is not empty, and we again check that we haven't
417+filled the packet window. We will operate on the head of the queue. If the
418+packet is live, then do nothing. Otherwise, we go ahead and send it.
443419
444−To send, we (1) decrement `wid`, our packet window width; (2) cons the
445−packet onto the `rub`, which will be returned as the list of packets to
446−send; (3) increment `nif`, the number of live packets; (4) set the
447−packet to be live; (5) increment the number of transmissions of the
448−packet; and (6) set the last sent time of the packet to now.
420+To send, we (1) decrement `wid`, our packet window width; (2) cons the packet
421+onto the `rub`, which will be returned as the list of packets to send; (3)
422+increment `nif`, the number of live packets; (4) set the packet to be live; (5)
423+increment the number of transmissions of the packet; and (6) set the last sent
424+time of the packet to now.
449425
450426 ++ left
451427 ?> ?=(^ puq)
@@ -454,8 +430,8 @@ packet; and (6) set the last sent time of the packet to now.
454430 ?> ?=(^ puq)
455431 ^+(. =+(rig=apse(puq r.puq) rig(puq [n.puq l.puq puq.rig])))
456432
457−These do exactly what you would expect: they traverse the packet queue
458−so that `++apse` gets called recursively through it.
433+These do exactly what you would expect: they traverse the packet queue so that
434+`++apse` gets called recursively through it.
459435
460436Finally, `++abet` gets called, which resolves the changes.
461437
@@ -463,14 +439,13 @@ Finally, `++abet` gets called, which resolves the changes.
463439 ?~ rub [~ +>.$]
464440 [(flop rub) +>.$(rtn [~ (add rto now)])]
465441
466−This returns the packets that we wish to send, and it updates the
467−timeout so that we know when to try resending unacknowledged packets.
442+This returns the packets that we wish to send, and it updates the timeout so
443+that we know when to try resending unacknowledged packets.
468444
469−This concludes our discussion of `++whap:pu`. To finish
470−`++wind:ho:um:am`, we just need to delve into `++busk:ho:um:am`. But
471−wait, in the call to `++busk`, the first argument is `xong:diz`. What is
472−this? This, my dear reader, is one more detour, this time into
473−`++xong:lax:as:go`.
445+This concludes our discussion of `++whap:pu`. To finish `++wind:ho:um:am`, we
446+just need to delve into `++busk:ho:um:am`. But wait, in the call to `++busk`,
447+the first argument is `xong:diz`. What is this? This, my dear reader, is one
448+more detour, this time into `++xong:lax:as:go`.
474449
475450 ++ xong :: xong:lax:as:go
476451 ^- (list ship) :: route unto
@@ -484,26 +459,24 @@ this? This, my dear reader, is one more detour, this time into
484459 :: ~& [%xong-to [our her] (weld oot ?>(?=(^ fro) t.fro))]
485460 (weld oot ?>(?=(^ fro) t.fro))
486461
487−This gets the list of intermediate ships needed to get a packet from us
488−to our neighbor. First, we get `fro` and `too`, the "canons" of ourself
489−and our neighbor, respectively.
462+This gets the list of intermediate ships needed to get a packet from us to our
463+neighbor. First, we get `fro` and `too`, the "canons" of ourself and our
464+neighbor, respectively.
490465
491−What is this "canon", you ask? A canon is simply a ship plus its
492−"ancestors", as defined by `++sein`. For example, the canon of
493−`~hoclur-bicrel` is:
466+What is this "canon", you ask? A canon is simply a ship plus its "ancestors", as
467+defined by `++sein`. For example, the canon of `~hoclur-bicrel` is:
494468
495469 ~hoclur-bicrel/try=> (saxo ~hoclur-bicrel)
496470 ~[~hoclur-bicrel ~tasruc ~tug]
497471
498−If we follow the algorithm in `++xong`, we see that we are simply
499−creating a list of ships that form a path from our neighbor to ourself.
500−Essentially, we look through the canon of our neighbor until we find
501−something in our own cannon -- a common ancestor. Or, if we are from
502−different carriers, then there is no common ancestor. We then weld this
503−onto the tail of our own canon. In the end, this is simply a list of
504−possible ships to try to route via to get to our neighbor, ordered by
505−preferability (that is, closeness to our neighbor). We will end up
506−trying, in order, to find a lane to these.
472+If we follow the algorithm in `++xong`, we see that we are simply creating a
473+list of ships that form a path from our neighbor to ourself. Essentially, we
474+look through the canon of our neighbor until we find something in our own cannon
475+-- a common ancestor. Or, if we are from different carriers, then there is no
476+common ancestor. We then weld this onto the tail of our own canon. In the end,
477+this is simply a list of possible ships to try to route via to get to our
478+neighbor, ordered by preferability (that is, closeness to our neighbor). We will
479+end up trying, in order, to find a lane to these.
507480
508481Now, we can finally get to `++busk:ho:um:am`.
509482
@@ -516,10 +489,9 @@ Now, we can finally get to `++busk:ho:um:am`.
516489 $(pax t.pax, bin (weld (flop (wist:diz now waz ~ i.pax)) bin))
517490 ==
518491
519−Thankfully, `++busk` is fairly simple. We go through the list of packets
520−and convert them to `++boon`s with `++wist:lax:as:go`. These boons are
521−placed into `bin`, and they end up getting processed by `++clop` (this
522−happens in `++knob`).
492+Thankfully, `++busk` is fairly simple. We go through the list of packets and
493+convert them to `++boon`s with `++wist:lax:as:go`. These boons are placed into
494+`bin`, and they end up getting processed by `++clop` (this happens in `++knob`).
523495
524496 ++ wist :: wist:lax:as:go
525497 |= $: now=@da :: route via
@@ -554,53 +526,50 @@ happens in `++knob`).
554526This takes a sample of the current time, the list of ships that we just
555527generated, a lane if we already know it, and the packet itself.
556528
557−First, if we are sending a message to ourself, then we simply create a
558−`%ouzo` boon with a bunted lane. Otherwise, if there are no routing
559−candidates, there is nothing we can do, so we return nil.
560−
561−Next, we get the `dore` of the first routing candidate. If we're looking
562−at the neighbor to whom we're trying to send the message, then we simply
563−use the `dore` that we already have. Otherwise, we get a default `dore`.
564−
565−If we're the first routing candidate, or if we have don't have a lane to
566−this candidate, then we skip this candidate and move on to the next one.
567−
568−If we have only a provisional ip address, then we try to send on it, but
569−we also try to send on later routing candidates as well. Otherwise, we
570−only send on this one candidate.
571−
572−Finally, we create the actual `%ouzo` boon. The lane is the one from our
573−`dore`. If we're sending it directly to our intended recipient, and we
574−haven't been told to use a specific lane, then we just send the packet
575−directly. Otherwise, we wrap it in a little `%fore` meal, telling the
576−intermediary to whom we wish it to be sent. If we have already set up a
577−symmetric key with the intermediary, then we encrypt it with that.
578−Otherwise, we send it in the clear.
579−
580−Now, if you recall, we have traced all the way through from the
581−beginning when, in `++knob`, the `%wont` card was handled by a call to
582−`++wise`. There is only one more step before the packet is finally sent.
583−Looking in `++knob`, we see that the resultant list of boons is passed
584−into `++clop`, which will execute the correct actions and return a list
585−of moves. In `++clop`, we see the handling of each specific boon. The
586−one we are interested in is `%ouzo`, since that is the only one we have
587−sent thus far.
529+First, if we are sending a message to ourself, then we simply create a `%ouzo`
530+boon with a bunted lane. Otherwise, if there are no routing candidates, there is
531+nothing we can do, so we return nil.
532+
533+Next, we get the `dore` of the first routing candidate. If we're looking at the
534+neighbor to whom we're trying to send the message, then we simply use the `dore`
535+that we already have. Otherwise, we get a default `dore`.
536+
537+If we're the first routing candidate, or if we have don't have a lane to this
538+candidate, then we skip this candidate and move on to the next one.
539+
540+If we have only a provisional ip address, then we try to send on it, but we also
541+try to send on later routing candidates as well. Otherwise, we only send on this
542+one candidate.
543+
544+Finally, we create the actual `%ouzo` boon. The lane is the one from our `dore`.
545+If we're sending it directly to our intended recipient, and we haven't been told
546+to use a specific lane, then we just send the packet directly. Otherwise, we
547+wrap it in a little `%fore` meal, telling the intermediary to whom we wish it to
548+be sent. If we have already set up a symmetric key with the intermediary, then
549+we encrypt it with that. Otherwise, we send it in the clear.
550+
551+Now, if you recall, we have traced all the way through from the beginning when,
552+in `++knob`, the `%wont` card was handled by a call to `++wise`. There is only
553+one more step before the packet is finally sent. Looking in `++knob`, we see
554+that the resultant list of boons is passed into `++clop`, which will execute the
555+correct actions and return a list of moves. In `++clop`, we see the handling of
556+each specific boon. The one we are interested in is `%ouzo`, since that is the
557+only one we have sent thus far.
588558
589559 %ouzo
590560 :: ~& [%send now p.bon `@p`(mug (shaf %flap q.bon))]
591561 :_ fox
592562 [[gad.fox [%give %send p.bon q.bon]] ~]
593563
594−Very simply, we give a `%send` gift along the special duct that goes
595−straight into the bowels of unix. This is the last stop before we drop
596−into vere, and later libuv. And then... the world.
564+Very simply, we give a `%send` gift along the special duct that goes straight
565+into the bowels of unix. This is the last stop before we drop into vere, and
566+later libuv. And then... the world.
597567
598−The packet, after its creation, embarks on a journey across physical
599−time and space into the great unknown. Hurtling through fiber-optic
600−cables at hundreds of thousands of kilometers per second, it finally
601−arrives at our neighbor's network adapter. The adapter tells unix, unix
602−tells libuv, libuv tells vere, and vere sends a `%hear` kiss to ames.
603−And now we reenter the kernel.
568+The packet, after its creation, embarks on a journey across physical time and
569+space into the great unknown. Hurtling through fiber-optic cables at hundreds of
570+thousands of kilometers per second, it finally arrives at our neighbor's network
571+adapter. The adapter tells unix, unix tells libuv, libuv tells vere, and vere
572+sends a `%hear` kiss to ames. And now we reenter the kernel.
604573
605574The `%hear` kiss goes straight to `++knob`, just as did the `%wont` kiss
606575earlier.
@@ -608,14 +577,13 @@ earlier.
608577 %hear
609578 (~(gnaw am [now fox]) %good p.kyz q.kyz)
610579
611−Here, though, we call `++gnaw:am` to process the packet. The arguments
612−to `++gnaw` are the same as those to the `%hear` kiss: the lane on which
613−the packet was received and the packet itself. The other argument is
614−just `%good`, which is a `++cape` saying that we expect the packet to
615−succeed. If a formal error occurs, then since we have a transactional
616−event system, the `%hear` event will never be considered to have
617−actually happened, and unix will send a `%hole` kiss so that we may send
618−a negative acknowledgment.
580+Here, though, we call `++gnaw:am` to process the packet. The arguments to
581+`++gnaw` are the same as those to the `%hear` kiss: the lane on which the packet
582+was received and the packet itself. The other argument is just `%good`, which is
583+a `++cape` saying that we expect the packet to succeed. If a formal error
584+occurs, then since we have a transactional event system, the `%hear` event will
585+never be considered to have actually happened, and unix will send a `%hole` kiss
586+so that we may send a negative acknowledgment.
619587
620588 ++ gnaw :: gnaw:am
621589 |= [kay=cape ryn=lane pac=rock] :: process packet
@@ -630,11 +598,10 @@ a negative acknowledgment.
630598 %- ~(chew la:(ho:(um q.p.kec) p.p.kec) kay ryn %none (shaf %flap pac))
631599 [q.kec r.kec]
632600
633−First, we check the protocol number. If it is not correct, then we
634−simply ignore the packet entirely. Otherwise, we parse the packet with
635−`++bite`, which converts a packet atom into a `cake`, that is, a triple
636−of the `sock` (pair of sender and receiver), the `skin` (encryption
637−type), and the data.
601+First, we check the protocol number. If it is not correct, then we simply ignore
602+the packet entirely. Otherwise, we parse the packet with `++bite`, which
603+converts a packet atom into a `cake`, that is, a triple of the `sock` (pair of
604+sender and receiver), the `skin` (encryption type), and the data.
638605
639606 ++ bite :: packet to cake
640607 |= pac=rock ^- cake
@@ -651,26 +618,24 @@ type), and the data.
651618 (kins tay)
652619 (rsh 3 (add wix vix) bod)
653620
654−This is exactly the inverse of `++spit`. Note that here we check both
655−the protocol number and the hash, crashing on error. Remember that a
656−crash will result in a negative acknowledgment being sent.
621+This is exactly the inverse of `++spit`. Note that here we check both the
622+protocol number and the hash, crashing on error. Remember that a crash will
623+result in a negative acknowledgment being sent.
657624
658−Continuing in `++gnaw`, we see that if the intended recipient is not on
659−our pier, then we drop the packet.
625+Continuing in `++gnaw`, we see that if the intended recipient is not on our
626+pier, then we drop the packet.
660627
661−If we've gotten this far, then we wish to process the packet. Recall
662−that `++ho` and `++um` set up the domestic server and foreign client
663−cores, respectively, and that `++zork` and `++zank` resolve any changes
664−to these cores.
628+If we've gotten this far, then we wish to process the packet. Recall that `++ho`
629+and `++um` set up the domestic server and foreign client cores, respectively,
630+and that `++zork` and `++zank` resolve any changes to these cores.
665631
666−The new stuff here, then, is the `++la` core and the `++chew` arm. The
667−`++la` sets up a core for this particular packet, containing the current
668−success/failure `cape`, the lane it was sent on, the encryption type,
669−and a hash of the packet, used as an id.
632+The new stuff here, then, is the `++la` core and the `++chew` arm. The `++la`
633+sets up a core for this particular packet, containing the current
634+success/failure `cape`, the lane it was sent on, the encryption type, and a hash
635+of the packet, used as an id.
670636
671−`++chew` is called with the encryption type and the message itself. It
672−contains a little helper core inside of it, which starts immediately
673−with `++apse`.
637+`++chew` is called with the encryption type and the message itself. It contains
638+a little helper core inside of it, which starts immediately with `++apse`.
674639
675640 ++ apse
676641 ^+ +>.$
@@ -687,23 +652,23 @@ with `++apse`.
687652 :_(bin [%wine [our her] " is your neighbor"])
688653 +>.$
689654
690−First, we let `oub` be true if our neighbor hasn't been responding to us
691−for more than sixteen seconds. Let `neg` be true if we haven't yet
692−proposed a symmetric key, meaning that we haven't yet corresponded with
693−this ship, so they are not our neighbor. Next, we run `++east`, which
694−we'll go into in just a minute.
655+First, we let `oub` be true if our neighbor hasn't been responding to us for
656+more than sixteen seconds. Let `neg` be true if we haven't yet proposed a
657+symmetric key, meaning that we haven't yet corresponded with this ship, so they
658+are not our neighbor. Next, we run `++east`, which we'll go into in just a
659+minute.
695660
696−We now do the same two checks and store the results in `eng` and `bou`.
697−If our neighbor has, like the prodigal son, returned after an extended
698−absense, then we send a `%wine` boon as the proverbial fatted calf,
699−which is simply printed out to the console. Likewise, if we are meeting
700−one with whom we have never had the pleasure of acquainting ourselves,
701−we send a message to the console to that effect.
661+We now do the same two checks and store the results in `eng` and `bou`. If our
662+neighbor has, like the prodigal son, returned after an extended absense, then we
663+send a `%wine` boon as the proverbial fatted calf, which is simply printed out
664+to the console. Likewise, if we are meeting one with whom we have never had the
665+pleasure of acquainting ourselves, we send a message to the console to that
666+effect.
702667
703−We skipped over `++east`, which contains the meat of the processing. It
704−first decrypts the message, then calls `++chow:la:ho:um:am` with the
705−resultant meal. We'll go through each of the four cases in turn, but
706−first since each one calls `++bilk:pu`, we'll take a brief detour.
668+We skipped over `++east`, which contains the meat of the processing. It first
669+decrypts the message, then calls `++chow:la:ho:um:am` with the resultant meal.
670+We'll go through each of the four cases in turn, but first since each one calls
671+`++bilk:pu`, we'll take a brief detour.
707672
708673 ++ bilk :: bilk:pu
709674 |= now=@da :: inbound packet
@@ -715,11 +680,10 @@ first since each one calls `++bilk:pu`, we'll take a brief detour.
715680 rtn ?~(puq ~ [~ (add now trt)])
716681 ==
717682
718−This updates the timing information in our packet pump. `rue`, the last
719−time we have heard from this neighbor, is set to now. `rto`, the
720−retransmit timeout is set to twice the current ping time, and if there
721−is anything in the packet queue, then we reset the next timeout, since
722−we've just heard a message.
683+This updates the timing information in our packet pump. `rue`, the last time we
684+have heard from this neighbor, is set to now. `rto`, the retransmit timeout is
685+set to twice the current ping time, and if there is anything in the packet
686+queue, then we reset the next timeout, since we've just heard a message.
723687
724688Back to `++east`.
725689
@@ -727,11 +691,11 @@ Back to `++east`.
727691 =. puz (bilk:puz now)
728692 (chow ((hard meal) (cue msg)))
729693
730−The simplest case is when the encryption type is `%none`. We first call
731−`++bilk` to update the packet pump, then we cue (unjam) the message into
732−a meal. We hard cast it into a meal -- if the cast fails, then we do
733−want to crash since someone is sending us malformed data. Finally, we
734−send the result to `++chow` for interpretation and handling.
694+The simplest case is when the encryption type is `%none`. We first call `++bilk`
695+to update the packet pump, then we cue (unjam) the message into a meal. We hard
696+cast it into a meal -- if the cast fails, then we do want to crash since someone
697+is sending us malformed data. Finally, we send the result to `++chow` for
698+interpretation and handling.
735699
736700 %fast
737701 =+ [mag=`hand`(end 7 1 msg) bod=(rsh 7 1 msg)]
@@ -743,15 +707,14 @@ send the result to `++chow` for interpretation and handling.
743707 =^ key diz u.dey
744708 (chow(aut sin) ((hard meal) (cue (dy:q:sen:gus key bod))))
745709
746−For symmetric encryption, we first get the `hand`, which is the hash of
747−the symmetric key. We pass it to `++kuch:lax:as:go`, which returns the
748−key if we either have used it before or we have proposed it. If we have
749−proposed it, then we change its status from proposed to real. If
750−`++kuch` fails, then we drop the packet and print out a `%bad-key`
751−message.
710+For symmetric encryption, we first get the `hand`, which is the hash of the
711+symmetric key. We pass it to `++kuch:lax:as:go`, which returns the key if we
712+either have used it before or we have proposed it. If we have proposed it, then
713+we change its status from proposed to real. If `++kuch` fails, then we drop the
714+packet and print out a `%bad-key` message.
752715
753−Otherwise, we call `++bilk` as before to update the packet pump and pass
754−into `++chow` the decrypted data.
716+Otherwise, we call `++bilk` as before to update the packet pump and pass into
717+`++chow` the decrypted data.
755718
756719 %full
757720 =+ mex=((hard ,[p=[p=life q=life] q=will r=@]) (cue msg))
@@ -764,17 +727,16 @@ into `++chow` the decrypted data.
764727 =. puz (bilk:puz now)
765728 (west(msg q.mes))
766729
767−For sealed asymmetric encryption, we first take off the the layer of
768−data that gives us the life and will of our neighbor, and we apply try
769−to extend their former will with the new data. `++deng` will fail if
770−this is impossible.
730+For sealed asymmetric encryption, we first take off the the layer of data that
731+gives us the life and will of our neighbor, and we apply try to extend their
732+former will with the new data. `++deng` will fail if this is impossible.
771733
772−Next, we get our most current understanding of our neighbor's crypto,
773−and we verify that it's the same life as what they're sending. Then, we
774−get our own crypto from `++sev` and decrypt the message with the public
775−key from our neighbor's crypto. We register the proposed symmetric key,
776−update the packet pump, and call `++west`, which simply casts the
777−message to a meal and calls `++chow`, reporting any error.
734+Next, we get our most current understanding of our neighbor's crypto, and we
735+verify that it's the same life as what they're sending. Then, we get our own
736+crypto from `++sev` and decrypt the message with the public key from our
737+neighbor's crypto. We register the proposed symmetric key, update the packet
738+pump, and call `++west`, which simply casts the message to a meal and calls
739+`++chow`, reporting any error.
778740
779741 %open
780742 =+ mex=((hard ,[p=[~ q=life] q=will r=@]) (cue msg))
@@ -785,14 +747,13 @@ message to a meal and calls `++chow`, reporting any error.
785747 =. puz (bilk:puz now)
786748 (west(msg mes))
787749
788−Finally, for signed asymmetric encryption, we, as before, take off the
789−layer of data that gives us the life and will of our neighbor. This
790−time, of course, we do not get our own crypto -- only that of our
791−neighbor.
750+Finally, for signed asymmetric encryption, we, as before, take off the layer of
751+data that gives us the life and will of our neighbor. This time, of course, we
752+do not get our own crypto -- only that of our neighbor.
792753
793−The rest you have seen. We call `++deng` to extend the will, we verify
794−that their crypto life is what we think it ought to be, we "decrypt" the
795−data, we update the packet pump, and we call `++west` to call `++chow`.
754+The rest you have seen. We call `++deng` to extend the will, we verify that
755+their crypto life is what we think it ought to be, we "decrypt" the data, we
756+update the packet pump, and we call `++west` to call `++chow`.
796757
797758 ++ chow :: chow:la:ho:um:am
798759 |= fud=meal :: interpret meal
@@ -800,15 +761,14 @@ data, we update the packet pump, and we call `++west` to call `++chow`.
800761 =. diz ?:(=(%none aut) diz (wast:diz ryn))
801762 (dine fud)
802763
803−Here, if the message was encrypted at all, then we call
804−`++wast:lax:as:go`, which simply updates the lane (route) to our
805−neighbor (unless we're given a provisional route). This ensures that we
806−always have the most direct possible path to them.
764+Here, if the message was encrypted at all, then we call `++wast:lax:as:go`,
765+which simply updates the lane (route) to our neighbor (unless we're given a
766+provisional route). This ensures that we always have the most direct possible
767+path to them.
807768
808−We've been handling this meal for so long, we've almost forgotten what
809−we want to do with it. The telos is of any meal to be dined on. We will
810−choose out the cases here that are important to our current
811−investigation.
769+We've been handling this meal for so long, we've almost forgotten what we want
770+to do with it. The telos is of any meal to be dined on. We will choose out the
771+cases here that are important to our current investigation.
812772
813773 %fore
814774 =+ ^= lyn ^- lane
@@ -821,12 +781,12 @@ investigation.
821781 =+ zid=(myx:gus p.fud)
822782 (emir (wist:zid now xong:zid [~ lyn] r.fud))
823783
824−Forwarding is the simplest case, since we've seen all the arms before,
825−except perhaps `++emit` and `++emir`, which simply take a boon or list
826−of boons respectively and queue them up to be handled when the core
827−resolves. If we're told to forward a packet to ourselves, then we emit a
828−`%mead` boon which simply sends another `%hear` kiss to ourselves with
829−the data. Otherwise, we try to find a route to the recipient, as before.
784+Forwarding is the simplest case, since we've seen all the arms before, except
785+perhaps `++emit` and `++emir`, which simply take a boon or list of boons
786+respectively and queue them up to be handled when the core resolves. If we're
787+told to forward a packet to ourselves, then we emit a `%mead` boon which simply
788+sends another `%hear` kiss to ourselves with the data. Otherwise, we try to find
789+a route to the recipient, as before.
830790
831791 %carp
832792 =+ zol=(~(get by olz.weg) s.fud)
@@ -855,31 +815,30 @@ the data. Otherwise, we try to find a route to the recipient, as before.
855815 +>.$(nys.weg (~(put by nys.weg) s.fud neb))
856816
857817Here, we have received a partial message, and we're just assembling the
858−individual packets into a message. Most of this code is fairly
859−algorithmic, so we'll just hit the high points. In the beginning, we
860−check if we've already received this message, and if so, we resend the
861−acknowledgment. Remember, "always ack a dupe, never ack an ack".
862−
863−In `nys.weg` we keep track of an incoming set of partial packets,
864−indexed by the `flap` hash that comes with every packet. We check to see
865−if we have already received this partial message, and if so we
866−acknowledge it. Otherwise, we put it in `nys.weg` unless this is the
867−last message, in which case we ack the last partial message, move the
868−complete message into `olz.weg`, and call `++golf`, which assembles the
869−message and calls `++chew`, to start the dance again with the complete
870−message.
818+individual packets into a message. Most of this code is fairly algorithmic, so
819+we'll just hit the high points. In the beginning, we check if we've already
820+received this message, and if so, we resend the acknowledgment. Remember,
821+"always ack a dupe, never ack an ack".
822+
823+In `nys.weg` we keep track of an incoming set of partial packets, indexed by the
824+`flap` hash that comes with every packet. We check to see if we have already
825+received this partial message, and if so we acknowledge it. Otherwise, we put it
826+in `nys.weg` unless this is the last message, in which case we ack the last
827+partial message, move the complete message into `olz.weg`, and call `++golf`,
828+which assembles the message and calls `++chew`, to start the dance again with
829+the complete message.
871830
872831 %bund
873832 :: ~& [%bund q.fud r.fud]
874833 ?> =(p:sen:gus p.fud)
875834 (deer q.fud r.fud ?-(kay %dead ~, %good [~ s.fud]))
876835
877−What if we're just receiving a regular old, garden variety message? We
878−call `++deer` with the data from the message. If we already know that
879−the message processing will fail (that is, if we got a `%hole` card from
880−unix rather than a `%hear` card), then we don't even send the data at
881−all. Remember, if a packet fails to process, it's as if it never even
882−arrived, except that we send a negative acknowledgment.
836+What if we're just receiving a regular old, garden variety message? We call
837+`++deer` with the data from the message. If we already know that the message
838+processing will fail (that is, if we got a `%hole` card from unix rather than a
839+`%hear` card), then we don't even send the data at all. Remember, if a packet
840+fails to process, it's as if it never even arrived, except that we send a
841+negative acknowledgment.
883842
884843 ++ deer :: deer:la:ho:um:am
885844 |= [cha=path num=@ud dut=(unit)] :: interpret message
@@ -898,24 +857,22 @@ arrived, except that we send a negative acknowledgment.
898857 ==
899858 ==
900859
901−First, we get the race for this particular triple of sender, receiver,
902−and path, creating it if it doesn't exist. If we've already acked the
903−message, then we resend the ack. Note that `did.rum` is the number of
904−packets we acknowledged, positively or negatively while `bum.rum` is a
905−map of message numbers to negative acknowledgments. Thus, if a message
906−number is less than `did.rum`, then if it's in `bum.rum` then it was
907−negatively acknowledged, otherwise it's postively acknowledged. Thus, we
908−are constant in space with the number of successful messages and linear
909−in the number of failed messages. We'll document `++cook` later on, but
910−suffice it to say that it sends an acknowledgment. It is to end-to-end
911−acknowledgments what `++cock` is to packet-level acknowledgments.
912−
913−If we are still processing a message (that is, `dod.rum` is false), then
914−we simply put this message in the map of misordered packets to be
915−processed when their time comes. "Processing a message" in this case
916−means that we've received the message and notified the correct
917−application, but we're still waiting for the application-level
918−acknowledgment.
860+First, we get the race for this particular triple of sender, receiver, and path,
861+creating it if it doesn't exist. If we've already acked the message, then we
862+resend the ack. Note that `did.rum` is the number of packets we acknowledged,
863+positively or negatively while `bum.rum` is a map of message numbers to negative
864+acknowledgments. Thus, if a message number is less than `did.rum`, then if it's
865+in `bum.rum` then it was negatively acknowledged, otherwise it's postively
866+acknowledged. Thus, we are constant in space with the number of successful
867+messages and linear in the number of failed messages. We'll document `++cook`
868+later on, but suffice it to say that it sends an acknowledgment. It is to
869+end-to-end acknowledgments what `++cock` is to packet-level acknowledgments.
870+
871+If we are still processing a message (that is, `dod.rum` is false), then we
872+simply put this message in the map of misordered packets to be processed when
873+their time comes. "Processing a message" in this case means that we've received
874+the message and notified the correct application, but we're still waiting for
875+the application-level acknowledgment.
919876
920877Otherwise, we're ready for a packet, so we process it.
921878
@@ -937,20 +894,18 @@ Otherwise, we're ready for a packet, so we process it.
937894 u.s.u.cun
938895 ==
939896
940−First, we grab the message we want to process and store it in `cun`. If
941−it's a good packet, then we change `dod.rum` to false, meaning that
942−we're in the middle of processing a packet and should not start
943−processing another one. We also put a `%mulk` boon into the queue so
944−that, when it all resolves, we send a mesage to the intended recipient
945−application. The boon contains the sender, the receiver, the identity of
946−the message, and the message itself.
947−
948−This bubbles up all the way back to `++knob`, where we were handling the
949−`%hear` card. Following the logic in `++knob`, we can see that the boons
950−get sent into `++clop` to be turned into actual arvo-level moves. We've
951−been here before, if you recall, when we handled the `%cake` boon to
952−send a message. Now, we're handling the `%mulk` boon, which is
953−unfortunately slightly more complicated.
897+First, we grab the message we want to process and store it in `cun`. If it's a
898+good packet, then we change `dod.rum` to false, meaning that we're in the middle
899+of processing a packet and should not start processing another one. We also put
900+a `%mulk` boon into the queue so that, when it all resolves, we send a mesage to
901+the intended recipient application. The boon contains the sender, the receiver,
902+the identity of the message, and the message itself.
903+
904+This bubbles up all the way back to `++knob`, where we were handling the `%hear`
905+card. Following the logic in `++knob`, we can see that the boons get sent into
906+`++clop` to be turned into actual arvo-level moves. We've been here before, if
907+you recall, when we handled the `%cake` boon to send a message. Now, we're
908+handling the `%mulk` boon, which is unfortunately slightly more complicated.
954909
955910 %mulk
956911 :: ~& [%mulk p.bon q.bon]
@@ -980,51 +935,48 @@ unfortunately slightly more complicated.
980935 :_ fox [hen %pass pax %g %roth p.bon app r.bon]~
981936 ==
982937
983−We're dispatching messages based on the prefix of their path. Since only
984−`%gall` apps use end-to-end acknowledgments at the moment, every path
985−must have at least two elements, and the first one must be `%q`. Beyond
986−that, we handle the `/q/ge` and `/q/gh` cases for gall requests and
987−responses, respectively.
988−
989−In both cases, we require the next term in the path to be the name of
990−the intended recipient `%gall` app. Thus, a message to `/q/ge/talk` for
991−example, will send a message to the talk app.
992−
993−We then send a message to the app itself. The message is either a
994−`%rote` or a `%roth` for a request and a response, respectively. The
995−content is the `rook` or `roon` that was sent (stored in `r.bon`), but
996−we don't actually handle that at all here. That's completely a
997−`%gall`-level thing. We're just the messenger.
998−
999−Notice the path we send this over. We encode the sender, the receiver,
1000−and the path over which it was sent. This fully specifies the `race` so
1001−that when the app gives us the acknowledgment we know where to send it.
1002−
1003−We now have another interlude. We have entrusted our precious data, so
1004−carefully guarded and guided from the app on that far-away ship, to our
1005−local app. It has the ability to do whatever it pleases with it. It may
1006−take a significant amount of time to process. When the message has been
1007−handled by this app, though, it must produce an acknowledgment. Our
1008−final task is to deliver this acknowledgment to the sending app.
938+We're dispatching messages based on the prefix of their path. Since only `%gall`
939+apps use end-to-end acknowledgments at the moment, every path must have at least
940+two elements, and the first one must be `%q`. Beyond that, we handle the `/q/ge`
941+and `/q/gh` cases for gall requests and responses, respectively.
942+
943+In both cases, we require the next term in the path to be the name of the
944+intended recipient `%gall` app. Thus, a message to `/q/ge/talk` for example,
945+will send a message to the talk app.
946+
947+We then send a message to the app itself. The message is either a `%rote` or a
948+`%roth` for a request and a response, respectively. The content is the `rook` or
949+`roon` that was sent (stored in `r.bon`), but we don't actually handle that at
950+all here. That's completely a `%gall`-level thing. We're just the messenger.
951+
952+Notice the path we send this over. We encode the sender, the receiver, and the
953+path over which it was sent. This fully specifies the `race` so that when the
954+app gives us the acknowledgment we know where to send it.
955+
956+We now have another interlude. We have entrusted our precious data, so carefully
957+guarded and guided from the app on that far-away ship, to our local app. It has
958+the ability to do whatever it pleases with it. It may take a significant amount
959+of time to process. When the message has been handled by this app, though, it
960+must produce an acknowledgment. Our final task is to deliver this acknowledgment
961+to the sending app.
1009962
1010963We should describe here what exactly these oft-mentioned acknowledgments
1011−actually consist of. There are two kinds of acknowledgments: positive
1012−and negative. A positive acknowledgment contains no data other than its
1013−existence. A negative acknowledgment may optionally include a reason for
1014−said negativity. Formally, a negative acknowledgment is an `ares`, which
1015−is a unit pair of a term and a list of tanks. If this is null, this is
1016−simply a failure with no associated information. If the pair exists, the
1017−term is a short error code that is usually both human and computer
1018−readable. For example, if you try to send a message to a valid `%gall`
1019−app that doesn't have any `++poke` to handle it, then `%gall` will give
1020−a negative acknowledgment with error term `%poke-find-fail`. The list of
1021−tanks is a human-readable description of the error. This often contains
1022−a stack trace. At any rate, all this information is returned to the
964+actually consist of. There are two kinds of acknowledgments: positive and
965+negative. A positive acknowledgment contains no data other than its existence. A
966+negative acknowledgment may optionally include a reason for said negativity.
967+Formally, a negative acknowledgment is an `ares`, which is a unit pair of a term
968+and a list of tanks. If this is null, this is simply a failure with no
969+associated information. If the pair exists, the term is a short error code that
970+is usually both human and computer readable. For example, if you try to send a
971+message to a valid `%gall` app that doesn't have any `++poke` to handle it, then
972+`%gall` will give a negative acknowledgment with error term `%poke-find-fail`.
973+The list of tanks is a human-readable description of the error. This often
974+contains a stack trace. At any rate, all this information is returned to the
1023975sending app on the other end of the wire.
1024976
1025−After this brief interlude, our story resumes in `++knap`, where we
1026−receive responses. In particular, a `%mean` indicates a negative
1027−acknowledgment while a `%nice` indicates a positive acknowledgment.
977+After this brief interlude, our story resumes in `++knap`, where we receive
978+responses. In particular, a `%mean` indicates a negative acknowledgment while a
979+`%nice` indicates a positive acknowledgment.
1028980
1029981 ?(%mean %nice)
1030982 ?> ?=([@ @ @ *] tea)
@@ -1042,11 +994,10 @@ acknowledgment while a `%nice` indicates a positive acknowledgment.
1042994 =^ toe fox (clop now hen i.p.fuy)
1043995 $(p.fuy t.p.fuy, out (weld (flop toe) out))
1044996
1045−Recall the format of the path we sent the message on, and you'll
1046−understand why `soq` and `pax` are the sender/receiver pair and path on
1047−which the message was sent. The rest of this is structured much like
1048−`++knob`, so we call `++rack:am` and send the resulting boons to
1049−`++clop`. Business as usual.
997+Recall the format of the path we sent the message on, and you'll understand why
998+`soq` and `pax` are the sender/receiver pair and path on which the message was
999+sent. The rest of this is structured much like `++knob`, so we call `++rack:am`
1000+and send the resulting boons to `++clop`. Business as usual.
10501001
10511002 ++ rack :: rack:am
10521003 |= [soq=sock cha=path cop=coop] :: e2e ack
@@ -1054,11 +1005,10 @@ which the message was sent. The rest of this is structured much like
10541005 =. oh (cook:oh cop cha ~)
10551006 (cans:oh cha)
10561007
1057−First, we set up `++um` and `++ho`, as we've done twice before, for our
1058−domestic and foreign servers, respectively. The other two things are
1059−new, though. Well, `++cook` is not actually new, but we delayed the
1060−explanation saying only that it sends an acknowledgment. The time has
1061−come.
1008+First, we set up `++um` and `++ho`, as we've done twice before, for our domestic
1009+and foreign servers, respectively. The other two things are new, though. Well,
1010+`++cook` is not actually new, but we delayed the explanation saying only that it
1011+sends an acknowledgment. The time has come.
10621012
10631013 ++ cook :: cook:ho:um:am
10641014 |= [cop=coop cha=path ram=(unit ,[ryn=lane dam=flap])]
@@ -1077,61 +1027,58 @@ come.
10771027 =^ roc diz (zuul:diz now [%buck cop dam ~s0])
10781028 (busk(diz (wast:diz ryn)) xong:diz roc)
10791029
1080−If we are acknowledging a message that we have already acked, the `ram`
1081−will contain the new lane and flap to send the duplicate ack to. This
1082−happens if we call `++cook` in `++deer`, but it doesn't happen from
1083−`++rack`. If there is no message waiting to be acknowledged and we're
1084−not given an explicit lane and flap (that is, we're not sending a
1085−duplicate ack), then the app must have sent us multiple acknowledgments.
1086−We do the only sensible thing we can do and drop all acknowledgments
1087−after the first, printing a message. This is, in fact, an error, so it
1088−could be argued that we ought to crash. Whatever you do, don't depend on
1030+If we are acknowledging a message that we have already acked, the `ram` will
1031+contain the new lane and flap to send the duplicate ack to. This happens if we
1032+call `++cook` in `++deer`, but it doesn't happen from `++rack`. If there is no
1033+message waiting to be acknowledged and we're not given an explicit lane and flap
1034+(that is, we're not sending a duplicate ack), then the app must have sent us
1035+multiple acknowledgments. We do the only sensible thing we can do and drop all
1036+acknowledgments after the first, printing a message. This is, in fact, an error,
1037+so it could be argued that we ought to crash. Whatever you do, don't depend on
10891038this not crashing.
10901039
1091−First, we grab the race specified by the given path, and we get the most
1092−recent in-order message, which must be the one which is being
1093−acknowledged.
1094−
1095−Then, we decide which lane/flap to respond on/to. Basically, in the
1096−usual case we respond on the lane through which the initial message was
1097−sent, which is stored along with the other packet information in
1098−`mis.rum`, since it has to be remembered across calls to ames. However,
1099−if we receive a duplicate message, then we must respond to the new
1100−message. It's quite possible the reason the other acknowledgment didn't
1101−get returned was that the lane between the ships was broken.
1102−
1103−At any rate, we update the race by saying that we've finished processing
1104−this packet (unless we're sending a duplicate ack) and, if we're sending
1105−a negative acknowledgment, putting the negative ack into `bum.rum` so
1106−that we can resend it if necessary.
1107−
1108−We encode our new message, updating the packet pump, with `++zuul`, as
1109−before, and we send it off with `++busk`, routed via `++wast` to one of
1110−the ships in `++xong`. Of course, in practice, we don't even look at the
1111−ships in `++xong` because we already have a lane directly to our
1112−neighbor (the one over which they sent their message to us).
1113−
1114−We glossed over the actual message we're sending back. We're sending a
1115−`%buck` meal, which is an acknowledgment. The `cop` specifies whether
1116−this is a positive or a negative ack, `dam` specifies the message we're
1117−acknowledging, and the `~s0` is a placeholder for the processing time
1118−required. This time is neither calculated (though it is hopefully
1119−obvious how to do so) nor used at present, but this information may be
1120−used in the future for improved congestion control. Since the round-trip
1121−time for an end-to-end acknowledged packet includes the processing time
1122−on the other end, most common congestion control algorithms will stumble
1123−when some messages take much longer to process than others. As noted,
1124−though, this is simply an opportunity for improvement -- our congestion
1125−control algorithms are relatively naive at the moment.
1126−
1127−Recall that `++busk` calls `++wist` to put the actual `%ouzo` boon in
1128−the queue, which gets handled by `++clop` to actually send the message.
1129−This is the same pipeline as sending any other message, so we'll refer
1130−you to the explanation above if you've forgotten it.
1131−
1132−The last thing we need to do on this ship is move on to the next packet
1133−in the queue if there is one. If you recall, in `++rack` after the call
1134−to `++cook` there was a call to `++cans:ho:um:am`.
1040+First, we grab the race specified by the given path, and we get the most recent
1041+in-order message, which must be the one which is being acknowledged.
1042+
1043+Then, we decide which lane/flap to respond on/to. Basically, in the usual case
1044+we respond on the lane through which the initial message was sent, which is
1045+stored along with the other packet information in `mis.rum`, since it has to be
1046+remembered across calls to ames. However, if we receive a duplicate message,
1047+then we must respond to the new message. It's quite possible the reason the
1048+other acknowledgment didn't get returned was that the lane between the ships was
1049+broken.
1050+
1051+At any rate, we update the race by saying that we've finished processing this
1052+packet (unless we're sending a duplicate ack) and, if we're sending a negative
1053+acknowledgment, putting the negative ack into `bum.rum` so that we can resend it
1054+if necessary.
1055+
1056+We encode our new message, updating the packet pump, with `++zuul`, as before,
1057+and we send it off with `++busk`, routed via `++wast` to one of the ships in
1058+`++xong`. Of course, in practice, we don't even look at the ships in `++xong`
1059+because we already have a lane directly to our neighbor (the one over which they
1060+sent their message to us).
1061+
1062+We glossed over the actual message we're sending back. We're sending a `%buck`
1063+meal, which is an acknowledgment. The `cop` specifies whether this is a positive
1064+or a negative ack, `dam` specifies the message we're acknowledging, and the
1065+`~s0` is a placeholder for the processing time required. This time is neither
1066+calculated (though it is hopefully obvious how to do so) nor used at present,
1067+but this information may be used in the future for improved congestion control.
1068+Since the round-trip time for an end-to-end acknowledged packet includes the
1069+processing time on the other end, most common congestion control algorithms will
1070+stumble when some messages take much longer to process than others. As noted,
1071+though, this is simply an opportunity for improvement -- our congestion control
1072+algorithms are relatively naive at the moment.
1073+
1074+Recall that `++busk` calls `++wist` to put the actual `%ouzo` boon in the queue,
1075+which gets handled by `++clop` to actually send the message. This is the same
1076+pipeline as sending any other message, so we'll refer you to the explanation
1077+above if you've forgotten it.
1078+
1079+The last thing we need to do on this ship is move on to the next packet in the
1080+queue if there is one. If you recall, in `++rack` after the call to `++cook`
1081+there was a call to `++cans:ho:um:am`.
11351082
11361083 ++ cans :: cans:ho:um:am
11371084 |= cha=path
@@ -1143,38 +1090,37 @@ to `++cook` there was a call to `++cans:ho:um:am`.
11431090 ==
11441091 (coat cha rum)
11451092
1146−This is very simple. We increment the number of packets that we've
1147−acknowledged on this race and we delete the packet that we just
1148−acknowledged from the set of misordered packets.
1093+This is very simple. We increment the number of packets that we've acknowledged
1094+on this race and we delete the packet that we just acknowledged from the set of
1095+misordered packets.
11491096
11501097Then, we call `++coat` again to process the next packet if we've already
11511098received it. And that's it for this.
11521099
1153−The acknowledgment now travels the same path that its forebearer, the
1154−original message, once tread, but this time not into the great unknown.
1155−The weary traveler is seeking out its familial roots, finding the app
1156−from whom sprung forth the original message way back in paragraph three.
1157−When it arrives at the network adapter of its ancestors, the adapter
1158−tells unix, unix tells libuv, libuv tells vere, and vere sends a `%hear`
1159−kiss to ames. Once more into the kernel.
1100+The acknowledgment now travels the same path that its forebearer, the original
1101+message, once tread, but this time not into the great unknown. The weary
1102+traveler is seeking out its familial roots, finding the app from whom sprung
1103+forth the original message way back in paragraph three. When it arrives at the
1104+network adapter of its ancestors, the adapter tells unix, unix tells libuv,
1105+libuv tells vere, and vere sends a `%hear` kiss to ames. Once more into the
1106+kernel.
11601107
1161−The `%hear` kiss is handled in `++knob` as before, leading to `++gnaw`,
1162−going over to `++chew`, `++apse`, `++chow`, and eventualy to `++dine`.
1163−We've seen most of the cases in `++dine`, but we haven't yet looked at
1164−the handling of this `%buck` meal.
1108+The `%hear` kiss is handled in `++knob` as before, leading to `++gnaw`, going
1109+over to `++chew`, `++apse`, `++chow`, and eventualy to `++dine`. We've seen most
1110+of the cases in `++dine`, but we haven't yet looked at the handling of this
1111+`%buck` meal.
11651112
11661113 %buck
11671114 =. +> ?.(=(%full aut) +> cock) :: finish key exch
11681115 +>(..la (tock p.fud q.fud r.fud))
11691116
1170−We send a packet level acknowledgment if we're finishing a key exchange,
1171−else we call `++tock` to process the acknowledgment.
1117+We send a packet level acknowledgment if we're finishing a key exchange, else we
1118+call `++tock` to process the acknowledgment.
11721119
1173−This will get a little involved, so if you don't much care about how
1174−exactly an acknowledgment happens, just know that the result gets gifted
1175−as a `%woot` card back to the app who sent it. For those brave souls who
1176−wish to see this thing through to the end, it's once more into the
1177−breach.
1120+This will get a little involved, so if you don't much care about how exactly an
1121+acknowledgment happens, just know that the result gets gifted as a `%woot` card
1122+back to the app who sent it. For those brave souls who wish to see this thing
1123+through to the end, it's once more into the breach.
11781124
11791125 ++ tock :: tock:ho:um:am
11801126 |= [cop=coop fap=flap cot=@dr] :: e2e ack by hash
@@ -1192,9 +1138,9 @@ breach.
11921138 ==
11931139 (busk xong:diz q.yoh)
11941140
1195−We're going to work through this one a little backwards since it's
1196−mostly fairly simple except the call to `++bick:pu`. In fact, we'll just
1197−skip `++bick` for the moment and finish the rest.
1141+We're going to work through this one a little backwards since it's mostly fairly
1142+simple except the call to `++bick:pu`. In fact, we'll just skip `++bick` for the
1143+moment and finish the rest.
11981144
11991145If `++bick` succesfully acks the message, then we call `++done`.
12001146
@@ -1210,37 +1156,35 @@ If `++bick` succesfully acks the message, then we call `++done`.
12101156 (~(put by ryl.bah) cha rol(san (~(del by san.rol) num)))
12111157 ==
12121158
1213−This very simply gets the rill (the outgoing counterpart to a race, if
1214−you recall), pulls out of the map of outstanding messages the duct over
1215−which the original message was sent, and produces this duct while
1216−deleting that entry from the map of outstanding messages.
1159+This very simply gets the rill (the outgoing counterpart to a race, if you
1160+recall), pulls out of the map of outstanding messages the duct over which the
1161+original message was sent, and produces this duct while deleting that entry from
1162+the map of outstanding messages.
12171163
1218−Going back to `++tock`, we now have the duct we need to return the
1219−result over. We do the very sensible thing and put a `%cake` boon in the
1220−queue to be processed later by `++clop`.
1164+Going back to `++tock`, we now have the duct we need to return the result over.
1165+We do the very sensible thing and put a `%cake` boon in the queue to be
1166+processed later by `++clop`.
12211167
1222−In `q.yoh` we have a list of messages that may need to be sent, which we
1223−pass to `++busk` to send, as usual. When an acknowledgment arrives, that
1224−may trigger other messages immediately. This often happens when sending
1225−more messages than the width of the logical window since for congestion
1226−control reasons another message cannot be sent until some of the earlier
1227−ones have been acknowledged.
1168+In `q.yoh` we have a list of messages that may need to be sent, which we pass to
1169+`++busk` to send, as usual. When an acknowledgment arrives, that may trigger
1170+other messages immediately. This often happens when sending more messages than
1171+the width of the logical window since for congestion control reasons another
1172+message cannot be sent until some of the earlier ones have been acknowledged.
12281173
1229−We'll look at the processing of the `%cake` boon in `++clop` before we
1230−get back to talking about `++bick`.
1174+We'll look at the processing of the `%cake` boon in `++clop` before we get back
1175+to talking about `++bick`.
12311176
12321177 %cake
12331178 :_ fox
12341179 :~ [s.bon %give %woot q.p.bon r.bon]
12351180 ==
12361181
1237−We very simply give, along the duct we found above, a `%woot` card with
1238−the ship who sent us the ack and the ack itself. This allows the
1239−application to decide what to do about the result. In case of a failure,
1240−we usually either resend the message or display it to the user.
1241−Sometimes, we recognize the error term and handle it internally. In any
1242−case, the decision of how to handle the acknowledgment is entirely up to
1243−the application. Our job is done.
1182+We very simply give, along the duct we found above, a `%woot` card with the ship
1183+who sent us the ack and the ack itself. This allows the application to decide
1184+what to do about the result. In case of a failure, we usually either resend the
1185+message or display it to the user. Sometimes, we recognize the error term and
1186+handle it internally. In any case, the decision of how to handle the
1187+acknowledgment is entirely up to the application. Our job is done.
12441188
12451189Well, except that we skipped `++bick:pu`. Let's go back to that.
12461190
@@ -1255,19 +1199,18 @@ Well, except that we skipped `++bick:pu`. Let's go back to that.
12551199 =^ yop +>.$ (harv now)
12561200 [[gub yop] +>.$]
12571201
1258−If you recall, in `++whap:pu` we created the packet pump's
1259−representation of the message, which included putting the message into
1260−`diq`, which maps from packet hashes to packet sequence numbers. Thus,
1261−`u.sun` is the sequence number of this particular message.
1202+If you recall, in `++whap:pu` we created the packet pump's representation of the
1203+message, which included putting the message into `diq`, which maps from packet
1204+hashes to packet sequence numbers. Thus, `u.sun` is the sequence number of this
1205+particular message.
12621206
1263−We delete this message from `diq` since we have now received an ack for
1264−it. We call `++bock` to perform the ack by sequence number. We call
1265−`++harv` to harvest the packet queue, sending any messages that are now
1266−able to be sent.
1207+We delete this message from `diq` since we have now received an ack for it. We
1208+call `++bock` to perform the ack by sequence number. We call `++harv` to harvest
1209+the packet queue, sending any messages that are now able to be sent.
12671210
1268−In `++bock`, there are three arms we haven't seen before: `++bine`,
1269−`+wept`, and `++beet`. We'll describe each of these before we get to
1270−`++bock`. `++bine` looks scariest.
1211+In `++bock`, there are three arms we haven't seen before: `++bine`, `+wept`, and
1212+`++beet`. We'll describe each of these before we get to `++bock`. `++bine` looks
1213+scariest.
12711214
12721215 ++ bine :: bine:pu
12731216 |= [now=@da num=@ud] :: apply ack
@@ -1293,36 +1236,34 @@ In `++bock`, there are three arms we haven't seen before: `++bine`,
12931236 :- gub
12941237 +>.$(puq ~(nap to puq))
12951238
1296−The first few lines are simply looking through the packet queue until we
1297−find the correct packet to ack. This is basic queue manipulation that
1298−operates directly on the treap structure of the queue. If you understand
1299−treap queues, the logic is easy to follow. Otherwise, just trust us that
1300−by the time we get to the `=:`, the packet with sequence number `num` is
1301−on the top of the packet queue (that is, at `n.puq`).
1302−
1303−We first update the round-trip time. If the packet is either not alive
1304−or had to be transmitted more than once, then we don't have any reliable
1305−way of calculating the round-trip time since we're unsure of exactly
1306−which transmission was acknowledged. Otherwise, the round-trip time is
1307−the difference between now and when the packet was last sent. We set
1308−`rtt` by a little weighted average where the previous smoothed RTT is
1309−weighted twice as much as the RTT of the current packet. Thus,
1310−`(2*rtt+gap)/3`. This gives us a nice smooth RTT that is somewhat
1311−resilient to outlier data while still being responsive to our
1239+The first few lines are simply looking through the packet queue until we find
1240+the correct packet to ack. This is basic queue manipulation that operates
1241+directly on the treap structure of the queue. If you understand treap queues,
1242+the logic is easy to follow. Otherwise, just trust us that by the time we get to
1243+the `=:`, the packet with sequence number `num` is on the top of the packet
1244+queue (that is, at `n.puq`).
1245+
1246+We first update the round-trip time. If the packet is either not alive or had to
1247+be transmitted more than once, then we don't have any reliable way of
1248+calculating the round-trip time since we're unsure of exactly which transmission
1249+was acknowledged. Otherwise, the round-trip time is the difference between now
1250+and when the packet was last sent. We set `rtt` by a little weighted average
1251+where the previous smoothed RTT is weighted twice as much as the RTT of the
1252+current packet. Thus, `(2*rtt+gap)/3`. This gives us a nice smooth RTT that is
1253+somewhat resilient to outlier data while still being responsive to our
13121254ever-changing world.
13131255
1314−If the packet wasn't already dead, then we decrement the number of live
1315−packets, which may allow more packets to be sent.
1256+If the packet wasn't already dead, then we decrement the number of live packets,
1257+which may allow more packets to be sent.
13161258
13171259We decrement the number of unacknowledged packets in our `pyz` for this
1318−particular message. If you recall, this was set in `++whap` to the
1319−number of packets required to send a message.
1260+particular message. If you recall, this was set in `++whap` to the number of
1261+packets required to send a message.
13201262
1321−If that was the last packet in the messge that needed to be acked, then
1322−we delete the messgae reference from `pyz` and produce the id of the
1323−message. Otherwise, we simply update `pyz` with the new number of
1324−unacked messages. In either case, we remove the packet from the packet
1325−queue.
1263+If that was the last packet in the messge that needed to be acked, then we
1264+delete the messgae reference from `pyz` and produce the id of the message.
1265+Otherwise, we simply update `pyz` with the new number of unacked messages. In
1266+either case, we remove the packet from the packet queue.
13261267
13271268 ++ wept :: wept:pu
13281269 |= [fip=@ud lap=@ud] :: fip thru lap-1
@@ -1346,12 +1287,12 @@ queue.
13461287 ^+(. =+(rig=apse(puq r.puq) rig(puq [n.puq l.puq puq.rig])))
13471288 --
13481289
1349−The algorithm is a simple case of traversing the packet queue.
1350−Essentialy, we mark as dead all packets in the queue between `fip` and
1351−`(dec lap)`. We also update `nif`, the number of live packets. Lest you
1352−mourn too much the passing of these packets, know that they shall soon
1353−rise again. Recall that in `++bick` after the call to `++bock` we call
1354−`++harv`. This will resend the packets that have just been labeled dead.
1290+The algorithm is a simple case of traversing the packet queue. Essentialy, we
1291+mark as dead all packets in the queue between `fip` and `(dec lap)`. We also
1292+update `nif`, the number of live packets. Lest you mourn too much the passing of
1293+these packets, know that they shall soon rise again. Recall that in `++bick`
1294+after the call to `++bock` we call `++harv`. This will resend the packets that
1295+have just been labeled dead.
13551296
13561297 ++ beet :: beet:pu
13571298 ^+ . :: advance unacked
@@ -1363,10 +1304,9 @@ rise again. Recall that in `++bick` after the call to `++bock` we call
13631304 =+ rig=$(puq r.puq)
13641305 ?^(rig rig [~ p.n.puq])
13651306
1366−Here we search for the next expected packet number. Basically, we search
1367−the queue for the leftmost packet whose number is greater than the
1368−current `nep`. If we don't find any such packet, we just use the total
1369−number of packets sent.
1307+Here we search for the next expected packet number. Basically, we search the
1308+queue for the leftmost packet whose number is greater than the current `nep`. If
1309+we don't find any such packet, we just use the total number of packets sent.
13701310
13711311We can now dive into `++bock`, our last arm.
13721312
@@ -1387,32 +1327,29 @@ We can now dive into `++bock`, our last arm.
13871327 :: ~& [%bock-fill num nif caw cag]
13881328 +>.$
13891329
1390−First, we call `++bine` to apply the ack to the packet pump information.
1391−We produce `gym`, which, if it exists, is the id of the packet that was
1392−acked. If we received an ack for a packet later than the one we
1393−expected, then we halve the logical packet window and kill all the
1394−earlier packets so that they may be resent.
1330+First, we call `++bine` to apply the ack to the packet pump information. We
1331+produce `gym`, which, if it exists, is the id of the packet that was acked. If
1332+we received an ack for a packet later than the one we expected, then we halve
1333+the logical packet window and kill all the earlier packets so that they may be
1334+resent.
13951335
1396−Otherwise, we possibly increase the congestion window. If the window is
1397−less than the congestion threshold, then we increment the size of the
1398−window. Otherwise, we only increment one out of every `caw` times.
1336+Otherwise, we possibly increase the congestion window. If the window is less
1337+than the congestion threshold, then we increment the size of the window.
1338+Otherwise, we only increment one out of every `caw` times.
13991339
1400−If we received an ack for the packet we expected, then we simply advance
1401−`nep` with `++beet`. If we received an ack for a packet earlier than we
1402−expected, we do nothing.
1340+If we received an ack for the packet we expected, then we simply advance `nep`
1341+with `++beet`. If we received an ack for a packet earlier than we expected, we
1342+do nothing.
14031343
1404−It may be hard to believe, but we are, in fact, done. The message has
1405−been sent, received, acknowledged, and the acknowledgment has been
1406−returned to the original sender. We hope it's clear that, while the
1407−process has been somewhat involved, the algorithms are not all that
1408−complicated. If you've read this far, you know `%ames`. The only other
1409−code involves initialization, timeouts, and the like.
1344+It may be hard to believe, but we are, in fact, done. The message has been sent,
1345+received, acknowledged, and the acknowledgment has been returned to the original
1346+sender. We hope it's clear that, while the process has been somewhat involved,
1347+the algorithms are not all that complicated. If you've read this far, you know
1348+`%ames`. The only other code involves initialization, timeouts, and the like.
14101349
1411−Below, we give detailed reference documentation for the data models
1412−involved.
1350+Below, we give detailed reference documentation for the data models involved.
14131351
1414−Data Models
1415−-----------
1352+## Data Models
14161353
14171354### `++fort`, formal state
14181355
@@ -1424,28 +1361,27 @@ Data Models
14241361 zac=(map ship corn) :: flows by server
14251362 == ::
14261363
1427−This is the state of our vane. Anything that must be remembered between
1428−calls to ames must be stored in this state.
1364+This is the state of our vane. Anything that must be remembered between calls to
1365+ames must be stored in this state.
14291366
1430−`%0` is the version of the ames state model itself. If the data model
1431−`++fort` changes, then this number needs to be incremented, and an
1432−adapter must be written to upgrade the old state into the new state.
1433−Note that this is the version number of the model itself, not the
1434−contents. When the data changes, there is of course no need to change
1435−this.
1367+`%0` is the version of the ames state model itself. If the data model `++fort`
1368+changes, then this number needs to be incremented, and an adapter must be
1369+written to upgrade the old state into the new state. Note that this is the
1370+version number of the model itself, not the contents. When the data changes,
1371+there is of course no need to change this.
14361372
14371373`gad` is a `duct` over which we send `%send` cards to unix. This card is
1438−initialized when unix sends a `%barn` card as vere starts up. Vere
1439−treats this duct specially -- don't send anything weird over it.
1374+initialized when unix sends a `%barn` card as vere starts up. Vere treats this
1375+duct specially -- don't send anything weird over it.
14401376
1441−`hop` is the network boot date. This is set when the `%kick` card is
1442−sent by vere on start up.
1377+`hop` is the network boot date. This is set when the `%kick` card is sent by
1378+vere on start up.
14431379
1444−`ton` is a `++town`, where we store all of our security/encryption
1445−state. Note that this is shared across all ships on a pier.
1380+`ton` is a `++town`, where we store all of our security/encryption state. Note
1381+that this is shared across all ships on a pier.
14461382
1447−`zac` is a map of ships to `++corn`. This stores all the per-ship state.
1448−The keys to this map are the ships on the current pier.
1383+`zac` is a map of ships to `++corn`. This stores all the per-ship state. The
1384+keys to this map are the ships on the current pier.
14491385
14501386### `++town`, all security state
14511387
@@ -1460,20 +1396,17 @@ This is the security state of our pier.
14601396
14611397`lit` is unused.
14621398
1463−`any` is 256 bits of entropy. This entropy is used and updated in
1464−exactly two places: when we send a `%junk` card, and when we generate a
1465−new symmetric key in `++griz:lax:as:go`. When it is updated, it is
1466−updated by a SHA-256 hash of the current time and the old value of the
1467−entropy.
1399+`any` is 256 bits of entropy. This entropy is used and updated in exactly two
1400+places: when we send a `%junk` card, and when we generate a new symmetric key in
1401+`++griz:lax:as:go`. When it is updated, it is updated by a SHA-256 hash of the
1402+current time and the old value of the entropy.
14681403
1469−`urb` is a map of ships to `++sufi`. This is where we store all the
1470−per-ship state for the pier. The keys to this map are the ships on the
1471−current pier.
1404+`urb` is a map of ships to `++sufi`. This is where we store all the per-ship
1405+state for the pier. The keys to this map are the ships on the current pier.
14721406
1473−`fak` is true if we are on a fake network. This disables certain
1474−security checks so that anyone may run a fake `~zod`. This is used only
1475−for development. To use, run vere with the `-F` option (and the
1476−`-I ~zod` option for a fake `~zod`).
1407+`fak` is true if we are on a fake network. This disables certain security checks
1408+so that anyone may run a fake `~zod`. This is used only for development. To use,
1409+run vere with the `-F` option (and the `-I ~zod` option for a fake `~zod`).
14771410
14781411### `++sufi`, domestic host
14791412
@@ -1487,9 +1420,8 @@ for development. To use, run vere with the `-F` option (and the
14871420
14881421This is the security state of a domestic server.
14891422
1490−`hoy` is a list of the ships directly above us in the hierarchy of
1491−ships. For example, for `~hoclur-bicrel`, this would be `~tasruc` and
1492−`~tug`. See `++sein`.
1423+`hoy` is a list of the ships directly above us in the hierarchy of ships. For
1424+example, for `~hoclur-bicrel`, this would be `~tasruc` and `~tug`. See `++sein`.
14931425
14941426`val` is a list of our private keys.
14951427
@@ -1497,51 +1429,51 @@ ships. For example, for `~hoclur-bicrel`, this would be `~tasruc` and
14971429
14981430`seh`
14991431
1500−`hoc` is a map of ships to `++dore`. The stores all the security
1501−informatoin about foreign ships. The keys to this map are the neighbors
1502−(ships we have been in contact with) of this domestic server.
1432+`hoc` is a map of ships to `++dore`. The stores all the security informatoin
1433+about foreign ships. The keys to this map are the neighbors (ships we have been
1434+in contact with) of this domestic server.
15031435
15041436### `++wund`, private keys
15051437
15061438 ++ wund (list ,[p=life q=ring r=acru]) :: mace in action
15071439
1508−This is a list of our own private keys, indexed by life. The key itself
1509−is the `++ring`, and the `++acru` is the encryption engine. We generate
1510−the `++acru` from the private key by calling `++weur`. Thus, we can at
1511−any time regenerate our `++wund` from a `++mace`. The current crypto is
1512−at the head of the list and can be accessed with `++sen:as:go`.
1440+This is a list of our own private keys, indexed by life. The key itself is the
1441+`++ring`, and the `++acru` is the encryption engine. We generate the `++acru`
1442+from the private key by calling `++weur`. Thus, we can at any time regenerate
1443+our `++wund` from a `++mace`. The current crypto is at the head of the list and
1444+can be accessed with `++sen:as:go`.
15131445
15141446### `++ring`, private key
15151447
15161448 ++ ring ,@ :: private key
15171449
1518−This is a private key. The first byte is reserved to identify the type
1519−of cryptography. Lower-case means public key, upper-case means public
1520−key, and the letter identifies which `++acru` to use.
1450+This is a private key. The first byte is reserved to identify the type of
1451+cryptography. Lower-case means public key, upper-case means public key, and the
1452+letter identifies which `++acru` to use.
15211453
15221454### `++pass`, public key
15231455
15241456 ++ pass ,@ :: public key
15251457
15261458This is a public key. The first byte is reserved to identify the type of
1527−cryptography. Lower-case means public key, upper-case means public key,
1528−and the letter identifies which `++acru` to use.
1459+cryptography. Lower-case means public key, upper-case means public key, and the
1460+letter identifies which `++acru` to use.
15291461
15301462### `++mace`, private secrets
15311463
15321464 ++ mace (list ,[p=life q=ring]) :: private secrets
15331465
1534−This is a list of the our private keys, indexed by life. From this we
1535−can generate a `++wund` for actual use.
1466+This is a list of the our private keys, indexed by life. From this we can
1467+generate a `++wund` for actual use.
15361468
15371469### `++skin`, encoding stem
15381470
15391471 ++ skin ?(%none %open %fast %full) :: encoding stem
15401472
1541−This defines the type of encryption used for each message. `%none`
1542−refers to messages sent in the clear, `%open` refers to signed messages,
1543−`%full` refers to sealed messages, and `%fast` refers to symmetrically
1544−encrypted messages. See `++acru` for details.
1473+This defines the type of encryption used for each message. `%none` refers to
1474+messages sent in the clear, `%open` refers to signed messages, `%full` refers to
1475+sealed messages, and `%fast` refers to symmetrically encrypted messages. See
1476+`++acru` for details.
15451477
15461478### `++acru`, asymmetric cryptosuite
15471479
@@ -1570,11 +1502,11 @@ encrypted messages. See `++acru` for details.
15701502 --
15711503 --
15721504
1573−This is an opaque interface for a general asymmetric cryptosuite. Any
1574−form of asymmetric cryptography can be dropped in to be used instead of
1575−the default. Right now, there are two cryptosuites, `++crua`, which is
1576−your standard RSA, and `++crub`, which is elliptic curve crypto but is
1577−mostly stubbed out at the moment.
1505+This is an opaque interface for a general asymmetric cryptosuite. Any form of
1506+asymmetric cryptography can be dropped in to be used instead of the default.
1507+Right now, there are two cryptosuites, `++crua`, which is your standard RSA, and
1508+`++crub`, which is elliptic curve crypto but is mostly stubbed out at the
1509+moment.
15781510
15791511#### `++as:acru`, asymmetric operations
15801512
@@ -1586,31 +1518,28 @@ mostly stubbed out at the moment.
15861518 *(unit ,[p=@ q=@]) ::
15871519 -- ::
15881520
1589−This is the core that defines the standard asymmetric cryptography
1590−operations.
1591−
1592−`++seal:as:acru` allows us to send a message encrypted with someone's
1593−public key so that only they may read it. If Alice seals a message with
1594−Bob's public key, then she can be sure that Bob is the only one who can
1595−read it. This is associated with the `++skin` `%full`.
1596−
1597−`++sign:as:acru` allows us to sign a message with our private key so
1598−that others can verify that we sent the message. If Alice signs a
1599−message with her private key, then Bob can verify with her public key
1600−that it was indeed Alice who sent it. This is associated with the
1601−`++skin` `%open`.
1602−
1603−`++sure:as:acru` is the dual to `++sign:as:acru`. It allows us to verify
1604−that a message we have received is indeed from the claimed sender. If
1605−Alice sends a message with her private key, then Bob can use this arm to
1606−verify that it was indeed Alice who sent it. This is associated with the
1607−`++skin` `%open`.
1608−
1609−`++tear:as:acru` is the dual to `++seal:as:acru`. It allows us to read a
1610−message that we can be sure is only read by us. If Alice seals a message
1611−with Bob's public key, then Bob can use this arm to read it. This is
1521+This is the core that defines the standard asymmetric cryptography operations.
1522+
1523+`++seal:as:acru` allows us to send a message encrypted with someone's public key
1524+so that only they may read it. If Alice seals a message with Bob's public key,
1525+then she can be sure that Bob is the only one who can read it. This is
16121526associated with the `++skin` `%full`.
16131527
1528+`++sign:as:acru` allows us to sign a message with our private key so that others
1529+can verify that we sent the message. If Alice signs a message with her private
1530+key, then Bob can verify with her public key that it was indeed Alice who sent
1531+it. This is associated with the `++skin` `%open`.
1532+
1533+`++sure:as:acru` is the dual to `++sign:as:acru`. It allows us to verify that a
1534+message we have received is indeed from the claimed sender. If Alice sends a
1535+message with her private key, then Bob can use this arm to verify that it was
1536+indeed Alice who sent it. This is associated with the `++skin` `%open`.
1537+
1538+`++tear:as:acru` is the dual to `++seal:as:acru`. It allows us to read a message
1539+that we can be sure is only read by us. If Alice seals a message with Bob's
1540+public key, then Bob can use this arm to read it. This is associated with the
1541+`++skin` `%full`.
1542+
16141543#### `++de:acru`, `++dy:acru`, and `++en:acru`, symmetric encryption/decryption
16151544
16161545 ++ de |+([a=@ b=@] *(unit ,@)) :: symmetric de, soft
@@ -1619,12 +1548,12 @@ associated with the `++skin` `%full`.
16191548
16201549Symmetric encryption is associated with the `++skin` `%fast`.
16211550
1622−`++de:acru` decrypts a message with a symmetric key, returning `~` on
1623−failure and `[~ u=data]` on success.
1551+`++de:acru` decrypts a message with a symmetric key, returning `~` on failure
1552+and `[~ u=data]` on success.
16241553
1625−`++dy:acru` decrypts a message with a symmetric key, crashing on
1626−failure. This should almost always be defined as, and should always be
1627−semantically equivalent to, `(need (de a b))`.
1554+`++dy:acru` decrypts a message with a symmetric key, crashing on failure. This
1555+should almost always be defined as, and should always be semantically equivalent
1556+to, `(need (de a b))`.
16281557
16291558`++en:acru` encrypts a message with a symmetric key.
16301559
@@ -1637,10 +1566,9 @@ semantically equivalent to, `(need (de a b))`.
16371566 ++ sec *ring :: private key
16381567 --
16391568
1640−`++fig:ex:acru` is our fingerprint, usually a hash of our public key.
1641−This is used, for example, in `++zeno`, where every carrier owner's
1642−fingerprint is stored so that we can ensure that carriers are indeed
1643−owned by their owners
1569+`++fig:ex:acru` is our fingerprint, usually a hash of our public key. This is
1570+used, for example, in `++zeno`, where every carrier owner's fingerprint is
1571+stored so that we can ensure that carriers are indeed owned by their owners
16441572
16451573`++pac:ex:acru` is our default passcode, which is unused at present.
16461574
@@ -1658,51 +1586,45 @@ owned by their owners
16581586
16591587These arms allow us to reconstruct a `++acru` from basic data.
16601588
1661−`++pit:nu:acru` constructs a `++acru` from the width of our intended key
1662−and seed entropy. This is usually used in the initial construction of
1663−the `++acru`.
1589+`++pit:nu:acru` constructs a `++acru` from the width of our intended key and
1590+seed entropy. This is usually used in the initial construction of the `++acru`.
16641591
1665−`++nol:nu:acru` constructs a `++acru` from a "naked ring", meaning a
1666−`++ring` without the initial byte identifying the type of crypto. There
1667−is often a helper arm that that wraps this; see `++weur` for `++crua`
1668−and `++wear` for `++crub`.
1592+`++nol:nu:acru` constructs a `++acru` from a "naked ring", meaning a `++ring`
1593+without the initial byte identifying the type of crypto. There is often a helper
1594+arm that that wraps this; see `++weur` for `++crua` and `++wear` for `++crub`.
16691595
1670−`++com:nu:acru` constructs a `++acru` from a "naked pass", meaning a
1671−`++ring` without the initial byte identifying the type of crypto. There
1672−is often a helper arm that that wraps this; see `++haul` for `++crua`
1673−and `++hail` for `++crub`.
1596+`++com:nu:acru` constructs a `++acru` from a "naked pass", meaning a `++ring`
1597+without the initial byte identifying the type of crypto. There is often a helper
1598+arm that that wraps this; see `++haul` for `++crua` and `++hail` for `++crub`.
16741599
16751600### `++will`, certificate
16761601
16771602 ++ will (list deed) :: certificate
16781603
1679−This is a list of deeds associated with the current ship. There should
1680−be an item in this list for every ship from this point up in the
1681−hierarchy times the number of lives that each ship has had. For example,
1682−\~hoclur-bicrel may have a will with three items: one for itself, one
1683−for \~tasruc (who issued \~hoclur-bicrel's deed) and one for \~tug (who
1684−issued \~tasruc's deed).
1604+This is a list of deeds associated with the current ship. There should be an
1605+item in this list for every ship from this point up in the hierarchy times the
1606+number of lives that each ship has had. For example, ~hoclur-bicrel may have a
1607+will with three items: one for itself, one for ~tasruc (who issued
1608+~hoclur-bicrel's deed) and one for ~tug (who issued ~tasruc's deed).
16851609
16861610### `++deed`, identity
16871611
16881612 ++ deed ,[p=@ q=step r=?] :: sig, stage, fake?
16891613
1690−`p` is the signature of a particular deed, which is a signed copy of
1691−`q`.
1614+`p` is the signature of a particular deed, which is a signed copy of `q`.
16921615
16931616`q` is the stage in the identity.
16941617
1695−`r` is true if we're working on a fake network, where we don't check
1696−that the carrier fingerprints are correct. This allows us to create fake
1697−networks for development without interfering with the real network.
1618+`r` is true if we're working on a fake network, where we don't check that the
1619+carrier fingerprints are correct. This allows us to create fake networks for
1620+development without interfering with the real network.
16981621
16991622### `++step`, identity stage
17001623
17011624 ++ step ,[p=bray q=gens r=pass] :: identity stage
17021625
1703−This is a single stage in our identity. Thus, this is specific to a
1704−single life in a single ship. Everything in here may change between
1705−lives.
1626+This is a single stage in our identity. Thus, this is specific to a single life
1627+in a single ship. Everything in here may change between lives.
17061628
17071629`p`
17081630
@@ -1720,9 +1642,9 @@ XXX
17201642
17211643 ++ gens ,[p=lang q=gcos] :: general identity
17221644
1723−`p` is the IETF language code for the preferred language of this
1724−identity. This is unused at the moment, but in the future text should be
1725−localized based on this.
1645+`p` is the IETF language code for the preferred language of this identity. This
1646+is unused at the moment, but in the future text should be localized based on
1647+this.
17261648
17271649`q` is the description of the ship.
17281650
@@ -1736,32 +1658,31 @@ localized based on this.
17361658 [%pawn p=(unit ,@t)] :: 128-bit ship
17371659 == ::
17381660
1739−This is the description of the identity of a ship. Most types of
1740−identity have a `@t` field, which is their human-readable name. The
1741−identity of a `%duke` is more involved.
1661+This is the description of the identity of a ship. Most types of identity have a
1662+`@t` field, which is their human-readable name. The identity of a `%duke` is
1663+more involved.
17421664
1743−A `%czar`, a carrier, is a ship with an 8-bit address. Thus, there are
1744−only 256 carriers. These are at the top of the namespace hierarchy, and
1745−the fingerprint of each carrier is stored in `++zeno`. These are the
1746−"senators" of Urbit.
1665+A `%czar`, a carrier, is a ship with an 8-bit address. Thus, there are only 256
1666+carriers. These are at the top of the namespace hierarchy, and the fingerprint
1667+of each carrier is stored in `++zeno`. These are the "senators" of Urbit.
17471668
1748−A `%king`, a cruiser, is a ship with a 16-bit address. Thus, there are
1749−65,536 cruisers. Each carrier may issue 256 cruisers. These are the
1750−infrastructure of Urbit.
1669+A `%king`, a cruiser, is a ship with a 16-bit address. Thus, there are 65,536
1670+cruisers. Each carrier may issue 256 cruisers. These are the infrastructure of
1671+Urbit.
17511672
17521673A `%duke`, a destroyer, is a ship with a 32-bit address. Thus, there are
1753−4,294,967,296 destroyers. Each cruiser may issue 65,536 cruisers. These
1754−are the individuals of Urbit.
1674+4,294,967,296 destroyers. Each cruiser may issue 65,536 cruisers. These are the
1675+individuals of Urbit.
17551676
17561677A `%earl`, a yacht, is a ship with a 64-bit address. Thus, there are
1757−18,446,744,073,709,551,616 yachts. Each destroyer may issue
1758−4,294,967,296 yachts. These are the devices of Urbit.
1678+18,446,744,073,709,551,616 yachts. Each destroyer may issue 4,294,967,296
1679+yachts. These are the devices of Urbit.
17591680
1760−A `%pawn`, a submarine, is a ship with a 128-bit address. Thus, there
1761−are a lot of submarines. The chance of random name collision is
1762−negligible, so submarines are not issued by any ship. They must simply
1763−assert their presence, and they are all considered children of \~zod.
1764−This is the underworld of Urbit, where anonymity reigns supreme.
1681+A `%pawn`, a submarine, is a ship with a 128-bit address. Thus, there are a lot
1682+of submarines. The chance of random name collision is negligible, so submarines
1683+are not issued by any ship. They must simply assert their presence, and they are
1684+all considered children of ~zod. This is the underworld of Urbit, where
1685+anonymity reigns supreme.
17651686
17661687### `++what`, logical destroyer identity
17671688
@@ -1774,10 +1695,10 @@ This is the underworld of Urbit, where anonymity reigns supreme.
17741695
17751696This is the logical identity of a destroyer.
17761697
1777−A `%anon` is a completely anonymous destroyer. The difference between
1778−this and a submarine is that a submarine is ephemeral while a `%anon`
1779−destroyer is not. Thus, we may not know who \~hoclur-bicrel is, but we
1780−do know that it's always the same person.
1698+A `%anon` is a completely anonymous destroyer. The difference between this and a
1699+submarine is that a submarine is ephemeral while a `%anon` destroyer is not.
1700+Thus, we may not know who ~hoclur-bicrel is, but we do know that it's always the
1701+same person.
17811702
17821703A `%lady` is a female person. The name used here should be a real name.
17831704
@@ -1789,8 +1710,8 @@ A `%punk` is a person who is identified only by a handle.
17891710
17901711 ++ whom ,[p=@ud q=govt r=sect s=name] :: year/govt/id
17911712
1792−Ths is the information associated with a real person. It is mostly
1793−information that could be observed with the briefest of interactions.
1713+Ths is the information associated with a real person. It is mostly information
1714+that could be observed with the briefest of interactions.
17941715
17951716`p` is the birth year.
17961717
@@ -1816,5 +1737,5 @@ XXX
18161737
18171738 ++ name ,[p=@t q=(unit ,@t) r=(unit ,@t) s=@t] :: first mid/nick last
18181739
1819−This is the given name, possible middle name/initial, possible nickname,
1820−and surname of a user.
1740+This is the given name, possible middle name/initial, possible nickname, and
1741+surname of a user.
docs/arvo/internals/behn.md+12−14
@@ -1,22 +1,20 @@
11---
2−navhome: /docs/
2+navhome: '/docs/'
33sort: 2
44---
55
6−`%behn`
7−=======
6+# `%behn`
87
98Our simple timer.
109
11−It allows vanes and applications to set and timer events, which are
12−managed in a simple priority queue. `%behn` produces effects to start
13−the unix timer, and when the requested `%behn` passes, unix sends wake
14−events to `%behn`, which time routes back to original sender. We don't
15−guarantee that a timer event will happen at exactly the `%behn` it was
16−set for, or even that it'll be particularly close. A timer event is a
17−request to not be woken until after the given time.
10+It allows vanes and applications to set and timer events, which are managed in a
11+simple priority queue. `%behn` produces effects to start the unix timer, and
12+when the requested `%behn` passes, unix sends wake events to `%behn`, which time
13+routes back to original sender. We don't guarantee that a timer event will
14+happen at exactly the `%behn` it was set for, or even that it'll be particularly
15+close. A timer event is a request to not be woken until after the given time.
1816
19−`%eyre` uses `%behn` for timing out sessions, and `%clay` uses `%behn`
20−for keeping track of time-specified file requests. `%ames` should
21−probably use `%behn` to keep track of things like network timeouts and
22−retry timing, but it currently uses its own alarm system.
17+`%eyre` uses `%behn` for timing out sessions, and `%clay` uses `%behn` for
18+keeping track of time-specified file requests. `%ames` should probably use
19+`%behn` to keep track of things like network timeouts and retry timing, but it
20+currently uses its own alarm system.
docs/arvo/internals/clay.md+13−16
@@ -1,26 +1,23 @@
11---
2−navhome: /docs/
2+navhome: '/docs/'
33sort: 3
44---
55
6−`%clay`
7−=======
6+# `%clay`
87
98Our filesystem.
109
11−`%clay` is version-controlled, referentially-transparent, and global.
12−While this filesystem is stored in `%clay`, it is mirrored to Unix for
13−convenience. Unix tells `%clay`s whenever a file changes in the Unix
14−copy of the filesystem so that the change may be applied. `%clay` tells
15−unix whenever an app or vane changes the filesystem so that the change
16−can be effected in Unix. Apps and vanes may use `%clay` to write to the
17−filesystem, query it, and subscribe to changes in it. Ford and gall use
18−`%clay` to serve up apps and web pages.
10+`%clay` is version-controlled, referentially-transparent, and global. While this
11+filesystem is stored in `%clay`, it is mirrored to Unix for convenience. Unix
12+tells `%clay`s whenever a file changes in the Unix copy of the filesystem so
13+that the change may be applied. `%clay` tells unix whenever an app or vane
14+changes the filesystem so that the change can be effected in Unix. Apps and
15+vanes may use `%clay` to write to the filesystem, query it, and subscribe to
16+changes in it. Ford and gall use `%clay` to serve up apps and web pages.
1917
20−`%clay` includes three components. First is the filesystem/version
21−control algorithms, which are mostly defined in `++ze` and `++zu` in
22−zuse. Second is the write, query, and subscription logic. Finally, there
23−is the logic for communicating requests to, and receiving requests from,
24−foreign ships.
18+`%clay` includes three components. First is the filesystem/version control
19+algorithms, which are mostly defined in `++ze` and `++zu` in zuse. Second is the
20+write, query, and subscription logic. Finally, there is the logic for
21+communicating requests to, and receiving requests from, foreign ships.
2522
2623<list></list>
docs/arvo/internals/clay/architecture.md+295−349
@@ -1,201 +1,176 @@
11---
2−navhome: /docs/
2+navhome: '/docs/'
33---
44
5−
65# clay
76
87## high-level
98
10−clay is the primary filesystem for the arvo operating system,
11−which is the core of an urbit. The architecture of clay is
12−intrinsically connected with arvo, but we assume no knowledge of
13−either arvo or urbit. We will point out only those features of
14−arvo that are necessary for an understanding of clay, and we will
15−do so only when they arise.
16−
17−The first relevant feature of arvo is that it is a deterministic
18−system where input and output are defined as a series of events
19−and effects. The state of arvo is simply a function of its event
20−log. None of the effects from an event are emitted until the
21−event is entered in the log and persisted, either to disk or
22−another trusted source of persistence, such as a Kafka cluster.
23−Consequently, arvo is a single-level store: everything in its
24−state is persistent.
25−
26−In a more traditional OS, everything in RAM can be erased at any
27−time by power failure, and is always erased on reboot. Thus, a
28−primary purpose of a filesystem is to ensure files persist across
29−power failures and reboots. In arvo, both power failures and
30−reboots are special cases of suspending computation, which is
31−done safely since our event log is already persistent. Therefore,
32−clay is not needed in arvo for persistence. Why, then, do we have a
33−filesystem? There are two answers to this question.
34−
35−First, clay provides a filesystem tree, which is a convenient
36−user interface for some applications. Unix has the useful concept
37−of virtual filesystems, which are used for everything from direct
38−access to devices, to random number generators, to the /proc
39−tree. It is easy and intuitive to read from and write to a
9+clay is the primary filesystem for the arvo operating system, which is the core
10+of an urbit. The architecture of clay is intrinsically connected with arvo, but
11+we assume no knowledge of either arvo or urbit. We will point out only those
12+features of arvo that are necessary for an understanding of clay, and we will do
13+so only when they arise.
14+
15+The first relevant feature of arvo is that it is a deterministic system where
16+input and output are defined as a series of events and effects. The state of
17+arvo is simply a function of its event log. None of the effects from an event
18+are emitted until the event is entered in the log and persisted, either to disk
19+or another trusted source of persistence, such as a Kafka cluster. Consequently,
20+arvo is a single-level store: everything in its state is persistent.
21+
22+In a more traditional OS, everything in RAM can be erased at any time by power
23+failure, and is always erased on reboot. Thus, a primary purpose of a filesystem
24+is to ensure files persist across power failures and reboots. In arvo, both
25+power failures and reboots are special cases of suspending computation, which is
26+done safely since our event log is already persistent. Therefore, clay is not
27+needed in arvo for persistence. Why, then, do we have a filesystem? There are
28+two answers to this question.
29+
30+First, clay provides a filesystem tree, which is a convenient user interface for
31+some applications. Unix has the useful concept of virtual filesystems, which are
32+used for everything from direct access to devices, to random number generators,
33+to the /proc tree. It is easy and intuitive to read from and write to a
4034filesystem tree.
4135
42−Second, clay has a distributed revision control system baked into
43−it. Traditional filesystems are not revision controlled, so
44−userspace software -- such as git -- is written on top of them to
45−do so. clay natively provides the same functionality as modern
46−DVCSes, and more.
36+Second, clay has a distributed revision control system baked into it.
37+Traditional filesystems are not revision controlled, so userspace software --
38+such as git -- is written on top of them to do so. clay natively provides the
39+same functionality as modern DVCSes, and more.
4740
48−clay has two other unique properties that we'll cover later on:
49−it supports typed data and is referentially transparent.
41+clay has two other unique properties that we'll cover later on: it supports
42+typed data and is referentially transparent.
5043
5144### Revision Control
5245
53−Every urbit has one or more "desks", which are independently
54−revision-controlled branches. Each desk contains its own mark
55−definitions, apps, doc, and so forth.
56−
57−Traditionally, an urbit has at least a base and a home desk. The
58−base desk has all the system software from the distribution. the
59−home desk is a fork of base with all the stuff specific to the
60−user of the urbit.
61−
62−A desk is a series of numbered commits, the most recent of which
63−represents the current state of the desk. A commit is composed of
64−(1) an absolute time when it was created, (2) a list of zero or
65−more parents, and (3) a map from paths to data.
66−
67−Most commits have exactly one parent, but the initial commit on a
68−desk may have zero parents, and merge commits have more than one
69−parent.
70−
71−The non-meta data is stored in the map of paths to data. It's
72−worth noting that no constraints are put on this map, so, for
73−example, both /a/b and /a/b/c could have data. This is impossible
74−in a traditional Unix filesystem since it means that /a/b is both
75−a file and a directory. Conventionally, the final element in the
76−path is its mark -- much like a filename extension in Unix. Thus,
46+Every urbit has one or more "desks", which are independently revision-controlled
47+branches. Each desk contains its own mark definitions, apps, doc, and so forth.
48+
49+Traditionally, an urbit has at least a base and a home desk. The base desk has
50+all the system software from the distribution. the home desk is a fork of base
51+with all the stuff specific to the user of the urbit.
52+
53+A desk is a series of numbered commits, the most recent of which represents the
54+current state of the desk. A commit is composed of (1) an absolute time when it
55+was created, (2) a list of zero or more parents, and (3) a map from paths to
56+data.
57+
58+Most commits have exactly one parent, but the initial commit on a desk may have
59+zero parents, and merge commits have more than one parent.
60+
61+The non-meta data is stored in the map of paths to data. It's worth noting that
62+no constraints are put on this map, so, for example, both /a/b and /a/b/c could
63+have data. This is impossible in a traditional Unix filesystem since it means
64+that /a/b is both a file and a directory. Conventionally, the final element in
65+the path is its mark -- much like a filename extension in Unix. Thus,
7766/doc/readme.md in Unix is stored as /doc/readme/md in urbit.
7867
79−The data is not stored directly in the map; rather, a hash of the
80−data is stored, and we maintain a master blob store. Thus, if the
81−same data is referred to in multiple commits (as, for example,
82−when a file doesn't change between commits), only the hash is
83−duplicated.
84−
85−In the master blob store, we either store the data directly, or
86−else we store a diff against another blob. The hash is dependent
87−only on the data within and not on whether or not it's stored
88−directly, so we may on occasion rearrange the contents of the
89−blob store for performance reasons.
90−
91−Recall that a desk is a series of numbered commits. Not every
92−commit in a desk must be numbered. For example, if the base desk
93−has had 50 commits since home was forked from it, then a merge
94−from base to home will only add a single revision number to home,
95−although the full commit history will be accessible by traversing
96−the parentage of the individual commits.
97−
98−We do guarantee that the first commit is numbered 1, commits are
99−numbered consecutively after that (i.e. there are no "holes"),
100−the topmost commit is always numbered, and every numbered commit
101−is an ancestor of every later numbered commit.
102−
103−There are three ways to refer to particular commits in the
104−revision history. Firstly, one can use the revision number.
105−Secondly, one can use any absolute time between the one numbered
106−commit and the next (inclusive of the first, exclusive of the
107−second). Thirdly, every desk has a map of labels to revision
68+The data is not stored directly in the map; rather, a hash of the data is
69+stored, and we maintain a master blob store. Thus, if the same data is referred
70+to in multiple commits (as, for example, when a file doesn't change between
71+commits), only the hash is duplicated.
72+
73+In the master blob store, we either store the data directly, or else we store a
74+diff against another blob. The hash is dependent only on the data within and not
75+on whether or not it's stored directly, so we may on occasion rearrange the
76+contents of the blob store for performance reasons.
77+
78+Recall that a desk is a series of numbered commits. Not every commit in a desk
79+must be numbered. For example, if the base desk has had 50 commits since home
80+was forked from it, then a merge from base to home will only add a single
81+revision number to home, although the full commit history will be accessible by
82+traversing the parentage of the individual commits.
83+
84+We do guarantee that the first commit is numbered 1, commits are numbered
85+consecutively after that (i.e. there are no "holes"), the topmost commit is
86+always numbered, and every numbered commit is an ancestor of every later
87+numbered commit.
88+
89+There are three ways to refer to particular commits in the revision history.
90+Firstly, one can use the revision number. Secondly, one can use any absolute
91+time between the one numbered commit and the next (inclusive of the first,
92+exclusive of the second). Thirdly, every desk has a map of labels to revision
10893numbers. These labels may be used to refer to specific commits.
10994
110−Additionally, clay is a global filesystem, so data on other urbit
111−is easily accessible the same way as data on our local urbit. In
112−general, the path to a particular revision of a desk is
113−/~urbit-name/desk-name/revision. Thus, to get /try/readme/md
114−from revision 5 of the home desk on ~sampel-sipnym, we refer to
115−/~sampel-sipnym/home/5/try/readme/md. Clay's namespace is thus
116−global and referentially transparent.
95+Additionally, clay is a global filesystem, so data on other urbit is easily
96+accessible the same way as data on our local urbit. In general, the path to a
97+particular revision of a desk is /~urbit-name/desk-name/revision. Thus, to get
98+/try/readme/md from revision 5 of the home desk on ~sampel-sipnym, we refer to
99+/~sampel-sipnym/home/5/try/readme/md. Clay's namespace is thus global and
100+referentially transparent.
117101
118102XXX reactivity here?
119103
120104### A Typed Filesystem
121105
122−Since clay is a general filesystem for storing data of arbitrary
123−types, in order to revision control correctly it needs to be
124−aware of types all the way through. Traditional revision control
125−does an excellent job of handling source code, so for source code
126−we act very similar to traditional revision control. The
106+Since clay is a general filesystem for storing data of arbitrary types, in order
107+to revision control correctly it needs to be aware of types all the way through.
108+Traditional revision control does an excellent job of handling source code, so
109+for source code we act very similar to traditional revision control. The
127110challenge is to handle other data similarly well.
128111
129−For example, modern VCSs generally support "binary files", which
130−are files for which the standard textual diffing, patching, and
131−merging algorithms are not helpful. A "diff" of two binary files
132−is just a pair of the files, "patching" this diff is just
133−replacing the old file with the new one, and "merging"
134−non-identical diffs is always a conflict, which can't even be
135−helpfully annotated. Without knowing anything about the structure
136−of a blob of data, this is the best we can do.
137−
138−Often, though, "binary" files have some internal structure, and
139−it is possible to create diff, patch, and merge algorithms that
140−take advantage of this structure. An image may be the result of a
141−base image with some set of operations applied. With algorithms
142−aware of this set of operations, not only can revision control
143−software save space by not having to save every revision of the
144−image individually, these transformations can be made on parallel
145−branches and merged at will.
146−
147−Suppose Alice is tasked with touching up a picture, improving the
148−color balance, adjusting the contrast, and so forth, while Bob
149−has the job of cropping the picture to fit where it's needed and
150−adding textual overlay. Without type-aware revision control,
151−these changes must be made serially, requiring Alice and Bob to
152−explicitly coordinate their efforts. With type-aware revision
153−control, these operations may be performed in parallel, and then
154−the two changesets can be merged programmatically.
155−
156−Of course, even some kinds of text files may be better served by
157−diff, patch, and merge algorithms aware of the structure of the
158−files. Consider a file containing a pretty-printed JSON object.
159−Small changes in the JSON object may result in rather significant
160−changes in how the object is pretty-printed (for example, by
161−addding an indentation level, splitting a single line into
162−multiple lines).
163−
164−A text file wrapped at 80 columns also reacts suboptimally with
165−unadorned Hunt-McIlroy diffs. A single word inserted in a
166−paragraph may push the final word or two of the line onto the
167−next line, and the entire rest of the paragraph may be flagged as
168−a change. Two diffs consisting of a single added word to
169−different sentences may be flagged as a conflict. In general,
170−prose should be diffed by sentence, not by line.
171−
172−As far as the author is aware, clay is the first generalized,
173−type-aware revision control system. We'll go into the workings
174−of this system in some detail.
112+For example, modern VCSs generally support "binary files", which are files for
113+which the standard textual diffing, patching, and merging algorithms are not
114+helpful. A "diff" of two binary files is just a pair of the files, "patching"
115+this diff is just replacing the old file with the new one, and "merging"
116+non-identical diffs is always a conflict, which can't even be helpfully
117+annotated. Without knowing anything about the structure of a blob of data, this
118+is the best we can do.
119+
120+Often, though, "binary" files have some internal structure, and it is possible
121+to create diff, patch, and merge algorithms that take advantage of this
122+structure. An image may be the result of a base image with some set of
123+operations applied. With algorithms aware of this set of operations, not only
124+can revision control software save space by not having to save every revision of
125+the image individually, these transformations can be made on parallel branches
126+and merged at will.
127+
128+Suppose Alice is tasked with touching up a picture, improving the color balance,
129+adjusting the contrast, and so forth, while Bob has the job of cropping the
130+picture to fit where it's needed and adding textual overlay. Without type-aware
131+revision control, these changes must be made serially, requiring Alice and Bob
132+to explicitly coordinate their efforts. With type-aware revision control, these
133+operations may be performed in parallel, and then the two changesets can be
134+merged programmatically.
135+
136+Of course, even some kinds of text files may be better served by diff, patch,
137+and merge algorithms aware of the structure of the files. Consider a file
138+containing a pretty-printed JSON object. Small changes in the JSON object may
139+result in rather significant changes in how the object is pretty-printed (for
140+example, by addding an indentation level, splitting a single line into multiple
141+lines).
142+
143+A text file wrapped at 80 columns also reacts suboptimally with unadorned
144+Hunt-McIlroy diffs. A single word inserted in a paragraph may push the final
145+word or two of the line onto the next line, and the entire rest of the paragraph
146+may be flagged as a change. Two diffs consisting of a single added word to
147+different sentences may be flagged as a conflict. In general, prose should be
148+diffed by sentence, not by line.
149+
150+As far as the author is aware, clay is the first generalized, type-aware
151+revision control system. We'll go into the workings of this system in some
152+detail.
175153
176154### Marks
177155
178−Central to a typed filesystem is the idea of types. In clay, we
179−call these "marks". A mark is a file that defines a type,
180−conversion routines to and from the mark, and diff, patch, and
181−merge routines.
156+Central to a typed filesystem is the idea of types. In clay, we call these
157+"marks". A mark is a file that defines a type, conversion routines to and from
158+the mark, and diff, patch, and merge routines.
182159
183−For example, a `%txt` mark may be a list of lines of text, and it
184−may include conversions to `%mime` to allow it to be serialized
185−and sent to a browswer or to the unix filesystem. It will also
186−include Hunt-McIlroy diff, patch, and merge algorithms.
160+For example, a `%txt` mark may be a list of lines of text, and it may include
161+conversions to `%mime` to allow it to be serialized and sent to a browswer or to
162+the unix filesystem. It will also include Hunt-McIlroy diff, patch, and merge
163+algorithms.
187164
188−A `%json` mark would be defined as a json object in the code, and
189−it would have a parser to convert from `%txt` and a printer to
190−convert back to `%txt`. The diff, patch, and merge algorithms are
191−fairly straightforward for json, though they're very different
192−from the text ones.
165+A `%json` mark would be defined as a json object in the code, and it would have
166+a parser to convert from `%txt` and a printer to convert back to `%txt`. The
167+diff, patch, and merge algorithms are fairly straightforward for json, though
168+they're very different from the text ones.
193169
194−More formally, a mark is a core with three arms, `++grab`,
195−`++grow`, and `++grad`. In `++grab` is a series of functions to
196−convert from other marks to the given mark. In `++grow` is a
197−series of functions to convert from the given mark to other
198−marks. In `++grad` is `++diff`, `++pact`, `++join`, and `++mash`.
170+More formally, a mark is a core with three arms, `++grab`, `++grow`, and
171+`++grad`. In `++grab` is a series of functions to convert from other marks to
172+the given mark. In `++grow` is a series of functions to convert from the given
173+mark to other marks. In `++grad` is `++diff`, `++pact`, `++join`, and `++mash`.
199174
200175The types are as follows, in an informal pseudocode:
201176
@@ -213,208 +188,179 @@ The types are as follows, in an informal pseudocode:
213188 ++ join: (<diff-type>, <diff-type>) -> <diff-type> or NULL
214189 ++ mash: (<diff-type>, <diff-type>) -> <diff-type>
215190
216−These types are basically what you would expect. Not every mark
217−has each of these functions defined -- all of them are optional
218−in the general case.
191+These types are basically what you would expect. Not every mark has each of
192+these functions defined -- all of them are optional in the general case.
219193
220−In general, for a particular mark, the `++grab` and `++grow` entries
221−(if they exist) should be inverses of each other.
194+In general, for a particular mark, the `++grab` and `++grow` entries (if they
195+exist) should be inverses of each other.
222196
223−In `++grad`, `++diff` takes two instances of a mark and produces
224−a diff of them. `++pact` takes an instance of a mark and patches
225−it with the given diff. `++join` takes two diffs and attempts to
226−merge them into a single diff. If there are conflicts, it
227−produces null. `++mash` takes two diffs and forces a merge,
197+In `++grad`, `++diff` takes two instances of a mark and produces a diff of them.
198+`++pact` takes an instance of a mark and patches it with the given diff.
199+`++join` takes two diffs and attempts to merge them into a single diff. If there
200+are conflicts, it produces null. `++mash` takes two diffs and forces a merge,
228201annotating any conflicts.
229202
230−In general, if `++diff` called with A and B produces diff D, then
231−`++pact` called with A and D should produce B. Also, if `++join`
232−of two diffs does not produce null, then `++mash` of the same
233−diffs should produce the same result.
203+In general, if `++diff` called with A and B produces diff D, then `++pact`
204+called with A and D should produce B. Also, if `++join` of two diffs does not
205+produce null, then `++mash` of the same diffs should produce the same result.
234206
235−Alternately, instead of `++diff`, `++pact`, `++join`, and
236−`++mash`, a mark can provide the same functionality by defining
237−`++sted` to be the name of another mark to which we wish to
238−delegate the revision control responsibilities. Then, before
239−running any of those functions, clay will convert to the other
240−mark, and convert back afterward. For example, the `%hoon` mark
241−is revision-controlled in the same way as `%txt`, so its `++grad`
242−is simply `++sted %txt`. Of course, `++txt` must be defined in
243−`++grow` and `++grab` as well.
207+Alternately, instead of `++diff`, `++pact`, `++join`, and `++mash`, a mark can
208+provide the same functionality by defining `++sted` to be the name of another
209+mark to which we wish to delegate the revision control responsibilities. Then,
210+before running any of those functions, clay will convert to the other mark, and
211+convert back afterward. For example, the `%hoon` mark is revision-controlled in
212+the same way as `%txt`, so its `++grad` is simply `++sted %txt`. Of course,
213+`++txt` must be defined in `++grow` and `++grab` as well.
244214
245−Every file in clay has a mark, and that mark must have a
246−fully-functioning `++grad`. Marks are used for more than just
247−clay, and other marks don't need a `++grad`, but if a piece of
248−data is to be saved to clay, we must know how to revision-control
249−it.
215+Every file in clay has a mark, and that mark must have a fully-functioning
216+`++grad`. Marks are used for more than just clay, and other marks don't need a
217+`++grad`, but if a piece of data is to be saved to clay, we must know how to
218+revision-control it.
250219
251−Additionally, if a file is to be synced out to unix, then it must
252−have conversion routines to and from the `%mime` mark.
220+Additionally, if a file is to be synced out to unix, then it must have
221+conversion routines to and from the `%mime` mark.
253222
254−##Using clay
223+## Using clay
255224
256225### Reading and Subscribing
257226
258−When reading from Clay, there are three types of requests. A
259−`%sing` request asks for data at single revsion. A `%next`
260−request asks to be notified the next time there's a change to
261−given file. A `%many` request asks to be notified on every
262−change in a desk for a range of changes.
263−
264−For `%sing` and `%next`, there are generally three things to be
265−queried. A `%u` request simply checks for the existence of a
266−file at a path. A `%x` request gets the data in the file at a
267−path. A `%y` request gets a hash of the data in the file at the
268−path combined with all its children and their data. Thus, `%y`
269−of a node changes if it or any of its children change.
270−
271−A `%sing` request is fulfilled immediately if possible. If the
272−requested revision is in the future, or is on another ship for
273−which we don't have the result cached, we don't respond
274−immediately. If the requested revision is in the future, we wait
275−until the revision happens before we respond to the request. If
276−the request is for data on another ship, we pass on the request
277−to the other ship. In general, Clay subscriptions, like most
278−things in Urbit, aren't guaranteed to return immediately.
279−They'll return when they can, and they'll do so in a
280−referentially transparent manner.
281−
282−A `%next` request checks query at the given revision, and it
283−produces the result of the query the next time it changes, along
284−with the revsion number when it changes. Thus, a `%next` of a
285−`%u` is triggered when a file is added or deleted, a `%next` of a
286−`%x` is triggered when a file is added, deleted, or changed, and
287−a `%next` of a `%y` is triggered when a file or any of its
288−children is added, deleted, or changed.
289−
290−A `%many` request is triggered every time the given desk has a
291−new revision. Unlike a `%next`, a `%many` has both a start and
292−an end revsion, after which it stops returning. For `%next`, a
293−single change is reported, and if the caller wishes to hear of
294−the next change, it must resubscribe. For `%many`, every revsion
295−from the start to the end triggers a response. Since a `%many`
296−request doesn't ask for any particular data, there aren't `%u`,
297−`%x`, and `%y` versions for it.
227+When reading from Clay, there are three types of requests. A `%sing` request
228+asks for data at single revsion. A `%next` request asks to be notified the next
229+time there's a change to given file. A `%many` request asks to be notified on
230+every change in a desk for a range of changes.
231+
232+For `%sing` and `%next`, there are generally three things to be queried. A `%u`
233+request simply checks for the existence of a file at a path. A `%x` request gets
234+the data in the file at a path. A `%y` request gets a hash of the data in the
235+file at the path combined with all its children and their data. Thus, `%y` of a
236+node changes if it or any of its children change.
237+
238+A `%sing` request is fulfilled immediately if possible. If the requested
239+revision is in the future, or is on another ship for which we don't have the
240+result cached, we don't respond immediately. If the requested revision is in the
241+future, we wait until the revision happens before we respond to the request. If
242+the request is for data on another ship, we pass on the request to the other
243+ship. In general, Clay subscriptions, like most things in Urbit, aren't
244+guaranteed to return immediately. They'll return when they can, and they'll do
245+so in a referentially transparent manner.
246+
247+A `%next` request checks query at the given revision, and it produces the result
248+of the query the next time it changes, along with the revsion number when it
249+changes. Thus, a `%next` of a `%u` is triggered when a file is added or deleted,
250+a `%next` of a `%x` is triggered when a file is added, deleted, or changed, and
251+a `%next` of a `%y` is triggered when a file or any of its children is added,
252+deleted, or changed.
253+
254+A `%many` request is triggered every time the given desk has a new revision.
255+Unlike a `%next`, a `%many` has both a start and an end revsion, after which it
256+stops returning. For `%next`, a single change is reported, and if the caller
257+wishes to hear of the next change, it must resubscribe. For `%many`, every
258+revsion from the start to the end triggers a response. Since a `%many` request
259+doesn't ask for any particular data, there aren't `%u`, `%x`, and `%y` versions
260+for it.
298261
299262### Unix sync
300263
301−One of the primary functions of clay is as a convenient user
302−interface. While tools exist to use clay from within urbit, it's
303−often useful to be able to treat clay like any other filesystem
304−from the Unix perspective -- to "mount" it, as it were.
264+One of the primary functions of clay is as a convenient user interface. While
265+tools exist to use clay from within urbit, it's often useful to be able to treat
266+clay like any other filesystem from the Unix perspective -- to "mount" it, as it
267+were.
305268
306−From urbit, you can run `|mount /path/to/directory %mount-point`,
307−and this will mount the given clay directory to the mount-point
308−directory in Unix. Every file is converted to `%mime` before it's
309−written to Unix, and converted back when read from Unix. The
310−entire directory is watched (a la Dropbox), and every change is
311−auto-committed to clay.
269+From urbit, you can run `|mount /path/to/directory %mount-point`, and this will
270+mount the given clay directory to the mount-point directory in Unix. Every file
271+is converted to `%mime` before it's written to Unix, and converted back when
272+read from Unix. The entire directory is watched (a la Dropbox), and every change
273+is auto-committed to clay.
312274
313275### Merging
314276
315−Merging is a fundamental operation for a distributed revision
316−control system. At their root, clay's merges are similar to
317−git's, but with some additions to accomodate typed data. There
318−are seven different merge strategies.
319−
320−Throughout our discussion, we'll say that the merge is from
321−Alice's desk to Bob's. Recall that a commit is a date (for all
322−new commits this will be the current date), a list of parents,
323−and the data itself.
324−
325−A `%init` merge should be used iff it's the first commit to a
326−desk. The head of Alice's desk is used as the number 1 commit to
327−Bob's desk. Obviously, the ancestry remains intact through
328−traversing the parentage of the commit even though previous
329−commits are not numbered for Bob's desk.
330−
331−A `%this` merge means to keep what's in Bob's desk, but join the
332−ancestry. Thus, the new commit has the head of each desk as
333−parents, but the data is exactly what's in Bob's desk. For those
334−following along in git, this is the 'ours' merge strategy, not
335−the '--ours' option to the 'recursive' merge strategy. In other
336−words, even if Alice makes a change that does not conflict with
337−Bob, we throw it away. It's Bob's way or the highway.
338−
339−A `%that` merge means to take what's in Alice's desk, but join
340−the ancestry. This is the reverse of `%this`.
341−
342−A `%fine` merge is a "fast-forward" merge. This succeeds iff one
343−head is in the ancestry of the other. In this case, we use the
344−descendant as our new head.
345−
346−For `%meet`, `%mate`, and `%meld` merges, we first find the most
347−recent common ancestor to use as our merge base. If we have no
348−common ancestors, then we fail. If we have more than one most
349−recent common ancestor, then we have a criss-cross situation,
350−which should be handled delicately. At present, we delicately
351−throw up our hands and give up, but something akin to git's
352−'recursive' strategy should be implemented in the future.
353−
354−There's a functional inclusion ordering on `%fine`, `%meet`,
355−`%mate`, and `%meld` such that if an earlier strategy would have
356−succeeded, then every later strategy will produce the same
357−result. Put another way, every earlier strategy is the same as
358−every later strategy except with a restricted domain.
359−
360−A `%meet` merge only succeeds if the changes from the merge base
361−to Alice's head (hereafter, "Alice's changes") are in different
362−files than Bob's changes. In this case, the parents are both
363−Alice's and Bob's heads, and the data is the merge base plus
364−Alice's changed files plus Bob's changed files.
365−
366−A `%mate` merge attempts to merge changes to the same file when
367−both Alice and bob change it. If the merge is clean, we use it;
368−otherwise, we fail. A merge between different types of changes --
369−for example, deleting a file vs changing it -- is always a
370−conflict. If we succeed, the parents are both Alice's and Bob's
371−heads, and the data is the merge base plus Alice's changed files
372−plus Bob's changed files plus the merged files.
373−
374−A `%meld` merge will succeed even if there are conflicts. If
375−there are conflicts in a file, then we use the merge base's
376−version of that file, and we produce a set of files with
377−conflicts. The parents are both Alice's and Bob's heads, and the
378−data is the merge base plus Alice's changed files plus Bob's
379−changed files plus the successfully merged files plus the merge
380−base's version of the conflicting files.
381−
382−That's the extent of the merge options in clay proper. In
383−userspace there's a final option `%auto`, which is the most
384−common. `%auto` checks to see if Bob's desk exists, and if it
385−doesn't we use a `%init` merge. Otherwise, we progressively try
386−`%fine`, `%meet`, and `%mate` until one succeeds.
387−
388−If none succeed, we merge Bob's desk into a scratch desk. Then,
389−we merge Alice's desk into the scratch desk with the `%meld`
390−option to force the merge. For each file in the produced set of
391−conflicting files, we call the `++mash` function for the
392−appropriate mark, which annotates the conflicts if we know how.
393−
394−Finally, we display a message to the user informing them of the
395−scratch desk's existence, which files have annotated conflicts,
396−and which files have unannotated conflicts. When the user has
397−resolved the conflicts, they can merge the scratch desk back into
398−Bob's desk. This will be a `%fine` merge since Bob's head is in
399−the ancestry of the scratch desk.
277+Merging is a fundamental operation for a distributed revision control system. At
278+their root, clay's merges are similar to git's, but with some additions to
279+accomodate typed data. There are seven different merge strategies.
280+
281+Throughout our discussion, we'll say that the merge is from Alice's desk to
282+Bob's. Recall that a commit is a date (for all new commits this will be the
283+current date), a list of parents, and the data itself.
284+
285+A `%init` merge should be used iff it's the first commit to a desk. The head of
286+Alice's desk is used as the number 1 commit to Bob's desk. Obviously, the
287+ancestry remains intact through traversing the parentage of the commit even
288+though previous commits are not numbered for Bob's desk.
289+
290+A `%this` merge means to keep what's in Bob's desk, but join the ancestry. Thus,
291+the new commit has the head of each desk as parents, but the data is exactly
292+what's in Bob's desk. For those following along in git, this is the 'ours' merge
293+strategy, not the '--ours' option to the 'recursive' merge strategy. In other
294+words, even if Alice makes a change that does not conflict with Bob, we throw it
295+away. It's Bob's way or the highway.
296+
297+A `%that` merge means to take what's in Alice's desk, but join the ancestry.
298+This is the reverse of `%this`.
299+
300+A `%fine` merge is a "fast-forward" merge. This succeeds iff one head is in the
301+ancestry of the other. In this case, we use the descendant as our new head.
302+
303+For `%meet`, `%mate`, and `%meld` merges, we first find the most recent common
304+ancestor to use as our merge base. If we have no common ancestors, then we fail.
305+If we have more than one most recent common ancestor, then we have a criss-cross
306+situation, which should be handled delicately. At present, we delicately throw
307+up our hands and give up, but something akin to git's 'recursive' strategy
308+should be implemented in the future.
309+
310+There's a functional inclusion ordering on `%fine`, `%meet`, `%mate`, and
311+`%meld` such that if an earlier strategy would have succeeded, then every later
312+strategy will produce the same result. Put another way, every earlier strategy
313+is the same as every later strategy except with a restricted domain.
314+
315+A `%meet` merge only succeeds if the changes from the merge base to Alice's head
316+(hereafter, "Alice's changes") are in different files than Bob's changes. In
317+this case, the parents are both Alice's and Bob's heads, and the data is the
318+merge base plus Alice's changed files plus Bob's changed files.
319+
320+A `%mate` merge attempts to merge changes to the same file when both Alice and
321+bob change it. If the merge is clean, we use it; otherwise, we fail. A merge
322+between different types of changes -- for example, deleting a file vs changing
323+it -- is always a conflict. If we succeed, the parents are both Alice's and
324+Bob's heads, and the data is the merge base plus Alice's changed files plus
325+Bob's changed files plus the merged files.
326+
327+A `%meld` merge will succeed even if there are conflicts. If there are conflicts
328+in a file, then we use the merge base's version of that file, and we produce a
329+set of files with conflicts. The parents are both Alice's and Bob's heads, and
330+the data is the merge base plus Alice's changed files plus Bob's changed files
331+plus the successfully merged files plus the merge base's version of the
332+conflicting files.
333+
334+That's the extent of the merge options in clay proper. In userspace there's a
335+final option `%auto`, which is the most common. `%auto` checks to see if Bob's
336+desk exists, and if it doesn't we use a `%init` merge. Otherwise, we
337+progressively try `%fine`, `%meet`, and `%mate` until one succeeds.
338+
339+If none succeed, we merge Bob's desk into a scratch desk. Then, we merge Alice's
340+desk into the scratch desk with the `%meld` option to force the merge. For each
341+file in the produced set of conflicting files, we call the `++mash` function for
342+the appropriate mark, which annotates the conflicts if we know how.
343+
344+Finally, we display a message to the user informing them of the scratch desk's
345+existence, which files have annotated conflicts, and which files have
346+unannotated conflicts. When the user has resolved the conflicts, they can merge
347+the scratch desk back into Bob's desk. This will be a `%fine` merge since Bob's
348+head is in the ancestry of the scratch desk.
400349
401350### Autosync
402351
403−Tracking and staying in sync with another desk is another
404−fundamental operation. We call this "autosync". This doesn't mean
405−simply mirroring a desk, since that wouldn't allow local changes.
406−We simply want to apply changes as they are made upstream, as
407−long as there are no conflicts with local changes.
352+Tracking and staying in sync with another desk is another fundamental operation.
353+We call this "autosync". This doesn't mean simply mirroring a desk, since that
354+wouldn't allow local changes. We simply want to apply changes as they are made
355+upstream, as long as there are no conflicts with local changes.
408356
409−This is implemented by watching the other desk, and, when it has
410−changes, merging these changes into our desk with the usual merge
411−strategies.
357+This is implemented by watching the other desk, and, when it has changes,
358+merging these changes into our desk with the usual merge strategies.
412359
413−Note that it's quite reasonable for two desks to be autosynced to
414−each other. This results in any change on one desk being mirrored
415−to the other and vice versa.
360+Note that it's quite reasonable for two desks to be autosynced to each other.
361+This results in any change on one desk being mirrored to the other and vice
362+versa.
416363
417−Additionally, it's fine to set up an autosync even if one desk,
418−the other desk, or both desks do not exist. The sync will be
419−activated when the upstream desk comes into existence and will
420−create the downstream desk if needed.
364+Additionally, it's fine to set up an autosync even if one desk, the other desk,
365+or both desks do not exist. The sync will be activated when the upstream desk
366+comes into existence and will create the downstream desk if needed.
docs/arvo/internals/clay/commentary.md+724−811
@@ -1,46 +1,39 @@
11---
2−navhome: /docs/
2+navhome: '/docs/'
33---
44
5−
6−`%clay` commentary
7−==================
5+# `%clay` commentary
86
97`%clay` is our filesystem.
108
11−The first part of this will be reference documentation for the data
12−types used by our filesystem. In fact, as a general guide, we recommend
13−reading and attempting to understand the data structures used in any
14−Hoon code before you try to read the code itself. Although complete
15−understanding of the data structures is impossible without seeing them
16−used in the code, an 80% understanding greatly clarifies the code. As
17−another general guide, when reading Hoon, it rarely pays off to
18−understand every line of code when it appears. Try to get the gist of
19−it, and then move on. The next time you come back to it, it'll likely
20−make a lot more sense.
21−
22−After a description of the data models, we'll give an overview of the
23−interface that vanes and applications can use to interact with the
24−filesystem.
25−
26−Finally, we'll dive into the code and the algorithms themselves. You
27−know, the fun part.
28−
29−Data Models
30−-----------
31−
32−As you're reading through this section, remember you can always come
33−back to this when you run into these types later on. You're not going to
34−remember everything the first time through, but it is worth reading, or
35−at least skimming, this so that you get a rough idea of how our state is
36−organized.
37−
38−The types that are certainly worth reading are `++raft`, `++room`,
39−`++dome`, `++ankh`, `++rung`, `++rang`, `++blob`, `++yaki`, and `++nori`
40−(possibly in that order). All in all, though, this section isn't too
41−long, so many readers may wish to quickly read through all of it. If you
42−get bored, though, just skip to the next section. You can always come
43−back when you need to.
9+The first part of this will be reference documentation for the data types used
10+by our filesystem. In fact, as a general guide, we recommend reading and
11+attempting to understand the data structures used in any Hoon code before you
12+try to read the code itself. Although complete understanding of the data
13+structures is impossible without seeing them used in the code, an 80%
14+understanding greatly clarifies the code. As another general guide, when reading
15+Hoon, it rarely pays off to understand every line of code when it appears. Try
16+to get the gist of it, and then move on. The next time you come back to it,
17+it'll likely make a lot more sense.
18+
19+After a description of the data models, we'll give an overview of the interface
20+that vanes and applications can use to interact with the filesystem.
21+
22+Finally, we'll dive into the code and the algorithms themselves. You know, the
23+fun part.
24+
25+## Data Models
26+
27+As you're reading through this section, remember you can always come back to
28+this when you run into these types later on. You're not going to remember
29+everything the first time through, but it is worth reading, or at least
30+skimming, this so that you get a rough idea of how our state is organized.
31+
32+The types that are certainly worth reading are `++raft`, `++room`, `++dome`,
33+`++ankh`, `++rung`, `++rang`, `++blob`, `++yaki`, and `++nori` (possibly in that
34+order). All in all, though, this section isn't too long, so many readers may
35+wish to quickly read through all of it. If you get bored, though, just skip to
36+the next section. You can always come back when you need to.
4437
4538### `++raft`, formal state
4639
@@ -50,18 +43,17 @@ back when you need to.
5043 ran=rang :: hashes
5144 == ::
5245
53−This is the state of our vane. Anything that must be remembered between
54−calls to clay is stored in this state.
46+This is the state of our vane. Anything that must be remembered between calls to
47+clay is stored in this state.
5548
56−`fat` is the set of domestic servers. This stores all the information
57−that is specfic to a particular ship on this pier. The keys to this map
58−are the ships on the current pier. all the information that is specific
59−to a particular foreign ship. The keys to this map are all the ships
60−whose filesystems we have attempted to access through clay.
49+`fat` is the set of domestic servers. This stores all the information that is
50+specfic to a particular ship on this pier. The keys to this map are the ships on
51+the current pier. all the information that is specific to a particular foreign
52+ship. The keys to this map are all the ships whose filesystems we have attempted
53+to access through clay.
6154
62−`ran` is the store of all commits and deltas, keyed by hash. The is
63−where all the "real" data we know is stored; the rest is "just
64−bookkeeping".
55+`ran` is the store of all commits and deltas, keyed by hash. The is where all
56+the "real" data we know is stored; the rest is "just bookkeeping".
6557
6658### `++room`, filesystem per domestic ship
6759
@@ -73,42 +65,40 @@ bookkeeping".
7365
7466This is the representation of the filesystem of a ship on our pier.
7567
76−`hun` is the duct we use to send messages to dill to display
77−notifications of filesystem changes. Only `%note` gifts should be
78−produced along this duct. This is set by the `%init` kiss.
68+`hun` is the duct we use to send messages to dill to display notifications of
69+filesystem changes. Only `%note` gifts should be produced along this duct. This
70+is set by the `%init` kiss.
7971
80−`hez`, if present, is the duct we use to send sync messages to unix so
81−that they end up in the pier unix directory. Only `%ergo` gifts should
82−be producd along this duct. This is set by `%into` and `%invo` kisses.
72+`hez`, if present, is the duct we use to send sync messages to unix so that they
73+end up in the pier unix directory. Only `%ergo` gifts should be producd along
74+this duct. This is set by `%into` and `%invo` kisses.
8375
84−`dos` is a well-known operating system released in 1981. It is also the
85−set of desks on this ship, mapped to their data.
76+`dos` is a well-known operating system released in 1981. It is also the set of
77+desks on this ship, mapped to their data.
8678
8779### `++desk`, filesystem branch
8880
8981 ++ desk ,@tas :: ship desk case spur
9082
91−This is the name of a branch of the filesystem. The default desks are
92−"arvo", "main", and "try". More may be created by simply referencing
93−them. Desks have independent histories and states, and they may be
94−merged into each other.
83+This is the name of a branch of the filesystem. The default desks are "arvo",
84+"main", and "try". More may be created by simply referencing them. Desks have
85+independent histories and states, and they may be merged into each other.
9586
9687### `++dojo`, domestic desk state
9788
9889 ++ dojo ,[p=cult q=dome] :: domestic desk state
9990
100−This is the all the data that is specific to a particular desk on a
101−domestic ship. `p` is the set of subscribers to this desk and `q` is the
102−data in the desk.
91+This is the all the data that is specific to a particular desk on a domestic
92+ship. `p` is the set of subscribers to this desk and `q` is the data in the
93+desk.
10394
10495### `++cult`, subscriptions
10596
10697 ++ cult (map duct rave) :: subscriptions
10798
108−This is the set of subscriptions to a particular desk. The keys are the
109−ducts from where the subscriptions requests came. The results will be
110−produced along these ducts. The values are a description of the
111−requested information.
99+This is the set of subscriptions to a particular desk. The keys are the ducts
100+from where the subscriptions requests came. The results will be produced along
101+these ducts. The values are a description of the requested information.
112102
113103### `++rave`, general subscription request
114104
@@ -117,61 +107,60 @@ requested information.
117107 [| p=moat] :: change range
118108 == ::
119109
120−This represents a subscription request for a desk. The request can be
121−for either a single item in the desk or else for a range of changes on
122−the desk.
110+This represents a subscription request for a desk. The request can be for either
111+a single item in the desk or else for a range of changes on the desk.
123112
124113### `++rove`, stored general subscription request
125114
126115 ++ rove (each mood moot) :: stored request
127116
128−When we store a request, we store subscriptions with a little extra
129−information so that we can determine whether new versions actually
130−affect the path we're subscribed to.
117+When we store a request, we store subscriptions with a little extra information
118+so that we can determine whether new versions actually affect the path we're
119+subscribed to.
131120
132121### `++mood`, single subscription request
133122
134123 ++ mood ,[p=care q=case r=path] :: request in desk
135124
136−This represents a request for the state of the desk at a particular
137−commit, specfied by `q`. `p` specifies what kind of information is
138−desired, and `r` specifies the path we are requesting.
125+This represents a request for the state of the desk at a particular commit,
126+specfied by `q`. `p` specifies what kind of information is desired, and `r`
127+specifies the path we are requesting.
139128
140129### `++moat`, range subscription request
141130
142131 ++ moat ,[p=case q=case r=path] :: change range
143132
144−This represents a request for all changes between `p` and `q` on path
145−`r`. You will be notified when a change is made to the node referenced
146−by the path or to any of its children.
133+This represents a request for all changes between `p` and `q` on path `r`. You
134+will be notified when a change is made to the node referenced by the path or to
135+any of its children.
147136
148137### `++moot`, stored range subscription request
149138
150139 ++ moot ,[p=case q=case r=path s=(map path lobe)] ::
151140
152−This is just a `++moat` plus a map of paths to lobes. This map
153−represents the data at the node referenced by the path at case `p`, if
154−we've gotten to that case (else null). We only send a notification along
155−the subscription if the data at a new revision is different than it was.
141+This is just a `++moat` plus a map of paths to lobes. This map represents the
142+data at the node referenced by the path at case `p`, if we've gotten to that
143+case (else null). We only send a notification along the subscription if the data
144+at a new revision is different than it was.
156145
157146### `++care`, clay submode
158147
159148 ++ care ?(%u %v %w %x %y %z) :: clay submode
160149
161−This specifies what type of information is requested in a subscription
162−or a scry.
150+This specifies what type of information is requested in a subscription or a
151+scry.
163152
164−`%u` requests the `++rang` at the current moment. Because this
165−information is not stored for any moment other than the present, we
166−crash if the `++case` is not a `%da` for now.
153+`%u` requests the `++rang` at the current moment. Because this information is
154+not stored for any moment other than the present, we crash if the `++case` is
155+not a `%da` for now.
167156
168157`%v` requests the `++dome` at the specified commit.
169158
170159`%w` requests the revsion number of the desk.
171160
172−`%x` requests the file at a specified path at the specified commit. If
173−there is no node at that path or if the node has no contents (that is,
174−if `q:ankh` is null), then this produces null.
161+`%x` requests the file at a specified path at the specified commit. If there is
162+no node at that path or if the node has no contents (that is, if `q:ankh` is
163+null), then this produces null.
175164
176165`%y` requests a `++arch` of the specfied commit at the specified path.
177166
@@ -181,13 +170,12 @@ if `q:ankh` is null), then this produces null.
181170
182171 ++ arch ,[p=@uvI q=(unit ,@uvI) r=(map ,@ta ,~)] :: fundamental node
183172
184−This is analogous to `++ankh` except that the we have neither our
185−contents nor the ankhs of our children. The other fields are exactly the
186−same, so `p` is a hash of the associated ankh, `u.q`, if it exists, is a
187−hash of the contents of this node, and the keys of `r` are the names of
188−our children. `r` is a map to null rather than a set so that the
189−ordering of the map will be equivalent to that of `r:ankh`, allowing
190−efficient conversion.
173+This is analogous to `++ankh` except that the we have neither our contents nor
174+the ankhs of our children. The other fields are exactly the same, so `p` is a
175+hash of the associated ankh, `u.q`, if it exists, is a hash of the contents of
176+this node, and the keys of `r` are the names of our children. `r` is a map to
177+null rather than a set so that the ordering of the map will be equivalent to
178+that of `r:ankh`, allowing efficient conversion.
191179
192180### `++case`, specifying a commit
193181
@@ -197,11 +185,10 @@ efficient conversion.
197185 [%ud p=@ud] :: number
198186 == ::
199187
200−A commit can be referred to in three ways: `%da` refers to the commit
201−that was at the head on date `p`, `%tas` refers to the commit labeled
202−`p`, and `%ud` refers to the commit numbered `p`. Note that since these
203−all can be reduced down to a `%ud`, only numbered commits may be
204−referenced with a `++case`.
188+A commit can be referred to in three ways: `%da` refers to the commit that was
189+at the head on date `p`, `%tas` refers to the commit labeled `p`, and `%ud`
190+refers to the commit numbered `p`. Note that since these all can be reduced down
191+to a `%ud`, only numbered commits may be referenced with a `++case`.
205192
206193### `++dome`, desk data
207194
@@ -217,29 +204,26 @@ This is the data that is actually stored in a desk.
217204
218205`ang` is unused and should be removed.
219206
220−`ank` is the current state of the desk. Thus, it is the state of the
221−filesystem at revison `let`. The head of a desk is always a numbered
222−commit.
223−
224−`let` is the number of the most recently numbered commit. This is also
225−the total number of numbered commits.
226−
227−`hit` is a map of numerical ids to hashes of commits. These hashes are
228−mapped into their associated commits in `hut:rang`. In general, the keys
229−of this map are exactly the numbers from 1 to `let`, with no gaps. Of
230−course, when there are no numbered commits, `let` is 0, so `hit` is
231−null. Additionally, each of the commits is an ancestor of every commit
232−numbered greater than this one. Thus, each is a descendant of every
233−commit numbered less than this one. Since it is true that the date in
234−each commit (`t:yaki`) is no earlier than that of each of its parents,
235−the numbered commits are totally ordered in the same way by both
236−pedigree and date. Of course, not every commit is numbered. If that
237−sounds too complicated to you, don't worry about it. It basically
238−behaves exactly as you would expect.
239−
240−`lab` is a map of textual labels to numbered commits. Note that labels
241−can only be applied to numbered commits. Labels must be unique across a
242−desk.
207+`ank` is the current state of the desk. Thus, it is the state of the filesystem
208+at revison `let`. The head of a desk is always a numbered commit.
209+
210+`let` is the number of the most recently numbered commit. This is also the total
211+number of numbered commits.
212+
213+`hit` is a map of numerical ids to hashes of commits. These hashes are mapped
214+into their associated commits in `hut:rang`. In general, the keys of this map
215+are exactly the numbers from 1 to `let`, with no gaps. Of course, when there are
216+no numbered commits, `let` is 0, so `hit` is null. Additionally, each of the
217+commits is an ancestor of every commit numbered greater than this one. Thus,
218+each is a descendant of every commit numbered less than this one. Since it is
219+true that the date in each commit (`t:yaki`) is no earlier than that of each of
220+its parents, the numbered commits are totally ordered in the same way by both
221+pedigree and date. Of course, not every commit is numbered. If that sounds too
222+complicated to you, don't worry about it. It basically behaves exactly as you
223+would expect.
224+
225+`lab` is a map of textual labels to numbered commits. Note that labels can only
226+be applied to numbered commits. Labels must be unique across a desk.
243227
244228### `++ankh`, filesystem node
245229
@@ -249,35 +233,34 @@ desk.
249233 r=(map ,@ta ankh) :: folders
250234 == ::
251235
252−This is a single node in the filesystem. This may be file or a directory
253−or both. In earth filesystems, a node is a file xor a directory. On
254−mars, we're inclusive, so a node is a file ior a directory.
236+This is a single node in the filesystem. This may be file or a directory or
237+both. In earth filesystems, a node is a file xor a directory. On mars, we're
238+inclusive, so a node is a file ior a directory.
255239
256240`p` is a recursive hash that depends on the contents of the this file or
257241directory and on any children.
258242
259−`q` is the contents of this file, if any. `p.q` is a hash of the
260−contents while `q.q` is the data itself.
243+`q` is the contents of this file, if any. `p.q` is a hash of the contents while
244+`q.q` is the data itself.
261245
262−`r` is the set of children of this node. In the case of a pure file,
263−this is empty. The keys are the names of the children and the values
264−are, recursively, the nodes themselves.
246+`r` is the set of children of this node. In the case of a pure file, this is
247+empty. The keys are the names of the children and the values are, recursively,
248+the nodes themselves.
265249
266250### `++cash`, ankh hash
267251
268252 ++ cash ,@uvH :: ankh hash
269253
270254This is a 128-bit hash of an ankh. These are mostly stored within ankhs
271−themselves, and they are used to check for changes in possibly-deep
272−hierarchies.
255+themselves, and they are used to check for changes in possibly-deep hierarchies.
273256
274257### `++rung`, filesystem per neighbor ship
275258
276259 ++ rung $: rus=(map desk rede) :: neighbor desks
277260 == ::
278261
279−This is the filesystem of a neighbor ship. The keys to this map are all
280−the desks we know about on their ship.
262+This is the filesystem of a neighbor ship. The keys to this map are all the
263+desks we know about on their ship.
281264
282265### `++rede`, desk state
283266
@@ -288,18 +271,17 @@ the desks we know about on their ship.
288271 dom=dome :: revision state
289272 == ::
290273
291−This is our knowledge of the state of a desk, either foreign or
292−domestic.
274+This is our knowledge of the state of a desk, either foreign or domestic.
293275
294−`lim` is the date of the last full update. We only respond to requests
295−for stuff before this time.
276+`lim` is the date of the last full update. We only respond to requests for stuff
277+before this time.
296278
297−`qyx` is the list of subscribers to this desk. For domestic desks, this
298−is simply `p:dojo`, all subscribers to the desk, while in foreign desks
299−this is all the subscribers from our ship to the foreign desk.
279+`qyx` is the list of subscribers to this desk. For domestic desks, this is
280+simply `p:dojo`, all subscribers to the desk, while in foreign desks this is all
281+the subscribers from our ship to the foreign desk.
300282
301−`ref` is the request manager for the desk. For domestic desks, this is
302−null since we handle requests ourselves.
283+`ref` is the request manager for the desk. For domestic desks, this is null
284+since we handle requests ourselves.
303285
304286`dom` is the actual data in the desk.
305287
@@ -314,23 +296,22 @@ null since we handle requests ourselves.
314296
315297This is the request manager for a foreign desk.
316298
317−`nix` is one more than the index of the most recent request. Thus, it is
318−the next available request number.
299+`nix` is one more than the index of the most recent request. Thus, it is the
300+next available request number.
319301
320−`bom` is the set of outstanding requests. The keys of this map are some
321−subset of the numbers between 0 and one less than `nix`. The members of
322−the map are exactly those requests that have not yet been fully
323−satisfied.
302+`bom` is the set of outstanding requests. The keys of this map are some subset
303+of the numbers between 0 and one less than `nix`. The members of the map are
304+exactly those requests that have not yet been fully satisfied.
324305
325−`fod` is the same set as `bom`, but from a different perspective. In
326−particular, the values of `fod` are the same as the values of `bom`, and
327−the `p` out of the values of `bom` are the same as the keys of `fod`.
328−Thus, we can map ducts to their associated request number and `++rave`,
329−and we can map numbers to their associated duct and `++rave`.
306+`fod` is the same set as `bom`, but from a different perspective. In particular,
307+the values of `fod` are the same as the values of `bom`, and the `p` out of the
308+values of `bom` are the same as the keys of `fod`. Thus, we can map ducts to
309+their associated request number and `++rave`, and we can map numbers to their
310+associated duct and `++rave`.
330311
331−`haw` is a map from simple requests to their values. This acts as a
332−cache for requests that have already been made. Thus, the second request
333−for a particular `++mood` is nearly instantaneous.
312+`haw` is a map from simple requests to their values. This acts as a cache for
313+requests that have already been made. Thus, the second request for a particular
314+`++mood` is nearly instantaneous.
334315
335316### `++rang`, data store
336317
@@ -338,26 +319,23 @@ for a particular `++mood` is nearly instantaneous.
338319 lat=(map lobe blob) ::
339320 == ::
340321
341−This is a set of data keyed by hash. Thus, this is where the "real" data
342−is stored, but it is only meaningful if we know the hash of what we're
343−looking for.
322+This is a set of data keyed by hash. Thus, this is where the "real" data is
323+stored, but it is only meaningful if we know the hash of what we're looking for.
344324
345−`hut` is a map from hashes to commits. We often get the hashes from
346−`hit:dome`, which keys them by logical id. Not every commit has an id.
325+`hut` is a map from hashes to commits. We often get the hashes from `hit:dome`,
326+which keys them by logical id. Not every commit has an id.
347327
348−`lat` is a map from hashes to the actual data. We often get the hashes
349−from a `++yaki`, a commit, which references this map to get the data.
350−There is no `++blob` in any `++yaki`. They are only accessible through
351−this map.
328+`lat` is a map from hashes to the actual data. We often get the hashes from a
329+`++yaki`, a commit, which references this map to get the data. There is no
330+`++blob` in any `++yaki`. They are only accessible through this map.
352331
353332### `++tako`, commit reference
354333
355334 ++ tako ,@ :: yaki ref
356335
357−This is a hash of a `++yaki`, a commit. These are most notably used as
358−the keys in `hut:rang`, where they are associated with the actual
359−`++yaki`, and as the values in `hit:dome`, where sequential ids are
360−associated with these.
336+This is a hash of a `++yaki`, a commit. These are most notably used as the keys
337+in `hut:rang`, where they are associated with the actual `++yaki`, and as the
338+values in `hit:dome`, where sequential ids are associated with these.
361339
362340### `++yaki`, commit
363341
@@ -365,15 +343,14 @@ associated with these.
365343
366344This is a single commit.
367345
368−`p` is a list of the hashes of the parents of this commit. In most
369−cases, this will be a single commit, but in a merge there may be more
370−parents. In theory, there may be an arbitrary number of parents, but in
371−practice merges have exactly two parents. This may change in the future.
372−For commit 1, there is no parent.
346+`p` is a list of the hashes of the parents of this commit. In most cases, this
347+will be a single commit, but in a merge there may be more parents. In theory,
348+there may be an arbitrary number of parents, but in practice merges have exactly
349+two parents. This may change in the future. For commit 1, there is no parent.
373350
374351`q` is a map of the paths on a desk to the data at that location. If you
375−understand what a `++lobe` and a `++blob` is, then the type signature
376−here tells the whole story.
352+understand what a `++lobe` and a `++blob` is, then the type signature here tells
353+the whole story.
377354
378355`r` is the hash associated with this commit.
379356
@@ -383,9 +360,9 @@ here tells the whole story.
383360
384361 ++ lobe ,@ :: blob ref
385362
386−This is a hash of a `++blob`. These are most notably used in `lat:rang`,
387−where they are associated with the actual `++blob`, and as the values in
388−`q:yaki`, where paths are associated with their data in a commit.
363+This is a hash of a `++blob`. These are most notably used in `lat:rang`, where
364+they are associated with the actual `++blob`, and as the values in `q:yaki`,
365+where paths are associated with their data in a commit.
389366
390367### `++blob`, data
391368
@@ -396,22 +373,21 @@ where they are associated with the actual `++blob`, and as the values in
396373
397374This is a node of data. In every case, `p` is the hash of the blob.
398375
399−`%delta` is the case where we define the data by a delta on other data.
400−In practice, the other data is always the previous commit, but nothing
401−depends on this. `q` is the hash of the parent blob, and `r` is the
402−delta.
376+`%delta` is the case where we define the data by a delta on other data. In
377+practice, the other data is always the previous commit, but nothing depends on
378+this. `q` is the hash of the parent blob, and `r` is the delta.
403379
404−`%direct` is the case where we simply have the data directly. `q` is the
405−data itself, and `r` is any preprocessing instructions. These almost
406−always come from the creation of a file.
380+`%direct` is the case where we simply have the data directly. `q` is the data
381+itself, and `r` is any preprocessing instructions. These almost always come from
382+the creation of a file.
407383
408−`%indirect` is both of the preceding cases at once. `q` is the direct
409−data, `r` is the delta, and `s` is the parent blob. It should always be
410−the case that applying `r` to `s` gives the same data as `q` directly
411−(with the prepreprocessor instructions in `p.r`). This exists purely for
412−performance reasons. This is unused, at the moment, but in general these
413−should be created when there are a long line of changes so that we do
414−not have to traverse the delta chain back to the creation of the file.
384+`%indirect` is both of the preceding cases at once. `q` is the direct data, `r`
385+is the delta, and `s` is the parent blob. It should always be the case that
386+applying `r` to `s` gives the same data as `q` directly (with the
387+prepreprocessor instructions in `p.r`). This exists purely for performance
388+reasons. This is unused, at the moment, but in general these should be created
389+when there are a long line of changes so that we do not have to traverse the
390+delta chain back to the creation of the file.
415391
416392### `++udon`, abstract delta
417393
@@ -425,33 +401,31 @@ not have to traverse the delta chain back to the creation of the file.
425401 == ::
426402 == ::
427403
428−This is an abstract change to a file. This is a superset of what would
429−normally be called diffs. Diffs usually refer to changes in lines of
430−text while we have the ability to do more interesting deltas on
431−arbitrary data structures.
404+This is an abstract change to a file. This is a superset of what would normally
405+be called diffs. Diffs usually refer to changes in lines of text while we have
406+the ability to do more interesting deltas on arbitrary data structures.
432407
433408`p` is any preprocessor instructions.
434409
435−`%a` refers to the trival delta of a complete replace of old data with
436−new data.
410+`%a` refers to the trival delta of a complete replace of old data with new data.
437411
438−`%b` refers to changes in an opaque atom on the block level. This has
439−very limited usefulness, and is not used at the moment.
412+`%b` refers to changes in an opaque atom on the block level. This has very
413+limited usefulness, and is not used at the moment.
440414
441−`%c` refers to changes in a list of data. This is often lines of text,
442−which is your classic diff. We, however, will work on any list of data.
415+`%c` refers to changes in a list of data. This is often lines of text, which is
416+your classic diff. We, however, will work on any list of data.
443417
444−`%d` refers to changes in a tree of data. This is general enough to
445−describe changes to any hoon noun, but often more special-purpose delta
446−should be created for different content types. This is not used at the
447−moment, and may in fact be unimplemented.
418+`%d` refers to changes in a tree of data. This is general enough to describe
419+changes to any hoon noun, but often more special-purpose delta should be created
420+for different content types. This is not used at the moment, and may in fact be
421+unimplemented.
448422
449423### `++urge`, list change
450424
451425 ++ urge |*(a=_,* (list (unce a))) :: list change
452426
453−This is a parametrized type for list changes. For example, `(urge ,@t)`
454−is a list change for lines of text.
427+This is a parametrized type for list changes. For example, `(urge ,@t)` is a
428+list change for lines of text.
455429
456430### `++unce`, change part of a list.
457431
@@ -477,8 +451,8 @@ This is a single change in a list of elements of type `a`. For example,
477451 $% [%d p=@ud] :: blocklist
478452 == ::
479453
480−This space intentionally left undocumented. This stuff will change once
481−we get a well-typed clay.
454+This space intentionally left undocumented. This stuff will change once we get a
455+well-typed clay.
482456
483457### `++upas`, tree change
484458
@@ -489,9 +463,9 @@ we get a well-typed clay.
489463 [%2 p=axis q=udon] :: mutate!
490464 == ::
491465
492−This space intentionally left undocumented. This stuff is not known to
493−work, and will likely change when we get a well-typed clay. Also, this
494−is not a complicated type; it is not difficult to work out the meaning.
466+This space intentionally left undocumented. This stuff is not known to work, and
467+will likely change when we get a well-typed clay. Also, this is not a
468+complicated type; it is not difficult to work out the meaning.
495469
496470### `++nori`, repository action
497471
@@ -500,22 +474,21 @@ is not a complicated type; it is not difficult to work out the meaning.
500474 [| p=@tas] :: label
501475 == ::
502476
503−This describes a change that we are asking clay to make to the desk.
504−There are two kinds of changes that may be made: we can modify files or
505−we can apply a label to a commit.
477+This describes a change that we are asking clay to make to the desk. There are
478+two kinds of changes that may be made: we can modify files or we can apply a
479+label to a commit.
506480
507−In the `|` case, we will simply label the current commit with the given
508−label. In the `&` case, we will apply the given changes.
481+In the `|` case, we will simply label the current commit with the given label.
482+In the `&` case, we will apply the given changes.
509483
510484### `++soba`, delta
511485
512486 ++ soba ,[p=cart q=(list ,[p=path q=miso])] :: delta
513487
514−This describes a set of changes to make to a desk. The `cart` is simply
515−a pair of the old hash and the new hash of the desk. The list is a list
516−of changes keyed by the file they're changing. Thus, the paths are paths
517−to files to be changed while `miso` is a description of the change
518−itself.
488+This describes a set of changes to make to a desk. The `cart` is simply a pair
489+of the old hash and the new hash of the desk. The list is a list of changes
490+keyed by the file they're changing. Thus, the paths are paths to files to be
491+changed while `miso` is a description of the change itself.
519492
520493### `++miso`, ankh delta
521494
@@ -525,40 +498,38 @@ itself.
525498 [%mut p=udon] :: mutate
526499 == ::
527500
528−There are three kinds of changes that may be made to a node in a desk.
529−We can insert a file, in which case `p` is the contents of the new file.
530−We can delete a file, in which case `p` is the contents of the old file.
531−Finally, we can mutate that file, in which case the `udon` describes the
532−changes we are applying to the file.
501+There are three kinds of changes that may be made to a node in a desk. We can
502+insert a file, in which case `p` is the contents of the new file. We can delete
503+a file, in which case `p` is the contents of the old file. Finally, we can
504+mutate that file, in which case the `udon` describes the changes we are applying
505+to the file.
533506
534507### `++mizu`, merged state
535508
536509 ++ mizu ,[p=@u q=(map ,@ud tako) r=rang] :: new state
537510
538−This is the input to the `%merg` kiss, which allows us to perform a
539−merge. The `p` is the number of the new head commit. The `q` is a map
540−from numbers to commit hashes. This is all the new numbered commits that
541−are to be inserted. The keys to this should always be the numbers from
542−`let.dom` plus one to `p`, inclusive. The `r` is the maps of all the new
543−commits and data. Since these are merged into the current state, no old
544−commits or data need be here.
511+This is the input to the `%merg` kiss, which allows us to perform a merge. The
512+`p` is the number of the new head commit. The `q` is a map from numbers to
513+commit hashes. This is all the new numbered commits that are to be inserted. The
514+keys to this should always be the numbers from `let.dom` plus one to `p`,
515+inclusive. The `r` is the maps of all the new commits and data. Since these are
516+merged into the current state, no old commits or data need be here.
545517
546518### `++riff`, request/desist
547519
548520 ++ riff ,[p=desk q=(unit rave)] :: request/desist
549521
550−This represents a request for data about a particular desk. If `q`
551−contains a `rave`, then this opens a subscription to the desk for that
552−data. If `q` is null, then this tells clay to cancel the subscription
553−along this duct.
522+This represents a request for data about a particular desk. If `q` contains a
523+`rave`, then this opens a subscription to the desk for that data. If `q` is
524+null, then this tells clay to cancel the subscription along this duct.
554525
555526### `++riot`, response
556527
557528 ++ riot (unit rant) :: response/complete
558529
559−A riot is a response to a subscription. If null, the subscription has
560−been completed, and no more responses will be sent. Otherwise, the
561−`rant` is the produced data.
530+A riot is a response to a subscription. If null, the subscription has been
531+completed, and no more responses will be sent. Otherwise, the `rant` is the
532+produced data.
562533
563534### `++rant`, response data
564535
@@ -568,11 +539,11 @@ been completed, and no more responses will be sent. Otherwise, the
568539 r=* :: data
569540 == ::
570541
571−This is the data at a particular node in the filesystem. `p.p` specifies
572−the type of data that was requested (and is produced). `q.p` gives the
573−specific version reported (since a range of versions may be requested in
574−a subscription). `r.p` is the desk. `q` is the path to the filesystem
575−node. `r` is the data itself (in the format specified by `p.p`).
542+This is the data at a particular node in the filesystem. `p.p` specifies the
543+type of data that was requested (and is produced). `q.p` gives the specific
544+version reported (since a range of versions may be requested in a subscription).
545+`r.p` is the desk. `q` is the path to the filesystem node. `r` is the data
546+itself (in the format specified by `p.p`).
576547
577548### `++nako`, subscription response data
578549
@@ -582,26 +553,24 @@ node. `r` is the data itself (in the format specified by `p.p`).
582553 bar=(set blob) :: new content
583554 == ::
584555
585−This is the data that is produced by a request for a range of revisions
586−of a desk. This allows us to easily keep track of a remote repository --
587−all the new information we need is contained in the `nako`.
556+This is the data that is produced by a request for a range of revisions of a
557+desk. This allows us to easily keep track of a remote repository -- all the new
558+information we need is contained in the `nako`.
588559
589−`gar` is a map of the revisions in the range to the hash of the commit
590−at that revision. These hashes can be used with `hut:rang` to find the
591−commit itself.
560+`gar` is a map of the revisions in the range to the hash of the commit at that
561+revision. These hashes can be used with `hut:rang` to find the commit itself.
592562
593563`let` is either the last revision number in the range or the most recent
594564revision number, whichever is smaller.
595565
596566`lar` is the set of new commits, and `bar` is the set of new content.
597567
598−Public Interface
599−----------------
568+## Public Interface
600569
601−As with all vanes, there are exactly two ways to interact with clay.
602−`%clay` exports a namespace accessible through `.^`, which is described
603−above under `++care`. The primary way of interacting with clay, though,
604−is by sending kisses and receiving gifts.
570+As with all vanes, there are exactly two ways to interact with clay. `%clay`
571+exports a namespace accessible through `.^`, which is described above under
572+`++care`. The primary way of interacting with clay, though, is by sending kisses
573+and receiving gifts.
605574
606575 ++ gift :: out result <-$
607576 $% [%ergo p=@p q=@tas r=@ud] :: version update
@@ -619,91 +588,82 @@ is by sending kisses and receiving gifts.
619588 [%warp p=sock q=riff] :: file request
620589 == ::
621590
622−There are only a small number of possible kisses, so it behooves us to
623−describe each in detail.
591+There are only a small number of possible kisses, so it behooves us to describe
592+each in detail.
624593
625594 $% [%info p=@p q=@tas r=nori] :: internal edit
626595
627596 [%into p=@p q=@tas r=nori] :: external edit
628597
629−These two kisses are nearly identical. At a high level, they apply
630−changes to the filesystem. Whenever we add, remove, or edit a file, one
631−of these cards is sent. The `p` is the ship whose filesystem we're
632−trying to change, the `q` is the desk we're changing, and the `r` is the
633−request change. For the format of the requested change, see the
634−documentation for `++nori` above.
598+These two kisses are nearly identical. At a high level, they apply changes to
599+the filesystem. Whenever we add, remove, or edit a file, one of these cards is
600+sent. The `p` is the ship whose filesystem we're trying to change, the `q` is
601+the desk we're changing, and the `r` is the request change. For the format of
602+the requested change, see the documentation for `++nori` above.
635603
636−When a file is changed in the unix filesystem, vere will send a `%into`
637−kiss. This tells clay that the duct over which the kiss was sent is the
638−duct that unix is listening on for changes. From within Arvo, though, we
639−should never send a `%into` kiss. The `%info` kiss is exactly identical
640−except it does not reset the duct.
604+When a file is changed in the unix filesystem, vere will send a `%into` kiss.
605+This tells clay that the duct over which the kiss was sent is the duct that unix
606+is listening on for changes. From within Arvo, though, we should never send a
607+`%into` kiss. The `%info` kiss is exactly identical except it does not reset the
608+duct.
641609
642610 [%ingo p=@p q=@tas r=nori] :: internal noun edit
643611
644612 [%invo p=@p q=@tas r=nori] :: external noun edit
645613
646−These kisses are currently identical to `%info` and `%into`, though this
647−will not always be the case. The intent is for these kisses to allow
648−typed changes to clay so that we may store typed data. This is currently
649−unimplemented.
614+These kisses are currently identical to `%info` and `%into`, though this will
615+not always be the case. The intent is for these kisses to allow typed changes to
616+clay so that we may store typed data. This is currently unimplemented.
650617
651618 [%init p=@p] :: report install
652619
653−Init is called when a ship is started on our pier. This simply creates a
654−default `room` to go into our `raft`. Essentially, this initializes the
655−filesystem for a ship.
620+Init is called when a ship is started on our pier. This simply creates a default
621+`room` to go into our `raft`. Essentially, this initializes the filesystem for a
622+ship.
656623
657624 [%merg p=@p q=@tas r=mizu] :: internal change
658625
659−This is called to perform a merge. This is most visibly called by
660−:update to update the filesystem of the current ship to that of its
661−sein. The `p` and `q` are as in `%info`, and the `r` is the description
662−of the merge. See `++mizu` above.
626+This is called to perform a merge. This is most visibly called by :update to
627+update the filesystem of the current ship to that of its sein. The `p` and `q`
628+are as in `%info`, and the `r` is the description of the merge. See `++mizu`
629+above.
663630
664631XX
665632`XX [%wake ~] :: timer activate XX`
666−XX\
667−XX This card is sent by unix at the time specified by `++doze`. This
668−time is XX usually the closest time specified in a subscription request.
669−When `%wake` is XX called, we update our subscribers if there have been
670−any changes.
633+XX\\ XX This card is sent by unix at the time specified by `++doze`. This time
634+is XX usually the closest time specified in a subscription request. When `%wake`
635+is XX called, we update our subscribers if there have been any changes.
671636
672637 [%wart p=sock q=@tas r=path s=*] :: network request
673638
674−This is a request that has come across the network for a particular
675−file. When another ship asks for a file from us, that request comes to
676−us in the form of a `%wart` kiss. This is handled by trivially turning
677−it into a `%warp`.
639+This is a request that has come across the network for a particular file. When
640+another ship asks for a file from us, that request comes to us in the form of a
641+`%wart` kiss. This is handled by trivially turning it into a `%warp`.
678642
679643 [%warp p=sock q=riff] :: file request
680644
681−This is a request for information about a particular desk. This is, in
682−its most general form, a subscription, though in many cases it is the
683−trivial case of a subscription -- a read. See `++riff` for the format of
684−the request.
645+This is a request for information about a particular desk. This is, in its most
646+general form, a subscription, though in many cases it is the trivial case of a
647+subscription -- a read. See `++riff` for the format of the request.
685648
686−Lifecycle of a Local Read
687−-------------------------
649+## Lifecycle of a Local Read
688650
689−There are two real types of interaction with a filesystem: you can read,
690−and you can write. We'll describe each process, detailing both the flow
691−of control followed by the kernel and the algorithms involved. The
692−simpler case is that of the read, so we'll begin with that.
651+There are two real types of interaction with a filesystem: you can read, and you
652+can write. We'll describe each process, detailing both the flow of control
653+followed by the kernel and the algorithms involved. The simpler case is that of
654+the read, so we'll begin with that.
693655
694−When a vane or an application wishes to read a file from the filesystem,
695−it sends a `%warp` kiss, as described above. Of course, you may request
696−a file on another ship and, being a global filesystem, clay will happily
697−produce it for you. That code pathway will be described in another
698−section; here, we will restrict ourselves to examining the case of a
699−read from a ship on our own pier.
656+When a vane or an application wishes to read a file from the filesystem, it
657+sends a `%warp` kiss, as described above. Of course, you may request a file on
658+another ship and, being a global filesystem, clay will happily produce it for
659+you. That code pathway will be described in another section; here, we will
660+restrict ourselves to examining the case of a read from a ship on our own pier.
700661
701−The kiss can request either a single version of a file node or a range
702−of versions of a desk. Here, we'll deal only with a request for a single
703−version.
662+The kiss can request either a single version of a file node or a range of
663+versions of a desk. Here, we'll deal only with a request for a single version.
704664
705−As in all vanes, a kiss enters clay via a call to `++call`. Scanning
706−through the arm, we quickly see where `%warp` is handled.
665+As in all vanes, a kiss enters clay via a call to `++call`. Scanning through the
666+arm, we quickly see where `%warp` is handled.
707667
708668 ?: =(p.p.q.hic q.p.q.hic)
709669 =+ une=(un p.p.q.hic now ruf)
@@ -716,33 +676,31 @@ through the arm, we quickly see where `%warp` is handled.
716676 abet:wao
717677 [-.woo abet:(pish:une p.q.q.hic +.woo ran.wao)]
718678
719−We're following the familar patern of producing a list of moves and an
720−updated state. In this case, the state is `++raft`.
679+We're following the familar patern of producing a list of moves and an updated
680+state. In this case, the state is `++raft`.
721681
722−We first check to see if the sending and receiving ships are the same.
723−If they're not, then this is a request for data on another ship. We
724−describe that process later. Here, we discuss only the case of a local
725−read.
682+We first check to see if the sending and receiving ships are the same. If
683+they're not, then this is a request for data on another ship. We describe that
684+process later. Here, we discuss only the case of a local read.
726685
727−At a high level, the call to `++un` sets up the core for the domestic
728−ship that contains the files we're looking for. The call to `++di` sets
729−up the core for the particular desk we're referring to.
686+At a high level, the call to `++un` sets up the core for the domestic ship that
687+contains the files we're looking for. The call to `++di` sets up the core for
688+the particular desk we're referring to.
730689
731−After this, we perform the actual request. If there is no rave in the
732−riff, then that means we are cancelling a request, so we call
733−`++ease:de`. Otherwise, we start a subscription with `++eave:de`. We
734−call `++abet:de` to resolve our various types of output into actual
735−moves. We produce the moves we found above and the `++un` core resolved
736−with `++pish:un` (putting the modified desk in the room) and `++abet:un`
737−(putting the modified room in the raft).
690+After this, we perform the actual request. If there is no rave in the riff, then
691+that means we are cancelling a request, so we call `++ease:de`. Otherwise, we
692+start a subscription with `++eave:de`. We call `++abet:de` to resolve our
693+various types of output into actual moves. We produce the moves we found above
694+and the `++un` core resolved with `++pish:un` (putting the modified desk in the
695+room) and `++abet:un` (putting the modified room in the raft).
738696
739697Much of this is fairly straightforward, so we'll only describe `++ease`,
740−`++eave`, and `++abet:de`. Feel free to look up the code to the other
741−steps -- it should be easy to follow.
698+`++eave`, and `++abet:de`. Feel free to look up the code to the other steps --
699+it should be easy to follow.
742700
743−Although it's called last, it's usually worth examining `++abet` first,
744−since it defines in what ways we can cause side effects. Let's do that,
745−and also a few of the lines at the beginning of `++de`.
701+Although it's called last, it's usually worth examining `++abet` first, since it
702+defines in what ways we can cause side effects. Let's do that, and also a few of
703+the lines at the beginning of `++de`.
746704
747705 =| yel=(list ,[p=duct q=gift])
748706 =| byn=(list ,[p=duct q=riot])
@@ -772,31 +730,31 @@ and also a few of the lines at the beginning of `++de`.
772730 |=([a=duct b=path c=note] [a %pass b c])
773731 ==
774732
775−This is very simple code. We see there are exactly five different kinds
776−of side effects we can generate.
733+This is very simple code. We see there are exactly five different kinds of side
734+effects we can generate.
777735
778−In `yel` we put gifts that we wish to be sent along the `hun:room` duct
779−to dill. See the documentation for `++room` above. This is how we
780−display messages to the terminal.
736+In `yel` we put gifts that we wish to be sent along the `hun:room` duct to dill.
737+See the documentation for `++room` above. This is how we display messages to the
738+terminal.
781739
782−In `byn` we put riots that we wish returned to subscribers. Recall that
783−a riot is a response to a subscription. These are returned to our
784−subscribers in the form of a `%writ` gift.
740+In `byn` we put riots that we wish returned to subscribers. Recall that a riot
741+is a response to a subscription. These are returned to our subscribers in the
742+form of a `%writ` gift.
785743
786−In `vag` we put gifts along with the ducts on which to send them. This
787−allows us to produce arbitrary gifts, but in practice this is only used
788−to produce `%ergo` gifts.
744+In `vag` we put gifts along with the ducts on which to send them. This allows us
745+to produce arbitrary gifts, but in practice this is only used to produce `%ergo`
746+gifts.
789747
790−In `say` we put messages we wish to pass to ames. These messages are
791−used to request information from clay on other piers. We must provide
792−not only the duct and the request (the riff), but also the return path,
793−the other ship to talk to, and the sequence number of the request.
748+In `say` we put messages we wish to pass to ames. These messages are used to
749+request information from clay on other piers. We must provide not only the duct
750+and the request (the riff), but also the return path, the other ship to talk to,
751+and the sequence number of the request.
794752
795−In `tag` we put arbitrary notes we wish to pass to other vanes. For now,
796−the only notes we pass here are `%wait` and `%rest` to the timer vane.
753+In `tag` we put arbitrary notes we wish to pass to other vanes. For now, the
754+only notes we pass here are `%wait` and `%rest` to the timer vane.
797755
798−Now that we know what kinds of side effects we may have, we can jump
799−into the handling of requests.
756+Now that we know what kinds of side effects we may have, we can jump into the
757+handling of requests.
800758
801759 ++ ease :: release request
802760 |= hen=duct
@@ -815,24 +773,24 @@ into the handling of requests.
815773 bom.u.ref (~(del by bom.u.ref) u.nux)
816774 ==
817775
818−This is called when we're cancelling a subscription. For domestic desks,
819−`ref` is null, so we're going to cancel any timer we might have created.
820−We first delete the duct from our map of requests, and then we call
821−`++mabe` with `++best` to send a `%rest` kiss to the timer vane if we
822−have started a timer. We'll describe `++best` and `++mabe` momentarily.
776+This is called when we're cancelling a subscription. For domestic desks, `ref`
777+is null, so we're going to cancel any timer we might have created. We first
778+delete the duct from our map of requests, and then we call `++mabe` with
779+`++best` to send a `%rest` kiss to the timer vane if we have started a timer.
780+We'll describe `++best` and `++mabe` momentarily.
823781
824−Although we said we're not going to talk about foreign requests yet,
825−it's easy to see that for foreign desks, we cancel any outstanding
826−requests for this duct and send a message over ames to the other ship
827−telling them to cancel the subscription.
782+Although we said we're not going to talk about foreign requests yet, it's easy
783+to see that for foreign desks, we cancel any outstanding requests for this duct
784+and send a message over ames to the other ship telling them to cancel the
785+subscription.
828786
829787 ++ best
830788 |= [hen=duct tym=@da]
831789 %_(+> tag :_(tag [hen /tyme %t %rest tym]))
832790
833−This simply pushes a `%rest` note onto `tag`, from where it will be
834−passed back to arvo to be handled. This cancels the timer at the given
835−duct (with the given time).
791+This simply pushes a `%rest` note onto `tag`, from where it will be passed back
792+to arvo to be handled. This cancels the timer at the given duct (with the given
793+time).
836794
837795 ++ mabe :: maybe fire function
838796 |* [rov=rove fun=$+(@da _+>.^$)]
@@ -853,15 +811,15 @@ duct (with the given time).
853811 ?.((lth now p.q.mot) [~ now] [~ p.q.mot])
854812 ==
855813
856−This decides whether the given request can only be satsified in the
857−future. In that case, we call the given function with the time in the
858−future when we expect to have an update to give to this request. This is
859−called with `++best` to cancel timers and with `++bait` to start them.
814+This decides whether the given request can only be satsified in the future. In
815+that case, we call the given function with the time in the future when we expect
816+to have an update to give to this request. This is called with `++best` to
817+cancel timers and with `++bait` to start them.
860818
861−For single requests, we have a time if the request is for a particular
862−time (which is assumed to be in the future). For ranges of requests, we
863−check both the start and end cases to see if they are time cases. If so,
864−we choose the earlier time.
819+For single requests, we have a time if the request is for a particular time
820+(which is assumed to be in the future). For ranges of requests, we check both
821+the start and end cases to see if they are time cases. If so, we choose the
822+earlier time.
865823
866824If any of those give us a time, then we call the given funciton with the
867825smallest time.
@@ -884,22 +842,22 @@ subscription but starting one.
884842 (blub hen)
885843 (blab hen p.rav u.u.ver)
886844
887−There are two types of subscriptions -- either we're requesting a single
888−file or we're requesting a range of versions of a desk. We'll dicuss the
889−simpler case first.
845+There are two types of subscriptions -- either we're requesting a single file or
846+we're requesting a range of versions of a desk. We'll dicuss the simpler case
847+first.
890848
891−First, we check that we're not requesting the `rang` from any time other
892−than the present. Since we don't store that information for any other
893−time, we can't produce it in a referentially transparent manner for any
894−time other than the present.
849+First, we check that we're not requesting the `rang` from any time other than
850+the present. Since we don't store that information for any other time, we can't
851+produce it in a referentially transparent manner for any time other than the
852+present.
895853
896−Then, we try to read the requested `mood` `p.rav`. If we can't access
897−the request data right now, we call `++duce` to put the request in our
898−queue to be satisfied when the information becomes available.
854+Then, we try to read the requested `mood` `p.rav`. If we can't access the
855+request data right now, we call `++duce` to put the request in our queue to be
856+satisfied when the information becomes available.
899857
900−This case occurs when we make a request for a case whose (1) date is
901−after the current date, (2) number is after the current number, or (3)
902−label is not yet used.
858+This case occurs when we make a request for a case whose (1) date is after the
859+current date, (2) number is after the current number, or (3) label is not yet
860+used.
903861
904862 ++ duce :: produce request
905863 |= [hen=duct rov=rove]
@@ -920,43 +878,41 @@ label is not yet used.
920878 fod.u.ref (~(put by fod.u.ref) hen inx)
921879 ==
922880
923−The code for `++duce` is nearly the exact inverse of `++ease`, which in
924−the case of a domestic desk is very simple -- we simply put the duct and
925−rave into `qyx` and possibly start a timer with `++mabe` and `++bait`.
926−Recall that `ref` is null for domestic desks and that `++mabe` fires the
927−given function with the time we need to be woken up at, if we need to be
928−woken up at a particular time.
881+The code for `++duce` is nearly the exact inverse of `++ease`, which in the case
882+of a domestic desk is very simple -- we simply put the duct and rave into `qyx`
883+and possibly start a timer with `++mabe` and `++bait`. Recall that `ref` is null
884+for domestic desks and that `++mabe` fires the given function with the time we
885+need to be woken up at, if we need to be woken up at a particular time.
929886
930887 ++ bait
931888 |= [hen=duct tym=@da]
932889 %_(+> tag :_(tag [hen /tyme %t %wait tym]))
933890
934−This sets an alarm by sending a `%wait` card with the given time to the
935−timer vane.
891+This sets an alarm by sending a `%wait` card with the given time to the timer
892+vane.
936893
937−Back in `++eave`, if `++aver` returned `[~ ~]`, then we cancel the
938−subscription. This occurs when we make (1) a `%x` request for a file
939−that does not exist, (2) a `%w` request with a case that is not a
940−number, or (3) a `%w` request with a nonempty path. The `++blub` is
941−exactly what you would expect it to be.
894+Back in `++eave`, if `++aver` returned `[~ ~]`, then we cancel the subscription.
895+This occurs when we make (1) a `%x` request for a file that does not exist, (2)
896+a `%w` request with a case that is not a number, or (3) a `%w` request with a
897+nonempty path. The `++blub` is exactly what you would expect it to be.
942898
943899 ++ blub :: ship stop
944900 |= hen=duct
945901 %_(+> byn [[hen ~] byn])
946902
947−We notify the duct that we're cancelling their subscription since it
948−isn't satisfiable.
903+We notify the duct that we're cancelling their subscription since it isn't
904+satisfiable.
949905
950−Otherwise, we have received the desired information, so we send it on to
951−the subscriber with `++blab`.
906+Otherwise, we have received the desired information, so we send it on to the
907+subscriber with `++blab`.
952908
953909 ++ blab :: ship result
954910 |= [hen=duct mun=mood dat=*]
955911 ^+ +>
956912 +>(byn [[hen ~ [p.mun q.mun syd] r.mun dat] byn])
957913
958−The most interesting arm called in `++eave` is, of course, `++aver`,
959−where we actually try to read the data.
914+The most interesting arm called in `++eave` is, of course, `++aver`, where we
915+actually try to read the data.
960916
961917 ++ aver :: read
962918 |= mun=mood
@@ -969,19 +925,19 @@ where we actually try to read the data.
969925 =+ nao=(~(case-to-aeon ze lim dom ran) q.mun)
970926 ?~(nao ~ [~ (~(read-at-aeon ze lim dom ran) u.nao mun)])
971927
972−We check immediately that we're not requesting the `rang` for any time
973−other than the present.
928+We check immediately that we're not requesting the `rang` for any time other
929+than the present.
974930
975−If this is a foreign desk, then we check our cache for the specific
976−request. If either this is a domestic desk or we don't have the request
977−in our cache, then we have to actually go read the data from our dome.
931+If this is a foreign desk, then we check our cache for the specific request. If
932+either this is a domestic desk or we don't have the request in our cache, then
933+we have to actually go read the data from our dome.
978934
979935We need to do two things. First, we try to find the number of the commit
980936specified by the given case, and then we try to get the data there.
981937
982−Here, we jump into `arvo/zuse.hoon`, which is where much of the
983−algorithmic code is stored, as opposed to the clay interface, which is
984−stored in `arvo/clay.hoon`. We examine `++case-to-aeon:ze`.
938+Here, we jump into `arvo/zuse.hoon`, which is where much of the algorithmic code
939+is stored, as opposed to the clay interface, which is stored in
940+`arvo/clay.hoon`. We examine `++case-to-aeon:ze`.
985941
986942 ++ case-to-aeon :: case-to-aeon:ze
987943 |= lok=case :: act count through
@@ -1003,22 +959,20 @@ stored in `arvo/clay.hoon`. We examine `++case-to-aeon:ze`.
1003959 %ud ?:((gth p.lok let) ~ [~ p.lok])
1004960 ==
1005961
1006−We handle each type of `case` differently. The latter two types are
1007−easy.
962+We handle each type of `case` differently. The latter two types are easy.
1008963
1009−If we're requesting a revision by label, then we simply look up the
1010−requested label in `lab` from the given dome. If it exists, that is our
1011−aeon; else we produce null, indicating the requested revision does not
1012−yet exist.
964+If we're requesting a revision by label, then we simply look up the requested
965+label in `lab` from the given dome. If it exists, that is our aeon; else we
966+produce null, indicating the requested revision does not yet exist.
1013967
1014−If we're requesting a revision by number, we check if we've yet reached
1015−that number. If so, we produce the number; else we produce null.
968+If we're requesting a revision by number, we check if we've yet reached that
969+number. If so, we produce the number; else we produce null.
1016970
1017−If we're requesting a revision by date, we check first if the date is in
1018−the future, returning null if so. Else we start from the most recent
1019−revision and scan backwards until we find the first revision committed
1020−before that date, and we produce that. If we requested a date before any
1021−revisions were committed, we produce `0`.
971+If we're requesting a revision by date, we check first if the date is in the
972+future, returning null if so. Else we start from the most recent revision and
973+scan backwards until we find the first revision committed before that date, and
974+we produce that. If we requested a date before any revisions were committed, we
975+produce `0`.
1022976
1023977The definitions of `++aeon-to-tako` and `++tako-to-yaki` are trivial.
1024978
@@ -1026,12 +980,10 @@ The definitions of `++aeon-to-tako` and `++tako-to-yaki` are trivial.
1026980
1027981 ++ tako-to-yaki ~(got by hut) :: grab yaki
1028982
1029−We simply look up the aeon or tako in their respective maps (`hit` and
1030−`hut`).
983+We simply look up the aeon or tako in their respective maps (`hit` and `hut`).
1031984
1032−Assuming we got a valid version number, `++aver` calls
1033−`++read-at-aeon:ze`, which reads the requested data at the given
1034−revision.
985+Assuming we got a valid version number, `++aver` calls `++read-at-aeon:ze`,
986+which reads the requested data at the given revision.
1035987
1036988 ++ read-at-aeon :: read-at-aeon:ze
1037989 |= [oan=aeon mun=mood] :: seek and read
@@ -1040,10 +992,10 @@ revision.
1040992 ?^(r.mun ~ [~ oan])
1041993 (read:(rewind oan) mun)
1042994
1043−If we're requesting the revision number with a case other than by
1044−number, then we go ahead and just produce the number we were given.
1045−Otherwise, we call `++rewind` to rewind our state to the given revision,
1046−and then we call `++read` to get the requested information.
995+If we're requesting the revision number with a case other than by number, then
996+we go ahead and just produce the number we were given. Otherwise, we call
997+`++rewind` to rewind our state to the given revision, and then we call `++read`
998+to get the requested information.
1047999
10481000 ++ rewind :: rewind:ze
10491001 |= oan=aeon :: rewind to aeon
@@ -1052,14 +1004,13 @@ and then we call `++read` to get the requested information.
10521004 ?: (gth oan let) !! :: don't have version
10531005 +>(ank (checkout-ankh q:(tako-to-yaki (aeon-to-tako oan))), let oan)
10541006
1055−If we're already at the requested version, we do nothing. If we're
1056−requesting a version later than our head, we are unable to comply.
1007+If we're already at the requested version, we do nothing. If we're requesting a
1008+version later than our head, we are unable to comply.
10571009
1058−Otherwise, we get the hash of the commit at the number, and from that we
1059−get the commit itself (the yaki), which has the map of path to lobe that
1060−represents a version of the filesystem. We call `++checkout-ankh` to
1061−checkout the commit, and we replace `ank` in our context with the
1062−result.
1010+Otherwise, we get the hash of the commit at the number, and from that we get the
1011+commit itself (the yaki), which has the map of path to lobe that represents a
1012+version of the filesystem. We call `++checkout-ankh` to checkout the commit, and
1013+we replace `ank` in our context with the result.
10631014
10641015 ++ checkout-ankh :: checkout-ankh:ze
10651016 |= hat=(map path lobe) :: checkout commit
@@ -1078,9 +1029,8 @@ result.
10781029 $(pat t.pat, ank (fall nak _ankh))
10791030 ==
10801031
1081−Twice we call `++cosh`, which hashes a commit, updating `p` in an
1082−`ankh`. Let's jump into that algorithm before we describe
1083−`++checkout-ankh`.
1032+Twice we call `++cosh`, which hashes a commit, updating `p` in an `ankh`. Let's
1033+jump into that algorithm before we describe `++checkout-ankh`.
10841034
10851035 ++ cosh :: locally rehash
10861036 |= ank=ankh :: NB v/unix.c
@@ -1106,33 +1056,30 @@ We simply replace `p` in the hash with the `cash` we get from a call to
11061056 $(r.ank r.r.ank, axe (peg axe 3))
11071057 ==
11081058
1109−`++zu` is a core we set up with a particular filesystem node to traverse
1110−a checkout of the filesystem and access the actual data inside it. One
1111−of the things we can do with it is to create a recursive hash of the
1112−node.
1059+`++zu` is a core we set up with a particular filesystem node to traverse a
1060+checkout of the filesystem and access the actual data inside it. One of the
1061+things we can do with it is to create a recursive hash of the node.
11131062
1114−In `++rehash`, if this node is a file, then we xor the remainder of the
1115−hash with the hash of the contents of the file. The remainder of the
1116−hash is `0` if we have no children, else we descend into our children.
1117−Basically, we do a half SHA-256 of the xor of the axis of this child and
1118−the half SHA-256 of the xor of the name of the child and the hash of the
1119−child. This is done for each child and all the results are xored
1120−together.
1063+In `++rehash`, if this node is a file, then we xor the remainder of the hash
1064+with the hash of the contents of the file. The remainder of the hash is `0` if
1065+we have no children, else we descend into our children. Basically, we do a half
1066+SHA-256 of the xor of the axis of this child and the half SHA-256 of the xor of
1067+the name of the child and the hash of the child. This is done for each child and
1068+all the results are xored together.
11211069
11221070Now we return to our discussion of `++checkout-ankh`.
11231071
1124−We fold over every path in this version of the filesystem and create a
1125−great ankh out of them. First, we call `++lobe-to-noun` to get the raw
1126−data referred to be each lobe.
1072+We fold over every path in this version of the filesystem and create a great
1073+ankh out of them. First, we call `++lobe-to-noun` to get the raw data referred
1074+to be each lobe.
11271075
11281076 ++ lobe-to-noun :: grab blob
11291077 |= p=lobe :: ^- *
11301078 %- blob-to-noun
11311079 (lobe-to-blob p)
11321080
1133−This converts a lobe into the raw data it refers to by first getting the
1134−blob with `++lobe-to-blob` and converting that into data with
1135−`++blob-to-noun`.
1081+This converts a lobe into the raw data it refers to by first getting the blob
1082+with `++lobe-to-blob` and converting that into data with `++blob-to-noun`.
11361083
11371084 ++ lobe-to-blob ~(got by lat) :: grab blob
11381085
@@ -1146,10 +1093,10 @@ This just grabs the blob that the lobe refers to.
11461093 %indirect q.p
11471094 ==
11481095
1149−If we have either a direct or an indirect blob, then the data is stored
1150−right in the blob. Otherwise, we have to reconstruct it from the diffs.
1151−We do this by calling `++lump` on the diff in the blob with the data
1152−obtained by recursively calling the parent of this blob.
1096+If we have either a direct or an indirect blob, then the data is stored right in
1097+the blob. Otherwise, we have to reconstruct it from the diffs. We do this by
1098+calling `++lump` on the diff in the blob with the data obtained by recursively
1099+calling the parent of this blob.
11531100
11541101 ++ lump :: apply patch
11551102 |= [don=udon src=*]
@@ -1171,13 +1118,12 @@ obtained by recursively calling the parent of this blob.
11711118 ==
11721119 ==
11731120
1174−This is defined in `arvo/hoon.hoon` for historical reasons which are
1175−likely no longer applicable. Since the `++umph` structure will likely
1176−change we convert clay to be a typed filesystem, we'll only give a
1177−high-level description of this process. If we have a `%a` udon, then
1178−we're performing a trivial replace, so we produce simply `q.q.don`. If
1179−we have a `%c` udon, then we're performing a list merge (as in, for
1180−example, lines of text). The merge is performed by `++lurk`.
1121+This is defined in `arvo/hoon.hoon` for historical reasons which are likely no
1122+longer applicable. Since the `++umph` structure will likely change we convert
1123+clay to be a typed filesystem, we'll only give a high-level description of this
1124+process. If we have a `%a` udon, then we're performing a trivial replace, so we
1125+produce simply `q.q.don`. If we have a `%c` udon, then we're performing a list
1126+merge (as in, for example, lines of text). The merge is performed by `++lurk`.
11811127
11821128 ++ lurk :: apply list patch
11831129 |* [hel=(list) rug=(urge)]
@@ -1204,17 +1150,16 @@ example, lines of text). The merge is performed by `++lurk`.
12041150 ==
12051151 ==
12061152
1207−We accumulate our final result in `war`. If there's nothing more in our
1208−list of merge instructions (unces), we just reverse `war` and produce
1209−it. Otherwise, we process another unce. If the unce is of type `&`, then
1210−we have `p.i.rug` lines of no changes, so we just copy them over from
1211−`hel` to `war`. If the unice is of type `|`, then we verify that the
1212−source lines (in `hel`) are what we expect them to be (`p.i.rug`),
1213−crashing on failure. If they're good, then we append the new lines in
1214−`q.i.rug` onto `war`.
1153+We accumulate our final result in `war`. If there's nothing more in our list of
1154+merge instructions (unces), we just reverse `war` and produce it. Otherwise, we
1155+process another unce. If the unce is of type `&`, then we have `p.i.rug` lines
1156+of no changes, so we just copy them over from `hel` to `war`. If the unice is of
1157+type `|`, then we verify that the source lines (in `hel`) are what we expect
1158+them to be (`p.i.rug`), crashing on failure. If they're good, then we append the
1159+new lines in `q.i.rug` onto `war`.
12151160
1216−And that's really it. List merges are pretty easy. Anyway, if you
1217−recall, we were discussing `++checkout-ankh`.
1161+And that's really it. List merges are pretty easy. Anyway, if you recall, we
1162+were discussing `++checkout-ankh`.
12181163
12191164 ++ checkout-ankh :: checkout-ankh:ze
12201165 |= hat=(map path lobe) :: checkout commit
@@ -1233,16 +1178,16 @@ recall, we were discussing `++checkout-ankh`.
12331178 $(pat t.pat, ank (fall nak _ankh))
12341179 ==
12351180
1236−If the path is null, then we calculate `zar`, the raw data at the path
1237−`pat` in this version. We produce the given ankh with the correct data.
1181+If the path is null, then we calculate `zar`, the raw data at the path `pat` in
1182+this version. We produce the given ankh with the correct data.
12381183
1239−Otherwise, we try to get the child we're looking at from our parent
1240−ankh. If it's already been created, this succeeds; otherwise, we simply
1241−create a default blank ankh. We place ourselves in our parent after
1242−recursively computing our children.
1184+Otherwise, we try to get the child we're looking at from our parent ankh. If
1185+it's already been created, this succeeds; otherwise, we simply create a default
1186+blank ankh. We place ourselves in our parent after recursively computing our
1187+children.
12431188
1244−This algorithm really isn't that complicated, but it may not be
1245−immediately obvious why it works. An example should clear everything up.
1189+This algorithm really isn't that complicated, but it may not be immediately
1190+obvious why it works. An example should clear everything up.
12461191
12471192Suppose `hat` is a map of the following information.
12481193
@@ -1262,63 +1207,60 @@ Furthermore, let's say that we process them in this order:
12621207 /greeting/spanish
12631208 /farewell/russian
12641209
1265−Then, the first path we process is `/greeting/english` . Since our path
1266−is not null, we try to get `nak`, but because our ankh is blank at this
1267−point it doesn't find anything. Thus, update our blank top-level ankh
1268−with a child `%greeting`. and recurse with the blank `nak` to create the
1269−ankh of the new child.
1270−
1271−In the recursion, we our path is `/english` and our ankh is again blank.
1272−We try to get the `english` child of our ankh, but this of course fails.
1273−Thus, we update our blank `/greeting` ankh with a child `english`
1274−produced by recursing.
1275−
1276−Now our path is null, so we call `++lobe-to-noun` to get the actual
1277−data, and we place it in the brand-new ankh.
1278−
1279−Next, we process `/greeting/russian/short`. Since our path is not null,
1280−we try to get the child named `%greeting`, which does exist since we
1281−created it earlier. We put modify this child by recursing on it. Our
1282−path is now `/russian/short`, so we look for a `%russian` child in our
1283−`/greeting` ankh. This doesn't exist, so we add it by recursing. Our
1284−path is now `/short`, so we look for a `%short` child in our
1285−`/greeting/russian` ankh. This doesn't exist, so we add it by recursing.
1286−Now our path is null, so we set the contents of this node to `"привет"`,
1287−and we're done processing this path.
1288−
1289−Next, we process `/greeting/russian/long`. This proceeds similarly to
1290−the previous except that now the ankh for `/greeting/russian` already
1291−exists, so we simply reuse it rather than creating a new one. Of course,
1292−we still must create a new `/greeting/russian/long` ankh.
1293−
1294−Next, we process `/greeting`. This ankh already exists, so after we've
1295−recursed once, our path is null, and our ankh is not blank -- it already
1296−has two children (and two grandchildren). We don't touch those, though,
1297−since a node may be both a file and a directory. We just add the
1298−contents of the file -- "customary upon meeting" -- to the existing
1299−ankh.
1300−
1301−Next, we process `/greeting/spanish`. Of course, the `/greeting` ankh
1302−already exists, but it doesn't have a `%spanish` child, so we create
1303−that, taking care not to disturb the contents of the `/greeting` file.
1304−We put "hola" into the ankh and call it good.
1305−
1306−Finally, we process `/farewell/russian`. Here, the `/farewell` ankh
1307−doesn't exist, so we create it. Clearly the newly-created ankh doesn't
1308−have any children, so we have to add a `%russian` child, and in this
1309−child we put our last content -- "до свидания".
1310−
1311−We hope it's fairly obvious that the order we process the paths doesn't
1312−affect the final ankh tree. The tree will be constructed in a very
1313−different order depending on what order the paths come in, but the
1314−resulting tree is independent of order.
1315−
1316−At any rate, we were talking about something important, weren't we? If
1317−you recall, that concludes our discussion of `++rewind`, which was
1318−called from `++read-at-aeon`. In summary, `++rewind` returns a context
1319−in which our current state is (very nearly) as it was when the specified
1320−version of the desk was the head. This allows `++read-at-aeon` to call
1321−`++read` to read the requested information.
1210+Then, the first path we process is `/greeting/english` . Since our path is not
1211+null, we try to get `nak`, but because our ankh is blank at this point it
1212+doesn't find anything. Thus, update our blank top-level ankh with a child
1213+`%greeting`. and recurse with the blank `nak` to create the ankh of the new
1214+child.
1215+
1216+In the recursion, we our path is `/english` and our ankh is again blank. We try
1217+to get the `english` child of our ankh, but this of course fails. Thus, we
1218+update our blank `/greeting` ankh with a child `english` produced by recursing.
1219+
1220+Now our path is null, so we call `++lobe-to-noun` to get the actual data, and we
1221+place it in the brand-new ankh.
1222+
1223+Next, we process `/greeting/russian/short`. Since our path is not null, we try
1224+to get the child named `%greeting`, which does exist since we created it
1225+earlier. We put modify this child by recursing on it. Our path is now
1226+`/russian/short`, so we look for a `%russian` child in our `/greeting` ankh.
1227+This doesn't exist, so we add it by recursing. Our path is now `/short`, so we
1228+look for a `%short` child in our `/greeting/russian` ankh. This doesn't exist,
1229+so we add it by recursing. Now our path is null, so we set the contents of this
1230+node to `"привет"`, and we're done processing this path.
1231+
1232+Next, we process `/greeting/russian/long`. This proceeds similarly to the
1233+previous except that now the ankh for `/greeting/russian` already exists, so we
1234+simply reuse it rather than creating a new one. Of course, we still must create
1235+a new `/greeting/russian/long` ankh.
1236+
1237+Next, we process `/greeting`. This ankh already exists, so after we've recursed
1238+once, our path is null, and our ankh is not blank -- it already has two children
1239+(and two grandchildren). We don't touch those, though, since a node may be both
1240+a file and a directory. We just add the contents of the file -- "customary upon
1241+meeting" -- to the existing ankh.
1242+
1243+Next, we process `/greeting/spanish`. Of course, the `/greeting` ankh already
1244+exists, but it doesn't have a `%spanish` child, so we create that, taking care
1245+not to disturb the contents of the `/greeting` file. We put "hola" into the ankh
1246+and call it good.
1247+
1248+Finally, we process `/farewell/russian`. Here, the `/farewell` ankh doesn't
1249+exist, so we create it. Clearly the newly-created ankh doesn't have any
1250+children, so we have to add a `%russian` child, and in this child we put our
1251+last content -- "до свидания".
1252+
1253+We hope it's fairly obvious that the order we process the paths doesn't affect
1254+the final ankh tree. The tree will be constructed in a very different order
1255+depending on what order the paths come in, but the resulting tree is independent
1256+of order.
1257+
1258+At any rate, we were talking about something important, weren't we? If you
1259+recall, that concludes our discussion of `++rewind`, which was called from
1260+`++read-at-aeon`. In summary, `++rewind` returns a context in which our current
1261+state is (very nearly) as it was when the specified version of the desk was the
1262+head. This allows `++read-at-aeon` to call `++read` to read the requested
1263+information.
13221264
13231265 ++ read :: read:ze
13241266 |= mun=mood :: read at point
@@ -1338,14 +1280,13 @@ version of the desk was the head. This allows `++read-at-aeon` to call
13381280
13391281If we're requesting the dome, then we just return that immediately.
13401282
1341−If we're requesting the revision number of the desk and we're not
1342−requesting it by number, then we just return the current number of this
1343−desk. Note of course that this was really already handled in
1344−`++read-at-aeon`.
1283+If we're requesting the revision number of the desk and we're not requesting it
1284+by number, then we just return the current number of this desk. Note of course
1285+that this was really already handled in `++read-at-aeon`.
13451286
1346−If we're requesting a `%w` with a specific revision number, then we do
1347−something or other with the commit there. It's kind of weird, and it
1348−doesn't seem to work, so we'll ignore this case.
1287+If we're requesting a `%w` with a specific revision number, then we do something
1288+or other with the commit there. It's kind of weird, and it doesn't seem to work,
1289+so we'll ignore this case.
13491290
13501291Otherwise, we descend into the ankh tree to the given path with
13511292`++descend-path:zu`, and then we handle specific request in `++query`.
@@ -1355,8 +1296,8 @@ Otherwise, we descend into the ankh tree to the given path with
13551296 ^+ +>
13561297 ?~(way +> $(way t.way, +> (descend i.way)))
13571298
1358−This is simple recursion down into the ankh tree. `++descend` descends
1359−one level, so this will eventually get us down to the path we want.
1299+This is simple recursion down into the ankh tree. `++descend` descends one
1300+level, so this will eventually get us down to the path we want.
13601301
13611302 ++ descend :: descend
13621303 |= lol=@ta
@@ -1364,12 +1305,12 @@ one level, so this will eventually get us down to the path we want.
13641305 =+ you=(~(get by r.ank) lol)
13651306 +>.$(ram [lol ram], ank ?~(you [*cash ~ ~] u.you))
13661307
1367−`ram` is the path that we're at, so to descend one level we push the
1368−name of this level onto that path. We update the ankh with the correct
1369−one at that path if it exists; else we create a blank one.
1308+`ram` is the path that we're at, so to descend one level we push the name of
1309+this level onto that path. We update the ankh with the correct one at that path
1310+if it exists; else we create a blank one.
13701311
1371−Once we've decscended to the correct level, we need to actually deal
1372−with the request.
1312+Once we've decscended to the correct level, we need to actually deal with the
1313+request.
13731314
13741315 ++ query :: query:ze
13751316 |= ren=?(%u %v %x %y %z) :: endpoint query
@@ -1382,10 +1323,9 @@ with the request.
13821323 %z [~ ank]
13831324 ==
13841325
1385−Now that everything's set up, it's really easy. If they're requesting
1386−the rang, dome, or ankh, we give it to them. If the contents of a file,
1387−we give it to them if it is in fact a file. If the `arch`, then we
1388−calculate it with `++as-arch`.
1326+Now that everything's set up, it's really easy. If they're requesting the rang,
1327+dome, or ankh, we give it to them. If the contents of a file, we give it to them
1328+if it is in fact a file. If the `arch`, then we calculate it with `++as-arch`.
13891329
13901330 ++ as-arch :: as-arch:ze
13911331 ^- arch :: arch report
@@ -1395,17 +1335,16 @@ calculate it with `++as-arch`.
13951335 ?~ r.ank ~
13961336 [[p.n.r.ank ~] $(r.ank l.r.ank) $(r.ank r.r.ank)]
13971337
1398−This very simply strips out all the "real" data and returns just our own
1399−hash, the hash of the file contents (if we're a file), and a map of the
1400−names of our immediate children.
1338+This very simply strips out all the "real" data and returns just our own hash,
1339+the hash of the file contents (if we're a file), and a map of the names of our
1340+immediate children.
14011341
1402−Lifecycle of a Local Subscription
1403−---------------------------------
1342+## Lifecycle of a Local Subscription
14041343
1405−A subscription to a range of revisions of a desk initially follows the
1406−same path that a single read does. In `++aver`, we checked the head of
1407−the given rave. If the head was `&`, then it was a single request, so we
1408−handled it above. If `|`, then we handle it with the following code.
1344+A subscription to a range of revisions of a desk initially follows the same path
1345+that a single read does. In `++aver`, we checked the head of the given rave. If
1346+the head was `&`, then it was a single request, so we handled it above. If `|`,
1347+then we handle it with the following code.
14091348
14101349 =+ nab=(~(case-to-aeon ze lim dom ran) p.p.rav)
14111350 ?~ nab
@@ -1429,51 +1368,46 @@ handled it above. If `|`, then we handle it with the following code.
14291368 ==
14301369
14311370Recall that `++case-to-aeon:ze` produces the revision number that a case
1432−corresponds to, if it corresponds to any. If it doesn't yet correspond
1433−to a revision, then it produces null.
1434−
1435−Thus, we first check to see if we've even gotten to the beginning of the
1436−range of revisions requested. If not, then we assert that we haven't yet
1437−gotten to the end of the range either, because that would be really
1438−strange. If not, then we immediately call `++duce`, which, if you
1439−recall, for a local request, simply puts this duct and rove into our
1440−cult `qyx`, so that we know who to respond to when the revision does
1441−appear.
1442−
1443−If we've already gotten to the first revision, then we can produce some
1444−content immediately. If we've also gotten to the final revision, and
1445−that revision is earlier than the start revision, then it's a bad
1446−request and we call `++blub`, which tells the subscriber that his
1447−subscription will not be satisfied.
1371+corresponds to, if it corresponds to any. If it doesn't yet correspond to a
1372+revision, then it produces null.
1373+
1374+Thus, we first check to see if we've even gotten to the beginning of the range
1375+of revisions requested. If not, then we assert that we haven't yet gotten to the
1376+end of the range either, because that would be really strange. If not, then we
1377+immediately call `++duce`, which, if you recall, for a local request, simply
1378+puts this duct and rove into our cult `qyx`, so that we know who to respond to
1379+when the revision does appear.
1380+
1381+If we've already gotten to the first revision, then we can produce some content
1382+immediately. If we've also gotten to the final revision, and that revision is
1383+earlier than the start revision, then it's a bad request and we call `++blub`,
1384+which tells the subscriber that his subscription will not be satisfied.
14481385
14491386Otherwise, we find the data at the given path at the beginning of the
1450−subscription and at the last available revision in the subscription. If
1451−they're the same, then we don't send a notification. Otherwise, we call
1452−`++gack`, which creates the `++nako` we need to produce. We call
1453−`++bleb` to actually produce the information.
1387+subscription and at the last available revision in the subscription. If they're
1388+the same, then we don't send a notification. Otherwise, we call `++gack`, which
1389+creates the `++nako` we need to produce. We call `++bleb` to actually produce
1390+the information.
14541391
1455−If we already have the last requested revision, then we also tell the
1456−subscriber with `++blub` that the subscription will receive no further
1457−updates.
1392+If we already have the last requested revision, then we also tell the subscriber
1393+with `++blub` that the subscription will receive no further updates.
14581394
1459−If there will be more revisions in the subscription, then we call
1460−`++duce`, adding the duct to our subscribers. We modify the rove to
1461−start at the next revision since we've already handled all the revisions
1462−up to the present.
1395+If there will be more revisions in the subscription, then we call `++duce`,
1396+adding the duct to our subscribers. We modify the rove to start at the next
1397+revision since we've already handled all the revisions up to the present.
14631398
1464−We glossed over the calls to `++lobes-at-path`, `++make-nako`, and
1465−`++bleb`, so we'll get back to those right now. `++bleb` is simple, so
1466−we'll start with that.
1399+We glossed over the calls to `++lobes-at-path`, `++make-nako`, and `++bleb`, so
1400+we'll get back to those right now. `++bleb` is simple, so we'll start with that.
14671401
14681402 ++ bleb :: ship sequence
14691403 |= [hen=duct ins=@ud hip=nako]
14701404 ^+ +>
14711405 (blab hen [%w [%ud ins] ~] hip)
14721406
1473−We're given a duct, the beginning revision number, and the nako that
1474−contains the updates since that revision. We use `++blab` to produce
1475−this result to the subscriber. The case is `%w` with a revision number
1476−of the beginning of the subscription, and the data is the nako itself.
1407+We're given a duct, the beginning revision number, and the nako that contains
1408+the updates since that revision. We use `++blab` to produce this result to the
1409+subscriber. The case is `%w` with a revision number of the beginning of the
1410+subscription, and the data is the nako itself.
14771411
14781412We call `++lobes-at-path:ze` to get the data at the particular path.
14791413
@@ -1496,15 +1430,14 @@ We call `++lobes-at-path:ze` to get the data at the particular path.
14961430 $(p +.p, pax +.pax)
14971431 == ==
14981432
1499−At revision zero, the theoretical common revision between all
1500−repositories, there is no data, so we produce null.
1433+At revision zero, the theoretical common revision between all repositories,
1434+there is no data, so we produce null.
15011435
1502−We get the list of paths (paired with their lobe) in the revision
1503−referred to by the given number and we keep only those paths which begin
1504−with `pax`. Converting to a map, we now have a map from the subpaths at
1505−the given path to the hash of their data. This is simple and efficient
1506−to calculate and compare to later revisions. This allows us to easily
1507−tell if a node or its children have changed.
1436+We get the list of paths (paired with their lobe) in the revision referred to by
1437+the given number and we keep only those paths which begin with `pax`. Converting
1438+to a map, we now have a map from the subpaths at the given path to the hash of
1439+their data. This is simple and efficient to calculate and compare to later
1440+revisions. This allows us to easily tell if a node or its children have changed.
15081441
15091442Finally, we will describe `++make-nako:ze`.
15101443
@@ -1521,19 +1454,17 @@ Finally, we will describe `++make-nako:ze`.
15211454 |= [p=aeon *]
15221455 &((gth p a) (lte p b))
15231456
1524−We need to produce four things -- the numbers of the new commits, the
1525−number of the latest commit, the new commits themselves, and the new
1526−data itself.
1457+We need to produce four things -- the numbers of the new commits, the number of
1458+the latest commit, the new commits themselves, and the new data itself.
15271459
1528−The first is fairly easy to produce. We simply go over our map of
1529−numbered commits and produce all those numbered greater than `a` and not
1530−greater than `b`.
1460+The first is fairly easy to produce. We simply go over our map of numbered
1461+commits and produce all those numbered greater than `a` and not greater than
1462+`b`.
15311463
1532−The second is even easier to produce -- `b` is clearly our most recent
1533−commit.
1464+The second is even easier to produce -- `b` is clearly our most recent commit.
15341465
1535−The third and fourth are slightly more interesting, though not too
1536−terribly difficult. First, we call `++reachable-between-takos`.
1466+The third and fourth are slightly more interesting, though not too terribly
1467+difficult. First, we call `++reachable-between-takos`.
15371468
15381469 ++ reachable-between-takos
15391470 |= [a=(unit tako) b=tako] :: pack a through b
@@ -1557,12 +1488,12 @@ terribly difficult. First, we call `++reachable-between-takos`.
15571488 %- ~(uni in bar)
15581489 ^$(yak (tako-to-yaki yek))
15591490
1560−We take a possible starting commit and a definite ending commit, and we
1561−produce the set of commits and the set of data between them.
1491+We take a possible starting commit and a definite ending commit, and we produce
1492+the set of commits and the set of data between them.
15621493
1563−We let `sar` be the set of commits reachable from `a`. If `a` is null,
1564−then obviously no commits are reachable. Otherwise, we call
1565−`++reachable-takos` to calculate this.
1494+We let `sar` be the set of commits reachable from `a`. If `a` is null, then
1495+obviously no commits are reachable. Otherwise, we call `++reachable-takos` to
1496+calculate this.
15661497
15671498 ++ reachable-takos :: reachable
15681499 |= p=tako :: XX slow
@@ -1575,17 +1506,16 @@ then obviously no commits are reachable. Otherwise, we call
15751506 s :: hence skip
15761507 (~(uni in s) ^$(p q)) :: otherwise traverse
15771508
1578−We very simply produce the set of the given tako plus its parents,
1579−recursively.
1509+We very simply produce the set of the given tako plus its parents, recursively.
15801510
1581−Back in `++reachable-between-takos`, we let `yak` be the yaki of `b`,
1582−the ending commit. With this, we create a set that is the union of `sar`
1583−and all takos reachable from `b`.
1511+Back in `++reachable-between-takos`, we let `yak` be the yaki of `b`, the ending
1512+commit. With this, we create a set that is the union of `sar` and all takos
1513+reachable from `b`.
15841514
1585−We pass `sar` into `++new-lobes` to get all the lobes referenced by any
1586−tako referenced by `a`. The result is passed into `++new-lobes-takos` to
1587−do the same, but not recomputing those in already calculated last
1588−sentence. This produces the sets of takos and lobes we need.
1515+We pass `sar` into `++new-lobes` to get all the lobes referenced by any tako
1516+referenced by `a`. The result is passed into `++new-lobes-takos` to do the same,
1517+but not recomputing those in already calculated last sentence. This produces the
1518+sets of takos and lobes we need.
15891519
15901520 ++ new-lobes :: object hash set
15911521 |= [b=(set lobe) a=(set tako)] :: that aren't in b
@@ -1606,37 +1536,34 @@ sentence. This produces the sets of takos and lobes we need.
16061536 %indirect (~(put in $(lob s.gar)) lob)
16071537 ==
16081538
1609−Here, we're creating a set of lobes referenced in a commit in `a`. We
1610−start out with `b` as the initial set of lobes, so we don't need to
1611−recompute any of the lobes referenced in there.
1539+Here, we're creating a set of lobes referenced in a commit in `a`. We start out
1540+with `b` as the initial set of lobes, so we don't need to recompute any of the
1541+lobes referenced in there.
16121542
1613−The algorithm is pretty simple, so we won't bore you with the details.
1614−We simply traverse every commit in `a`, looking at every blob referenced
1615−there, and, if it's not already in `b`, we add it to `b`. In the case of
1616−a direct blob, we're done. For a delta or an indirect blob, we
1617−recursively add every blob referenced within the blob.
1543+The algorithm is pretty simple, so we won't bore you with the details. We simply
1544+traverse every commit in `a`, looking at every blob referenced there, and, if
1545+it's not already in `b`, we add it to `b`. In the case of a direct blob, we're
1546+done. For a delta or an indirect blob, we recursively add every blob referenced
1547+within the blob.
16181548
16191549 ++ new-lobes-takos :: garg & repack
16201550 |= [b=(set lobe) a=(set tako)]
16211551 ^- [(set tako) (set lobe)]
16221552 [a (new-lobes b a)]
16231553
1624−Here, we just update the set of lobes we're given with the commits we're
1625−given and produce both sets.
1554+Here, we just update the set of lobes we're given with the commits we're given
1555+and produce both sets.
16261556
16271557This concludes our discussion of a local subscription.
16281558
1629−Lifecycle of a Foreign Read or Subscription
1630−-------------------------------------------
1559+## Lifecycle of a Foreign Read or Subscription
16311560
1632−Foreign reads and subscriptions are handled in much the same way as
1633−local ones. The interface is the same -- a vane or app sends a `%warp`
1634−kiss with the request. The difference is simply that the `sock` refers
1635−to the foreign ship.
1561+Foreign reads and subscriptions are handled in much the same way as local ones.
1562+The interface is the same -- a vane or app sends a `%warp` kiss with the
1563+request. The difference is simply that the `sock` refers to the foreign ship.
16361564
1637−Thus, we start in the same place -- in `++call`, handling `%warp`.
1638−However, since the two side of the `sock` are different, we follow a
1639−different path.
1565+Thus, we start in the same place -- in `++call`, handling `%warp`. However,
1566+since the two side of the `sock` are different, we follow a different path.
16401567
16411568 =+ wex=(do now p.q.hic p.q.q.hic ruf)
16421569 =+ ^= woo
@@ -1645,14 +1572,13 @@ different path.
16451572 abet:(eave:wex hen u.q.q.q.hic)
16461573 [-.woo (posh q.p.q.hic p.q.q.hic +.woo ruf)]
16471574
1648−If we compare this to how the local case was handled, we see that it's
1649−not all that different. We use `++do` rather than `++un` and `++de` to
1650−set up the core for the foreign ship. This gives us a `++de` core, so we
1651−either cancel or begin the request by calling `++ease` or `++eave`,
1652−exactly as in the local case. In either case, we call `++abet:de` to
1653−resolve our various types of output into actual moves, as described in
1654−the local case. Finally, we call `++posh` to update our raft, putting
1655−the modified rung into the raft.
1575+If we compare this to how the local case was handled, we see that it's not all
1576+that different. We use `++do` rather than `++un` and `++de` to set up the core
1577+for the foreign ship. This gives us a `++de` core, so we either cancel or begin
1578+the request by calling `++ease` or `++eave`, exactly as in the local case. In
1579+either case, we call `++abet:de` to resolve our various types of output into
1580+actual moves, as described in the local case. Finally, we call `++posh` to
1581+update our raft, putting the modified rung into the raft.
16561582
16571583We'll first trace through `++do`.
16581584
@@ -1666,17 +1592,16 @@ We'll first trace through `++do`.
16661592 ?^(yit u.yit `rede`[~2000.1.1 ~ [~ *rind] *dome])
16671593 ((de now ~ ~) [who him] syd red ran.ruf)
16681594
1669−If we already have a rung for this foreign ship, then we use that.
1670−Otherwise, we create a new blank one. If we already have a rede in this
1671−rung, then we use that, otherwise we create a blank one. An important
1672−point to note here is that we let `ref` in the rede be `[~ *rind]`.
1673−Recall, for domestic desks `ref` is null. We use this to distinguish
1674−between foreign and domestic desks in `++de`.
1595+If we already have a rung for this foreign ship, then we use that. Otherwise, we
1596+create a new blank one. If we already have a rede in this rung, then we use
1597+that, otherwise we create a blank one. An important point to note here is that
1598+we let `ref` in the rede be `[~ *rind]`. Recall, for domestic desks `ref` is
1599+null. We use this to distinguish between foreign and domestic desks in `++de`.
16751600
16761601With this information, we create a `++de` core as usual.
16771602
1678−Although we've already covered `++ease` and `++eave`, we'll go through
1679−them quickly again, highlighting the case of foreign request.
1603+Although we've already covered `++ease` and `++eave`, we'll go through them
1604+quickly again, highlighting the case of foreign request.
16801605
16811606 ++ ease :: release request
16821607 |= hen=duct
@@ -1695,20 +1620,19 @@ them quickly again, highlighting the case of foreign request.
16951620 bom.u.ref (~(del by bom.u.ref) u.nux)
16961621 ==
16971622
1698−Here, we still remove the duct from our cult (we maintain a cult even
1699−for foreign desks), but we also need to tell the foreign desk to cancel
1700−our subscription. We do this by sending a request (by appending to
1701−`say`, which gets resolved in `++abet:de` to a `%want` kiss to ames) to
1702−the foreign ship to cancel the subscription. Since we don't anymore
1703−expect a response on this duct, we remove it from `fod` and `bom`, which
1704−are the maps between ducts, raves, and request sequence numbers.
1705−Basically, we remove every trace of the subscription from our request
1706−manager.
1707−
1708−In the case of `++eave`, where we're creating a new request, everything
1709−is exactly identical to the case of the local request except `++duce`.
1710−We said that `++duce` simply puts the request into our cult. This is
1711−true for a domestic request, but distinctly untrue for foreign requests.
1623+Here, we still remove the duct from our cult (we maintain a cult even for
1624+foreign desks), but we also need to tell the foreign desk to cancel our
1625+subscription. We do this by sending a request (by appending to `say`, which gets
1626+resolved in `++abet:de` to a `%want` kiss to ames) to the foreign ship to cancel
1627+the subscription. Since we don't anymore expect a response on this duct, we
1628+remove it from `fod` and `bom`, which are the maps between ducts, raves, and
1629+request sequence numbers. Basically, we remove every trace of the subscription
1630+from our request manager.
1631+
1632+In the case of `++eave`, where we're creating a new request, everything is
1633+exactly identical to the case of the local request except `++duce`. We said that
1634+`++duce` simply puts the request into our cult. This is true for a domestic
1635+request, but distinctly untrue for foreign requests.
17121636
17131637 ++ duce :: produce request
17141638 |= [hen=duct rov=rove]
@@ -1728,22 +1652,21 @@ true for a domestic request, but distinctly untrue for foreign requests.
17281652 fod.u.ref (~(put by fod.u.ref) hen inx)
17291653 ==
17301654
1731−If we have a request manager (i.e. this is a foreign desk), then we do
1732−the approximate inverse of `++ease`. We create a rave out of the given
1733−request and send it off to the foreign desk by putting it in `say`. Note
1734−that the rave is created to request the information starting at the next
1735−revision number. Since this is a new request, we put it into `fod` and
1736−`bom` to associate the request with its duct and its sequence number.
1737−Since we're using another sequence number, we must increment `nix`,
1738−which represents the next available sequence number.
1655+If we have a request manager (i.e. this is a foreign desk), then we do the
1656+approximate inverse of `++ease`. We create a rave out of the given request and
1657+send it off to the foreign desk by putting it in `say`. Note that the rave is
1658+created to request the information starting at the next revision number. Since
1659+this is a new request, we put it into `fod` and `bom` to associate the request
1660+with its duct and its sequence number. Since we're using another sequence
1661+number, we must increment `nix`, which represents the next available sequence
1662+number.
17391663
17401664And that's really it for this side of the request. Requesting foreign
1741−information isn't that hard. Let's see what it looks like on the other
1742−side. When we get a request from another ship for information on our
1743−ship, that comes to us in the form of a `%wart` from ames.
1665+information isn't that hard. Let's see what it looks like on the other side.
1666+When we get a request from another ship for information on our ship, that comes
1667+to us in the form of a `%wart` from ames.
17441668
1745−We handle a `%wart` in `++call`, right next to where we handle the
1746−`%warp` case.
1669+We handle a `%wart` in `++call`, right next to where we handle the `%warp` case.
17471670
17481671 %wart
17491672 ?> ?=(%re q.q.hic)
@@ -1755,11 +1678,11 @@ We handle a `%wart` in `++call`, right next to where we handle the
17551678 [%warp [p.p.q.hic p.p.q.hic] ryf]
17561679 ==
17571680
1758−Every request we receive should be of type `riff`, so we coerce it into
1759−that type. We just convert this into a new `%warp` kiss that we pass to
1760−ourself. This gets handled like normal, as a local request. When the
1761−request produces a value, it does so like normal as a `%writ`, which is
1762−returned to `++take` along the path we just sent it on.
1681+Every request we receive should be of type `riff`, so we coerce it into that
1682+type. We just convert this into a new `%warp` kiss that we pass to ourself. This
1683+gets handled like normal, as a local request. When the request produces a value,
1684+it does so like normal as a `%writ`, which is returned to `++take` along the
1685+path we just sent it on.
17631686
17641687 %writ
17651688 ?> ?=([@ @ *] tea)
@@ -1770,12 +1693,12 @@ returned to `++take` along the path we just sent it on.
17701693 [%pass ~ %a [%want [our him] [%r %re %c t.t.tea] p.+.q.hin]]
17711694 ==
17721695
1773−Since we encoded the ship we need to respond to in the path, we can just
1774−pass our `%want` back to ames, so that we tell the requesting ship about
1775−the new data.
1696+Since we encoded the ship we need to respond to in the path, we can just pass
1697+our `%want` back to ames, so that we tell the requesting ship about the new
1698+data.
17761699
1777−This comes back to the original ship as a `%waft` from ames, which comes
1778−into `++take`, right next to where we handled `%writ`.
1700+This comes back to the original ship as a `%waft` from ames, which comes into
1701+`++take`, right next to where we handled `%writ`.
17791702
17801703 %waft
17811704 ?> ?=([@ @ ~] tea)
@@ -1789,11 +1712,10 @@ into `++take`, right next to where we handled `%writ`.
17891712 [-.zot (posh q.p.+.q.hin syd +.zot ruf)]
17901713 [mos ..^$(ran.ruf ran.zat)] :: merge in new obj
17911714
1792−This gets the desk and sequence number from the path the request was
1793−sent over. This determines exactly which request is being responded to.
1794−We call `++knit:de` to apply the changes to our local desk, and we call
1795−`++wake` to update our subscribers. Then we call `++abet:de` and
1796−`++posh` as normal (like in `++eave`).
1715+This gets the desk and sequence number from the path the request was sent over.
1716+This determines exactly which request is being responded to. We call `++knit:de`
1717+to apply the changes to our local desk, and we call `++wake` to update our
1718+subscribers. Then we call `++abet:de` and `++posh` as normal (like in `++eave`).
17971719
17981720We'll examine `++knit` and `++wake`, in that order.
17991721
@@ -1836,36 +1758,33 @@ We'll examine `++knit` and `++wake`, in that order.
18361758
18371759This is kind of a long gate, but don't worry, it's not bad at all.
18381760
1839−First, we assert that we're not a domestic desk. That wouldn't make any
1840−sense at all.
1841−
1842−Since we have the sequence number of the request, we can get the duct
1843−and rave from `bom` in our request manager. If we didn't actually
1844−request this data (or the request was canceled before we got it), then
1845−we do nothing.
1846−
1847−Else, we remove the request from `bom` and `fod` unless this was a
1848−subscription request and we didn't receive a null riot (which would
1849−indicate the last message on the subscription).
1850−
1851−Now, if we received a null riot, then if this was a subscription request
1852−by date, then we update `lim` in our request manager (representing the
1853−latest time at which we have complete information for this desk) to the
1854−date that was requested. If this was a single read request, then we put
1855−the result in our simple cache `haw` to make future requests faster.
1856−Then we're done.
1857−
1858−If we received actual data, then we put it into our cache `haw`. Unless
1859−it's a `%w` request, we're done.
1860−
1861−If it is a `%w` request, then we try to get the `%w` at our current head
1862−from the cache. In general, that should be the thing we just put in a
1863−moment ago, but that is not guaranteed. The most common case where this
1864−is different is when we receive desk updates out of order. At any rate,
1865−since we now have new information, we need to apply it to our local copy
1866−of the desk. We do so in `++edis`, and then we remove the stuff we just
1867−applied from the cache, since it's not really a true "single read", like
1868−what should really be in the cache.
1761+First, we assert that we're not a domestic desk. That wouldn't make any sense at
1762+all.
1763+
1764+Since we have the sequence number of the request, we can get the duct and rave
1765+from `bom` in our request manager. If we didn't actually request this data (or
1766+the request was canceled before we got it), then we do nothing.
1767+
1768+Else, we remove the request from `bom` and `fod` unless this was a subscription
1769+request and we didn't receive a null riot (which would indicate the last message
1770+on the subscription).
1771+
1772+Now, if we received a null riot, then if this was a subscription request by
1773+date, then we update `lim` in our request manager (representing the latest time
1774+at which we have complete information for this desk) to the date that was
1775+requested. If this was a single read request, then we put the result in our
1776+simple cache `haw` to make future requests faster. Then we're done.
1777+
1778+If we received actual data, then we put it into our cache `haw`. Unless it's a
1779+`%w` request, we're done.
1780+
1781+If it is a `%w` request, then we try to get the `%w` at our current head from
1782+the cache. In general, that should be the thing we just put in a moment ago, but
1783+that is not guaranteed. The most common case where this is different is when we
1784+receive desk updates out of order. At any rate, since we now have new
1785+information, we need to apply it to our local copy of the desk. We do so in
1786+`++edis`, and then we remove the stuff we just applied from the cache, since
1787+it's not really a true "single read", like what should really be in the cache.
18691788
18701789 ++ edis :: apply subscription
18711790 |= nak=nako
@@ -1884,21 +1803,21 @@ what should really be in the cache.
18841803 %+ ~(put by yeb) r.sar sar
18851804 ==
18861805
1887−This shows, of course, exactly why nako is defined the way it is. To
1888−become completely up to date with the foreign desk, we need to merge
1889−`hit` with the foreign one so that we have all the revision numbers. We
1890−update `let` so that we know which revision is the head.
1806+This shows, of course, exactly why nako is defined the way it is. To become
1807+completely up to date with the foreign desk, we need to merge `hit` with the
1808+foreign one so that we have all the revision numbers. We update `let` so that we
1809+know which revision is the head.
18911810
1892−We merge the new blobs in `lat`, keying them by their hash, which we get
1893−from a call to `++blob-to-lobe`. Recall that the hash is stored in the
1894−actual blob itself. We do the same thing to the new yakis, putting them
1895−in `hut`, keyed by their hash.
1811+We merge the new blobs in `lat`, keying them by their hash, which we get from a
1812+call to `++blob-to-lobe`. Recall that the hash is stored in the actual blob
1813+itself. We do the same thing to the new yakis, putting them in `hut`, keyed by
1814+their hash.
18961815
18971816Now, our local dome should be exactly the same as the foreign one.
18981817
1899−This concludes our discussion of `++knit`. Now the changes have been
1900−applied to our local copy of the desk, and we just need to update our
1901−subscribers. We do so in `++wake:de`.
1818+This concludes our discussion of `++knit`. Now the changes have been applied to
1819+our local copy of the desk, and we just need to update our subscribers. We do so
1820+in `++wake:de`.
19021821
19031822 ++ wake :: update subscribers
19041823 ^+ .
@@ -1949,27 +1868,24 @@ subscribers. We do so in `++wake:de`.
19491868 ==
19501869 --
19511870
1952−This is even longer than `++knit`, but it's pretty similar to `++eave`.
1953−We loop through each of our subscribers `xiq`, processing each in turn.
1954−When we're done, we just put the remaining subscribers back in our
1955−subscriber list.
1956−
1957−If the subscriber is a single read, then, if this is a foreign desk
1958−(note that `++wake` is called from other arms, and not only on foreign
1959−desks). Obviously, if we find an identical request there, then we can
1960−produce the result immediately. Referential transparency for the win. We
1961−produce the result with a call to `++blab`. If this is a foreign desk
1962−but the result is not in the cache, then we produce `++blub` (canceled
1963−subscription with no data) for reasons entirely opaque to me. Seriously,
1964−it seems like we should wait until we get an actual response to the
1965−request. If someone figures out why this is, let me know. At any rate,
1966−it seems to work.
1967−
1968−If this is a domestic desk, then we check to see if the case exists yet.
1969−If it doesn't, then we simply move on to the next subscriber, consing
1970−this one onto `xaq` so that we can check again the next time around. If
1971−it does exist, then we call `++balk` to fulfill the request and produce
1972−it.
1871+This is even longer than `++knit`, but it's pretty similar to `++eave`. We loop
1872+through each of our subscribers `xiq`, processing each in turn. When we're done,
1873+we just put the remaining subscribers back in our subscriber list.
1874+
1875+If the subscriber is a single read, then, if this is a foreign desk (note that
1876+`++wake` is called from other arms, and not only on foreign desks). Obviously,
1877+if we find an identical request there, then we can produce the result
1878+immediately. Referential transparency for the win. We produce the result with a
1879+call to `++blab`. If this is a foreign desk but the result is not in the cache,
1880+then we produce `++blub` (canceled subscription with no data) for reasons
1881+entirely opaque to me. Seriously, it seems like we should wait until we get an
1882+actual response to the request. If someone figures out why this is, let me know.
1883+At any rate, it seems to work.
1884+
1885+If this is a domestic desk, then we check to see if the case exists yet. If it
1886+doesn't, then we simply move on to the next subscriber, consing this one onto
1887+`xaq` so that we can check again the next time around. If it does exist, then we
1888+call `++balk` to fulfill the request and produce it.
19731889
19741890`++balk` is very simple, so we'll describe it here before we get to the
19751891subscription case.
@@ -1980,33 +1896,30 @@ subscription case.
19801896 =+ vid=(~(read-at-aeon ze lim dom ran) oan mun)
19811897 ?~ vid (blub hen) (blab hen mun u.vid)
19821898
1983−We call `++read-at-aeon` on the given request and aeon. If you recall,
1984−this processes a `mood` at a particular aeon and produces the result, if
1985−there is one. If there is data at the requested location, then we
1986−produce it with `++blab`. Else, we call `++blub` to notify the
1987−subscriber that no data can ever come over this subscriptioin since it
1988−is now impossible for there to ever be data for the given request.
1989−Because referential transparency.
1990−
1991−At any rate, back to `++wake`. If the given rave is a subscription
1992−request, then we proceed similarly to how we do in `++eave`. We first
1993−try to get the aeon referred to by the starting case. If it doesn't
1994−exist yet, then we can't do anything interesting with this subscription,
1995−so we move on to the next one.
1996−
1997−Otherwise, we try to get the aeon referred to by the ending case. If it
1998−doesn't exist yet, then we produce all the information we can. We call
1999−`++lobes-at-path` at the given aeon and path to see if the requested
2000−path has actually changed. If it hasn't, then we don't produce anything;
2001−else, we produce the correct nako by calling `++bleb` on the result of
2002−`++make-nako`, as in `++eave`. At any rate, we move on to the next
2003−subscription, putting back into our cult the current subscription with a
2004−new start case of the next aeon after the present.
1899+We call `++read-at-aeon` on the given request and aeon. If you recall, this
1900+processes a `mood` at a particular aeon and produces the result, if there is
1901+one. If there is data at the requested location, then we produce it with
1902+`++blab`. Else, we call `++blub` to notify the subscriber that no data can ever
1903+come over this subscriptioin since it is now impossible for there to ever be
1904+data for the given request. Because referential transparency.
1905+
1906+At any rate, back to `++wake`. If the given rave is a subscription request, then
1907+we proceed similarly to how we do in `++eave`. We first try to get the aeon
1908+referred to by the starting case. If it doesn't exist yet, then we can't do
1909+anything interesting with this subscription, so we move on to the next one.
1910+
1911+Otherwise, we try to get the aeon referred to by the ending case. If it doesn't
1912+exist yet, then we produce all the information we can. We call `++lobes-at-path`
1913+at the given aeon and path to see if the requested path has actually changed. If
1914+it hasn't, then we don't produce anything; else, we produce the correct nako by
1915+calling `++bleb` on the result of `++make-nako`, as in `++eave`. At any rate, we
1916+move on to the next subscription, putting back into our cult the current
1917+subscription with a new start case of the next aeon after the present.
20051918
20061919If the aeon referred to by the ending case does exist, then we drop this
2007−subscriber from our cult and satisfy its request immediately. This is
2008−the same as before -- we check to see if the data at the path has
2009−actually changed, producing it if it has; else, we call `++blub` since
2010−no more data can be produced over this subscription.
1920+subscriber from our cult and satisfy its request immediately. This is the same
1921+as before -- we check to see if the data at the path has actually changed,
1922+producing it if it has; else, we call `++blub` since no more data can be
1923+produced over this subscription.
20111924
20121925This concludes our discussion of foreign requests.
docs/arvo/internals/dill.md+16−18
@@ -1,26 +1,24 @@
11---
2−navhome: /docs/
2+navhome: '/docs/'
33sort: 4
44---
55
6−`%dill`
7−=======
6+# `%dill`
87
98Our terminal driver.
109
11−Unix sends keyboard events to `%dill` from either the console or telnet,
12−and `%dill` produces terminal output. The only app that should directly
13−talk to `%dill` is the terminal app. Command-line apps are run by,
14−receive input from, and produce output to, the `%shell` app, which is
15−controlled by `%terminal`, which talks to `%dill`, which talks to unix.
16−Clay also uses `%dill` directly to print out the filesystem change
17−events, but this is questionable behavior.
10+Unix sends keyboard events to `%dill` from either the console or telnet, and
11+`%dill` produces terminal output. The only app that should directly talk to
12+`%dill` is the terminal app. Command-line apps are run by, receive input from,
13+and produce output to, the `%shell` app, which is controlled by `%terminal`,
14+which talks to `%dill`, which talks to unix. Clay also uses `%dill` directly to
15+print out the filesystem change events, but this is questionable behavior.
1816
19−`%dill` has two main components. First, it controls the terminal on a
20−very basic, event-by-event level. This includes keeping track of things
21−like the dimensions of the terminal, the prompt type (plain text or
22−password), which duct to produce effects on, and so forth. Second, it
23−handles terminal events, keystroke by keystroke. Most characters are
24−simply pushed onto the buffer and blitted to the screen, but some
25−characters, including control-modified keys, arrow keys, etc. require
26−special handling. Most of the readline functionality is in `%dill`.
17+`%dill` has two main components. First, it controls the terminal on a very
18+basic, event-by-event level. This includes keeping track of things like the
19+dimensions of the terminal, the prompt type (plain text or password), which duct
20+to produce effects on, and so forth. Second, it handles terminal events,
21+keystroke by keystroke. Most characters are simply pushed onto the buffer and
22+blitted to the screen, but some characters, including control-modified keys,
23+arrow keys, etc. require special handling. Most of the readline functionality is
24+in `%dill`.
docs/arvo/internals/eyre.md+14−13
@@ -1,22 +1,23 @@
11---
2−navhome: /docs/
2+navhome: '/docs/'
33sort: 5
44---
55
6−`%eyre`
7−=======
6+# `%eyre`
87
98Our http server.
109
11−Unix sends http messages to `%eyre`, and `%eyre` produces http messages
12−in response. In general, apps and vanes do not call `%eyre`; rather,
13−`%eyre` calls apps and vanes. `%eyre` uses `%ford` and `%gall` to
14−functionally publish pages and facilitate communication with apps.
10+Unix sends http messages to `%eyre`, and `%eyre` produces http messages in
11+response. In general, apps and vanes do not call `%eyre`; rather, `%eyre` calls
12+apps and vanes. `%eyre` uses `%ford` and `%gall` to functionally publish pages
13+and facilitate communication with apps.
1514
16−`%eyre` primarily parses web requests and handles them in a variety of
17−ways, depending on the control string. Nearly all of these are
18−essentially stateless, like functional publishing with `%ford`.
19−Additionally, there's a fairly significant component that handles
20−`%gall` messaging and subscriptions, which must be stateful.
15+`%eyre` primarily parses web requests and handles them in a variety of ways,
16+depending on the control string. Nearly all of these are essentially stateless,
17+like functional publishing with `%ford`. Additionally, there's a fairly
18+significant component that handles `%gall` messaging and subscriptions, which
19+must be stateful.
2120
22−<div><list/></div>
21+<div>
22+<list/>
23+</div>
docs/arvo/internals/eyre/commentary.md+50−45
@@ -1,43 +1,42 @@
11---
2−navhome: /docs/
2+navhome: '/docs/'
33---
44
5−Eyre: Reference
6−===============
5+# Eyre: Reference
76
87## State
98
109Stored
1110
12−- `++bolo`
13−- `++cyst`
14−- `++stem`
11+- `++bolo`
12+- `++cyst`
13+- `++stem`
1514
1615Runtime
1716
18−- `perk`
19− + `perk-auth`
20−- `pest`
21−- `even`
17+- `perk`
18+- `perk-auth`
19+- `pest`
20+- `even`
2221
2322## Cores
2423
25−- `++handle`
26− + `++parse`
27− - `++as...`
28−- `++ya`
29−- `++ix`
24+- `++handle`
25+- `++parse`
26+ - `++as...`
27+- `++ya`
28+- `++ix`
3029
31−Eyre: Commentary
32−================
30+# Eyre: Commentary
3331
34−Let us follow the loading of a simple cli app, as it bounces from
35−browser to server to browser and back.
32+Let us follow the loading of a simple cli app, as it bounces from browser to
33+server to browser and back.
3634
3735## Initial request<a id="init"/>
3836
39−An http request for `http://sampel-sipnym.urbit.org/cli` will be [redirected](dns)
40−to the `%eyre` on ~sampel-sipnym, and come in as a `%this` kiss.
37+An http request for `http://sampel-sipnym.urbit.org/cli` will be
38+[redirected](dns) to the `%eyre` on ~sampel-sipnym, and come in as a `%this`
39+kiss.
4140
4241From arvo, requests enter `++call`, which after some type reification are passed
4342along to `++apex:ye`. In the case of a `%this` kiss, its components are
@@ -46,7 +45,8 @@ in `++emule` to produce a `++fail` page in case of error. `++apex:handle` will
4645`++process` the request to a `pest` or a `++done` core, and in the former case
4746`++resolve` the pest into an outgoing card.
4847
49−XX it also seems to affect the current ship, test that serving ship name is consistently correct
48+XX it also seems to affect the current ship, test that serving ship name is
49+consistently correct
5050
5151The pest is produced by `++process`, which will first further `++parse` the
5252request, and if this does not make the response immediately obvious,
@@ -68,8 +68,8 @@ the perk it into a `%boil` `++ford-req`, adding an `++fcgi` path-segment
6868containing query string and `++fcgi-cred:for-client` auth information.
6969
7070`%ford`s translation of `/=cli=/hymn/hook` to a self-refreshing `%urb` html page
71−[deserves its own commentary](../ford/commentary), but we resume in `%eyre`
72−when the `%made` sign arrives in `++take`, and soon after `++axon:ye`. There the
71+[deserves its own commentary](../ford/commentary), but we resume in `%eyre` when
72+the `%made` sign arrives in `++take`, and soon after `++axon:ye`. There the
7373`wire`, or rather the `whir` it has been verified to be, determines that the
7474response should be served immediately. However, as the mark is not `%mime`,
7575another trip to `%ford` is required to encode it, on the same wire; afterwards,
@@ -145,7 +145,7 @@ To understand `/~/at`, there will first be a brief diversion to `~/auth.json`.
145145`auth.json`, perk `[%auth %json]`, in `++process-auth` serves `++stat-json:ya`,
146146containing such information as the serving ship, which identities are associated
147147with this session, and `oryx`, a CSRF token. An oryx must be present on all
148−stateful requests, in this case executing a log in. It also saves the new/old
148+stateful requests, in this case executing a log in. It also saves the new/old
149149session using `abet`.
150150
151151XX explain `ixor` here and not [later](#ixor)?
@@ -153,21 +153,22 @@ XX explain `ixor` here and not [later](#ixor)?
153153`/~/at` is an alternate interface, which injects `auth.json` data into the
154154requested file. `/~/at/auth.js`, then, is a request for the built-in `auth:js`
155155(parsed to and processed from an `[%auth %js ~]` perk), with session data added
156−as `window.urb`. And indeed, ``[`%js /~/at/auth]`` is parsed to
157−``[%auth at [`%js /auth]``, which in `++process-auth` is re-`process`ed to
158−`[%js ++auth:js]`, which is `++resolve`d after an `++add-json` of
159−the relevant data. The yac cookies are also passed to `resolve`, which
160−`++add-cookies` injects into the `httr`.
156+as `window.urb`. And indeed, `` [`%js /~/at/auth] `` is parsed to
157+`` [%auth at [`%js /auth] ``, which in `++process-auth` is re-`process`ed to
158+`[%js ++auth:js]`, which is `++resolve`d after an `++add-json` of the relevant
159+data. The yac cookies are also passed to `resolve`, which `++add-cookies`
160+injects into the `httr`.
161161
162−It is at this point that there is first occasion for user input, namely the password.
162+It is at this point that there is first occasion for user input, namely the
163+password.
163164
164165The `auth:js` script sends a `PUT` request, also to `/~/auth.json`. In `parse`,
165166the first nontrivial `++check-oryx` occurs, `++grab-body` the request oryx and
166167ensuring it is recorded for the session. The request parsed with `++need-body`
167168to a `[%auth %try {password}]` perk. `%get:process-auth` checks it against
168−`++load-secret`, upon success updates the session with `++logon:ya`, and
169−serves a fresh `auth.json` which reflects the changed `user`. Upon receiving
170−this, the page is refreshed to retry the original request.
169+`++load-secret`, upon success updates the session with `++logon:ya`, and serves
170+a fresh `auth.json` which reflects the changed `user`. Upon receiving this, the
171+page is refreshed to retry the original request.
171172
172173## Post-authentication: app communication. <a id="auth-ok"/>
173174
@@ -182,7 +183,7 @@ know to serve the window.urb necessary to make requests, and the `urb.js`
182183standard library which extends it with a number of wrappers to them and other
183184useful functions.
184185
185−---
186+--------------------------------------------------------------------------------
186187
187188One of those functions is `urb.bind`, which is used to subscribe to application
188189data. Userspace javascript sets `urb.appl` to `/tic`, and binds `lines` to a
@@ -212,18 +213,19 @@ is started using `urb.poll`. At `/~/of/{ixor}`, perk
212213`[%view ixor ~ {sequence-number}]`, it is `process`ed by `++poll:ix` (the cyst
213214is retrieved by `++ire-ix` form global state, using the perk `ixor`): the
214215sequence number is in the past, so the previously received `%rush` is
215−`++give-even`. After deleting the previous message in the queue and invoking
216+`++give-even`. After deleting the previous message in the queue and invoking
216217`++pass-took` to signal `%gall` of this occurrence, the data is annotated with
217218the source app+path `++subs-to-json`, and returned to the polling duct.
218219
219220On the client, the user callback receives the `/cli` history, and displays it on
220221the page. The `/~/of` long poll is continued, this time reaching `++poll:ix`
221−with the "pending" sequence number, and being stored in the `cyst` for its troubles.
222+with the "pending" sequence number, and being stored in the `cyst` for its
223+troubles.
222224
223−---
225+--------------------------------------------------------------------------------
224226
225227Its next update proceeds idenitcally, but first it must be triggered, which
226−happens when the user enters "(add 2 2)\n", firing an `urb.send` from the event
228+happens when the user enters "(add 2 2)\\n", firing an `urb.send` from the event
227229handler. This sends a `POST` request to `/~/to/cli/json.json`, perk `%mess`,
228230`++process`ed to a `%g %mess`. Were the mark not `%json`, a `%ford` conversion
229231would occur first, and `%made:axon` would send the gall message proper. In
@@ -233,7 +235,7 @@ sent to the client callback.
233235## A path not taken: magic filenames <a id="mage"/>
234236
235237The `/robots.txt` and `/favicon.(ico|png)` files are static, and served
236−immediately when caught by a `++parse`.
238+immediately when caught by a `++parse`.
237239
238240XX index.html?
239241
@@ -250,7 +252,6 @@ normal login page but later sends the client back. XX expand, basically the
250252status quo is you're logged in and `/~/as/foo` is ignored, just setting your
251253`urb.user` XX
252254
253−
254255## A path not taken: deauthentication
255256
256257`/~/away`, perk `[%away ~]`, produces a static `++logout-page:xml`, which also
@@ -264,8 +265,12 @@ from memory.
264265`++del-subs:ix` acting as reverse of `++add-subs` by deleting the duct binding
265266and sending `%g %nuke`.
266267
267−
268−XX unmentioned arms: abet, add-poll, adit, ames-gram, anon, ares-to-json, bolo, cyst, doze, even, ford-kill, get-mean, gift, give-json, give-thou, gram, hapt, hasp, host-to-ship, ix, ixor, js, kiss, load, mean-json, move, note, pass-note, perk, perk-auth, pest, poke-test, print-subs, render-tang, resp, root-beak, scry, ses-authed, ses-ya, sign, silk, sine, stay, stem, teba, titl, to-oryx, urb, wait-era, wake, whir, wush, xml, ya, ye
268+XX unmentioned arms: abet, add-poll, adit, ames-gram, anon, ares-to-json, bolo,
269+cyst, doze, even, ford-kill, get-mean, gift, give-json, give-thou, gram, hapt,
270+hasp, host-to-ship, ix, ixor, js, kiss, load, mean-json, move, note, pass-note,
271+perk, perk-auth, pest, poke-test, print-subs, render-tang, resp, root-beak,
272+scry, ses-authed, ses-ya, sign, silk, sine, stay, stem, teba, titl, to-oryx,
273+urb, wait-era, wake, whir, wush, xml, ya, ye
269274
270275## Appendix A: DNS <a id="dns"/>
271276
@@ -273,5 +278,5 @@ The `*.urbit.org` domain can be used to access destroyers and cruisers. In the
273278common case oh hosted ships, this is done by dynamic DNS directly to the hosting
274279instance. We do not speak of the uncommon case. When ports are blocked and
275280infrastructure crumbles around you, only imported martian networking can be
276−trusted: the `%get` and `%got` [gram]()s are used to proxy [`%this` requests]() and
277−[`%thou` responses]() respectively.
281+trusted: the `%get` and `%got` [gram]()s are used to proxy [`%this` requests]()
282+and [`%thou` responses]() respectively.
docs/arvo/internals/eyre/specification.md+355−189
@@ -1,135 +1,186 @@
11# Specification
22
3−The `%eyre` vane serves one purpose: receiving inbound HTTP requests from browsers and clients pretending to be browsers. To facilitate this communication, `%eyre` does two things: 1. provide an API for traditional clients to talk to; and 2. provide a mechanism for saving state that allows the server to keep track of identities/sessions, subscription data, and active connections.
3+The `%eyre` vane serves one purpose: receiving inbound HTTP requests from
4+browsers and clients pretending to be browsers. To facilitate this
5+communication, `%eyre` does two things: 1. provide an API for traditional
6+clients to talk to; and 2. provide a mechanism for saving state that allows the
7+server to keep track of identities/sessions, subscription data, and active
8+connections.
49
510This document outlines the following:
611
7−1. [`perk`](#perk), a `pork` subset that defines what URLs the client can send to `%eyre`.
8−2. [the values stored on the client](#client), both statically in cookies and dynamically as the `window.urb` object, which facilitate this transaction.
12+1. [`perk`](#perk), a `pork` subset that defines what URLs the client can send
13+ to `%eyre`.
14+2. [the values stored on the client](#client), both statically in cookies and
15+ dynamically as the `window.urb` object, which facilitate this transaction.
916
10−3. [`kiss`](#kiss), the requests `%eyre` will accept.
11−4. [`gift`](#gift), the responses it will give to those requests.
17+3. [`kiss`](#kiss), the requests `%eyre` will accept.
18+4. [`gift`](#gift), the responses it will give to those requests.
1219
13−5. [`note`](#note), the set of arvo requests that %eyre makes to the other vanes.
14−6. [`whir`](#whir), a `wire` subset, the associated dynamic state
15−7. [`sign`](#sign), the responses `%eyre` accepts
16−8. [`bolo`](#bolo), the state stored between separate events.
20+5. [`note`](#note), the set of arvo requests that %eyre makes to the other
21+ vanes.
22+6. [`whir`](#whir), a `wire` subset, the associated dynamic state
23+7. [`sign`](#sign), the responses `%eyre` accepts
24+8. [`bolo`](#bolo), the state stored between separate events.
1725
1826# 1. URL structure <a id="perk"/>
19−There exist several URL forms accepted by `%eyre`.
27+
28+There exist several URL forms accepted by `%eyre`.
2029
2130## 1.1 Functional request
31+
2232The simplest of them is a static `%f` functional publish request:
2333
24− ```hoon
25− GET /[ship]/[desk]/[case]/path/to/file.[mark]
26− ```
27−e.g.
34+`hoon GET /[ship]/[desk]/[case]/path/to/file.[mark]` e.g.
2835
29− ```hoon
30− /~pittyp-pittyp/main/5/lib/urb.js
31− ```
32−A `case` of 0 signifies the most recent version.
36+`hoon /~pittyp-pittyp/main/5/lib/urb.js` A `case` of 0 signifies the most
37+recent version.
3338
34−If no file extension is provided, the default `mark` is `%urb`, which consists of `%html` injected with an auto-refresh script.
39+If no file extension is provided, the default `mark` is `%urb`, which consists
40+of `%html` injected with an auto-refresh script.
3541
3642A shorter form:
3743
38− ```hoon
39− /path/to.[mark]
40− ```
41−is prepended with the [default request path](#prefix). For example, if `%eyre`
42−is configured with a root of `/<our>/main/0/pub`, then `/doc/arvo` is
43−interpreted as a request for `/=main=/pub/doc/arvo.urb`.
44+`hoon /path/to.[mark]` is prepended with the [default request path](#prefix).
45+For example, if `%eyre` is configured with a root of `/<our>/main/0/pub`, then
46+`/doc/arvo` is interpreted as a request for `/=main=/pub/doc/arvo.urb`.
4447
4548Auxiliary paths start with `/~/`, and provide other functionality, such as:
4649
4750## 1.2 Auto-reload
48−When a new version of a page becomes available, it is useful to propagate it to the client. The `%f` vane manages the particulars, and provides an update token along with all published pages. The `/~/on` long-polling endpoint makes use of that token, which is a hash of the server-stored dependency set.
49−- `/~/on/[hash].json` retuns `true` when a page may require updating.
50−- `/~/on/[hash].js` is a lightweight script that polls for the above. It is primarily used in error messages.
51+
52+When a new version of a page becomes available, it is useful to propagate it to
53+the client. The `%f` vane manages the particulars, and provides an update token
54+along with all published pages. The `/~/on` long-polling endpoint makes use of
55+that token, which is a hash of the server-stored dependency set. -
56+`/~/on/[hash].json` retuns `true` when a page may require updating. -
57+`/~/on/[hash].js` is a lightweight script that polls for the above. It is
58+primarily used in error messages.
5159
5260## 1.3 Authentication <a id="auth"/>
53−Authenticated requests are accomplished through sessions, tracked with cookies which are set on the first such request.
54−- `/~/as/[user]/...` is an authenticated request to `...`, where `user` can be a `@p` ship, `'own'`, `'any'`, or `'anon'`.
55− + `'anon'` is a randomly-generated per-session submarine, and requires no further authentication.
56− + `'own'` represents the serving ship. The short form of `/~/as/own/` is `/~~/`
57− + `'any'` requires a network ship, chosen with a prompt if unknown. The short form of `/~/as/any/` is `/_/`
58− + Auth requests are handled in three ways:
59− + I. If the session is associated with the `ship`, serve `...`, storing the ship as the session's default ship.
60− For example,
61− /~/as/sivtyv-barnel/main/pub/test.html
62− is an authenticated request of
63− /main/pub/test.html
64− with the identity of `~sivtyv-barnel`.
65− + II. If the session is not associated with the `ship` in the path, the client is redirected to a login page, where a password can be entered. Successful authentication results in a page refresh to the requested path.
66− + III. otherwise, [send a message](#foreign) to the claimed ship, and redirect the user to `https://[foreign-host]/~/am/[ses]/...#[current-host]&?code=[code]`
67−
68−
69−- `/~/am/[ses]/...#original-host` similarly serves a login page. Upon success, inform the `ship` of the success and redirect it back to `http://[original-host]/~/as/<this-ship>/...`
70−- `/~/away.html` is a log-out page.
71−- `/~/auth.json` returns `{ship,oryx,user,auth}`: the serving ship, a CSRF token, active user, and all allowed users respectively.
72−- `/~/at/{...}.js` is an alternate form of `/~/auth.json`, which injects a line into the served js file that sets `{ship, oryx, user, auth}` on the `window.urb` object.
73−
74−So far, all the paths specified have been GET requests. Authentication, however, requires sending data. This is also done at the `/~/auth.json` endpoint.
75−- `POST {oryx,ship,code} /~/auth.json?PUT` is used by the login script to authorize a user, and returns the same result as `GET`, additionally containing either`{ok:true}` or `{fail:'type',mess:"Error message"}`
76−- `POST {oryx,ship?} /~/auth.json?DELETE` revokes authorization. Response as above.
61+
62+Authenticated requests are accomplished through sessions, tracked with cookies
63+which are set on the first such request. - `/~/as/[user]/...` is an
64+authenticated request to `...`, where `user` can be a `@p` ship, `'own'`,
65+`'any'`, or `'anon'`. + `'anon'` is a randomly-generated per-session submarine,
66+and requires no further authentication. + `'own'` represents the serving ship.
67+The short form of `/~/as/own/` is `/~~/` + `'any'` requires a network ship,
68+chosen with a prompt if unknown. The short form of `/~/as/any/` is `/_/` + Auth
69+requests are handled in three ways: + I. If the session is associated with the
70+`ship`, serve `...`, storing the ship as the session's default ship. For
71+example, /~/as/sivtyv-barnel/main/pub/test.html is an authenticated request of
72+/main/pub/test.html with the identity of `~sivtyv-barnel`. + II. If the session
73+is not associated with the `ship` in the path, the client is redirected to a
74+login page, where a password can be entered. Successful authentication results
75+in a page refresh to the requested path. + III. otherwise, [send a
76+message](#foreign) to the claimed ship, and redirect the user to
77+`https://[foreign-host]/~/am/[ses]/...#[current-host]&?code=[code]`
78+
79+- `/~/am/[ses]/...#original-host` similarly serves a login page. Upon success,
80+ inform the `ship` of the success and redirect it back to
81+ `http://[original-host]/~/as/<this-ship>/...`
82+- `/~/away.html` is a log-out page.
83+- `/~/auth.json` returns `{ship,oryx,user,auth}`: the serving ship, a CSRF
84+ token, active user, and all allowed users respectively.
85+- `/~/at/{...}.js` is an alternate form of `/~/auth.json`, which injects a
86+ line into the served js file that sets `{ship, oryx, user, auth}` on the
87+ `window.urb` object.
88+
89+So far, all the paths specified have been GET requests. Authentication, however,
90+requires sending data. This is also done at the `/~/auth.json` endpoint. -
91+`POST {oryx,ship,code} /~/auth.json?PUT` is used by the login script to
92+authorize a user, and returns the same result as `GET`, additionally containing
93+either`{ok:true}` or `{fail:'type',mess:"Error message"}` -
94+`POST {oryx,ship?} /~/auth.json?DELETE` revokes authorization. Response as
95+above.
7796
7897## 1.4 Messaging
79−- `POST {oryx, wire, xyro} /~/to/[app]/[mark].json`, where `xyro` is data that will be converted to the `mark`. In the simplest case, `/~/to/hello/json.json` will pass `xyro` through verbatim, sending `[%json xyro]` to the `++poke` arm of app `%hello`.
80−- `POST {oryx, wire, xyro} /~/to/<ship>/[app]/[mark].json` is a foreign message send, as above.
98+
99+- `POST {oryx, wire, xyro} /~/to/[app]/[mark].json`, where `xyro` is data that
100+ will be converted to the `mark`. In the simplest case,
101+ `/~/to/hello/json.json` will pass `xyro` through verbatim, sending
102+ `[%json xyro]` to the `++poke` arm of app `%hello`.
103+- `POST {oryx, wire, xyro} /~/to/<ship>/[app]/[mark].json` is a foreign
104+ message send, as above.
81105
82106## 1.5 Subscriptions <a id="subs"/>
83−- `/~/of/[ixor]`<a id="of-ixor"/> is an `EventSource`: a conceptually infinite file containing a stream of events. By default, it sends a newline every 30 seconds serving to signal that the connection is alive to both the server and IP middleware.
84− + `/~/of/[ixor]?poll={n}` is a long-polling fallback interface. Produces event number {n}, blocking until it occurs.
85107
86−Its contexts can be affected by `POST` requests with a body of `{oryx, wire}`, and a query string of `PUT` or `DELETE`. They return either `{mark}`(which may be `null`), or [`{fail, mess}`](#mean-json)
108+- `/~/of/[ixor]`<a id="of-ixor"/> is an `EventSource`: a conceptually infinite
109+ file containing a stream of events. By default, it sends a newline every 30
110+ seconds serving to signal that the connection is alive to both the server
111+ and IP middleware.
112+- `/~/of/[ixor]?poll={n}` is a long-polling fallback interface. Produces event
113+ number {n}, blocking until it occurs.
114+
115+Its contexts can be affected by `POST` requests with a body of `{oryx, wire}`,
116+and a query string of `PUT` or `DELETE`. They return either `{mark}`(which may
117+be `null`), or [`{fail, mess}`](#mean-json)
87118
88−- `/~/in/[hash].json` is a dual to [`/~/on`](#on-change). It binds `mod` events, which echo the requesting token.
89−- `/~/is/[app]/path/to.[mark]` binds `rush` events, formatted with a first line of `[app] /path/to`, and the rest containing subscription data. Additionally, `mean` events formatted similarly may arrive, also converted to the relevant mark.
119+- `/~/in/[hash].json` is a dual to [`/~/on`](#on-change). It binds `mod`
120+ events, which echo the requesting token.
121+- `/~/is/[app]/path/to.[mark]` binds `rush` events, formatted with a first
122+ line of `[app] /path/to`, and the rest containing subscription data.
123+ Additionally, `mean` events formatted similarly may arrive, also converted
124+ to the relevant mark.
90125
91126## 1.6 Ablative <a id="temp"/>
92−These interfaces will temporarily exist to aid development, and are to be considered unstable.
93−- `/~/debug/...` access normally inaccessible pages. For example, `/~/debug/as.html` will present the login page, regardless of current session status.
127+
128+These interfaces will temporarily exist to aid development, and are to be
129+considered unstable. - `/~/debug/...` access normally inaccessible pages. For
130+example, `/~/debug/as.html` will present the login page, regardless of current
131+session status.
94132
95133# 2. Client state <a id="client"/>
134+
96135Some information is stored on, and provided to, browser clients
97136
98137## 2.1 Cookies
99−Authenticated users receive a cookie on the domain of `*.urbit.org`. The cookie contains a client session token, keyed by the serving ship.
138+
139+Authenticated users receive a cookie on the domain of `*.urbit.org`. The cookie
140+contains a client session token, keyed by the serving ship.
100141
101142## 2.2 Authentication <a id="auth-json"/>
102−It is common(e.g. by the `%urb` mark) to set window.urb to the contents of `/~/auth.json`:
103−- `ship` is the serving ship
104−- `oryx` is a unique CSRF token that identifies this view, bound to the session cookie
105−- `ixor` is a hash of `oryx`, used as an insecure view identifier
106−- `user` is the authenticated/generated ship name
107−- `auth` is a list of identities usable by this session
143+
144+It is common(e.g. by the `%urb` mark) to set window.urb to the contents of
145+`/~/auth.json`: - `ship` is the serving ship - `oryx` is a unique CSRF token
146+that identifies this view, bound to the session cookie - `ixor` is a hash of
147+`oryx`, used as an insecure view identifier - `user` is the
148+authenticated/generated ship name - `auth` is a list of identities usable by
149+this session
108150
109151## 2.3 Client library
110−To this object, `/main/lib/urb.js` adds helpers:
111−- `app` is an optional app name to send messages to by default
112−- `send({data,mark?='json',app?=urb.app,ship?}, cb?)` delivers messages
113−- `bind({path,app?=urb.app}, cb)` subscribes by path
114−- `drop({path,app?=urb.app}, cb?)` pulls the subscription
115−- `util` is an object containing methods for converting between JavaScript types and Hoon atom odors.
152+
153+To this object, `/main/lib/urb.js` adds helpers: - `app` is an optional app name
154+to send messages to by default -
155+`send({data,mark?='json',app?=urb.app,ship?}, cb?)` delivers messages -
156+`bind({path,app?=urb.app}, cb)` subscribes by path -
157+`drop({path,app?=urb.app}, cb?)` pulls the subscription - `util` is an object
158+containing methods for converting between JavaScript types and Hoon atom odors.
116159
117160# 3. Requests <a id="kiss"/>
118161
119162## `[%born port=@ud]`, unix init
120−When the `vere` process is re/started, a TCP port is bound, HTTP requests on which are the scope of this document. The `%born` gift informs eyre of this occurrence, which in turn updates [its state.](#bolo)
163+
164+When the `vere` process is re/started, a TCP port is bound, HTTP requests on
165+which are the scope of this document. The `%born` gift informs eyre of this
166+occurrence, which in turn updates [its state.](#bolo)
121167
122168**Gifts given in response:** none.
123169
124170## `[%hiss p=mark q=cage]`, outbound http
171+
125172Userspace http request, converted by `%ford` into an actual `hiss`.
126173
127174**Gifts given in response:** a [`%sigh`]()
128175
129176## 3.1 `[%this httq]`, inbound http
130−The primary `%eyre` request type comes from the host system, and constitutes an inbound http request. It consists of five parts:
131177
132−I. `p=[? @if]`: a loobean determining whether the request is being made over https, and the client source, an IPv6 address possibly encoding an IPv4 one as `.0.0.0.0.0.ffff.wwxx.yyzz`
178+The primary `%eyre` request type comes from the host system, and constitutes an
179+inbound http request. It consists of five parts:
180+
181+I. `p=[? @if]`: a loobean determining whether the request is being made over
182+https, and the client source, an IPv6 address possibly encoding an IPv4 one as
183+`.0.0.0.0.0.ffff.wwxx.yyzz`
133184
134185II. `q=meth`, an http method
135186
@@ -139,225 +190,342 @@ IV. `s=mess`, an associative list of header keys/values
139190
140191V. `t=(unit octs)`, the request body, if any.
141192
142−After `r` is parsed to a `purl`, the `pork`(relative path) determines the resource being served. The first step in handling an http request is [classifying its intent](#perk).
143−
144−- A ford request results in a [`%boil` note](#boil).
145−- `/~/[name].js` is generated from [session](#sink) or [view](#stem) state, and [served](#mime) as `%js`.
146−- `/~/am` generates a login page.
147−- `/~/as` is resolved further if authenticated, generates a similar login page if the claimed ship is local, and otherwise is saved to [session state](#sink) and sends a ["login" `%a` message](#lon) to the foreign ship.
148−- `/~/at` and `/~/auth.json` generate a new `oryx` and store it in the [session state](#sink).
149−- `/~/in` and `/~/is` affect [view state](#stem), possibly sending subscriptions or unsubscriptions to `%f` and `%g` respectively, and are generated from view state.
150−- `/~/on` is saved to the `bolo` by `hash`, and translated to a [`%wasp` note](#wasp).
151−- `/~/of` fails if the `ixor` is unknown, and otherwise is stored in the `ixor`, receiving a partial response and all events after its [last-seen header](#). If it has a `poll` parameter, the response is full, and only occurs if the body is non-empty. Otherwise the oryx is saved as a [live](#live) request in case of cancellation.
152−- `/~/to` transforms into a [`%g` message](#mess).
153−
154−**Gifts given in response:** a [`%thou`](), or a [`%that`](#that) followed by multiple [`%thar`]()s.
193+After `r` is parsed to a `purl`, the `pork`(relative path) determines the
194+resource being served. The first step in handling an http request is
195+[classifying its intent](#perk).
196+
197+- A ford request results in a [`%boil` note](#boil).
198+- `/~/[name].js` is generated from [session](#sink) or [view](#stem) state,
199+ and [served](#mime) as `%js`.
200+- `/~/am` generates a login page.
201+- `/~/as` is resolved further if authenticated, generates a similar login page
202+ if the claimed ship is local, and otherwise is saved to [session
203+ state](#sink) and sends a ["login" `%a` message](#lon) to the foreign ship.
204+- `/~/at` and `/~/auth.json` generate a new `oryx` and store it in the
205+ [session state](#sink).
206+- `/~/in` and `/~/is` affect [view state](#stem), possibly sending
207+ subscriptions or unsubscriptions to `%f` and `%g` respectively, and are
208+ generated from view state.
209+- `/~/on` is saved to the `bolo` by `hash`, and translated to a [`%wasp`
210+ note](#wasp).
211+- `/~/of` fails if the `ixor` is unknown, and otherwise is stored in the
212+ `ixor`, receiving a partial response and all events after its [last-seen
213+ header](#). If it has a `poll` parameter, the response is full, and only
214+ occurs if the body is non-empty. Otherwise the oryx is saved as a
215+ [live](#live) request in case of cancellation.
216+- `/~/to` transforms into a [`%g` message](#mess).
217+
218+**Gifts given in response:** a [`%thou`](), or a [`%that`](#that) followed by
219+multiple [`%thar`]()s.
155220
156221## 3.2 `[%thud ~]`, inbound close
157−Sent when an unresponded-to request is cancelled. The [live](#live) effect of the request is looked up, and
158−- `%exec` ford boil requests are cancelled with `[%exec ~]`
159−- `%wasp` ford deps requests are cancelled with `[%wasp |]`
160−- `%poll` session polls `%rest` the session heartbeat timeout
222+
223+Sent when an unresponded-to request is cancelled. The [live](#live) effect of
224+the request is looked up, and - `%exec` ford boil requests are cancelled with
225+`[%exec ~]` - `%wasp` ford deps requests are cancelled with `[%wasp |]` -
226+`%poll` session polls `%rest` the session heartbeat timeout
161227
162228## 3.3 `[%thin p=@ud]`, delivery failure
163−Sent when a partial [response](#that) or [body](#thar) fails to arrive. Its `duct` is the same as that of the original request. This is handled by [waiting](#wait) for the client to reconnect, and if this not occur, unwinding all subscription state.
229+
230+Sent when a partial [response](#that) or [body](#thar) fails to arrive. Its
231+`duct` is the same as that of the original request. This is handled by
232+[waiting](#wait) for the client to reconnect, and if this not occur, unwinding
233+all subscription state.
164234
165235**Gifts given in response:** None.
166236
167−## 3.4 ``[%wart sock [path *]]``, inbound message
168−Sometimes, messages are received from other ships. They are expected to take the from of a [`gram`]().
237+## 3.4 `[%wart sock [path *]]`, inbound message
238+
239+Sometimes, messages are received from other ships. They are expected to take the
240+from of a [`gram`]().
169241
170242**Gifts given in response:** [`%nice` or `%mean`](#ack).
171243
172244### 3.4.1 `gram` <a id="gram"/>
173245
174−There are three messages of note, all concerning authentication <a id="foreign"/>
175−- `[/lon ses]` <a id="lon"/> is a login request, which contains the session wishing to authenticate.
176−- if the session is already authorized, a reply of `[/aut ses]` from (%eyre on) a foreign ship prescribes that the session is henceforth allowed to act on its behalf.
177−All waiting `/~/as` are resolved as succesful.
178−- otherwise, `[/hat ses hart]` contains the ship's preferred hostname. This can then be used to redirect the client.
179−All waiting `/~/as` are given `307 Redirect`s to `/~/am` on the provided host.
246+There are three messages of note, all concerning authentication
247+<a id="foreign"/> - `[/lon ses]` <a id="lon"/> is a login request, which
248+contains the session wishing to authenticate. - if the session is already
249+authorized, a reply of `[/aut ses]` from (%eyre on) a foreign ship prescribes
250+that the session is henceforth allowed to act on its behalf. All waiting `/~/as`
251+are resolved as succesful. - otherwise, `[/hat ses hart]` contains the ship's
252+preferred hostname. This can then be used to redirect the client. All waiting
253+`/~/as` are given `307 Redirect`s to `/~/am` on the provided host.
180254
181255**Gifts given in response:** nice?
182256
183257# 4. Responses <a id="gift"/>
258+
184259## 4.1 `[%nice ~]`, `[%mean ares]`, network acknowledgement <a id="ack"/>
185−A `%nice` is given upon receiving an [ames message](#gram), indicating succesful receipt. `%mean` is currently unused directly, but reserved for error conditions.
260+
261+A `%nice` is given upon receiving an [ames message](#gram), indicating succesful
262+receipt. `%mean` is currently unused directly, but reserved for error
263+conditions.
186264
187265## `[%sigh p=cage]`, inbound http response
188−An HTTP response gets converted to the requested mark, or `%tang` in case of error.
266+
267+An HTTP response gets converted to the requested mark, or `%tang` in case of
268+error.
189269
190270## 4.2 `[%thou httr]`, full HTTP response
191−Most requests are served with one coherent response, consisting of
192−- `p=@ud`, an HTTP status code
193−- `q=mess`, response headers
194−- `r=(unit octs)`, an optional body
271+
272+Most requests are served with one coherent response, consisting of - `p=@ud`, an
273+HTTP status code - `q=mess`, response headers - `r=(unit octs)`, an optional
274+body
195275
196276## 4.3 `[%that httr]`, partial HTTP response <a id="that"/>
197−[EventStream responses](#of-ixor) consist of multiple sequential chunks. Treated as `%thou`, except the request is kept open.
277+
278+[EventStream responses](#of-ixor) consist of multiple sequential chunks. Treated
279+as `%thou`, except the request is kept open.
198280
199281## 4.4 `[%thar (unit octs)]`, partial HTTP body <a id="thar"/>
200−Complementing `%that`, `%thar` is a body chunk, containing an event. An empty `%thar` signals for the connection to be closed.
201282
202−Body chunks, besides `[1 '\0a']`(a heartbeat newline), are encoded from `even` events. The stem becomes the [`event` field](#eventsource), and the content, `data` lines.
283+Complementing `%that`, `%thar` is a body chunk, containing an event. An empty
284+`%thar` signals for the connection to be closed.
285+
286+Body chunks, besides `[1 '\0a']`(a heartbeat newline), are encoded from `even`
287+events. The stem becomes the [`event` field](#eventsource), and the content,
288+`data` lines.
203289
204290### 4.4.1 `even`, event types <a id="even"/>
291+
205292There are three events that a [client subscription](#subs) will be given.
206293
207−- `[%news hash]`<a id="even-news"/> is a `%f` update, and contains the relevant dependency token.
208−- `[%rush [term path] wain]`<a id="even-rush"/> is sourced subscription data.
209−- `[%mean [term path] ares]` is a sourced subscription error.
294+- `[%news hash]`<a id="even-news"/> is a `%f` update, and contains the
295+ relevant dependency token.
296+- `[%rush [term path] wain]`<a id="even-rush"/> is sourced subscription data.
297+- `[%mean [term path] ares]` is a sourced subscription error.
210298
211299# 5. Vane requests <a id="note"/>
212−## 5.1 ``[%a %wont sock `[path *]`gram]``, outbound message
300+
301+## 5.1 `` [%a %wont sock `[path *]`gram] ``, outbound message
302+
213303The `%a` interface provides conveyance of [messages](#gram) over UDP.
214304
215305Signs a `%woot` upon message arrival.
216306
217307## 5.2 `[%b ?(%wait %rest) time]`, timeout set/unset <a id="wait"/>
218−All open [subscriptions](#of-ixor) require a "heartbeat" newline every `~s30`. When this fails to arrive, a complementary timer is set for `~m1`, after which the client is considered to have departed.
219−The `%b` timer interface is used to schedule the next such event, or cancel past scheduled ones when a connection closes.
308+
309+All open [subscriptions](#of-ixor) require a "heartbeat" newline every `~s30`.
310+When this fails to arrive, a complementary timer is set for `~m1`, after which
311+the client is considered to have departed. The `%b` timer interface is used to
312+schedule the next such event, or cancel past scheduled ones when a connection
313+closes.
220314
221315Signs a `%wake` upon timer activation.
222316
223317## 5.3 `[%f %wasp @uvI]`, dependency listen <a id="wasp"/>
224−Knowledge of filesystem changes, requested by `/~/on` and `/~/in`, is requested the `%wasp` note. It contains the hash token which idenitifes a set of dependencies to query. Saved as a (live[live](#live)#live] request in case of cancellation when caused by `/~/on`.
225318
226−Signs a `%writ` upon change.
319+Knowledge of filesystem changes, requested by `/~/on` and `/~/in`, is requested
320+the `%wasp` note. It contains the hash token which idenitifes a set of
321+dependencies to query. Saved as a (live[live](#live)\#live\] request in case of
322+cancellation when caused by `/~/on`.
323+
324+Signs a `%writ` upon change.
227325
228326## 5.4 `[%f %exec (unit silk)]`, functional transformations
229−The `%f` interface converts nouns from one form to another. An empty unit represents cancellation.
327+
328+The `%f` interface converts nouns from one form to another. An empty unit
329+represents cancellation.
230330
231331Signs a `%made` containing the computation result.
232332
233−The `silk`s used are as follows:
333+The `silk`s used are as follows:
234334
235335### `[%cast %mime %boil mark beam [%web span ~]]`, file load
236−The simplest functional request is the construction of a page. Saved as a [live](#live) request in case of cancellation.
237−- The `mark` is the request extension, defaulting to `%html`.
238−- A `beam`(path in `%clay`) is decoded from the request path.
239−- A `/web/<nyp ced quy>` virtual path is appended, span-encoding method, auth, and query string.
336+
337+The simplest functional request is the construction of a page. Saved as a
338+[live](#live) request in case of cancellation. - The `mark` is the request
339+extension, defaulting to `%html`. - A `beam`(path in `%clay`) is decoded from
340+the request path. - A `/web/<nyp ced quy>` virtual path is appended,
341+span-encoding method, auth, and query string.
240342
241343### `[%cast mark %done ~ cage]`, convert <a id="done"/>
242−This is used when communicating with apps, in both directions.
243−- Client messages are encoded as JSON objects, but can contain many different marks. Ones sent to non-`json.json` endpoints are `%cast` to he relevant mark, with a `cage` of `[%json p:!>(*json) jon]`, prior to being sent onwards to applications with `[%g %mess]`.
244−- Subscription responses also come in arbitrary marks, but are required to be sent as whichever mark an endpoint is subscribed to. They get `%cast` prior to being sent back as a `%that` EventSource segment.
344+
345+This is used when communicating with apps, in both directions. - Client messages
346+are encoded as JSON objects, but can contain many different marks. Ones sent to
347+non-`json.json` endpoints are `%cast` to he relevant mark, with a `cage` of
348+`[%json p:!>(*json) jon]`, prior to being sent onwards to applications with
349+`[%g %mess]`. - Subscription responses also come in arbitrary marks, but are
350+required to be sent as whichever mark an endpoint is subscribed to. They get
351+`%cast` prior to being sent back as a `%that` EventSource segment.
245352
246353## 5.5 `%g`, app actions
247−The end goal of many a userspace `hymn.hook` is to provide UI for a `%gall` app. To accommodate this, various functionality needs to be interfaced with.
354+
355+The end goal of many a userspace `hymn.hook` is to provide UI for a `%gall` app.
356+To accommodate this, various functionality needs to be interfaced with.
248357
249358### `[%mess hapt ship cage]`, app message <a id="mess"/>
250−After a `/~/to` POST has been received, and possibly converted to the correct mark, it is sent to `%g` for processing. The `hapt` is the destination, the `ship` is the source, the `cage` is the marked message data.
359+
360+After a `/~/to` POST has been received, and possibly converted to the correct
361+mark, it is sent to `%g` for processing. The `hapt` is the destination, the
362+`ship` is the source, the `cage` is the marked message data.
251363
252364Signs a `%nice` or `%mean`, in userspace or upon crashing.
253365
254366### `[%show hapt ship path]`, app subscription<a id="show"/>
255−An `/~/is` PUT, if not already registered, results in a new subscription. A request for such contains the destination `hapt`, requesting `ship`, and app-internal `path`.
256367
257−Signs a `%nice` on init, `%rush` on data, and a `%mean` in subscription termination.
368+An `/~/is` PUT, if not already registered, results in a new subscription. A
369+request for such contains the destination `hapt`, requesting `ship`, and
370+app-internal `path`.
371+
372+Signs a `%nice` on init, `%rush` on data, and a `%mean` in subscription
373+termination.
258374
259375### `[%took hapt ship]`, %rush confirmation
260−A `%took` must be sent to acknowledge the receipt of subscription data, which in this case occurs automatically.
376+
377+A `%took` must be sent to acknowledge the receipt of subscription data, which in
378+this case occurs automatically.
261379
262380Causes no signs.
263381
264382### `[%nuke hapt $|(ship [ship path])]`, subscription cancel
265−An `/~/is` DELETE is used to remove a subscription, and is converted straightforwardly to a `%nuke`. Additionally, when a client disconnects, all of its subscriptions are `%nuke`d to reflect their experiation.
383+
384+An `/~/is` DELETE is used to remove a subscription, and is converted
385+straightforwardly to a `%nuke`. Additionally, when a client disconnects, all of
386+its subscriptions are `%nuke`d to reflect their experiation.
266387
267388Signs an empty `%mean` for each open subscription that is closed.
268389
269390# 6. In-flight metadata <a id="whir"/>
270−Various state can be associated with requests, but not necessarily be returned in responses to them.
391+
392+Various state can be associated with requests, but not necessarily be returned
393+in responses to them.
271394
272395## 6.1 `~`, dropthrough <a id="wire-drop"/>
273−If the response should be sent statelessly further up the duct, the `wire` is empty. This is used in `%f` pure functional page generation.
396+
397+If the response should be sent statelessly further up the duct, the `wire` is
398+empty. This is used in `%f` pure functional page generation.
274399
275400## 6.2 `[?(%y %n) ...]`, stability <a id="wire-live"/>
276−The first element of a [`%b` timer](#wait) path distinguishes between live(%y) and dying(%n) channels.
401+
402+The first element of a [`%b` timer](#wait) path distinguishes between live(%y)
403+and dying(%n) channels.
277404
278405## 6.3 `/of/[ixor]`, view
406+
279407Designates which stream to act upon. Present on `%b` timer cards.
280408
281409## 6.4 `/on/<deps>`
282−Present on `%f` dependency news. Looked up in [the state](#bolo) to see if any response is necessary.
410+
411+Present on `%f` dependency news. Looked up in [the state](#bolo) to see if any
412+response is necessary.
283413
284414## 6.5 `/to/<hasp>/<ship>`, app <a id="wire-to"/>
415+
285416Present on `%f` translations of message marks
286417
287418## 6.6 `/is/[ixor]/{hasp path}`, subscription <a id="wire-is"/>
288−Subscription requests. Present on `%g` subscription requests, and `%f` translations of [`%rush` subscription data](#show).
419+
420+Subscription requests. Present on `%g` subscription requests, and `%f`
421+translations of [`%rush` subscription data](#show).
289422
290423# 7. Vane responses <a id="sign"/>
291−The goal of requests is to cause some manner of result. Specifically,
424+
425+The goal of requests is to cause some manner of result. Specifically,
292426
293427## 7.1 `[%a %woot ship coop]`, acknowledgement
428+
294429A [message](#mess) which has been acknowledged remotely.
295430
296431## 7.2 `[%b %wake ~]`, timer
297−Timer activate. If this is a `%y` [timer](#wire-live), send a newline to each `/~/of/[oryx]`; if `%n` and the `oryx` still has no listeners, wipe its state/subscriptions.
432+
433+Timer activate. If this is a `%y` [timer](#wire-live), send a newline to each
434+`/~/of/[oryx]`; if `%n` and the `oryx` still has no listeners, wipe its
435+state/subscriptions.
298436
299437## 7.3 `[%f %news ~]`, dependency update
300−This message signifies a `hash` has changed, and listeners to it should be updated. Results in [`%news` events](#even-news) to concerned streams, and [full responses](#thou) to relevant long-polls.
438+
439+This message signifies a `hash` has changed, and listeners to it should be
440+updated. Results in [`%news` events](#even-news) to concerned streams, and [full
441+responses](#thou) to relevant long-polls.
301442
302443## 7.4 `[%f %made (each bead (list tank))]`, compute result
303−Further action depends on the [`wire`](#whir). It can:
304−- Be empty, designating direct request data, which is [served](#mime) back up the `duct`.
305−- Contain [app and requester identities](#wire-to), which designates an app message has been converted to the correct `mark`, and can now be [sent to the app](#mess) with an empty `wire`.
306−- Contain an `oryx`, app, and `path`, designating subscription data. If the subscription is active in the relevant `stem`, it is acknowledged with a `%took` and given as a [`%rush` event](#even-rush) to all listeners. Otherwise, the subscription is `%nuke`d.
444+
445+Further action depends on the [`wire`](#whir). It can: - Be empty, designating
446+direct request data, which is [served](#mime) back up the `duct`. - Contain [app
447+and requester identities](#wire-to), which designates an app message has been
448+converted to the correct `mark`, and can now be [sent to the app](#mess) with an
449+empty `wire`. - Contain an `oryx`, app, and `path`, designating subscription
450+data. If the subscription is active in the relevant `stem`, it is acknowledged
451+with a `%took` and given as a [`%rush` event](#even-rush) to all listeners.
452+Otherwise, the subscription is `%nuke`d.
307453
308454## 7.5 `%g`, applications
455+
309456The `%g` interface sends several responses.
310457
311458### `[%nice ~]` and `[%mean ares]`, acknowledgment
312−These are given as a response to `%mess`, with an empty wire, and `%show`s, with a [subscription wire](#wire-is).
313−The former is [served](#mime) back to the requester(i.e. the remaining duct), and the latter returned to the client.
459+
460+These are given as a response to `%mess`, with an empty wire, and `%show`s, with
461+a [subscription wire](#wire-is). The former is [served](#mime) back to the
462+requester(i.e. the remaining duct), and the latter returned to the client.
314463
315464### 7.5 `[%rush cage]`, subscription data
316−A `%rush` arrives on a [subscription wire](#wire-is), and is then sent [for conversion](#done) to the correct mark. An unexpected `%rush` is `%nuke`d.
465+
466+A `%rush` arrives on a [subscription wire](#wire-is), and is then sent [for
467+conversion](#done) to the correct mark. An unexpected `%rush` is `%nuke`d.
317468
318469# 8. Server state <a id="bolo"/>
470+
319471There is a quantity of data that persists between events.
320472
321473## 8.1 Global
322−- `path` <a id="prefix"/> the default path which is prepended to relative plain requests. Initialized to `/<our>`, the serving ship; this interprets the first element of requests as a desk, and injects a `case` of `0`.
323−- `(jar ship hart)` remembered hostnames in order of preference, made accessible through `.^`
324− + The default values(for self) are `http://<ship>.urbit.org:80` if not on a fake network, followed by `https://0.0.0.0:[port]`.
325−- `(jug deps (each duct oryx))`, `/~/on` and `/~/in` endpoints listening to `%c` updates.
326−- `(map duct live)`, inbound request state
327−- `(map ixor oryx)`, open `/~/of` streams.
328−- `(map oryx stem)`, open view state.
329−- `(map hole sink)`, session state.
330−- `(map hole ,[ship ?])`, foreign session names, along with their origin ships and whether they are authorized to act on our behalf.
474+
475+- `path` <a id="prefix"/> the default path which is prepended to relative
476+ plain requests. Initialized to `/<our>`, the serving ship; this interprets
477+ the first element of requests as a desk, and injects a `case` of `0`.
478+- `(jar ship hart)` remembered hostnames in order of preference, made
479+ accessible through `.^`
480+- The default values(for self) are `http://<ship>.urbit.org:80` if not on a
481+ fake network, followed by `https://0.0.0.0:[port]`.
482+- `(jug deps (each duct oryx))`, `/~/on` and `/~/in` endpoints listening to
483+ `%c` updates.
484+- `(map duct live)`, inbound request state
485+- `(map ixor oryx)`, open `/~/of` streams.
486+- `(map oryx stem)`, open view state.
487+- `(map hole sink)`, session state.
488+- `(map hole ,[ship ?])`, foreign session names, along with their origin ships
489+ and whether they are authorized to act on our behalf.
331490
332491## 8.2 `live`, per-request state <a id="live"/>
333−To honor request cancellations, each unserved request must track which effect it is causing.
334−+ `[%exec whir]` if it is a ford data request
335−+ `[%wasp (list @uvH)]` if it is a ford dependency poll
336−+ `[%xeno ship]` if this is a proxied request
337−+ `[%poll ixor]` if this is a session long-poll
492+
493+To honor request cancellations, each unserved request must track which effect it
494+is causing. + `[%exec whir]` if it is a ford data request +
495+`[%wasp (list @uvH)]` if it is a ford dependency poll + `[%xeno ship]` if this
496+is a proxied request + `[%poll ixor]` if this is a session long-poll
338497
339498## 8.3 `sink`, per-session state <a id="sink"/>
340−Each `hole` has associated authentication state.
341−- `priv`, a random secret that verifies the session, stored in cookie.
342−- `[ship (set ship)]`, the `ship` a session is acting as and any others it has been authorized with.
343−- `(jug ship ,[path duct])`, authentication `/~/as` requests waiting on foreign ships.
344−- `(set oryx)`, views associated with this session. Dual of `hole` in `stem`.
499+
500+Each `hole` has associated authentication state. - `priv`, a random secret that
501+verifies the session, stored in cookie. - `[ship (set ship)]`, the `ship` a
502+session is acting as and any others it has been authorized with. -
503+`(jug ship ,[path duct])`, authentication `/~/as` requests waiting on foreign
504+ships. - `(set oryx)`, views associated with this session. Dual of `hole` in
505+`stem`.
345506
346507## 8.4 `stem`, per-view state <a id="stem"/>
347−Each `oryx` has active subscription state.
348−- `hole`, session in which this view resides. Dual of `(set oryx)` in `sink`.
349−- `ixor`<a id="ixor"/>, a cached hash of the `oryx` that is used as a subscription id, by the `/~/of` EventStream.
350−- `[,@u (map ,@u even)]`, queued [events](#even). Has a maximum size.
351−- `(unit ,[duct @u ?])`, http connection, its last received event, and whether it is a long-poll request.
352−- `(set deps)`, subscribed `/~/in` points. Mirrored in `bolo`.
353−- `(map ,[hasp path] mark)`, subscribed `/~/is` points
354−- `(que duct)`, where any `%nice`/`%mean
508+
509+Each `oryx` has active subscription state. - `hole`, session in which this view
510+resides. Dual of `(set oryx)` in `sink`. - `ixor`<a id="ixor"/>, a cached hash
511+of the `oryx` that is used as a subscription id, by the `/~/of` EventStream. -
512+`[,@u (map ,@u even)]`, queued [events](#even). Has a maximum size. -
513+`(unit ,[duct @u ?])`, http connection, its last received event, and whether it
514+is a long-poll request. - `(set deps)`, subscribed `/~/in` points. Mirrored in
515+`bolo`. - `(map ,[hasp path] mark)`, subscribed `/~/is` points - `(que duct)`,
516+where any `%nice`/\`%mean
355517
356518# Appendix A: Glossary
357−- An `oryx` is a CSRF token used for [authenticated requests](#auth)
358−- `mean.json`<a id="mean-json"/> is a rendering of hoon `ares`: an error message formatted as `{fail:'type',mess:"Error message"}`
359−- `urb.js`<a id="urb-js"/> is the standard client-side implementation of the `%eyre` protocols, normally found in `/=main=/lib`
360−- The act of "serving"<a id="mime"/>, refers to the wrapping of a `%mime` cage in an HTTP `200 Success` response, and errors or other marks being [sent to ford](#done) for conversion. Inside a `sign`, this conversion occurs along the same [`wire`](#wire); otherwise, the `wire` is [empty](#wire-drop).
519+
520+- An `oryx` is a CSRF token used for [authenticated requests](#auth)
521+- `mean.json`<a id="mean-json"/> is a rendering of hoon `ares`: an error
522+ message formatted as `{fail:'type',mess:"Error message"}`
523+- `urb.js`<a id="urb-js"/> is the standard client-side implementation of the
524+ `%eyre` protocols, normally found in `/=main=/lib`
525+- The act of "serving"<a id="mime"/>, refers to the wrapping of a `%mime` cage
526+ in an HTTP `200 Success` response, and errors or other marks being [sent to
527+ ford](#done) for conversion. Inside a `sign`, this conversion occurs along
528+ the same [`wire`](#wire); otherwise, the `wire` is [empty](#wire-drop).
361529
362530# Appendix B: EventSource <a id="eventsource"/>
363531
@@ -365,12 +533,10 @@ UNIMPLEMENTED
365533
366534For more information, see <http://dev.w3.org/html5/eventsource/>
367535
368−An EventSource is a stream of events, encoded in a conceptually infinite `GET` request. Each event is formatted as
369− ```http
370− id: {number}
371− event: {type}
372− data: {contents}
373− data: {more-contents}
374− ```
536+An EventSource is a stream of events, encoded in a conceptually infinite `GET`
537+request. Each event is formatted as
538+`http id: {number} event: {type} data: {contents} data: {more-contents}`
375539
376−Data lines are joined by ASCII `10` newline characters; multiple newlines signify separate events. The `id` is used in a `Last-Event-ID` HTTP request header upon reconnection.
540+Data lines are joined by ASCII `10` newline characters; multiple newlines
541+signify separate events. The `id` is used in a `Last-Event-ID` HTTP request
542+header upon reconnection.
docs/arvo/internals/ford.md+47−55
@@ -1,53 +1,47 @@
11---
2−navhome: /docs/
2+navhome: '/docs/'
33sort: 6
44---
55
6−
7−`%ford`
8−=======
6+# `%ford`
97
108Our typed and marked computation engine.
119
12−A variety of different services are provided by `%ford`, but they mostly
13−involve compiling hook files, slapping/slammming code with marked data,
14−and converting data between marks, including validating data to a mark.
15−Throughout every computation, `%ford` keeps track of which resources are
16−dependencies so that the client may be aware when one or more
17−dependencies are updated.
10+A variety of different services are provided by `%ford`, but they mostly involve
11+compiling hook files, slapping/slammming code with marked data, and converting
12+data between marks, including validating data to a mark. Throughout every
13+computation, `%ford` keeps track of which resources are dependencies so that the
14+client may be aware when one or more dependencies are updated.
1815
19−`%ford` neither accepts unix events nor produces effects. It exists
20−entirely for the benefit of applications and other vanes, in particular
21−`%gall`. `%eyre` exposes the functional publishing aspects of `%ford`
22−while `%gall` uses `%ford` to control the execution of applications.
23−`%clay` is intended to use `%ford` to managed marked data, but this is
24−not yet reality.
16+`%ford` neither accepts unix events nor produces effects. It exists entirely for
17+the benefit of applications and other vanes, in particular `%gall`. `%eyre`
18+exposes the functional publishing aspects of `%ford` while `%gall` uses `%ford`
19+to control the execution of applications. `%clay` is intended to use `%ford` to
20+managed marked data, but this is not yet reality.
2521
2622<list></list>
2723
28−Cards
29−-----
24+## Cards
3025
31−`%ford` accepts just one card, `%exec`. This is misleading, however,
32−since there are fourteen different `silk`s that may be used with it. In
33−every case, the expected response to a `%exec` card is a `%made` gift
34−with either an error or the produced result along with its set of
35−dependencies.
26+`%ford` accepts just one card, `%exec`. This is misleading, however, since there
27+are fourteen different `silk`s that may be used with it. In every case, the
28+expected response to a `%exec` card is a `%made` gift with either an error or
29+the produced result along with its set of dependencies.
3630
37−Silks may autocons, so that the product of a cell of silks is a cell of
38−the product of the two silks.
31+Silks may autocons, so that the product of a cell of silks is a cell of the
32+product of the two silks.
3933
4034### `%bake`
4135
42−Tries to functionally produce the file at a given beam with the given
43−mark and heel. It fails if there is no way to translate at this level.
36+Tries to functionally produce the file at a given beam with the given mark and
37+heel. It fails if there is no way to translate at this level.
4438
4539### `%boil`
4640
47−Functionally produces the file at a given beam with the given mark and
48−heel. If there is no way to translate at this beam, we pop levels off
49−the stack and attempt to bake there until we find a level we can bake.
50−This should almost always be called instead of `%bake`.
41+Functionally produces the file at a given beam with the given mark and heel. If
42+there is no way to translate at this beam, we pop levels off the stack and
43+attempt to bake there until we find a level we can bake. This should almost
44+always be called instead of `%bake`.
5145
5246### `%call`
5347
@@ -55,52 +49,50 @@ Slams the result of one silk against the result of another.
5549
5650### `%cast`
5751
58−Translates the given silk to the given mark, if possible. This is one of
59−the critical and fundamental operations of ford.
52+Translates the given silk to the given mark, if possible. This is one of the
53+critical and fundamental operations of ford.
6054
6155### `%diff`
6256
63−Diffs the two given silks (which must be of the same mark), producing a
64−cage of the mark specified in `++mark` in `++grad` for the mark of the
65−two silks.
57+Diffs the two given silks (which must be of the same mark), producing a cage of
58+the mark specified in `++mark` in `++grad` for the mark of the two silks.
6659
6760### `%done`
6861
69−Produces exactly its input. This is rarely used on its own, but many
70−silks are recursively defined in terms of other silks, so we often need
71−a silk that simply produces its input. A monadic return, if you will.
62+Produces exactly its input. This is rarely used on its own, but many silks are
63+recursively defined in terms of other silks, so we often need a silk that simply
64+produces its input. A monadic return, if you will.
7265
7366### `%dude`
7467
75−Computes the given silk with the given tank as part of the stack trace
76−if there is an error.
68+Computes the given silk with the given tank as part of the stack trace if there
69+is an error.
7770
7871### `%dune`
7972
80−Produces an error if the cage is empty. Otherwise, it produces the value
81−in the unit.
73+Produces an error if the cage is empty. Otherwise, it produces the value in the
74+unit.
8275
8376### `%mute`
8477
85−Takes a silk and a list of changes to make to the silk. At each wing in
86−the list we put the value of the associated silk.
78+Takes a silk and a list of changes to make to the silk. At each wing in the list
79+we put the value of the associated silk.
8780
8881### `%pact`
8982
90−Applies the second silk as a patch to the first silk. The second silk
91−must be of the mark specified in `++mark` in `++grad` for the mark of
92−the first silk.
83+Applies the second silk as a patch to the first silk. The second silk must be of
84+the mark specified in `++mark` in `++grad` for the mark of the first silk.
9385
9486### `%plan`
9587
96−Performs a structured assembly directly. This is not generally directly
97−useful because several other silks perform supersets of this
98−functionality. We don't usually have naked hoods outside ford.
88+Performs a structured assembly directly. This is not generally directly useful
89+because several other silks perform supersets of this functionality. We don't
90+usually have naked hoods outside ford.
9991
10092### `%reef`
10193
102−Produces a core containing the entirety of zuse and hoon, suitable for
103−running arbitrary code against. The mark is `%noun`.
94+Produces a core containing the entirety of zuse and hoon, suitable for running
95+arbitrary code against. The mark is `%noun`.
10496
10597### `%ride`
10698
@@ -108,5 +100,5 @@ Slaps a twig against a subject silk. The mark of the result is `%noun`.
108100
109101### `%vale`
110102
111−Validates untyped data from a ship against a given mark. This is an
112−extremely useful function.
103+Validates untyped data from a ship against a given mark. This is an extremely
104+useful function.
docs/arvo/internals/ford/commentary.md+852−956
@@ -1,13 +1,10 @@
11---
2−navhome: /docs/
2+navhome: '/docs/'
33---
44
5+# Reference
56
6−Reference
7−=========
8−
9−Data Models
10−-----------
7+## Data Models
118
129### `++axle`, formal state
1310
@@ -16,13 +13,13 @@ Data Models
1613 pol=(map ship baby) ::
1714 == ::
1815
19−This is the formal state of our vane. Anything that must be remembered
20−between calls to ford must be stored here. The number `%1` is a version
21−number for our state that allows us to upgrade the structure of our
22−state in the future if we wish.
16+This is the formal state of our vane. Anything that must be remembered between
17+calls to ford must be stored here. The number `%1` is a version number for our
18+state that allows us to upgrade the structure of our state in the future if we
19+wish.
2320
24−`pol` is the a map from every ship on our pier to their individual ford
25−state. There is no shared ford state -- every ship is entirely separate.
21+`pol` is the a map from every ship on our pier to their individual ford state.
22+There is no shared ford state -- every ship is entirely separate.
2623
2724### `++baby`, state by ship
2825
@@ -34,19 +31,18 @@ state. There is no shared ford state -- every ship is entirely separate.
3431
3532This is the state specific to each ship.
3633
37−`tad` and `dym` keep track of the tasks we're currently working on.
38−`dym` is a map from ducts to task numbers, and `q.tad` is a map from
39−task number to the task itself. `p.tad` is the next available task
40−number. Thus, the keys of `q.tad` are a subset of the numbers less than
41−`p.tad`, and ford has attempted exactly `p.tad` tasks so far.
34+`tad` and `dym` keep track of the tasks we're currently working on. `dym` is a
35+map from ducts to task numbers, and `q.tad` is a map from task number to the
36+task itself. `p.tad` is the next available task number. Thus, the keys of
37+`q.tad` are a subset of the numbers less than `p.tad`, and ford has attempted
38+exactly `p.tad` tasks so far.
4239
43−`jav` is the cache of previously-solved problems. The keys are a pair of
44−a term (either `%hood`, `%slap`, or `%slam`) and a noun that represents
45−the exact problem solved. In the case of a `%hood`, then, the key is of
46−the form `[%hood beam cage]`. For `%slap`, there is `[%slap vase twig]`.
47−For `%slam`, there is `[%slam vase vase]`. The values are the result of
48−solving the problem. Note that this cache is wiped in `++stay` when ford
49−is reloaded.
40+`jav` is the cache of previously-solved problems. The keys are a pair of a term
41+(either `%hood`, `%slap`, or `%slam`) and a noun that represents the exact
42+problem solved. In the case of a `%hood`, then, the key is of the form
43+`[%hood beam cage]`. For `%slap`, there is `[%slap vase twig]`. For `%slam`,
44+there is `[%slam vase vase]`. The values are the result of solving the problem.
45+Note that this cache is wiped in `++stay` when ford is reloaded.
5046
5147### `++task`, problem in progress
5248
@@ -56,12 +52,12 @@ is reloaded.
5652 kig=[p=@ud q=(map ,@ud beam)] :: blocks
5753 == ::
5854
59−This is all the state we keep regarding a particular task. `nah` is the
60−duct which asked us to solve the problem, and `kas` is the most recent
61−statement of the problem.
55+This is all the state we keep regarding a particular task. `nah` is the duct
56+which asked us to solve the problem, and `kas` is the most recent statement of
57+the problem.
6258
63−`kig` keeps track of which resources we are blocked on. Our blocks are
64−stored by index in `q.kig`, and the next available index is `p.kig`.
59+`kig` keeps track of which resources we are blocked on. Our blocks are stored by
60+index in `q.kig`, and the next available index is `p.kig`.
6561
6662### `++silk`, problem
6763
@@ -83,13 +79,12 @@ stored by index in `q.kig`, and the next available index is `p.kig`.
8379 [%vale p=mark q=ship r=*] :: validate [our his]
8480 == ::
8581
86−This is the every type of problem we can solve. Every `%exec` kiss that
87−requests us to solve a problem must choose one of these problems to
88−solve.
82+This is the every type of problem we can solve. Every `%exec` kiss that requests
83+us to solve a problem must choose one of these problems to solve.
8984
90−Because this is both an internal structure used in ford and the public
91−interface to ford, we choose to document this structure in our
92−discussion of the public interface to ford below.
85+Because this is both an internal structure used in ford and the public interface
86+to ford, we choose to document this structure in our discussion of the public
87+interface to ford below.
9388
9489### `++calx`, cache line
9590
@@ -99,20 +94,19 @@ discussion of the public interface to ford below.
9994 [%slam p=calm q=[p=vase q=vase] r=vase] :: compute
10095 == ::
10196
102−There are three kinds of cache entries. Every entry includes some
103−metadata in `p` and is the combination of an input and its output.
97+There are three kinds of cache entries. Every entry includes some metadata in
98+`p` and is the combination of an input and its output.
10499
105−The input to a `%hood` is the location of the resource and a cage
106−representing the data at that location. The output is the hood found by
107−compiling the given cage at the given location.
100+The input to a `%hood` is the location of the resource and a cage representing
101+the data at that location. The output is the hood found by compiling the given
102+cage at the given location.
108103
109−The input to a `%slap` is the vase of the subject and the twig of the
110−formula against which we are slapping the subject. The output is the
111−vase produced by slapping them.
104+The input to a `%slap` is the vase of the subject and the twig of the formula
105+against which we are slapping the subject. The output is the vase produced by
106+slapping them.
112107
113−The input to a `%slam` is the vase of the subject and the vase of the
114−gate which we are slapping. The output is the vase produced by slamming
115−them.
108+The input to a `%slam` is the vase of the subject and the vase of the gate which
109+we are slapping. The output is the vase produced by slamming them.
116110
117111### `++calm`, cache line metadata
118112
@@ -121,9 +115,9 @@ them.
121115 dep=(set beam) :: dependencies
122116 == ::
123117
124−Every line in the cache needs to have two pieces of metadata. We must
125−know the last time this line in the cache was accessed, and we must know
126−what are the dependencies of this line.
118+Every line in the cache needs to have two pieces of metadata. We must know the
119+last time this line in the cache was accessed, and we must know what are the
120+dependencies of this line.
127121
128122### `++hood`, assembly components
129123
@@ -137,46 +131,43 @@ what are the dependencies of this line.
137131
138132When assembling a hook file, we split it into several sections.
139133
140−`zus` is the kelvin version of the required zuse. In general, we assume
141−that any newer (lower-numbered) zuse will retain backward compatibility,
142−so any newer zuse is also permissible. This number is set with a `/?` at
143−the beginning of the file.
134+`zus` is the kelvin version of the required zuse. In general, we assume that any
135+newer (lower-numbered) zuse will retain backward compatibility, so any newer
136+zuse is also permissible. This number is set with a `/?` at the beginning of the
137+file.
144138
145−`sur` is the set of structures included. These are included with the
146−`/-` rune. When a structure is included, we look in `/=main=/sur` for
147−the given structure and we load the gate there. When compiling, all the
148−included structures are collected into a single core placed in the
149−subject of the body with a `=>`.
139+`sur` is the set of structures included. These are included with the `/-` rune.
140+When a structure is included, we look in `/=main=/sur` for the given structure
141+and we load the gate there. When compiling, all the included structures are
142+collected into a single core placed in the subject of the body with a `=>`.
150143
151−`lib` is the set of librarires included. These are included with the
152−`/+` rune. When a library is included, we look in `/=main=/lib` for the
153−given library and we load the library there. As with structures, all the
154−included libraries are collected into a single core placed in the
155−subject of the body with a `=>`.
144+`lib` is the set of librarires included. These are included with the `/+` rune.
145+When a library is included, we look in `/=main=/lib` for the given library and
146+we load the library there. As with structures, all the included libraries are
147+collected into a single core placed in the subject of the body with a `=>`.
156148
157−`fan` is the set of resources included. These are loaded in many
158−different ways and may load resources from any location. These are
159−placed in the subject of the body with a `=~`.
149+`fan` is the set of resources included. These are loaded in many different ways
150+and may load resources from any location. These are placed in the subject of the
151+body with a `=~`.
160152
161−`src` is the set of twigs or references to twigs in the body of the
162−program. Generally, each of these will represent a core, but this is not
163−required. When compiling, these are strung together in a `=~`.
153+`src` is the set of twigs or references to twigs in the body of the program.
154+Generally, each of these will represent a core, but this is not required. When
155+compiling, these are strung together in a `=~`.
164156
165157### `++hoot`
166158
167159 ++ hoot (pair bean hoof) :: structure gate/core
168160
169−A structures may be either a direct gate or a core. These are
170−syntactically distinguished by adding a `*` to the beginning of the
171−structure name for a core. The structure itself is a `hoof`.
161+A structures may be either a direct gate or a core. These are syntactically
162+distinguished by adding a `*` to the beginning of the structure name for a core.
163+The structure itself is a `hoof`.
172164
173165### `++hoof`
174166
175167 ++ hoof (pair term (unit (pair case ship))) :: resource reference
176168
177−A hoof, which is either a structure or a library, has a name, and it may
178−also specify which version of the resource to use and which ship to
179−retrieve it from.
169+A hoof, which is either a structure or a library, has a name, and it may also
170+specify which version of the resource to use and which ship to retrieve it from.
180171
181172### `++horn`
182173
@@ -202,44 +193,42 @@ discussion of their use from a user's perspective is documented in the [runes
202193documentation](https://urbit.org/docs/arvo/internals/runes), so we will here
203194only give a description of the data structure itself.
204195
205−A `%ape` horn is simply a twig that gets evaluated and placed in the
206−subject.
196+A `%ape` horn is simply a twig that gets evaluated and placed in the subject.
207197
208−A `%arg` is a gate that gets evaluated with a sample of our location and
209−our heel.
198+A `%arg` is a gate that gets evaluated with a sample of our location and our
199+heel.
210200
211−A `%day` is a horn that applies to each of a list of `@dr`-named files
212−in the directory.
201+A `%day` is a horn that applies to each of a list of `@dr`-named files in the
202+directory.
213203
214−A `%dub` is a term and horn, where the result of a horn is given the
215−face of the term.
204+A `%dub` is a term and horn, where the result of a horn is given the face of the
205+term.
216206
217207A `%fan` is a list of horns, all at the current directory level.
218208
219−A `%for` is a path and a horn, where the horn is evaluated relative to
220−the given path, where the given path is relative to the current
221−location.
209+A `%for` is a path and a horn, where the horn is evaluated relative to the given
210+path, where the given path is relative to the current location.
222211
223−A `%hub` is a horn that applies to each of a list of `@ud`-named files
224−in the directory.
212+A `%hub` is a horn that applies to each of a list of `@ud`-named files in the
213+directory.
225214
226−A `%man` is a map of spans to horns where the result is a set of each
227−horn applied to the current directory given the associated face.
215+A `%man` is a map of spans to horns where the result is a set of each horn
216+applied to the current directory given the associated face.
228217
229−A `%nap` is a homogenous map where each entry in a directory is handled
230−with the same horn and is given a face according to its name.
218+A `%nap` is a homogenous map where each entry in a directory is handled with the
219+same horn and is given a face according to its name.
231220
232−A `%now` is a horn that applies to each of a list of `@da`-named files
233−in the directory.
221+A `%now` is a horn that applies to each of a list of `@da`-named files in the
222+directory.
234223
235−A `%saw` is a twig and a horn, where the twig operates on the result of
236−the horn.
224+A `%saw` is a twig and a horn, where the twig operates on the result of the
225+horn.
237226
238−A `%see` is a beam and a horn, where the horn is evaluated at a location
239−of the given beam.
227+A `%see` is a beam and a horn, where the horn is evaluated at a location of the
228+given beam.
240229
241−A `%sic` is a tile and a horn, where the horn is evaluated and cast to
242−the type associated with the tile.
230+A `%sic` is a tile and a horn, where the horn is evaluated and cast to the type
231+associated with the tile.
243232
244233A `%toy` is simply a mark to be baked.
245234
@@ -250,9 +239,9 @@ A `%toy` is simply a mark to be baked.
250239 [%| p=beam] :: resource location
251240 == ::
252241
253−This is an entry in the body of the hook file. The hoop can either be
254−defined directly in the given file or it can be a reference to another
255−file. The second is specified with a `//` rune.
242+This is an entry in the body of the hook file. The hoop can either be defined
243+directly in the given file or it can be a reference to another file. The second
244+is specified with a `//` rune.
256245
257246### `++bolt`, monadic edge
258247
@@ -266,28 +255,27 @@ file. The second is specified with a `//` rune.
266255 == ::
267256 == ::
268257
269−Throughout our computation, we let our result flow through with the set
270−of dependencies of the value. At various times, we may wish to either
271−throw an error or declare that the actual result cannot be found until a
272−particular resource is retrieved. This is a perfect case for a monad, so
273−here we define a data structure for it.
258+Throughout our computation, we let our result flow through with the set of
259+dependencies of the value. At various times, we may wish to either throw an
260+error or declare that the actual result cannot be found until a particular
261+resource is retrieved. This is a perfect case for a monad, so here we define a
262+data structure for it.
274263
275−At every step, we have a cache, so we store that in `p`. In `q` we store
276−the data.
264+At every step, we have a cache, so we store that in `p`. In `q` we store the
265+data.
277266
278−In the case of `%0`, we have the result in `q` and the set of
279−dependencies in `p`.
267+In the case of `%0`, we have the result in `q` and the set of dependencies in
268+`p`.
280269
281−In the case of `%1`, we have a set of dependencies on which we are
282−blocking. When this happens, we make a call to clay to get the
283−dependencies, and we proceed with the computation when we receive them.
284−Technically, we restart the computation, but since every expensive step
285−is cached, there is no significant performance penalty to doing this.
286−Referential transparency has its uses.
270+In the case of `%1`, we have a set of dependencies on which we are blocking.
271+When this happens, we make a call to clay to get the dependencies, and we
272+proceed with the computation when we receive them. Technically, we restart the
273+computation, but since every expensive step is cached, there is no significant
274+performance penalty to doing this. Referential transparency has its uses.
287275
288−In the case of `%2`, we have a hit an error. This gets passed all the
289−way through to the calling duct. The list of tanks is some description
290−of what went wrong, often including a stack trace.
276+In the case of `%2`, we have a hit an error. This gets passed all the way
277+through to the calling duct. The list of tanks is some description of what went
278+wrong, often including a stack trace.
291279
292280### `++burg`, monadic rule
293281
@@ -296,53 +284,49 @@ of what went wrong, often including a stack trace.
296284 $+([c=cafe d=a] (bolt b)) ::
297285 :: ::
298286
299−To operate on bolts, we use `++cope` as our bind operator, and the
300−functions it works on are of type `burg`. Our functions that operate on
301−bolts should have a sample of the cache and a value. Their output should
302−be a bolt of the output value. Then, `++cope` will only call the
303−function when necessary (in the `%0` case), and it will do so without
304−the wrapping of a bolt.
287+To operate on bolts, we use `++cope` as our bind operator, and the functions it
288+works on are of type `burg`. Our functions that operate on bolts should have a
289+sample of the cache and a value. Their output should be a bolt of the output
290+value. Then, `++cope` will only call the function when necessary (in the `%0`
291+case), and it will do so without the wrapping of a bolt.
305292
306−If you understand monads, this is probably fairly obvious. Otherwise,
307−see the discussion on `++cope` (link).
293+If you understand monads, this is probably fairly obvious. Otherwise, see the
294+discussion on `++cope` (link).
308295
309−Public Interface
310−----------------
296+## Public Interface
311297
312−Ford does not export a scry interface, so the only way to interact with
313−ford is by sending kisses and receiving gifts. In fact, ford only sends
314−accepts one kiss and gives one gift. This is, of course, misleading
315−because ford actually does many different things. It does, however, only
316−produce one type of thing -- a result of a computation, which is either
317−an error or the value produced along with the set of dependencies
318−referenced by it.
298+Ford does not export a scry interface, so the only way to interact with ford is
299+by sending kisses and receiving gifts. In fact, ford only sends accepts one kiss
300+and gives one gift. This is, of course, misleading because ford actually does
301+many different things. It does, however, only produce one type of thing -- a
302+result of a computation, which is either an error or the value produced along
303+with the set of dependencies referenced by it.
319304
320305 ++ kiss :: in request ->$
321306 $% [%exec p=@p q=(unit silk)] :: make / kill
322307 == ::
323308
324309The `%exec` gift requests ford to perform a computation on behalf of a
325−particular ship. `p` is the ship, and `q` is the computation. If `q` is
326−null, then we are requesting that ford cancel the computation that it is
327−currently being run along this duct. Thus, if you wish to cancel a
328−computation, you must send the kiss along the same duct as the original
329−request.
310+particular ship. `p` is the ship, and `q` is the computation. If `q` is null,
311+then we are requesting that ford cancel the computation that it is currently
312+being run along this duct. Thus, if you wish to cancel a computation, you must
313+send the kiss along the same duct as the original request.
330314
331−Otherwise, we ask ford to perform a certain computation, as defined in
332−`++silk`. Since all computations produce the same type of result, we
333−will discuss that result before we jump into `++silk`.
315+Otherwise, we ask ford to perform a certain computation, as defined in `++silk`.
316+Since all computations produce the same type of result, we will discuss that
317+result before we jump into `++silk`.
334318
335319 ++ gift :: out result <-$
336320 $% [%made p=(each bead (list tank))] :: computed result
337321 == ::
338322
339−We give either a `bead`, which is a result, or a list of tanks, which is
340−an error messge, often including a stack trace.
323+We give either a `bead`, which is a result, or a list of tanks, which is an
324+error messge, often including a stack trace.
341325
342326 ++ bead ,[p=(set beam) q=cage] :: computed result
343327
344−This is a set of dependencies required to compute this value and a cage
345−of the result with its associated mark.
328+This is a set of dependencies required to compute this value and a cage of the
329+result with its associated mark.
346330
347331There are twelve possible computations defined in `++silk`.
348332
@@ -362,83 +346,77 @@ There are twelve possible computations defined in `++silk`.
362346 [%vale p=mark q=ship r=*] :: validate [our his]
363347 == ::
364348
365−First, we allow silks to autocons. A cell of silks is also a silk, and
366−the product vase is a cell of the two silks. This obviously extends to
367−an arbitrary number of silks.
349+First, we allow silks to autocons. A cell of silks is also a silk, and the
350+product vase is a cell of the two silks. This obviously extends to an arbitrary
351+number of silks.
368352
369−`%bake` tries to functionally produce the file at a given beam with the
370−given mark and heel. It fails if there is no way to translate at this
371−level.
353+`%bake` tries to functionally produce the file at a given beam with the given
354+mark and heel. It fails if there is no way to translate at this level.
372355
373−`%boil` functionally produces the file at a given beam with the given
374−mark and heel. If there is no way to translate at this beam, we pop
375−levels off the stack and attempt to bake there until we find a level we
376−can bake. This should almost always be called instead of `%bake`.
356+`%boil` functionally produces the file at a given beam with the given mark and
357+heel. If there is no way to translate at this beam, we pop levels off the stack
358+and attempt to bake there until we find a level we can bake. This should almost
359+always be called instead of `%bake`.
377360
378361`%call` slams the result of one silk against the result of another.
379362
380−`%cast` translates the given silk to the given mark, if possible. This
381−is one of the critical and fundamental operations of ford.
363+`%cast` translates the given silk to the given mark, if possible. This is one of
364+the critical and fundamental operations of ford.
382365
383−`%done` produces exactly its input. This is rarely used on its own, but
384−many silks are recursively defined in terms of other silks, so we often
385−need a silk that simply produces its input. A monadic return, if you
386−will.
366+`%done` produces exactly its input. This is rarely used on its own, but many
367+silks are recursively defined in terms of other silks, so we often need a silk
368+that simply produces its input. A monadic return, if you will.
387369
388−`%diff` diffs the two given silks (which must be of the same mark),
389−producing a cage of the mark specified in `++mark` in `++grad` for the
390−mark of the two silks.
370+`%diff` diffs the two given silks (which must be of the same mark), producing a
371+cage of the mark specified in `++mark` in `++grad` for the mark of the two
372+silks.
391373
392−`%dude` computes the given silk with the given tank as part of the stack
393−trace if there is an error.
374+`%dude` computes the given silk with the given tank as part of the stack trace
375+if there is an error.
394376
395−`%dune` produces an error if the cage is empty. Otherwise, it produces
396−the value in the unit.
377+`%dune` produces an error if the cage is empty. Otherwise, it produces the value
378+in the unit.
397379
398−`%mute` takes a silk and a list of changes to make to the silk. At each
399−wing in the list we put the value of the associated silk.
380+`%mute` takes a silk and a list of changes to make to the silk. At each wing in
381+the list we put the value of the associated silk.
400382
401−`%pact` applies the second silk as a patch to the first silk. The second
402−silk must be of the mark specified in `++mark` in `++grad` for the mark
403−of the first silk.
383+`%pact` applies the second silk as a patch to the first silk. The second silk
384+must be of the mark specified in `++mark` in `++grad` for the mark of the first
385+silk.
404386
405−`%plan` performs a structured assembly directly. This is not generally
406−directly useful because several other silks perform supersets of this
407−functionality. We don't usually have naked hoods outside ford.
387+`%plan` performs a structured assembly directly. This is not generally directly
388+useful because several other silks perform supersets of this functionality. We
389+don't usually have naked hoods outside ford.
408390
409−`%reef` produces a core containing the entirety of zuse and hoon,
410−suitable for running arbitrary code against. The mark is `%noun`.
391+`%reef` produces a core containing the entirety of zuse and hoon, suitable for
392+running arbitrary code against. The mark is `%noun`.
411393
412−`%ride` slaps a twig against a subject silk. The mark of the result is
413−`%noun`.
394+`%ride` slaps a twig against a subject silk. The mark of the result is `%noun`.
414395
415−`%vale` validates untyped data from a ship against a given mark. This is
416−an extremely useful function.
396+`%vale` validates untyped data from a ship against a given mark. This is an
397+extremely useful function.
417398
418−Commentary
419−==========
399+# Commentary
420400
421−Parsing Hook Files
422−------------------
401+## Parsing Hook Files
423402
424−In the commentary on other vanes, we have traced through the lifecycle
425−of various external requests. This is generally a very reasonable order
426−to examine vanes since it will eventually cover the entire vane, and we
427−are never left wondering why we are doing something.
403+In the commentary on other vanes, we have traced through the lifecycle of
404+various external requests. This is generally a very reasonable order to examine
405+vanes since it will eventually cover the entire vane, and we are never left
406+wondering why we are doing something.
428407
429−For ford, however, it makes more sense to begin by discussing the
430−parsing and assembliing of hook files. Many of the possible requests
431−require us to assemble hook files, so we may as well examine this
432−immediately.
408+For ford, however, it makes more sense to begin by discussing the parsing and
409+assembliing of hook files. Many of the possible requests require us to assemble
410+hook files, so we may as well examine this immediately.
433411
434−First, we will examine the parsing. We parse a file at a beam to a hood
435−in `++fade:zo:za`. The top-level parsing rule is `++fair`, which takes a
436−beam and produces a rule to parse an entire hood file.
412+First, we will examine the parsing. We parse a file at a beam to a hood in
413+`++fade:zo:za`. The top-level parsing rule is `++fair`, which takes a beam and
414+produces a rule to parse an entire hood file.
437415
438−A note on the naming scheme: the parsing the combinators that parse into
439−a particular structure are conventionally given the same name as the
440−structure. Although this locally clobbers the type names, this pattern
441−makes obvious the intent of the parsing combinators.
416+A note on the naming scheme: the parsing the combinators that parse into a
417+particular structure are conventionally given the same name as the structure.
418+Although this locally clobbers the type names, this pattern makes obvious the
419+intent of the parsing combinators.
442420
443421We kick off with `++hood:fair`.
444422
@@ -464,24 +442,23 @@ We kick off with `++hood:fair`.
464442 (most gap hoop)
465443 ==
466444
467−There are five sections to a hood: system version, structures,
468−libraries, resources, and body.
445+There are five sections to a hood: system version, structures, libraries,
446+resources, and body.
469447
470−First, we parse the requested version number of the system. This is
471−specified with a unary `/?` rune. If not present, then we default to the
472−current version.
448+First, we parse the requested version number of the system. This is specified
449+with a unary `/?` rune. If not present, then we default to the current version.
473450
474−Second, we may have zero or more `/-` runes followed by a parsing of a
475−`++hoot`, which represents a shared structure.
451+Second, we may have zero or more `/-` runes followed by a parsing of a `++hoot`,
452+which represents a shared structure.
476453
477−Third, we may have zero or more `/+` runes followed by a parsing of a
478−`++hoof`, which represents a shared library.
454+Third, we may have zero or more `/+` runes followed by a parsing of a `++hoof`,
455+which represents a shared library.
479456
480−Fourth, we may have zero or more other `/` runes (as described in
481−`++horn`), which represent program-specific resources to be loaded.
457+Fourth, we may have zero or more other `/` runes (as described in `++horn`),
458+which represent program-specific resources to be loaded.
482459
483−Fifth and finally, we must have one or more body statements (hoops),
484−which are either direct twigs or `//` runes.
460+Fifth and finally, we must have one or more body statements (hoops), which are
461+either direct twigs or `//` runes.
485462
486463 ++ hoot
487464 ;~ pose
@@ -489,9 +466,9 @@ which are either direct twigs or `//` runes.
489466 (stag %& hoof)
490467 ==
491468
492−A structure can either be a direct gate, or it can be a simple core.
493−Either one is parsed with `++hoof`, so we distinguish the two cases by
494−requireing core references to be prefixed by a `*`.
469+A structure can either be a direct gate, or it can be a simple core. Either one
470+is parsed with `++hoof`, so we distinguish the two cases by requireing core
471+references to be prefixed by a `*`.
495472
496473 ++ hoof
497474 %+ cook |=(a=^hoof a)
@@ -504,11 +481,11 @@ requireing core references to be prefixed by a `*`.
504481 ==
505482 ==
506483
507−A hoof must have a name, which is a term. Optionally, we also include a
508−case and a ship. This is marked by appending a `/` followed by a case to
509−denote the requested version of the resource and a `/` followed by a
510−ship name to denote the requested source of the resource. For example,
511−`resource/1/~zod` requests the first version of `resource` on `~zod`.
484+A hoof must have a name, which is a term. Optionally, we also include a case and
485+a ship. This is marked by appending a `/` followed by a case to denote the
486+requested version of the resource and a `/` followed by a ship name to denote
487+the requested source of the resource. For example, `resource/1/~zod` requests
488+the first version of `resource` on `~zod`.
512489
513490 ++ case
514491 %- sear
@@ -517,11 +494,11 @@ ship name to denote the requested source of the resource. For example,
517494 ?. ?=([%$ ?(%da %ud %tas) *] a) ~
518495 [~ u=(^case a)]
519496
520−Here, we parse a literal with `++nuck:so`, and we accept the input if it
521−is either an absolute date, an unsigned decimal, or a label.
497+Here, we parse a literal with `++nuck:so`, and we accept the input if it is
498+either an absolute date, an unsigned decimal, or a label.
522499
523−This leaves only horns and hoops to parse. Hoops are much simple to
524−parse, so we'll discuss those first.
500+This leaves only horns and hoops to parse. Hoops are much simple to parse, so
501+we'll discuss those first.
525502
526503 ++ hoop
527504 ;~ pose
@@ -529,20 +506,20 @@ parse, so we'll discuss those first.
529506 (stag %& tall:vez)
530507 ==
531508
532−There are two types of hoops. Direct twigs are parsed with
533−`++tall:vast`, which is the just the hoon parser for a tall-form twig.
509+There are two types of hoops. Direct twigs are parsed with `++tall:vast`, which
510+is the just the hoon parser for a tall-form twig.
534511
535−References to external twigs are marked with a `//` rune followed by a
536−beam, which is parsed with `++have`.
512+References to external twigs are marked with a `//` rune followed by a beam,
513+which is parsed with `++have`.
537514
538515 ++ hath (sear plex:voz (stag %clsg poor:voz)) :: hood path
539516 ++ have (sear tome ;~(pfix fas hath)) :: hood beam
540517
541−`++have` parses a path with `++hath`, and then it converts the path into
542−a beam with `++tome`.
518+`++have` parses a path with `++hath`, and then it converts the path into a beam
519+with `++tome`.
543520
544−`++hath` parses a `/`-separated list with `++poor:vast`, then converts
545−it to an actual path with `++plex:vast`.
521+`++hath` parses a `/`-separated list with `++poor:vast`, then converts it to an
522+actual path with `++plex:vast`.
546523
547524This leaves only horns to parse.
548525
@@ -571,18 +548,17 @@ This leaves only horns to parse.
571548 ==
572549 ==
573550
574−Horn parsing is slightly complex, so we create an internal core to
575−organize our code. Our core has a global variable of `tol`, which is
576−true if tall form is permissible and false if we're already in wide
577−form. We kick off the parsing with `++apex`.
551+Horn parsing is slightly complex, so we create an internal core to organize our
552+code. Our core has a global variable of `tol`, which is true if tall form is
553+permissible and false if we're already in wide form. We kick off the parsing
554+with `++apex`.
578555
579−`++apex` specifies how each rune is parsed. This allows us to offload
580−the different ways of parsing the arguments to these runes into separate
581−arms. The exception here is that the `%toy` horn is simply of the form
582−`/mark/`.
556+`++apex` specifies how each rune is parsed. This allows us to offload the
557+different ways of parsing the arguments to these runes into separate arms. The
558+exception here is that the `%toy` horn is simply of the form `/mark/`.
583559
584−We'll examine each of the horn parsing arms right after we discuss
585−`++rail`, which is used in each one.
560+We'll examine each of the horn parsing arms right after we discuss `++rail`,
561+which is used in each one.
586562
587563 ++ rail
588564 |* [wid=_rule tal=_rule]
@@ -590,8 +566,8 @@ We'll examine each of the horn parsing arms right after we discuss
590566 ;~(pose wid tal)
591567
592568This takes a wide-form and a tall-form parsing rule. If tall form is
593−permissible, then it allows either rule to match; else, it allows only
594−the wide form rule.
569+permissible, then it allows either rule to match; else, it allows only the wide
570+form rule.
595571
596572 ++ read
597573 |% ++ ape
@@ -599,49 +575,47 @@ the wide form rule.
599575 (ifix [sel ser] (stag %cltr (most ace wide:vez)))
600576 ;~(pfix gap tall:vez)
601577
602−`++ape:read` parses for both the `/~` and the `/$` runes. It produces a
603−twig. The wide form is a tuple of one or more ace-separated wide-form
604−twigs parsed with `++wide:vast` and surrounded by `[` and `]`. The tall
605−form is a single tall form twig parsed by `++tall:vast`
578+`++ape:read` parses for both the `/~` and the `/$` runes. It produces a twig.
579+The wide form is a tuple of one or more ace-separated wide-form twigs parsed
580+with `++wide:vast` and surrounded by `[` and `]`. The tall form is a single tall
581+form twig parsed by `++tall:vast`
606582
607583 ++ day
608584 %+ rail
609585 apex(tol |)
610586 ;~(pfix gap apex)
611587
612−This parses for the `/|`, `/@`, `/%`, and `/&` runes. It produces a
613−horn. The wide form is, recursively, the entire horn parser with tall
614−form disabled. The tall form is a gap followed by, recursively, the
615−entire horn parser.
588+This parses for the `/|`, `/@`, `/%`, and `/&` runes. It produces a horn. The
589+wide form is, recursively, the entire horn parser with tall form disabled. The
590+tall form is a gap followed by, recursively, the entire horn parser.
616591
617592 ++ dub
618593 %+ rail
619594 ;~(plug sym ;~(pfix tis apex(tol |)))
620595 ;~(pfix gap ;~(plug sym ;~(pfix gap apex)))
621596
622−This parses for the `/=` rune. It produces a term followed by a horn.
623−The wide form is a symbol name followed by a `=` and, recursively, the
624−entire horn parser with tall form disabled. The tall form is a gap
625−followed by a symbol name, another gap, and, recursively, the entire
626−horn parser.
597+This parses for the `/=` rune. It produces a term followed by a horn. The wide
598+form is a symbol name followed by a `=` and, recursively, the entire horn parser
599+with tall form disabled. The tall form is a gap followed by a symbol name,
600+another gap, and, recursively, the entire horn parser.
627601
628602 ++ fan
629603 %+ rail fail
630604 ;~(sfix (star ;~(pfix gap apex)) ;~(plug gap duz))
631605
632−This parses for the `/.` rune. It produces a list of horns. There is no
633−wide form. The tall form is a stet-terminated series of gap-separated
634−recursive calls to the entire horn parser.
606+This parses for the `/.` rune. It produces a list of horns. There is no wide
607+form. The tall form is a stet-terminated series of gap-separated recursive calls
608+to the entire horn parser.
635609
636610 ++ for
637611 %+ rail
638612 ;~(plug (ifix [sel ser] hath) apex(tol |))
639613 ;~(pfix gap ;~(plug hath ;~(pfix gap apex)))
640614
641−This parses for the `/,` rune. It produces a path and a horn. The wide
642−form is a `[`-`]`-surrounded path followed by, recursively, the entire
643−horn parser with tall form disabled. The tall form is a gap followed by
644−a path, another gap, and, recursively, the entire horn parser.
615+This parses for the `/,` rune. It produces a path and a horn. The wide form is a
616+`[`-`]`-surrounded path followed by, recursively, the entire horn parser with
617+tall form disabled. The tall form is a gap followed by a path, another gap, and,
618+recursively, the entire horn parser.
645619
646620 ++ man
647621 %+ rail fail
@@ -654,31 +628,31 @@ a path, another gap, and, recursively, the entire horn parser.
654628 ?. ?=(%dub -.i.fan) ~
655629 $(fan t.fan, naf [[p.i.fan q.i.fan] naf])
656630
657−This parses for the `/*` rune. It produces a map of spans to horns.
658−There is no wide form. The tall form is a stet-terminated series of
659−gap-separated recursive calls to the entire horn parser. All produced
660−horns are expected to be from `/=` runes. The term and horn in each `/=`
661−horn is inserted into the produced map as a key-value pair.
631+This parses for the `/*` rune. It produces a map of spans to horns. There is no
632+wide form. The tall form is a stet-terminated series of gap-separated recursive
633+calls to the entire horn parser. All produced horns are expected to be from `/=`
634+runes. The term and horn in each `/=` horn is inserted into the produced map as
635+a key-value pair.
662636
663637 ++ saw
664638 %+ rail
665639 ;~(plug ;~(sfix wide:vez sem) apex(tol |))
666640 ;~(pfix gap ;~(plug tall:vez ;~(pfix gap apex)))
667641
668−This parses for the `/;` rune. It produces a twig and a horn. The wide
669−form is a wide-form twig followed by a `;` and, recursively, the entire
670−horn parser with tall form disabled. The tall form is a gap followed by
671−a tall-form twig, another gap, and, recursively, the entire horn parser.
642+This parses for the `/;` rune. It produces a twig and a horn. The wide form is a
643+wide-form twig followed by a `;` and, recursively, the entire horn parser with
644+tall form disabled. The tall form is a gap followed by a tall-form twig, another
645+gap, and, recursively, the entire horn parser.
672646
673647 ++ see
674648 %+ rail
675649 ;~(plug ;~(sfix have col) apex(tol |))
676650 ;~(pfix gap ;~(plug have ;~(pfix gap apex)))
677651
678−This parses for the `/:` rune. It produces a beam and a horn. The wide
679−form is a beam followed by a `;` and, recursively, the entire horn
680−parser with tall form disabled. The tall form is a gap followed by a
681−beam, another gap, and, recursively, the entire horn parser.
652+This parses for the `/:` rune. It produces a beam and a horn. The wide form is a
653+beam followed by a `;` and, recursively, the entire horn parser with tall form
654+disabled. The tall form is a gap followed by a beam, another gap, and,
655+recursively, the entire horn parser.
682656
683657 ++ sic
684658 %+ rail
@@ -686,18 +660,17 @@ beam, another gap, and, recursively, the entire horn parser.
686660 ;~(pfix gap ;~(plug howl:vez ;~(pfix gap apex)))
687661 --
688662
689−This parses for the `/^` rune. It produces a tile and a horn. The wide
690−form is a wide-form tile, parsed with `++toil:vast`, followed by a `^`
691−and, recursively, the entire horn parser with tall form disabled. The
692−tall form is a gap followed by a tall-form tile, parsed with
693−`++howl:vast`, another gap, and, recursively, the entire horn parser.
663+This parses for the `/^` rune. It produces a tile and a horn. The wide form is a
664+wide-form tile, parsed with `++toil:vast`, followed by a `^` and, recursively,
665+the entire horn parser with tall form disabled. The tall form is a gap followed
666+by a tall-form tile, parsed with `++howl:vast`, another gap, and, recursively,
667+the entire horn parser.
694668
695−Assembling Hook Files
696−---------------------
669+## Assembling Hook Files
697670
698−At this point, we've parsed a hook file into a hood. We will now
699−describe exactly how this hood is assembled into a vase. The problem of
700−assembling is handled entirely within the `++meow:zo:za` core.
671+At this point, we've parsed a hook file into a hood. We will now describe
672+exactly how this hood is assembled into a vase. The problem of assembling is
673+handled entirely within the `++meow:zo:za` core.
701674
702675 ++ meow :: assemble
703676 |= [how=beam arg=heel]
@@ -711,47 +684,45 @@ assembling is handled entirely within the `++meow:zo:za` core.
711684 ==
712685 |%
713686
714−We take two arguments and keep seven pieces of state. `how` is the
715−location of the hook file we're assembling, and `arg` is the heel, or
716−virtual path extension, of the file.
687+We take two arguments and keep seven pieces of state. `how` is the location of
688+the hook file we're assembling, and `arg` is the heel, or virtual path
689+extension, of the file.
717690
718−In `rop`, we maintain a map of terms to pairs of hooves and twigs to
719−represent the structures we've encountered that we will put together in
720−a core at the top of the file.
691+In `rop`, we maintain a map of terms to pairs of hooves and twigs to represent
692+the structures we've encountered that we will put together in a core at the top
693+of the file.
721694
722−In `zog`, we maintain the set of structures we're in the middle of
723−loading. If we try to load a structure already in our dependency
724−ancestry, then we fail because we do not allow circular dependencies.
725−This enforces that our structure dependency graph is a DAG.
695+In `zog`, we maintain the set of structures we're in the middle of loading. If
696+we try to load a structure already in our dependency ancestry, then we fail
697+because we do not allow circular dependencies. This enforces that our structure
698+dependency graph is a DAG.
726699
727−In `bil`, we maintain a map of terms to pairs of hooves and twigs to
728−represent the libraries we've encountered that we will put together in a
729−series of cores after the structure core.
700+In `bil`, we maintain a map of terms to pairs of hooves and twigs to represent
701+the libraries we've encountered that we will put together in a series of cores
702+after the structure core.
730703
731−In `lot`, we maintain a stack of library names as they are encountered
732−during a depth-first search. More precisely, we push a library onto the
733−stack after we've processed all its children. Thus, every library
734−depends only on things deeper in the list. The libraries must be loaded
735−in the reverse of this order. Concisely, this is a topological sort of
736−the library dependency partial ordering.
704+In `lot`, we maintain a stack of library names as they are encountered during a
705+depth-first search. More precisely, we push a library onto the stack after we've
706+processed all its children. Thus, every library depends only on things deeper in
707+the list. The libraries must be loaded in the reverse of this order. Concisely,
708+this is a topological sort of the library dependency partial ordering.
737709
738−In `zeg`, we maintain the set of libraries we're in the middle of
739−loading. If we try to load a library already in our dependency ancestry,
740−then we fail because we do not allow circular dependencies. This
741−enforces that our library dependency graph is a DAG.
710+In `zeg`, we maintain the set of libraries we're in the middle of loading. If we
711+try to load a library already in our dependency ancestry, then we fail because
712+we do not allow circular dependencies. This enforces that our library dependency
713+graph is a DAG.
742714
743−In `boy`, we maintain a stack of body twigs, which we'll put together in
744−a series of cores at the end of the file.
715+In `boy`, we maintain a stack of body twigs, which we'll put together in a
716+series of cores at the end of the file.
745717
746−In `hol`, we decide if we're allowed to contain horns. Libraries and
747−structures are not allowed to contain horns.
718+In `hol`, we decide if we're allowed to contain horns. Libraries and structures
719+are not allowed to contain horns.
748720
749−We in every case enter `++meow` through `++abut`. You'll notice that
750−there are four (count 'em, four!) calls to `++cope` in `++abut`. If
751−you've glanced at the ford code in general, you've probably seen cope
752−over and over. It is called in 79 different places. We need to discuss
753−the use of this critical function in detail, so we may as well do it
754−here.
721+We in every case enter `++meow` through `++abut`. You'll notice that there are
722+four (count 'em, four!) calls to `++cope` in `++abut`. If you've glanced at the
723+ford code in general, you've probably seen cope over and over. It is called in
724+79 different places. We need to discuss the use of this critical function in
725+detail, so we may as well do it here.
755726
756727 ++ cope :: bolt along
757728 |* [hoc=(bolt) fun=(burg)]
@@ -767,40 +738,36 @@ here.
767738 %0 [%0 p=(grom `_p.q.nuf`p.q.hoc p.q.nuf) q=q.q.nuf]
768739 == ==
769740
770−In monad-speak, this is the bind operator for the bolt monad. If monads
771−aren't your thing, don't worry, we're going to explain the use of cope
772−without further reference to them.
773−
774−Recall that there are three different types of bolt. A `%2` error bolt
775−contains a list of tanks describing the error, a `%1` block bolt
776−contains a set of resources we're blocked on, and a `%0` value bolt
777−contains an actual value and the set of its dependencies.
778−
779−We most commonly want to perform an operation on the value in a bolt if
780−it is a `%0` bolt. If it's not a `%0` bolt, we want to leave it alone.
781−This requires us to write a certain amount of boilerplate between each
782−of our operations to see if any of them produced a `%1` or a `%2` bolt.
783−This gets tiresome, so we pull it out into a separate arm and call it
784−`++cope`.
785−
786−Intuitively, we're calling the function `fun` with the value in `hoc`,
787−where `fun` takes an argument of type whatever is the value in a `%0`
788−case of `hoc`, and it produces a bolt of some (possibly different) type.
789−For brevity, we will refer to the type of the of the value in the `%0`
790−case of a bolt as the "type of the bolt".
791−
792−If the `hoc` bolt we're given as input to `fun` is already a `%1` or a
793−`%2` bolt, then we simply produce that. We don't even try to run `fun`
794−on it.
795−
796−Otherwise, we run `fun` with the arguments from the bolt and, if it
797−produces a `%1` or a `%2` bolt, we simply produce that. If it produces a
798−`%0` bolt, then we produce that with the old set of dependencies merged
799−in with the new set.
800−
801−We'll see more about how the bolt monad works as we run into more
802−interesting uses of it. For now, this is sufficient to move on with
803−`++abut`.
741+In monad-speak, this is the bind operator for the bolt monad. If monads aren't
742+your thing, don't worry, we're going to explain the use of cope without further
743+reference to them.
744+
745+Recall that there are three different types of bolt. A `%2` error bolt contains
746+a list of tanks describing the error, a `%1` block bolt contains a set of
747+resources we're blocked on, and a `%0` value bolt contains an actual value and
748+the set of its dependencies.
749+
750+We most commonly want to perform an operation on the value in a bolt if it is a
751+`%0` bolt. If it's not a `%0` bolt, we want to leave it alone. This requires us
752+to write a certain amount of boilerplate between each of our operations to see
753+if any of them produced a `%1` or a `%2` bolt. This gets tiresome, so we pull it
754+out into a separate arm and call it `++cope`.
755+
756+Intuitively, we're calling the function `fun` with the value in `hoc`, where
757+`fun` takes an argument of type whatever is the value in a `%0` case of `hoc`,
758+and it produces a bolt of some (possibly different) type. For brevity, we will
759+refer to the type of the of the value in the `%0` case of a bolt as the "type of
760+the bolt".
761+
762+If the `hoc` bolt we're given as input to `fun` is already a `%1` or a `%2`
763+bolt, then we simply produce that. We don't even try to run `fun` on it.
764+
765+Otherwise, we run `fun` with the arguments from the bolt and, if it produces a
766+`%1` or a `%2` bolt, we simply produce that. If it produces a `%0` bolt, then we
767+produce that with the old set of dependencies merged in with the new set.
768+
769+We'll see more about how the bolt monad works as we run into more interesting
770+uses of it. For now, this is sufficient to move on with `++abut`.
804771
805772 ++ abut :: generate
806773 |= [cof=cafe hyd=hood]
@@ -816,18 +783,17 @@ interesting uses of it. For now, this is sufficient to move on with
816783 |= [cof=cafe fin=vase]
817784 (fine cof fin)
818785
819−Our job is simple: we must assemble a hood file into a vase. Hopefully,
820−the usage of `++cope` is fairly understandable. The correct way to read
821−this is that it does essentially five things.
786+Our job is simple: we must assemble a hood file into a vase. Hopefully, the
787+usage of `++cope` is fairly understandable. The correct way to read this is that
788+it does essentially five things.
822789
823−First, we call `++apex` to process the structures, libraries, and body.
824−This changes our state, so we set our context to the produced context.
825−Second, we call `++able` to assemble the strucutres and libraries into a
826−twig, which we slap against zuse with `++maim`. Third, we call `++chap`
827−to process the resources in the context of the already-loaded structures
828−and libraries. Fourth, we slap the body against the structures,
829−libraries, and resources. Fifth and finally, we produce the resultant
830−vase.
790+First, we call `++apex` to process the structures, libraries, and body. This
791+changes our state, so we set our context to the produced context. Second, we
792+call `++able` to assemble the strucutres and libraries into a twig, which we
793+slap against zuse with `++maim`. Third, we call `++chap` to process the
794+resources in the context of the already-loaded structures and libraries. Fourth,
795+we slap the body against the structures, libraries, and resources. Fifth and
796+finally, we produce the resultant vase.
831797
832798 ++ apex :: build to body
833799 |= [cof=cafe hyd=hood]
@@ -852,9 +818,9 @@ Otherwise, we produce and error with `++flaw`.
852818
853819This produces a `%2` error bolt from a list of tanks. Fairly trivial.
854820
855−We should be starting to get used to the cope syntax, so we can see that
856−we really only do three things here. We process the body with `++body`,
857−the libraries with `++neck`, and the structures with `++head`.
821+We should be starting to get used to the cope syntax, so we can see that we
822+really only do three things here. We process the body with `++body`, the
823+libraries with `++neck`, and the structures with `++head`.
858824
859825 ++ body :: produce functions
860826 |= [cof=cafe src=(list hoop)]
@@ -864,19 +830,19 @@ the libraries with `++neck`, and the structures with `++head`.
864830 |= [cof=cafe sel=_..body]
865831 ^$(cof cof, src t.src, ..body sel)
866832
867−We must process a list of hoops that represent our body. If there are no
868−more hoops, we just produce our context in a `%0` bolt with `++fine`.
833+We must process a list of hoops that represent our body. If there are no more
834+hoops, we just produce our context in a `%0` bolt with `++fine`.
869835
870836 ++ fine |* [a=cafe b=*] :: bolt from data
871837 [p=`cafe`a q=[%0 p=*(set beam) q=b]] ::
872838
873−In monad-speak, this is the return operator. For us, this just means
874−that we're producing a `%0` bolt, which contains a path and a set of
875−dependencies. We assume there are no dependencies for the given data, or
876−that they will be added later.
839+In monad-speak, this is the return operator. For us, this just means that we're
840+producing a `%0` bolt, which contains a path and a set of dependencies. We
841+assume there are no dependencies for the given data, or that they will be added
842+later.
877843
878−If there are more hoops in `++body`, we call `++wilt` to process an
879−individual hoop and recurse.
844+If there are more hoops in `++body`, we call `++wilt` to process an individual
845+hoop and recurse.
880846
881847 ++ wilt :: process body entry
882848 |= [cof=cafe hop=hoop]
@@ -916,24 +882,22 @@ individual hoop and recurse.
916882 (fine cof sel(boy [[%brcn mav] boy]))
917883 ==
918884
919−In the case of a direct twig hoop, we just push it onto `boy` and we're
920−done. In the case of an indirect hoop, we must compile the referenced
921−file.
885+In the case of a direct twig hoop, we just push it onto `boy` and we're done. In
886+the case of an indirect hoop, we must compile the referenced file.
922887
923−First, we push onto the stack trace a message indicating which file
924−exactly we're compiling at the moment with `++cool`.
888+First, we push onto the stack trace a message indicating which file exactly
889+we're compiling at the moment with `++cool`.
925890
926891 ++ cool :: error caption
927892 |* [cyt=trap hoc=(bolt)]
928893 ?. ?=(%2 -.q.hoc) hoc
929894 [p.hoc [%2 *cyt p.q.hoc]]
930895
931−If an error occurred in computing `hoc`, we put the bunt of `cyt` onto
932−the stack trace. Thus, `cyt` is not evaluated at all unless an error
933−occurred.
896+If an error occurred in computing `hoc`, we put the bunt of `cyt` onto the stack
897+trace. Thus, `cyt` is not evaluated at all unless an error occurred.
934898
935−Next in `++wilt`, we load the information about the filesystem node
936−referenced by the hoop with `++lend`.
899+Next in `++wilt`, we load the information about the filesystem node referenced
900+by the hoop with `++lend`.
937901
938902 ++ lend :: load arch
939903 |= [cof=cafe bem=beam]
@@ -942,28 +906,27 @@ referenced by the hoop with `++lend`.
942906 ?~ von [p=cof q=[%1 [bem ~] ~ ~]]
943907 (fine cof ((hard arch) (need u.von)))
944908
945−This is a simple call to the namespace. If the resource does not yet
946−exist, we block on it by producing a `%1` bolt. Otherwise, we cast it to
947−an arch and produce this.
909+This is a simple call to the namespace. If the resource does not yet exist, we
910+block on it by producing a `%1` bolt. Otherwise, we cast it to an arch and
911+produce this.
948912
949913Continuing in `++wilt`, we examine the produced arch. If the referenced
950−filesystem node has a `hoon` child node, then we've found the required
951−source, so we parse it with `++fade`. Recall that we referred earlier to
952−`++fade`. The salient point there is that it takes a beam, reads in the
953−hook file there, and parses it into a hood file with `++fair`.
914+filesystem node has a `hoon` child node, then we've found the required source,
915+so we parse it with `++fade`. Recall that we referred earlier to `++fade`. The
916+salient point there is that it takes a beam, reads in the hook file there, and
917+parses it into a hood file with `++fair`.
954918
955−Now, we simply recurse on `++apex` to compile the new hood. Note that,
956−while we do clear the `boy` list, we do not clear the other lists. Thus,
957−we are accumulating all the structures and libraries referenced in all
958−the referenced hook files in one group, which we will put at the top of
959−the product.
919+Now, we simply recurse on `++apex` to compile the new hood. Note that, while we
920+do clear the `boy` list, we do not clear the other lists. Thus, we are
921+accumulating all the structures and libraries referenced in all the referenced
922+hook files in one group, which we will put at the top of the product.
960923
961−After this, we put the new list of body twigs into a `=~`, push this
962−onto our old list of body twigs, and produce the result.
924+After this, we put the new list of body twigs into a `=~`, push this onto our
925+old list of body twigs, and produce the result.
963926
964−If there is no hoon file here, then we descend into each of our children
965−until we find a hoon file. First, we produce a list of all our children
966−whose names are terms with `++lark`.
927+If there is no hoon file here, then we descend into each of our children until
928+we find a hoon file. First, we produce a list of all our children whose names
929+are terms with `++lark`.
967930
968931 ++ lark :: filter arch names
969932 |= [wox=$+(span (unit ,@)) arc=arch]
@@ -976,43 +939,39 @@ whose names are terms with `++lark`.
976939 =+ gib=(wox p.n.r.arc)
977940 ?~(gib rac [[u.gib p.n.r.arc] rac])
978941
979−We traverse the children map of `arc` to filter out those children whose
980−names aren't accepted by `wox` and produce a map from the product of
981−`wox` to the original name. `++lark` is used in many cases to parse
982−names into other types, like numbers or dates, ignoring those which do
983−not fit the format. In `++wilt`, though, we simply want to filter out
984−those children whose names are not terms.
942+We traverse the children map of `arc` to filter out those children whose names
943+aren't accepted by `wox` and produce a map from the product of `wox` to the
944+original name. `++lark` is used in many cases to parse names into other types,
945+like numbers or dates, ignoring those which do not fit the format. In `++wilt`,
946+though, we simply want to filter out those children whose names are not terms.
985947
986−Next, we will produce a map from terms to feet. Each of these feet will
987−be placed in a core named by the child name, and it will contain arms
988−according to its children. Thus, if the indirect hoop references
989−`/path`, then to access the twig defined in `/path/to/twig/hoon`, our
990−body must refer to `twig:to`.
948+Next, we will produce a map from terms to feet. Each of these feet will be
949+placed in a core named by the child name, and it will contain arms according to
950+its children. Thus, if the indirect hoop references `/path`, then to access the
951+twig defined in `/path/to/twig/hoon`, our body must refer to `twig:to`.
991952
992−If there are no more children, then we are done, so we produce our
993−current context.
953+If there are no more children, then we are done, so we produce our current
954+context.
994955
995−Else, we recurse into the left and right sides of our map. Finally, we
996−process our current entry in the map. We first recurse by calling
997−`++wilt` one level down. Thus, in the previous example, the first time
998−we get to this point we are processing `/path`, so we recurse on
999−`++wilt` with path `/path/to`. We also remove our current body from the
1000−recursion, so that we may add it back in later the way we want to.
956+Else, we recurse into the left and right sides of our map. Finally, we process
957+our current entry in the map. We first recurse by calling `++wilt` one level
958+down. Thus, in the previous example, the first time we get to this point we are
959+processing `/path`, so we recurse on `++wilt` with path `/path/to`. We also
960+remove our current body from the recursion, so that we may add it back in later
961+the way we want to.
1001962
1002−After recursing, we push the new body onto our map, keyed by its name.
1003−We also produce the new context so that all external structures,
1004−libraries, and resources are collected into the same place.
963+After recursing, we push the new body onto our map, keyed by its name. We also
964+produce the new context so that all external structures, libraries, and
965+resources are collected into the same place.
1005966
1006−Finally, we have a map of names to feet. If this map is empty, then
1007−there were no twigs at the requested path, so we give an error with
1008−`++flaw`.
967+Finally, we have a map of names to feet. If this map is empty, then there were
968+no twigs at the requested path, so we give an error with `++flaw`.
1009969
1010−If the map is nonempty, then we finally produce our context with with
1011−one thing pushed onto the front: a core made out of the map we just
1012−produced.
970+If the map is nonempty, then we finally produce our context with with one thing
971+pushed onto the front: a core made out of the map we just produced.
1013972
1014−This concludes our discussion of `++wilt` and `++body`. Thus, it remains
1015−in `++apex` to discuss `++neck` and `++head`.
973+This concludes our discussion of `++wilt` and `++body`. Thus, it remains in
974+`++apex` to discuss `++neck` and `++head`.
1016975
1017976 ++ neck :: consume libraries
1018977 |= [cof=cafe bir=(list hoof)]
@@ -1040,26 +999,24 @@ in `++apex` to discuss `++neck` and `++head`.
1040999 ==
10411000 ^^$(cof cof, bir t.bir)
10421001
1043−Here, we're going to consume the list of libraries and place them in
1044−`bil`. If there are no more libraries, we're done, so we just produce
1045−our current context.
1002+Here, we're going to consume the list of libraries and place them in `bil`. If
1003+there are no more libraries, we're done, so we just produce our current context.
10461004
1047−Otherwise, we check to see if the next library in the list is in `zeg`.
1048−If so, then this library is one of the libraries that we're already in
1049−the middle of compiling. There is a circular dependency, so we fail.
1005+Otherwise, we check to see if the next library in the list is in `zeg`. If so,
1006+then this library is one of the libraries that we're already in the middle of
1007+compiling. There is a circular dependency, so we fail.
10501008
10511009Otherwise, we let `gez` be `zeg` plus the current library so that while
1052−compiling the dependencies of this library we don't later create a
1053−circular dependency. We check next to see if this library is alredy in
1054−`bil`. If so, then we have already included this library earlier, so we
1055−check to see if this is the same version of the library as we included
1056−earlier. If so, we skip it. Else, we fail since we can't include two
1057−different versions of a library. We really should allow for newer
1058−versions of a library since in kelvin versioning we assume backwards
1059−compatibility, but for now we require an exact match.
1060−
1061−If we haven't already included this library, then we're going to do
1062−that. First, we get the location of the library with `++hone`.
1010+compiling the dependencies of this library we don't later create a circular
1011+dependency. We check next to see if this library is alredy in `bil`. If so, then
1012+we have already included this library earlier, so we check to see if this is the
1013+same version of the library as we included earlier. If so, we skip it. Else, we
1014+fail since we can't include two different versions of a library. We really
1015+should allow for newer versions of a library since in kelvin versioning we
1016+assume backwards compatibility, but for now we require an exact match.
1017+
1018+If we haven't already included this library, then we're going to do that. First,
1019+we get the location of the library with `++hone`.
10631020
10641021 ++ hone :: plant hoof
10651022 |= [for=@tas way=@tas huf=hoof]
@@ -1068,28 +1025,27 @@ that. First, we get the location of the library with `++hone`.
10681025 how(s ~[for p.huf way])
10691026 [[q.u.q.huf %main p.u.q.huf] ~[for p.huf way]]
10701027
1071−If we haven't specified the version of the library, we use the current
1072−ship, desk, and case. Otherwise, we use the given ship and case on desk
1073−`%main`. In either case, the path is `/way/p.huf/for`. In the case of
1074−`++neck`, this means `/lib/core/[library name]`.
1075−
1076−In `++neck`, we next compile the hook file at that location with
1077−`++fade`. Again, we will delay the discussion of `++fade`, noting only
1078−that it takes a beam and parses the hook file there into a hood.
1079−
1080−We recurse on this to compile the library. During the compilation, we
1081−let `zeg` be `gez` to avoid circular dependencies, we let `hol` be false
1082−since we don't allow horns in libraries, and we let `boy` be null so
1083−that we can isolate the new body twigs.
1084−
1085−Next, we reintegrate the new data into our context. We use the context
1086−created by the recursion with four changes. First, we reset `zeg` to our
1087−old `zeg`. Second, we reset `hol` to our old `hol`. Third, we put the
1088−name of our library onto the stack of libraries. This means all of a
1089−libraries dependencies will be earlier in `lot` than the library itself,
1090−making `lot` a topological ordering on the dependency graph. Fourth, we
1091−put in `bil` the library hoof and body (with all body twigs collected in
1092−a `=~`), keyed by the library name.
1028+If we haven't specified the version of the library, we use the current ship,
1029+desk, and case. Otherwise, we use the given ship and case on desk `%main`. In
1030+either case, the path is `/way/p.huf/for`. In the case of `++neck`, this means
1031+`/lib/core/[library name]`.
1032+
1033+In `++neck`, we next compile the hook file at that location with `++fade`.
1034+Again, we will delay the discussion of `++fade`, noting only that it takes a
1035+beam and parses the hook file there into a hood.
1036+
1037+We recurse on this to compile the library. During the compilation, we let `zeg`
1038+be `gez` to avoid circular dependencies, we let `hol` be false since we don't
1039+allow horns in libraries, and we let `boy` be null so that we can isolate the
1040+new body twigs.
1041+
1042+Next, we reintegrate the new data into our context. We use the context created
1043+by the recursion with four changes. First, we reset `zeg` to our old `zeg`.
1044+Second, we reset `hol` to our old `hol`. Third, we put the name of our library
1045+onto the stack of libraries. This means all of a libraries dependencies will be
1046+earlier in `lot` than the library itself, making `lot` a topological ordering on
1047+the dependency graph. Fourth, we put in `bil` the library hoof and body (with
1048+all body twigs collected in a `=~`), keyed by the library name.
10931049
10941050Finally, we recurse, processing the next library in our list.
10951051
@@ -1128,38 +1084,36 @@ To complete our disucssion of `++apex`, we must process our structures.
11281084 ==
11291085 ^^$(cof cof, bir t.bir)
11301086
1131−The processing of our structures is very similar to that of our
1132−libraries. For clarity, we'll use many of the same phrases in describing
1133−the parallel natures. First, we check to see if there are more
1134−structures to process. If not, we're done, so we produce our context.
1135−
1136−Otherwise, we let `goz` be `zog` plus the current structure so that
1137−while compiling the dependencies of this structure we don't later create
1138−a circular dependency. We check next to see if this structure is alredy
1139−in `rop`. If so, then we have already included this structure earlier,
1140−so we check to see if this is the same version of the structure as we
1141−included earlier. If so, we skip it. Else, we fail since we can't
1142−include two different versions of a structure.
1143−
1144−If we haven't loaded this structure, then we call `++hone` to get the
1145−beam where the file structure should be. If the loobean in the hoot is
1146−true, then we're looking for a gate; otherwise, we're looking for a
1147−core. We parse this file with `++fade`.
1148−
1149−Now, we recurse on this to compile the structure. During the recursion,
1150−there we have threee changes. Frist, we let `zog` be `goz` so that we
1151−don't create a circular dependency. Second, we let `hol` be false since
1152−we do not allow horns in structures. Third, we let `boy` be null so that
1153−we can isolate the new body twigs.
1154−
1155−Next, we reintegrate the new data into our context. We use the context
1156−cretaed by the recursion with four changes. First, if we're including a
1157−gate structure, then we reset the body to its original body. Else we put
1158−on the top of our list of body twigs what is essentially a
1159−`=+ structure-name` to take off the face of the structure. Second, we
1160−reset `zog` to our old `zog`. Third, we reset `hol` to our old `hol`.
1161−Finally, we put in `rop` the structure hoof and body (with all body
1162−twiggs collected in a `=~`), keyed by the structure name.
1087+The processing of our structures is very similar to that of our libraries. For
1088+clarity, we'll use many of the same phrases in describing the parallel natures.
1089+First, we check to see if there are more structures to process. If not, we're
1090+done, so we produce our context.
1091+
1092+Otherwise, we let `goz` be `zog` plus the current structure so that while
1093+compiling the dependencies of this structure we don't later create a circular
1094+dependency. We check next to see if this structure is alredy in `rop`. If so,
1095+then we have already included this structure earlier, so we check to see if this
1096+is the same version of the structure as we included earlier. If so, we skip it.
1097+Else, we fail since we can't include two different versions of a structure.
1098+
1099+If we haven't loaded this structure, then we call `++hone` to get the beam where
1100+the file structure should be. If the loobean in the hoot is true, then we're
1101+looking for a gate; otherwise, we're looking for a core. We parse this file with
1102+`++fade`.
1103+
1104+Now, we recurse on this to compile the structure. During the recursion, there we
1105+have threee changes. Frist, we let `zog` be `goz` so that we don't create a
1106+circular dependency. Second, we let `hol` be false since we do not allow horns
1107+in structures. Third, we let `boy` be null so that we can isolate the new body
1108+twigs.
1109+
1110+Next, we reintegrate the new data into our context. We use the context cretaed
1111+by the recursion with four changes. First, if we're including a gate structure,
1112+then we reset the body to its original body. Else we put on the top of our list
1113+of body twigs what is essentially a `=+ structure-name` to take off the face of
1114+the structure. Second, we reset `zog` to our old `zog`. Third, we reset `hol` to
1115+our old `hol`. Finally, we put in `rop` the structure hoof and body (with all
1116+body twiggs collected in a `=~`), keyed by the structure name.
11631117
11641118Finally, we recurse, processing the next structure in our list.
11651119
@@ -1179,9 +1133,9 @@ This concludes our discussion of `++apex`.
11791133 |= [cof=cafe fin=vase]
11801134 (fine cof fin)
11811135
1182−Returning to `++abut`, we have now processed the structures, libraries
1183−and body twigs. Next, we slap our preamble (structures and libraries)
1184−against zuse. First, we construct our preamble in `++able`.
1136+Returning to `++abut`, we have now processed the structures, libraries and body
1137+twigs. Next, we slap our preamble (structures and libraries) against zuse.
1138+First, we construct our preamble in `++able`.
11851139
11861140 ++ able :: assemble preamble
11871141 ^- twig
@@ -1189,10 +1143,10 @@ against zuse. First, we construct our preamble in `++able`.
11891143 ?:(=(~ rop) [%$ 1] [%brcn (~(run by rop) |=([* a=twig] [%ash a]))])
11901144 [%tssg (turn (flop lot) |=(a=term q:(need (~(get by bil) a))))]
11911145
1192−We first put the structures in `rop` into a single `|%` at the top and
1193−`=>` it onto a `=~` of our libraries, in the reverse order that they
1194−appear in `lot`. Thus, the structures are in a single core while the
1195−libraries are in consecutive cores.
1146+We first put the structures in `rop` into a single `|%` at the top and `=>` it
1147+onto a `=~` of our libraries, in the reverse order that they appear in `lot`.
1148+Thus, the structures are in a single core while the libraries are in consecutive
1149+cores.
11961150
11971151We slap the preamble against zuse with `++maim`.
11981152
@@ -1209,49 +1163,47 @@ We slap the preamble against zuse with `++maim`.
12091163 `vase`[p.p.puz val]
12101164 ==
12111165
1212−Here we start to get into ford's caching system. We wrap our computation
1213−in a call to `++clef` so that we only actually compute it if the result
1214−is not already in our cache. First we'll discuss the computation, then
1215−we'll discuss the caching system.
1166+Here we start to get into ford's caching system. We wrap our computation in a
1167+call to `++clef` so that we only actually compute it if the result is not
1168+already in our cache. First we'll discuss the computation, then we'll discuss
1169+the caching system.
12161170
1217−We call `++mule` with a call to `++mint:ut` on the type of our subject
1218−vase against the given twig. In other words, we're compiling the twig
1219−with against the subject type in the given subject vase.
1171+We call `++mule` with a call to `++mint:ut` on the type of our subject vase
1172+against the given twig. In other words, we're compiling the twig with against
1173+the subject type in the given subject vase.
12201174
1221−If compilation fails, then we produce an error bolt with the produced
1222−stack trace. Otherwise, we run the produced nock with `++mock` and our
1223−sky function. We convert the produced toon to a bolt with `++coup` and
1224−use the type from `puz` combined with the value from `mock` to produce
1225−our vase.
1175+If compilation fails, then we produce an error bolt with the produced stack
1176+trace. Otherwise, we run the produced nock with `++mock` and our sky function.
1177+We convert the produced toon to a bolt with `++coup` and use the type from `puz`
1178+combined with the value from `mock` to produce our vase.
12261179
1227−If this process seems harder than just calling `++slap`, it's because it
1228−is. We have two requirements that `++slap` doesn't satisfy. First, we
1229−want the to use an explicit sky function for use with `.^`. With
1230−`++slap`, you get whatever sky function is available in the calling
1231−context, which in ford is none. Second, we want to explicitly handle the
1232−stack trace on failure. `++slap` would cause crash on failure.
1180+If this process seems harder than just calling `++slap`, it's because it is. We
1181+have two requirements that `++slap` doesn't satisfy. First, we want the to use
1182+an explicit sky function for use with `.^`. With `++slap`, you get whatever sky
1183+function is available in the calling context, which in ford is none. Second, we
1184+want to explicitly handle the stack trace on failure. `++slap` would cause crash
1185+on failure.
12331186
1234−We haven't yet discussed either `++clef` or `++coup`. We'll start with
1235−`++coup` to finish the discussion of the computation.
1187+We haven't yet discussed either `++clef` or `++coup`. We'll start with `++coup`
1188+to finish the discussion of the computation.
12361189
12371190\``++ coup :: toon to bolt |= cof=cafe |* [ton=toon fun=$+(* *)] :- p=cof ^= q ?- -.ton %2 [%2 p=p.ton] %0 [%0 p=*(set beam) q=(fun p.ton)] %1 ~& [%coup-need ((list path) p.ton)] =- ?- -.faw & [%1 p=(sa (turn p.faw |=(a=beam [a *(list tank)])))] | [%2 p=p.faw] == ^= faw |- ^- (each (list beam) (list tank)) ?~ p.ton [%& ~] =+ nex=$(p.ton t.p.ton) =+ pax=(path i.p.ton) ?~ pax [%| (smyt pax) ?:(?=(& -.nex) ~ p.nex)] =+ zis=(tome t.pax) ?~ zis [%| (smyt pax) ?:(?=(& -.nex) ~ p.nex)] ?- -.nex & [%& u.zis p.nex] | nex == ==`
12381191
1239−Recall that a toon is either a `%0` value, a `%1` block, or a `%2`
1240−failure. Converting a `%2` toon failure into a `%2` bolt failure is
1241−trivial. Converting a `%0` toon value into a `%0` bolt value is easy
1242−since we assume there were no dependencies. Converting the blocks is
1243−rather more difficult.
1192+Recall that a toon is either a `%0` value, a `%1` block, or a `%2` failure.
1193+Converting a `%2` toon failure into a `%2` bolt failure is trivial. Converting a
1194+`%0` toon value into a `%0` bolt value is easy since we assume there were no
1195+dependencies. Converting the blocks is rather more difficult.
12441196
1245−To compute `faw`, we recurse through the list of paths in the `%1` toon.
1246−At each one, we make sure with `++tome` that it is, in fact, a beam. If
1247−so, then we check to see if the later paths succeed as well. If so, we
1248−append the current path to the list of other paths. If not, we produce
1249−the error message we got from processing the rest of the paths. If this
1250−path is not a beam, then we fail, producing a list of tanks including
1251−this path and, if later paths fail too, those paths as well.
1197+To compute `faw`, we recurse through the list of paths in the `%1` toon. At each
1198+one, we make sure with `++tome` that it is, in fact, a beam. If so, then we
1199+check to see if the later paths succeed as well. If so, we append the current
1200+path to the list of other paths. If not, we produce the error message we got
1201+from processing the rest of the paths. If this path is not a beam, then we fail,
1202+producing a list of tanks including this path and, if later paths fail too,
1203+those paths as well.
12521204
1253−If some paths were not beams, then we produce a `%2` error bolt. If all
1254−paths were correct, then we produce a `%1` blocking bolt.
1205+If some paths were not beams, then we produce a `%2` error bolt. If all paths
1206+were correct, then we produce a `%1` blocking bolt.
12551207
12561208We will now discuss `++clef`. This is where the cache magic happens.
12571209
@@ -1286,29 +1238,28 @@ Otherwise, we look up the request in the cache with `++calk`.
12861238 ?~ d [~ a] ::
12871239 [d a(p (~(put in p.a) u.d))] ::
12881240
1289−When looking up something in the cache, we mark it if we find it. This
1290−way, we have in our cache the set of all cache entries that have been
1291−referenced. While we do not at present do anything with this data, it
1292−should be used to clear out old and unused entries in the cache.
1241+When looking up something in the cache, we mark it if we find it. This way, we
1242+have in our cache the set of all cache entries that have been referenced. While
1243+we do not at present do anything with this data, it should be used to clear out
1244+old and unused entries in the cache.
12931245
1294−Moving on in `++clef`, we check to see if we actually found anything. If
1295−we didn't find a cache entry, then we run the computation in `fun`, and
1296−examine its result. If it produced a `%2` error or `%1` block bolt, we
1297−just pass that through. Otherwise, we produce both the value and an
1298−updated cache with this new entry. We add the entry with `++came`.
1246+Moving on in `++clef`, we check to see if we actually found anything. If we
1247+didn't find a cache entry, then we run the computation in `fun`, and examine its
1248+result. If it produced a `%2` error or `%1` block bolt, we just pass that
1249+through. Otherwise, we produce both the value and an updated cache with this new
1250+entry. We add the entry with `++came`.
12991251
13001252 ++ came ::
13011253 |= [a=cafe b=calx] :: cache install
13021254 ^- cafe ::
13031255 a(q (~(put by q.a) [-.b q.b] b)) ::
13041256
1305−We key cache entries by the type of computation (`-:calx`) and the
1306−inputs to the computation (`q:calc`). This just puts the cache line in
1307−the cache at the correct key.
1257+We key cache entries by the type of computation (`-:calx`) and the inputs to the
1258+computation (`q:calc`). This just puts the cache line in the cache at the
1259+correct key.
13081260
1309−Back in `++clef`, if we did find a cache entry, then we just produce the
1310−value at that cache line. We convert the cache line into a value with
1311−`++calf`.
1261+Back in `++clef`, if we did find a cache entry, then we just produce the value
1262+at that cache line. We convert the cache line into a value with `++calf`.
13121263
13131264 ++ calf :: reduce calx
13141265 |* sem=* :: a typesystem hack
@@ -1319,23 +1270,22 @@ value at that cache line. We convert the cache line into a value with
13191270 %slam ?>(?=(%slam -.cax) r.cax)
13201271 ==
13211272
1322−This is simply a typesystem hack. Because the `sem` is passed in through
1323−a wet gate, we know at type time which of the three cases will be
1324−chosen. Thus, the correct type of the value in the cache line gets
1325−passed through to the caller. This also depends on the fact that
1326−`++clef` is wet. The type stuff here is mathematically interesting, but
1327−the action is simple: we get the value from the cache line.
1273+This is simply a typesystem hack. Because the `sem` is passed in through a wet
1274+gate, we know at type time which of the three cases will be chosen. Thus, the
1275+correct type of the value in the cache line gets passed through to the caller.
1276+This also depends on the fact that `++clef` is wet. The type stuff here is
1277+mathematically interesting, but the action is simple: we get the value from the
1278+cache line.
13281279
13291280This concludes our discussion of `++clef` and `++maim`.
13301281
1331−Back in `++abut`, recall that we processed the structures, libraries,
1332−and body with `++apex`. Then, we slapped our preamble (structures and
1333−libraries) against zuse with `++maim`. Next, we process our resources
1334−with `++chap`. Note that we pass in the preamble so that we may refer to
1335−anything in there in our resources.
1282+Back in `++abut`, recall that we processed the structures, libraries, and body
1283+with `++apex`. Then, we slapped our preamble (structures and libraries) against
1284+zuse with `++maim`. Next, we process our resources with `++chap`. Note that we
1285+pass in the preamble so that we may refer to anything in there in our resources.
13361286
1337−`++chap` is broken up into a different case for each horn. We'll go
1338−through them one by one.
1287+`++chap` is broken up into a different case for each horn. We'll go through them
1288+one by one.
13391289
13401290 ++ chap :: produce resources
13411291 |= [cof=cafe bax=vase hon=horn]
@@ -1350,9 +1300,9 @@ This is `/~`. We slap the twig against our context.
13501300 |= [cof=cafe gat=vase]
13511301 (maul cof gat !>([how arg]))
13521302
1353−This is `/$`. We slap the twig against our context, which we expect to
1354−produce a gate. We slam this gate with a sample of `how` and `arg`,
1355−which is our location and the heel (virtual path extension).
1303+This is `/$`. We slap the twig against our context, which we expect to produce a
1304+gate. We slam this gate with a sample of `how` and `arg`, which is our location
1305+and the heel (virtual path extension).
13561306
13571307`++maul` is similar to `++maim`, but it slams instead of slaps.
13581308
@@ -1369,20 +1319,19 @@ which is our location and the heel (virtual path extension).
13691319 `vase`[p.top val]
13701320 ==
13711321
1372−We cache slams exactly as we cache slaps. We use `++slit` to find the
1373−type of the product of the slam given the types of the gate and the
1374−sample.
1322+We cache slams exactly as we cache slaps. We use `++slit` to find the type of
1323+the product of the slam given the types of the gate and the sample.
13751324
1376−If this type fails, we produce the given stack trace as a `%2` error
1377−bolt. Otherwise, we produce the top produced above combined with the
1378−value we get from slamming the values in the vases with `++mong`.
1325+If this type fails, we produce the given stack trace as a `%2` error bolt.
1326+Otherwise, we produce the top produced above combined with the value we get from
1327+slamming the values in the vases with `++mong`.
13791328
13801329Back to `++chap`.
13811330
13821331 %day (chad cof bax %dr p.hon)
13831332
1384−This is `/|`. We call `++chad` to convert textual names to relative
1385−dates and process the next horn against each of the discovered paths.
1333+This is `/|`. We call `++chad` to convert textual names to relative dates and
1334+process the next horn against each of the discovered paths.
13861335
13871336 ++ chad :: atomic list
13881337 |= [cof=cafe bax=vase doe=term hon=horn]
@@ -1406,8 +1355,8 @@ dates and process the next horn against each of the discovered paths.
14061355 ?~ yal [[%cube 0 [%atom %n]] 0]
14071356 (slop (slop [[%atom doe] p.i.yal] q.i.yal) $(yal t.yal))
14081357
1409−First, we call `++lash` to parse the children of the current beam and
1410−pick out those ones that are of the requested format.
1358+First, we call `++lash` to parse the children of the current beam and pick out
1359+those ones that are of the requested format.
14111360
14121361 ++ lash :: atomic sequence
14131362 |= wox=$+(span (unit ,@))
@@ -1417,26 +1366,22 @@ pick out those ones that are of the requested format.
14171366 |= [cof=cafe arc=arch]
14181367 (fine cof (lark wox arc))
14191368
1420−First, we get the arch with `++lend`, as described above. We filter and
1421−parse the child names with `++lark` according to the given parser
1422−function.
1369+First, we get the arch with `++lend`, as described above. We filter and parse
1370+the child names with `++lark` according to the given parser function.
14231371
1424−In `++chad`, this parser function is `(slat doe)`, which will parse a
1425−cord into an atom of the requested odor. For `%day` the odor is for
1426−relative dates.
1372+In `++chad`, this parser function is `(slat doe)`, which will parse a cord into
1373+an atom of the requested odor. For `%day` the odor is for relative dates.
14271374
1428−Thus, we now have a map from atoms of the given odor to the actual child
1429−names. We next turn this map into a list and sort it in increasing order
1430−by the atom.
1375+Thus, we now have a map from atoms of the given odor to the actual child names.
1376+We next turn this map into a list and sort it in increasing order by the atom.
14311377
1432−We next convert this list of pairs of atoms and spans to a list of pairs
1433−of atoms and vases. We process the given horn once at every child beam,
1434−producing the resource at that location.
1378+We next convert this list of pairs of atoms and spans to a list of pairs of
1379+atoms and vases. We process the given horn once at every child beam, producing
1380+the resource at that location.
14351381
1436−Finally, we convert this list of pairs of atoms and vases to a vase of a
1437−list of pairs of atoms to (well-typed) values. Each entry in the list is
1438−of type atom with the given odor combined with the type of the produced
1439−vase.
1382+Finally, we convert this list of pairs of atoms and vases to a vase of a list of
1383+pairs of atoms to (well-typed) values. Each entry in the list is of type atom
1384+with the given odor combined with the type of the produced vase.
14401385
14411386Back in `++chap`, we continue parsing resources.
14421387
@@ -1445,8 +1390,8 @@ Back in `++chap`, we continue parsing resources.
14451390 |= [cof=cafe vax=vase]
14461391 (fine cof [[%face p.hon p.vax] q.vax])
14471392
1448−This is `/=`. We process the given horn, giving us a vase. We put as a
1449−face on the vase so that it may be referred to later by name.
1393+This is `/=`. We process the given horn, giving us a vase. We put as a face on
1394+the vase so that it may be referred to later by name.
14501395
14511396 %fan
14521397 %+ cope
@@ -1463,21 +1408,21 @@ face on the vase so that it may be referred to later by name.
14631408 ?~ tev [[%cube 0 [%atom %n]] 0]
14641409 (slop i.tev $(tev t.tev))
14651410
1466−This is `/.`. We first process each of the child horns, producing a list
1467−of vases. This is done by just recursing on `++chap`. Then, we simply
1468−fold over this list to create a vase of the list of values.
1411+This is `/.`. We first process each of the child horns, producing a list of
1412+vases. This is done by just recursing on `++chap`. Then, we simply fold over
1413+this list to create a vase of the list of values.
14691414
14701415 %for $(hon q.hon, s.how (weld (flop p.hon) s.how))
14711416
1472−This is `/,`. We simply recurse on the horn with the given path welded
1473−onto our current beam.
1417+This is `/,`. We simply recurse on the horn with the given path welded onto our
1418+current beam.
14741419
14751420 %hub (chad cof bax %ud p.hon)
14761421
1477−This is `/@`. This is exactly like the processing of `%day` except we
1478−expect the children to be named as unsigned integers rather than
1479−relative dates. We process the horn at each of the children's locations
1480−and produce a list of pairs of absolute dates and values.
1422+This is `/@`. This is exactly like the processing of `%day` except we expect the
1423+children to be named as unsigned integers rather than relative dates. We process
1424+the horn at each of the children's locations and produce a list of pairs of
1425+absolute dates and values.
14811426
14821427 %man
14831428 |- ^- (bolt vase)
@@ -1493,21 +1438,20 @@ and produce a list of pairs of absolute dates and values.
14931438 (slop [[%atom %tas] p.n.p.hon] vax)
14941439 (slop lef rig)
14951440
1496−This is `/*`. We process each of the horns in the given map by recursion
1497−through `++chap`. Once we have these vases, we create a vase of a map
1498−from the given textual names to the produced values.
1441+This is `/*`. We process each of the horns in the given map by recursion through
1442+`++chap`. Once we have these vases, we create a vase of a map from the given
1443+textual names to the produced values.
14991444
15001445 %now (chad cof bax %da p.hon)
15011446
1502−This is `/&`. This is exactly like the processing of `%now` except we
1503−expect the children to be names as absolute dates rather than relative
1504−dates. We process the horn at each of the children's locations and
1505−produce a list of pairs of absolute dates and values.
1447+This is `/&`. This is exactly like the processing of `%now` except we expect the
1448+children to be names as absolute dates rather than relative dates. We process
1449+the horn at each of the children's locations and produce a list of pairs of
1450+absolute dates and values.
15061451
15071452 %nap (chai cof bax p.hon)
15081453
1509−This is `/%`. Here, we process the horn at each of our children with
1510−`++chai`.
1454+This is `/%`. Here, we process the horn at each of our children with `++chai`.
15111455
15121456 ++ chai :: atomic map
15131457 |= [cof=cafe bax=vase hon=horn]
@@ -1532,10 +1476,10 @@ This is `/%`. Here, we process the horn at each of our children with
15321476 (slop [[%atom %a] p.n.doy] q.n.doy)
15331477 (slop $(doy l.doy) $(doy r.doy))
15341478
1535−We get the arch at our current beam with `++lend`. Then, we process the
1536−horn at each of our children to give us a map of atoms to vases.
1537−Finally, we convert that into a vase of a map of these atoms to the
1538−values. This is very similar to `++chad` and the handling of `%man`.
1479+We get the arch at our current beam with `++lend`. Then, we process the horn at
1480+each of our children to give us a map of atoms to vases. Finally, we convert
1481+that into a vase of a map of these atoms to the values. This is very similar to
1482+`++chad` and the handling of `%man`.
15391483
15401484 %see $(hon q.hon, how p.hon)
15411485
@@ -1548,9 +1492,9 @@ This is `/:`. We process the given horn at the given beam.
15481492 |= [cof=cafe gat=vase]
15491493 (maul cof gat sam)
15501494
1551−This is `/;`. First, we process the given horn. Then, we slap the given
1552−twig against our context to produce (hopefully) a gate. Finally, we slam
1553−the vase we got from processing the horn against the gate.
1495+This is `/;`. First, we process the given horn. Then, we slap the given twig
1496+against our context to produce (hopefully) a gate. Finally, we slam the vase we
1497+got from processing the horn against the gate.
15541498
15551499 %sic
15561500 %+ cope $(hon q.hon)
@@ -1561,27 +1505,26 @@ the vase we got from processing the horn against the gate.
15611505 (flaw cof [%leaf "type error: {<p.hon>} {<q.hon>}"]~)
15621506 (fine cof [p.tug q.vax])
15631507
1564−This is `/^`. First, we process the given horn. Then, we slap the the
1565−bunt of the given tile against our context. This will produce a vase
1566−with the correct type. We test to see if this type nests within the type
1567−of the vase we got from processing the horn. If so, we produce the value
1568−from the horn along with the type from the tile. Otherwise, we produce a
1569−`%2` error bolt.
1508+This is `/^`. First, we process the given horn. Then, we slap the the bunt of
1509+the given tile against our context. This will produce a vase with the correct
1510+type. We test to see if this type nests within the type of the vase we got from
1511+processing the horn. If so, we produce the value from the horn along with the
1512+type from the tile. Otherwise, we produce a `%2` error bolt.
15701513
15711514 %toy (cope (make cof %bake p.hon how ~) feel)
15721515 ==
15731516
1574−This is `/mark/`. Here, we simply run the `%bake` silk on the given
1575−mark, producing a cage. We convert this cage into a vase with `++feel`,
1576−which is exactly as simple as it sounds like it should be.
1517+This is `/mark/`. Here, we simply run the `%bake` silk on the given mark,
1518+producing a cage. We convert this cage into a vase with `++feel`, which is
1519+exactly as simple as it sounds like it should be.
15771520
15781521 ++ feel |=([a=cafe b=cage] (fine a q.b)) :: cage to vase
15791522
15801523This is trivial.
15811524
1582−We will discuss later `++make` and how `%bake` is processed. Suffice it
1583−to say that baking a resource with a given mark gets the resource and
1584−converts it, if necessary, to the requested mark.
1525+We will discuss later `++make` and how `%bake` is processed. Suffice it to say
1526+that baking a resource with a given mark gets the resource and converts it, if
1527+necessary, to the requested mark.
15851528
15861529This concludes our discussion of `++chap`.
15871530
@@ -1601,26 +1544,24 @@ We return once more to `++abut`.
16011544 |= [cof=cafe fin=vase]
16021545 (fine cof fin)
16031546
1604−Recall that we processed our structures, libraries and body with
1605−`++apex`. We slapped our structures and libraries against zuse with
1606−`++maim`. We processed our resources with `++chap`. Now, all our body
1607−twigs are collected in a `=~` and slapped against our structures,
1608−libraries, and resources. This produces our final result.
1547+Recall that we processed our structures, libraries and body with `++apex`. We
1548+slapped our structures and libraries against zuse with `++maim`. We processed
1549+our resources with `++chap`. Now, all our body twigs are collected in a `=~` and
1550+slapped against our structures, libraries, and resources. This produces our
1551+final result.
16091552
16101553The hook file has been assembled. And there was great rejoicing.
16111554
1612−Lifecycle of a Kiss
1613−-------------------
1555+## Lifecycle of a Kiss
16141556
1615−We're now going to go through a series of lifecycle descriptions. When a
1616−user of ford sends a kiss, it is one of a dozen different types of silk.
1617−We'll go through each one, tracing through the flow of control of each
1618−of these.
1557+We're now going to go through a series of lifecycle descriptions. When a user of
1558+ford sends a kiss, it is one of a dozen different types of silk. We'll go
1559+through each one, tracing through the flow of control of each of these.
16191560
16201561First, though, we'll describe the common handling to all kisses.
16211562
1622−The silk in a `%exec` kiss to ford ends up in `++apex`, so we'll enter
1623−the narrative here.
1563+The silk in a `%exec` kiss to ford ends up in `++apex`, so we'll enter the
1564+narrative here.
16241565
16251566 ++ apex :: call
16261567 |= kus=(unit silk)
@@ -1639,13 +1580,13 @@ the narrative here.
16391580 ==
16401581 ~(exec zo [num `task`[hen u.kus 0 ~]])
16411582
1642−Recall that a `%exec` kiss actually sends a unit silk. If it's null,
1643−we're trying to cancel the request. We first look up the task number
1644−keyed by duct. If we don't find it, then we're trying to cancel a
1645−request that either was never started or has already completed. We print
1646−out `%ford-mystery` and do nothing. If we do find the task number, then
1647−we look up the task from it, call `++camo:zo` to cancel pending
1648−requests, and call `++amok:zo` to remove the task from our task lists.
1583+Recall that a `%exec` kiss actually sends a unit silk. If it's null, we're
1584+trying to cancel the request. We first look up the task number keyed by duct. If
1585+we don't find it, then we're trying to cancel a request that either was never
1586+started or has already completed. We print out `%ford-mystery` and do nothing.
1587+If we do find the task number, then we look up the task from it, call
1588+`++camo:zo` to cancel pending requests, and call `++amok:zo` to remove the task
1589+from our task lists.
16491590
16501591 ++ camo :: stop requests
16511592 ^+ .
@@ -1661,9 +1602,9 @@ requests, and call `++amok:zo` to remove the task from our task lists.
16611602 [%warp [our p.q.i.kiz] q.q.i.kiz ~]
16621603 ==
16631604
1664−Our list of blocks is in `q.kig`, so we iterate over it, cancelling our
1665−pending requests for each block. Our requests are all to clay, so we
1666−need only to send `%warp` kisses with a null instead of a rave.
1605+Our list of blocks is in `q.kig`, so we iterate over it, cancelling our pending
1606+requests for each block. Our requests are all to clay, so we need only to send
1607+`%warp` kisses with a null instead of a rave.
16671608
16681609 ++ amok
16691610 %_ ..zo
@@ -1671,12 +1612,12 @@ need only to send `%warp` kisses with a null instead of a rave.
16711612 dym.bay (~(del by dym.bay) nah)
16721613 ==
16731614
1674−We remove the task number from the map of numbers to tasks and the duct
1675−from the map of ducts to task numbers.
1615+We remove the task number from the map of numbers to tasks and the duct from the
1616+map of ducts to task numbers.
16761617
1677−Back in `++apex`, if we were given a silk, we need to process it. We add
1678−the task to our maps, increment the next task number, and call
1679−`++exec:zo` on the new task.
1618+Back in `++apex`, if we were given a silk, we need to process it. We add the
1619+task to our maps, increment the next task number, and call `++exec:zo` on the
1620+new task.
16801621
16811622 ++ exec :: execute app
16821623 ^+ ..zo
@@ -1697,9 +1638,9 @@ the task to our maps, increment the next task number, and call
16971638
16981639If we're still blocked on something in `q.kig`, we don't do anything.
16991640
1700−Otherwise, we try to process the silk with `++make`. `++make` handles
1701−each individual request and will be the entire focus of the remainder of
1702−this doc after this section. It produces a bolt of a cage.
1641+Otherwise, we try to process the silk with `++make`. `++make` handles each
1642+individual request and will be the entire focus of the remainder of this doc
1643+after this section. It produces a bolt of a cage.
17031644
17041645We put the new cache in our state with `++dash`.
17051646
@@ -1708,13 +1649,12 @@ We put the new cache in our state with `++dash`.
17081649 ^+ +>
17091650 %_(+> jav.bay q.cof)
17101651
1711−The cache is put in the baby so that it gets stored across calls to
1712−ford.
1652+The cache is put in the baby so that it gets stored across calls to ford.
17131653
1714−In `++exec`, we process the bolt in three different ways according to
1715−the type of bolt produced. If we produced a `%0` value bolt, we use
1716−`++expo` to give the produced value and set of dependencies as a `%made`
1717−gift, and we remove ourselves from the task list with `++amok`.
1654+In `++exec`, we process the bolt in three different ways according to the type
1655+of bolt produced. If we produced a `%0` value bolt, we use `++expo` to give the
1656+produced value and set of dependencies as a `%made` gift, and we remove
1657+ourselves from the task list with `++amok`.
17181658
17191659 ++ expo :: return gift
17201660 |= gef=gift
@@ -1722,11 +1662,11 @@ gift, and we remove ourselves from the task list with `++amok`.
17221662
17231663We simply push the gift onto our list of moves.
17241664
1725−In `++exec`, if we produced a `%2` error bolt, we produce a `%made` gift
1726−with the stack trace.
1665+In `++exec`, if we produced a `%2` error bolt, we produce a `%made` gift with
1666+the stack trace.
17271667
1728−If we produced a `%1` block bolt, we iterate through each of the blocks
1729−and call `++camp` to produce a clay request for the resource.
1668+If we produced a `%1` block bolt, we iterate through each of the blocks and call
1669+`++camp` to produce a clay request for the resource.
17301670
17311671 ++ camp :: request a file
17321672 |= [ren=care bem=beam]
@@ -1740,16 +1680,13 @@ and call `++camp` to produce a clay request for the resource.
17401680 [%warp [our p.bem] q.bem [~ %& %x r.bem s.bem]]
17411681 ==
17421682
1743−We put the resource in our block list in `q.kig` so that we save the
1744−fact that we're blocked. We then produce the `%warp` request to clay for
1745−the resource. Our request path has the format
1746−\`/[our-ship]/[task-number]/[block-number]'.
1683+We put the resource in our block list in `q.kig` so that we save the fact that
1684+we're blocked. We then produce the `%warp` request to clay for the resource. Our
1685+request path has the format \`/\[our-ship\]/\[task-number\]/\[block-number\]'.
17471686
1748−We'll now describe how each of the individual silks are processed in
1749−`++make`.
1687+We'll now describe how each of the individual silks are processed in `++make`.
17501688
1751−Lifecycle of a Cell
1752−-------------------
1689+## Lifecycle of a Cell
17531690
17541691 ^
17551692 %. [cof p.kas q.kas]
@@ -1763,10 +1700,10 @@ Lifecycle of a Cell
17631700 [p=cof q=[%0 ~ [%$ (slop q.bor q.heg)]]]
17641701 ==
17651702
1766−Silks autocons. The product of a cell of silks is a cell of the products
1767−of the silks, so we evaluate the two silks in parallel with `++coax` and
1768−slop together the results in a cell vase. We mark the product with `%$`,
1769−which means we know no more mark information than that it is a noun.
1703+Silks autocons. The product of a cell of silks is a cell of the products of the
1704+silks, so we evaluate the two silks in parallel with `++coax` and slop together
1705+the results in a cell vase. We mark the product with `%$`, which means we know
1706+no more mark information than that it is a noun.
17701707
17711708 ++ coax :: bolt across
17721709 |* [hoc=(bolt) fun=(burg)]
@@ -1790,23 +1727,19 @@ which means we know no more mark information than that it is a noun.
17901727 %2 hoc
17911728 ==
17921729
1793−If the first bolt is a value, we evaluate the burg to get the next bolt.
1794−If that also produces a value, we merge the dependency sets and produce
1795−a cell of the two values. Otherwise, we produce the block or error of
1796−the second bolt.
1730+If the first bolt is a value, we evaluate the burg to get the next bolt. If that
1731+also produces a value, we merge the dependency sets and produce a cell of the
1732+two values. Otherwise, we produce the block or error of the second bolt.
17971733
1798−If the first bolt is a block, we evaluate the burg to get the next bolt.
1799−If that produces a value, we just produce the block. If it produces a
1800−block, we merge the two block sets. If it produces an error, we produce
1801−that error.
1734+If the first bolt is a block, we evaluate the burg to get the next bolt. If that
1735+produces a value, we just produce the block. If it produces a block, we merge
1736+the two block sets. If it produces an error, we produce that error.
18021737
18031738If the first bolt is already an error, we just pass that through.
18041739
1805−Note that `++coax` (and, indeed, `++cope`) is reasonable to use with
1806−`;~`.
1740+Note that `++coax` (and, indeed, `++cope`) is reasonable to use with `;~`.
18071741
1808−Lifecycle of a `%bake`
1809−----------------------
1742+## Lifecycle of a `%bake`
18101743
18111744 %bake
18121745 %+ cool |.(leaf/"ford: bake {<p.kas>} {<(tope q.kas)>}")
@@ -1816,12 +1749,11 @@ Lifecycle of a `%bake`
18161749 (flaw cof (smyt (tope q.kas)) ~)
18171750 (fine cof [p.kas u.vux])
18181751
1819−This is one of the most critical silks. We are going to functionally
1820−produce the hook file at the given beam with the given heel. The result
1821−will be of the correct mark, even if we need to run conversion
1822−functions. The functionality is encapsulated in `++lime`. If it produces
1823−null, then we produce an error. Otherwise, we take the vase produced and
1824−give it the correct mark.
1752+This is one of the most critical silks. We are going to functionally produce the
1753+hook file at the given beam with the given heel. The result will be of the
1754+correct mark, even if we need to run conversion functions. The functionality is
1755+encapsulated in `++lime`. If it produces null, then we produce an error.
1756+Otherwise, we take the vase produced and give it the correct mark.
18251757
18261758 ++ lima :: load at depth
18271759 |= [cof=cafe for=mark bem=beam arg=heel]
@@ -1843,19 +1775,19 @@ give it the correct mark.
18431775 |= [cof=cafe vax=vase]
18441776 (fine cof ~ vax)
18451777
1846−First, we load the arch at the given beam with `++lend`. If we have a
1847−child named the mark, our job is straightforward, so we go ahead and
1848−load that with `++lace`.
1778+First, we load the arch at the given beam with `++lend`. If we have a child
1779+named the mark, our job is straightforward, so we go ahead and load that with
1780+`++lace`.
18491781
1850−Otherwise, we iterate through our children. If we have no children, we
1851−produce null, signifying that we didn't find any way to convert to the
1852−requested mark. Otherwise, we call `++lion` to find a translation path
1853−from one of the available marks into the target mark. We recursively
1854−bake the child that has a path to the target mark, and then we call
1855−`++lope` to translate this mark into the target mark.
1782+Otherwise, we iterate through our children. If we have no children, we produce
1783+null, signifying that we didn't find any way to convert to the requested mark.
1784+Otherwise, we call `++lion` to find a translation path from one of the available
1785+marks into the target mark. We recursively bake the child that has a path to the
1786+target mark, and then we call `++lope` to translate this mark into the target
1787+mark.
18561788
1857−We'll first discuss the direct case of when one of our children is of
1858−the correct mark.
1789+We'll first discuss the direct case of when one of our children is of the
1790+correct mark.
18591791
18601792 ++ lace :: load and check
18611793 |= [cof=cafe for=mark bem=beam arg=heel]
@@ -1871,11 +1803,10 @@ the correct mark.
18711803 (cope (cope (abut:(meow bem arg) cof hyd) (lake for bek)) fest)
18721804 (fine cof ~)
18731805
1874−First, we get the arch at the given beam with `++lend`. If this is a
1875−file, we load the file with `++liar` and coerce the type with `++lake`.
1876−Otherwise, we check to see if we have a hook file here. If so, we parse
1877−it with `++fade`, compile it with `++abut:meow`, and coerce the type
1878−with `++lake`.
1806+First, we get the arch at the given beam with `++lend`. If this is a file, we
1807+load the file with `++liar` and coerce the type with `++lake`. Otherwise, we
1808+check to see if we have a hook file here. If so, we parse it with `++fade`,
1809+compile it with `++abut:meow`, and coerce the type with `++lake`.
18791810
18801811Otherwise, there is no way to translate this, so we produce null.
18811812
@@ -1886,9 +1817,8 @@ Otherwise, there is no way to translate this, so we produce null.
18861817This is just `++some` for bolts.
18871818
18881819We've delayed the discussion of `++fade` far too many times. It's not
1889−complicated, we just wanted to spare a premature discussion of `++make`
1890−and the `%bake` silk. We 're now able to discuss everything in `++fade`
1891−with ease.
1820+complicated, we just wanted to spare a premature discussion of `++make` and the
1821+`%bake` silk. We 're now able to discuss everything in `++fade` with ease.
18921822
18931823 ++ fade :: compile to hood
18941824 |= [cof=cafe for=mark bem=beam]
@@ -1907,18 +1837,17 @@ with ease.
19071837 (flaw cof [%leaf "syntax error: {<p.p.vex>} {<q.p.vex>}"] ~)
19081838 (fine cof p.u.q.vex)
19091839
1910−We first push a line onto a stack trace to say that we're parsing into a
1911−hood file.
1840+We first push a line onto a stack trace to say that we're parsing into a hood
1841+file.
19121842
1913−We bake the given beam with the given mark and no heel. Recall that
1914−baking gate, core, door, hoon, and hook files produces simply an atom of
1915−the text. We check to make sure that our value is an atom, failing
1916−otherwise.
1843+We bake the given beam with the given mark and no heel. Recall that baking gate,
1844+core, door, hoon, and hook files produces simply an atom of the text. We check
1845+to make sure that our value is an atom, failing otherwise.
19171846
1918−The parsing step is run within `++clef` so that the result is cached. We
1919−call `++fair` with the current beam to generate the parsing rule, and we
1920−parse the file. If parsing fails, we fail giving a syntax error with the
1921−line and column number. Otherwise, we produce the value.
1847+The parsing step is run within `++clef` so that the result is cached. We call
1848+`++fair` with the current beam to generate the parsing rule, and we parse the
1849+file. If parsing fails, we fail giving a syntax error with the line and column
1850+number. Otherwise, we produce the value.
19221851
19231852 ++ liar :: load vase
19241853 |= [cof=cafe bem=beam]
@@ -1930,15 +1859,14 @@ line and column number. Otherwise, we produce the value.
19301859 (flaw cof (smyt (tope bem)) ~)
19311860 (fine cof ?^(u.u.von [%cell %noun %noun] [%atom %$]) u.u.von)
19321861
1933−This takes a beam and loads the file at that location. If our sky
1934−function produces null, that means the resource is currently
1935−unavailable, so we block on it. If it produces `[~ ~]`, that means our
1936−resource is permanently unavailable, so we produce an error. Otherwise,
1937−we produce the value there with a type of either a cell of two nouns or
1938−an atom, depending on whether the value is a cell or not.
1862+This takes a beam and loads the file at that location. If our sky function
1863+produces null, that means the resource is currently unavailable, so we block on
1864+it. If it produces `[~ ~]`, that means our resource is permanently unavailable,
1865+so we produce an error. Otherwise, we produce the value there with a type of
1866+either a cell of two nouns or an atom, depending on whether the value is a cell
1867+or not.
19391868
1940−Back in `++lima`, recall that we call `++lion` to find a translation
1941−path.
1869+Back in `++lima`, recall that we call `++lion` to find a translation path.
19421870
19431871 ++ lion :: translation search
19441872 |= [cof=cafe too=@tas bek=beak fro=(list ,@tas)]
@@ -1973,41 +1901,38 @@ path.
19731901 (fine cof ?~(ked ~ [~ for u.ked]))
19741902 --
19751903
1976−At a high level, we have `++apex` and `++apse`. `++apex` takes a list of
1977−marks to try in succession until we find one that can be translated into
1978−the target mark. On each one, it calls `++apse`, which takes a single
1979−mark and tries to find a translation path from this mark to the target.
1980−To do this, it sees which marks we know how to directly translate to,
1981−and calls `++apex` on this list. The result of this mututal recursion is
1982−a depth-first search of the translation graph to find the target mark.
1983−Since the translation graph is not necessarily acyclic, we maintain a
1984−set of marks that we've already tried.
1904+At a high level, we have `++apex` and `++apse`. `++apex` takes a list of marks
1905+to try in succession until we find one that can be translated into the target
1906+mark. On each one, it calls `++apse`, which takes a single mark and tries to
1907+find a translation path from this mark to the target. To do this, it sees which
1908+marks we know how to directly translate to, and calls `++apex` on this list. The
1909+result of this mututal recursion is a depth-first search of the translation
1910+graph to find the target mark. Since the translation graph is not necessarily
1911+acyclic, we maintain a set of marks that we've already tried.
19851912
1986−We kick off our search in `++apex`, starting with the given initial list
1987−of marks that we know how to get to.
1913+We kick off our search in `++apex`, starting with the given initial list of
1914+marks that we know how to get to.
19881915
1989−If `++apex` is called with a bolt other than a `%0` value bolt, we
1990−simply produce it. Otherwise, we check to see if the list of available
1991−marks to investigate is null. If so, then we're done, so we produce a
1992−`%0` bolt with a null list of accessible marks.
1916+If `++apex` is called with a bolt other than a `%0` value bolt, we simply
1917+produce it. Otherwise, we check to see if the list of available marks to
1918+investigate is null. If so, then we're done, so we produce a `%0` bolt with a
1919+null list of accessible marks.
19931920
19941921Otherwise, we process this next mark with `++apse`, which will produce a
1995−possible list of marks from this one to the target mark. If it fails to
1996−produce a `%0` bolt, we just produce that. Otherwise, if it produces
1997−null, we can't get to our target through this mark, so we move on to the
1998−next one.
1922+possible list of marks from this one to the target mark. If it fails to produce
1923+a `%0` bolt, we just produce that. Otherwise, if it produces null, we can't get
1924+to our target through this mark, so we move on to the next one.
19991925
2000−If it doesn't produce null, then we have successfully found a
2001−translation path, so we produce it.
1926+If it doesn't produce null, then we have successfully found a translation path,
1927+so we produce it.
20021928
2003−In `++apse`, we first test to see if we've arrived at the target path.
2004−If so, we're done, so we produce a list including just ourself.
2005−Otherwise, we check to see if we've already tried this mark. If so, we
2006−know we can't succeed here, so we produce null. Otherwise, we put
2007−ourselves in the set of already-tried marks, and we move on.
1929+In `++apse`, we first test to see if we've arrived at the target path. If so,
1930+we're done, so we produce a list including just ourself. Otherwise, we check to
1931+see if we've already tried this mark. If so, we know we can't succeed here, so
1932+we produce null. Otherwise, we put ourselves in the set of already-tried marks,
1933+and we move on.
20081934
2009−We call `++lily` to get the list of marks we can translate this one
2010−into.
1935+We call `++lily` to get the list of marks we can translate this one into.
20111936
20121937 ++ lily :: translation targets
20131938 |= [cof=cafe for=mark bek=beak]
@@ -2026,29 +1951,27 @@ into.
20261951 =+ gow=(slap vax [%cnzy %grow])
20271952 (sloe p.gow)
20281953
2029−We call `++fang` to get the mark definition door. This is documented
2030−under `%vale`. If getting the mark fails, we produce null because we
2031−can't translate a non-existent mark into anything.
1954+We call `++fang` to get the mark definition door. This is documented under
1955+`%vale`. If getting the mark fails, we produce null because we can't translate a
1956+non-existent mark into anything.
20321957
2033−Otherwise, we examine the door. The door may have a `++garb`, which is
2034−simply a list of marks which know how to translate from the current one.
2035−There must be a corresponding `++grab` in the definition of the other
2036−mark, though we don't check that here.
1958+Otherwise, we examine the door. The door may have a `++garb`, which is simply a
1959+list of marks which know how to translate from the current one. There must be a
1960+corresponding `++grab` in the definition of the other mark, though we don't
1961+check that here.
20371962
2038−The door may also have a `++grow`, which defines how to translate this
2039−mark into another one. Each arm in `++grow` is the name of a mark we can
2040−translate into. The call to `++sloe` simply produces a list of arm names
2041−in `++grow`.
1963+The door may also have a `++grow`, which defines how to translate this mark into
1964+another one. Each arm in `++grow` is the name of a mark we can translate into.
1965+The call to `++sloe` simply produces a list of arm names in `++grow`.
20421966
2043−Back in `++apse:lion`, we take the list of translation targets we just
2044−found and call `++apex` on it. If we got back a null, we produce a null;
2045−otherwise, we produce the list of marks we got back plus the current
2046−mark.
1967+Back in `++apse:lion`, we take the list of translation targets we just found and
1968+call `++apex` on it. If we got back a null, we produce a null; otherwise, we
1969+produce the list of marks we got back plus the current mark.
20471970
20481971This concludes our discussion of `++lion`.
20491972
2050−The final piece of `++lima` is `++lope`, which performs the actual
2051−translation along the path we just computed.
1973+The final piece of `++lima` is `++lope`, which performs the actual translation
1974+along the path we just computed.
20521975
20531976 ++ lope :: translation pipe
20541977 |= [cof=cafe for=mark yaw=(list mark) bek=beak vax=vase]
@@ -2058,14 +1981,12 @@ translation along the path we just computed.
20581981 |= [cof=cafe yed=vase]
20591982 ^$(cof cof, for i.yaw, yaw t.yaw, vax yed)
20601983
2061−We iterate through our list, calling `++link` on every adjacent pair of
2062−marks, translating from one mark to the next until we finish the list of
2063−marks. A call to `++link` is equivalent to a `%cast` silk, so we
2064−document it there. After we've called performed every step in the
2065−translation pipeline, we're done.
1984+We iterate through our list, calling `++link` on every adjacent pair of marks,
1985+translating from one mark to the next until we finish the list of marks. A call
1986+to `++link` is equivalent to a `%cast` silk, so we document it there. After
1987+we've called performed every step in the translation pipeline, we're done.
20661988
2067−Lifecycle of a `%boil`
2068−----------------------
1989+## Lifecycle of a `%boil`
20691990
20701991 %boil
20711992 %+ cool |.(leaf/"ford: boil {<p.kas>} {<(tope q.kas)>} {<r.kas>}")
@@ -2075,13 +1996,13 @@ Lifecycle of a `%boil`
20751996 |= [cof=cafe vax=vase]
20761997 (fine cof `cage`[p.kas vax])
20771998
2078−At a high level, we try to bake at the given beam, and if it fails, we
2079−go up a level and try again. This is the usual semantics of ford, and
2080−this should nearly always be preferred over directly baking.
1999+At a high level, we try to bake at the given beam, and if it fails, we go up a
2000+level and try again. This is the usual semantics of ford, and this should nearly
2001+always be preferred over directly baking.
20812002
2082−First, we normalize the version case to a number with `++lamp`. This
2083−allows caching to be based on revision number rather than something more
2084−ephemeral like a particular time.
2003+First, we normalize the version case to a number with `++lamp`. This allows
2004+caching to be based on revision number rather than something more ephemeral like
2005+a particular time.
20852006
20862007 ++ lamp :: normalize version
20872008 |= [cof=cafe bem=beam]
@@ -2090,11 +2011,10 @@ ephemeral like a particular time.
20902011 ?~ von [p=cof q=[%1 [bem ~] ~ ~]]
20912012 (fine cof bem(r [%ud ((hard ,@) (need u.von))]))
20922013
2093−We call the sky function with `%cw`, asking clay for the revision number
2094−at this case. If the case refers to a revision that isn't there yet, we
2095−produce a `%1` blocking bolt. Otherwise, we require that the value exist
2096−and that it's a number, both of which are guaranteed by clay. We produce
2097−this number.
2014+We call the sky function with `%cw`, asking clay for the revision number at this
2015+case. If the case refers to a revision that isn't there yet, we produce a `%1`
2016+blocking bolt. Otherwise, we require that the value exist and that it's a
2017+number, both of which are guaranteed by clay. We produce this number.
20982018
20992019Next for `%boil` we call `++lime` to try to load the beam.
21002020
@@ -2109,14 +2029,13 @@ Next for `%boil` we call `++lime` to try to load the beam.
21092029 (flaw cof (smyt (tope bem)) ~)
21102030 ^$(s.mob t.s.mob, mer [i.s.mob mer])
21112031
2112−We start at the given beam and try to bake it. If it succeeds, we're
2113−good. Otherwise, we pop off the top level of the path and put it in our
2114−heel (virtual path extension). We do this recursively until either we
2115−find something we can bake or we've gone all the way up to the root path
2116−of the desk, in which case we fail.
2032+We start at the given beam and try to bake it. If it succeeds, we're good.
2033+Otherwise, we pop off the top level of the path and put it in our heel (virtual
2034+path extension). We do this recursively until either we find something we can
2035+bake or we've gone all the way up to the root path of the desk, in which case we
2036+fail.
21172037
2118−Lifecycle of a `%call`
2119−----------------------
2038+## Lifecycle of a `%call`
21202039
21212040 %call
21222041 %+ cool |.(leaf/"ford: call {<`@p`(mug kas)>}")
@@ -2134,15 +2053,13 @@ Lifecycle of a `%call`
21342053 (fine cof %noun vax)
21352054 ==
21362055
2137−This is slam for silks. We process both of the given silks in parallel
2138−with `++coax`. We then slam the two produced vases together with
2139−`++maul` and mark the produced vase with `%noun` since we don't know any
2140−more specific mark.
2056+This is slam for silks. We process both of the given silks in parallel with
2057+`++coax`. We then slam the two produced vases together with `++maul` and mark
2058+the produced vase with `%noun` since we don't know any more specific mark.
21412059
21422060`++coax` is documented under Lifecycle of a Cell.
21432061
2144−Lifecycle of a `%cast`
2145−----------------------
2062+## Lifecycle of a `%cast`
21462063
21472064 %cast
21482065 %+ cool |.(leaf/"ford: cast {<p.kas>}")
@@ -2152,11 +2069,11 @@ Lifecycle of a `%cast`
21522069 |= [cof=cafe vax=vase]
21532070 (fine cof [p.kas vax])
21542071
2155−This is a request to convert data of one mark to another mark directly.
2156−We evaluate the given silk and pass the result into `++link`, which
2157−performs the actual translation. Note that this will not search for
2158−indirect conversion paths, so the conversion must be defined either in
2159−the `++grow` of the given mark or the `++grab` of the target mark.
2072+This is a request to convert data of one mark to another mark directly. We
2073+evaluate the given silk and pass the result into `++link`, which performs the
2074+actual translation. Note that this will not search for indirect conversion
2075+paths, so the conversion must be defined either in the `++grow` of the given
2076+mark or the `++grab` of the target mark.
21602077
21612078 ++ link :: translate
21622079 |= [cof=cafe too=mark for=mark bek=beak vax=vase]
@@ -2181,29 +2098,28 @@ the `++grow` of the given mark or the `++grab` of the target mark.
21812098 (flaw cof [%leaf "ford: no link: {<[for too]>}"]~)
21822099 (maul cof u.zat vax)
21832100
2184−This performs one step in the translation pipeline. If the given and
2185−target marks are the same, we're done. If we're translating from a noun
2186−or the empty mark, we coerce with `++lake` (documented in `%vale`).
2187−Otherwise, we're translating from a user-defined mark.
2101+This performs one step in the translation pipeline. If the given and target
2102+marks are the same, we're done. If we're translating from a noun or the empty
2103+mark, we coerce with `++lake` (documented in `%vale`). Otherwise, we're
2104+translating from a user-defined mark.
21882105
2189−We load the definition of the given mark with `++fang`, and we check to
2190−see if it has an arm in `++grow` named the target mark. If so, we place
2191−our data in the sample of the door with `++keel` and slap the arm.
2192−`++keel` is equivalent to a `%mute` silk, so we document it there.
2106+We load the definition of the given mark with `++fang`, and we check to see if
2107+it has an arm in `++grow` named the target mark. If so, we place our data in the
2108+sample of the door with `++keel` and slap the arm. `++keel` is equivalent to a
2109+`%mute` silk, so we document it there.
21932110
2194−If there is no arm in `++grow` of the given mark named the target mark,
2195−we suppose there must be an arm in `++grab` of the target mark named the
2196−given mark. We get the definition of the target mark and check to see if
2197−it has the required arm, failing if it doesn't. Finally, we slam the
2198−data against the correct arm, producing the translated data.
2111+If there is no arm in `++grow` of the given mark named the target mark, we
2112+suppose there must be an arm in `++grab` of the target mark named the given
2113+mark. We get the definition of the target mark and check to see if it has the
2114+required arm, failing if it doesn't. Finally, we slam the data against the
2115+correct arm, producing the translated data.
21992116
22002117If you're confused as to why the handling of `++grow` and `++grab` look
2201−superficially so different, remember that the correct arm in `++grow`
2202−does not have a sample while the one in `++grab` does. This means they
2203−must be called rather differently.
2118+superficially so different, remember that the correct arm in `++grow` does not
2119+have a sample while the one in `++grab` does. This means they must be called
2120+rather differently.
22042121
2205−Lifecycle of a `%diff`
2206−----------------------
2122+## Lifecycle of a `%diff`
22072123
22082124 %diff
22092125 %+ cool |.(leaf/"ford: diff {<`@p`(mug p.kas)>} {<`@p`(mug q.kas)>}")
@@ -2228,8 +2144,7 @@ First, we process the two given silks to get our arguments.
22282144 %+ flaw cof :_ ~
22292145 leaf/"diff on data of different marks: {(trip p.cay)} {(trip p.coy)}"
22302146
2231−If the two cages have different marks, then we can't diff them, so we
2232−complain.
2147+If the two cages have different marks, then we can't diff them, so we complain.
22332148
22342149 %+ cope (fang cof p.cay [our %main %da now])
22352150 |= [cof=cafe pro=vase]
@@ -2247,12 +2162,11 @@ We pull in the relevant mark's definition.
22472162 (flaw cof leaf/"bad ++sted:grad" ~)
22482163 (make cof %diff [%cast u.for kas] [%cast u.for kos])
22492164
2250−If there's no `++grad`, we complain. If there's no `++form:grad`, then
2251−we look for a `++sted:grad`. If we can't find either, or if
2252−`++sted:grad` isn't a term, then we complain. If `++sted:grad` exists
2253−and is a term, then it represents the mark we should use as a proxy to
2254−get our diff. So, we cast both our given cages to the new mark and start
2255−the dance again.
2165+If there's no `++grad`, we complain. If there's no `++form:grad`, then we look
2166+for a `++sted:grad`. If we can't find either, or if `++sted:grad` isn't a term,
2167+then we complain. If `++sted:grad` exists and is a term, then it represents the
2168+mark we should use as a proxy to get our diff. So, we cast both our given cages
2169+to the new mark and start the dance again.
22562170
22572171 ?. (slab %diff p.gar)
22582172 (flaw cof leaf/"no ++diff:grad" ~)
@@ -2262,8 +2176,7 @@ Otherwise, we expect a `++diff:grad`.
22622176 %+ cope (keel cof pro [[%& 6]~ q.cay]~)
22632177 |= [cof=cafe pox=vase]
22642178
2265−We put the first cage's data into the sample of the given mark's
2266−definition.
2179+We put the first cage's data into the sample of the given mark's definition.
22672180
22682181 %+ cope
22692182 %^ maul cof
@@ -2279,46 +2192,41 @@ We run `++diff:grad` with a sample of the second cage's data.
22792192 (fine cof u.for dif)
22802193 ==
22812194
2282−We check that `++form:grad` exists, and we tag the result with it to
2283−give the final cage.
2195+We check that `++form:grad` exists, and we tag the result with it to give the
2196+final cage.
22842197
2285−Lifecycle of a `%done`
2286−----------------------
2198+## Lifecycle of a `%done`
22872199
22882200 %done [cof %0 p.kas q.kas]
22892201
22902202This is trivial. We simply produce the given cage with the given set of
2291−dependencies. This is used when we already have a cage that we want to
2292−insert into another silk that requires a silk argument. It's analogous
2293−to the return operator in a monad -- which makes it sound way more
2294−complicated than it is.
2203+dependencies. This is used when we already have a cage that we want to insert
2204+into another silk that requires a silk argument. It's analogous to the return
2205+operator in a monad -- which makes it sound way more complicated than it is.
22952206
2296−Lifecycle of a `%dude`
2297−----------------------
2207+## Lifecycle of a `%dude`
22982208
22992209 %dude (cool |.(p.kas) $(kas q.kas))
23002210
2301−This simply puts a given tank on the stack trace if the given silk
2302−produces an error. This is implemented as a simple call to `++cool`.
2211+This simply puts a given tank on the stack trace if the given silk produces an
2212+error. This is implemented as a simple call to `++cool`.
23032213
2304−Lifecycle of a `%dune`
2305−----------------------
2214+## Lifecycle of a `%dune`
23062215
23072216 %dune
23082217 ?~ q.kas [cof [%2 [%leaf "no data"]~]]
23092218 $(kas [%done p.kas u.q.kas])
23102219
2311−This is a sort of a `++need` for silks. If there is no data in the unit
2312−cage, we produce an error. Else, we simply produce the data in the cage.
2220+This is a sort of a `++need` for silks. If there is no data in the unit cage, we
2221+produce an error. Else, we simply produce the data in the cage.
23132222
2314−Lifcycle of a `%mute`
2315−---------------------
2223+## Lifcycle of a `%mute`
23162224
23172225 %mute (kale cof p.kas q.kas)
23182226
2319−This mutates a silk by putting the values of other silks at particular
2320−axes. This is useful in, for example, replacing the sample of the door
2321−in a mark definition.
2227+This mutates a silk by putting the values of other silks at particular axes.
2228+This is useful in, for example, replacing the sample of the door in a mark
2229+definition.
23222230
23232231 ++ kale :: mutate
23242232 |= [cof=cafe kas=silk muy=(list (pair wing silk))]
@@ -2338,10 +2246,10 @@ in a mark definition.
23382246 |= [cof=cafe vax=vase]
23392247 (fine cof p.cay vax)
23402248
2341−First, we process each of the silks by calling `++make` on them. We pass
2342−the resultant vase and list of pairs of wings and silks to `++keel` to
2343−do the actual mutation. We assume the mutation doesn't change the mark
2344−of the main silk, so we mark the produced vase with the original mark.
2249+First, we process each of the silks by calling `++make` on them. We pass the
2250+resultant vase and list of pairs of wings and silks to `++keel` to do the actual
2251+mutation. We assume the mutation doesn't change the mark of the main silk, so we
2252+mark the produced vase with the original mark.
23452253
23462254 ++ keel :: apply mutations
23472255 |= [cof=cafe suh=vase yom=(list (pair wing vase))]
@@ -2359,19 +2267,16 @@ of the main silk, so we mark the produced vase with the original mark.
23592267 :- [p.i.yom [%$ (peg axe 2)]]
23602268 $(yom t.yom, axe (peg axe 3))
23612269
2362−We first put the vases together in one big tuple starting with the
2363−subject and going through the mutations. We slap against this tuple a
2364−`%_` twig we directly construct. Since a `%_` twig takes a list of pairs
2365−of wings and twigs, we simply have to generate twigs referring to the
2366−correct axes in the subject. This is very easy since we just recur on
2367−axis 3 of whatever axis we were already at.
2270+We first put the vases together in one big tuple starting with the subject and
2271+going through the mutations. We slap against this tuple a `%_` twig we directly
2272+construct. Since a `%_` twig takes a list of pairs of wings and twigs, we simply
2273+have to generate twigs referring to the correct axes in the subject. This is
2274+very easy since we just recur on axis 3 of whatever axis we were already at.
23682275
2369−Note the use of `%_` instead of `%=` enforces that our mutations don't
2370−change the type of the subject, which justifies our use of the original
2371−mark.
2276+Note the use of `%_` instead of `%=` enforces that our mutations don't change
2277+the type of the subject, which justifies our use of the original mark.
23722278
2373−Lifecycle of a `%pact`
2374−----------------------
2279+## Lifecycle of a `%pact`
23752280
23762281 %pact
23772282 %+ cool |.(leaf/"ford: pact {<`@p`(mug p.kas)>} {<`@p`(mug q.kas)>}")
@@ -2408,12 +2313,12 @@ We pull in the relevant mark's definition.
24082313 (flaw cof leaf/"bad ++sted:grad" ~)
24092314 (make cof %cast p.cay %pact [%cast u.for kas] kos)
24102315
2411−If there's no `++grad`, we complain. If there's no `++form:grad`, then
2412−we look for a `++sted:grad`. If we can't find either, or if
2413−`++sted:grad` isn't a term, then we complain. If `++sted:grad` exists
2414−and is a term, then it represents the mark we should use as a proxy to
2415−get our diff. So, we cast the first argument to the new mark, then try
2416−to patch. Afterward, we cast the result back to the original mark.
2316+If there's no `++grad`, we complain. If there's no `++form:grad`, then we look
2317+for a `++sted:grad`. If we can't find either, or if `++sted:grad` isn't a term,
2318+then we complain. If `++sted:grad` exists and is a term, then it represents the
2319+mark we should use as a proxy to get our diff. So, we cast the first argument to
2320+the new mark, then try to patch. Afterward, we cast the result back to the
2321+original mark.
24172322
24182323 =+ for=((soft ,@tas) q:(slap gar [%cnzy %form]))
24192324 ?~ for
@@ -2423,8 +2328,8 @@ to patch. Afterward, we cast the result back to the original mark.
24232328 =< leaf/"pact on data with wrong form: {-} {+<} {+>}"
24242329 [(trip p.cay) (trip u.for) (trip p.coy)]
24252330
2426−If `++form:grad` isn't a term, or else our second argument isn't of that
2427−mark, we complain.
2331+If `++form:grad` isn't a term, or else our second argument isn't of that mark,
2332+we complain.
24282333
24292334 ?. (slab %pact p.gar)
24302335 (flaw cof leaf/"no ++pact:grad" ~)
@@ -2434,8 +2339,7 @@ If we don't have a `++pact:grad`, we complain.
24342339 %+ cope (keel cof pro [[%& 6]~ q.cay]~)
24352340 |= [cof=cafe pox=vase]
24362341
2437−We put the first cage's data into the sample of the given mark's
2438−definition.
2342+We put the first cage's data into the sample of the given mark's definition.
24392343
24402344 %+ cope
24412345 %^ maul cof
@@ -2443,36 +2347,32 @@ definition.
24432347 q.coy
24442348 |= [cof=cafe pat=vase]
24452349
2446−We run `++pact:grad` with a sample of the second cage's data, which is
2447−the diff.
2350+We run `++pact:grad` with a sample of the second cage's data, which is the diff.
24482351
24492352 (fine cof p.cay pat)
24502353 ==
24512354
24522355We tag the result with the mark of our first argument.
24532356
2454−Lifecycle of a `%plan`
2455−----------------------
2357+## Lifecycle of a `%plan`
24562358
24572359 %plan
24582360 %+ cope (abut:(meow p.kas q.kas) cof r.kas)
24592361 |= [cof=cafe vax=vase]
24602362 (fine cof %noun vax)
24612363
2462−This is a direct request to compile a hood at a given beam with a heel
2463−of the given path. We comply by calling `++abut` with the given
2464−arguments and producing the vase with a mark of `%noun`.
2364+This is a direct request to compile a hood at a given beam with a heel of the
2365+given path. We comply by calling `++abut` with the given arguments and producing
2366+the vase with a mark of `%noun`.
24652367
2466−Lifecycle of a `%reef`
2467−----------------------
2368+## Lifecycle of a `%reef`
24682369
24692370 %reef (fine cof %noun pit)
24702371
2471−This is one of the simplest silks. We simply produce our context, which
2472−is zuse compiled against hoon. The mark is a `%noun`.
2372+This is one of the simplest silks. We simply produce our context, which is zuse
2373+compiled against hoon. The mark is a `%noun`.
24732374
2474−Lifcycle of a `%ride`
2475−---------------------
2375+## Lifcycle of a `%ride`
24762376
24772377 %ride
24782378 %+ cool |.(leaf/"ford: ride {<`@p`(mug kas)>}")
@@ -2482,12 +2382,11 @@ Lifcycle of a `%ride`
24822382 |= [cof=cafe vax=vase]
24832383 (fine cof %noun vax)
24842384
2485−This slaps evaluates the given silk, then it slaps the result against
2486−the given twig. Since we don't know what of what mark (if any) is the
2487−result, we give it a mark of `%noun`.
2385+This slaps evaluates the given silk, then it slaps the result against the given
2386+twig. Since we don't know what of what mark (if any) is the result, we give it a
2387+mark of `%noun`.
24882388
2489−Lifecycle of a `%vale`
2490−----------------------
2389+## Lifecycle of a `%vale`
24912390
24922391 %vale
24932392 %+ cool |.(leaf/"ford: vale {<p.kas>} {<q.kas>} {<`@p`(mug r.kas)>}")
@@ -2495,20 +2394,20 @@ Lifecycle of a `%vale`
24952394 |= [cof=cafe vax=vase]
24962395 (fine cof `cage`[p.kas vax])
24972396
2498−This checks whether given data is of the given mark. If we don't have
2499−the definition of the mark, we check the given ship for it.
2397+This checks whether given data is of the given mark. If we don't have the
2398+definition of the mark, we check the given ship for it.
25002399
2501−We call `++lave` to perform the check, producing a vase. We produce this
2502−vase tagged with the given mark.
2400+We call `++lave` to perform the check, producing a vase. We produce this vase
2401+tagged with the given mark.
25032402
25042403 ++ lave :: validate
25052404 |= [cof=cafe for=mark his=ship som=*]
25062405 ^- (bolt vase)
25072406 ((lake for [our %main [%da now]]) cof [%noun som])
25082407
2509−This is a thinly-veiled wrapper over `++lake`. Note that, contrary to
2510−documented opinion, we do not in fact check the other ship's definition
2511−of a mark. This is likely a bug.
2408+This is a thinly-veiled wrapper over `++lake`. Note that, contrary to documented
2409+opinion, we do not in fact check the other ship's definition of a mark. This is
2410+likely a bug.
25122411
25132412At any rate, `++lake` coerces a noun into the correct type for a mark.
25142413
@@ -2536,27 +2435,24 @@ At any rate, `++lake` coerces a noun into the correct type for a mark.
25362435 (fine cof (slot 6 pro))
25372436 (flaw cof [%leaf "ford: invalid content: {<[for bek]>}"]~)
25382437
2539−This is going to coerce the sample into the correct type for the mark.
2540−First, we push a line onto the stack trace saying that we're checking
2541−the type. If the requested mark is a gate, core, door, hoon, or hook,
2542−then we don't do any more type information than just saying it's a noun,
2543−so we're done.
2438+This is going to coerce the sample into the correct type for the mark. First, we
2439+push a line onto the stack trace saying that we're checking the type. If the
2440+requested mark is a gate, core, door, hoon, or hook, then we don't do any more
2441+type information than just saying it's a noun, so we're done.
25442442
2545−Otherwise, we get the mark definition from our `/=main=/mar` directory
2546−with `++fang`, which we'll describe below.
2443+Otherwise, we get the mark definition from our `/=main=/mar` directory with
2444+`++fang`, which we'll describe below.
25472445
2548−We check to see if our sample type nests within the type of the sample
2549−to the door. If so, then we're already of the correct type, so we're
2550−done.
2446+We check to see if our sample type nests within the type of the sample to the
2447+door. If so, then we're already of the correct type, so we're done.
25512448
2552−Otherwise, we check to see if there's a `++grab` in the door, and a
2553−`++noun` in the `++grab`. If not, there's no way we can translate to
2554−this mark, so we fail.
2449+Otherwise, we check to see if there's a `++grab` in the door, and a `++noun` in
2450+the `++grab`. If not, there's no way we can translate to this mark, so we fail.
25552451
2556−If we have everything we need, we slam our sample (typed as a noun)
2557−against the `++noun` in `++grab`. If the sample of the door is the same
2558−as our sample, then the check succeeded, so we produce the well-typed
2559−sample of the door. Otherwise, we fail.
2452+If we have everything we need, we slam our sample (typed as a noun) against the
2453+`++noun` in `++grab`. If the sample of the door is the same as our sample, then
2454+the check succeeded, so we produce the well-typed sample of the door. Otherwise,
2455+we fail.
25602456
25612457 ++ fang :: protocol door
25622458 |= [cof=cafe for=mark bek=beak]
@@ -2571,6 +2467,6 @@ sample of the door. Otherwise, we fail.
25712467 (cope (fade cof %hook bem) abut:(meow bem ~))
25722468
25732469A mark's definition is generally in
2574−`/=main=/mar/[mark-name]/door/hook'. If we don't find it there, we look in`/[given-beak]/mar/[mark-name]/door/hook'.
2575−We parse the mark definition with `++fade` and assemble it with
2576−`++abut:meow`. `++fade` is defined under the `%bake` silk.
2470+`/=main=/mar/[mark-name]/door/hook'. If we don't find it there, we look in`/\[given-beak\]/mar/\[mark-name\]/door/hook'.
2471+We parse the mark definition with `++fade` and assemble it with `++abut:meow`.
2472+`++fade` is defined under the `%bake` silk.
docs/arvo/internals/ford/runes.md+228−225
@@ -2,22 +2,33 @@
22
33## ford runes
44
5−One of the most common ways to use ford is through ford's runes, all of which begin with `/` ("fas"). A ford rune runs a step of a ford build and places the result in the subject. There are various kinds of build steps, some of which take other build steps as parameters. The most common pattern is to have a sequence of ford runes at the top of a hoon source file that import the results of evaluating other hoon files. This is how we "import a library" in urbit: we add the result of compiling another hoon file into the current subject, possibly renaming it by wrapping a face around it.
6−
7−Another common use case is assembling and rendering markdown templates into a single HTML file, to be sent as an HTTP response in urbit's web server `%eyre`. It's important to keep in mind that %ford is quite flexible and generic, and is used in other parts of urbit -- such as the dojo -- that would not traditionally fall under the purview of a build system.
5+One of the most common ways to use ford is through ford's runes, all of which
6+begin with `/` ("fas"). A ford rune runs a step of a ford build and places the
7+result in the subject. There are various kinds of build steps, some of which
8+take other build steps as parameters. The most common pattern is to have a
9+sequence of ford runes at the top of a hoon source file that import the results
10+of evaluating other hoon files. This is how we "import a library" in urbit: we
11+add the result of compiling another hoon file into the current subject, possibly
12+renaming it by wrapping a face around it.
13+
14+Another common use case is assembling and rendering markdown templates into a
15+single HTML file, to be sent as an HTTP response in urbit's web server `%eyre`.
16+It's important to keep in mind that %ford is quite flexible and generic, and is
17+used in other parts of urbit -- such as the dojo -- that would not traditionally
18+fall under the purview of a build system.
819
920### `/+` import from lib/
1021
11−The `/+` rune accepts a filename as an argument. It interprets that filename
12−as a hoon source file within the `lib` directory. This is how we import a shared
22+The `/+` rune accepts a filename as an argument. It interprets that filename as
23+a hoon source file within the `lib` directory. This is how we import a shared
1324library in urbit.
1425
1526Example:
16−```
17−/+ time-to-id
18−::
19−(time-to-id now)
20−```
27+
28+ /+ time-to-id
29+ ::
30+ (time-to-id now)
31+
2132produces: `"c.314d"` (or something similar depending on when you run it)
2233
2334### `/-` import from sur/
@@ -28,11 +39,11 @@ shared structures that can be used by other parts of urbit. This is somewhat
2839similar to including a header file in C.
2940
3041Example:
31−```
32−/- talk
33−::
34−*serial:talk
35−```
42+
43+ /- talk
44+ ::
45+ *serial:talk
46+
3647produces: `0v0`
3748
3849### `/~` twig by hand
@@ -43,53 +54,52 @@ the subject. Arbitrary hoon can be in the twig. A
4354structure representing a `%ford` static resource.
4455
4556Example:
46−```
47−/~ [a=0 b=1]
48−[a b]
49−```
50−produces:
51−`[0 1]`
5257
53−In wide-form, `/~` always takes a tuple (which may be a degenerate tuple of one element), and produces it.
58+ /~ [a=0 b=1]
59+ [a b]
60+
61+produces: `[0 1]`
62+
63+In wide-form, `/~` always takes a tuple (which may be a degenerate tuple of one
64+element), and produces it.
5465
5566Example:
56−```
57−/~[%something]
58−```
67+
68+ /~[%something]
69+
5970produces: `%something`
6071
61−```
62−/~[%a %b]
63−```
72+ /~[%a %b]
73+
6474produces: `[%a %b]`
6575
6676### `//` include a file by relative path
6777
6878`// <rel-path>` parses `rel-path` as a hoon twig, and then adds the resulting
6979twig to the subject. Note that the result type of this rune is not a horn, but
70−just a hoon twig, so its result can't be used as an argument to other runes
71−that expect a horn. There is no wide-form for this rune.
80+just a hoon twig, so its result can't be used as an argument to other runes that
81+expect a horn. There is no wide-form for this rune.
7282
7383Example:
74−```
75−// %/file-to-include
76−::
77−(frobnicate:file-to-include %.n)
78−
79−:: contents of file-to-include.hoon
80−|%
81−++ frobnicate
82− |= a/? ^+ a
83− !a
84−--
85−```
84+
85+ // %/file-to-include
86+ ::
87+ (frobnicate:file-to-include %.n)
88+
89+ :: contents of file-to-include.hoon
90+ |%
91+ ++ frobnicate
92+ |= a/? ^+ a
93+ !a
94+ --
95+
8696produces: `%.y`
8797
88−_Note: `%` means current directory, which in a hoon file will resolve to the
98+*Note: `%` means current directory, which in a hoon file will resolve to the
8999"directory" containing that file. Also, %clay doesn't have first-class
90100directories the way unix filesystems do. Whereas in unix, a directory is a
91101special kind of file, in %clay it's just a path prefix, and there is no file
92−stored at that path._
102+stored at that path.*
93103
94104### `/=` wrap a face around an included horn
95105
@@ -97,44 +107,42 @@ stored at that path._
97107that horn, and wraps a face around it.
98108
99109Example:
100−```
101−/= foo /~ [a=0 b=1]
102−::
103−[a.foo b.foo]
104−```
110+
111+ /= foo /~ [a=0 b=1]
112+ ::
113+ [a.foo b.foo]
114+
105115produces: `[0 1]`
106116
107117In wide-form, `/=` uses `=` as a delimiter: `/=foo=/~[a=0 b=1]`
108118
109119### `/:` evaluate at path, and `/<mark>/` render mark at current path
110120
111−`/:` takes a path and a horn, and evaluates the horn with the current path set to the supplied path.
112−`/mar/` renders the mark 'mar' at the current path.
121+`/:` takes a path and a horn, and evaluates the horn with the current path set
122+to the supplied path. `/mar/` renders the mark 'mar' at the current path.
113123
114124Example:
115−```
116−/= hoo-source /: /path/to/hoon-file /hoon/
117−::
118−`@t`hoo-source
119−```
125+
126+ /= hoo-source /: /path/to/hoon-file /hoon/
127+ ::
128+ `@t`hoo-source
120129
121130produces the text of the hoon file at "/path/to/hoon-file/hoon".
122131
123132`/hoon/` renders the current path using the `%hoon` mark, which in this case
124−passes the contents through unchanged. In general, rendering a file with a
125−mark will potentially run the contents through a series of conversion
126−operations. For details on marks, see the
127−[marks docs](https://urbit.org/docs/arvo/marks).
133+passes the contents through unchanged. In general, rendering a file with a mark
134+will potentially run the contents through a series of conversion operations. For
135+details on marks, see the [marks docs](https://urbit.org/docs/arvo/marks).
128136
129137Here's an example that includes a mark conversion:
130−```
131−/= page /: /path/to/html/file /mime/
132−::
133−page
134−
135−:: contents of /path/to/html/file:
136−<html><head><title>My Fascinating Blog</title></head></html>
137−```
138+
139+ /= page /: /path/to/html/file /mime/
140+ ::
141+ page
142+
143+ :: contents of /path/to/html/file:
144+ <html><head><title>My Fascinating Blog</title></head></html>
145+
138146produces:
139147`[[%text %html ~] 60 '<html><head><title>My Fascinating Blog</title></head></html>']`
140148
@@ -146,51 +154,49 @@ In wide-form, `/:` uses `:` as a delimiter: `/=page=/:/path/to/html/file:/mime/`
146154### `/!mark/` evaluate as hoon, then pass through mark
147155
148156Example:
149−```
150−/= mime /: /%/some-hoon-file /!mime/
151−::
152−mime
153−
154−:: contents of /%/some-hoon-file:
155−%produces-a-cord
156−```
157+
158+ /= mime /: /%/some-hoon-file /!mime/
159+ ::
160+ mime
161+
162+ :: contents of /%/some-hoon-file:
163+ %produces-a-cord
164+
157165produces: `[[%text %plain ~] 15 'produces-a-cord']`
158166
159167### `/&` pass through a series of marks
160168
161169`/&` passes a horn through multiple marks, right-to-left. It has both a
162170wide-form and a tall-form syntax. In wide-form, it takes a series of mark
163−arguments followed by a horn. In tall-form, it takes a single mark followed by
164−a horn.
165−
166−```
167−/= some-text /: /%/text-file /&mime&/txt/
168−::
169−some-text
170−```
171+arguments followed by a horn. In tall-form, it takes a single mark followed by a
172+horn.
173+
174+ /= some-text /: /%/text-file /&mime&/txt/
175+ ::
176+ some-text
177+
171178produces: `[[%text %plain ~] p=17 q='Hi I\'m some text\0a']`
172179
173−This example shows two of the ways marks are used. The first way is what
174−happens with the `/txt/` mark: we use it to find a file in clay with that
175−extension, without performing any conversions. Since this file is stored with
176−the `%txt` mark in `%clay`, its type is a `wain`: a list of cords, where each
177−cord is a single line. Once we've read the file, the `%mime` mark converts the
178−`wain` to a triple that includes the MIME type ("text/plain"), the content
179−length in bytes, and the content itself as a cord.
180−
181−```
182−/= page /&html&elem&/~[;div.foo;]
183−::
184−page
185−```
180+This example shows two of the ways marks are used. The first way is what happens
181+with the `/txt/` mark: we use it to find a file in clay with that extension,
182+without performing any conversions. Since this file is stored with the `%txt`
183+mark in `%clay`, its type is a `wain`: a list of cords, where each cord is a
184+single line. Once we've read the file, the `%mime` mark converts the `wain` to a
185+triple that includes the MIME type ("text/plain"), the content length in bytes,
186+and the content itself as a cord.
187+
188+ /= page /&html&elem&/~[;div.foo;]
189+ ::
190+ page
191+
186192produces: `'<html><head></head><body><div class="foo"></div></body></html>'`
187193
188−This runs the sail expression `;div.foo;` through the `%elem` mark, then
189−through the `%html` mark. The `/~` rune produces an item of mark `noun`. The
190−`%elem` mark converts the mark of the expression from `noun` to `elem` by
191−checking that the type fits in `manx` (a hoon/sail type indicating an XML
192−element). The `%html` mark recognizes the `%elem` and converts it to an HTML
193−string with enclosing `<html>`, `<head>`, and `<body>` tags.
194+This runs the sail expression `;div.foo;` through the `%elem` mark, then through
195+the `%html` mark. The `/~` rune produces an item of mark `noun`. The `%elem`
196+mark converts the mark of the expression from `noun` to `elem` by checking that
197+the type fits in `manx` (a hoon/sail type indicating an XML element). The
198+`%html` mark recognizes the `%elem` and converts it to an HTML string with
199+enclosing `<html>`, `<head>`, and `<body>` tags.
194200
195201It's possible to use wide-form `/&` with more than two marks, by using `&` as a
196202delimiter between marks and adding a `/` before the last mark, like:
@@ -206,41 +212,40 @@ need to be enclosed in `/`'s: `/& html /elem/`
206212succeeds. If none succeed, it produces stack traces from all of its arguments.
207213
208214Example:
209−```
210−/= res /: /%/path/to/file
211−/|
212− /!elem/
213− /elem/
214−==
215−::
216−res
217−```
215+
216+ /= res /: /%/path/to/file
217+ /|
218+ /!elem/
219+ /elem/
220+ ==
221+ ::
222+ res
223+
218224tries to parse the file at `/%/path/to/file` as a hoon expression and evaluate
219225it (`/!elem/`), and then if that fails, tries to convert the file to an HTML
220−element directly (`/elem/`). This is used in urbit's `tree` publishing system
221−to enable a user to place either a hoon file or a static file in a directory,
222−and have them both result in webpages, with preference given to treating the
223−file as hoon to be evaluated.
226+element directly (`/elem/`). This is used in urbit's `tree` publishing system to
227+enable a user to place either a hoon file or a static file in a directory, and
228+have them both result in webpages, with preference given to treating the file as
229+hoon to be evaluated.
224230
225−Wide-form `/|` encloses its arguments in parentheses, with a single space as a delimiter:
226−`/|(/!elem/ /elem/)`
231+Wide-form `/|` encloses its arguments in parentheses, with a single space as a
232+delimiter: `/|(/!elem/ /elem/)`
227233
228234### `/_` unfiltered: run a horn on each file in the current directory
229235
230236`/_` can be used in two ways: filtered and unfiltered.
231237
232−Unfiltered `/_` takes a horn as an argument. It produces a new horn representing the
233−result of mapping the supplied horn over the list of files in the current
238+Unfiltered `/_` takes a horn as an argument. It produces a new horn representing
239+the result of mapping the supplied horn over the list of files in the current
234240directory. The keys in the resulting map are the basenames of the files in the
235241directory, and each value is the result of running that horn on the contents of
236242the file.
237243
238244Example:
239−```
240−/= kids /_ /hoon/
241−::
242−`(map term cord)`kids
243−```
245+
246+ /= kids /_ /hoon/
247+ ::
248+ `(map term cord)`kids
244249
245250produces a value of type `(map term cord)`, where each key is the basename (the
246251filename without the prefix), and each value is the result of running the
@@ -255,14 +260,14 @@ Wide-form unfiltered `/_` doesn't need a delimiter: `/= kids /_/hoon/`
255260Filtered `/_` takes an aura and a horn, and filters the list of files in the
256261current directory by whether their filenames can be parsed to an atom of that
257262aura. It then produces a map where each key is the filename after parsing into
258−that atom type, and each value is the result of running the horn on the
259−contents of that file.
263+that atom type, and each value is the result of running the horn on the contents
264+of that file.
260265
261266Example:
262−```
263−/= timed-posts /_ @da /md/
264−`(map @da @t)`timed-posts
265−```
267+
268+ /= timed-posts /_ @da /md/
269+ `(map @da @t)`timed-posts
270+
266271produces a map from dates to cords. This product will only contain files whose
267272names are parsable into `@da` dates. The values are the file contents converted
268273to a cord of markdown-formatted text.
@@ -271,89 +276,86 @@ Wide-form filtered `/_` uses `_` as a delimiter: `/= timed-posts /_@da_/md/`
271276
272277### `/;` operate on
273278
274−`/;` takes a twig and a horn. The twig should evaluate to a gate, which is then slammed
275−with the result of the horn as its sample.
279+`/;` takes a twig and a horn. The twig should evaluate to a gate, which is then
280+slammed with the result of the horn as its sample.
276281
277282Example:
278−```
279−/= goo
280− /; |=({a/@ b/@} +(b))
281− /~ [a=0 b=1]
282−::
283−goo
284−```
283+
284+ /= goo
285+ /; |=({a/@ b/@} +(b))
286+ /~ [a=0 b=1]
287+ ::
288+ goo
285289
286290produces: `2`
287291
288292Here's a slightly more complex example with runes that use the filesystem:
289−```
290−/= file-length
291− /; |=(a/@t (lent (crip a)))
292− /: /%/path/to/hoon/file /hoon/
293−::
294−file-length
295−```
293+
294+ /= file-length
295+ /; |=(a/@t (lent (crip a)))
296+ /: /%/path/to/hoon/file /hoon/
297+ ::
298+ file-length
299+
296300produces the number of bytes in the file "/%/path/to/hoon/file."
297301
298302### `/,` switch by path
299303
300−`/,` is a switch statement, which picks a branch to evaluate based on
301−whether the current path matches the path in the switch statement.
302−Takes a sequence of pairs of (path, horn) terminated by a `==`. No wide-form.
304+`/,` is a switch statement, which picks a branch to evaluate based on whether
305+the current path matches the path in the switch statement. Takes a sequence of
306+pairs of (path, horn) terminated by a `==`. No wide-form.
303307
304308Example:
305−```
306−/= just-right
307− /: /===/right-path :: set path to /%/right-path
308− /,
309− /wrong-path /~ ~
310− /another-wrong-path /~ ~
311− /right-path /~ %evaluate-me :: only evaluate this horn
312− ==
313−::
314−`@t`just-right
315−```
309+
310+ /= just-right
311+ /: /===/right-path :: set path to /%/right-path
312+ /,
313+ /wrong-path /~ ~
314+ /another-wrong-path /~ ~
315+ /right-path /~ %evaluate-me :: only evaluate this horn
316+ ==
317+ ::
318+ `@t`just-right
316319
317320produces: `'evaluate-me'`
318321
319322### `/.` list
320323
321−Produce a null-terminated list from a sequence of horns, terminated by a `==`. No wide-form.
324+Produce a null-terminated list from a sequence of horns, terminated by a `==`.
325+No wide-form.
322326
323327Example:
324−```
325−/= vanes
326− /.
327− /~ %ames
328− /~ %behn
329− /~ %clay
330− /~ %dill
331− /~ %eyre
332− /~ %ford
333− /~ %gall
334− ==
335−::
336−vanes
337−```
328+
329+ /= vanes
330+ /.
331+ /~ %ames
332+ /~ %behn
333+ /~ %clay
334+ /~ %dill
335+ /~ %eyre
336+ /~ %ford
337+ /~ %gall
338+ ==
339+ ::
340+ vanes
341+
338342produces: `[%ames %behn %clay %dill %eyre %ford %gall ~]`.
339343
340344### `/*` heterogeneous map
341345
342−_DEPRECATED_
343−TODO: remove
346+*DEPRECATED* TODO: remove
344347
345348### `/^` cast
346349
347350`/^` takes a mold and a horn, and casts the result of the horn to the mold.
348351
349352Example:
350−```
351−/= liz /^ (list @) :: cast to real list
352− /~ ~[1 2 3] :: no 'i' or 't' faces
353−::
354−?< ?=($~ liz) :: prevent find-fork
355−i.liz
356−```
353+
354+ /= liz /^ (list @) :: cast to real list
355+ /~ ~[1 2 3] :: no 'i' or 't' faces
356+ ::
357+ ?< ?=($~ liz) :: prevent find-fork
358+ i.liz
357359
358360produces: `1`
359361
@@ -363,60 +365,61 @@ Wide-form `/^` uses `^` as a delimiter: `/^(list @)^/~[1 2 3 ~]`
363365
364366### `/#` insert dephash
365367
366−`/#` takes a horn and produces a cell of the dependency
367−hash of the result of the horn, and the result itself.
368+`/#` takes a horn and produces a cell of the dependency hash of the result of
369+the horn, and the result itself.
368370
369371Example:
370−```
371−/= inline /^ {dep/@uvH txt/@t} /# /: /%/my-script /js/
372−::
373−;= ;script: (trip txt.inline) :: set script contents
374− ;script@"/~/on/{<dep.inline>}.js"; :: set script src
375−==
376−```
377−produces two `<script>` tags. The first has its contents set to the contents
378−of the JavaScript file we loaded from clay. The second is an auto-update
379−script that polls the server to check whether the dependency hash has changed.
380−This pattern is used in urbit's `tree` web publishing system.
372+
373+ /= inline /^ {dep/@uvH txt/@t} /# /: /%/my-script /js/
374+ ::
375+ ;= ;script: (trip txt.inline) :: set script contents
376+ ;script@"/~/on/{<dep.inline>}.js"; :: set script src
377+ ==
378+
379+produces two `<script>` tags. The first has its contents set to the contents of
380+the JavaScript file we loaded from clay. The second is an auto-update script
381+that polls the server to check whether the dependency hash has changed. This
382+pattern is used in urbit's `tree` web publishing system.
381383
382384Wide-form `/#` does not need a delimiter:
383385`/= inline /^ {dep/@uvH txt/@t} /#/:/%/my-script:/js/`
384386
385387### `/$` process extra arguments
386388
387−`/$` will slam a gate on whatever extra arguments have been supplied to this build.
388−At the moment, only HTTP requests forwarded by `%eyre` contain any extra arguments,
389−and using this rune outside of that context will cause an error. Requests from `%eyre`
390−contain an argument representing the query string, which can be parsed using the
391−standard library gate `++fuel`.
389+`/$` will slam a gate on whatever extra arguments have been supplied to this
390+build. At the moment, only HTTP requests forwarded by `%eyre` contain any extra
391+arguments, and using this rune outside of that context will cause an error.
392+Requests from `%eyre` contain an argument representing the query string, which
393+can be parsed using the standard library gate `++fuel`.
392394
393395Example:
394−```
395−/= gas /$ fuel
396−::
397−:*
398− %who {<(~(get ju aut.ced.gas) 0)>}
399− %where {(spud s.bem.gas)}
400− %case {(scow %ud p.r.bem.gas)}
401−==
402−```
403−produces: [%who '~zod' %where /ford/pages/web %case 60]
404−
405−Wide-form `/$` takes its arguments inside brackets, like `/~`:
406−`/=gas=/$[fuel]`
396+
397+ /= gas /$ fuel
398+ ::
399+ :*
400+ %who {<(~(get ju aut.ced.gas) 0)>}
401+ %where {(spud s.bem.gas)}
402+ %case {(scow %ud p.r.bem.gas)}
403+ ==
404+
405+produces: \[%who '~zod' %where /ford/pages/web %case 60\]
406+
407+Wide-form `/$` takes its arguments inside brackets, like `/~`: `/=gas=/$[fuel]`
407408
408409### `/%` propagate extra arguments into renderers
409410
410−`/%` will forward extra arguments (usually from `%eyre`) on to any enclosed `/renderer/`'s. Without this,
411−renderers that use `/$` to read the extra arguments will crash.
411+`/%` will forward extra arguments (usually from `%eyre`) on to any enclosed
412+`/renderer/`'s. Without this, renderers that use `/$` to read the extra
413+arguments will crash.
412414
413415Example:
414−```
415−/= dat /% /tree-json/
416−::
417−dat
418−```
419−produces the results of running `ren/tree-json` on the current path. This renderer needs the query string,
420−which is one of the extra arguments passed in from `%eyre`.
416+
417+ /= dat /% /tree-json/
418+ ::
419+ dat
420+
421+produces the results of running `ren/tree-json` on the current path. This
422+renderer needs the query string, which is one of the extra arguments passed in
423+from `%eyre`.
421424
422425Wide-form `/%` has no delimiter: `/%/tree-json/`
docs/arvo/internals/gall.md+57−71
@@ -1,116 +1,102 @@
11---
2−navhome: /docs/
2+navhome: '/docs/'
33sort: 7
44---
55
6−
7−`%gall`
8−=======
6+# `%gall`
97
108Our application server manager.
119
12−It allows applications and vanes to send messages to applications and
13−subscribe to data streams. This requires `%gall` to be a sort of a
14−hypervisor. Messages coming into `%gall` are routed to the intended
15−application, and the response comes back along the same route. If the
16−intended target is on another ship, `%gall` will behind-the-scenes route
17−it through ames to the other ship to run. This provides an abstraction
18−where all apps on all ships are communicated with over the same
19−interface.
10+It allows applications and vanes to send messages to applications and subscribe
11+to data streams. This requires `%gall` to be a sort of a hypervisor. Messages
12+coming into `%gall` are routed to the intended application, and the response
13+comes back along the same route. If the intended target is on another ship,
14+`%gall` will behind-the-scenes route it through ames to the other ship to run.
15+This provides an abstraction where all apps on all ships are communicated with
16+over the same interface.
2017
2118`%gall` neither accepts events from unix nor produces effects. It exists
22−entirely for the benefit of other vanes and, in particular,
23−applications. Eyre exposes `%gall`'s interface over http, and ames does
24−the same over the ames network. `%gall` uses ford to compile and run the
25−applications.
19+entirely for the benefit of other vanes and, in particular, applications. Eyre
20+exposes `%gall`'s interface over http, and ames does the same over the ames
21+network. `%gall` uses ford to compile and run the applications.
2622
27−Cards
28−-----
23+## Cards
2924
30−`%gall` accepts the following cards. The first three are the most
31−commonly used, while the others are primarily used internally.
25+`%gall` accepts the following cards. The first three are the most commonly used,
26+while the others are primarily used internally.
3227
3328### `%mess`
3429
35−Sends a message to an app. This will result in a call to the app's
36−`++poke` arm. The response is exactly one of a `%nice` if the action
37−succeeded or a `%mean` if not.
30+Sends a message to an app. This will result in a call to the app's `++poke` arm.
31+The response is exactly one of a `%nice` if the action succeeded or a `%mean` if
32+not.
3833
3934### `%show`
4035
41−Subscribes to a stream from an app. This will result in a call to the
42−app's either `++peek` or `++peer` arm. The first response will always be
43−either a `%nice` or a `%mean`, indicating whether or not the
44−subscription was successful. After the first response, there will be
45−zero or more responses of either `%rush` or `%rust`, which communicate
46−either a differntial or full update to the data stream. There may be a
47−`%mean`, which indicates that the subscription has been canceled and no
48−more responses will be received along this stream.
49−
36+Subscribes to a stream from an app. This will result in a call to the app's
37+either `++peek` or `++peer` arm. The first response will always be either a
38+`%nice` or a `%mean`, indicating whether or not the subscription was successful.
39+After the first response, there will be zero or more responses of either `%rush`
40+or `%rust`, which communicate either a differntial or full update to the data
41+stream. There may be a `%mean`, which indicates that the subscription has been
42+canceled and no more responses will be received along this stream.
5043
5144### `%nuke`
5245
53−Unsubscribes the current duct from its stream. This receives a response
54−of either a `%nice` or a `%mean`. Note that a response of `%nice` does
55−not imply that the current duct was in fact subscribed to any stream.
46+Unsubscribes the current duct from its stream. This receives a response of
47+either a `%nice` or a `%mean`. Note that a response of `%nice` does not imply
48+that the current duct was in fact subscribed to any stream.
5649
5750### `%init`
5851
59−Initializes a ship's apps. This should be called exactly once for each
60−ship on the pier. This produces no moves in response.
52+Initializes a ship's apps. This should be called exactly once for each ship on
53+the pier. This produces no moves in response.
6154
6255### `%sire`
6356
64−Instantiates a child app. The app will be at path `[p parent-path]`, and
65−it will be an instance of the `q` app. The only response will be `%gone`
66−when the child dies.
67−
57+Instantiates a child app. The app will be at path `[p parent-path]`, and it will
58+be an instance of the `q` app. The only response will be `%gone` when the child
59+dies.
6860
6961### `%rote`
7062
71−Signifies a remote request from ames. `r` should be of type `rook`. This
72−how an app on a foreign ship may send a `%mess`, `%show`, or `%nuke`
73−card. Note that `%gall` automatically converts `%mess`, `%show`, and
74−`%nuke` into ames messages behind the scenes, so the only entity that
75−should use `%rote` and `%roth` is ames. Formally, the response is either
76−a `%nice` or a `%mean`, which ames uses to give a positive or negative
77−ack. A logical response comes by passing a `%roth` card.
78−
63+Signifies a remote request from ames. `r` should be of type `rook`. This how an
64+app on a foreign ship may send a `%mess`, `%show`, or `%nuke` card. Note that
65+`%gall` automatically converts `%mess`, `%show`, and `%nuke` into ames messages
66+behind the scenes, so the only entity that should use `%rote` and `%roth` is
67+ames. Formally, the response is either a `%nice` or a `%mean`, which ames uses
68+to give a positive or negative ack. A logical response comes by passing a
69+`%roth` card.
7970
8071### `%roth`
8172
82−Gives the response received from a remote request. `r` should be of type
83−`roon`. This is how an app responds to a foreign request with a `%rush`,
84−`%rust`, `%nice`, or `%mean`. The response is either a `%nice` or a
85−`%mean`. Even though we, as the proverb goes, "never ack an ack", we do
86−need to acknowledge these responses since they're really independent
87−one-way messages.
88−
73+Gives the response received from a remote request. `r` should be of type `roon`.
74+This is how an app responds to a foreign request with a `%rush`, `%rust`,
75+`%nice`, or `%mean`. The response is either a `%nice` or a `%mean`. Even though
76+we, as the proverb goes, "never ack an ack", we do need to acknowledge these
77+responses since they're really independent one-way messages.
8978
9079### `%wipe`
9180
92−Wipes the given app from memory. This is generally considered a hack,
93−but it is sometimes useful during development to wipe the state of an
94−app. We don't guarantee that this actually completely wipes the app.
95−Generally, you want to use a `%cide` card if you actually want to kill
96−an app. This gives no response.
97−
81+Wipes the given app from memory. This is generally considered a hack, but it is
82+sometimes useful during development to wipe the state of an app. We don't
83+guarantee that this actually completely wipes the app. Generally, you want to
84+use a `%cide` card if you actually want to kill an app. This gives no response.
9885
9986### `%cide`
10087
101−Kills an app and all its children. Even though it's not technically a
102−part of `%gall`'s interface since it's not in `++kiss` and can't be
103−called from the outside, it's worth mentioning `%cide`, which may be
104−called from within `%gall` apps. It should call `++part` to allow the
105−app any last words. This gives no response.
88+Kills an app and all its children. Even though it's not technically a part of
89+`%gall`'s interface since it's not in `++kiss` and can't be called from the
90+outside, it's worth mentioning `%cide`, which may be called from within `%gall`
91+apps. It should call `++part` to allow the app any last words. This gives no
92+response.
10693
107−Service Gates
108−-------------
94+## Service Gates
10995
11096### `++poke`
11197
112−Handles incoming messages. Most commonly with an associated `%logo`. For
113−example `++poke-json` handles an incoming JSON request from `%eyre`.
98+Handles incoming messages. Most commonly with an associated `%logo`. For example
99+`++poke-json` handles an incoming JSON request from `%eyre`.
114100
115101### `++peer`
116102
docs/arvo/marks.md+82−102
@@ -1,131 +1,111 @@
11---
2−navhome: /docs/
3−next: true
2+navhome: '/docs/'
3+next: True
44sort: 16
55title: Marks
66---
77
88# Marks
99
10−We've used predefined marks already, but we haven't yet created
11−our own marks. Let's write a sample mark of our own, then chain
12−it together with some preexisting ones to have fun with type
13−conversions.
10+We've used predefined marks already, but we haven't yet created our own marks.
11+Let's write a sample mark of our own, then chain it together with some
12+preexisting ones to have fun with type conversions.
1413
15−Let's make a small "examples-cord" mark. "Cord" is a name we use for `@t`
16−text, but there's no predefined mark for it. Let's put the following code in:
14+Let's make a small "examples-cord" mark. "Cord" is a name we use for `@t` text,
15+but there's no predefined mark for it. Let's put the following code in:
1716`/mar/examples/cord.hoon`:
1817
19−```
20−/? 314
21−|_ cod/@t
22−++ grab
23− |%
24− ++ atom |=(arg/@ `@t`(scot %ud arg))
25− --
26−++ grow
27− |%
28− ++ md cod
29− --
30−--
31−```
32−
33−`/? 314` is the required
34−version number, just like in apps. After that everything's in a
35−`|_`, which is a `|%` core, but with input arguments. In our
18+ /? 314
19+ |_ cod/@t
20+ ++ grab
21+ |%
22+ ++ atom |=(arg/@ `@t`(scot %ud arg))
23+ --
24+ ++ grow
25+ |%
26+ ++ md cod
27+ --
28+ --
29+
30+`/? 314` is the required version number, just like in apps. After that
31+everything's in a `|_`, which is a `|%` core, but with input arguments. In our
3632case, the argument is the marked data.
3733
38−There are three possible top-level arms in the `|_` core,
39−`++grab`, `++grow`, and `++grad` (which is used for revision
40−control, covered elsewhere). `++grab` specifies
41−functions to convert from another mark to the current mark.
42−`++grow` specifies how to convert from the current mark to
43−another one.
44−
45−In our case, we only define one arm in `++grab`, namely `++atom`.
46−This allows us to convert any atom to a cord. `++scot` is a
47−standard library function in `hoon.hoon` which pretty-prints
48−atoms of various types. We want to treat the atom as an
49−unsigned decimal number, so we give `%ud` and the given argument
50−to `++scot`. Thus, the form of an arm in `++grab` is
34+There are three possible top-level arms in the `|_` core, `++grab`, `++grow`,
35+and `++grad` (which is used for revision control, covered elsewhere). `++grab`
36+specifies functions to convert from another mark to the current mark. `++grow`
37+specifies how to convert from the current mark to another one.
38+
39+In our case, we only define one arm in `++grab`, namely `++atom`. This allows us
40+to convert any atom to a cord. `++scot` is a standard library function in
41+`hoon.hoon` which pretty-prints atoms of various types. We want to treat the
42+atom as an unsigned decimal number, so we give `%ud` and the given argument to
43+`++scot`. Thus, the form of an arm in `++grab` is
5144`|=(other-mark-type this-mark-value)`.
5245
53−In `++grow`, we just convert to the `md` mark, which is just a
54−`@t` internally, but it has fancy conversion functions to things
55−like html. `++md` isn't a function because the "argument" is
56−already a `@t`, so we can just produce the new value directly.
46+In `++grow`, we just convert to the `md` mark, which is just a `@t` internally,
47+but it has fancy conversion functions to things like html. `++md` isn't a
48+function because the "argument" is already a `@t`, so we can just produce the
49+new value directly.
5750
58−Let's play around a bit with this mark. First, let's take a
59−marked atom and convert it to our new mark.
51+Let's play around a bit with this mark. First, let's take a marked atom and
52+convert it to our new mark.
6053
61−```
62−~fintud-macrep:dojo> &atom 9
63−9
64−~fintud-macrep:dojo> &examples-cord &atom 9
65−'9'
66−-~fintud-macrep:dojo> &examples-cord &atom &examples-cord &atom 9
67− -'57'
68−```
54+ ~fintud-macrep:dojo> &atom 9
55+ 9
56+ ~fintud-macrep:dojo> &examples-cord &atom 9
57+ '9'
58+ -~fintud-macrep:dojo> &examples-cord &atom &examples-cord &atom 9
59+ -'57'
6960
70−ASCII 9 is 57. There's no requirement, implicit or otherwise,
71−that conversions back and forth between marks be inverses of each
72−other. These are semantic conversions, in that they refer to the
73−same concept. They're not isomorphisms.
61+ASCII 9 is 57. There's no requirement, implicit or otherwise, that conversions
62+back and forth between marks be inverses of each other. These are semantic
63+conversions, in that they refer to the same concept. They're not isomorphisms.
7464
7565Let's play around a little more:
7666
77−```
78−~fintud-macrep:dojo> &md &examples-cord &atom 17
79−'17'
80−~fintud-macrep:dojo> &hymn &md &examples-cord &atom 17
81−[ [%html ~]
82− [[%head ~] [[%title ~] [[%~. [%~. "Untitled"] ~] ~] ~] ~]
83− [ [%body ~]
84− [ i=[g=[n=%meta a=~[[n=%value v="{}"] [n=%name v="frontmatter"] [n=[%urb %front] v=""]]] c=~]
85− t=[i=[g=[n=%p a=~] c=~[[g=[n=%$ a=~[[n=%$ v="17"]]] c=~]]] t=~]
67+ ~fintud-macrep:dojo> &md &examples-cord &atom 17
68+ '17'
69+ ~fintud-macrep:dojo> &hymn &md &examples-cord &atom 17
70+ [ [%html ~]
71+ [[%head ~] [[%title ~] [[%~. [%~. "Untitled"] ~] ~] ~] ~]
72+ [ [%body ~]
73+ [ i=[g=[n=%meta a=~[[n=%value v="{}"] [n=%name v="frontmatter"] [n=[%urb %front] v=""]]] c=~]
74+ t=[i=[g=[n=%p a=~] c=~[[g=[n=%$ a=~[[n=%$ v="17"]]] c=~]]] t=~]
75+ ]
76+ ]
77+ ~
8678 ]
87− ]
88− ~
89−]
90−```
91−
92−That was exciting. If you squint at that, it looks an
93−awful lot like html. Our value `17` is still in there, in the
94−body. `urb` is the mark we render most web pages to. It makes
95−sure you have a complete skeleton of a web page. Of course, by
96−the time this gets to the web page, it's plain html. Let's do
97−the final step in the conversion.
98−
99−```
100−~fintud-macrep:dojo> &mime &hymn &md &examples-cord &atom 17
101−[ [%text %html ~]
102− p=121
103− q='<html><head><title>Untitled</title></head><body><meta value="{}" name="frontmatter" urb:front="" /><p>17</p></body></html>'
104−]
105−```
106−
107−This is a mime-typed octet stream with type `/text/html`, length
108−121 bytes, and our lowly number `17` rendered to a web page.
109−`examples-cord` was just one step in the chain.
79+
80+That was exciting. If you squint at that, it looks an awful lot like html. Our
81+value `17` is still in there, in the body. `urb` is the mark we render most web
82+pages to. It makes sure you have a complete skeleton of a web page. Of course,
83+by the time this gets to the web page, it's plain html. Let's do the final step
84+in the conversion.
85+
86+ ~fintud-macrep:dojo> &mime &hymn &md &examples-cord &atom 17
87+ [ [%text %html ~]
88+ p=121
89+ q='<html><head><title>Untitled</title></head><body><meta value="{}" name="frontmatter" urb:front="" /><p>17</p></body></html>'
90+ ]
91+
92+This is a mime-typed octet stream with type `/text/html`, length 121 bytes, and
93+our lowly number `17` rendered to a web page. `examples-cord` was just one step
94+in the chain.
11095
11196Of course, arvo can infer some parts of this chain:
11297
113−```
114−~fintud-macrep:dojo> &examples-cord 17
115−'17'
116−```
98+ ~fintud-macrep:dojo> &examples-cord 17
99+ '17'
117100
118−Likewise, `md` is the only way to get from `examples-cord` to `hymn`, so
119−that can be omitted. If we omit the `hymn`, though, we get:
101+Likewise, `md` is the only way to get from `examples-cord` to `hymn`, so that
102+can be omitted. If we omit the `hymn`, though, we get:
120103
121−```
122−~fintud-macrep:dojo> &mime &examples-cord 17
123−[[%text %x-markdown ~] p=1 q='7']
124−```
104+ ~fintud-macrep:dojo> &mime &examples-cord 17
105+ [[%text %x-markdown ~] p=1 q='7']
125106
126−Here, we converted straight from `examples-cord` to `md` to `mime`. Arvo
127−decided that was the most straightforward conversion, but it
128−gives a different result than passing it through the `hymn`
129−mark.
107+Here, we converted straight from `examples-cord` to `md` to `mime`. Arvo decided
108+that was the most straightforward conversion, but it gives a different result
109+than passing it through the `hymn` mark.
130110
131111The minimal correct input, then, is `&mime &hymn &examples-cord &atom 17`.
docs/arvo/network.md+183−202
@@ -1,19 +1,18 @@
11---
2−navhome: /docs/
3−next: false
2+navhome: '/docs/'
3+next: False
44sort: 13
55title: Network messages
66---
77
8−Network messages
9−================
8+# Network messages
109
11−Now we've learned enough Hoon to do more interesting things. Let's get
12−our planets to talk to each other.
10+Now we've learned enough Hoon to do more interesting things. Let's get our
11+planets to talk to each other.
1312
14−All we've written up until now are just shell commands that produce a
15−value and then disappear. To listen for and receive messages from other
16−planets, we'll need an app. Let's look at a very simple one:
13+All we've written up until now are just shell commands that produce a value and
14+then disappear. To listen for and receive messages from other planets, we'll
15+need an app. Let's look at a very simple one:
1716
1817 :: Accepts any noun from dojo and prints it out
1918 ::
@@ -29,10 +28,9 @@ planets, we'll need an app. Let's look at a very simple one:
2928 [~ +>.$]
3029 --
3130
32−This is a very simple app that does only one thing. If you poke it with
33−a value, it prints that value out. To try this out, you have to start
34−the app, then you can poke it from the command line with the following
35−commands:
31+This is a very simple app that does only one thing. If you poke it with a value,
32+it prints that value out. To try this out, you have to start the app, then you
33+can poke it from the command line with the following commands:
3634
3735 ~fintud-macrep:dojo> |start %examples-echo
3836 'prep'
@@ -44,46 +42,44 @@ commands:
4442 [%argument [1 2]]
4543 >=
4644
47−> There is currently a bug where the `%argument` lines are printed
48−> *above* the line you entered, so your output may not look exactly like
49−> this. `>=` means that a command was successfully received and
50−> executed.
45+> There is currently a bug where the `%argument` lines are printed *above* the
46+> line you entered, so your output may not look exactly like this. `>=` means
47+> that a command was successfully received and executed.
5148
5249Most of the app code should be simple enough to guess its function. The
5350important part of this code is the definition of `++poke-noun`.
5451
55−Once an app starts, it's always running in the background and you
56−interact with it by sending it messages. The most straightforward way to
57−do that is to poke it from the command line, which we we did with
58−`:echo 5` (`:[app-name] [argument(s)]`).
59−
60−In this case, `++poke-noun` takes an argument `arg` and prints it out
61−with `~&` ([sigpam](../../hoon/twig/sig-hint/pam-dump/)). This is an unusual
62−rune that formally "does nothing", but the interpreter detects it and
63−printfs the first child, before executing the second as if the first
64−didn't exist. This is a slightly hacky way of printing to the console,
65−but we'll get to the correct way later on.
66−
67−But what does `++poke-noun` produce? Recall that `^-` casts to a type.
68−In this case, it's declaring that the end result of the function will be of
69−type `{(list) _+>.$}`. But what does this mean?
70−
71−The phrase to remember is "a list of moves and our state". Urbit is a
72−message passing system, so whenever we want to do something that
73−interacts with the rest of the system, we send a message. Thus, a move
74−is Arvo's equivalent of a syscall. The first thing that `++poke-noun`
75−produces is a list of messages, called "moves". In this case, we don't
76−actually want the system to do anything, so we produce the empty list,
77−`~` (in the `[~ +>.$]` line).
52+Once an app starts, it's always running in the background and you interact with
53+it by sending it messages. The most straightforward way to do that is to poke it
54+from the command line, which we we did with `:echo 5`
55+(`:[app-name] [argument(s)]`).
56+
57+In this case, `++poke-noun` takes an argument `arg` and prints it out with `~&`
58+([sigpam](../../hoon/twig/sig-hint/pam-dump/)). This is an unusual rune that
59+formally "does nothing", but the interpreter detects it and printfs the first
60+child, before executing the second as if the first didn't exist. This is a
61+slightly hacky way of printing to the console, but we'll get to the correct way
62+later on.
63+
64+But what does `++poke-noun` produce? Recall that `^-` casts to a type. In this
65+case, it's declaring that the end result of the function will be of type
66+`{(list) _+>.$}`. But what does this mean?
67+
68+The phrase to remember is "a list of moves and our state". Urbit is a message
69+passing system, so whenever we want to do something that interacts with the rest
70+of the system, we send a message. Thus, a move is Arvo's equivalent of a
71+syscall. The first thing that `++poke-noun` produces is a list of messages,
72+called "moves". In this case, we don't actually want the system to do anything,
73+so we produce the empty list, `~` (in the `[~ +>.$]` line).
7874
7975The second thing `++poke-noun` produces is our state. `+>.$` refers to a
80−particular address in our subject where our formal app state is stored.
81−It'll become clear why this is later on, but for now pretend that `+>.$`
82−is a magic invocation that means "app state".
76+particular address in our subject where our formal app state is stored. It'll
77+become clear why this is later on, but for now pretend that `+>.$` is a magic
78+invocation that means "app state".
8379
84−Let's look at another example (edit your code in
85−`/app/examples/echo/hoon` to reflect the code below). Say we want to
86−only accept a number, and then print out the square of that number.
80+Let's look at another example (edit your code in `/app/examples/echo/hoon` to
81+reflect the code below). Say we want to only accept a number, and then print out
82+the square of that number.
8783
8884 /? 314
8985 !:
@@ -96,31 +92,27 @@ only accept a number, and then print out the square of that number.
9692 [~ +>.$]
9793 --
9894
99−A few things have changed. Firstly, we no longer accept arbitrary nouns
100−because we can only square atoms (integers, in this case an unsigned
101−one). Thus, our argument is now `arg/@`. Secondly, it's `++poke-atom`
102−rather than `++poke-noun`.
95+A few things have changed. Firstly, we no longer accept arbitrary nouns because
96+we can only square atoms (integers, in this case an unsigned one). Thus, our
97+argument is now `arg/@`. Secondly, it's `++poke-atom` rather than `++poke-noun`.
10398
104−Intro to marks
105−==============
99+# Intro to marks
106100
107−Are there other `++poke`s? Yes. In fact, `noun` and `atom` are just two
108−of arbitrarily many "marks". A mark is fundamentally a type definition,
109−but accessible at the Arvo level. Each mark is defined in the `/mar`
110−directory. Some marks have conversion routines to other marks, and some
111−have diff, patch, and merge algorithms. None of these are required for a
112−mark to exist, however.
101+Are there other `++poke`s? Yes. In fact, `noun` and `atom` are just two of
102+arbitrarily many "marks". A mark is fundamentally a type definition, but
103+accessible at the Arvo level. Each mark is defined in the `/mar` directory. Some
104+marks have conversion routines to other marks, and some have diff, patch, and
105+merge algorithms. None of these are required for a mark to exist, however.
113106
114−`noun` and `atom` are two predefined marks. In your `/mar` directory,
115−there are already many more, and you may add more at will. The type
116−associated with `noun` is `*`, and the type associated with `atom` is
117−`@`.
107+`noun` and `atom` are two predefined marks. In your `/mar` directory, there are
108+already many more, and you may add more at will. The type associated with `noun`
109+is `*`, and the type associated with `atom` is `@`.
118110
119−When we poke an app from anywhere, we do so with a mark that searches
120−for the corresponding (`++poke-[mark]`) arm. Data constructed on the
121−command line is by default marked with `noun`. In this case, the app is
122−expecting an atom, so we have to explicitly mark the data with `atom`
123−using `&[mark]`. Try the following commands:
111+When we poke an app from anywhere, we do so with a mark that searches for the
112+corresponding (`++poke-[mark]`) arm. Data constructed on the command line is by
113+default marked with `noun`. In this case, the app is expecting an atom, so we
114+have to explicitly mark the data with `atom` using `&[mark]`. Try the following
115+commands:
124116
125117 ~fintud-macrep:dojo> |start %square
126118 >=
@@ -132,16 +124,15 @@ using `&[mark]`. Try the following commands:
132124
133125> Recall the bug where `%square` may get printed above the input line.
134126
135−Marks are powerful, and they're the backbone of Urbit's data pipeline,
136−so we'll be getting quite used to them.
127+Marks are powerful, and they're the backbone of Urbit's data pipeline, so we'll
128+be getting quite used to them.
137129
138130**Exercise**:
139131
140132- Write an app that computes fizzbuzz on its input (as in the previous
141133 section).
142134
143−Sending a message to another urbit
144−==================================
135+# Sending a message to another urbit
145136
146137Let's write our first network message! Here's `/app/examples/pong.hoon`:
147138
@@ -173,36 +164,34 @@ Run it with these commands:
173164 ~fintud-macrep:dojo> :examples-pong &urbit ~sampel-sipnym
174165 >=
175166
176−Replace `~sampel-sipnym` with another urbit. The easiest thing to do is
177−to start a comet, a free and disposable Urbit identity. If you don't know
178−how to start a comet, see [the user setup section](/docs/using/setup/).
179−Don't forget to start the `%examples-pong` app on that urbit, too. You
180−should see, on the foreign urbit, this output:
167+Replace `~sampel-sipnym` with another urbit. The easiest thing to do is to start
168+a comet, a free and disposable Urbit identity. If you don't know how to start a
169+comet, see [the user setup section](/docs/using/setup/). Don't forget to start
170+the `%examples-pong` app on that urbit, too. You should see, on the foreign
171+urbit, this output:
181172
182173 [%receiving 'howdy']
183174
184−Most of the code should be straightforward. In `++poke-atom`, the only
185−new thing is the expression `(@t arg)`, which is the type `@t` being
186−called as a function with argument `arg`. As we already know, `@t` is
187−the type of "cord" text strings. In Hoon, when types are called as
188−functions, they serve as a validator function called a "clam" -- that
189−is, a function whose domain is all nouns, and range is the given type
190−(in this case, `@t`).
191−
192−In simpler terms, if a clam is passed a value of its own type, it
193−produces that value. Otherwise, it produces the default value (aka the
194−"bunt") of its type. Here we call this `@t` function on the argument.
195−This coerces the argument to text, so that we can print it out prettily
196−no matter what we're passed.
197−
198−The more interesting part is in `++poke-urbit`. The `urbit` mark is an
199−urbit identity, and the Hoon type associated with it is `@p` (the "p"
200−stands for "phonetic base").
201−
202−Recall that in a `++poke` arm we produce "a list of moves and our
203−state". Until now, we've left the list of moves empty, since we haven't
204−wanted to tell Arvo to do anything in particular. Now we want to send a
205−message to another urbit. Thus, we produce a list with one element:
175+Most of the code should be straightforward. In `++poke-atom`, the only new thing
176+is the expression `(@t arg)`, which is the type `@t` being called as a function
177+with argument `arg`. As we already know, `@t` is the type of "cord" text
178+strings. In Hoon, when types are called as functions, they serve as a validator
179+function called a "clam" -- that is, a function whose domain is all nouns, and
180+range is the given type (in this case, `@t`).
181+
182+In simpler terms, if a clam is passed a value of its own type, it produces that
183+value. Otherwise, it produces the default value (aka the "bunt") of its type.
184+Here we call this `@t` function on the argument. This coerces the argument to
185+text, so that we can print it out prettily no matter what we're passed.
186+
187+The more interesting part is in `++poke-urbit`. The `urbit` mark is an urbit
188+identity, and the Hoon type associated with it is `@p` (the "p" stands for
189+"phonetic base").
190+
191+Recall that in a `++poke` arm we produce "a list of moves and our state". Until
192+now, we've left the list of moves empty, since we haven't wanted to tell Arvo to
193+do anything in particular. Now we want to send a message to another urbit. Thus,
194+we produce a list with one element:
206195
207196 [ost %poke /sending [to-urbit-address %pong] %atom 'howdy']
208197
@@ -218,126 +207,118 @@ Let's walk through each of these elements step by step.
218207
219208#### Bones ("cause")
220209
221−If you look up `++bone` in `hoon.hoon`, you'll see that it's a number
222−(`@ud`), and that it's an opaque reference to a duct. `++duct` in
223−hoon.hoon is a list of `wire`s, where `++wire` is an alias for `++path`.
224−`++path` is a list of `++knot`s, which are ASCII text. Thus, a duct is a
225−list of paths, and a bone is an opaque reference to it (in the same way
226−that a Unix file descriptor is an opaque reference to a file structure).
227−Thus, to truly understand bones, we must understand ducts.
228−
229−A duct is stack of causes, again, represented as paths, which are called
230−wires. At the bottom of every duct is a unix event, such as a keystroke,
231−network packet, file change, or timer event. When Arvo is given this
232−event, it routes the event to appropriate kernel module for handling.
233−
234−Sometimes, the module can immediately handle the event and produce any
235−necessary results. For example, when we poked the `++poke-atom` arm
236−above, we poked %gall, our application server, which was able to respond
237−to our poke directly. When the module cannot service the request itself,
238−it sends instructions to another kernel module or application (through the
239−%gall module) to do a specified action, and produces the result from
240−that.
210+If you look up `++bone` in `hoon.hoon`, you'll see that it's a number (`@ud`),
211+and that it's an opaque reference to a duct. `++duct` in hoon.hoon is a list of
212+`wire`s, where `++wire` is an alias for `++path`. `++path` is a list of
213+`++knot`s, which are ASCII text. Thus, a duct is a list of paths, and a bone is
214+an opaque reference to it (in the same way that a Unix file descriptor is an
215+opaque reference to a file structure). Thus, to truly understand bones, we must
216+understand ducts.
217+
218+A duct is stack of causes, again, represented as paths, which are called wires.
219+At the bottom of every duct is a unix event, such as a keystroke, network
220+packet, file change, or timer event. When Arvo is given this event, it routes
221+the event to appropriate kernel module for handling.
222+
223+Sometimes, the module can immediately handle the event and produce any necessary
224+results. For example, when we poked the `++poke-atom` arm above, we poked %gall,
225+our application server, which was able to respond to our poke directly. When the
226+module cannot service the request itself, it sends instructions to another
227+kernel module or application (through the %gall module) to do a specified
228+action, and produces the result from that.
241229
242230Furthermore, when one module sends a message to another kernel module or
243−application, it also sends along the duct it was given with its new wire
244−tacked onto the end. Now the duct has two entries, with the unix event on
245−the bottom and the kernel module that handled it next. This process can
246−continue indefinitely, adding more and more layers onto the duct. When
247−an entity finally produces a result, a layer is popped off the duct, and
248−the result is passed all the way back down.
249−
250−In effect, a duct is an Arvo-level call stack. It's worth noting that
251−while in traditional call stacks a function call happens synchronously
252−and returns exactly once. In Arvo, multiple moves can be sent at once,
253−are evaluated asynchronously, and each one may be responded to zero or
254−more times.
255−
256−The point to take home is that whatever caused `++poke-urbit` to be
257−called is also the root cause for the network message we're trying to
258−send. Thus, we say to send the network message along the given bone
259−`ost`.
231+application, it also sends along the duct it was given with its new wire tacked
232+onto the end. Now the duct has two entries, with the unix event on the bottom
233+and the kernel module that handled it next. This process can continue
234+indefinitely, adding more and more layers onto the duct. When an entity finally
235+produces a result, a layer is popped off the duct, and the result is passed all
236+the way back down.
237+
238+In effect, a duct is an Arvo-level call stack. It's worth noting that while in
239+traditional call stacks a function call happens synchronously and returns
240+exactly once. In Arvo, multiple moves can be sent at once, are evaluated
241+asynchronously, and each one may be responded to zero or more times.
242+
243+The point to take home is that whatever caused `++poke-urbit` to be called is
244+also the root cause for the network message we're trying to send. Thus, we say
245+to send the network message along the given bone `ost`.
260246
261247##### Wire ('tack on new layer to duct')
262248
263−Of course, we have to push a new layer onto our duct before passing it
264−along (or responding to it directly) anywhere. This layer can have any
265−data we want in it, but we don't need anything specific here, so we just
266−use the wire `/sending` (`/elem1/elem2/elemN` is one syntax used to
267−create `++path`s and `++wire`s of N elements). If we were expecting a
268−response (which we're not), it would come back along the `/sending`
269−wire, meaning that the path `/sending` will be passed back to the
270−response handler as an argument. Although it's not required, it's
271−generally a good idea to make the wire human-readable for bug-handling
272−purposes.
249+Of course, we have to push a new layer onto our duct before passing it along (or
250+responding to it directly) anywhere. This layer can have any data we want in it,
251+but we don't need anything specific here, so we just use the wire `/sending`
252+(`/elem1/elem2/elemN` is one syntax used to create `++path`s and `++wire`s of N
253+elements). If we were expecting a response (which we're not), it would come back
254+along the `/sending` wire, meaning that the path `/sending` will be passed back
255+to the response handler as an argument. Although it's not required, it's
256+generally a good idea to make the wire human-readable for bug-handling purposes.
273257
274258##### Term (sys-call)
275259
276−Each move also has a `term`, composed of lowercase ASCII and/or `-`.
277−This `term` has the sign `@tas`. In this case, out `term` is `%poke`,
278−which is the name of the particular kind of move we're sending. You can
279−always use `%poke` to message an app. Other common names include
280−`%warp`, to read from the filesystem; `%wait`, to set a timer; and
281−`%them`, to send an http request.
260+Each move also has a `term`, composed of lowercase ASCII and/or `-`. This `term`
261+has the sign `@tas`. In this case, out `term` is `%poke`, which is the name of
262+the particular kind of move we're sending. You can always use `%poke` to message
263+an app. Other common names include `%warp`, to read from the filesystem;
264+`%wait`, to set a timer; and `%them`, to send an http request.
282265
283266The move ends with `*` (that is, any noun) since each type of move takes
284−different data. In our case, a `%poke` move takes a target (urbit and
285−app) and marked data, then pokes the arm of the corresponding mark on
286−that app on that urbit with that data. `[to-urbit-address %pong]` is the
287−target urbit and app, `%atom` is the `mark`, and`'howdy'` is the data.
267+different data. In our case, a `%poke` move takes a target (urbit and app) and
268+marked data, then pokes the arm of the corresponding mark on that app on that
269+urbit with that data. `[to-urbit-address %pong]` is the target urbit and app,
270+`%atom` is the `mark`, and`'howdy'` is the data.
288271
289−When Arvo receives a `%poke` move, it calls the appropriate `++poke`.
290−The same mechanism is used for sending messages between apps on the same
291−urbit as for sending messages between apps on different urbits.
272+When Arvo receives a `%poke` move, it calls the appropriate `++poke`. The same
273+mechanism is used for sending messages between apps on the same urbit as for
274+sending messages between apps on different urbits.
292275
293−> We said earlier that we're not expecting a response. This is not
294−> entirely true: the `++coup` is called when we receive acknowledgment
295−> that the `++poke` was called. We don't do anything with this
296−> information right now, but we could.
276+> We said earlier that we're not expecting a response. This is not entirely
277+> true: the `++coup` is called when we receive acknowledgment that the `++poke`
278+> was called. We don't do anything with this information right now, but we
279+> could.
297280
298281**Exercises**:
299282
300−- Extend either of the apps in the first two exercises to accept input
301− over the network in the same way as `pong`.
283+- Extend either of the apps in the first two exercises to accept input over
284+ the network in the same way as `pong`.
302285
303286- Modify `examples-pong` to print out a message when it receives
304287 acknowledgement.
305288
306−- Write two apps, `even` and `odd`. When you pass an atom to `even`,
307− check whether it's even. If so, divide it by two and recurse;
308− otherwise, poke `odd` with it. When `odd` receives an atom, check
309− whether it's equal to one. If so, terminate, printing "%success".
310− Otherwise, check whether it's odd. If so, multiply it by three, add
311− one, and recurse; otherwise, poke `even` with it. When either app
312− receives a number, print it out along with the name of the app. In
313− the end, you should be able to watch Collatz's conjecture play out
314− between the two apps. Sample output:
315−
316−```
317−~fintud-macrep:dojo> :even &atom 18
318−[%even 18]
319−[%odd 9]
320−[%even 28]
321−[%even 14]
322−[%odd 7]
323−[%even 22]
324−[%odd 11]
325−[%even 34]
326−[%odd 17]
327−[%even 52]
328−[%even 26]
329−[%odd 13]
330−[%even 40]
331−[%even 20]
332−[%even 10]
333−[%odd 5]
334−[%even 16]
335−[%even 8]
336−[%even 4]
337−[%even 2]
338−%success
339−```
340−
341−- Put `even` and `odd` on two separate urbits and pass the messages
342− over the network. Post a link to a working solution in :talk to
343− receive a cookie.
289+- Write two apps, `even` and `odd`. When you pass an atom to `even`, check
290+ whether it's even. If so, divide it by two and recurse; otherwise, poke
291+ `odd` with it. When `odd` receives an atom, check whether it's equal to one.
292+ If so, terminate, printing "%success". Otherwise, check whether it's odd. If
293+ so, multiply it by three, add one, and recurse; otherwise, poke `even` with
294+ it. When either app receives a number, print it out along with the name of
295+ the app. In the end, you should be able to watch Collatz's conjecture play
296+ out between the two apps. Sample output:
297+
298+<!-- -->
299+
300+ ~fintud-macrep:dojo> :even &atom 18
301+ [%even 18]
302+ [%odd 9]
303+ [%even 28]
304+ [%even 14]
305+ [%odd 7]
306+ [%even 22]
307+ [%odd 11]
308+ [%even 34]
309+ [%odd 17]
310+ [%even 52]
311+ [%even 26]
312+ [%odd 13]
313+ [%even 40]
314+ [%even 20]
315+ [%even 10]
316+ [%odd 5]
317+ [%even 16]
318+ [%even 8]
319+ [%even 4]
320+ [%even 2]
321+ %success
322+
323+- Put `even` and `odd` on two separate urbits and pass the messages over the
324+ network. Post a link to a working solution in :talk to receive a cookie.
docs/arvo/security-driver.md+215−255
@@ -1,302 +1,262 @@
11---
2−navhome: /docs/
3−next: false
2+navhome: '/docs/'
3+next: False
44sort: 20
55title: Security drivers
66---
77
88# Security drivers
99
10−A security driver is a file in `/=home=/sec/<tld>/<domain>/hoon`
11−that handles the authentication for all HTTP requests to
12−`https://<domain>.<tld>`. When anything in Urbit makes an HTTP
13−request through `%eyre` (our web server), it checks to see if we
14−have a security driver for the requested domain, and if so
15−filters the request through the driver. The security driver will
16−usually either decorate the request with the needed credentials
17−if it has them, or else it will guide the user through the
18−process of authenticating Urbit with the service.
19−
20−Each web service needs its own security driver, but most of them
21−are pretty standard. We recommend starting with an existing
22−security driver based on your needed authentication method (e.g.
23−basic auth, OAuth1, OAuth2), and changing whatever is specific to
24−your service.
25−
26−The best strategy for building security drivers is to copy a
27−similar one and tweak it until it works for you. The best
28−representatives are Github for Basic Authentication, Twitter for
29−OAuth1, Slack for OAuth2 when access tokens don't expire, and
30−Google APIs for OAuth2 when access tokens do expire. In most
31−cases you'll need to make very few changes to one of these
32−models.
33−
34−Still, it's worth seeing one or two built from the ground up.
35−Here, we'll build a connector for the Github API v3. The
36−simplest way to interact with the Github API is to just fetch
37−https://api.github.com from the dojo:
10+A security driver is a file in `/=home=/sec/<tld>/<domain>/hoon` that handles
11+the authentication for all HTTP requests to `https://<domain>.<tld>`. When
12+anything in Urbit makes an HTTP request through `%eyre` (our web server), it
13+checks to see if we have a security driver for the requested domain, and if so
14+filters the request through the driver. The security driver will usually either
15+decorate the request with the needed credentials if it has them, or else it will
16+guide the user through the process of authenticating Urbit with the service.
17+
18+Each web service needs its own security driver, but most of them are pretty
19+standard. We recommend starting with an existing security driver based on your
20+needed authentication method (e.g. basic auth, OAuth1, OAuth2), and changing
21+whatever is specific to your service.
22+
23+The best strategy for building security drivers is to copy a similar one and
24+tweak it until it works for you. The best representatives are Github for Basic
25+Authentication, Twitter for OAuth1, Slack for OAuth2 when access tokens don't
26+expire, and Google APIs for OAuth2 when access tokens do expire. In most cases
27+you'll need to make very few changes to one of these models.
28+
29+Still, it's worth seeing one or two built from the ground up. Here, we'll build
30+a connector for the Github API v3. The simplest way to interact with the Github
31+API is to just fetch https://api.github.com from the dojo:
3832
3933 ~your-urbit:dojo> +https://api.github.com
4034
41−Github exposes a few endpoints to the general web, and the root
42−endpoint is one of them. This gives you a textual representation
43−of a JSON object that contains a bunch of urls to other parts of
44−Github's API. This is exactly the same response you would get
45−from just running `curl https://api.github.com` on UNIX.
35+Github exposes a few endpoints to the general web, and the root endpoint is one
36+of them. This gives you a textual representation of a JSON object that contains
37+a bunch of urls to other parts of Github's API. This is exactly the same
38+response you would get from just running `curl https://api.github.com` on UNIX.
4639
47−If we don't have a security driver for Github yet, many of the
48−endpoints won't be accessible, or they will only have publicly
49−accessible information. Most of what we care about requires us
50−to be authenticated.
40+If we don't have a security driver for Github yet, many of the endpoints won't
41+be accessible, or they will only have publicly accessible information. Most of
42+what we care about requires us to be authenticated.
5143
5244## Basic auth
5345
5446Here's a simple security driver:
5547
56−```
57−:: Test url +https://api.github.com/user
58−::
59−:::: /hoon/github/com/sec
60− ::
61−/+ basic-auth
62−!:
63−|_ {bal/(bale keys:basic-auth) $~}
64−++ aut ~(standard basic-auth bal ~)
65−++ filter-request out-adding-header:aut
66−--
67−```
68−
69−Github supports authentication through either Basic
70−Authentication or OAuth2. We'll show the basic auth example
71−first, but in general we'd prefer OAuth2.
72−
73−Since this driver is for Github, put it in
74−`/=home=/sec/com/github/hoon`.
48+ :: Test url +https://api.github.com/user
49+ ::
50+ :::: /hoon/github/com/sec
51+ ::
52+ /+ basic-auth
53+ !:
54+ |_ {bal/(bale keys:basic-auth) $~}
55+ ++ aut ~(standard basic-auth bal ~)
56+ ++ filter-request out-adding-header:aut
57+ --
58+
59+Github supports authentication through either Basic Authentication or OAuth2.
60+We'll show the basic auth example first, but in general we'd prefer OAuth2.
61+
62+Since this driver is for Github, put it in `/=home=/sec/com/github/hoon`.
7563
7664To try this out, we first have to initialize our credentials with
77−`|init-auth-basic`, which prompts for the url of the service
78−(api.github.com), username, and password. It stores this
79−information in a manner that `%eyre` knows how to decode and send
80−put into your `bale`. Note that `|init-auth-basic` is standard for
81−basic auth, but other auth schemes (like OAuth) are initialized
65+`|init-auth-basic`, which prompts for the url of the service (api.github.com),
66+username, and password. It stores this information in a manner that `%eyre`
67+knows how to decode and send put into your `bale`. Note that `|init-auth-basic`
68+is standard for basic auth, but other auth schemes (like OAuth) are initialized
8269in other ways.
8370
8471After you've run `|init-auth-basic`, you should be able to run
85−`+https://api.github.com/user` and get a response indicating who
86−you're logged in as.
72+`+https://api.github.com/user` and get a response indicating who you're logged
73+in as.
8774
8875You can similarly POST:
8976
9077 ~your-urbit:dojo> +https://api.github.com/gists &json _(cork poja need) '{"files":{"file1.txt":{"content":"can\'t stop the signal"}}}'
9178
92−This creates a gist, go to `https://gist.github.com/<username>` to
93−see it.
79+This creates a gist, go to `https://gist.github.com/<username>` to see it.
9480
95−The `+url` syntax used in "source" position makes a GET request,
96−but if you pass it data it will make a POST request with that
97−data as the body. This request is authenticated seamlessly. You
98−can send data of any mark as long as it has a conversion path to
99−`%mime`.
81+The `+url` syntax used in "source" position makes a GET request, but if you pass
82+it data it will make a POST request with that data as the body. This request is
83+authenticated seamlessly. You can send data of any mark as long as it has a
84+conversion path to `%mime`.
10085
101−Let's take a look at the code and see if we can figure out what's
102−happening here:
86+Let's take a look at the code and see if we can figure out what's happening
87+here:
10388
10489 /+ basic-auth
10590
106−First, we load a library called `basic-auth`. This library
107−exposes two items. `keys` is the type of the basic auth key,
108−which is essentially a base64'd username and password.
109−`standard` accepts a `bale` and produces a core with everything
110−we'll need to implement basic auth.
111−
112−Every security driver needs some amount of state, which is stored
113−in `bale`. `bale` contains:
114−
115−- `our`, our urbit name
116−- `now`, the current time
117−- `eny`, 256 bits of entropy
118−- `byk`, the urbit, desk and case which the security driver is
119− running from
120−- `usr`, the particular identity we're logging in with
121−- `dom`, the site we're accessing
122−- `key`, the secrets required to authenticate requests. The type
123− for this entry is supplied by the programmer as the argument to
124− `++bale`. Thus, in our case, `key` in our bale is of type
125− `keys:basic-auth`.
126−
127−Additionally, a security driver contains at least one out of the
128−five "special" arms:
129−
130−- `++filter-request` is a function which takes a hiss (http
131− request) and produces a `sec-move` (defined in zuse), which is
132− one of:
133−
134− * `[%send hiss]`, which sends the new hiss. This is the
135− case in, for example, basic auth, where all we need to do is
136− add an extra header to the request.
137− * `[%give httr]`, where httr is an http response. This
138− immediately returns an http response to the sender.
139− * `[%show purl]`, where a purl is a parsed url. This displays
140− a message asking the user to visit the given url to continue
141− the authentication process.
142− * `[%redo ~]`, which redoes the request.
143−
144− `%eyre` calls `++filter-request` just before sending an HTTP
145− request to the specified domain. This allows the security
146− driver to filter the requests, decorating them with
147− authentication data.
148−
149−- `++filter-response` is a function which takes an httr and
150− produces a `sec-move`. `%eyre` calls it after receiving an
151− HTTP response from the specified domain. This allows the
152− security driver to handle authentication errors, commonly
153− caused by expired tokens, and retry the request.
154−
155−- `++receive-auth-query-string` is a function that takes a `quay`
156− (list of query parameters) and produces a `sec-move`. `%eyre`
157− calls it when it receives a request on the callback url.
158− Generally, this happens in OAuth after the user has granted
159− access to the urbit app, and the service makes a request to the
160− callback url with the code. The security driver should then
161− make a request to convert the code into an access token.
162−
163−- `++receive-auth-response` is a function that takes an httr and
164− produces a `sec-move`. `%eyre` calls it when it gets a
165− response to the request made in `++receive-auth-query-string`.
166−
167−- `++update` is a function which converts old state to a new
168− format when the security driver gets updated. If you want to
169− just get rid of the old state, define `++discard-state` as `~`.
170−
171−For basic auth, we only have to worry about `++filter-request`,
172−since all we need to do is add the correct header to each
173−request. Our `++aut` core contains a function
174−`++out-addding-header`, which does exactly what we want.
175−
176−Where do the keys come from, though? Remember we ran
177−`|init-auth-basic` to input them. This just prompts you for the
178−service url, username, and password, and it stores them next to
179−the driver. In our case, that's
180−`/=home=/sec/com/gitub/api/atom`. These keys are stored
181−encrypted, and you don't want to edit them directly. `%eyre`
182−loads them directly into your `bale`.
91+First, we load a library called `basic-auth`. This library exposes two items.
92+`keys` is the type of the basic auth key, which is essentially a base64'd
93+username and password. `standard` accepts a `bale` and produces a core with
94+everything we'll need to implement basic auth.
95+
96+Every security driver needs some amount of state, which is stored in `bale`.
97+`bale` contains:
98+
99+- `our`, our urbit name
100+- `now`, the current time
101+- `eny`, 256 bits of entropy
102+- `byk`, the urbit, desk and case which the security driver is running from
103+- `usr`, the particular identity we're logging in with
104+- `dom`, the site we're accessing
105+- `key`, the secrets required to authenticate requests. The type for this
106+ entry is supplied by the programmer as the argument to `++bale`. Thus, in
107+ our case, `key` in our bale is of type `keys:basic-auth`.
108+
109+Additionally, a security driver contains at least one out of the five "special"
110+arms:
111+
112+- `++filter-request` is a function which takes a hiss (http request) and
113+ produces a `sec-move` (defined in zuse), which is one of:
114+
115+- `[%send hiss]`, which sends the new hiss. This is the case in, for example,
116+ basic auth, where all we need to do is add an extra header to the request.
117+- `[%give httr]`, where httr is an http response. This immediately returns an
118+ http response to the sender.
119+- `[%show purl]`, where a purl is a parsed url. This displays a message asking
120+ the user to visit the given url to continue the authentication process.
121+- `[%redo ~]`, which redoes the request.
122+
123+`%eyre` calls `++filter-request` just before sending an HTTP request to the
124+specified domain. This allows the security driver to filter the requests,
125+decorating them with authentication data.
126+
127+- `++filter-response` is a function which takes an httr and produces a
128+ `sec-move`. `%eyre` calls it after receiving an HTTP response from the
129+ specified domain. This allows the security driver to handle authentication
130+ errors, commonly caused by expired tokens, and retry the request.
131+
132+- `++receive-auth-query-string` is a function that takes a `quay` (list of
133+ query parameters) and produces a `sec-move`. `%eyre` calls it when it
134+ receives a request on the callback url. Generally, this happens in OAuth
135+ after the user has granted access to the urbit app, and the service makes a
136+ request to the callback url with the code. The security driver should then
137+ make a request to convert the code into an access token.
138+
139+- `++receive-auth-response` is a function that takes an httr and produces a
140+ `sec-move`. `%eyre` calls it when it gets a response to the request made in
141+ `++receive-auth-query-string`.
142+
143+- `++update` is a function which converts old state to a new format when the
144+ security driver gets updated. If you want to just get rid of the old state,
145+ define `++discard-state` as `~`.
146+
147+For basic auth, we only have to worry about `++filter-request`, since all we
148+need to do is add the correct header to each request. Our `++aut` core contains
149+a function `++out-addding-header`, which does exactly what we want.
150+
151+Where do the keys come from, though? Remember we ran `|init-auth-basic` to input
152+them. This just prompts you for the service url, username, and password, and it
153+stores them next to the driver. In our case, that's
154+`/=home=/sec/com/gitub/api/atom`. These keys are stored encrypted, and you don't
155+want to edit them directly. `%eyre` loads them directly into your `bale`.
183156
184157## OAuth2
185158
186−Most services are better accessed through some form of OAuth.
187−Github can be accessed with OAuth2, which is a little more
188−complicated than basic auth, but not hugely so.
159+Most services are better accessed through some form of OAuth. Github can be
160+accessed with OAuth2, which is a little more complicated than basic auth, but
161+not hugely so.
189162
190163The basic steps for OAuth2 are these:
191164
192−- create an app and get its client id and client secret (on
193− Github)
194−- store these in Urbit (with `|init-oauth2`)
195−- try to make a request that requires authentication. The
196− security driver should prompt you to visit a particular url.
197−- visit the url and click "authorize", which gives the app access
198− to your account
199−- the security driver will turn the code it receives into an
200− access token
201−- on every request, include that access token
165+- create an app and get its client id and client secret (on Github)
166+- store these in Urbit (with `|init-oauth2`)
167+- try to make a request that requires authentication. The security driver
168+ should prompt you to visit a particular url.
169+- visit the url and click "authorize", which gives the app access to your
170+ account
171+- the security driver will turn the code it receives into an access token
172+- on every request, include that access token
202173
203174Creating an app is easy and
204−[well-documented](https://github.com/settings/applications/new).
205−If necessary, set the callback url to
206−`/~/ac/github.com/_state/in`, and note its client id and client
207−secret.
208−
209−Run `|init-oauth2`, which will prompt for the hostname
210−(api.github.com), client id, and client secret. This will store
211−the information, encrypted, in `/=home=/sec/com/github.atom`,
212−just as with Basic Authentication.
213−
214−Now we need a security driver. Use this:
215−
216−```
217−:: Test url +https://api.github.com/user
218−::
219−:::: /hoon/github/com/sec
220− ::
221−/+ oauth2
222−!:
223−::::
224− ::
225−|_ {bal/(bale keys:oauth2) tok/token:oauth2}
226−++ scopes :: comment out scopes to taste
227− :~ 'user' 'user:email' 'user:follow' 'public_repo' 'repo'
228− 'repo_deployment' 'repo:status' 'delete_repo' 'notifications'
229− 'gist' 'read:repo_hook' 'write:repo_hook' 'admin:repo_hook'
230− 'admin:org_hook' 'read:org' 'write:org' 'admin:org'
231− 'read:public_key' 'write:public_key' 'admin:public_key'
232− ==
233−:: ++aut is a "standard oauth2" core, which implements the
234−:: most common handling of oauth2 semantics. see lib/oauth2 for more details,
235−:: and examples at the bottom of the file.
236−++ aut (~(standard oauth2 bal tok) . |=(tok/token:oauth2 +>(tok tok)))
237−++ filter-request
238− %^ out-add-query-param:aut 'access_token'
239− scope=~[%client %admin]
240− oauth-dialog='https://github.com/login/oauth/authorize'
241−::
242−++ receive-auth-query-string
243− %- in-code-to-token:aut
244− url='https://github.com/login/oauth/api/access_token'
245−++ receive-auth-response bak-save-token:aut
246−--
247−```
248−
249−The oauth2 library provides the main "engine" in `standard`, just
250−like in basic auth, except that we also have to specify a
251−function to save the access token when we get it. It's worth
252−noting that this library is well documented in the source,
253−including examples: `/=home=/lib/oauth2/hoon`.
254−
255−Running `+http://api.github.com/user` tries to make a request to
256−Github with authentication. This loads into the bale the keys,
257−which are of type `keys:oauth2`, defined in the oauth2 library.
258−We don't have to worry about the specifics of these keys -- the
259−library handles them -- but they include the client id and the
175+[well-documented](https://github.com/settings/applications/new). If necessary,
176+set the callback url to `/~/ac/github.com/_state/in`, and note its client id and
260177client secret.
261178
262−Before the request is sent, `%eyre` calls `++filter-request` to
263−decorate it with authentication headers. Since we don't yet have
264−an access token, we need to prompt the user to visit the "dialog"
265−url. `++out-add-query-param` checks whether we have a token, and
266−if we don't it produces `%show` and a message telling the user to
267−visit the `oauth-dialog` url we provide, with the extra query
268−parameters added (client id, scopes, and state).
269−
270−When the user visits that url, Github will ask them to log in and
271−authorize the application. When they do so, Github will post a
272−request to `/~/ac/github.com/_state/in` with a code in the query
273−string. `%eyre` sends the query string to
274−`++receive-auth-query-string`, which is a function that takes a
275−quay and produces a `sec-move`. `++in-code-to-token` from our
276−`aut` takes the `code` parameter from the quay and uses it to
277−create a request to the given url. This request includes the
278−client id, the client secret, and the code we just got.
279−
280−Github's response to that request includes an access token in its
281−body. This is handled in `++receive-auth-response`.
282−`++bak-save-token` extracts that token and gives it to the
283−function that we passed in the definition of `++aut`. In our
179+Run `|init-oauth2`, which will prompt for the hostname (api.github.com), client
180+id, and client secret. This will store the information, encrypted, in
181+`/=home=/sec/com/github.atom`, just as with Basic Authentication.
182+
183+Now we need a security driver. Use this:
184+
185+ :: Test url +https://api.github.com/user
186+ ::
187+ :::: /hoon/github/com/sec
188+ ::
189+ /+ oauth2
190+ !:
191+ ::::
192+ ::
193+ |_ {bal/(bale keys:oauth2) tok/token:oauth2}
194+ ++ scopes :: comment out scopes to taste
195+ :~ 'user' 'user:email' 'user:follow' 'public_repo' 'repo'
196+ 'repo_deployment' 'repo:status' 'delete_repo' 'notifications'
197+ 'gist' 'read:repo_hook' 'write:repo_hook' 'admin:repo_hook'
198+ 'admin:org_hook' 'read:org' 'write:org' 'admin:org'
199+ 'read:public_key' 'write:public_key' 'admin:public_key'
200+ ==
201+ :: ++aut is a "standard oauth2" core, which implements the
202+ :: most common handling of oauth2 semantics. see lib/oauth2 for more details,
203+ :: and examples at the bottom of the file.
204+ ++ aut (~(standard oauth2 bal tok) . |=(tok/token:oauth2 +>(tok tok)))
205+ ++ filter-request
206+ %^ out-add-query-param:aut 'access_token'
207+ scope=~[%client %admin]
208+ oauth-dialog='https://github.com/login/oauth/authorize'
209+ ::
210+ ++ receive-auth-query-string
211+ %- in-code-to-token:aut
212+ url='https://github.com/login/oauth/api/access_token'
213+ ++ receive-auth-response bak-save-token:aut
214+ --
215+
216+The oauth2 library provides the main "engine" in `standard`, just like in basic
217+auth, except that we also have to specify a function to save the access token
218+when we get it. It's worth noting that this library is well documented in the
219+source, including examples: `/=home=/lib/oauth2/hoon`.
220+
221+Running `+http://api.github.com/user` tries to make a request to Github with
222+authentication. This loads into the bale the keys, which are of type
223+`keys:oauth2`, defined in the oauth2 library. We don't have to worry about the
224+specifics of these keys -- the library handles them -- but they include the
225+client id and the client secret.
226+
227+Before the request is sent, `%eyre` calls `++filter-request` to decorate it with
228+authentication headers. Since we don't yet have an access token, we need to
229+prompt the user to visit the "dialog" url. `++out-add-query-param` checks
230+whether we have a token, and if we don't it produces `%show` and a message
231+telling the user to visit the `oauth-dialog` url we provide, with the extra
232+query parameters added (client id, scopes, and state).
233+
234+When the user visits that url, Github will ask them to log in and authorize the
235+application. When they do so, Github will post a request to
236+`/~/ac/github.com/_state/in` with a code in the query string. `%eyre` sends the
237+query string to `++receive-auth-query-string`, which is a function that takes a
238+quay and produces a `sec-move`. `++in-code-to-token` from our `aut` takes the
239+`code` parameter from the quay and uses it to create a request to the given url.
240+This request includes the client id, the client secret, and the code we just
241+got.
242+
243+Github's response to that request includes an access token in its body. This is
244+handled in `++receive-auth-response`. `++bak-save-token` extracts that token and
245+gives it to the function that we passed in the definition of `++aut`. In our
284246case, we just save that token into our state for later usage.
285247
286−Now we have the credentials we need, so `++filter-request` is
287−called with the original request, and `++out-add-query-param`
288−passes the request through with the addition of the query
289−parameter `access_token`.
248+Now we have the credentials we need, so `++filter-request` is called with the
249+original request, and `++out-add-query-param` passes the request through with
250+the addition of the query parameter `access_token`.
290251
291252Just like with Basic Authentication, you should be able to run
292−`+https://api.github.com/user` and get a response indicating who
293−you're logged in as.
253+`+https://api.github.com/user` and get a response indicating who you're logged
254+in as.
294255
295−Some drivers a slightly more complicated. For example, Github's
296−access token's don't expire, but that's not the case for all
297−service. The googleapis driver shows the flow when the access
298−token can expire. Twitter uses OAuth1, for which we have another
299−library.
256+Some drivers a slightly more complicated. For example, Github's access token's
257+don't expire, but that's not the case for all service. The googleapis driver
258+shows the flow when the access token can expire. Twitter uses OAuth1, for which
259+we have another library.
300260
301−Remember, of course, that the best strategy for building security
302−drivers is to copy a similar one and tweak it to taste.
261+Remember, of course, that the best strategy for building security drivers is to
262+copy a similar one and tweak it to taste.
docs/arvo/state.md+62−69
@@ -1,18 +1,16 @@
11---
2−navhome: /docs/
3−next: true
2+navhome: '/docs/'
3+next: True
44sort: 14
55title: State
66---
77
8−State
9−=====
8+# State
109
11−In the last section we built a few small apps that sent moves. These
12−apps were entirely stateless, however. Most useful apps require some
13−amount of state. Let's build a trivial stateful app. It'll keep a
14−running the sum of all the atoms we poke it with. Here's
15−`app/examples/sum.hoon`:
10+In the last section we built a few small apps that sent moves. These apps were
11+entirely stateless, however. Most useful apps require some amount of state.
12+Let's build a trivial stateful app. It'll keep a running the sum of all the
13+atoms we poke it with. Here's `app/examples/sum.hoon`:
1614
1715 /? 314
1816 !:
@@ -38,72 +36,67 @@ We can start it with `|start %examples-sum`, and then run it:
3836
3937We can see that app state is being saved, but when, where, and how?
4038
41−The state is stored as the second thing in the `|_` line. In our case,
42−it's simply an atom named `state`. We change it by producing our
43−state not with `+>.$` (as before), but with
44−`+>.$(state (add state arg))`. We've seen all these parts before, but
45−you might not recognize them.
39+The state is stored as the second thing in the `|_` line. In our case, it's
40+simply an atom named `state`. We change it by producing our state not with
41+`+>.$` (as before), but with `+>.$(state (add state arg))`. We've seen all these
42+parts before, but you might not recognize them.
4643
4744Recall in the first chapter that we recursed with the expression
48−`$(b (add 3 b))`. This meant "produce `$` with `b` changed to
49−`(add 3 b)`. Similarly, `+>.$(state (add state arg))` means "produce
50−`+>.$` (i.e. our context, which contains our state) with `state` changed
51−to `(add state arg)`.
52−
53−At a high level, then, when we handle state, we do it explicitly. It's
54−passed in and produced explicitly. In Unix systems, application state is
55−just a block of memory, which you need to serialize to disk if you want
56−to keep it around for very long.
57−
58−In Urbit, app state is a single (usually complex) value. In our example,
59−we have very simple state, so we defined `state/@`, meaning that our
60−state is an atom. Of course, `state` is just a name, and you're free to
61−name your state whatever you like. But let's clarify a couple other
62−things before we continue.
63−
64−First, `bowl` is a set of general global states. This set is managed by
65−the system. It includes things like `now` (the current time), `our` (our
66−urbit identity), and `eny` (256 bits of guaranteed-fresh entropy). For
67−the full list of things in `++bowl`, search for `++ bowl` (note: two
68−spaces) in `/arvo/zuse.hoon`.
69−
70−> This is, perhaps, the most common way to learn Hoon. The easiest way
71−> to learn about an identifier you see in code is to search in
72−> `/arvo/zuse.hoon` and `/arvo/hoon.hoon` for it.\
73−> These "standard libraries" are usually simple to read. Since Urbit's
74−> codebase is less than 15000 lines of code combined, including the hoon
75−> parser, the compiler, and the `/arvo` microkernel, you can usually use
76−> the code and its comments as a reference doc.
45+`$(b (add 3 b))`. This meant "produce `$` with `b` changed to `(add 3 b)`.
46+Similarly, `+>.$(state (add state arg))` means "produce `+>.$` (i.e. our
47+context, which contains our state) with `state` changed to `(add state arg)`.
48+
49+At a high level, then, when we handle state, we do it explicitly. It's passed in
50+and produced explicitly. In Unix systems, application state is just a block of
51+memory, which you need to serialize to disk if you want to keep it around for
52+very long.
53+
54+In Urbit, app state is a single (usually complex) value. In our example, we have
55+very simple state, so we defined `state/@`, meaning that our state is an atom.
56+Of course, `state` is just a name, and you're free to name your state whatever
57+you like. But let's clarify a couple other things before we continue.
58+
59+First, `bowl` is a set of general global states. This set is managed by the
60+system. It includes things like `now` (the current time), `our` (our urbit
61+identity), and `eny` (256 bits of guaranteed-fresh entropy). For the full list
62+of things in `++bowl`, search for `++ bowl` (note: two spaces) in
63+`/arvo/zuse.hoon`.
64+
65+> This is, perhaps, the most common way to learn Hoon. The easiest way to learn
66+> about an identifier you see in code is to search in `/arvo/zuse.hoon` and
67+> `/arvo/hoon.hoon` for it.\\ These "standard libraries" are usually simple to
68+> read. Since Urbit's codebase is less than 15000 lines of code combined,
69+> including the hoon parser, the compiler, and the `/arvo` microkernel, you can
70+> usually use the code and its comments as a reference doc.
7771>
7872> You can also read
79−> [zuse.hoon](https://github.com/urbit/arvo/blob/master/arvo/zuse.hoon)
80−> and
81−> [hoon.hoon](https://github.com/urbit/arvo/blob/master/arvo/hoon.hoon)
82−> in your browser.
83−
84−The second thing we should clear up is this: Urbit needs no "serialize
85−to disk" step. Everything you produce in the app state is persistent
86−across calls to the app, restarts of the urbit, and even power failure.
87−If you want to write to the Unix filesystem, you can, but it's not
88−needed for persistence. Urbit has transactional events, which makes it
89−an [ACID operating system](https://en.wikipedia.org/wiki/ACID). Thus,
90−you don't have to worry about persistence when programming in Urbit, or
91−ever go through the hassle of having to set up and write to a database.
73+> [zuse.hoon](https://github.com/urbit/arvo/blob/master/arvo/zuse.hoon) and
74+> [hoon.hoon](https://github.com/urbit/arvo/blob/master/arvo/hoon.hoon) in your
75+> browser.
76+
77+The second thing we should clear up is this: Urbit needs no "serialize to disk"
78+step. Everything you produce in the app state is persistent across calls to the
79+app, restarts of the urbit, and even power failure. If you want to write to the
80+Unix filesystem, you can, but it's not needed for persistence. Urbit has
81+transactional events, which makes it an [ACID operating
82+system](https://en.wikipedia.org/wiki/ACID). Thus, you don't have to worry about
83+persistence when programming in Urbit, or ever go through the hassle of having
84+to set up and write to a database.
9285
9386**Exercises**:
9487
9588- Modify `:examples-sum` to reset the counter when you poke it with 0.
9689
97−- Write an app that prints out the previous value you poked it with.
98− Sample output:
99−
100−```
101−~fintud-macrep:dojo> :examples-last 7
102−[%last 0]
103−>=
104−~fintud-macrep:dojo> :examples-last [1 2 3]
105−[%last 7]
106−>=
107−~fintud-macrep:dojo> :examples-last 'howdy'
108−[%last [1 2 3]]
109−```
90+- Write an app that prints out the previous value you poked it with. Sample
91+ output:
92+
93+<!-- -->
94+
95+ ~fintud-macrep:dojo> :examples-last 7
96+ [%last 0]
97+ >=
98+ ~fintud-macrep:dojo> :examples-last [1 2 3]
99+ [%last 7]
100+ >=
101+ ~fintud-macrep:dojo> :examples-last 'howdy'
102+ [%last [1 2 3]]
docs/arvo/subject.md+36−43
@@ -1,12 +1,11 @@
11---
2−navhome: /docs/
2+navhome: '/docs/'
3+next: True
34sort: 12
4−next: true
55title: The subject
66---
77
8−The subject
9−===========
8+# The subject
109
1110Now we're going to cover the boiler plate that we skimmed over earlier.
1211
@@ -14,26 +13,24 @@ Now we're going to cover the boiler plate that we skimmed over earlier.
1413 :- %noun
1514 =< (sum [1.000 2.000])
1615
17−The first rune, `:-` (colhep, aka
18−[:cons](../../hoon/twig/col-cell/hep-cons/)), constructs the 2-element cell
19−that will be our program. The first element, `%say`, tells the
20−interpreter what to produce--in this case a value.
16+The first rune, `:-` (colhep, aka [:cons](../../hoon/twig/col-cell/hep-cons/)),
17+constructs the 2-element cell that will be our program. The first element,
18+`%say`, tells the interpreter what to produce--in this case a value.
2119
22−The second element is `|=`, which we know produces a function. `|=`'s
23−first child is its argument(s), which in this case is any noun (`*`).
24−Its second child is the remainder of the program.
20+The second element is `|=`, which we know produces a function. `|=`'s first
21+child is its argument(s), which in this case is any noun (`*`). Its second child
22+is the remainder of the program.
2523
26−Similarly, the rest of the program (which we construct with another
27−`:-`) is a cell of the literal `%noun`, which tells the shell that we're
28−producing a value of type `noun`, and the code that we run to actually
29−produce our value of the type `noun`.
24+Similarly, the rest of the program (which we construct with another `:-`) is a
25+cell of the literal `%noun`, which tells the shell that we're producing a value
26+of type `noun`, and the code that we run to actually produce our value of the
27+type `noun`.
3028
3129`=<` ([tisgal](../../hoon/twig/tis-flow/gal-rap/)) is a rune that takes two
32−children. The second child is the context against which we run the first
33−child. So in this case, we are running the expression
34−`(sum [1.000 2.000])` against everything contained within the `|%`. In
35−Hoon, we call the code executed the "formula" and its context the
36−"subject".
30+children. The second child is the context against which we run the first child.
31+So in this case, we are running the expression `(sum [1.000 2.000])` against
32+everything contained within the `|%`. In Hoon, we call the code executed the
33+"formula" and its context the "subject".
3734
3835 ::::::::::::::::::::::::::::::
3936 =< (sum [1.000 2.000]) :: formula
@@ -63,39 +60,35 @@ Hoon, we call the code executed the "formula" and its context the
6360 -- ::
6461 ::::::::::::::::::::::::::::::
6562
66−In nearly every language there is a similar concept of a "context" in
67−which expressions are executed. For example, in C this includes things
68−like the call stack, stack variables, and so on.
63+In nearly every language there is a similar concept of a "context" in which
64+expressions are executed. For example, in C this includes things like the call
65+stack, stack variables, and so on.
6966
70−Hoon is unique in that this context is a first-class value. Scheme
71−allows a sort of reification of the context through continuations, and
72−some may see a parallel to Forth's stack, but Hoon takes the
73−concept one step further.
67+Hoon is unique in that this context is a first-class value. Scheme allows a sort
68+of reification of the context through continuations, and some may see a parallel
69+to Forth's stack, but Hoon takes the concept one step further.
7470
7571Our starting subject is the [standard library](../../hoon/library), which is
76−defined in `/arvo/hoon.hoon` and `/arvo/zuse.hoon`. This is where
77−functions like `add` are defined. When we define a core with `|%`, we
78−don't throw away the subject (i.e. the standard library); rather, we
79−stack the new core on top of the old subject so that both are
80−accessible.
72+defined in `/arvo/hoon.hoon` and `/arvo/zuse.hoon`. This is where functions like
73+`add` are defined. When we define a core with `|%`, we don't throw away the
74+subject (i.e. the standard library); rather, we stack the new core on top of the
75+old subject so that both are accessible.
8176
8277**Exercises**:
8378
84−- Pass `++sum` its arguments (`2.000` and `3.000`) from the
85− command line.
79+- Pass `++sum` its arguments (`2.000` and `3.000`) from the command line.
8680
87−- Comment out all of the arms of the `|%`. Now add another arm and
88− call it `++add`, have it accept two arguments and produce 42
89− (regardless of input). Change the `=<` line to
90− `[(add 5 7) (^add 5 7)]`. Can you recognize what's happening?
81+- Comment out all of the arms of the `|%`. Now add another arm and call it
82+ `++add`, have it accept two arguments and produce 42 (regardless of input).
83+ Change the `=<` line to `[(add 5 7) (^add 5 7)]`. Can you recognize what's
84+ happening?
9185
9286Cheatsheet:
9387
94−- To pass arguments from the command line to a program, you replace
95− the `*` in the first line of the boiler plate to
96− `{^ {{arg/TYPE $~} $~}}` where `TYPE` is replaced with the type of
97− argument you're expecting. Then `+euler1 a` from the dojo sets `arg`
98− to `a`.
88+- To pass arguments from the command line to a program, you replace the `*` in
89+ the first line of the boiler plate to `{^ {{arg/TYPE $~} $~}}` where `TYPE`
90+ is replaced with the type of argument you're expecting. Then `+euler1 a`
91+ from the dojo sets `arg` to `a`.
9992- The empty list is `~`
10093- Lisp-style cons (construct a cell/prepend an element) is
10194 `[new-element list]`
docs/arvo/subscriptions.md+116−129
@@ -1,20 +1,19 @@
11---
2−navhome: /docs/
3−next: true
2+navhome: '/docs/'
3+next: True
44sort: 15
55title: Subscriptions
66---
77
88# Subscriptions
99
10−We've dealt fairly extensively with "poke" messages to an app, but these
11−are somewhat limited. A poke is a one-way message, but more often we
12−want to subscribe to updates from another app. You could build a
13−subscription model out of one-way pokes, but it's such a common pattern
14−that it's built into arvo.
10+We've dealt fairly extensively with "poke" messages to an app, but these are
11+somewhat limited. A poke is a one-way message, but more often we want to
12+subscribe to updates from another app. You could build a subscription model out
13+of one-way pokes, but it's such a common pattern that it's built into arvo.
1514
16−Let's take a look at two apps, `:examples-source` and `:examples-sink`.
17−First, `:examples-source`:
15+Let's take a look at two apps, `:examples-source` and `:examples-sink`. First,
16+`:examples-source`:
1817
1918 /? 314
2019 !:
@@ -73,54 +72,50 @@ And secondly, `:examples-sink`:
7372
7473Cheat sheet:
7574
76−- `&` (pam) can either be the boolean true (as can `%.y`, `0`), or
77− the irregular wide form of the `?&`
78− ([wutpam](../../hoon/twig/wut-test/pam-and)) rune, which computes
79− logical `AND` on its two children.
75+- `&` (pam) can either be the boolean true (as can `%.y`, `0`), or the
76+ irregular wide form of the `?&` ([wutpam](../../hoon/twig/wut-test/pam-and))
77+ rune, which computes logical `AND` on its two children.
8078
81−- Similar to `&`,`|` is either the boolean false (along with `%.n` and
82− `1`), or the irregular short for of `?|`
83− ([wutbar](../../hoon/twig/wut-test/bar-or)), which computes logical `OR`
84− on its two children.
79+- Similar to `&`,`|` is either the boolean false (along with `%.n` and `1`),
80+ or the irregular short for of `?|`
81+ ([wutbar](../../hoon/twig/wut-test/bar-or)), which computes logical `OR` on
82+ its two children.
8583
8684- `!` is the irregular wide form of `?!`
87− ([wutzap](../../hoon/twig/wut-test/zap-not/)), which computes logical
88− `NOT` on its child.
85+ ([wutzap](../../hoon/twig/wut-test/zap-not/)), which computes logical `NOT`
86+ on its child.
8987
9088- `?~` ([wutsig](../../hoon/twig/wut-test/sig-ifno/)) is basically an
91− if-then-else that checks whether condition `p` is `~` (null). `?~`
92− is slightly different from `?:(~ %tru %fal)` in that `?~` reduces to
89+ if-then-else that checks whether condition `p` is `~` (null). `?~` is
90+ slightly different from `?:(~ %tru %fal)` in that `?~` reduces to
9391 `?:($=(%type value) %tru %false)`. `$=`
94− ([buctis](../../hoon/twig/buc-mold/tis-coat/)) tests whether value `q` is
95− of type `p`.
96−<!-- One thing to watch out for in hoon: if you do `?~`, it
97− affects the type of the conditional value: XXexample -->
92+ ([buctis](../../hoon/twig/buc-mold/tis-coat/)) tests whether value `q` is of
93+ type `p`. <!-- One thing to watch out for in hoon: if you do `?~`, it
94+ affects the type of the conditional value: XXexample -->
9895
9996- `:_` ([colcab](../../hoon/twig/col-cell/cab-scon/)) is inverted `:-`: it
10097 accepts `p` and `q`, and produces `[q p]`.
10198
102−- `++bowl` is the type of the system state within our app. For
103− example, it includes things like `our`, the name of the host urbit,
104− and `now`, the current time.
99+- `++bowl` is the type of the system state within our app. For example, it
100+ includes things like `our`, the name of the host urbit, and `now`, the
101+ current time.
105102
106−- `$%` ([buccen](../../hoon/twig/buc-mold/cen-book/)) is a type
107− constructor: it defines a new type, composed of `n` types that it is
108− passed. For example `$% @ * ^ ==` is the type of either `@`,
109− `*`, or a cell `^`.
110−<!-- XX this is a union, right? -->
103+- `$%` ([buccen](../../hoon/twig/buc-mold/cen-book/)) is a type constructor:
104+ it defines a new type, composed of `n` types that it is passed. For example
105+ `$% @ * ^ ==` is the type of either `@`, `*`, or a cell `^`.
106+ <!-- XX this is a union, right? -->
111107
112108- You may have noticed the separate `|%`
113109 ([barcen](../../hoon/twig/bar-core/cen-core/)) above the application core
114− `|_` ([barcab](../../hoon/twig/bar-core/cab-door/). We usually put our
115− types in another core on top of the application core. We can access
116− these type from our `|_` because in `hoon.hoon` files, all cores are
117− called against each other. (The shorthand for 'called' is `=>`.)
118− Thus, the `|%` with the types is in the context of the `|_`, as it
119− lies above it: `hoon.hoon` `=> |% w types => |_`
110+ `|_` ([barcab](../../hoon/twig/bar-core/cab-door/). We usually put our types
111+ in another core on top of the application core. We can access these type
112+ from our `|_` because in `hoon.hoon` files, all cores are called against
113+ each other. (The shorthand for 'called' is `=>`.) Thus, the `|%` with the
114+ types is in the context of the `|_`, as it lies above it: `hoon.hoon`
115+ `=> |% w types => |_`
120116
121117Here's some sample output of the two working together:
122118
123−
124119 ~fintud-macrep:dojo> |start %examples-source
125120 >=
126121 ~fintud-macrep:dojo> |start %examples-sink
@@ -147,123 +142,115 @@ Here's some sample output of the two working together:
147142### :examples-source
148143
149144Hopefully you can get a sense for what's happening here. When we poke
150−`:examples-sink` with `%on`, `:examples-sink` subscribes to
151−`:examples-source`, and so whenever we poke `:examples-source`,
152−`:examples-sink` gets the update and prints it out. Then we unsubscribe
153−by poking `:examples-sink` with `%off`, and `:examples-sink` stops
154−getting updates. We then resubscribe.
145+`:examples-sink` with `%on`, `:examples-sink` subscribes to `:examples-source`,
146+and so whenever we poke `:examples-source`, `:examples-sink` gets the update and
147+prints it out. Then we unsubscribe by poking `:examples-sink` with `%off`, and
148+`:examples-sink` stops getting updates. We then resubscribe.
155149
156−There's a fair bit going on in this code. Let's look at
157−`:examples-source` first.
150+There's a fair bit going on in this code. Let's look at `:examples-source`
151+first.
158152
159−Our definition of `move` is fairly specific, since we're only going to
160−sending one kind of move. The `%diff` move is a subscription update, and
161−its content is marked data which gall routes to our subscribers.
153+Our definition of `move` is fairly specific, since we're only going to sending
154+one kind of move. The `%diff` move is a subscription update, and its content is
155+marked data which gall routes to our subscribers.
162156
163157This is a slightly different kind of move than [we've dealt with so
164−far](/arvo/network). It's producing a result rather than calling other
165−code (i.e. it's a return rather than a function call), so if you recall
166−the discussion of ducts, a layer gets popped off the duct rather than
167−added to it. This is why no wire is needed for the move -- we won't
168−receive anything in response to it.
158+far](/arvo/network). It's producing a result rather than calling other code
159+(i.e. it's a return rather than a function call), so if you recall the
160+discussion of ducts, a layer gets popped off the duct rather than added to it.
161+This is why no wire is needed for the move -- we won't receive anything in
162+response to it.
169163
170164Anyways, there're two functions inside the `|_`. We already know when
171−`++poke-noun` is called. `++peer` is called when someone tries to
172−subscribe to our app. Of course, you don't just subscribe to an app; you
173−subscribe to a path on that app. This path comes in as the argument to
174−`++peer`.
175−
176−In our case, we don't care what path you subscribed on, and all we do is
177−print out that you subscribed. Arvo keeps track of your subscriptions,
178−so you don't have to. You can access your subscribers by looking at
179−`sup` in the bowl that's passed in. `sup` is of type
180−`(map bone {@p path})`, which associates bones with the urbit who
181−subscribed, and which path they subscribed on. If you want to
165+`++poke-noun` is called. `++peer` is called when someone tries to subscribe to
166+our app. Of course, you don't just subscribe to an app; you subscribe to a path
167+on that app. This path comes in as the argument to `++peer`.
168+
169+In our case, we don't care what path you subscribed on, and all we do is print
170+out that you subscribed. Arvo keeps track of your subscriptions, so you don't
171+have to. You can access your subscribers by looking at `sup` in the bowl that's
172+passed in. `sup` is of type `(map bone {@p path})`, which associates bones with
173+the urbit who subscribed, and which path they subscribed on. If you want to
182174communicate with your subscribers, send them messages along their bone.
183175
184−`++poke-noun` "spams" the given argument to all our subscribers.
185−There's a few things we haven't seen before. Firstly, `:_(a b)` is the
186−same as `[b a]`. It's just a convenient way of formatting things when
187−the first thing in a cell is much more complicated than the second.
188−Thus, we're producing our state unchanged.
176+`++poke-noun` "spams" the given argument to all our subscribers. There's a few
177+things we haven't seen before. Firstly, `:_(a b)` is the same as `[b a]`. It's
178+just a convenient way of formatting things when the first thing in a cell is
179+much more complicated than the second. Thus, we're producing our state
180+unchanged.
189181
190−Our list of moves is the result of a call to `++turn`. `++turn` is what
191−many languages call "map" -- it runs a function on every item in a list
192−and collects the results in a list. The list is `(prey /example-path hid)`
193−and the function is the `|=` line right after it.
182+Our list of moves is the result of a call to `++turn`. `++turn` is what many
183+languages call "map" -- it runs a function on every item in a list and collects
184+the results in a list. The list is `(prey /example-path hid)` and the function
185+is the `|=` line right after it.
194186
195−`++prey` is a standard library function defined in `zuse`. It takes a
196−path and a bowl and gives you a list of the subscribers who are
197−subscribed on a path that begins with the given path. "Prey" is short
198−for "prefix".
187+`++prey` is a standard library function defined in `zuse`. It takes a path and a
188+bowl and gives you a list of the subscribers who are subscribed on a path that
189+begins with the given path. "Prey" is short for "prefix".
199190
200191Now we have the list of relevant subscribers. This a list of triples,
201−`{bone @p path}`, where the only thing we really need is the bone,
202−because we don't need to know their urbit or what exact path they
203−subscribed on. Thus, our transformer function takes `{o/bone *}` and
204−produces `[o %diff %noun arg]`, which is a move that provides bone `o`
205−with this subscription update: `[%noun arg]`". This is fairly dense
206−code, but what it's doing is straightforward.
192+`{bone @p path}`, where the only thing we really need is the bone, because we
193+don't need to know their urbit or what exact path they subscribed on. Thus, our
194+transformer function takes `{o/bone *}` and produces `[o %diff %noun arg]`,
195+which is a move that provides bone `o` with this subscription update:
196+`[%noun arg]`". This is fairly dense code, but what it's doing is
197+straightforward.
207198
208199### :examples-sink
209200
210−`:examples-source` should now make sense. `:examples-sink` is a little
211−longer, but not much more complicated.
212−
213−In `:examples-sink`, our definition of of `++move` is different. All
214−moves start with a `bone`, and we conventionally refer to the second
215−half as the "card", so that we can say a move is an action that sends a
216−card along a bone.
217−
218−We have two kinds of cards here: we `%peer` to start a subscription, and
219−we `%pull` to stop it. Both of these are "forward" moves that may
220−receive a response, so they need a wire to tack onto the duct before
221−they pass it on. They also need a target, which is a pair of an urbit
222−and an app name. Additionally, `%peer` needs a path on that app to
223−subscribe too. `%pull` doesn't need this, because its semantics are to
224−cancel any subscriptions coming over this duct. If your bone and wire
225−are the same as when you subscribed, then the cancellation will happen
226−correctly.
227−
228−The only state we need for `:examples-sink` is a boolean to indicate
229−whether we're already subscribed to `:examples-source`. We use
230−`available/?`, where `?` is the sign of type boolean (similar to `*`,
231−`@`), which defaults to true (that is, `0`).
201+`:examples-source` should now make sense. `:examples-sink` is a little longer,
202+but not much more complicated.
203+
204+In `:examples-sink`, our definition of of `++move` is different. All moves start
205+with a `bone`, and we conventionally refer to the second half as the "card", so
206+that we can say a move is an action that sends a card along a bone.
207+
208+We have two kinds of cards here: we `%peer` to start a subscription, and we
209+`%pull` to stop it. Both of these are "forward" moves that may receive a
210+response, so they need a wire to tack onto the duct before they pass it on. They
211+also need a target, which is a pair of an urbit and an app name. Additionally,
212+`%peer` needs a path on that app to subscribe too. `%pull` doesn't need this,
213+because its semantics are to cancel any subscriptions coming over this duct. If
214+your bone and wire are the same as when you subscribed, then the cancellation
215+will happen correctly.
216+
217+The only state we need for `:examples-sink` is a boolean to indicate whether
218+we're already subscribed to `:examples-source`. We use `available/?`, where `?`
219+is the sign of type boolean (similar to `*`, `@`), which defaults to true (that
220+is, `0`).
232221
233222In `++poke-noun` we check our input to see both if it's `%on` and we're
234−available. If so, we produce the move to subscribe to
235−`:examples-source`:
223+available. If so, we produce the move to subscribe to `:examples-source`:
236224
237225 [ost %peer /subscribe [our %source] /example-path]
238226
239227Also, we set available to false (`|`) with `+>.$(available |)`.
240228
241−Otherwise, if our input is `%off` and we're already subscribed (i.e.
242−`available` is false), then we unsubscribe from `:examples-source`:
229+Otherwise, if our input is `%off` and we're already subscribed (i.e. `available`
230+is false), then we unsubscribe from `:examples-source`:
243231
244232 [ost %pull /subscribe [our %source] ~]
245233
246−It's important to send over the same bone and wire (`/subscribe`) as the
247−one we originally subscribed on.
234+It's important to send over the same bone and wire (`/subscribe`) as the one we
235+originally subscribed on.
248236
249237We also set `available` to true (`&`).
250238
251−If neither of these cases are true, then we print our current
252−subscription state.
239+If neither of these cases are true, then we print our current subscription
240+state.
253241
254−`++diff-noun` is called when we get a `%diff` update along a
255−subscription with a mark of `noun`. `++diff-noun` is given the wire that
256−we originally passed with the `%peer` subscription request along and the
257−data we got back. In our case we just print out the data.
242+`++diff-noun` is called when we get a `%diff` update along a subscription with a
243+mark of `noun`. `++diff-noun` is given the wire that we originally passed with
244+the `%peer` subscription request along and the data we got back. In our case we
245+just print out the data.
258246
259247`++reap` is called when we receive an acknowledgment as to whether the
260−subscription was handled successfully. You can remember that `++reap` is
261−the counterpart to `++peer` as it's pronounced like 'peer' backwards.
262−Similarly, `coup` is similar to 'poke' backwards.
263−
264−Moving forward, `++reap` is given the wire we attempted to subscribe
265−over, possibly along with an error message in cases of failure.
266−`(unit type)` means "either `~` or `[~ type]`, which means it's used
267−like Haskell's "maybe" or C's nullability. If `error` is `~`, then the
268−subscription was successful and we tell that to the user. Otherwise, we
269−print out the error message.
248+subscription was handled successfully. You can remember that `++reap` is the
249+counterpart to `++peer` as it's pronounced like 'peer' backwards. Similarly,
250+`coup` is similar to 'poke' backwards.
251+
252+Moving forward, `++reap` is given the wire we attempted to subscribe over,
253+possibly along with an error message in cases of failure. `(unit type)` means
254+"either `~` or `[~ type]`, which means it's used like Haskell's "maybe" or C's
255+nullability. If `error` is `~`, then the subscription was successful and we tell
256+that to the user. Otherwise, we print out the error message.
docs/arvo/web-apps.md+212−229
@@ -1,265 +1,248 @@
11---
2−navhome: /docs/
3−next: true
2+navhome: '/docs/'
3+next: True
44sort: 17
55title: Web apps
66---
77
88# Backend
99
10−We've done purely functional web pages as hook files, and we've
11−done command line apps, so now let's interact with an app over
12−the web. The fundamental concepts are no different than from the
13−command line -- you send "poke" messages to apps and subscribe to
14−data streams. The only difference is that you do it with
15−javascript.
10+We've done purely functional web pages as hook files, and we've done command
11+line apps, so now let's interact with an app over the web. The fundamental
12+concepts are no different than from the command line -- you send "poke" messages
13+to apps and subscribe to data streams. The only difference is that you do it
14+with javascript.
1615
17−Let's create a small web app that counts the number of times you
18−poke it. There'll be a button to poke the app, and line of text
19−below it saying how many times the app has been poked. We can
20−update this by subscribing our page to the relevant path on its app.
16+Let's create a small web app that counts the number of times you poke it.
17+There'll be a button to poke the app, and line of text below it saying how many
18+times the app has been poked. We can update this by subscribing our page to the
19+relevant path on its app.
2120
2221Let's first checkout the app `/app/examples/click.hoon`:
2322
24−```
25−/? 314
26−!:
27−|%
28−++ move {bone $diff $mark *}
29−--
30−!:
31−|_ {hid/bowl clicks/@}
32−++ poke-examples-click-click
33− |= click/$click
34− ~& [%poked +(clicks)]
35− :_ +>.$(clicks +(clicks))
36− %+ turn (prey /the-path hid)
37− |=({o/bone *} [o %diff %examples-click-clicks +(clicks)])
38−++ peer-the-path
39− |= pax/path
40− [[[ost.hid %diff %examples-click-clicks clicks] ~] +>.$]
41−--
42−```
43−
44−There's nothing really new here, except that we use a couple of
45−new marks, `click` and `clicks`. When we get poked with a
46−`click`, we increment the variable `clicks` in our state and tell
47−all our subcribers the new value. When someone subscribes to us
48−on the path `/the-path`, we immediately give them the current
49−number of clicks.
50−
51−Let's take a look at the new marks. Here's `/mar/examples/click/click.hoon`:
52−
53−```
54−|_ click/$click
55−++ grab
56− |%
57− ++ noun |=(* %click)
58− ++ json
59− |= jon/^json
60− ?> =('click' (need (so:jo jon)))
61− %click
62− --
63−--
64−```
23+ /? 314
24+ !:
25+ |%
26+ ++ move {bone $diff $mark *}
27+ --
28+ !:
29+ |_ {hid/bowl clicks/@}
30+ ++ poke-examples-click-click
31+ |= click/$click
32+ ~& [%poked +(clicks)]
33+ :_ +>.$(clicks +(clicks))
34+ %+ turn (prey /the-path hid)
35+ |=({o/bone *} [o %diff %examples-click-clicks +(clicks)])
36+ ++ peer-the-path
37+ |= pax/path
38+ [[[ost.hid %diff %examples-click-clicks clicks] ~] +>.$]
39+ --
40+
41+There's nothing really new here, except that we use a couple of new marks,
42+`click` and `clicks`. When we get poked with a `click`, we increment the
43+variable `clicks` in our state and tell all our subcribers the new value. When
44+someone subscribes to us on the path `/the-path`, we immediately give them the
45+current number of clicks.
46+
47+Let's take a look at the new marks. Here's `/mar/examples/click/click.hoon`:
48+
49+ |_ click/$click
50+ ++ grab
51+ |%
52+ ++ noun |=(* %click)
53+ ++ json
54+ |= jon/^json
55+ ?> =('click' (need (so:jo jon)))
56+ %click
57+ --
58+ --
6559
6660The mark `examples-click-click` has hoon type `%click`, which means the only
67−valid value is `%click`. We can convert from `noun` by just
68−producing `%click`.
69−
70−We also convert from json by parsing a json string with `so:jo`,
71−asserting the parsing succeeded with `need`, and asserting the
72−result was 'click' with `?>`, which asserts that its first child
73−is true.
74−
75−> Note the argument to `++json`is `jon/^json`. Why `^json`?
76−> `++json` shadows the type definition, so if we want to refer to
77−> the type, we have to prepend a `^`. This extends to multiple
78−> levels: `^^^foo` means the fourth most innermost instance of `foo`.
79−
80−> `++jo` in `zuse` is a useful library for parsing complex json
81−> into hoon structures. In this case, the `:` between `so` and
82−> `jo` means 'inside of', because `so` is an arm contained within
83−> the core `jo`. Our case is actually simple enough that the
84−> `?>` line could have been `?> =([%s 'click'] jon)`.
85−
86−We can test this mark from the command line (don't forget to start your app with `|start %examples-click`)
87−
88−```
89−~fintud-macrep:dojo> &examples-click-click %click
90−%click
91−~fintud-macrep:dojo> &examples-click-click &json [%s 'click']
92−%click
93−~fintud-macrep:dojo> &examples-click-click &json &mime [/text/json (taco '"click"')]
94−%click
95−~fintud-macrep:dojo> &examples-click-click &json &mime [/text/json (taco '"clickety"')]
96−/~fintud-macrep/home/0/mar/click:<[7 5].[8 11]>
97−ford: casting %json to %click
98−ford: cast %click
99−```
61+valid value is `%click`. We can convert from `noun` by just producing `%click`.
62+
63+We also convert from json by parsing a json string with `so:jo`, asserting the
64+parsing succeeded with `need`, and asserting the result was 'click' with `?>`,
65+which asserts that its first child is true.
66+
67+> Note the argument to `++json`is `jon/^json`. Why `^json`? `++json` shadows the
68+> type definition, so if we want to refer to the type, we have to prepend a `^`.
69+> This extends to multiple levels: `^^^foo` means the fourth most innermost
70+> instance of `foo`.
71+
72+> `++jo` in `zuse` is a useful library for parsing complex json into hoon
73+> structures. In this case, the `:` between `so` and `jo` means 'inside of',
74+> because `so` is an arm contained within the core `jo`. Our case is actually
75+> simple enough that the `?>` line could have been `?> =([%s 'click'] jon)`.
76+
77+We can test this mark from the command line (don't forget to start your app with
78+`|start %examples-click`)
79+
80+ ~fintud-macrep:dojo> &examples-click-click %click
81+ %click
82+ ~fintud-macrep:dojo> &examples-click-click &json [%s 'click']
83+ %click
84+ ~fintud-macrep:dojo> &examples-click-click &json &mime [/text/json (taco '"click"')]
85+ %click
86+ ~fintud-macrep:dojo> &examples-click-click &json &mime [/text/json (taco '"clickety"')]
87+ /~fintud-macrep/home/0/mar/click:<[7 5].[8 11]>
88+ ford: casting %json to %click
89+ ford: cast %click
10090
10191And `/mar/examples/click/clicks.hoon`:
10292
103−```
104−|_ clicks/@
105−++ grow
106− |%
107− ++ json
108− (joba %clicks (jone clicks))
109− --
110−--
111−```
112−
113−`examples-clicks-clicks` is just an atom. We convert to json by creating an
93+ |_ clicks/@
94+ ++ grow
95+ |%
96+ ++ json
97+ (joba %clicks (jone clicks))
98+ --
99+ --
100+
101+`examples-clicks-clicks` is just an atom. We convert to json by creating an
114102object with a single field "clicks" with our value.
115103
116−> Be sure to checkout section 3bD, JSON and XML, in zuse.hoon
117−> `++joba` is just a function that takes a key-value pair and
118−> produces a JSON object with one element.
104+> Be sure to checkout section 3bD, JSON and XML, in zuse.hoon `++joba` is just a
105+> function that takes a key-value pair and produces a JSON object with one
106+> element.
119107
120−```
121−~fintud-macrep:dojo> &json &examples-click-clicks 6
122−[%o p={[p='clicks' q=[%n p=~.6]]}]
123−```
108+ ~fintud-macrep:dojo> &json &examples-click-clicks 6
109+ [%o p={[p='clicks' q=[%n p=~.6]]}]
124110
125−Now that we know the marks involved, take another look at the app
126−above. Everything should be pretty straightforward. Let's poke
127−the app from the command line.
111+Now that we know the marks involved, take another look at the app above.
112+Everything should be pretty straightforward. Let's poke the app from the command
113+line.
128114
129−```
130−~fintud-macrep:dojo> |start %examples-click
131−>=
132−~fintud-macrep:dojo> :examples-click &examples-click-click %click
133−[%poked 1]
134−>=
135−~fintud-macrep:dojo> :examples-click &examples-click-click %click
136−[%poked 2]
137−>=
138−```
115+ ~fintud-macrep:dojo> |start %examples-click
116+ >=
117+ ~fintud-macrep:dojo> :examples-click &examples-click-click %click
118+ [%poked 1]
119+ >=
120+ ~fintud-macrep:dojo> :examples-click &examples-click-click %click
121+ [%poked 2]
122+ >=
139123
140−Please pardon the awkwardness of the name 'examples-click-click', but we used it to stay true to our examples naming convention.
124+Please pardon the awkwardness of the name 'examples-click-click', but we used it
125+to stay true to our examples naming convention.
141126
142127**Exercise**:
143128
144−- Modify `:sink` from the subcriptions chapter to listen to
145− `:click` and print out the subscription updates on the command
146− line.
129+- Modify `:sink` from the subcriptions chapter to listen to `:click` and print
130+ out the subscription updates on the command line.
147131
148132# Frontend
149133
150−That's all that's needed for the back end. The front end is just
151−some "sail" html (Hoon markup for XML) and javascript. Here's `/web/pages/examples/click.hoon`:
152−
153−```
154−;html
155− ;head
156− ;script(type "text/javascript", src "//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js");
157− ;script(type "text/javascript", src "/~/at/lib/js/urb.js");
158− ;title: Clickety!
159− ==
160− ;body
161− ;div#cont
162− ;input#go(type "button", value "Poke!");
163− ;div#err(class "disabled");
164− ;div#clicks;
134+That's all that's needed for the back end. The front end is just some "sail"
135+html (Hoon markup for XML) and javascript. Here's
136+`/web/pages/examples/click.hoon`:
137+
138+ ;html
139+ ;head
140+ ;script(type "text/javascript", src "//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js");
141+ ;script(type "text/javascript", src "/~/at/lib/js/urb.js");
142+ ;title: Clickety!
143+ ==
144+ ;body
145+ ;div#cont
146+ ;input#go(type "button", value "Poke!");
147+ ;div#err(class "disabled");
148+ ;div#clicks;
149+ ==
150+ ;script(type "text/javascript", src "/pages/examples/click/click.js");
151+ ==
165152 ==
166− ;script(type "text/javascript", src "/pages/examples/click/click.js");
167− ==
168−==
169−```
170−
171−You should recognize the sail syntax from an earlier chapter.
172−Aside from jquery, we also include `urb.js`, which is a framework
173−for interacting with urbit.
174−
175−To view the frontend, point your browser at `ship-name.urbit.org/~~/pages/examples/click` if you're on the live network. If you're running a fake galaxy, navigate to whatever port it's running on, which is usually: `https://localhost:8443/~~/pages/examples/click`.
176−
177−We have a button labeled "Poke!" and a div with id `clicks` where
178−we'll put the number of clicks. We also include a small
179−javascript file where the client-side application logic can be
180−found. It's in `/web/pages/examples/click/click.js`:
181−
182−```
183−
184−$(function() {
185− var clicks, $go, $clicks, $err
186−
187− $go = $('#go')
188− $clicks = $('#clicks')
189− $err = $('#err')
190−
191− $go.on("click",
192− function() {
193− window.urb.send(
194− "click", {mark: "examples-click-click"}
195− ,function(err,res) {
196− if(err)
197− return $err.text("There was an error. Sorry!")
198− if(res.data !== undefined &&
199− res.data.ok !== undefined &&
200− res.data.ok !== true)
201− $err.text(res.data.res)
202− else
203− console.log("poke succeeded");
153+
154+You should recognize the sail syntax from an earlier chapter. Aside from jquery,
155+we also include `urb.js`, which is a framework for interacting with urbit.
156+
157+To view the frontend, point your browser at
158+`ship-name.urbit.org/~~/pages/examples/click` if you're on the live network. If
159+you're running a fake galaxy, navigate to whatever port it's running on, which
160+is usually: `https://localhost:8443/~~/pages/examples/click`.
161+
162+We have a button labeled "Poke!" and a div with id `clicks` where we'll put the
163+number of clicks. We also include a small javascript file where the client-side
164+application logic can be found. It's in `/web/pages/examples/click/click.js`:
165+
166+
167+ $(function() {
168+ var clicks, $go, $clicks, $err
169+
170+ $go = $('#go')
171+ $clicks = $('#clicks')
172+ $err = $('#err')
173+
174+ $go.on("click",
175+ function() {
176+ window.urb.send(
177+ "click", {mark: "examples-click-click"}
178+ ,function(err,res) {
179+ if(err)
180+ return $err.text("There was an error. Sorry!")
181+ if(res.data !== undefined &&
182+ res.data.ok !== undefined &&
183+ res.data.ok !== true)
184+ $err.text(res.data.res)
185+ else
186+ console.log("poke succeeded");
187+ })
204188 })
205− })
206−
207− window.urb.appl = "examples-click"
208− window.urb.bind('/the-path',
209− function(err,dat) {
210− clicks = dat.data.clicks
211− $clicks.text(clicks)
212− }
213− )
214−})
215−```
216−
217−We set up two event handlers. When we click the button, we run
218−`window.urb.send`, which sends a poke to the app specified as the first argument, in this case our :click app. The arguments
219−are data, parameters, and the callback. The data is the specific
220−data we want to send. The parameters are all optional, but here's a list
221−of the available ones:
222−
223−- `ship`: target urbit. Defaults to `window.urb.ship`, which
224− defaults to the urbit which served the page.
225−- `appl`: target app. Defaults to `window.urb.appl`, which
226− defaults to null.
227−- `mark`: mark of the data. Defaults to `window.urb.send.mark`,
228− which defaults to "json".
229−- `wire`: wire of the poke. Defaults to `/`.
189+
190+ window.urb.appl = "examples-click"
191+ window.urb.bind('/the-path',
192+ function(err,dat) {
193+ clicks = dat.data.clicks
194+ $clicks.text(clicks)
195+ }
196+ )
197+ })
198+
199+We set up two event handlers. When we click the button, we run
200+`window.urb.send`, which sends a poke to the app specified as the first
201+argument, in this case our :click app. The arguments are data, parameters, and
202+the callback. The data is the specific data we want to send. The parameters are
203+all optional, but here's a list of the available ones:
204+
205+- `ship`: target urbit. Defaults to `window.urb.ship`, which defaults to the
206+ urbit which served the page.
207+- `appl`: target app. Defaults to `window.urb.appl`, which defaults to null.
208+- `mark`: mark of the data. Defaults to `window.urb.send.mark`, which defaults
209+ to "json".
210+- `wire`: wire of the poke. Defaults to `/`.
230211
231212In our case, we specify only that the mark is "click".
232213
233−The callback funciton is called when we receive an
234−acknowledgment. If there was an error, we put it in the `err`
235−div that we defined above. Otherwise, we printf to the console a
236−message saying the poke succeeded. As is common, we gray
237−out the button when it is clicked. It is only reenabled when positive acknowledgement is received.
238−
239−Our second event handler is `window.urb.bind`, which is called immediately when the page is loaded, subscribing the page to the specified data stream on the app set with `urb.appl` (which is, in this case, :click). It also takes three arguments: path, parameters, and callback. The path is the path on the app to subscribe to. The parameters are all optional (indeed, we omit them entirely here), but are similar to those for `send`:
240−
241−- `ship`: target urbit. Defaults to `window.urb.ship`, which
242− defaults to the urbit which served the page.
243−- `appl`: target app. Defaults to `window.urb.appl`, which
244− defaults to null.
245−- `mark`: mark of expected data. Data of other marks is
246− converted to this mark on the server before coming to the web
247− front end. Defaults to `window.urb.bind.mark`, which defaults
248− to "json".
249−- `wire`: wire of the subscription. Defaults to the given path.
250−
251−The callback function here just updates the data in the `clicks`
252−div. A truly robust app would intelligently handle errors, of
253−course.
254−
255−Note that the app doesn't have anything web-specific in itself.
256−As far as it knows, it's just receiving pokes and subscriptions.
257−The javascript is fairly pure as well, sending and receiving json
258−everywhere. The marks are the translation layer, and they're the
259−only things that need to know how the hoon types map to json.
214+The callback funciton is called when we receive an acknowledgment. If there was
215+an error, we put it in the `err` div that we defined above. Otherwise, we printf
216+to the console a message saying the poke succeeded. As is common, we gray out
217+the button when it is clicked. It is only reenabled when positive
218+acknowledgement is received.
219+
220+Our second event handler is `window.urb.bind`, which is called immediately when
221+the page is loaded, subscribing the page to the specified data stream on the app
222+set with `urb.appl` (which is, in this case, :click). It also takes three
223+arguments: path, parameters, and callback. The path is the path on the app to
224+subscribe to. The parameters are all optional (indeed, we omit them entirely
225+here), but are similar to those for `send`:
226+
227+- `ship`: target urbit. Defaults to `window.urb.ship`, which defaults to the
228+ urbit which served the page.
229+- `appl`: target app. Defaults to `window.urb.appl`, which defaults to null.
230+- `mark`: mark of expected data. Data of other marks is converted to this mark
231+ on the server before coming to the web front end. Defaults to
232+ `window.urb.bind.mark`, which defaults to "json".
233+- `wire`: wire of the subscription. Defaults to the given path.
234+
235+The callback function here just updates the data in the `clicks` div. A truly
236+robust app would intelligently handle errors, of course.
237+
238+Note that the app doesn't have anything web-specific in itself. As far as it
239+knows, it's just receiving pokes and subscriptions. The javascript is fairly
240+pure as well, sending and receiving json everywhere. The marks are the
241+translation layer, and they're the only things that need to know how the hoon
242+types map to json.
260243
261244**Exercise**:
262245
263−- Open the app in multiple tabs, click the button, and verify
264− that all the tabs stay in sink. Poke it manually from the
265− command line and verify the tabs are updated as well.
246+- Open the app in multiple tabs, click the button, and verify that all the
247+ tabs stay in sink. Poke it manually from the command line and verify the
248+ tabs are updated as well.
docs/byte.md+3−2
@@ -1,10 +1,11 @@
11---
2−navhome: /docs/
2+navhome: '/docs/'
33sort: 2
44---
55
66# Learn
77
8−Learn Hoon in short, self-contained, bottom-up tutorials through our in-house Urbyte series. A work in progress. Still ideal for the complete newbie.
8+Learn Hoon in short, self-contained, bottom-up tutorials through our in-house
9+Urbyte series. A work in progress. Still ideal for the complete newbie.
910
1011<list/>
docs/byte/0.md+157−199
@@ -1,7 +1,7 @@
11---
2−navhome: /docs/
2+navhome: '/docs/'
3+next: True
34sort: 1
4−next: true
55title: Setup and nouns
66---
77
@@ -9,276 +9,234 @@ title: Setup and nouns
99
1010This is the first post in our new Urbyte series.
1111
12−The Urbyte concept is that you, an ordinary programmer, not a
13−kernel hacker or a Haskell magician (not that there's anything
14−wrong with kernel hackers or Haskell magicians) can learn Hoon,
15−Urbit's programming language.
12+The Urbyte concept is that you, an ordinary programmer, not a kernel hacker or a
13+Haskell magician (not that there's anything wrong with kernel hackers or Haskell
14+magicians) can learn Hoon, Urbit's programming language.
1615
17−We're going to test this daring idea by teaching you Hoon, in
18−easily digestible, byte-size chunks. Each post in the "Urbytes"
19−series is designed to take about 15 minutes to consume. (Maybe
20−10, if you're a kernel hacker or a Haskell magician.)
16+We're going to test this daring idea by teaching you Hoon, in easily digestible,
17+byte-size chunks. Each post in the "Urbytes" series is designed to take about 15
18+minutes to consume. (Maybe 10, if you're a kernel hacker or a Haskell magician.)
2119
22−We'll assume no knowledge of Urbit except for previous lessons.
23−Ideally you have some basic familiarity with programming and can
24−operate the Unix command line.
20+We'll assume no knowledge of Urbit except for previous lessons. Ideally you have
21+some basic familiarity with programming and can operate the Unix command line.
2522
26−We strongly encourage you to type in all the examples in each
27−Urbyte. Urbytes are short, but not meant to be skimmed.
23+We strongly encourage you to type in all the examples in each Urbyte. Urbytes
24+are short, but not meant to be skimmed.
2825
2926## Install
3027
31−First, [install Urbit](http://urbit.org/docs/using/install/) on any
32−Mac or Unix machine. On Windows, make a virtual Linux machine
33−using VirtualBox or a similar tool.
28+First, [install Urbit](http://urbit.org/docs/using/install/) on any Mac or Unix
29+machine. On Windows, make a virtual Linux machine using VirtualBox or a similar
30+tool.
3431
3532While you're downloading, read about Urbit ships:
3633
3734## Ships
3835
39−In the Urbyte exercises you'll be running what we call a "comet". A string starting with `~`, like `~zod`, is what Urbit
40−calls a *ship*.
36+In the Urbyte exercises you'll be running what we call a "comet". A string
37+starting with `~`, like `~zod`, is what Urbit calls a *ship*.
4138
42−A *ship* is one number which means four things: a network address,
43−a cryptographic identity, a memorable name, and a single virtual
44−computer.
39+A *ship* is one number which means four things: a network address, a
40+cryptographic identity, a memorable name, and a single virtual computer.
4541
46−We write this number in a base-256 format, where each digit is a
47−syllable. Imagine if your phone number was a pronounceable
48−string which sounded like a name in a foreign language. `~zod`
49−is ship zero (making it a very important ship indeed!). An ordinary
50−user-level ship is a "planet", a 32-bit number which becomes
51−a four-syllable string, like `~talsur-todres`.
42+We write this number in a base-256 format, where each digit is a syllable.
43+Imagine if your phone number was a pronounceable string which sounded like a
44+name in a foreign language. `~zod` is ship zero (making it a very important ship
45+indeed!). An ordinary user-level ship is a "planet", a 32-bit number which
46+becomes a four-syllable string, like `~talsur-todres`.
5247
53−*Comets*, at 128-bits or 16 syllables, are
54−disposable identities that anyone can make for free to
55−join the live network. Thus, comets make the ideal ship for
56−playing around with Hoon, asking for help from other Urbit devs in [`:talk`](http://urbit.org/docs/using/messaging/) if you
57−need it, and showing off Urbit to your hacker friends.
48+*Comets*, at 128-bits or 16 syllables, are disposable identities that anyone can
49+make for free to join the live network. Thus, comets make the ideal ship for
50+playing around with Hoon, asking for help from other Urbit devs in
51+[`:talk`](http://urbit.org/docs/using/messaging/) if you need it, and showing
52+off Urbit to your hacker friends.
5853
5954## Create and restart
6055
6156To create your comet, run:
6257
63−```
64−$ cd ~
65−$ mkdir urbit
66−$ cd urbit
67−$ urbit -c mycomet
68−```
69−
70−This will take a few minutes and will spin out a bunch of boot
71−messages. At the end, you'll see something like:
72−
73−```
74−ames: on localhost, UDP 31337.
75−http: live (insecure, public) on 8080
76−http: live ("secure", public) on 8443
77−http: live (insecure, loopback) on 12321
78−~palnul_nocser:dojo>
79−```
80−
81−To make sure everything is working, type `(add 2 2)` at the
82−prompt, then hit return. Your screen now shows:
83−
84−```
85−ames: on localhost, UDP 31337.
86−http: live (insecure, public) on 8080
87−http: live ("secure", public) on 8443
88−http: live (insecure, loopback) on 12321
89−> (add 2 2)
90−4
91−```
92−~palnul_nocser:dojo>
93−
94−That's super awesome! You made your first noun! We'll make a
95−few more in a second. First, quit Urbit with `ctrl-d`:
96−
97−```
98−> (add 2 2)
99−4
100−~palnul_nocser:dojo>
101−$
102−```
103−
104−You now have an Urbit image, or *pier*, in the `mycomet` directory.
105−Right now the only thing in your pier is Urbit's system files:
106−
107−```
108−$ ls -a /path/to/mycomet
109−./ ../ .urb/
110−```
111−
112−Restarting uses almost the same command, but without `-c` (which
113−means "create"). There are also fewer startup messages:
114−
115−```
116−$ urbit mycomet
117−[...]
118−ames: on localhost, UDP 31337.
119−http: live (insecure, public) on 8080
120−http: live ("secure", public) on 8443
121−http: live (insecure, loopback) on 12321
122−~palnul_nocser:dojo>
123−```
124−
125−Note also that Urbit is an ACID database. You can stop it
126−politely with `ctrl-d`, abruptly with `ctrl-z`, even violently with `kill
127−-9`. None of these should cause Urbit to lose data. If you do
128−manage to corrupt a pier, it's a bug; please let us know.
58+ $ cd ~
59+ $ mkdir urbit
60+ $ cd urbit
61+ $ urbit -c mycomet
12962
130−## Let's make a noun
63+This will take a few minutes and will spin out a bunch of boot messages. At the
64+end, you'll see something like:
65+
66+ ames: on localhost, UDP 31337.
67+ http: live (insecure, public) on 8080
68+ http: live ("secure", public) on 8443
69+ http: live (insecure, loopback) on 12321
70+ ~palnul_nocser:dojo>
71+
72+To make sure everything is working, type `(add 2 2)` at the prompt, then hit
73+return. Your screen now shows:
74+
75+ ames: on localhost, UDP 31337.
76+ http: live (insecure, public) on 8080
77+ http: live ("secure", public) on 8443
78+ http: live (insecure, loopback) on 12321
79+ > (add 2 2)
80+ 4
81+
82+~palnul\_nocser:dojo&gt;
83+
84+That's super awesome! You made your first noun! We'll make a few more in a
85+second. First, quit Urbit with `ctrl-d`:
86+
87+ > (add 2 2)
88+ 4
89+ ~palnul_nocser:dojo>
90+ $
13191
132−You've already made a noun. Let's make another!
92+You now have an Urbit image, or *pier*, in the `mycomet` directory. Right now
93+the only thing in your pier is Urbit's system files:
94+
95+ $ ls -a /path/to/mycomet
96+ ./ ../ .urb/
97+
98+Restarting uses almost the same command, but without `-c` (which means
99+"create"). There are also fewer startup messages:
100+
101+ $ urbit mycomet
102+ [...]
103+ ames: on localhost, UDP 31337.
104+ http: live (insecure, public) on 8080
105+ http: live ("secure", public) on 8443
106+ http: live (insecure, loopback) on 12321
107+ ~palnul_nocser:dojo>
108+
109+Note also that Urbit is an ACID database. You can stop it politely with
110+`ctrl-d`, abruptly with `ctrl-z`, even violently with `kill -9`. None of these
111+should cause Urbit to lose data. If you do manage to corrupt a pier, it's a bug;
112+please let us know.
113+
114+## Let's make a noun
133115
134−*We won't show the `~palnul_nocser:dojo> ` prompt from here on out.
135−We'll just show the echoed command.*
116+You've already made a noun. Let's make another!
136117
118+*We won't show the `~palnul_nocser:dojo>` prompt from here on out. We'll just
119+show the echoed command.*
137120
138−```
139−~palnul_nocser:dojo> 42
140−42
141−```
121+ ~palnul_nocser:dojo> 42
122+ 42
142123
143124You'll see:
144125
145−```
146−> 42
147−42
148−```
126+ > 42
127+ 42
149128
150129## Understanding nouns
151130
152−A value in Urbit is called a *noun*. A noun is either an *atom*
153−(an unsigned integer of any size) or a *cell* (an ordered pair of
154−any two nouns).
131+A value in Urbit is called a *noun*. A noun is either an *atom* (an unsigned
132+integer of any size) or a *cell* (an ordered pair of any two nouns).
155133
156−In a sentence, a noun is a binary tree whose leaves are numbers.
157−If you know Lisp, a noun is a minimalist S-expression. A noun
158−can't have cycles (pointer loops). An implementation can use
159−dags (shared subtrees), but the programmer can't detect them
160−(there's no pointer equality test).
134+In a sentence, a noun is a binary tree whose leaves are numbers. If you know
135+Lisp, a noun is a minimalist S-expression. A noun can't have cycles (pointer
136+loops). An implementation can use dags (shared subtrees), but the programmer
137+can't detect them (there's no pointer equality test).
161138
162−The absence of graph cycles makes nouns much easier to save in
163−persistent storage, send over the network, manage memory for
164−(Urbit has no tracing garbage collector), etc.
139+The absence of graph cycles makes nouns much easier to save in persistent
140+storage, send over the network, manage memory for (Urbit has no tracing garbage
141+collector), etc.
165142
166143## Let's make some atoms
167144
168−So one kind of atom is a number. And the syntax (or at least one
169−syntax) for a number is a decimal, like `42`. Seems legit.
145+So one kind of atom is a number. And the syntax (or at least one syntax) for a
146+number is a decimal, like `42`. Seems legit.
170147
171−But just to be sure we understand this decimal thing, let's make
172−some atoms:
148+But just to be sure we understand this decimal thing, let's make some atoms:
173149
174−```
175−> 4
176−4
177−```
150+ > 4
151+ 4
178152
179153Seems pretty straightforward.
180154
181−```
182−> 42
183−42
184−```
155+ > 42
156+ 42
185157
186158Why not try it again to make sure?
187159
188−```
189−> 420
190−420
191−```
160+ > 420
161+ 420
192162
193163Can we add another zero?
194164
195−```
196−> 420
197−```
165+ > 420
198166
199−Wat? When you tried to type that next zero and turn `420` into
200−`4200`, Urbit actually *deleted the `0` and beeped at you.*
167+Wat? When you tried to type that next zero and turn `420` into `4200`, Urbit
168+actually *deleted the `0` and beeped at you.*
201169
202−But isn't an atom an unsigned integer of any size? It is.
203−But the syntax is actually `4.200`:
170+But isn't an atom an unsigned integer of any size? It is. But the syntax is
171+actually `4.200`:
204172
205−```
206−> 4.200
207−4.200
208−> (mul 42 100)
209−4.200
210−```
173+ > 4.200
174+ 4.200
175+ > (mul 42 100)
176+ 4.200
211177
212178Just think of it as "4,200", written the German way with a dot.
213179
214−Why? Long decimals are unreadable. Human beings know this, so
215−we group them in threes. For some historical reason, programming
216−languages never copied this marvelous usability innovation.
180+Why? Long decimals are unreadable. Human beings know this, so we group them in
181+threes. For some historical reason, programming languages never copied this
182+marvelous usability innovation.
217183
218−English notation for decimals is more common than German
219−notation. Unfortunately, dot is URL-safe and comma isn't, and
220−it's nice to have a regular syntax for atoms that's URL-safe.
184+English notation for decimals is more common than German notation.
185+Unfortunately, dot is URL-safe and comma isn't, and it's nice to have a regular
186+syntax for atoms that's URL-safe.
221187
222−As for why Urbit deleted your zero: it parses your command line
223−as you type, and rejects any characters after the parser stops.
188+As for why Urbit deleted your zero: it parses your command line as you type, and
189+rejects any characters after the parser stops.
224190
225191## Let's make some cells
226192
227−There's not much mystery about cells. A cell has a head and a
228−tail, and puts brackets around them:
193+There's not much mystery about cells. A cell has a head and a tail, and puts
194+brackets around them:
229195
230−```
231−> [42 420]
232−[42 420]
233−```
196+ > [42 420]
197+ [42 420]
234198
235−`42` is the *head* and `420` is the *tail* of the cell. Cell
236−syntax nests to the right:
199+`42` is the *head* and `420` is the *tail* of the cell. Cell syntax nests to the
200+right:
237201
238−```
239−> [4 [42 420]]
240−[4 42 420]
202+ > [4 [42 420]]
203+ [4 42 420]
241204
242−> [4 42 420]
243−[4 42 420]
205+ > [4 42 420]
206+ [4 42 420]
244207
245−> [[4 42] 420]
246−[[4 42] 420]
247−```
208+ > [[4 42] 420]
209+ [[4 42] 420]
248210
249211If you look at these nouns as binary trees, you see
250212
251−```
252− [4 [42 420]] [[4 42] 420]
253− . .
254− / \ / \
255− 4 . . 420
256− / \ / \
257− 42 420 4 42
258−```
213+ [4 [42 420]] [[4 42] 420]
214+ . .
215+ / \ / \
216+ 4 . . 420
217+ / \ / \
218+ 42 420 4 42
259219
260220Each number is an atom; each dot is a cell.
261221
262222## And we're done
263223
264−And we're done! Type `|exit` to exit:
224+And we're done! Type `|exit` to exit:
265225
266−```
267−~palnul_nocser:dojo> |exit
268−%drum-exit
269−$
270−```
226+ ~palnul_nocser:dojo> |exit
227+ %drum-exit
228+ $
271229
272230## Questions and/or exercises
273231
274−And we're done with our very first Urbyte! Here are some questions to
275−think about. These exercises are never mandatory, but they may
276−be fun and/or interesting. Skip them if they're obvious.
232+And we're done with our very first Urbyte! Here are some questions to think
233+about. These exercises are never mandatory, but they may be fun and/or
234+interesting. Skip them if they're obvious.
277235
278−* What is the right way to represent common
279−data structures as nouns?
280−* A linked list?
281−* A string? A *signed* integer?
282−* A table or associative array?
236+- What is the right way to represent common data structures as nouns?
237+- A linked list?
238+- A string? A *signed* integer?
239+- A table or associative array?
283240
284−Just try to picture these structures in your head, or draw them on a piece of paper.
241+Just try to picture these structures in your head, or draw them on a piece of
242+paper.
docs/byte/1.md+222−252
@@ -1,369 +1,339 @@
11---
2−navhome: /docs/
2+navhome: '/docs/'
3+next: True
34sort: 2
4−next: true
5−title: Atoms, auras, types
5+title: 'Atoms, auras, types'
66---
77
88# Urbyte 1: Atoms, auras, types
99
10−Thanks for reading Urbyte 0! In Urbyte 1, we'll look a little
11−more deeply at atoms and other simple noun types.
10+Thanks for reading Urbyte 0! In Urbyte 1, we'll look a little more deeply at
11+atoms and other simple noun types.
1212
1313Let's restart our engines:
1414
15−```
16−$ urbit mycomet
17−[...]
18−ames: on localhost, UDP 31337.
19−http: live (insecure, public) on 8080
20−http: live ("secure", public) on 8443
21−http: live (insecure, loopback) on 12321
22−~palnul_nocser:dojo>
23−```
15+ $ urbit mycomet
16+ [...]
17+ ames: on localhost, UDP 31337.
18+ http: live (insecure, public) on 8080
19+ http: live ("secure", public) on 8443
20+ http: live (insecure, loopback) on 12321
21+ ~palnul_nocser:dojo>
2422
2523## What's in an atom?
2624
27−It seems limiting to have only one kind of atom, the unsigned
28−decimal. How are signed integers represented? Symbols?
29−Floating-point values? Dates? IP addresses? Even just hex?
25+It seems limiting to have only one kind of atom, the unsigned decimal. How are
26+signed integers represented? Symbols? Floating-point values? Dates? IP
27+addresses? Even just hex?
3028
31−Lisp's S-expression, with its own cells and atoms, is very
32−similar to Hoon's nouns. But languages in the Lisp family mark
33−each atom with a dynamic tag that defines the atom's meaning.
34−These tags are effectively dynamic types.
29+Lisp's S-expression, with its own cells and atoms, is very similar to Hoon's
30+nouns. But languages in the Lisp family mark each atom with a dynamic tag that
31+defines the atom's meaning. These tags are effectively dynamic types.
3532
36−Hoon also tracks the meaning of atoms. But Hoon is statically
37−typed, so an atom description is obviously a type. An atomic type
38−in Hoon is called an *aura*. The aura syntax is just an ASCII
39−string starting with `@`, like `@ud` for unsigned decimal.
33+Hoon also tracks the meaning of atoms. But Hoon is statically typed, so an atom
34+description is obviously a type. An atomic type in Hoon is called an *aura*. The
35+aura syntax is just an ASCII string starting with `@`, like `@ud` for unsigned
36+decimal.
4037
41−Hoon has a wide (but not extensible) variety of atom syntaxes.
42−Each syntax for an atom produces an appropriate predefined aura.
43−And Hoon's printer can invertibly print any aura Hoon can parse.
44−Because atoms make great path nodes and paths make great URLs,
45−all regular atom syntaxes use only URL-safe characters.
38+Hoon has a wide (but not extensible) variety of atom syntaxes. Each syntax for
39+an atom produces an appropriate predefined aura. And Hoon's printer can
40+invertibly print any aura Hoon can parse. Because atoms make great path nodes
41+and paths make great URLs, all regular atom syntaxes use only URL-safe
42+characters.
4643
4744## Examples
4845
49−With the dojo command `? expression`, you tell the dojo to print
50−both the product of the expression, and the product's type.
46+With the dojo command `? expression`, you tell the dojo to print both the
47+product of the expression, and the product's type.
5148
5249Let's type in some aura examples:
5350
5451### Unsigned integers
5552
56−```
57−> 42
58−42
53+ > 42
54+ 42
5955
60−> ? 42
61− @ud
62−42
56+ > ? 42
57+ @ud
58+ 42
6359
64−> ? 0x42
65− @ux
66−0x42
60+ > ? 0x42
61+ @ux
62+ 0x42
6763
68−> ? (add 0x42 42)
69− @
70−108
64+ > ? (add 0x42 42)
65+ @
66+ 108
7167
72−> ? `@ud`0x42
73− @ud
74−66
68+ > ? `@ud`0x42
69+ @ud
70+ 66
7571
76−```
72+So decimal is aura `@ud`, hexadecimal is `@ux`. Note the cast syntax, which lets
73+us change the type of an atom, converting hex `0x42` to a decimal `66`.
7774
78−So decimal is aura `@ud`, hexadecimal is `@ux`. Note the cast
79−syntax, which lets us change the type of an atom, converting hex
80−`0x42` to a decimal `66`.
81−
82−An aura is soft type. The programmer can always insist on how
83−to interpret an atom. Hoon doesn't have "dependent types"; it
84−can't enforce any constraints the aura puts on the atom's value.
75+An aura is soft type. The programmer can always insist on how to interpret an
76+atom. Hoon doesn't have "dependent types"; it can't enforce any constraints the
77+aura puts on the atom's value.
8578
8679### Signed integers
8780
88−```
89−> -7
90−-7
81+ > -7
82+ -7
9183
92−> ? -7
93− @sd
84+ > ? -7
85+ @sd
9486
95−> --7
96−--7
87+ > --7
88+ --7
9789
98−> ? --7
99− @sd
100−--7
90+ > ? --7
91+ @sd
92+ --7
10193
102−> ? (sum:si -7 --7)
103− @s
104−--0
94+ > ? (sum:si -7 --7)
95+ @s
96+ --0
10597
106−> `@ud`-7
107−13
98+ > `@ud`-7
99+ 13
108100
109−> `@ud`--7
110−14
111−```
101+ > `@ud`--7
102+ 14
112103
113−`--7` means "positive 7." `+7` might have been better, but `+`
114−is not URL-safe.
104+`--7` means "positive 7." `+7` might have been better, but `+` is not URL-safe.
115105
116−Hoon needs `--` to distinguish positive signed numbers because
117−Hoon's type system doesn't feed back into its parser. The
118−expression itself needs to control whether it's `@sd` or `@ud`.
106+Hoon needs `--` to distinguish positive signed numbers because Hoon's type
107+system doesn't feed back into its parser. The expression itself needs to control
108+whether it's `@sd` or `@ud`.
119109
120−With unlimited atom width, traditional sign extension makes no
121−sense. The sign bit is the low bit. Even atoms are positive,
122−odd atoms are negative.
110+With unlimited atom width, traditional sign extension makes no sense. The sign
111+bit is the low bit. Even atoms are positive, odd atoms are negative.
123112
124−And Hoon has no overloading or type detection; we need to use a
125−different function to add signed integers. We'll always choose
126−slightly clunkier syntax in exchange for much simpler semantics.
113+And Hoon has no overloading or type detection; we need to use a different
114+function to add signed integers. We'll always choose slightly clunkier syntax in
115+exchange for much simpler semantics.
127116
128117### Symbols
129118
130−```
131−> ? 'Ürbit'
132− @t
133−'Ürbit'
119+ > ? 'Ürbit'
120+ @t
121+ 'Ürbit'
134122
135−> ? `@ux`'Ürbit'
136− @ux
137−0x7469.6272.9cc3
123+ > ? `@ux`'Ürbit'
124+ @ux
125+ 0x7469.6272.9cc3
138126
139−> ? ~~Ürbit
140− @t
141−'Ürbit'
127+ > ? ~~Ürbit
128+ @t
129+ 'Ürbit'
142130
143−> ? ~.urbit
144− @ta
145−~.urbit
131+ > ? ~.urbit
132+ @ta
133+ ~.urbit
146134
147−> ? `@ux`'foo'
148− @ux
149−0x6f.6f66
150−```
135+ > ? `@ux`'foo'
136+ @ux
137+ 0x6f.6f66
151138
152−The `@t` aura is UTF-8 text, with the first byte low. Again,
153−Hoon doesn't actually have the power to check statically that
154−your UTF-8 is valid. Auras don't tell you what an atom is, just
155−what you think it is.
139+The `@t` aura is UTF-8 text, with the first byte low. Again, Hoon doesn't
140+actually have the power to check statically that your UTF-8 is valid. Auras
141+don't tell you what an atom is, just what you think it is.
156142
157−The familiar single-quote syntax for `@t` is an irregular form of
158−the more unusual `~~` prefix. The `~.` prefix, aura `@ta`, is
159−restricted to lowercase ASCII (a great common denominator). Of
160−course, `~` is URL-safe and `'` is not.
143+The familiar single-quote syntax for `@t` is an irregular form of the more
144+unusual `~~` prefix. The `~.` prefix, aura `@ta`, is restricted to lowercase
145+ASCII (a great common denominator). Of course, `~` is URL-safe and `'` is not.
161146
162147### Dates, floats, IP addresses...
163148
164−```
165−> ? now
166− @da
167−~2016.7.11..01.32.04..2c0d
149+ > ? now
150+ @da
151+ ~2016.7.11..01.32.04..2c0d
168152
169−> ? ~h6
170− @dr
171−~h6
153+ > ? ~h6
154+ @dr
155+ ~h6
172156
173−> `@ux`~h6
174− @ux
175−0x5460.0000.0000.0000.0000
157+ > `@ux`~h6
158+ @ux
159+ 0x5460.0000.0000.0000.0000
176160
177−> ? (add ~h6 now)
178− @
179−170.141.184.502.236.089.414.812.327.632.537.911.296
161+ > ? (add ~h6 now)
162+ @
163+ 170.141.184.502.236.089.414.812.327.632.537.911.296
180164
181−> `@da`(add ~h6 now)
182−~2016.7.11..07.32.28..842f
165+ > `@da`(add ~h6 now)
166+ ~2016.7.11..07.32.28..842f
183167
184−> ? .3.14
185− @rs
186−.3.14
168+ > ? .3.14
169+ @rs
170+ .3.14
187171
188−> ? .127.0.0.1
189− @if
190−.127.0.0.1
191−```
172+ > ? .127.0.0.1
173+ @if
174+ .127.0.0.1
192175
193−`@da` is a 128-bit absolute date (64 bits for fractions of a
194−second, 64 bits for seconds); `@dr` is a relative date; `@rs` is
195−a single-precision IEEE real; `@if` is an IPv4 address. This is
196−not all Hoon's aura syntax, just a good range of examples.
176+`@da` is a 128-bit absolute date (64 bits for fractions of a second, 64 bits for
177+seconds); `@dr` is a relative date; `@rs` is a single-precision IEEE real; `@if`
178+is an IPv4 address. This is not all Hoon's aura syntax, just a good range of
179+examples.
197180
198−`(add ~h6 now)` is a good example of the use and limits of
199−the aura system. Unlike the signed-integer sum, offsetting a
200−date can use plain atomic addition. But the product of `add` is
201−a flavorless atom with no aura, `@`. So we have to cast it back
202−to an absolute date `@da`.
181+`(add ~h6 now)` is a good example of the use and limits of the aura system.
182+Unlike the signed-integer sum, offsetting a date can use plain atomic addition.
183+But the product of `add` is a flavorless atom with no aura, `@`. So we have to
184+cast it back to an absolute date `@da`.
203185
204186## Auras explained
205187
206−Does an aura represent the units of the atom, its syntax, its
207−semantics, its constraints?
188+Does an aura represent the units of the atom, its syntax, its semantics, its
189+constraints?
208190
209−Any or all of the above. Programmers can even use their own aura
210−strings, which nothing in Hoon recognizes. The set of syntaxes
211−that Hoon knows how to parse and/or print is fixed. But there
212−are plenty of good reasons to use your own user-defined auras.
191+Any or all of the above. Programmers can even use their own aura strings, which
192+nothing in Hoon recognizes. The set of syntaxes that Hoon knows how to parse
193+and/or print is fixed. But there are plenty of good reasons to use your own
194+user-defined auras.
213195
214−If your program uses both fortnights and furlongs, Hoon will not
215−parse a user-defined fortnight syntax. It will not print furlongs
216−in the dojo. But the type system will keep you from accidentally
217−passing a furlong to a function that expects a fortnight.
196+If your program uses both fortnights and furlongs, Hoon will not parse a
197+user-defined fortnight syntax. It will not print furlongs in the dojo. But the
198+type system will keep you from accidentally passing a furlong to a function that
199+expects a fortnight.
218200
219−Hoon does interpret the aura string in one way: auras specialize
220−to the right. For example, `@u` is any unsigned integer; `@ux`
221−is an unsigned integer that likes to be printed as hex.
201+Hoon does interpret the aura string in one way: auras specialize to the right.
202+For example, `@u` is any unsigned integer; `@ux` is an unsigned integer that
203+likes to be printed as hex.
222204
223−Hoon's typechecker lets you go up or down the specialization
224−ladder. It complains if you try to move across. For example,
225−`@u` can silently convert into `@ux` or `@ux` into `@u`, but
226−turning `@ud` into `@ux`, `@ux` into `@da`, etc, requires an
227−explicit cast.
205+Hoon's typechecker lets you go up or down the specialization ladder. It
206+complains if you try to move across. For example, `@u` can silently convert into
207+`@ux` or `@ux` into `@u`, but turning `@ud` into `@ux`, `@ux` into `@da`, etc,
208+requires an explicit cast.
228209
229210## Constants, symbols, loobeans and null
230211
231−An atom type isn't just an aura. There's another choice: the
232−type can be *general* and contain all atoms (like the types we've
233−seen above), or *constant* and contain just one atom.
212+An atom type isn't just an aura. There's another choice: the type can be
213+*general* and contain all atoms (like the types we've seen above), or *constant*
214+and contain just one atom.
234215
235−A type describes a set of values. While auras may informally
236−describe a format for which not all atoms are valid, any atom can
237−be cast into the aura whether valid or invalid. But in a
238−constant, the type contains just one atom.
216+A type describes a set of values. While auras may informally describe a format
217+for which not all atoms are valid, any atom can be cast into the aura whether
218+valid or invalid. But in a constant, the type contains just one atom.
239219
240−The regular syntax for an atomic constant is just to put `%` in
241−front of the constant. Like:
220+The regular syntax for an atomic constant is just to put `%` in front of the
221+constant. Like:
242222
243−```
244−> ? 42
245− @ud
246−42
223+ > ? 42
224+ @ud
225+ 42
247226
248−> ? %42
249− $42
250−%42
227+ > ? %42
228+ $42
229+ %42
251230
252−> ? %~h6
253− $~h6
254−%~h6
255−```
231+ > ? %~h6
232+ $~h6
233+ %~h6
256234
257−The `$` on the type indicates the constant. Note that constants
258−still have auras; `~h6` (6 hours) is still a `@dr`.
235+The `$` on the type indicates the constant. Note that constants still have
236+auras; `~h6` (6 hours) is still a `@dr`.
259237
260238## Common irregulars
261239
262−There are a few special forms worth learning early: symbols,
263−null, loobeans, and of course ships:
240+There are a few special forms worth learning early: symbols, null, loobeans, and
241+of course ships:
264242
265−```
266−> ? %foo
267− $foo
268−%foo
243+ > ? %foo
244+ $foo
245+ %foo
269246
270−> `@ux`%foo
271−0x6f.6f66
247+ > `@ux`%foo
248+ 0x6f.6f66
272249
273−> .n
274−%.n
250+ > .n
251+ %.n
275252
276−> |
277−%.n
253+ > |
254+ %.n
278255
279−> .y
280−%.y
256+ > .y
257+ %.y
281258
282−> &
283−%.y
259+ > &
260+ %.y
284261
285−> `@ud`&
286−0
262+ > `@ud`&
263+ 0
287264
288−> ~
289−~
265+ > ~
266+ ~
290267
291−> `@ud`~
292−0
268+ > `@ud`~
269+ 0
293270
294−> ? ~zod
295− @p
296−~zod
271+ > ? ~zod
272+ @p
273+ ~zod
297274
298−> `@ux`~forseg-bolbyn
299−0x885e.8af9
300−```
275+ > `@ux`~forseg-bolbyn
276+ 0x885e.8af9
301277
302−`%symbol` is a constant with aura `@tas` (text, ASCII, symbol).
303−The symbol rules, which are enforced by the Hoon parser but not
304−(as we've discussed) the type system: a symbol is lowercase with
305−infix hyphens ("kebab-case").
278+`%symbol` is a constant with aura `@tas` (text, ASCII, symbol). The symbol
279+rules, which are enforced by the Hoon parser but not (as we've discussed) the
280+type system: a symbol is lowercase with infix hyphens ("kebab-case").
306281
307−Loobeans are not true and false, but yes (`.y` or `&`) and no
308−(`.n` or `|`). This is because *yes is zero and no is one*.
309−This makes sense at a certain mathematical level, though it
310−was probably a mistake from a practical perspective.
282+Loobeans are not true and false, but yes (`.y` or `&`) and no (`.n` or `|`).
283+This is because *yes is zero and no is one*. This makes sense at a certain
284+mathematical level, though it was probably a mistake from a practical
285+perspective.
311286
312287`~` is Hoon's nil: constant `0`, aura `@n`.
313288
314−And of course, `@p` is the phonemic base used for ship names.
315−(It's useful for any kind of memorable number.)
289+And of course, `@p` is the phonemic base used for ship names. (It's useful for
290+any kind of memorable number.)
316291
317292## Cells and types
318293
319−Naturally, all these atoms fit neatly into cells, and retain
320−their types within the cells.
294+Naturally, all these atoms fit neatly into cells, and retain their types within
295+the cells.
321296
322−```
323−> ? [~h6 [.3.14 %foo] 0xdead.beef]
324− {@dr {@rs $foo} @ux}
325−[~h6 [.3.14 %foo] 0xdead.beef]
297+ > ? [~h6 [.3.14 %foo] 0xdead.beef]
298+ {@dr {@rs $foo} @ux}
299+ [~h6 [.3.14 %foo] 0xdead.beef]
326300
327−> `*`[~h6 [.3.14 %foo] 0xdead.beef]
328−[398.449.671.992.126.314.905.600 [1.078.523.331 7.303.014] 3.735.928.559]
329−```
301+ > `*`[~h6 [.3.14 %foo] 0xdead.beef]
302+ [398.449.671.992.126.314.905.600 [1.078.523.331 7.303.014] 3.735.928.559]
330303
331−Another fun trick is to cast any noun to the `*` type, ie,
332−generic noun. We then know nothing about the noun, so we print
333−all its atoms as decimals.
304+Another fun trick is to cast any noun to the `*` type, ie, generic noun. We then
305+know nothing about the noun, so we print all its atoms as decimals.
334306
335307## And we're done
336308
337−And we're done! Type `|exit` to exit:
309+And we're done! Type `|exit` to exit:
338310
339−```
340−~palnul_nocser:dojo> |exit
341−%drum-exit
342−$
343−```
311+ ~palnul_nocser:dojo> |exit
312+ %drum-exit
313+ $
344314
345315## Questions and/or exercises
346316
347317As always, these questions are optional and only for fun.
348318
349−We didn't include anywhere near all Hoon's auras or syntaxes in
350−this lesson. It's just a set of examples.
319+We didn't include anywhere near all Hoon's auras or syntaxes in this lesson.
320+It's just a set of examples.
351321
352−* Try using the dojo's magic error erasure to stumble around the
353−rest of Hoon's atom syntax. Any string that can't be extended
354−into a valid expression will be trimmed back, with a beep, until
355−it can. Return will beep if the expression is not complete.
356−This feedback is harmless and does not use an electric shock.
357−It enables stochastic reinforcement learning of Hoon syntax.
322+- Try using the dojo's magic error erasure to stumble around the rest of
323+ Hoon's atom syntax. Any string that can't be extended into a valid
324+ expression will be trimmed back, with a beep, until it can. Return will beep
325+ if the expression is not complete. This feedback is harmless and does not
326+ use an electric shock. It enables stochastic reinforcement learning of Hoon
327+ syntax.
358328
359−* If `~h6` is six hours, how do you write forty-five minutes? Two
360−days, six hours and forty-five minutes?
329+- If `~h6` is six hours, how do you write forty-five minutes? Two days, six
330+ hours and forty-five minutes?
361331
362−* What would you expect the syntax for double-precision float to
363−be? What about base64?
332+- What would you expect the syntax for double-precision float to be? What
333+ about base64?
364334
365−* Does an absolute date have to include every zillisecond, or can
366−it be pruned to a day or a year?
335+- Does an absolute date have to include every zillisecond, or can it be pruned
336+ to a day or a year?
367337
368−* If there's an IP syntax, what about bitcoin addresses? What
369−other auras do you think should be supported?
338+- If there's an IP syntax, what about bitcoin addresses? What other auras do
339+ you think should be supported?
docs/byte/2.md+287−342
@@ -1,495 +1,440 @@
11---
2−navhome: /docs/
2+navhome: '/docs/'
33sort: 3
4−title: Subject-oriented programming
4+title: 'Subject-oriented programming'
55---
66
77# Urbyte 2: Subject-oriented programming
88
9−Thanks for reading Urbytes 0 and 1! In Urbyte 2, we'll take
10−nouns for granted and have some real fun with them.
9+Thanks for reading Urbytes 0 and 1! In Urbyte 2, we'll take nouns for granted
10+and have some real fun with them.
1111
1212Let's restart our engines:
1313
14−```
15−$ urbit mycomet
16−[...]
17−ames: on localhost, UDP 31337.
18−http: live (insecure, public) on 8080
19−http: live ("secure", public) on 8443
20−http: live (insecure, loopback) on 12321
21−~palnul_nocser:dojo>
22−```
14+ $ urbit mycomet
15+ [...]
16+ ames: on localhost, UDP 31337.
17+ http: live (insecure, public) on 8080
18+ http: live ("secure", public) on 8443
19+ http: live (insecure, loopback) on 12321
20+ ~palnul_nocser:dojo>
2321
2422## Welcome to the dojo
2523
2624Wait, where are we?
2725
28−We're playing in the Urbit `:dojo`. The dojo is sort of like a
29−cross between a Lisp REPL and the Unix shell. (If you know the
30−Unix shell, the Urbit command line has the same history model and
31−Emacs editing commands.)
26+We're playing in the Urbit `:dojo`. The dojo is sort of like a cross between a
27+Lisp REPL and the Unix shell. (If you know the Unix shell, the Urbit command
28+line has the same history model and Emacs editing commands.)
3229
33−The dojo has its own command language, which is a superset of
34−Hoon. Any Hoon expression is a command. But not all commands
35−are expressions.
30+The dojo has its own command language, which is a superset of Hoon. Any Hoon
31+expression is a command. But not all commands are expressions.
3632
37−(The dojo is not the only command-line app on your Urbit. By
38−default there is one other, `:talk`. Since you're on a fakezod,
39−you can only talk to yourself. If you accidentally press `ctrl-x`,
40−it will put you into `:talk`; press `ctrl-x` again to switch back.)
33+(The dojo is not the only command-line app on your Urbit. By default there is
34+one other, `:talk`. Since you're on a fakezod, you can only talk to yourself. If
35+you accidentally press `ctrl-x`, it will put you into `:talk`; press `ctrl-x`
36+again to switch back.)
4137
4238### Dojo variables
4339
44−Like the Unix shell, the dojo has command variables. Type
40+Like the Unix shell, the dojo has command variables. Type
4541
46−```
47−> =a 42
48−```
42+ > =a 42
4943
50−You've set the dojo variable `a` to the value `42`. The dojo
51−puts this binding in the Hoon subject for expressions to use.
52−So you can write:
44+You've set the dojo variable `a` to the value `42`. The dojo puts this binding
45+in the Hoon subject for expressions to use. So you can write:
5346
54−```
55−> a
56−42
47+ > a
48+ 42
5749
58−> [4 a]
59−[4 42]
50+ > [4 a]
51+ [4 42]
6052
61−> ? [4 a]
62− {@ud @ud}
63−[4 42]
64−```
53+ > ? [4 a]
54+ {@ud @ud}
55+ [4 42]
6556
6657To unbind `a`, just omit the value:
6758
68−```
69−> =a
70−```
59+ > =a
7160
72−You removed `a` from the subject. (We can bind it again later, or
73−bind over it without removing it.)
61+You removed `a` from the subject. (We can bind it again later, or bind over it
62+without removing it.)
7463
75−```
76−> [4 a]
77−-find.a
78−```
64+ > [4 a]
65+ -find.a
7966
8067Now trying to use `a` is an error.
8168
8269## Subject-oriented programming
8370
84−What is this *subject* thing, anyway? We put `a` in what?
71+What is this *subject* thing, anyway? We put `a` in what?
8572
86−Most programming languages have something called a *scope* or an
87−*environment* or a *context*. This is a data structure that
88−contains the variables and functions an expression can use.
73+Most programming languages have something called a *scope* or an *environment*
74+or a *context*. This is a data structure that contains the variables and
75+functions an expression can use.
8976
90−In a normal language, the environment is not a first-class value.
91−You cannot save an environment in a variable, compute an
92−expression against the environment in the variable, etc, etc.
77+In a normal language, the environment is not a first-class value. You cannot
78+save an environment in a variable, compute an expression against the environment
79+in the variable, etc, etc.
9380
94−In Hoon or any "subject-oriented" language, an expression is
95−executed against one normal value, the *subject*. In Hoon, of
96−course, the subject is a noun.
81+In Hoon or any "subject-oriented" language, an expression is executed against
82+one normal value, the *subject*. In Hoon, of course, the subject is a noun.
9783
9884## First experiments
9985
100−Up to now, we've only built constants. By definition, a constant
101−doesn't use the subject.
86+Up to now, we've only built constants. By definition, a constant doesn't use the
87+subject.
10288
103−It would be nice to start with the subject every dojo expression
104−gets. But that subject is pretty complex. Instead, let's make a
105−simple noun from the kinds of atoms we've already learned about:
89+It would be nice to start with the subject every dojo expression gets. But that
90+subject is pretty complex. Instead, let's make a simple noun from the kinds of
91+atoms we've already learned about:
10692
107−```
108−> =a [42 [%foo .6.28 ~m45] 0xdead.beef]
93+ > =a [42 [%foo .6.28 ~m45] 0xdead.beef]
10994
110−> ? a
111− {@ud {$foo @rs @dr} @ux}
112−[42 [%foo .3.14 ~m45] 0xdead.beef]
95+ > ? a
96+ {@ud {$foo @rs @dr} @ux}
97+ [42 [%foo .3.14 ~m45] 0xdead.beef]
11398
114−> 420:a
115−420
116−```
99+ > 420:a
100+ 420
117101
118−The syntax `expression:expression` uses the product of the second
119−expression as the subject of the first. So we're using `a` as
120−the subject of the expression `420`.
102+The syntax `expression:expression` uses the product of the second expression as
103+the subject of the first. So we're using `a` as the subject of the expression
104+`420`.
121105
122−Of course, `420` is a constant expression. It doesn't care what
123−the subject is. But:
106+Of course, `420` is a constant expression. It doesn't care what the subject is.
107+But:
124108
125−```
126−> (add 2 2):a
127−-find.add
128−```
109+ > (add 2 2):a
110+ -find.add
129111
130−We can't use `a` as the subject of even a simple addition. How
131−could we? There's no `add` function in our `a`. It sometimes
132−takes new Hoon programmers a little while before they realize
133−that there really isn't a scope or environment in Hoon.
112+We can't use `a` as the subject of even a simple addition. How could we? There's
113+no `add` function in our `a`. It sometimes takes new Hoon programmers a little
114+while before they realize that there really isn't a scope or environment in
115+Hoon.
134116
135117## Tree geometry
136118
137−So what can we do with this subject? How can we get data out of
138−it? Let's keep working with our little test subject `a`.
119+So what can we do with this subject? How can we get data out of it? Let's keep
120+working with our little test subject `a`.
139121
140−The most basic way to access the subject is *tree geometry*.
141−Every noun is a binary tree; every noun in the tree has a number
142−which is its address. The root of the tree is `1`; if the
143−address of a cell is `n`, its head is `2n` and its tail is
144−`2n+1`.
122+The most basic way to access the subject is *tree geometry*. Every noun is a
123+binary tree; every noun in the tree has a number which is its address. The root
124+of the tree is `1`; if the address of a cell is `n`, its head is `2n` and its
125+tail is `2n+1`.
145126
146127A picture might help:
147−```
148− 1
149− / \
150− 2 3
151− / \ / \
152− 4 5 6 7
153− / \
154− 14 15
155−```
156−
157−The syntax for a fragment of the subject at a tree address, or
158−*axis*, is just `+axis`. So:
159−
160−```
161−> +3:a
162−[[%foo .3.14 ~m45] 0xdead.beef]
163−
164−> ? +7:a
165− @ux
166−0xdead.beef
167−
168−> ? +13:a
169− {@rs @dr}
170−[.3.14 ~m45]
171−```
128+
129+ 1
130+ / \
131+ 2 3
132+ / \ / \
133+ 4 5 6 7
134+ / \
135+ 14 15
136+
137+The syntax for a fragment of the subject at a tree address, or *axis*, is just
138+`+axis`. So:
139+
140+ > +3:a
141+ [[%foo .3.14 ~m45] 0xdead.beef]
142+
143+ > ? +7:a
144+ @ux
145+ 0xdead.beef
146+
147+ > ? +13:a
148+ {@rs @dr}
149+ [.3.14 ~m45]
172150
173151Of course, the fragment retains the type it had when we built it.
174152
175153## Labeled surfaces
176154
177−We can obviously get anything we want out of the subject by tree
178−geometry. But that's not really how we'd like to program. We'd
179−much rather *label* subtrees with convenient, memorable symbols.
155+We can obviously get anything we want out of the subject by tree geometry. But
156+that's not really how we'd like to program. We'd much rather *label* subtrees
157+with convenient, memorable symbols.
180158
181159For example, suppose our tree looked like:
182160
183−```
184− 1
185− / \
186− x=2 3
187− / \
188− y=6 z=7
189− / \
190− p=14 15
191− / \
192− q=30 r=31
193−```
161+ 1
162+ / \
163+ x=2 3
164+ / \
165+ y=6 z=7
166+ / \
167+ p=14 15
168+ / \
169+ q=30 r=31
194170
195171Then instead of writing `+2`, we could write `x`, and so on.
196172
197−Let's replace our test subject `a` with a new noun built around
198−this tree of *labeled surfaces*.
173+Let's replace our test subject `a` with a new noun built around this tree of
174+*labeled surfaces*.
199175
200−```
201−> =a [x=42 y=[p=%foo q=.6.28 r=~m45] z=0xdead.beef]
176+ > =a [x=42 y=[p=%foo q=.6.28 r=~m45] z=0xdead.beef]
202177
203−> ? x:a
204− @ud
205−42
178+ > ? x:a
179+ @ud
180+ 42
206181
207−> ? y:a
208− {p/$foo q/@rs r/@dr}
209−[p=%foo q=.6.28 r=~m45]
182+ > ? y:a
183+ {p/$foo q/@rs r/@dr}
184+ [p=%foo q=.6.28 r=~m45]
210185
211−> ? q.y:a
212− @rs
213−.6.28
214−```
186+ > ? q.y:a
187+ @rs
188+ .6.28
215189
216−Surfaces might remind you of attributes in an object. But again,
217−attributes in an object are a symbol table. There is no symbol
218−table here -- just a tree search.
190+Surfaces might remind you of attributes in an object. But again, attributes in
191+an object are a symbol table. There is no symbol table here -- just a tree
192+search.
219193
220−An expression like the label `x` or the axis `+2`, which
221−designates a fragment or feature of the subject, is called a
222−*limb*. A list of limbs connected with `.` is a *wing*.
194+An expression like the label `x` or the axis `+2`, which designates a fragment
195+or feature of the subject, is called a *limb*. A list of limbs connected with
196+`.` is a *wing*.
223197
224−To remind you that you're not in Kansas anymore, the syntax for a
225−wing, like `q.y` above, means means "q inside y." In a classic
226−object-oriented system, of course, this would be written `y.q`,
227−that is, attribute `q` within object `y`. In Hoon, `q.y` means
228−"find limb `y`, then find limb `q` inside that."
198+To remind you that you're not in Kansas anymore, the syntax for a wing, like
199+`q.y` above, means means "q inside y." In a classic object-oriented system, of
200+course, this would be written `y.q`, that is, attribute `q` within object `y`.
201+In Hoon, `q.y` means "find limb `y`, then find limb `q` inside that."
229202
230203## Surfaces versus fragments
231204
232−Once again, Hoon has no symbol tables. When we put a surface
233−on a noun, the surface label is part of that noun's type. It's
234−not part of the cell or other structure that contains the noun.
235−This will take a little getting used to:
205+Once again, Hoon has no symbol tables. When we put a surface on a noun, the
206+surface label is part of that noun's type. It's not part of the cell or other
207+structure that contains the noun. This will take a little getting used to:
236208
237−```
238−> ? x:a
239− @ud
240−42
209+ > ? x:a
210+ @ud
211+ 42
241212
242−> ? +2:a
243− x/@ud
244−x=42
213+ > ? +2:a
214+ x/@ud
215+ x=42
245216
246−? x.+2:a
247− @ud
248−42
249−```
217+ ? x.+2:a
218+ @ud
219+ 42
250220
251−When we take fragment 2 of the labeled subject, the *surface
252−comes with it*. `+2` is not `42` but rather `x=42`. We can
253−take the surface off with `x.+2`.
221+When we take fragment 2 of the labeled subject, the *surface comes with it*.
222+`+2` is not `42` but rather `x=42`. We can take the surface off with `x.+2`.
254223
255224## The search algorithm
256225
257−In resolving a label to a fragment axis, we search the subject
258−type in a depth-first traverse.
226+In resolving a label to a fragment axis, we search the subject type in a
227+depth-first traverse.
259228
260−If we find a surface that matches the limb, we succeed. If we
261−find a surface that doesn't match the limb, we fail. If we find
262−a cell, we search first head, then tail.
229+If we find a surface that matches the limb, we succeed. If we find a surface
230+that doesn't match the limb, we fail. If we find a cell, we search first head,
231+then tail.
263232
264233## Skipping
265234
266−What if the same label appears twice in one noun? Let's modify
267−our subject slightly as a test case:
235+What if the same label appears twice in one noun? Let's modify our subject
236+slightly as a test case:
268237
269−```
270−> ? +7:a
271− z/@ux
272−z=0xdead.beef
238+ > ? +7:a
239+ z/@ux
240+ z=0xdead.beef
273241
274−> =a a(+7 x=z:a)
242+ > =a a(+7 x=z:a)
275243
276−> ? a
277− {x/@ud y/{p/$foo q/@rs r/@dr} x/@ux}
278−[x=42 y=[p=%foo q=.6.28 r=~m45] x=0xdead.beef]
244+ > ? a
245+ {x/@ud y/{p/$foo q/@rs r/@dr} x/@ux}
246+ [x=42 y=[p=%foo q=.6.28 r=~m45] x=0xdead.beef]
279247
280−> ? x:a
281− @ud
282−42
248+ > ? x:a
249+ @ud
250+ 42
283251
284−> ? ^x:a
285− @ux
286−0xdead.beef
287−```
252+ > ? ^x:a
253+ @ux
254+ 0xdead.beef
288255
289−We don't want to hide any part of the noun from an expression.
290−So the modified limb `^x` *skips* the first match with a surface
291−`x`, getting us to our `0xdead.beef`. This is a unary notation:
292−`^^x` would skip the first two matches.
256+We don't want to hide any part of the noun from an expression. So the modified
257+limb `^x` *skips* the first match with a surface `x`, getting us to our
258+`0xdead.beef`. This is a unary notation: `^^x` would skip the first two matches.
293259
294260## Editing
295261
296262Above, we mutated our first noun with the flashy `a(+7 x=z:a)`.
297263
298−Of course we are not really "modifying" a noun. Hoon is a pure
299−language. We are making an edited copy. `a(+7 x=z:a)` means "a
300−copy of `a`, with limb `+7` replaced by the product of `x=z:a`."
264+Of course we are not really "modifying" a noun. Hoon is a pure language. We are
265+making an edited copy. `a(+7 x=z:a)` means "a copy of `a`, with limb `+7`
266+replaced by the product of `x=z:a`."
301267
302268We can edit multiple (disjoint) wings in one expression:
303269
304−```
305−> ? a(+7 [%hello %world], q.y .3.14)
306− {x/@ud y/{p/$foo q/@rs r/@dr} $hello $world}
307−[x=42 y=[p=%foo q=.3.14 r=~m45] %hello %world]
308−```
270+ > ? a(+7 [%hello %world], q.y .3.14)
271+ {x/@ud y/{p/$foo q/@rs r/@dr} $hello $world}
272+ [x=42 y=[p=%foo q=.3.14 r=~m45] %hello %world]
309273
310−Notice that nothing stopped us from changing `+7` from
311−`x=0xdead.beef` to `[%hello %world]`. Since the mutated
312−copy is a different noun, it has a different type.
274+Notice that nothing stopped us from changing `+7` from `x=0xdead.beef` to
275+`[%hello %world]`. Since the mutated copy is a different noun, it has a
276+different type.
313277
314−(And remember that since `[x y z]` means `[x [y z]]`,
315−`[x y [%hello %world]]` means `[x y %hello %world]`.)
278+(And remember that since `[x y z]` means `[x [y z]]`, `[x y [%hello %world]]`
279+means `[x y %hello %world]`.)
316280
317281## Cores and arms
318282
319−It should be reasonably clear how Hoon's system of fragments and
320−surfaces parallels variables, records or structures in a
321−classical language. But where is Hoon's equivalent of objects:
322−values which bind code to data?
283+It should be reasonably clear how Hoon's system of fragments and surfaces
284+parallels variables, records or structures in a classical language. But where is
285+Hoon's equivalent of objects: values which bind code to data?
323286
324−The Hoon equivalent of an object is a *core*. As usual in Hoon,
325−the resemblance is inexact. A core has a set of computed
326−attributes, or *arms*. Each arm is an expression whose subject
327−is the core. There is no argument, so an arm is not a method.
287+The Hoon equivalent of an object is a *core*. As usual in Hoon, the resemblance
288+is inexact. A core has a set of computed attributes, or *arms*. Each arm is an
289+expression whose subject is the core. There is no argument, so an arm is not a
290+method.
328291
329−Physically, a core is always a cell `[battery payload]`, where
330−the *payload* is any noun, and the *battery* is a tree of
331−formulas in Nock (Hoon's functional assembly language) that
332−implements the arms. (A battery is like a C++ vtable, sort of.)
292+Physically, a core is always a cell `[battery payload]`, where the *payload* is
293+any noun, and the *battery* is a tree of formulas in Nock (Hoon's functional
294+assembly language) that implements the arms. (A battery is like a C++ vtable,
295+sort of.)
333296
334297## The search algorithm
335298
336−As you'd expect with a computed attribute, there is only one
337−namespace and one search algorithm. We just extend the algorithm
338−described above. And an expression which uses a label can't know
339−whether the subject will resolve it to a surface fragment (a
340−*leg*) or to an arm.
299+As you'd expect with a computed attribute, there is only one namespace and one
300+search algorithm. We just extend the algorithm described above. And an
301+expression which uses a label can't know whether the subject will resolve it to
302+a surface fragment (a *leg*) or to an arm.
341303
342−If we're searching a core and the label matches one of the core's
343−arms, we compute the arm against the core. If the label is not
344−found, we search into the payload of the core.
304+If we're searching a core and the label matches one of the core's arms, we
305+compute the arm against the core. If the label is not found, we search into the
306+payload of the core.
345307
346308## Some core examples
347309
348−When you type these examples, make sure you get the number of
349−spaces exactly right. Hoon syntax is not whitespace-sensitive
350−in general, except that "one space" is always a different token
351−from "two or more spaces."
310+When you type these examples, make sure you get the number of spaces exactly
311+right. Hoon syntax is not whitespace-sensitive in general, except that "one
312+space" is always a different token from "two or more spaces."
352313
353−```
354−> ? x:a
355− @ud
356−42
314+ > ? x:a
315+ @ud
316+ 42
357317
358−> ? :per a x
359− @ud
360−42
318+ > ? :per a x
319+ @ud
320+ 42
361321
362−> =b :per a :core ++ foo x ++ bar [q.y foo] --
363−```
322+ > =b :per a :core ++ foo x ++ bar [q.y foo] --
364323
365−We're seeing some Hoon regular forms for the first time. `x:a`
366−turns out to be an irregular relative of the regular `:per` form.
324+We're seeing some Hoon regular forms for the first time. `x:a` turns out to be
325+an irregular relative of the regular `:per` form.
367326
368−We'll get more into syntax in a later Urbyte. If some of these
369−examples seem syntactically a little funky, this isn't usually
370−way we'd do them in "real life." We don't normally write cores
371−on a single command line. In a file this would be:
327+We'll get more into syntax in a later Urbyte. If some of these examples seem
328+syntactically a little funky, this isn't usually way we'd do them in "real
329+life." We don't normally write cores on a single command line. In a file this
330+would be:
372331
373−```
374− :per a
375− :core
376− ++ foo x
377− ++ bar [q.y foo]
378− --
379−```
332+ :per a
333+ :core
334+ ++ foo x
335+ ++ bar [q.y foo]
336+ --
380337
381−which is much more readable, at least once you get used to it.
382−Let's look at the core itself:
338+which is much more readable, at least once you get used to it. Let's look at the
339+core itself:
383340
384−```
385−> b
386−<2.spy {x/@ud y/{p/$foo q/@rs r/@dr} x/@ux}>
341+ > b
342+ <2.spy {x/@ud y/{p/$foo q/@rs r/@dr} x/@ux}>
387343
388−> ? +2:b
389− *
390−[[0 6] [0 58] 9 4 0 1]
344+ > ? +2:b
345+ *
346+ [[0 6] [0 58] 9 4 0 1]
391347
392−> ? +3:b
393− {x/@ud y/{p/$foo q/@rs r/@dr} x/@ux}
394−[x=42 y=[p=%foo q=.6.28 r=~m45] x=0xdead.beef]
395−```
348+ > ? +3:b
349+ {x/@ud y/{p/$foo q/@rs r/@dr} x/@ux}
350+ [x=42 y=[p=%foo q=.6.28 r=~m45] x=0xdead.beef]
396351
397−When we print `b`, or any core, we see that typed noun printing
398−can't be an invertible function in Hoon.
352+When we print `b`, or any core, we see that typed noun printing can't be an
353+invertible function in Hoon.
399354
400−We actually can read the battery (with `+2:b` above), but it's
401−just Nock code, not typed data. `<2.spy>` tells us the battery
402−has two arms and hashes to the three-letter code `spy`.
355+We actually can read the battery (with `+2:b` above), but it's just Nock code,
356+not typed data. `<2.spy>` tells us the battery has two arms and hashes to the
357+three-letter code `spy`.
403358
404−When printing a full core, we don't even print the payload data,
405−just its type. But our `+3:b` confirms the `[battery payload]`
406−structure of the core. Remember, `+2` is the head and `+3` is
407−the tail.
359+When printing a full core, we don't even print the payload data, just its type.
360+But our `+3:b` confirms the `[battery payload]` structure of the core. Remember,
361+`+2` is the head and `+3` is the tail.
408362
409363Finally, let's use this thing:
410364
411−```
412−> ? foo:b
413− @ud
414−42
365+ > ? foo:b
366+ @ud
367+ 42
415368
416−> ? bar:b
417− {@rs @ud}
418−[.6.28 42]
369+ > ? bar:b
370+ {@rs @ud}
371+ [.6.28 42]
419372
420−? x:b
421− @ud
422−42
423−```
373+ ? x:b
374+ @ud
375+ 42
424376
425377Seems legit.
426378
427379## The dojo subject
428380
429−Now that we've made a test subject which is a core, we can look
430−directly at the real dojo subject:
431−
432−```
433−> +1
434−[ [ [ a=[x=42 y=[p=%foo q=.6.28 r=~m45] x=0xdead.beef]
435− b=<2.spy {x/@ud y/{p/$foo q/@rs r/@dr} x/@ux}>
381+Now that we've made a test subject which is a core, we can look directly at the
382+real dojo subject:
383+
384+ > +1
385+ [ [ [ a=[x=42 y=[p=%foo q=.6.28 r=~m45] x=0xdead.beef]
386+ b=<2.spy {x/@ud y/{p/$foo q/@rs r/@dr} x/@ux}>
387+ ]
388+ now=~2016.7.18..08.05.15..0b5c
389+ eny=0vl.hsfrh.tg642.g5o21.1n80b.0h141.0vuan.pm8o4.77ovg.96rk0.n26nn
390+ our=~palnul-wolmev-bonfex-danred--tilwen-midlux-bolfus-nocser
391+ ]
392+ ~
393+ <283.xzp 42.ajz 407.xtr 110.xht 1.ztu $151>
436394 ]
437− now=~2016.7.18..08.05.15..0b5c
438− eny=0vl.hsfrh.tg642.g5o21.1n80b.0h141.0vuan.pm8o4.77ovg.96rk0.n26nn
439− our=~palnul-wolmev-bonfex-danred--tilwen-midlux-bolfus-nocser
440− ]
441− ~
442− <283.xzp 42.ajz 407.xtr 110.xht 1.ztu $151>
443−]
444−```
445−
446−We see a bunch of surfaces: our custom `a` and `b`; standard
447−surfaces for identity, date, and entropy; and a ginormous core
448−stack with *over eight hundred* total arms.
449−
450−To be exact, the syntax `<283.xzp 42.ajz 407.xtr 110.xht 1.ztu
451−$151>` denotes a stack of six cores, each of whose payload is
452−another core, until the innermost payload `%151` (the Hoon
453−version number). This stack is our standard library, from which
454−comes `add` and other fine functions. (We don't know how to
455−write a Hoon function yet, but we're getting way closer.)
395+
396+We see a bunch of surfaces: our custom `a` and `b`; standard surfaces for
397+identity, date, and entropy; and a ginormous core stack with *over eight
398+hundred* total arms.
399+
400+To be exact, the syntax `<283.xzp 42.ajz 407.xtr 110.xht 1.ztu $151>` denotes a
401+stack of six cores, each of whose payload is another core, until the innermost
402+payload `%151` (the Hoon version number). This stack is our standard library,
403+from which comes `add` and other fine functions. (We don't know how to write a
404+Hoon function yet, but we're getting way closer.)
456405
457406Let's clean up our subject, just to be hygienic:
458407
459−```
460−> =a
461−> =b
408+ > =a
409+ > =b
462410
463−> +1
464− now=~2016.7.18..08.10.42..36a0
465− eny=0vf.8j71j.hlqim.k340u.q0ual.v2cd8.cfa65.vkbte.e733g.ehihg.e8aog
466−[ [ our=~palnul-wolmev-bonfex-danred--tilwen-midlux-bolfus-nocser
467− ]
468− ~
469− <283.xzp 42.ajz 407.xtr 110.xht 1.ztu $151>
470−]
471−```
411+ > +1
412+ now=~2016.7.18..08.10.42..36a0
413+ eny=0vf.8j71j.hlqim.k340u.q0ual.v2cd8.cfa65.vkbte.e733g.ehihg.e8aog
414+ [ [ our=~palnul-wolmev-bonfex-danred--tilwen-midlux-bolfus-nocser
415+ ]
416+ ~
417+ <283.xzp 42.ajz 407.xtr 110.xht 1.ztu $151>
418+ ]
472419
473−Again, remember that `=a` is not Hoon syntax, but `:dojo` syntax.
474−How the dojo assembles this subject remains a mystery. But it's
475−not a particularly interesting mystery.
420+Again, remember that `=a` is not Hoon syntax, but `:dojo` syntax. How the dojo
421+assembles this subject remains a mystery. But it's not a particularly
422+interesting mystery.
476423
477424## And we're done
478425
479−And we're done! Type `|exit` to exit:
426+And we're done! Type `|exit` to exit:
480427
481−```
482−~palnul_nocser:dojo> |exit
483−%drum-exit
484−$
485−```
428+ ~palnul_nocser:dojo> |exit
429+ %drum-exit
430+ $
486431
487432## Questions and/or exercises
488433
489434As always, these questions are optional and only for fun.
490435
491−What's the best way to construct a core which acts as a function?
492−What do you do to call the function?
436+What's the best way to construct a core which acts as a function? What do you do
437+to call the function?
493438
494−Why don't any other languages use subject-oriented programming?
495−Which languages are most similar to it?
439+Why don't any other languages use subject-oriented programming? Which languages
440+are most similar to it?
docs/community-docs.md+20−21
@@ -1,31 +1,30 @@
11---
2−navhome: /docs/
2+navhome: '/docs/'
33sort: 7
44---
55
6−
76# Community docs
87
98<div>
10−
119<ul>
12−
13−<li><code>~master-morzod</code>
14−<br />
15−<a href="https://mardev.urbit.org/docs/">docs</a>, <code>fora</code> <a href="https://urbit.org/fora/posts/~2016.12.25..06.35.44..a1ec~/">post</a></li>
16−
17−<li><code>~hidduc-posmeg</code>
18−<br />
19−<a href="https://fosnut-dandut.urbit.org/pages/hidducs-notes/tutorial/">docs</a>, <code>fora</code> <a href="https://urbit.org/fora/posts/~2017.2.12..21.54.40..6fde~/">post</a></li>
20−
21−<li><code>~palfun-foslup</code>
22−<br />
23−<a href="https://github.com/Fang-/Urbit-By-Doing">Urbit by Doing</a></li>
24−
25−<li><code>@knubie</code>
26−<br />
27−<a href="https://github.com/knubie/learning-hoon">Learning Hoon</a></li>
28−
10+<li>
11+<code>~master-morzod</code> <br />
12+<a href="https://mardev.urbit.org/docs/">docs</a>, <code>fora</code>
13+<a href="https://urbit.org/fora/posts/~2016.12.25..06.35.44..a1ec~/">post</a>
14+</li>
15+<li>
16+<code>~hidduc-posmeg</code> <br />
17+<a href="https://fosnut-dandut.urbit.org/pages/hidducs-notes/tutorial/">docs</a>,
18+<code>fora</code>
19+<a href="https://urbit.org/fora/posts/~2017.2.12..21.54.40..6fde~/">post</a>
20+</li>
21+<li>
22+<code>~palfun-foslup</code> <br />
23+<a href="https://github.com/Fang-/Urbit-By-Doing">Urbit by Doing</a>
24+</li>
25+<li>
26+<code>@knubie</code> <br />
27+<a href="https://github.com/knubie/learning-hoon">Learning Hoon</a>
28+</li>
2929</ul>
30−
3130</div>
docs/community-projects.md+15−19
@@ -1,30 +1,26 @@
11---
2−navhome: /docs/
2+navhome: '/docs/'
33sort: 8
44---
55
6−
76# Community projects
87
98<div>
10−
119<ul>
12−
13−<li><a href="https://github.com/ponnys-podfer/yint">Yint: A Tiny MUD</a>
14−<br />
15−<code>~ponnys-podfer</code></li>
16−
17−<li><a href="https://github.com/Fang-/talkbot">~talkbot</a>
18−<br />
19−<code>~palfun-foslup</code></li>
20−
21−<li><a href="https://github.com/Fang-/urbit-string">String processing</a>
22−<br />
23−<code>~palfun-foslup</code></li>
24−
25−<li><a href="community-projects/nock-implementations">Nock implementations</a>
10+<li>
11+<a href="https://github.com/ponnys-podfer/yint">Yint: A Tiny MUD</a> <br />
12+<code>~ponnys-podfer</code>
13+</li>
14+<li>
15+<a href="https://github.com/Fang-/talkbot">~talkbot</a> <br />
16+<code>~palfun-foslup</code>
17+</li>
18+<li>
19+<a href="https://github.com/Fang-/urbit-string">String processing</a> <br />
20+<code>~palfun-foslup</code>
21+</li>
22+<li>
23+<a href="community-projects/nock-implementations">Nock implementations</a>
2624</li>
27−
2825</ul>
29−
3026</div>
docs/community-projects/nock-implementations.md+2−2
@@ -1,8 +1,8 @@
11---
2−navhome: /docs/
2+navhome: '/docs/'
3+next: True
34sort: 4
45title: Nock implementations
5−next: true
66---
77
88# Community Nock implementations
docs/community-projects/nock-implementations/clojure.md+117−118
@@ -1,125 +1,124 @@
11---
2−navhome: /docs/
3−title: Clojure
2+navhome: '/docs/'
3+next: True
44sort: 5
5−next: true
5+title: Clojure
66---
77
88# Clojure
99
10−From [Matt Earnshaw](https://github.com/mattearnshaw/anock/blob/master/src/anock/core.clj):
11−
12−```
13−(ns anock.core
14− (:import anock.NockException))
15−
16−(declare atom? cell? cell)
17−
18−(defn noun?
19− "A noun is an atom or a cell."
20− [noun & ns]
21− (if ns false
22− (or (atom? noun) (cell? noun))))
23−
24−(defn atom?
25− "An atom is a natural number."
26− [noun & ns]
27− (if ns false
28− (and (integer? noun) (>= noun 0))))
29−
30−(defn cell?
31− "A cell is an ordered pair of nouns."
32− [noun]
33− (cond
34− (atom? noun) false
35− (nil? noun) false
36− (not= 2 (count noun)) false
37− :else (and (noun? (first noun))
38− (noun? (second noun)))))
39−
40−(defn tis
41− "= (pronounced 'tis') tests a cell for equality."
42− [noun]
43− (if (atom? noun) (throw (anock.NockException. "Cannot tis an atom."))
44− (let [[a b] noun]
45− (if (= a b) 0 1))))
46−
47−(defn wut
48− "? (pronounced 'wut') tests whether a noun is a cell."
49− [noun]
50− (cond
51− (atom? noun) 1
52− (cell? noun) 0
53− :else (throw (anock.NockException. "Invalid noun."))))
54−
55−(defn lus
56− "+ (pronounced 'lus') adds 1 to an atom."
57− [noun]
58− (if (atom? noun) (inc noun)
59− (throw (anock.NockException. "Can only lus atoms."))))
60−
61−(defn fas
62− "/ (pronounced 'fas') is a tree address function."
63− [noun]
64− (if (atom? noun) (throw (anock.NockException. "Cannot fas an atom."))
65− (let [[a b] (cell noun)]
66− (assert (and (pos? a) (atom? a)) "Subject of fas must be a positive atom.")
67− (if (and (not (coll? b)) (or (= 2 a) (= 3 a)))
68− (throw (anock.NockException. (str "Cannot fas noun: " noun))))
10+From [Matt
11+Earnshaw](https://github.com/mattearnshaw/anock/blob/master/src/anock/core.clj):
12+
13+ (ns anock.core
14+ (:import anock.NockException))
15+
16+ (declare atom? cell? cell)
17+
18+ (defn noun?
19+ "A noun is an atom or a cell."
20+ [noun & ns]
21+ (if ns false
22+ (or (atom? noun) (cell? noun))))
23+
24+ (defn atom?
25+ "An atom is a natural number."
26+ [noun & ns]
27+ (if ns false
28+ (and (integer? noun) (>= noun 0))))
29+
30+ (defn cell?
31+ "A cell is an ordered pair of nouns."
32+ [noun]
33+ (cond
34+ (atom? noun) false
35+ (nil? noun) false
36+ (not= 2 (count noun)) false
37+ :else (and (noun? (first noun))
38+ (noun? (second noun)))))
39+
40+ (defn tis
41+ "= (pronounced 'tis') tests a cell for equality."
42+ [noun]
43+ (if (atom? noun) (throw (anock.NockException. "Cannot tis an atom."))
44+ (let [[a b] noun]
45+ (if (= a b) 0 1))))
46+
47+ (defn wut
48+ "? (pronounced 'wut') tests whether a noun is a cell."
49+ [noun]
50+ (cond
51+ (atom? noun) 1
52+ (cell? noun) 0
53+ :else (throw (anock.NockException. "Invalid noun."))))
54+
55+ (defn lus
56+ "+ (pronounced 'lus') adds 1 to an atom."
57+ [noun]
58+ (if (atom? noun) (inc noun)
59+ (throw (anock.NockException. "Can only lus atoms."))))
60+
61+ (defn fas
62+ "/ (pronounced 'fas') is a tree address function."
63+ [noun]
64+ (if (atom? noun) (throw (anock.NockException. "Cannot fas an atom."))
65+ (let [[a b] (cell noun)]
66+ (assert (and (pos? a) (atom? a)) "Subject of fas must be a positive atom.")
67+ (if (and (not (coll? b)) (or (= 2 a) (= 3 a)))
68+ (throw (anock.NockException. (str "Cannot fas noun: " noun))))
69+ (cond
70+ (= 1 a) b
71+ (= 2 a) (first b)
72+ (= 3 a) (second b)
73+ (even? a) (fas [2 (fas [(/ a 2) b])])
74+ (odd? a) (fas [3 (fas [(/ (dec a) 2) b])])))))
75+
76+ (defn tar
77+ "* (pronounced 'tar') means Nock"
78+ [noun]
79+ (if (atom? noun) (throw (anock.NockException. "Cannot tar an atom."))
80+ (try
81+ (let [noun (cell noun) [x [y z]] noun]
82+ (cond
83+ (cell? y) (cell (tar [x y]) (tar [x z]))
84+ (zero? y) (fas [z x])
85+ (= 1 y) z
86+ (= 3 y) (wut (tar [x z]))
87+ (= 4 y) (lus (tar [x z]))
88+ (= 5 y) (tis (tar [x z]))
89+ :else (let [[p q] z]
90+ (cond
91+ (= 2 y) (tar [(tar [x p]) (tar [x q])])
92+ (= 6 y) (tar [x 2 [0 1] 2 [1 (first q) (second q)]
93+ [1 0] 2 [1 2 3] [1 0] 4 4 p])
94+ (= 7 y) (tar [x 2 p 1 q])
95+ (= 8 y) (tar [x 7 [[7 [0 1] p] 0 1] q])
96+ (= 9 y) (tar [x 7 q 2 [0 1] 0 p])
97+ (= 10 y) (if (cell? p)
98+ (tar [x 8 (second p) 7 [0 3] q])
99+ (tar [x q]))))))
100+ (catch RuntimeException e
101+ (throw (anock.NockException. (str "Cannot tar the noun " noun)))))))
102+
103+ (def nock tar)
104+
105+ ; Some convenience functions
106+ (defn apply* [f x]
107+ (if (and (= 1 (count x)) (coll? (first x)))
108+ (apply f x)
109+ (f x)))
110+
111+ (defn bracket
112+ "[a b c] -> [a [b c]]"
113+ [[a & b :as c]]
114+ (let [b (vec b)]
69115 (cond
70− (= 1 a) b
71− (= 2 a) (first b)
72− (= 3 a) (second b)
73− (even? a) (fas [2 (fas [(/ a 2) b])])
74− (odd? a) (fas [3 (fas [(/ (dec a) 2) b])])))))
75−
76−(defn tar
77− "* (pronounced 'tar') means Nock"
78− [noun]
79− (if (atom? noun) (throw (anock.NockException. "Cannot tar an atom."))
80− (try
81− (let [noun (cell noun) [x [y z]] noun]
82− (cond
83− (cell? y) (cell (tar [x y]) (tar [x z]))
84− (zero? y) (fas [z x])
85− (= 1 y) z
86− (= 3 y) (wut (tar [x z]))
87− (= 4 y) (lus (tar [x z]))
88− (= 5 y) (tis (tar [x z]))
89− :else (let [[p q] z]
90− (cond
91− (= 2 y) (tar [(tar [x p]) (tar [x q])])
92− (= 6 y) (tar [x 2 [0 1] 2 [1 (first q) (second q)]
93− [1 0] 2 [1 2 3] [1 0] 4 4 p])
94− (= 7 y) (tar [x 2 p 1 q])
95− (= 8 y) (tar [x 7 [[7 [0 1] p] 0 1] q])
96− (= 9 y) (tar [x 7 q 2 [0 1] 0 p])
97− (= 10 y) (if (cell? p)
98− (tar [x 8 (second p) 7 [0 3] q])
99− (tar [x q]))))))
100− (catch RuntimeException e
101− (throw (anock.NockException. (str "Cannot tar the noun " noun)))))))
102−
103−(def nock tar)
104−
105−; Some convenience functions
106−(defn apply* [f x]
107− (if (and (= 1 (count x)) (coll? (first x)))
108− (apply f x)
109− (f x)))
110−
111−(defn bracket
112− "[a b c] -> [a [b c]]"
113− [[a & b :as c]]
114− (let [b (vec b)]
115− (cond
116− (and (noun? a) (apply noun? b)) (vec c)
117− (apply noun? b) (apply vector (bracket a) b)
118− (noun? a) [a (apply* bracket b)]
119− :else [(bracket a) (apply* bracket b)])))
120−
121−(defn cell [& nouns]
122− (if (apply atom? nouns)
123− (throw (anock.NockException. "Cannot convert atom to cell."))
124− (apply* bracket nouns)))
125−```
116+ (and (noun? a) (apply noun? b)) (vec c)
117+ (apply noun? b) (apply vector (bracket a) b)
118+ (noun? a) [a (apply* bracket b)]
119+ :else [(bracket a) (apply* bracket b)])))
120+
121+ (defn cell [& nouns]
122+ (if (apply atom? nouns)
123+ (throw (anock.NockException. "Cannot convert atom to cell."))
124+ (apply* bracket nouns)))
docs/community-projects/nock-implementations/csharp.md+377−379

This diff is too big to show here.

docs/community-projects/nock-implementations/groovy.md+177−178

This diff is too big to show here.

docs/community-projects/nock-implementations/haskell.md+56−57

This diff is too big to show here.

docs/community-projects/nock-implementations/hoon.md+47−49

This diff is too big to show here.

docs/community-projects/nock-implementations/javascript.md+355−357

This diff is too big to show here.

docs/community-projects/nock-implementations/python.md+75−77

This diff is too big to show here.

docs/community-projects/nock-implementations/ruby.md+130−131

This diff is too big to show here.

docs/community-projects/nock-implementations/scala.md+68−69

This diff is too big to show here.

docs/community-projects/nock-implementations/scheme.md+112−113

This diff is too big to show here.

docs/community-projects/nock-implementations/swift.md+317−319

This diff is too big to show here.

docs/community-projects/string-processing.md+6−8

This diff is too big to show here.

docs/community-projects/talkbot.md+4−13

This diff is too big to show here.

docs/community-projects/yint.md+4−13

This diff is too big to show here.

docs/hoon.md+3−3

This diff is too big to show here.

docs/hoon/advanced.md+140−159

This diff is too big to show here.

docs/hoon/basic.md+123−139

This diff is too big to show here.

docs/hoon/concepts.md+134−154

This diff is too big to show here.

docs/hoon/demo.md+43−47

This diff is too big to show here.

docs/hoon/examples.md+453−512

This diff is too big to show here.

docs/hoon/exercises.md+6−7

This diff is too big to show here.

docs/hoon/exercises/data-structures.md+30−40

This diff is too big to show here.

docs/hoon/exercises/fizzbuzz.md+25−28

This diff is too big to show here.

docs/hoon/exercises/life.md+94−110

This diff is too big to show here.

docs/hoon/exercises/lists.md+22−27

This diff is too big to show here.

docs/hoon/exercises/math.md+12−17

This diff is too big to show here.

docs/hoon/irregular.md+114−95

This diff is too big to show here.

docs/hoon/library.md+1−1

This diff is too big to show here.

docs/hoon/library/1a.md+65−123

This diff is too big to show here.

docs/hoon/library/1b.md+21−37

This diff is too big to show here.

docs/hoon/library/1c.md+51−103

This diff is too big to show here.

docs/hoon/library/2a.md+75−141

This diff is too big to show here.

docs/hoon/library/2b.md+191−347

This diff is too big to show here.

docs/hoon/library/2c.md+74−150

This diff is too big to show here.

docs/hoon/library/2d.md+25−49

This diff is too big to show here.

docs/hoon/library/2e.md+22−41

This diff is too big to show here.

docs/hoon/library/2f.md+29−63

This diff is too big to show here.

docs/hoon/library/2g.md+1−2

This diff is too big to show here.

docs/hoon/library/2h.md+77−152

This diff is too big to show here.

docs/hoon/library/2i.md+46−55

This diff is too big to show here.

docs/hoon/library/2j.md+17−24

This diff is too big to show here.

docs/hoon/library/2k.md+46−84

This diff is too big to show here.

docs/hoon/library/2l.md+1−2

This diff is too big to show here.

docs/hoon/library/2m.md+1−2

This diff is too big to show here.

docs/hoon/library/2n.md+26−54

This diff is too big to show here.

docs/hoon/library/2o.md+21−44

This diff is too big to show here.

docs/hoon/library/2p.md+30−52

This diff is too big to show here.

docs/hoon/library/2q.md+49−85

This diff is too big to show here.

docs/hoon/library/3a.md+116−205

This diff is too big to show here.

docs/hoon/library/3b.md+1−2

This diff is too big to show here.

docs/hoon/library/3c.md+99−167

This diff is too big to show here.

docs/hoon/library/3d.md+13−31

This diff is too big to show here.

docs/hoon/library/3e.md+4−8

This diff is too big to show here.

docs/hoon/library/3f.md+108−182

This diff is too big to show here.

docs/hoon/library/3g.md+49−96

This diff is too big to show here.

docs/hoon/library/4a.md+30−52

This diff is too big to show here.

docs/hoon/library/4b.md+97−190

This diff is too big to show here.

docs/hoon/library/4c.md+33−66

This diff is too big to show here.

docs/hoon/library/4d.md+14−27

This diff is too big to show here.

docs/hoon/library/4e.md+70−136

This diff is too big to show here.

docs/hoon/library/4f.md+148−286

This diff is too big to show here.

docs/hoon/library/4g.md+24−47

This diff is too big to show here.

docs/hoon/library/4h.md+110−210

This diff is too big to show here.

docs/hoon/library/4i.md+1−2

This diff is too big to show here.

docs/hoon/library/4j.md+310−545

This diff is too big to show here.

docs/hoon/library/4k.md+138−267

This diff is too big to show here.

docs/hoon/library/4l.md+75−157

This diff is too big to show here.

docs/hoon/library/4m.md+57−111

This diff is too big to show here.

docs/hoon/library/4n.md+54−97

This diff is too big to show here.

docs/hoon/library/4o.md+107−182

This diff is too big to show here.

docs/hoon/library/5a.md+1−2

This diff is too big to show here.

docs/hoon/library/5b.md+1−2

This diff is too big to show here.

docs/hoon/library/5c.md+1−2

This diff is too big to show here.

docs/hoon/library/5d.md+1−2

This diff is too big to show here.

docs/hoon/library/5e.md+1−2

This diff is too big to show here.

docs/hoon/library/5f.md+31−61

This diff is too big to show here.

docs/hoon/library/5g.md+1−1

This diff is too big to show here.

docs/hoon/library/zuse.md+1−1

This diff is too big to show here.

docs/hoon/library/zuse/core/crua.md+1−6

This diff is too big to show here.

docs/hoon/library/zuse/core/epur.md+107−213

This diff is too big to show here.

docs/hoon/library/zuse/core/fu.md+2−5

This diff is too big to show here.

docs/hoon/library/zuse/core/jo.md+131−239

This diff is too big to show here.

docs/hoon/library/zuse/core/poja.md+114−209

This diff is too big to show here.

docs/hoon/library/zuse/core/poxa.md+50−99

This diff is too big to show here.

docs/hoon/library/zuse/core/poxo.md+25−52

This diff is too big to show here.

docs/hoon/library/zuse/core/yu.md+23−35

This diff is too big to show here.

docs/hoon/library/zuse/diff.md+82−143

This diff is too big to show here.

docs/hoon/library/zuse/gate/clan.md+5−12

This diff is too big to show here.

docs/hoon/library/zuse/gate/dawn.md+7−14

This diff is too big to show here.

docs/hoon/library/zuse/gate/daws.md+5−12

This diff is too big to show here.

docs/hoon/library/zuse/gate/deal.md+5−12

This diff is too big to show here.

docs/hoon/library/zuse/gate/deft.md+7−14

This diff is too big to show here.

docs/hoon/library/zuse/gate/dust.md+5−12

This diff is too big to show here.

docs/hoon/library/zuse/gate/earl.md+5−12

This diff is too big to show here.

docs/hoon/library/zuse/gate/earn.md+20−38

This diff is too big to show here.

docs/hoon/library/zuse/gate/fain.md+7−14

This diff is too big to show here.

docs/hoon/library/zuse/gate/feel.md+6−14

This diff is too big to show here.

docs/hoon/library/zuse/gate/file.md+6−14

This diff is too big to show here.

docs/hoon/library/zuse/gate/foal.md+7−14

This diff is too big to show here.

docs/hoon/library/zuse/gate/fray.md+7−14

This diff is too big to show here.

docs/hoon/library/zuse/gate/fuel.md+5−12

This diff is too big to show here.

docs/hoon/library/zuse/gate/furl.md+7−14

This diff is too big to show here.

docs/hoon/library/zuse/gate/glam.md+4−10

This diff is too big to show here.

docs/hoon/library/zuse/gate/glon.md+4−10

This diff is too big to show here.

docs/hoon/library/zuse/gate/gnom.md+4−10

This diff is too big to show here.

docs/hoon/library/zuse/gate/jape.md+5−12

This diff is too big to show here.

docs/hoon/library/zuse/gate/jesc.md+7−13

This diff is too big to show here.

docs/hoon/library/zuse/gate/joba.md+5−12

This diff is too big to show here.

docs/hoon/library/zuse/gate/jobe.md+5−12

This diff is too big to show here.

docs/hoon/library/zuse/gate/jone.md+5−12

This diff is too big to show here.

docs/hoon/library/zuse/gate/lead.md+6−14

This diff is too big to show here.

docs/hoon/library/zuse/gate/mang.md+7−15

This diff is too big to show here.

docs/hoon/library/zuse/gate/meat.md+5−12

This diff is too big to show here.

docs/hoon/library/zuse/gate/moon.md+6−14

This diff is too big to show here.

docs/hoon/library/zuse/gate/mung.md+7−14

This diff is too big to show here.

docs/hoon/library/zuse/gate/perk.md+16−23

This diff is too big to show here.

docs/hoon/library/zuse/gate/pojo.md+5−12

This diff is too big to show here.

docs/hoon/library/zuse/gate/saxo.md+6−13

This diff is too big to show here.

docs/hoon/library/zuse/gate/scanf.md+17−19

This diff is too big to show here.

docs/hoon/library/zuse/gate/sein.md+5−10

This diff is too big to show here.

docs/hoon/library/zuse/gate/sifo.md+5−12

This diff is too big to show here.

docs/hoon/library/zuse/gate/stud.md+5−12

This diff is too big to show here.

docs/hoon/library/zuse/gate/taco.md+4−10

This diff is too big to show here.

docs/hoon/library/zuse/gate/tact.md+7−14

This diff is too big to show here.

docs/hoon/library/zuse/gate/tame.md+7−14

This diff is too big to show here.

docs/hoon/library/zuse/gate/tell.md+7−14

This diff is too big to show here.

docs/hoon/library/zuse/gate/tome.md+6−13

This diff is too big to show here.

docs/hoon/library/zuse/gate/tope.md+3−7

This diff is too big to show here.

docs/hoon/library/zuse/gate/txml.md+5−11

This diff is too big to show here.

docs/hoon/library/zuse/gate/unt.md+5−12

This diff is too big to show here.

docs/hoon/library/zuse/gate/urld.md+5−12

This diff is too big to show here.

docs/hoon/library/zuse/gate/urle.md+7−15

This diff is too big to show here.

docs/hoon/library/zuse/mold/udal.md+3−7

This diff is too big to show here.

docs/hoon/library/zuse/mold/udon.md+1−4

This diff is too big to show here.

docs/hoon/library/zuse/mold/umph.md+1−4

This diff is too big to show here.

docs/hoon/library/zuse/mold/unce.md+1−2

This diff is too big to show here.

docs/hoon/library/zuse/mold/upas.md+1−4

This diff is too big to show here.

docs/hoon/library/zuse/mold/urge.md+1−4

This diff is too big to show here.

docs/hoon/library/zuse/rsa.md+24−26

This diff is too big to show here.

docs/hoon/mission.md+28−34

This diff is too big to show here.

docs/hoon/reference.md+11−12

This diff is too big to show here.

docs/hoon/syntax.md+228−262

This diff is too big to show here.

docs/hoon/troubleshooting.md+97−120

This diff is too big to show here.

docs/hoon/twig.md+44−50

This diff is too big to show here.

docs/hoon/twig/atom.md+3−6

This diff is too big to show here.

docs/hoon/twig/atom/knit.md+9−17

This diff is too big to show here.

docs/hoon/twig/atom/path.md+9−11

This diff is too big to show here.

docs/hoon/twig/atom/rock.md+12−16

This diff is too big to show here.

docs/hoon/twig/atom/sand.md+40−43

This diff is too big to show here.

docs/hoon/twig/bar-core.md+14−16

This diff is too big to show here.

docs/hoon/twig/bar-core/cab-door.md+46−60

This diff is too big to show here.

docs/hoon/twig/bar-core/cen-core.md+26−32

This diff is too big to show here.

docs/hoon/twig/bar-core/col-gasp.md+7−12

This diff is too big to show here.

docs/hoon/twig/bar-core/dot-trap.md+41−54

This diff is too big to show here.

docs/hoon/twig/bar-core/hep-loop.md+27−40

This diff is too big to show here.

docs/hoon/twig/bar-core/ket-cork.md+26−36

This diff is too big to show here.

docs/hoon/twig/bar-core/sig-port.md+6−15

This diff is too big to show here.

docs/hoon/twig/bar-core/tar-gill.md+38−48

This diff is too big to show here.

docs/hoon/twig/bar-core/tis-gate.md+29−43

This diff is too big to show here.

docs/hoon/twig/bar-core/wut-tray.md+12−20

This diff is too big to show here.

docs/hoon/twig/buc-mold.md+34−39

This diff is too big to show here.

docs/hoon/twig/buc-mold/base.md+15−18

This diff is too big to show here.

docs/hoon/twig/buc-mold/cab-shoe.md+20−28

This diff is too big to show here.

docs/hoon/twig/buc-mold/cen-book.md+21−25

This diff is too big to show here.

docs/hoon/twig/buc-mold/col-bank.md+18−23

This diff is too big to show here.

docs/hoon/twig/buc-mold/hep-lamb.md+16−25

This diff is too big to show here.

docs/hoon/twig/buc-mold/ket-bush.md+20−26

This diff is too big to show here.

docs/hoon/twig/buc-mold/pat-claw.md+21−25

This diff is too big to show here.

docs/hoon/twig/buc-mold/tis-coat.md+14−23

This diff is too big to show here.

docs/hoon/twig/buc-mold/wut-pick.md+20−26

This diff is too big to show here.

docs/hoon/twig/cen-call.md+3−5

This diff is too big to show here.

docs/hoon/twig/cen-call/cab-keep.md+26−35

This diff is too big to show here.

docs/hoon/twig/cen-call/dot-lace.md+10−19

This diff is too big to show here.

docs/hoon/twig/cen-call/hep-call.md+22−33

This diff is too big to show here.

docs/hoon/twig/cen-call/ket-calq.md+11−19

This diff is too big to show here.

docs/hoon/twig/cen-call/lus-calt.md+11−19

This diff is too big to show here.

docs/hoon/twig/cen-call/sig-open.md+11−18

This diff is too big to show here.

docs/hoon/twig/cen-call/tar-bake.md+20−27

This diff is too big to show here.

docs/hoon/twig/cen-call/tis-make.md+22−26

This diff is too big to show here.

docs/hoon/twig/col-cell.md+3−5

This diff is too big to show here.

docs/hoon/twig/col-cell/cab-scon.md+7−15

This diff is too big to show here.

docs/hoon/twig/col-cell/hep-cons.md+15−17

This diff is too big to show here.

docs/hoon/twig/col-cell/ket-conq.md+18−26

This diff is too big to show here.

docs/hoon/twig/col-cell/lus-cont.md+16−24

This diff is too big to show here.

docs/hoon/twig/col-cell/sig-conl.md+35−45

This diff is too big to show here.

docs/hoon/twig/col-cell/tar-conp.md+48−56

This diff is too big to show here.

docs/hoon/twig/dot-nock.md+1−2

This diff is too big to show here.

docs/hoon/twig/dot-nock/ket-wish.md+6−6

This diff is too big to show here.

docs/hoon/twig/dot-nock/lus-bump.md+11−13

This diff is too big to show here.

docs/hoon/twig/dot-nock/tar-nock.md+29−33

This diff is too big to show here.

docs/hoon/twig/dot-nock/tis-same.md+15−19

This diff is too big to show here.

docs/hoon/twig/dot-nock/wut-deep.md+11−15

This diff is too big to show here.

docs/hoon/twig/ket-cast.md+5−6

This diff is too big to show here.

docs/hoon/twig/ket-cast/bar-iron.md+14−20

This diff is too big to show here.

docs/hoon/twig/ket-cast/hep-cast.md+31−40

This diff is too big to show here.

docs/hoon/twig/ket-cast/lus-like.md+7−11

This diff is too big to show here.

docs/hoon/twig/ket-cast/sig-burn.md+10−14

This diff is too big to show here.

docs/hoon/twig/ket-cast/tis-name.md+15−17

This diff is too big to show here.

docs/hoon/twig/ket-cast/wut-lead.md+13−20

This diff is too big to show here.

docs/hoon/twig/limb.md+10−11

This diff is too big to show here.

docs/hoon/twig/limb/limb.md+31−41

This diff is too big to show here.

docs/hoon/twig/limb/wing.md+18−21

This diff is too big to show here.

docs/hoon/twig/sem-make.md+1−2

This diff is too big to show here.

docs/hoon/twig/sem-make/col-wad.md+26−36

This diff is too big to show here.

docs/hoon/twig/sem-make/fas-nub.md+6−11

This diff is too big to show here.

docs/hoon/twig/sem-make/sem-fry.md+23−41

This diff is too big to show here.

docs/hoon/twig/sem-make/sig-dip.md+29−36

This diff is too big to show here.

docs/hoon/twig/sig-hint.md+2−4

This diff is too big to show here.

docs/hoon/twig/sig-hint/bar-show.md+8−12

This diff is too big to show here.

docs/hoon/twig/sig-hint/buc-poll.md+5−9

This diff is too big to show here.

docs/hoon/twig/sig-hint/cab-lurk.md+8−12

This diff is too big to show here.

docs/hoon/twig/sig-hint/cen-fast.md+38−45

This diff is too big to show here.

docs/hoon/twig/sig-hint/fas-funk.md+12−18

This diff is too big to show here.

docs/hoon/twig/sig-hint/gal-thin.md+16−21

This diff is too big to show here.

docs/hoon/twig/sig-hint/gar-hint.md+18−27

This diff is too big to show here.

docs/hoon/twig/sig-hint/lus-memo.md+9−15

This diff is too big to show here.

docs/hoon/twig/sig-hint/pam-dump.md+9−13

This diff is too big to show here.

docs/hoon/twig/sig-hint/tis-ddup.md+10−13

This diff is too big to show here.

docs/hoon/twig/sig-hint/wut-warn.md+13−17

This diff is too big to show here.

docs/hoon/twig/sig-hint/zap-peep.md+13−17

This diff is too big to show here.

docs/hoon/twig/tis-flow.md+15−17

This diff is too big to show here.

docs/hoon/twig/tis-flow/bar-new.md+21−30

This diff is too big to show here.

docs/hoon/twig/tis-flow/col-fix.md+17−25

This diff is too big to show here.

docs/hoon/twig/tis-flow/dot-set.md+22−30

This diff is too big to show here.

docs/hoon/twig/tis-flow/fas-var.md+35−52

This diff is too big to show here.

docs/hoon/twig/tis-flow/gal-rap.md+9−15

This diff is too big to show here.

docs/hoon/twig/tis-flow/gar-per.md+11−15

This diff is too big to show here.

docs/hoon/twig/tis-flow/hep-nip.md+19−27

This diff is too big to show here.

docs/hoon/twig/tis-flow/ket-sip.md+22−32

This diff is too big to show here.

docs/hoon/twig/tis-flow/lus-pin.md+17−25

This diff is too big to show here.

docs/hoon/twig/tis-flow/sem-rev.md+16−24

This diff is too big to show here.

docs/hoon/twig/tis-flow/sig-tow.md+27−31

This diff is too big to show here.

docs/hoon/twig/tis-flow/tar-aka.md+27−31

This diff is too big to show here.

docs/hoon/twig/wut-test.md+13−15

This diff is too big to show here.

docs/hoon/twig/wut-test/bar-or.md+20−30

This diff is too big to show here.

docs/hoon/twig/wut-test/col-if.md+17−23

This diff is too big to show here.

docs/hoon/twig/wut-test/dot-lest.md+29−37

This diff is too big to show here.

docs/hoon/twig/wut-test/gal-deny.md+9−18

This diff is too big to show here.

docs/hoon/twig/wut-test/gar-sure.md+9−17

This diff is too big to show here.

docs/hoon/twig/wut-test/hep-case.md+50−63

This diff is too big to show here.

docs/hoon/twig/wut-test/ket-ifcl.md+22−30

This diff is too big to show here.

docs/hoon/twig/wut-test/lus-deft.md+43−53

This diff is too big to show here.

docs/hoon/twig/wut-test/pam-and.md+19−29

This diff is too big to show here.

docs/hoon/twig/wut-test/pat-ifat.md+22−30

This diff is too big to show here.

docs/hoon/twig/wut-test/sig-ifno.md+17−26

This diff is too big to show here.

docs/hoon/twig/wut-test/tis-fits.md+17−23

This diff is too big to show here.

docs/hoon/twig/wut-test/zap-not.md+21−29

This diff is too big to show here.

docs/hoon/twig/zap-wild.md+1−2

This diff is too big to show here.

docs/hoon/twig/zap-wild/gar-wrap.md+7−11

This diff is too big to show here.

docs/hoon/twig/zap-wild/tis-code.md+14−18

This diff is too big to show here.

docs/hoon/twig/zap-wild/wut-need.md+16−20

This diff is too big to show here.

docs/hoon/twig/zap-wild/zap-fail.md+6−10

This diff is too big to show here.

docs/nock.md+3−2

This diff is too big to show here.

docs/nock/definition.md+105−119

This diff is too big to show here.

docs/nock/example.md+159−243

This diff is too big to show here.

docs/nock/explanation.md+265−386

This diff is too big to show here.

docs/nock/implementations.md+179−179

This diff is too big to show here.

docs/nock/implementations/c.md+176−178

This diff is too big to show here.

docs/nock/implementations/clojure.md+117−118

This diff is too big to show here.

docs/nock/implementations/csharp.md+377−379

This diff is too big to show here.

docs/nock/implementations/groovy.md+177−178

This diff is too big to show here.

docs/nock/implementations/haskell.md+56−57

This diff is too big to show here.

docs/nock/implementations/hoon.md+47−49

This diff is too big to show here.

docs/nock/implementations/javascript.md+355−357

This diff is too big to show here.

docs/nock/implementations/python.md+75−77

This diff is too big to show here.

docs/nock/implementations/ruby.md+130−131

This diff is too big to show here.

docs/nock/implementations/scala.md+68−69

This diff is too big to show here.

docs/nock/implementations/scheme.md+112−113

This diff is too big to show here.

docs/nock/implementations/swift.md+317−319

This diff is too big to show here.

docs/using.md+3−2

This diff is too big to show here.

docs/using/admin.md+49−21

This diff is too big to show here.

docs/using/filesystem.md+70−86

This diff is too big to show here.

docs/using/install.md+38−34

This diff is too big to show here.

docs/using/layout.md+32−19

This diff is too big to show here.

docs/using/messaging.md+61−72

This diff is too big to show here.

docs/using/setup.md+31−37

This diff is too big to show here.

docs/using/shell.md+38−48

This diff is too big to show here.

docs/using/urb.md+255−282

This diff is too big to show here.

docs/using/web.md+188−118

This diff is too big to show here.

docs/using/web/blog.md+27−32

This diff is too big to show here.

docs/using/web/comments.md+13−15

This diff is too big to show here.

docs/using/web/static.md+23−26

This diff is too big to show here.