on master help sign in
Merge branch 'urbit:master' into docs/minio-s3-guide
commit4a1141ac3733357ba47b765774a2ee24991b0210 authorTom Snelling <tomsnelling8@gmail.com> dateThu 25 Nov 2021, 14:09 (5 years ago) parentca815616a88984
309 files changed+45862−16463
.gitignore+4−3 .npmrc+1 components/BubbleLink.js+25 components/Contact.js−6 components/EventPreview.js+42−38 components/Footer.js+1−1 components/Header.js+14 components/Markdown.js+16−4 components/TableOfContents.js+5−2 content/blog/2021-11-18-report-from-the-field.md+94 content/blog/2021-11-18-the-promise-and-paradox-of-decentralization.md+55 content/blog/value-of-address-space-pt1.md+1−5 content/blog/value-of-address-space-pt2.md+11−33 content/blog/value-of-address-space-pt3.md+5−15 content/docs/_index.md+1−1 content/docs/arvo/_index.md+2−4 content/docs/arvo/ames/_index.md+20 content/docs/arvo/ames/ames-api.md−292 content/docs/arvo/ames/ames.md+75−75 content/docs/arvo/ames/cryptography.md+3−3 content/docs/arvo/ames/data-types.md+389 content/docs/arvo/ames/scry.md+126 content/docs/arvo/ames/tasks.md+193 content/docs/arvo/behn/examples.md+2−2 content/docs/arvo/clay/architecture.md+43−120 content/docs/arvo/clay/clay.md+4−1 content/docs/arvo/clay/data-types.md+2−9 content/docs/arvo/clay/examples.md+99−102 content/docs/arvo/clay/marks/_index.md+23 content/docs/arvo/clay/marks/examples.md+248 content/docs/arvo/clay/marks/marks.md+59 content/docs/arvo/clay/marks/using-marks.md+240 content/docs/arvo/clay/marks/writing-marks.md+333 content/docs/arvo/clay/scry.md+6−6 content/docs/arvo/clay/tasks.md+2−2 content/docs/arvo/clay/using.md+67−61 content/docs/arvo/concepts/_index.md+4 content/docs/arvo/concepts/scry.md+77 content/docs/arvo/concepts/subscriptions.md+43−43 content/docs/arvo/dill/_index.md+16 content/docs/arvo/dill/data-types.md+187 content/docs/arvo/dill/dill-api.md−366 content/docs/arvo/dill/dill.md+35−18 content/docs/arvo/dill/scry.md+45 content/docs/arvo/dill/tasks.md+342 content/docs/arvo/eyre/_index.md+1−1 content/docs/arvo/eyre/external-api-ref.md+4−4 content/docs/arvo/eyre/eyre.md+5−5 content/docs/arvo/eyre/examples.md → content/docs/arvo/eyre/guide.md+29−23 content/docs/arvo/eyre/tasks.md+5−5 content/docs/arvo/gall/data-types.md+492 content/docs/userspace/gall/gall-api.md → content/docs/arvo/gall/gall-api.md+24−24 content/docs/userspace/gall/gall.md → content/docs/arvo/gall/gall.md content/docs/arvo/gall/overview.md−11 content/docs/arvo/iris/example.md+1−1 content/docs/arvo/jael/examples.md+3−3 content/docs/arvo/overview.md+2−2 content/docs/arvo/reference/filesystem.md+65−31 content/docs/azimuth/_index.md+26−7 content/docs/azimuth/advanced-azimuth-tools.md+82−25 content/docs/azimuth/azimuth-eth.md+158 content/docs/azimuth/azimuth.md+126−137 content/docs/azimuth/ecliptic.md+436 content/docs/azimuth/flow.md+232 content/docs/azimuth/hd-wallet.md+137 content/docs/azimuth/l2/_index.md+35 content/docs/azimuth/l2/bytestring.md+201 content/docs/azimuth/l2/l2-actions.md+183 content/docs/azimuth/l2/layer2-api.md+14 content/docs/azimuth/l2/layer2.md+402 content/docs/azimuth/l2/roller.md+66 content/docs/azimuth/life-and-rift.md+7−5 content/docs/development/develop.md+4−4 content/docs/development/environment.md+269−20 content/docs/development/precepts.md+1−1 content/docs/glossary/aqua.md−4 content/docs/glossary/azimuth.md+27−6 content/docs/glossary/desk.md+1−1 content/docs/glossary/dojo.md+2−1 content/docs/glossary/gall.md+2−1 content/docs/glossary/hdwallet.md+2−1 content/docs/glossary/proxies.md+6−1 content/docs/glossary/rollups.md+30 content/docs/hoon/guides/_index.md+4 content/docs/hoon/guides/json-guide.md+511 content/docs/hoon/guides/parsing.md+48−21 content/docs/hoon/guides/strings.md+531 content/docs/hoon/hoon-school/_index.md+28−33 content/docs/hoon/hoon-school/caesar.md+25−25 content/docs/hoon/hoon-school/egg-timer.md+33−28 content/docs/hoon/hoon-school/generators.md+13−14 content/docs/hoon/hoon-school/hoon-syntax.md+1−1 content/docs/hoon/hoon-school/intro.md+121 content/docs/hoon/hoon-school/list-of-numbers.md+3−3 content/docs/hoon/hoon-school/recursion.md+7−8 content/docs/hoon/hoon-school/setup.md−105 content/docs/hoon/hoon-school/type-polymorphism.md+81−81 content/docs/hoon/reference/_index.md+6−3 content/docs/hoon/reference/cheat-sheet.md+3−13 content/docs/hoon/reference/rune/ket.md+12−3 content/docs/hoon/reference/rune/mic.md+1−1 content/docs/hoon/reference/rune/tis.md+9−3 content/docs/hoon/reference/rune/zap.md+1−1 content/docs/hoon/reference/stdlib/1a.md+403−284 content/docs/hoon/reference/stdlib/1b.md+125−89 content/docs/hoon/reference/stdlib/1c.md+201−122 content/docs/hoon/reference/stdlib/2a.md+298−131 content/docs/hoon/reference/stdlib/2b.md+664−431 content/docs/hoon/reference/stdlib/2c.md+713−637 content/docs/hoon/reference/stdlib/2d.md+55−54 content/docs/hoon/reference/stdlib/2e.md+98−178 content/docs/hoon/reference/stdlib/2f.md+163−285 content/docs/hoon/reference/stdlib/2g.md+26−26 content/docs/hoon/reference/stdlib/2h.md+345−345 content/docs/hoon/reference/stdlib/2i.md+720−436 content/docs/hoon/reference/stdlib/2j.md+263−155 content/docs/hoon/reference/stdlib/2k.md+191−135 content/docs/hoon/reference/stdlib/2l.md+5−3 content/docs/hoon/reference/stdlib/2m.md+40−32 content/docs/hoon/reference/stdlib/2n.md+152−138 content/docs/hoon/reference/stdlib/2o.md+99−86 content/docs/hoon/reference/stdlib/2p.md+125−119 content/docs/hoon/reference/stdlib/2q.md+350−139 content/docs/hoon/reference/stdlib/3a.md+259−237 content/docs/hoon/reference/stdlib/3b.md+1583−1418 content/docs/hoon/reference/stdlib/3c.md+260−245 content/docs/hoon/reference/stdlib/3d.md+455−456 content/docs/hoon/reference/stdlib/3f.md+463−317 content/docs/hoon/reference/stdlib/3g.md+136−165 content/docs/hoon/reference/stdlib/4a.md+5−1 content/docs/hoon/reference/stdlib/4b.md+36−37 content/docs/hoon/reference/stdlib/4c.md+12−16 content/docs/hoon/reference/stdlib/4d.md+4−4 content/docs/hoon/reference/stdlib/4e.md+20−33 content/docs/hoon/reference/stdlib/4f.md+49−53 content/docs/hoon/reference/stdlib/4g.md+8−8 content/docs/hoon/reference/stdlib/4h.md+66−64 content/docs/hoon/reference/stdlib/4i.md+70−72 content/docs/hoon/reference/stdlib/4j.md+62−64 content/docs/hoon/reference/stdlib/4k.md+5−5 content/docs/hoon/reference/stdlib/4l.md+11−13 content/docs/hoon/reference/stdlib/4m.md+20−18 content/docs/hoon/reference/stdlib/4n.md+15−13 content/docs/hoon/reference/stdlib/4o.md+31−127 content/docs/hoon/reference/stdlib/5c.md+77−1 content/docs/hoon/reference/stdlib/5f.md+18−23 content/docs/hoon/reference/stdlib/table-of-contents.md+134−97 content/docs/hoon/reference/zuse/2d_1-5.md+587 content/docs/hoon/reference/zuse/2d_6.md+1551 content/docs/hoon/reference/zuse/2d_7.md+1307 content/docs/hoon/reference/zuse/2e_2-3.md+67 content/docs/hoon/reference/zuse/_index.md+31 content/docs/hoon/reference/zuse/table-of-contents.md+247 content/docs/system-overview/arvo.md+1−1 content/docs/userspace/_index.md+5−2 content/docs/userspace/dist/_index.md+29 content/docs/userspace/dist/dist.md+105 content/docs/userspace/dist/docket.md+296 content/docs/userspace/dist/glob.md+102 content/docs/userspace/dist/guide.md+269 content/docs/userspace/dist/tools.md+342 content/docs/userspace/gall/tutorial.md → content/docs/userspace/gall-guide.md+1−1 content/docs/userspace/gall/_index.md−21 content/docs/userspace/graph-store/overview.md+15−21 content/docs/userspace/graph-store/sample-application-overview.md+58−58 content/docs/userspace/graph-store/validator-walkthrough.md+38−49 content/docs/userspace/landscape/overview.md+5−14 content/docs/userspace/overview.md+7−2 content/docs/userspace/threads/basics/bind.md+1−1 content/docs/userspace/threads/basics/fundamentals.md+16−17 content/docs/userspace/threads/examples/child-thread.md+6−5 content/docs/userspace/threads/examples/get-json.md+1−1 content/docs/userspace/threads/examples/main-loop.md+2−2 content/docs/userspace/threads/examples/poke-agent.md+1−1 content/docs/userspace/threads/examples/scry.md+1−1 content/docs/userspace/threads/examples/take-fact.md+1−1 content/docs/userspace/threads/gall/poke-thread.md+1−1 content/docs/userspace/threads/gall/start-thread.md+3−3 content/docs/userspace/threads/gall/stop-thread.md+1−1 content/docs/userspace/threads/gall/take-facts.md+1−1 content/docs/userspace/threads/gall/take-result.md+1−1 content/docs/userspace/threads/http-api.md+6−6 content/docs/userspace/threads/overview.md+13−12 content/docs/userspace/threads/reference.md+11−2 content/events/2021-09-16-developer-call-azimuth-scaled.md+46 content/events/2021-10-16-assembly-keynote.md+14 content/events/2021-10-16-assembly-sw-dist-qa.md+14 content/events/2021-11-26-meetup-brisbane.md+30 content/events/20211007-developer-call-visor.md+38 content/events/20211028-developer-call-hosting.md+33 content/faq.md+10−155 content/getting-started/_index.md+54−4 content/getting-started/cli.md+15−24 content/getting-started/planet.md+167−83 content/grant-submission-guide.md+1−1 content/grants/a-collaborative-web-mapping-system-for-urbit.md → content/grants/a-network-enabled-spatial-database-and-demonstration-app.md+26−21 content/grants/analytics-script.md+2−1 content/grants/art-by-urbit.md+1 content/grants/authenticate-with-urbit.md+36 content/grants/azimuth-cli.md+164 content/grants/bridge-l2-revamp.md+1 content/grants/calendar-ui.md+1 content/grants/clojure-urbit-client.md+111 content/grants/comprehensive-local-server-and-mum-explanation-video.md+2−1 content/grants/contacts.md+1 content/grants/content-producer.md+1 content/grants/cross-platform-desktop-urbit-app.md+2−1 content/grants/cypherscope-bot.md+80 content/grants/educational-guide-todomvc-urbit-edition.md+1 content/grants/feed-aggregator.md+1 content/grants/graph-store-documentation-guide.md+1 content/grants/guide-to-s3.md+1 content/grants/host-two-urbit-meetups-12.md+2−1 content/grants/host-two-urbit-meetups-13.md+59 content/grants/host-two-urbit-meetups-14.md+59 content/grants/host-two-urbit-meetups-15.md+59 content/grants/host-two-urbit-meetups-16.md+59 content/grants/json-jet.md+1 content/grants/links-in-urbit-reference-docs.md+2−1 content/grants/login-with-urbit.md+3−8 content/grants/machine-learning.md+1 content/grants/market-interface.md+61 content/grants/meetup-bom.md+118 content/grants/minimal-urbit-os.md+1 content/grants/native-urbit.md+30 content/grants/network-explorer-data-pipeline-http-api.md+2−1 content/grants/network-explorer.md−233 content/grants/nuck-jet.md+1 content/grants/overhaul-the-urbitorg-website.md+3−2 content/grants/planet-sales.md+1 content/grants/pokur.md+90 content/grants/ra-page-tracking.md+2−2 content/grants/search-in-groups.md+1−1 content/grants/send-emails-to-a-mailing-list.md+78 content/grants/slaw-scot-jets.md+1−1 content/grants/-smol-future-sustained-knowledge-sharing-and-marketing.md → content/grants/smol-future-sustained-knowledge-sharing-and-marketing.md content/grants/speech-recognition.md+1 content/grants/static-site-generation.md+80 content/grants/translate-key-parts-of-urbitorg-into-german.md+1 content/grants/translate-key-parts-of-urbitorg-into-korean.md+1 content/grants/translate-key-parts-of-urbitorg-into-spanish.md+1 content/grants/try-urbit-website.md+2−1 content/grants/twitter-uv-extension.md+67 content/grants/ua-collaborative-text-editor.md+2−2 content/grants/ua-filesharer.md+1−1 content/grants/ua-heads-up-poker.md+1−1 content/grants/ua-invoice-system.md+1−1 content/grants/ua-marketplace.md+1−1 content/grants/ucal-google-and-outlook-integration.md+1 content/grants/urbian-a-customized-linux-distribution-for-urbit-appliances.md+1 content/grants/urbit-community-concierge-east-coast-2q2021.md+2−1 content/grants/urbit-community-concierge-east-coast.md+2−1 content/grants/urbit-community-concierge-west-coast-2q2021.md+2−1 content/grants/urbit-community-concierge-west-coast.md+2−1 content/grants/urbit-event-series.md+2−1 content/grants/urbit-explainer-video.md+1 content/grants/urbit-http-api-for-emacs-elisp.md+1 content/grants/urbit-http-api-for-kotlin.md+1 content/grants/urbit-http-api-for-python.md+1 content/grants/urbit-http-api-for-rust.md+1 content/grants/urbit-http-interface-java-edition.md+1 content/grants/urbit-http-library-for-ruby.md+1 content/grants/urbit-irc-bridge.md+1 content/grants/urbit-lfs-filehosting.md+1 content/grants/urbit-react-cookbook.md+2−1 content/grants/uturn.md+37 content/grants/uv-extension-library.md+44 content/grants/video-content-manager.md+1 content/grants/volt-lightning-on-urbit.md+39−9 content/grants/webrtc-gall-agent-and-external-app.md+16−18 content/grants/webrtc.md−80 content/grants/~home-urbit.md+120 content/using/_index.md+3−3 content/using/id/_index.md+26 content/using/id/guide-to-breaches.md+1−3 content/using/id/hd-wallet.md+164 content/using/id/l2-star.md+41 content/using/id/overview.md+187−55 content/using/id/proxies.md+56 content/using/id/using-bridge.md+1−1 content/using/os/_index.md+1−1 content/using/os/basics.md+236 content/using/os/dist-faq.md+162 content/using/os/filesystem.md+29−47 content/using/os/getting-started.md−335 content/using/os/shell.md+20−90 content/using/os/ship-troubleshooting.md+2−2 content/using/running/_index.md+4 content/using/running/port.md+157 lib/constants.js−1 lib/glossary.js+1301−551 next.config.js+46−10 package-lock.json+2313−3335 package.json+8−6 pages/bitcoin-wallet.js+21 pages/events.js+15−4 pages/events/[slug].js+2−2 pages/grants.js+1−1 pages/index.js+75−23 pages/using/[[...slug]].js+3−3 patches/prismjs+1.24.1.patch−42 public/images/developers-guide-logo.png public/images/network-explorer-logo.png public/images/operators-guide-logo.png public/images/star-market-logo.png public/rss.xml+17611 styles/markdown.css+2−6 vercel.json+5 yarn.lock−1865
.gitignore+4−3
@@ -5,14 +5,13 @@
55/.pnp
66.pnp.js
77
8−/public
9−
108# testing
119/coverage
1210
1311# next.js
1412/.next/
1513/out/
14+.next
1615
1716# production
1817/build
@@ -37,4 +36,6 @@ yarn-error.log*
3736.vercel
3837
3938# editors
40−/.nova/
39+/.nova/
40+
41+yarn.lock
.npmrcnew file+1
@@ -0,0 +1 @@
1+unsafe-perm = true
components/BubbleLink.jsnew file+25
@@ -0,0 +1,25 @@
1+export default function BubbleLink(props) {
2+ return (
3+ <li className={"list-none " + props.className}>
4+ <a className={"flex"} href={props.href} target={props.target}>
5+ <div>{props.children}</div>
6+ <div className="flex flex-col ml-4">
7+ <p className="font-bold">{props.title}</p>
8+ <p className="text-wall-400 dark:text-antiwall-400 font-bold leading-snug">
9+ {props.caption}
10+ </p>
11+ </div>
12+ </a>
13+ </li>
14+ );
15+}
16+
17+BubbleLink.defaultProps = {
18+ className: "",
19+ title: "",
20+ caption: "",
21+ children: (
22+ <div className="w-12 h-12 bg-wall-500 dark:bg-antiwall-500 rounded-full" />
23+ ),
24+ target: "_blank",
25+};
components/Contact.js−6
@@ -79,12 +79,6 @@ export default function Contact({ emphasize }) {
7979 Github
8080 </a>
8181 </h4>
82− <h4 className="mt-6 text-wall-500">
83− Ask questions in our{" "}
84− <a className={linkText} href={contact.discord}>
85− Discord
86− </a>
87− </h4>
8882 <h4 className="mt-4 text-wall-500 flex items-baseline flex-wrap">
8983 Boot Urbit and join{" "}
9084 <div className="md:ml-2 rounded-lg flex items-stretch">
components/EventPreview.js+42−38
@@ -4,6 +4,7 @@ import {
44 ShowOrHide,
55 ReadableList,
66 Person,
7+ Name,
78 DateRange,
89} from "../components/Snippets";
910import {
@@ -14,6 +15,42 @@ import {
1415 formatTimeZone,
1516} from "../lib/lib";
1617
18+// JAL(2021.9.13) Couldn't quite get this to work properly. There's a trailing
19+// "and"
20+//
21+// function GuestList({ guests, textClass }) {
22+
23+// const renderGuests = guests?.length > 2 ? guests?.slice(0,2) : guests;
24+// const noRenderGuestsCount = guests?.slice(2).length;
25+
26+// return (
27+// <p className={textClass + " type-sub"}>
28+// <b>
29+// {renderGuests?.length > 1 ? "With guests " : "With guest "}
30+// </b>
31+// <ReadableList>
32+// {renderGuests?.map((guest, index) => (
33+// <>
34+// <Person
35+// key={`${guest.name}-${guest.patp}`}
36+// nameClassNames={textClass}
37+// patpClassNames={textClass}
38+// name={guest.name}
39+// patp={guest.patp}
40+// />
41+// {renderGuests?.length > 1 ? <span>, </span> : <></>}
42+// </>
43+// ))}
44+// {noRenderGuestsCount > 1 ?
45+// <Name>{noRenderGuestsCount} more </Name>
46+// :
47+// <></>
48+// }
49+// </ReadableList>
50+// </p>
51+// );
52+// }
53+
1754export default function EventPreview({ event, className, big }) {
1855 // Event tiles have a 'dark mode' used when their background images are dark and white text is needed for legibility.
1956 const grayText = event?.dark ? "text-washedWhite" : "text-wall-400";
@@ -46,7 +83,11 @@ export default function EventPreview({ event, className, big }) {
4683 } flex-col h-full`}
4784 >
4885 <h3 className={`${blackText} mb-2`}>{event.title}</h3>
49− <p className={`${blackText} mb-2`}>{event.location}</p>
86+ <p className={blackText + ""}>{event.description}</p>
87+ </div>
88+
89+ <div className="absolute p-6 left-0 bottom-0 w-full pr-32">
90+ <p className={`${blackText} type-sub mb-1`}>{event.location}</p>
5091 <DateRange
5192 starts={starts}
5293 ends={ends}
@@ -54,43 +95,6 @@ export default function EventPreview({ event, className, big }) {
5495 />
5596 </div>
5697
57− <div className="absolute p-6 left-0 bottom-0 w-full pr-32">
58− <ShowOrHide condition={event.hosts}>
59− <p className={blackText + " type-sub"}>
60− <b>{"Hosted by "}</b>
61− <ReadableList>
62− {event.hosts?.map((host, index) => (
63− <Person
64− key={`${host.name}-${host.patp}`}
65− nameClassNames={blackText}
66− patpClassNames={blackText}
67− name={host.name}
68− patp={host.patp}
69− />
70− ))}
71− </ReadableList>
72− </p>
73− </ShowOrHide>
74− <ShowOrHide condition={event.guests}>
75− <p className={blackText + " type-sub"}>
76− <b>
77− {event.guests?.length > 1 ? "With guests " : "With guest "}
78− </b>
79− <ReadableList>
80− {event.guests?.map((guest, index) => (
81− <Person
82− key={`${guest.name}-${guest.patp}`}
83− nameClassNames={blackText}
84− patpClassNames={blackText}
85− name={guest.name}
86− patp={guest.patp}
87− />
88− ))}
89− </ReadableList>
90− </p>
91− </ShowOrHide>
92− </div>
93−
9498 {inFuture && event.registration_url ? (
9599 <div className="absolute right-0 bottom-0 p-6">
96100 <a
components/Footer.js+1−1
@@ -17,7 +17,7 @@ export default function Footer() {
1717 </Link>
1818 <Link href="/using">
1919 <div>
20− <a className="type-bold text-wall-500">Operator's Manual</a>
20+ <a className="type-bold text-wall-500">User's Manual</a>
2121 </div>
2222 </Link>
2323 <Link href="https://github.com/urbit/port/releases">
components/Header.js+14
@@ -72,6 +72,13 @@ export default function Header(props) {
7272 >
7373 Docs
7474 </ActiveLink>
75+ <ActiveLink
76+ currentPath={currentPath}
77+ className="mr-5 type-ui"
78+ href="/using"
79+ >
80+ Manual
81+ </ActiveLink>
7582 <ActiveLink
7683 currentPath={currentPath}
7784 className="mr-5 type-ui"
@@ -93,6 +100,13 @@ export default function Header(props) {
93100 >
94101 Get Started
95102 </ActiveLink>
103+ <ActiveLink
104+ currentPath={currentPath}
105+ className="mr-5 type-ui"
106+ href="/faq"
107+ >
108+ FAQ
109+ </ActiveLink>
96110 <button
97111 onClick={(e) => {
98112 e.stopPropagation();
components/Markdown.js+16−4
@@ -2,9 +2,14 @@ import remark from "remark";
22import gfm from "remark-gfm";
33import slug from "remark-slug";
44import heading from "remark-heading-id";
5−import html from "remark-html";
65import remarkprism from "remark-prism";
76import normalize from "mdurl/encode";
7+import merge from "deepmerge";
8+import github from "hast-util-sanitize/lib/github";
9+import remarkParse from "remark-parse";
10+import remarkRehype from "remark-rehype";
11+import rehypeStringify from "rehype-stringify";
12+import rehypeRaw from "rehype-raw";
813
914// img is wrapped in figure so that images can be extra wide in the blog posts
1015function Img(h, node) {
@@ -30,19 +35,26 @@ const options = {
3035 handlers: {
3136 image: Img,
3237 },
33− entities: "numbers",
38+ sanitize: merge(github, {
39+ // remove user-content from github.json to remark-slug work as expected
40+ clobberPrefix: "",
41+ attributes: { "*": ["className"] },
42+ }),
3443};
3544
3645// Converts markdown strings into markdown HTML/React components
3746export default async function Markdown({ post }) {
3847 const result = await remark()
39− .use(html, options)
40− .use(gfm)
48+ .use(remarkParse, options)
4149 .use(remarkprism, {
4250 plugins: ["show-invisibles"],
4351 })
52+ .use(gfm)
4453 .use(slug)
4554 .use(heading)
55+ .use(remarkRehype, { allowDangerousHtml: true })
56+ .use(rehypeRaw)
57+ .use(rehypeStringify)
4658 .process(post.content);
4759
4860 return result.toString();
components/TableOfContents.js+5−2
@@ -52,9 +52,12 @@ const useHeadingsData = (noh3s) => {
5252
5353const Headings = ({ headings, activeId }) => (
5454 <ul>
55− {headings.map((heading) => (
55+ {headings.map((heading, index) => (
5656 <li key={heading.id}>
57− <a className="font-semibold" href={`#${heading.id}`}>
57+ <a
58+ className={index === 0 ? "font-bold" : "font-medium"}
59+ href={`#${heading.id}`}
60+ >
5861 {heading.title}
5962 </a>
6063 {heading.items.length > 0 && (
content/blog/2021-11-18-report-from-the-field.mdnew file+94
@@ -0,0 +1,94 @@
1++++
2+title = "Report from the field: Assembly 2021"
3+date = "2021-11-18"
4+description = "The system builds the community and the community builds the system."
5+[extra]
6+author = "Galen Wolfe-Pauly"
7+ship = "~ravmel-ropdyl"
8+image = "https://storage.googleapis.com/media.urbit.org/site/posts/essays/galen-at-assembly.JPG"
9++++
10+
11+![Galen at Assembly](https://storage.googleapis.com/media.urbit.org/site/posts/essays/galen-at-assembly.JPG)
12+
13+Before Assembly I committed to write a ‘recap’ post for everyone who couldn’t make it. Originally I figured this post would be an opportunity to walk through the list of things that we shipped and showed off in Austin. But it turns out that the most important thing about Assembly was simply the way it felt to be there.
14+
15+I’m not sure it’s possible to really do the feeling in the room justice, but I’m going to try. Then I’ll get into the announcements and happenings for those of you who couldn’t make it.
16+
17+But first, a quick note:
18+
19+We ran Assembly under the [Chatham House rule](https://en.wikipedia.org/wiki/Chatham_House_Rule). Basically, you can talk about what happens at Assembly—but you can’t name anyone.
20+
21+I’ve run many of our Urbit events this way because I think it puts people at ease. Everyone in the room can just relax, connect with one another, and hang out without worrying about being named on the internet.
22+
23+I’ll try to abide by the Chatham rule in this post which is why no one is named specifically.
24+
25+![secret society shirt](https://storage.googleapis.com/media.urbit.org/site/posts/essays/secret-society-shirt.JPG)
26+
27+New world energy -
28+
29+In the months leading up to Assembly we were totally focussed on using the event as a release date for a bunch of different lines of work. Coming out of that sprint, we didn’t really know what to expect. We wanted to make sure Urbit was ready for people to build on and that everything we were going to ship worked well. What we didn’t realize was just how emphatically people are <em>ready to build</em>.
30+
31+When I got up on stage on Friday night to welcome everyone I was really impressed by the room itself. It was packed with people who looked excited and motivated. The room just looked amazing. There were so many different kinds of people staring back at me. Some who I recognized from the earliest days of the project, and lots I had never seen before. I’ve been at my share of Urbit events, but this was something totally different.
32+
33+We didn’t have much scheduled during Assembly. Most of the time was unstructured to allow for freeform discussion, sunbathing on the lawn, and gathering at picnic tables. The panels that we did schedule will go down in history. Panelists discussed questions about creators, escaping reward systems, and the role of DAOs from governance to governments. There was hard money with a computer on it, Moloch shoes, community members grabbing the mic, and a talk written two hours before it was delivered about the relationship between centralization and decentralization when it comes to UX that blew our minds.
34+
35+I spent the weekend of Assembly in almost constant conversation with people building Urbit hardware, experimenting with different kinds of Urbit software, and thinking about incredible things like a Nock chip. I talked to the lead architect of a CPU from the 90s, a former senior US government official, an editor of a well-known literary magazine, the inventor of a new display technology, musicians whose work I already admired, a fragrance designer, writers, and, of course, lots of engineers and designers from many different backgrounds. Data scientists, systems hackers, language nerds, someone running a successful currency. I watched these people get projects off the ground, start raising money, plan the future of Urbit hosting companies, and plan new features for Landscape. I saw a last-minute warehouse party come together that kept people talking well into the early hours of the morning.
36+
37+Where did these people come from? All over the place. They have this incredible <em>new world energy</em>. They understand immediately, intuitively that Urbit has the potential to be a foundation for the society they want to live in. I’ve never seen anything like it.
38+
39+This energy seems to have come from the very practical work we do day-to-day: building Urbit, refining it, making it easier to use. The crowd at Assembly was somehow brought together by Urbit itself. It’s insanely exciting. It makes working on Urbit feel even more like a form of definite optimism. The system builds the community and the community builds the system.
40+
41+![Use only beautiful computers](https://storage.googleapis.com/media.urbit.org/site/posts/essays/use-only-computers.JPG)
42+
43+Urbit is ready to be built upon -
44+
45+Sometime in early 2021 we realized that there were many lines of work converging on a single theme: ‘Urbit is ready to be built upon’. This is the spirit we wanted to bring to Assembly, and it was very much in the room in Austin. Some of that feeling is still lingering on the network. I think it comes from some very concrete improvements that have been made to the system.
46+
47+We’ve always wanted Urbit to be maintained by a self-sustaining ecosystem and, early this year, we could see what needed to be done to really let others begin doing so. There were four parallel projects that came together to hit this milestone: Software distribution, star.market, developer and operator guides, and the Foundation roadmap. We talked about all of these things in the Assembly keynote (which you can watch [here](https://www.youtube.com/watch?v=ywj36TUtbS4)), but let’s touch on them one by one.
48+
49+Software distribution
50+
51+The most important thing that we shipped just before Assembly is the ability to actually package and distribute software over Urbit itself. It’s now possible for someone to build an app, package it up, and share it with a friend directly over the network.
52+
53+For their friend, the experience is incredibly nice. You can simply send someone a link and they can install the app and run it themselves, on their own urbit, right away. The whole thing is peer-to-peer, of course. There’s no app store, no vetting process. It’s networked software like it’s supposed to be: people computing together freely.
54+
55+We’ve been saying for years that we want people to build on top of Urbit and we always meant it. Now it’s possible in a way it never has been before. To check it out, watch [this segment](https://www.youtube.com/watch?v=MA8sqFi8Bd8) from Assembly.
56+
57+Software distribution can get better in _a lot_ of ways, and we’re continuing to work on it. But it’s live, and people are experimenting with it already. There’s Chess, there’s Pokur, there are video calls (although they’re still a little buggy). Everyone seems to love ‘pals’ and ‘zone’—but you’ll have to get on the network to check those out.
58+
59+star.market
60+
61+We’ve always used the address space to fund our work as one of the primary Urbit developers. As Urbit has become more useful, and address space has become more expensive, it’s more and more difficult for others to do this. The community saw the need for developers to easily use their granted address space to fund their work and a higher resolution for the Foundation to fund contributions to Urbit.
62+
63+This is what [star.market](https://star.market/) and the WSTR project are for. WSTR is an ERC-20 token that is backed 1:1 by ERC-721 Urbit stars. Unlike a star, a WSTR token can be fractionally divided, allowing for a broader distribution of ownership of Urbit. WSTR was built by the community over the past couple of months with no involvement from Tlon. Tlon did, eventually, help to put together star.market—the interface for interacting with the WSTR contracts safely and securely.
64+
65+I’ve come to think that WSTR can be a powerful tool for funding new Urbit projects. I’m excited to see what both our early community of developers and operators can do with it, as well as the nascent Urbit Foundation.
66+
67+Guides
68+
69+As we make it easier for developers to build software, operators to participate in the economy, and communities to make Urbit their home, we need to improve our documentation. We always like to do things bottom-up: the product work comes first. Well, the product is now live.
70+To this end we recently launched:
71+
72+[operators.urbit.org](https://operators.urbit.org/) collects all of the information about participating in the Urbit economy, running infrastructure nodes, and participating in governance in one place.
73+
74+[developers.urbit.org](https://developers.urbit.org/) has an overhauled program for learning about Urbit as a system and beginning to develop on top of it.
75+
76+[network.urbit.org](https://network.urbit.org/) allows anyone to explore the network. View galaxy transfers or how many planets a star has spawned.
77+
78+We’ve got a lot more planned in this area of work in the coming months, and these three sites are a great start.
79+
80+Urbit Foundation
81+
82+Over these past few years we’ve operated the Urbit Foundation as a ‘protocol’ inside of Tlon. Our goal has been to develop that protocol to the point that it’s refined, working, and can run on its own outside of Tlon.
83+
84+Josh has done an exceptional job running the foundation protocol at Tlon over the last year or so. He and I have been working closely together on everything that Tlon builds, while also coordinating our community of contributors. I’m very excited that the Foundation, with Josh as its Director, is now separating from Tlon as a fully independent entity focussed on supporting the ecosystem.
85+
86+Assembly was the perfect moment to begin formally separating out the Foundation and, as of a week ago, it is an independent entity. We’ve thought long and hard about how to make the Foundation an enduring, stable organization. Josh will be the first Executive Director but, ultimately, the Senate of Galaxies will elect the Board. This will keep the Foundation accountable to the network as a whole and I’m optimistic it can work well.
87+
88+If you’re on the network, you can read more about the Foundation in ~wolref-podlex/foundation.
89+
90+Assembly 2022 -
91+
92+I had more than a few enthusiastic people come up to me at Assembly and ask what we were planning for Assembly 2022. I have absolutely no idea, of course. We poured all our energy into making Assembly 2021 a success.
93+
94+Given what I saw in Austin, I’m pretty confident that next year we’ll be in completely new territory. The goal of this project has always been to build a completely new digital world. And now, it seems to be building itself.
content/blog/2021-11-18-the-promise-and-paradox-of-decentralization.mdnew file+55
@@ -0,0 +1,55 @@
1++++
2+title = "The Promise and Paradox of Decentralization"
3+date = "2021-11-17"
4+description = "Is centralization just a natural tendency of all networks? Are we destined to have a 'decentralization sandwich?'"
5+[extra]
6+author = ""
7+ship = "~lableg-tadrex"
8+image = "https://storage.googleapis.com/media.urbit.org/site/posts/essays/ux-centralization.JPG"
9++++
10+
11+![Presentation](https://storage.googleapis.com/media.urbit.org/site/posts/essays/ux-centralization.JPG)
12+
13+Every so often, a platform will do something outrageous—changing its terms of use, kicking off API partners, restricting [the content category it was built on](https://www.theverge.com/2018/12/3/18123752/tumblr-adult-content-porn-ban-date-explicit-changes-why-safe-mode), banning Donald Trump, failing to ban Donald Trump, etc.—and we'll all realize we're utterly dependent on centralized entities that can make arbitrary and unaccountable decisions. Sure, you can build your own minimal Facebook or Twitter clone, if you really want, but can you build your own Cloudflare? How about your own payment network? If your company does something legal in your country but banned in America, and the US decides to sanction you, which leads to local banks cutting you off because they can't survive without access to the dollar, are you going to build your own reserve currency? Your own Taiwan Semiconductor Manufacturing Co. or ASML?
14+
15+There are, to varying extents, efforts to do all of the above. But what's worth considering is that <em>all of these bans happen through centralized actors running on decentralized systems</em>. The Internet was supposed to be a totally open set of protocols that anyone could interact with, and for a long time it was, and yet getting kicked off Facebook and Twitter means being exiled from public discourse. Banks are regulated, but every country can set up their own banking regulations, and different countries see the social role of banks very differently; for some countries they're a tool of economic planning, for others a way to help connect local companies to global markets, for others a source of money that can be channeled to politically favored groups. The chip industry was historically very open to new entrants; the transistor was developed at Bell Labs, and for political reasons AT&T licensed it to all comers at a low price.
16+
17+And yet all of these originally decentralized systems end up facing some degree of centralization.
18+
19+The promise of a decentralized system is that anyone can build anything they want, because no one owns it. There are three important features of this; two downsides and a caveat:
20+
21+- The first downside to "Anyone can build anything" is that "anyone" means <em>anyone</em>, and the people to whom decentralized systems are the most attractive are the ones who are banned from other systems, often for good reasons. Free speech absolutists want to be defending Aleksandr Solzhenitsyn or Eugene V. Debs or even Lenny Bruce, but if you want to get a sense for the typical piece of content enabled by a totally uncensored communications system, check your spam folder.
22+
23+- The second downside is that a lack of ownership means that no one is responsible when things go wrong. Bitcoin doesn't have a way to censor your decision to move money from one address to another or even a protocol-level sense of whether you're buying Alpaca socks or a rocket launcher. (nb: You are almost certainly not buying a rocket launcher with Bitcoin; you are at best getting scammed, and at worst [getting in trouble](https://www.justice.gov/usao-cdca/pr/los-angeles-county-man-pleads-guilty-federal-charge-attempting-obtain-biological-toxin)). But this also means that the protocol can't tell when you meant to send your life savings to your cold wallet and sent it to the wrong address instead.
24+
25+- The caveat is that, to quote a [<em>Diff</em> piece from last year](https://www.thediff.co/p/amazon-a-new-kind-of-antitrust-risk#:~:text=does%20it%2C%20too.-,Technology-Governance%20Fit,-Pondering%20Durian%20has) ($), "[A]ny decentralized order requires a centralized substrate, and the more decentralized the approach is the more important it is that you can count on the underlying system." This applies to cryptocurrencies (you can trust the protocols) and to the Internet (ditto). It also applies, in an interesting way, to the increasingly decentralized world of free trade and free-flowing capital: money can only flow and deals can only be made if everyone has a consistent sense of property rights and contracts, and the definition of those concepts will typically be determined by whichever participant in a transaction has the more sophisticated financial and legal system. Globalization ends up being a bit like Henry Ford's pitch: you can use any economic paradigm you want, as long as it's the American one.1
26+
27+An open, decentralized system is <em>sparse</em>: there's room for anything, which means that most of the possibility space consists of nothing at all. This creates a natural demand for onramps—Coinbase for figuring out Bitcoin, portals for figuring out the Internet, TSM for turning chip designs into functioning products, and the like. These create a complicated dynamic: these onramps are built on an open system, but part of their function is to close off some of it. And the better they do that, the more value they can capture. Meanwhile, because they have a monopoly on what they've fenced off, their economics support providing a better user experience. Make a really helpful update to the Bitcoin wiki, and you can feel good about yourself and perhaps contribute to the price of Bitcoin in a highly indirect way; design and launch an improved onboarding process at Coinbase and your contribution is quantifiable, and affects your next cycle's equity grants.
28+
29+This privatization proceeds in three different ways:
30+
31+- Some companies start building on an open protocol and then slowly make it their own. Chrome's decision to make the search bar synonymous with the address bar was a slight improvement in the interface, but also a very strong statement that Google had replaced manually typing in URLs as the default way to navigate. (The strongest evidence for this is the frequency of navigational searches; [the most commonly-searched term on Google](https://www.mondovo.com/keywords/) is "Facebook" and [the most frequently searched term on Bing is "Google"](https://www.bloomberg.com/news/articles/2021-09-28/google-tells-judges-it-s-so-popular-it-s-bing-s-top-search-term).) Typing in URLs is a sometimes-decent way to find what you're looking for, though [the half-life of links is about two years](https://blog.zomdir.com/2017/10/the-half-life-of-link-is-two-year.html). But guessing at URLs can be [perilous](https://en.wikipedia.org/wiki/Whitehouse.com). No one is responsible for fixing this, but Google is the closest approximation, because what they are responsible for is solving the "look for something on the Internet and get the wrong result" problem, a different but related one from the broader task of allowing arbitrary site owners to host arbitrary content. Privatizing is effective, and solves problems for users rather than protocol designers. But it does go against the spirit of the original network.
32+
33+- Twitter is another example, except that they basically created their own open mostly-open protocol and then slowly took control of it. Tweets were originally a simple format, with 140 characters of text and a bit more metadata (this made it compatible with SMS, which had a 160-character limit). For a while, Twitter looked like it would operate a novel protocol and let third parties decide what to put on it and what to read off it. And then the company started to realize that an open system was also one where it was trivial to filter out ads and recommendations. So the outside partners gradually got cut off.
34+
35+- Facebook—the product, not the company—is a third example. It essentially implemented a missing element to the protocol: <em>identity matters</em>. When the original protocols were being hammered out, identity was a problem taken care of by the fact that getting online required steep hurdles; if everyone involved is affiliated with a university that trusts them to use a PDP-10 responsibly, spam or abuse were not big concerns. (Not that early usage was [strictly professional](https://www.theguardian.com/science/2013/apr/19/online-high-net-drugs-deal).) With billions of people online, accessing relevant information can mean traversing a graph of people rather than links, so the identities of those people becomes important. To the user, if not to the network itself, a name and relationship is a far more important unique identifier than an IP address.
36+
37+This pattern raises a question: is centralization just a natural tendency of all networks? Are we destined to have a "decentralization sandwich," where there's a hard-to-change set of protocols, something open built on top of <em>that</em>, and a series of closed systems built on top of that, which are the only ones the average person interacts with?
38+
39+One of the interesting alternatives to this is [Urbit](https://urbit.org), which is trying to build a network in which identity exists from the start, and is neither free nor monopolized. One of Urbit's principles is that users own their data, and while they can use third-party services, they're sharing their data with services, not using a login to access information that lives on someone else's servers.
40+
41+This is a nice theoretical solution to the "build your own" problem above: if someone tries to start Twitter-but-without-banning-X, they begin with "Twitter-but-it's-100%-X," which seems bad until they reach the next stage where trolls arrive and they start to learn that Online Censorship is mostly about spam and gore and only occasionally about politics. But if they're moving their data around, and their friends graph with it, then spinning up a separate instance of the same service, pulling in the same content from their friends, and whitelisting someone who's blacklisted elsewhere is a lot more feasible.
42+
43+At least at first. One of the problems with owning your own data is that it ignores the question of what format that data is in. Data formats are sometimes considered carefully, but they can also be hammered out fast to get a minimum viable product out the door. Then they evolve over time, accumulating cruft and complexity, until they might as well be encrypted.
44+
45+And indeed, what's to stop someone from having a proprietary format that's literally encrypted? Or one that gets changed to an encrypted version later on? This is not a trivial point; if you're ever in a position where you absolutely have to share some information that you want to keep secret, the smartest thing to do is share a huge amount of confusing and poorly-explained information, or use an [annoying but technically accurate format](https://www.vice.com/en/article/gv5vxb/crypto-keys-printout-of-edward-snowdens-email-service-lavabit-ladar-levison). Strict and unalterable rules are no match for determined adversaries, whether they're trying to play a prank, make a point, or maximize shareholder value.
46+
47+But the data format questions are not rhetorical: there is actually an answer of sorts, though it's a frustrating one. Software systems are not just lines of code, but the entire extended system of people who maintain, host, and build on platforms. And the norms of those communities can push back against market pressures. I've been spending an increasing amount of time around Urbit users and devs, and they really do view the current centralized model of the Internet as anathema. They are aware that the fun apps we use are all either designed to be addictive from the start or subject to relentless evolutionary pressure to get more addictive. There's a history of [norms evolving in response to new addictive behavior](https://gist.github.com/jm3/6724931). And Urbit's architecture is a lot closer to norms than to the clumsy mechanism of laws; instead of centralized services that own data, there's a set of 256 Urbit identities that can route messages between users. Instead of single points of failure, there are a few hundred fallback options; instead of the binary of on-Facebook-or-anathematized, there's a 2^8 bit gradient.
48+
49+One possibility for the successor to the current Internet is that it will end up being a system designed to support communities that achieve cohesion based on which forms of addictive or socially corrosive technology they reject. Sort of a digital version of the Amish, [not rejecting technology wholesale but carefully considering every new technology before adopting it](https://kk.org/thetechnium/amish-hackers-a/). If you assume that the pace of change in consumer-facing Internet stays high, and that it gets more compelling over time, then in the long run the only options are a) be careful what you use, or b) accept that you're outsourcing a growing share of your decisions to product managers and growth hackers who do not necessarily have your interests at heart.
50+
51+Norms are not a perfect solution to these problems (if they were, we'd only know about issues like novel addictive behaviors, monopolies, and the homogenization of entertainment from history books). And technology can't fully solve social problems. But it can certainly have an effect on them—"you can't solve a social problem with technology" is a good guideline, but technologies mitigate them all the time. What's a streetlight if not a technological solution to the social problem that there are places where it's dangerous to be out when it's dark? What's asymmetric-key cryptography if not a technological solution to the social problem that it's hard to keep secrets? There's still a fundamental tension with open systems, where they get mature enough to be useful at which point the median user's priority is getting things done rather than adhering to the network's original design principles. But a design that recognizes this from the beginning, and a community that wants to make it happen, can stave off decline for a long time. And that's the positive story of technology: we're all fighting against entropy, which is a hard fight to win, but there are long and fascinating stalemates ahead.
52+
53+(Disclosure: I'm long decentralization by way of Bitcoin and Urbit. If you're on Urbit and would like to discuss <em>The Diff</em>, go to ~lableg-tadrex/the-diff.)
54+
55+<sup>1.</sup> There is naturally some resistance to this, both because of conflicts with different countries' norms and with other countries' natural desire to determine their own destiny. So it's a leaky abstraction, but it gets less leaky over time as economies get more integrated and thus more of the world has to standardize. The most direct example of this is the fact that [the dollar's share of global invoices is 4.7x the US's share of global imports](https://www.economist.com/schools-brief/2020/08/27/global-trades-dependence-on-dollars-lessens-its-benefits) ($, <em>Economist</em>). In the same way that English is most likely to be the shared second language of any two randomly-selected people who don't speak it as a first language, the dollar is most likely to be the second most useful currency to anyone in a country that doesn't use dollars.
content/blog/value-of-address-space-pt1.md+1−5
@@ -9,11 +9,7 @@ ship = "~patnes-rigtyn + ~ravmel-ropdyl"
99image = "https://media.urbit.org/site/posts/essays/value-of-address-space-pt1.jpg"
1010+++
1111
12−<br>
13−
14−<img class="ba" src="https://media.urbit.org/site/posts/essays/value-of-address-space-pt1.jpg">
15−
16−<br>
12+![](https://media.urbit.org/site/posts/essays/value-of-address-space-pt1.jpg)
1713
1814_This is the first in a series of three posts on Urbit address space. See also [part 2](https://urbit.org/blog/value-of-address-space-pt2/) and [part 3](https://urbit.org/blog/value-of-address-space-pt3/)._
1915
content/blog/value-of-address-space-pt2.md+11−33
@@ -9,11 +9,7 @@ ship = "~patnes-rigtyn + ~ravmel-ropdyl"
99image = "https://media.urbit.org/site/posts/essays/value-of-address-space-pt2.jpg"
1010+++
1111
12−<br>
13−
14−<img class="ba" src="https://media.urbit.org/site/posts/essays/value-of-address-space-pt2.jpg">
15−
16−<br>
12+![](https://media.urbit.org/site/posts/essays/value-of-address-space-pt2.jpg)
1713
1814_This is the second in a series of three posts on Urbit address space. See also [part 1](https://urbit.org/blog/value-of-address-space-pt1/) and [part 3](https://urbit.org/blog/value-of-address-space-pt3/)._
1915
@@ -25,21 +21,17 @@ Value and price are distinct concepts that often get conflated. In our view, Urb
2521
2622256 galaxies, ~65,000 stars, ~4B planets.
2723
28−<br>
29−
30−<img class="ba w-100" src="https://media.urbit.org/site/posts/essays/value-of-address-space-pt2a.svg">
31−
32−<br>
24+![](https://media.urbit.org/site/posts/essays/value-of-address-space-pt2a.svg)
3325
3426A foundational design principle of the Urbit network is that the address space is limited. This rarity helps qualify Urbit as a [collectible](https://nakamotoinstitute.org/shelling-out/), and thus creates a non-zero acquisition cost for an address. This cost discourages abuses like spam and bot-net attacks. Traditionally, these attacks are made with quasi-unlimited access to IP addresses. The unit economics of acquiring planets for these nefarious purposes is a strong deterrent.
3527
36−There are 256 galaxies on the network. Each galaxy is initialized with ownership of 256 stars. Galaxies act as root nodes for peer discovery and packet routing within the Urbit network, and they are each also entitled to vote on updates to the smart contracts which govern the network. To date, galaxies trade primarily on OTC (over the counter) desks, and rarely appear on the open market.
28+There are 256 galaxies on the network. Each galaxy is initialized with ownership of 255 stars. Galaxies act as root nodes for peer discovery and packet routing within the Urbit network, and they are each also entitled to vote on updates to the smart contracts which govern the network. To date, galaxies trade primarily on OTC (over the counter) desks, and rarely appear on the open market.
3729
38−There are 65,536 total stars on the network. In turn, each star is initialized with ownership of 65,536 planets. Stars currently trade on platforms independent of Tlon, such as [urbit.live](https://urbit.live/) and [opensea.io](https://opensea.io/). The current price range can easily be ascertained on those sites, but as of the time of this writing, stars are selling at a price that greatly discounts their planet holdings.
30+There are 65,280 total stars on the network. In turn, each star is initialized with ownership of 65,535 planets. Stars currently trade on platforms independent of Tlon, such as [urbit.live](https://urbit.live/) and [opensea.io](https://opensea.io/). The current price range can easily be ascertained on those sites, but as of the time of this writing, stars are selling at a price that greatly discounts their planet holdings.
3931
4032One would expect that in an efficient market the relative pricing of stars on one hand, and planets on the other hand would eventually align (so to speak). This may come to pass as the Urbit community increases education about Urbit, and as additional planet sellers and hosting providers enter the space.
4133
42−Finally, there are 4,294,967,296 (or 2<sup>32</sup>) planets on the network. Planets currently trade largely in a range of $10 to $15. We expect planet prices to fluctuate from provider to provider as described in the previous post, based on the quality of services various providers offer. That said, it's worth noting that the cost to configure addresses for distribution is fairly static and this may act as something of a lower bound.
34+Finally, there are 4,294,901,760 (or ~2<sup>32</sup>) planets on the network. Planets currently trade largely in a range of $10 to $15. We expect planet prices to fluctuate from provider to provider as described in the previous post, based on the quality of services various providers offer. That said, it's worth noting that the cost to configure addresses for distribution is fairly static and this may act as something of a lower bound.
4335
4436That said, we also anticipate that planet prices will be abstracted away from most purchasers, and will be included in bundled annual packages of hosting and data routing services. For this reason, infrastructure service providers (i.e. hosting providers) will likely be the best positioned parties to capture value from planet distribution.
4537
@@ -65,31 +57,21 @@ Utility is only one component of a value calculation. To further develop the inq
6557
6658Urbit IDs are individually represented by non-fungible ERC-721 tokens, and can therefore be sold by any platform that supports this token standard. Currently there are three known Urbit-exclusive sales platforms and one generalized ERC-721 platform that list Urbit IDs. Prices for stars and planets are readily available. Volume is low, as no effort has been made to promote the fact of availability, yet the number of [total transactions](https://azimuth.network/stats/events.txt) has increased steadily since the network was launched to Ethereum in 2019, even absent public messaging.
6759
68−<br>
69−<img class="" src="https://media.urbit.org/site/posts/essays/value-of-address-space-pt2-tps.svg">
70−<br>
60+![](https://media.urbit.org/site/posts/essays/value-of-address-space-pt2-tps.svg)
7161
72−<br>
73−<img class="" src="https://media.urbit.org/site/posts/essays/value-of-address-space-pt2-tss.svg">
74−<br>
62+![](https://media.urbit.org/site/posts/essays/value-of-address-space-pt2-tss.svg)
7563
7664Buying non-fungible tokens like Urbit IDs is rather different than trading quasi-fungible tokens like Bitcoin (even setting aside the issue of volume). Each Urbit ID is unique, and so they tend to be purchased by end users for their specific characteristics, rather than generically. As an example, the planet `~parret-barret` sold for about $1,000 at a time when most planets were selling for $10-20, perhaps due to its rhyming name. Planets with circular sigils also often sell for significantly more than other planets — we’re not entirely sure why this is the case.
7765
7866## Planet Sales
7967
80−<br>
81−<img class="" src="https://media.urbit.org/site/posts/essays/value-of-address-space-pt2e-price-eth.svg">
82−<br>
68+![](https://media.urbit.org/site/posts/essays/value-of-address-space-pt2e-price-eth.svg)
8369
84−<br>
85−<img class="" src="https://media.urbit.org/site/posts/essays/value-of-address-space-pt2e-price-btc.svg">
86−<br>
70+![](https://media.urbit.org/site/posts/essays/value-of-address-space-pt2e-price-btc.svg)
8771
8872## Star Sales
8973
90−<br>
91−<img class="w-100" src="https://media.urbit.org/site/posts/essays/value-of-address-space-pt2e-price-btc-usd.svg">
92−<br>
74+![](https://media.urbit.org/site/posts/essays/value-of-address-space-pt2e-price-btc-usd.svg)
9375
9476This ID-specific trading pattern is generally appropriate in our view: Urbit ID isn’t designed to be rapidly traded at high volume. Urbit is more like a house than a fungible good like a currency.
9577
@@ -97,11 +79,7 @@ For the time being buying and selling of Urbit IDs happens through auctions on s
9779
9880Strictly speaking, liquidity is a measure of the degree to which a given asset will change in value due to a given transaction. In that sense, Urbit address space is likely fairly illiquid. But liquidity can’t be properly understood without volume. As noted above, the volume of transactions on the network has been steadily increasing since inception, and yet the price has remained fairly constant. This seems to indicate a healthy ratio.
9981
100−<br>
101−
102−<img class="ba w-100" src="https://media.urbit.org/site/posts/essays/value-of-address-space-pt2b.svg">
103−
104−<br>
82+![](https://media.urbit.org/site/posts/essays/value-of-address-space-pt2b.svg)
10583
10684A further impact on liquidity and volume is that of available supply. At present, the majority of Urbit address space is locked by smart contracts. These lockups began to release at varying linear rates in January 2019. All address space will be completely unlocked and tradeable by January 2025. Eventually as both understanding and demand increase, we anticipate that planets will find an equilibrium price, and stars will be repriced accordingly.
10785
content/blog/value-of-address-space-pt3.md+5−15
@@ -11,9 +11,7 @@ image = "https://media.urbit.org/site/posts/essays/value-of-address-space-pt3.jp
1111
1212<br>
1313
14−<img class="ba" src="https://media.urbit.org/site/posts/essays/value-of-address-space-pt3.jpg">
15−
16−<br>
14+![](https://media.urbit.org/site/posts/essays/value-of-address-space-pt3.jpg)
1715
1816_This is the third in a series of three posts on Urbit address space. See also [part 1](https://urbit.org/blog/value-of-address-space-pt1/) and [part 2](https://urbit.org/blog/value-of-address-space-pt2/)._
1917
@@ -53,13 +51,9 @@ A locked star is held in a contract and can neither be booted nor issue planets.
5351
5452In practice, the only Urbit IDs that are ‘locked’ are stars. A galaxy that is said to be locked is simply a galaxy whose stars are currently held by a lockup contract. A locked galaxy can be transferred (i.e. sold or simply moved to a new key) and booted (importantly, any galaxy—booted or not—can vote), but it can’t issue stars until the lockup contract expires.
5553
56−<br>
57−<img class="ba" src="https://media.urbit.org/site/posts/essays/value-of-address-space-pt3-graph1.png">
58−<br>
54+![Star Unlocking Schedule](https://media.urbit.org/site/posts/essays/value-of-address-space-pt3-graph1.png)
5955
60−<br>
61−<img class="ba" src="https://media.urbit.org/site/posts/essays/value-of-address-space-pt3-graph2.png">
62−<br>
56+![Total Urbit IDs Spawned and Activated](https://media.urbit.org/site/posts/essays/value-of-address-space-pt3-graph2.png)
6357
6458These lockups all began to release at varying linear rates in January 2019 (specifically on Tue Jan 08 23:34:41 2019 UTC).
6559
@@ -78,9 +72,7 @@ Spawning Limits –
7872
7973Unlocked stars are further gated by the number of planets they’re able to spawn. Every unlocked star was immediately able to spawn 1024 planets from the moment Urbit went live on the blockchain in January 2019—we wanted everyone to be able to invite some friends to their communities right away. From that date forward, the spawnable amount doubles every year (365 days), maxing out at 65,535 spawnable planets after 6 years.
8074
81−<br>
82−<img class="ba" src="https://media.urbit.org/site/posts/essays/value-of-address-space-pt3-graph3.png">
83−<br>
75+![Total Spawnable Planets and Spawnable Planets per Star](https://media.urbit.org/site/posts/essays/value-of-address-space-pt3-graph3.png)
8476
8577When we layer the spawning limits over the various lockup contracts, we find that all Urbit address space is both unlocked and spawnable by January 9, 2025.
8678
@@ -92,9 +84,7 @@ We consider the opacity of our understanding about transactions on the network t
9284
9385The chart below is an estimate (as of January 2020) based on our general understanding of how galaxies are distributed. Much of this is anecdotal, and it’s largely based on the very few transactions we’ve observed within the galaxy table since Urbit went on chain in 2019. This chart should therefore be understood as incomplete, and an estimate only.
9486
95−<br>
96−<img class="ba" src="https://media.urbit.org/site/posts/essays/value-of-address-space-pt3-graph4.png">
97−<br>
87+![Estimated Galaxy Distribution](https://media.urbit.org/site/posts/essays/value-of-address-space-pt3-graph4.png)
9888
9989Address space distribution is best understood in terms of galaxies and stars independently, as they’re distinct assets. The chart above only illustrates galaxy distribution, but describes Tlon’s “naked” galaxy holdings, which are galaxies empty of their stars. These galaxies are empty because the stars they once contained have been distributed, primarily to Tlon contractors, employees, and to certain private buyers.
10090
content/docs/_index.md+1−1
@@ -6,7 +6,7 @@ template = "sections/docs.html"
66
77Welcome to the developer documentation for the Urbit project. This documentation
88is maintained by [Tlon](https://tlon.io) and the Urbit community in a public
9−[Github repository](https://github.com/urbit/docs). Issues and contributions are
9+[Github repository](https://github.com/urbit/urbit.org/tree/master/content/docs). Issues and contributions are
1010welcome.
1111
1212This documentation provides a series of explainers, guides, tutorials and
content/docs/arvo/_index.md+2−4
@@ -36,11 +36,11 @@ Eyre is our HTTP server. Unix sends HTTP messages to `%eyre`, and `%eyre` produc
3636
3737Ford is our build system. It handles resources and publishing.
3838
39−## [Gall](/docs/arvo/gall/overview)
39+## [Gall](/docs/arvo/gall/gall)
4040
4141Gall is the vane for controlling userspace apps.
4242
43−## [Iris](/docs/arvo/iris/iris-api)
43+## [Iris](/docs/arvo/iris/iris)
4444
4545Iris is our HTTP client.
4646
@@ -51,5 +51,3 @@ Explanations of design decisions that are pervasive throughout Arvo.
5151## [Tutorials](/docs/arvo/tutorials/)
5252
5353Walkthroughs that teach you more about how Arvo works.
54−
55−
content/docs/arvo/ames/_index.md+20
@@ -5,3 +5,23 @@ sort_by = "weight"
55template = "sections/docs/chapters.html"
66insert_anchor_links = "right"
77+++
8+
9+## [Overview](/docs/arvo/ames/ames)
10+
11+An overview of Ames and its capabilities.
12+
13+## [Cryptography](/docs/arvo/ames/cryptography)
14+
15+A technical overview of how Ames implements cryptography.
16+
17+## [API Reference](/docs/arvo/ames/tasks)
18+
19+The `task`s Ames takes and the `gift`s it returns.
20+
21+## [Scry Reference](/docs/arvo/ames/scry)
22+
23+The scry endpoints of Ames.
24+
25+## [Data Types](/docs/arvo/ames/data-types)
26+
27+Reference documentation of the various data types used by Ames.
content/docs/arvo/ames/ames-api.mddeleted−292
@@ -1,292 +0,0 @@
1−+++
2−title = "API Reference"
3−weight = 10
4−template = "doc.html"
5−+++
6−
7−In this document we describe the public interface for Ames. Namely, we describe
8−each `task` that Ames can be `%pass`ed, and which `gift`(s) Ames can `%give` in return.
9−
10−Some `task`s appear to have more than one arm associated to them, e.g. there are
11−four `+on-hear` arms. We denote this where it occurs, but always refer to the
12−`on-hear:event-core` arm.
13−
14−Ames `task`s can be naturally divided into two categories: messaging tasks and
15−system/lifecycle tasks.
16−
17−## Messaging Tasks
18−
19−### `%hear`
20−
21−`%hear` handles raw packet receipt. This `task` only ever originates from Unix.
22−It does the initial processing of a packet, namely by passing the raw packet
23−information to `+decode-packet` which deserializes the packet and giving that data and the origin of the
24−packet to `+on-hear-packet`, which begins the transformation of the packet into
25−a new event in the form of a `+event-core`.
26−
27−There are multiple `+on-hear` arms in `ames.hoon`. Here we refer to
28−`on-hear:event-core`, as that is the one called by a `%hear` `task`. The other ones are used
29−primarily for ack and nack processing, or receiving message fragments.
30−
31−#### Accepts
32−
33−```hoon
34−[=lane =blob]
35−```
36−
37−`%hear` takes in a `blob`, which is essentially a large atom (around 1kB or less)
38−that is the raw data of the message, and a `lane`, which is the origin of the
39−message (typically an IP address).
40−
41−#### Returns
42−
43−`%hear` can trigger a number of possible returns. It can trigger the release of
44−zero or more additional packets via `%send` `gift`s. It may also trigger a `%boon`
45−or `%plea` `gift` (collectively referred to as a `%memo` within Ames) to a local vane in the case of a completed message.
46−
47−
48−### `%heed`
49−
50−A vane can pass Ames a `%heed` `task` to request Ames track a peer's
51−responsiveness. If our `%boon`s to it start backing up locally,
52−Ames will `give` a `%clog` back to the requesting vane containing the
53−unresponsive peer's Urbit address.
54−
55−Stop tracking a peer by sending Ames a
56−`%jilt` `task`.
57−
58−
59−#### Accepts
60−
61−```hoon
62−=ship
63−```
64−
65−The ship to be tracked.
66−
67−#### Returns
68−
69−If the `ship` is indeed being unresponsive, as measured by backed up `%boon`s,
70−Ames will `give` a `%clog` `gift` to the requesting vane containing the
71−unresponsive peer's urbit address.
72−
73−
74−### `%hole`
75−
76−`%hole` handles packet crash notification. `%hole` works much like `%hear`, in
77−that it passes an incoming raw packet to `+decode-packet` to be deserialized,
78−and then passes that data along with the source of the packet to
79−`+on-hear-packet` along with a `?` set to `%.n` denoting that there is something wrong with
80−the packet.
81−
82−#### Accepts
83−
84−```hoon
85−[=lane =blob]
86−```
87−`%hole` takes in a `blob`, which is essentially a large atom (around 1kB or less)
88−that is the raw data of the message, and a `lane`, which is the origin of the
89−message (typically an IP address).
90−
91−#### Returns
92−
93−Like `%hear`, `%hole` can trigger additional packets in the form of `%send`
94−`gift`s, and may also yield a `%boon` or `%plea` `gift` to a local vane.
95−
96−
97−### `%jilt`
98−
99−`%jilt` stops tracking a potentially unresponsive peer that was previously being
100−tracked as a result of the `%heed` `task`.
101−
102−There are two `+on-jilt` arms, this `task` utilizes `on-hear:event-core`.
103−
104−#### Accepts
105−
106−```hoon
107−=ship
108−```
109−
110−The `ship` we no longer wish to track.
111−
112−#### Returns
113−
114−This `task` returns no `gift`s.
115−
116−
117−### `%plea`
118−
119−`%plea` is the `task` used to instruct Ames to send a message. It extends the
120−`%pass`/`%give` semantics across the network. As such, it is the most
121−fundamental `task` in Ames and the primary reason for its existence.
122−
123−Ames also `pass`es a `%plea` `note` to another vane when it receives a message on a
124−"forward flow" from a peer, originally passed from one of the peer's vanes to the
125−peer's Ames.
126−
127−Ultimately `%plea` causes `%send` `gift`(s) to be sent to Unix, which tells
128−Unix to send packets. In terms of `%pass`/`%give` semantics, this is in
129−response to the `%born` `task`, which came along the Unix `duct`, rather than a
130−response to the `%plea`.
131−
132−#### Accepts
133−
134−```hoon
135−[=ship =plea]
136−```
137−
138−A `%plea` `task` takes in the `ship` the `plea` is addressed to, and a `$plea`,
139−which is
140−
141−```hoon
142− +$ plea [vane=@tas =path payload=*]
143−```
144−Here, `vane` is the destination vane on the remote ship, `path` is the internal
145−route on the receiving ship, and `payload` is the semantic message content.
146−
147−#### Returns
148−
149−This `task` returns no `gift`s.
150−
151−## System and Lifecycle Tasks
152−
153−### `%born`
154−
155−Each time you start your Urbit, the Arvo kernel calls the `%born` task for Ames.
156−
157−#### Accepts
158−
159−`%born` takes no arguments.
160−
161−#### Returns
162−
163−In response to a `%born` `task`, Ames `%give`s Jael a `%turf` `gift`.
164−
165−The `duct` along which `%born` comes is Ames' only duct to Unix, so `%send`
166−`gift`s (which are instructions for Unix to send a packet) are also returned in
167−response to `%born`.
168−
169−
170−### `%crud`
171−
172−`%crud` is called whenever an error involving Ames occurs. It produces a crash
173−report in response.
174−
175−#### Accepts
176−
177−```hoon
178−=error
179−```
180−
181−A `$error` is a `[tag=@tas =tang]`.
182−
183−#### Returns
184−
185−Ames does not `give` a `gift` in response to a `%crud` `task`, but it does
186−`%pass` Dill a `%flog` `task` instructing it to print `error`.
187−
188−
189−## `%init`
190−
191−`%init` is called a single time during the very first boot process, immediately
192−after the [larval stage](/docs/arvo/overview#larval-stage-core)
193−is completed. This initializes the vane. Jael is initialized first, followed by
194−other vanes such as Ames.
195−
196−In response to receiving the `%init` `task`, Ames subscribes to the information
197−contained by Jael.
198−
199−#### Accepts
200−
201−```hoon
202−our=ship
203−```
204−
205−`%init` takes in the name of our ship, which is a `@p`.
206−
207−#### Returns
208−
209−```hoon
210− =~ (emit duct %pass /turf %j %turf ~)
211− (emit duct %pass /private-keys %j %private-keys ~)
212−```
213−
214−`%init` sends two moves that subscribe to `%turf` and `%private-keys` in Jael.
215−
216−
217−### `%sift`
218−
219−This `task` filters debug output by ship.
220−
221−#### Accepts
222−
223−```hoon
224−ships=(list ship)
225−```
226−
227−The list of ships for which debug output is desired.
228−
229−#### Returns
230−
231−This `task` returns no `gift`s.
232−
233−
234−### `%spew`
235−
236−Sets verbosity toggles on debug output. These toggles are as follows.
237−
238−* `%snd` - sending packets
239−* `%rcv` - receiving packets
240−* `%odd` - unusual events
241−* `%msg` - message-level events
242−* `%ges` - congestion control
243−* `%for` - packet forwarding
244−* `%rot` - routing attempts
245−
246−Each toggle is a flag set to `%.n` by default.
247−
248−#### Accepts
249−
250−```hoon
251−verbs=(list verb)
252−```
253−
254−`%spew` takes in a `list` of `verb`, which are verbosity flags for Ames.
255−
256−```hoon
257−+$ verb ?(%snd %rcv %odd %msg %ges %for %rot)
258−```
259−
260−`%spew` flips each toggle given in `verbs`.
261−
262−#### Returns
263−
264−This `task` returns no `gift`s.
265−
266−
267−### `%vega`
268−
269−`%vega` is called whenever the kernel is updated. Ames currently does not do
270−anything in response to this.
271−
272−#### Accepts
273−
274−`%vega` takes no arguments.
275−
276−#### Returns
277−
278−This `task` returns no `gift`s.
279−
280−
281−### `%wegh`
282−
283−This `task` is a request to Ames to produce a memory usage report.
284−
285−#### Accepts
286−
287−This `task` has no arguments.
288−
289−#### Returns
290−
291−In response to this `task,` Ames `%give`s a `%mass` `gift` containing Ames'
292−current memory usage.
content/docs/arvo/ames/ames.md+75−75
@@ -4,6 +4,7 @@ weight = 1
44template = "doc.html"
55aliases = ["/docs/learn/arvo/ames/"]
66+++
7+
78Our networking protocol.
89
910Ames is the name of both our network and the vane that communicates
@@ -11,7 +12,7 @@ over it. When Unix receives a packet over the correct UDP port, it pipes
1112it straight into Ames for handling. Also, all packets sent over the
1213Ames network are sent by the Ames vane. Apps and vanes may use
1314Ames to directly send messages to other ships. In general, apps use
14−[Gall](/docs/userspace/gall/gall) and [Clay](/docs/arvo/clay/clay)
15+[Gall](/docs/arvo/gall/gall) and [Clay](/docs/arvo/clay/clay)
1516to communicate with other ships rather than using Ames
1617directly, but this isn't a requirement. Of course, Gall and Clay use
1718Ames behind the scenes to communicate across the network. Jael is the only other
@@ -25,32 +26,33 @@ protocol itself, including how to route incoming packets to the correct
2526vane or app, is defined in Ames.
2627
2728## Technical Overview
29+
2830This section summarizes the design of Ames. Beyond this section are deeper
2931elaborations on the concepts presented here.
3032
3133Ames extends [Arvo's](/docs/arvo/overview) `%pass`/`%give` `move` semantics across the network.
3234
3335Ames receives packets as Arvo events and emits packets as Arvo
34−effects. The runtime is responsible for transferring the bytes in
36+effects. The runtime is responsible for transferring the bytes in
3537an Ames packet across a physical network to another ship.
3638
3739The runtime tells Ames which physical address a packet came from,
38−represented as an opaque atom. Ames can emit a packet effect to
40+represented as an opaque atom. Ames can emit a packet effect to
3941one of those opaque atoms or to the Urbit address of a galaxy
4042(root node), which the runtime is responsible for translating to a
41−physical address. One runtime implementation sends UDP packets
43+physical address. One runtime implementation sends UDP packets
4244using IPv4 addresses for ships and DNS lookups for galaxies, but
4345other implementations may overlay over other kinds of networks.
4446
45−A local vane can pass Ames a `%plea` request message. Ames
47+A local vane can pass Ames a `%plea` request message. Ames
4648transmits the message over the wire to the peer ship's Ames, which
4749passes the message to the destination vane.
4850
4951Once the peer has processed the `%plea` message, it sends a
5052message-acknowledgment packet over the wire back to the local
51−Ames. This "ack" can either be positive to indicate the request was
53+Ames. This "ack" can either be positive to indicate the request was
5254processed, or negative to indicate the request failed, in which
53−case it's called a "nack". (Don't confuse Ames nacks with TCP
55+case it's called a "nack". (Don't confuse Ames nacks with TCP
5456nacks, which are a different concept).
5557
5658When the local Ames receives either a positive message-ack or a
@@ -60,11 +62,11 @@ requested the original `%plea` message be sent.
6062
6163A local vane can give Ames zero or more `%boon` response messages in
6264response to a `%plea`, on the same duct that Ames used to pass the
63−`%plea` to the vane. Ames transmits a `%boon` over the wire to the
65+`%plea` to the vane. Ames transmits a `%boon` over the wire to the
6466peer's Ames, which gives it to the destination vane on the same
6567duct the vane had used to pass the original `%plea` to Ames.
6668
67−`%boon` messages are acked automatically by the receiver Ames. They
69+`%boon` messages are acked automatically by the receiver Ames. They
6870cannot be nacked, and Ames only uses the ack internally, without
6971notifying the client vane that gave Ames the `%boon`.
7072
@@ -74,15 +76,15 @@ indicating the `%boon` was missed.
7476
7577`%plea` messages can be nacked, in which case the peer will send
7678both a message-nack packet and a naxplanation message, which is
77−sent in a way that does not interfere with normal operation. The
79+sent in a way that does not interfere with normal operation. The
7880naxplanation is sent as a full Ames message, instead of just a
7981packet, because the contained error information can be arbitrarily
80−large. A naxplanation can only give rise to a positive ack --
82+large. A naxplanation can only give rise to a positive ack --
8183never ack an ack, and never nack a naxplanation.
8284
8385Ames guarantees a total ordering of messages within a "flow",
8486identified in other vanes by a duct and over the wire by a `bone`:
85−an opaque number. Each flow has a FIFO (first-in-first-out) queue of `%plea` requests
87+an opaque number. Each flow has a FIFO (first-in-first-out) queue of `%plea` requests
8688from the requesting ship to the responding ship and a FIFO queue
8789of `%boon`'s in the other direction.
8890
@@ -94,23 +96,23 @@ destination vane.
9496
9597Ames encrypts every message using symmetric-key encryption by
9698performing an elliptic curve Diffie-Hellman using our private key
97−and the public key of the peer. For ships in the Jael PKI
99+and the public key of the peer. For ships in the Jael PKI
98100(public-key infrastructure), Ames looks up the peer's public key
99−from Jael. Comets (128-bit ephemeral addresses) are not
101+from Jael. Comets (128-bit ephemeral addresses) are not
100102cryptographic assets and must self-attest over Ames by sending a
101103single self-signed packet containing their public key.
102104
103105When a peer suffers a continuity breach, Ames removes all
104−messaging state related to it. Ames does not guarantee that all
105−messages will be fully delivered to the now-stale peer. From
106+messaging state related to it. Ames does not guarantee that all
107+messages will be fully delivered to the now-stale peer. From
106108Ames's perspective, the newly restarted peer is a new ship.
107109Ames's guarantees are not maintained across a breach.
108110
109111A vane can pass Ames a `%heed` `$task` to request Ames track a peer's
110−responsiveness. If our `%boon`'s to it start backing up locally,
112+responsiveness. If our `%boon`'s to it start backing up locally,
111113Ames will give a `%clog` back to the requesting vane containing the
112−unresponsive peer's urbit address. This interaction does not use
113−ducts as unique keys. Stop tracking a peer by sending Ames a
114+unresponsive peer's urbit address. This interaction does not use
115+ducts as unique keys. Stop tracking a peer by sending Ames a
114116`%jilt` `$task`.
115117
116118Debug output can be adjusted using `%sift` and `%spew` `$task`'s.
@@ -128,46 +130,46 @@ There is a 32-bit header followed by a variable width body.
128130
129131The 32-bit header is given by the following data, presented in order:
130132
131− - 3 bits: reserved
132− - 1 bit: is this Ames? (i.e. not using a different protocol, such as the
133− planned remote scry protocol)
134− - 3 bits: Ames protocol version (currently 0)
135− - 2 bits: sender address size
136− - 2 bits: receiver address size
137− - 20 bits: checksum (truncated insecure hash of the body, done with
138− [`+mug`](/docs/hoon/reference/stdlib/2e#mug)
139− - 1 bit: is this relayed? (if set, `origin` will be present in the body)
133+- 3 bits: reserved
134+- 1 bit: is this Ames? (i.e. not using a different protocol, such as the
135+ planned remote scry protocol)
136+- 3 bits: Ames protocol version (currently 0)
137+- 2 bits: sender address size
138+- 2 bits: receiver address size
139+- 20 bits: checksum (truncated insecure hash of the body, done with
140+ [`+mug`](/docs/hoon/reference/stdlib/2e#mug)
141+- 1 bit: is this relayed? (if set, `origin` will be present in the body)
140142
141− Every packet sent between ships is encrypted except for self-signed attestation packets from 128-bit comets.
143+Every packet sent between ships is encrypted except for self-signed attestation packets from 128-bit comets.
142144
143145#### Body
144146
145147The body is of variable length and consists of the following parts in this
146148order:
147149
148− - 4 bits: sender life (mod 16)
149− - 4 bits: receiver life (mod 16)
150− - variable: sender address
151− - variable: receiver address
152− - 48 bits: (optional) 48-bit `origin`
153− - 128 bits: `SIV`
154− - 16 bits: ciphertext size
155− - variable: ciphertext
156−
157− `origin` is the IP and port of the original sender if the packet was proxied
158− through a relay.
159−
160− `SIV` is a "synthetic initialization vector" as defined in AES-256 SIV, the encryption
161− algorithm utilized to encrypt Ames packets (see the page on [Ames
162− cryptography](/docs/arvo/ames/cryptography)). It is formed from the
163− following noun: `~[sender=@p receiver=@p sender-life=@ receiver-life=@]` (see
164− [Life and Rift](/docs/azimuth/life-and-rift) for information on what `life`
165− is). As this data is in Azimuth, it is not explicitly sent over the wire. Thus
166− the mod 16 sender and receiver life in the first 8 bits are only for quick
167− filtering of honest packets sent to or from a stale life.
168−
169− The ciphertext is formed by `+jam`ming a `$shut-packet` and then encrypting
170− using [`+en:sivc:aes:crypto`](/docs/arvo/reference/cryptography#en).
150+- 4 bits: sender life (mod 16)
151+- 4 bits: receiver life (mod 16)
152+- variable: sender address
153+- variable: receiver address
154+- 48 bits: (optional) 48-bit `origin`
155+- 128 bits: `SIV`
156+- 16 bits: ciphertext size
157+- variable: ciphertext
158+
159+`origin` is the IP and port of the original sender if the packet was proxied
160+through a relay.
161+
162+`SIV` is a "synthetic initialization vector" as defined in AES-256 SIV, the encryption
163+algorithm utilized to encrypt Ames packets (see the page on [Ames
164+cryptography](/docs/arvo/ames/cryptography)). It is formed from the
165+following noun: `~[sender=@p receiver=@p sender-life=@ receiver-life=@]` (see
166+[Life and Rift](/docs/azimuth/life-and-rift) for information on what `life`
167+is). As this data is in Azimuth, it is not explicitly sent over the wire. Thus
168+the mod 16 sender and receiver life in the first 8 bits are only for quick
169+filtering of honest packets sent to or from a stale life.
170+
171+The ciphertext is formed by `+jam`ming a `$shut-packet` and then encrypting
172+using [`+en:sivc:aes:crypto`](/docs/arvo/reference/cryptography#en).
171173
172174### Packeting
173175
@@ -187,9 +189,7 @@ eventually get through, and when the other side gets them it can put them in the
187189correct order. If Ames doesn't get an ack on a packet then it will resend it
188190until it does. The logic for determining how many packets to send or re-send at what time is performed by an Ames-specific variant of TCP's "NewReno" congestion control algorithm.
189191
190−As each packet in a message is received, Ames decrypts it and stores the message fragment. Once it's received every packet for a message, Ames concatenates the fragments back into a single large atom and uses `+cue` to deserialize that back into the original message noun.
191−
192−
192+As each packet in a message is received, Ames decrypts it and stores the message fragment. Once it's received every packet for a message, Ames concatenates the fragments back into a single large atom and uses `+cue` to deserialize that back into the original message noun.
193193
194194### Acks and Nacks
195195
@@ -221,8 +221,7 @@ Thus a message-level ack must be received before the next message on the flow
221221can begin. The full story is more complicated than this; see the section on
222222[flows](#flows).
223223
224−
225−#### Nacks
224+#### Nacks {#nacks}
226225
227226A nack indicates a negative acknowledgement to a `%plea`, meaning that the
228227requested action was not performed.
@@ -248,9 +247,11 @@ the receiver will never both perform a `%plea` and return a naxplanation.
248247
249248A fragment ack's contents (before encryption) are a pure function of the
250249following noun:
250+
251251```hoon
252252[our-life her-life bone message-num fragment-num]
253253```
254+
254255This means all re-sends of an ack packet will be bitwise identical to each other, unless one of the peers changes its encryption keys.
255256
256257Each datum in this noun is an atom with the aura `@ud` or an aura that nests
@@ -269,11 +270,11 @@ A message (n)ack is a different kind of ack that is obtained by encrypting the
269270```hoon
270271[our-life her-life bone message-num ok=? lag=@dr]
271272```
273+
272274`ok` is a flag that is set to `%.y` for a message ack and `%.n` for a message
273275nack. In the future, `lag` will be used to
274276describe the time it took to process a message, but for now it is always zero.
275277
276−
277278### Flows
278279
279280Flows are asymmetric communication channels along which two ships send and
@@ -300,10 +301,10 @@ We give an example of such a partition. Let flow 12 be a flow between `~bacbel-t
300301`~bacbel-tagfeg` as the `%plea` sender. Then bones 12-15 are associated with the
301302flow, and the types of packets for each bone are:
302303
303− - bone 12, `%plea`s and acks to `~worwel-sipnum`,
304− - bone 13, `%boon`s and (n)acks to `~bacbel-tagfeg`,
305− - bone 14, acks of naxplanations to `~worwel-sipnum`,
306− - bone 15, naxplanations to `~bacbel-tagfeg`.
304+- bone 12, `%plea`s and acks to `~worwel-sipnum`,
305+- bone 13, `%boon`s and (n)acks to `~bacbel-tagfeg`,
306+- bone 14, acks of naxplanations to `~worwel-sipnum`,
307+- bone 15, naxplanations to `~bacbel-tagfeg`.
307308
308309Each bone is handled separately by congestion control, and this is one reason
309310for their segregation. For example, say a two-packet `%plea` is sent on bone 12,
@@ -379,16 +380,17 @@ private key and the public key of `~worwel-sipnum`, obtained via Jael. Then
379380`~bacbel-tagfeb` sends a packet addressed to `~worwel-sipnum` to `~zod`.
380381
381382The packet has the following format:
382− - The standard Ames header described in [header](#header), where the checksum
383− is the `+mug` of the body, and the sender and receiver ship types are `01`,
384− denoting that the sender and receiver are planets. The "is this relayed?" bit
385− is set to 0 since this is the first hop on the packet route.
386− - The body of this packet will be the life of `~bacbel-tagfeg` mod 16, followed
387− by the life of `~worwel-sipnum` mod 16, followed by `~bacbel-tagfeg`,
388− followed by the receiver `~worwel-sipnum`, followed by the origin `~`
389− (denoting that the ship sending the packet is the origin). After this comes
390− the payload.
391− - The payload of this packet will be the `+jam` of the `content`, which is an encrypted fragment of the message `%watch /path/to/recipes`.
383+
384+- The standard Ames header described in [header](#header), where the checksum
385+ is the `+mug` of the body, and the sender and receiver ship types are `01`,
386+ denoting that the sender and receiver are planets. The "is this relayed?" bit
387+ is set to 0 since this is the first hop on the packet route.
388+- The body of this packet will be the life of `~bacbel-tagfeg` mod 16, followed
389+ by the life of `~worwel-sipnum` mod 16, followed by `~bacbel-tagfeg`,
390+ followed by the receiver `~worwel-sipnum`, followed by the origin `~`
391+ (denoting that the ship sending the packet is the origin). After this comes
392+ the payload.
393+- The payload of this packet will be the `+jam` of the `content`, which is an encrypted fragment of the message `%watch /path/to/recipes`.
392394
393395`~zod` receives the packet and reads the body. It sees that it is not the
394396intended recipient of the packet, and so gets ready to forward it to
@@ -398,8 +400,7 @@ with the new mug. Since the packet is being relayed, `~zod` flips the "is it
398400relayed?" bit to `%.y`. `~zod` then forwards the packet to `~worwel-sipnum`.
399401
400402In order to decrypt the packet, `~worwel-sipnum` will need to calculate the
401−associated data vector utilized by SIV, which consists of `~[sender=@p
402−receiver=@p sender-life=@ receiver-life=@]`. It then passes that along with the
403+associated data vector utilized by SIV, which consists of `~[sender=@p receiver=@p sender-life=@ receiver-life=@]`. It then passes that along with the
403404SIV and ciphertext to the decryption function, and receives the unencrypted
404405packet as a return.
405406
@@ -463,4 +464,3 @@ hands it off the the Unix network interface to be sent.
463464Now the receiving King is handed a UDP packet by Unix. The King removes the UDP
464465wrapper, `+jam`s the `lane` on which it heard the packet, and delivers the packet
465466to the Ames vane as an atom by copying the bytes it heard on the UDP port.
466−
content/docs/arvo/ames/cryptography.md+3−3
@@ -1,6 +1,6 @@
11+++
22title = "Cryptography"
3−weight = 5
3+weight = 2
44template = "doc.html"
55+++
66
@@ -34,7 +34,7 @@ Algorithm](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algori
3434is used for authentication
3535
3636The encrypted payload of each packet is a `$shut-packet`, which is the `+jam` of
37−a cell with the `bone`, message number, and message fragment or ack (see
37+a cell with the [$bone](/docs/arvo/ames/data-types#bone), message number, and message fragment or ack (see
3838[Ames](/docs/arvo/ames/ames) for more information on packet structure). The
3939message fragment is signed using the authentication key. It is encrypted using
4040[`+en:crub:crypto`](/docs/arvo/reference/cryptography#en) found in
@@ -43,7 +43,7 @@ message fragment is signed using the authentication key. It is encrypted using
4343## Diffie-Hellman key exchange {#key-exchange}
4444
4545For each foreign ship a given ship has communicated with, `$ames-state` contains a
46−`$peer-state`, inside which the `$symmetric-key` (an atom which nests under
46+[$peer-state](/docs/arvo/ames/data-types#peer-state), inside which the [$symmetric-key](/docs/arvo/ames/data-types#symmetric-key) (an atom which nests under
4747`@uw`) is utilized for encrypting all Ames packets shared between the two ships.
4848The `symmetric-key` is derived using [`+shar:ed:crypto`](/docs/arvo/reference/cryptography#ed) found in `sys/zuse.hoon`,
4949which is an arm utilized for generating the symmetric key for elliptic curve
content/docs/arvo/ames/data-types.mdnew file+389
@@ -0,0 +1,389 @@
1++++
2+title = "Data Types"
3+weight = 5
4+template = "doc.html"
5++++
6+
7+Here are the data types used by Ames, as defined in `lull.hoon`.
8+
9+## `$address`
10+
11+```hoon
12++$ address @uxaddress
13+```
14+
15+Opaque atomic transport address to or from Unix. For Ames over UDP, it will encode the IP address and port.
16+
17+## `$verb`
18+
19+```hoon
20++$ verb ?(%snd %rcv %odd %msg %ges %for %rot)
21+```
22+
23+Verbosity flag for Ames. Use with `|ames-verb %flag1 %flag2 ...` and turn off with `|ames-verb`.
24+
25+- `%snd` - Sending packets.
26+- `%rcv` - Receiving packets.
27+- `%odd` - Unusual events.
28+- `%msg` - Message-level events.
29+- `%ges` - Congestion control.
30+- `%for` - Packet forwarding.
31+- `%rot` - Routing attempts.
32+
33+## `$blob`
34+
35+```hoon
36++$ blob @uxblob
37+```
38+
39+Raw atom to or from Unix, representing a packet.
40+
41+## `$error`
42+
43+```hoon
44++$ error [tag=@tas =tang]
45+```
46+
47+Tagged diagnostic trace.
48+
49+## `$lane`
50+
51+```hoon
52++$ lane (each @pC address)
53+```
54+
55+Ship transport address; either opaque [$address](#address) or galaxy. The runtime knows how to look up galaxies, so we don't need to know their transport addresses.
56+
57+## `$plea`
58+
59+```hoon
60++$ plea [vane=@tas =path payload=*]
61+```
62+
63+Application-level message, as a `%pass`.
64+
65+- `vane` - Destination vane on remote ship.
66+- `path` - Internal route on the receiving ship.
67+- `payload` - Semantic message contents.
68+
69+## `$bone`
70+
71+```hoon
72++$ bone @udbone
73+```
74+
75+Message flow index - mapped to `duct`s in the [$ossuary](#ossuary).
76+
77+The first `bone` is 0. They increment by 4, since each flow includes a bit for each message determining forward vs. backward and a second bit for whether the message is on the normal flow or the associated diagnostic flow (for naxplanations).
78+
79+The least significant bit of a `bone` is:
80+
81+- 1 if "forward", i.e. we send `%plea`s on this flow.
82+- 0 if "backward", i.e. we receive `%plea`s on this flow.
83+
84+The second-least significant bit is 1 if the `bone` is a naxplanation `bone`, and 0 otherwise. Only naxplanation messages can be sent on a naxplanation `bone`, as `%boon`s.
85+
86+## `$fragment`
87+
88+```hoon
89++$ fragment @uwfragment
90+```
91+
92+A message fragment.
93+
94+## `$fragment-num`
95+
96+```hoon
97++$ fragment-num @udfragmentnum
98+```
99+
100+Message fragment count.
101+
102+## `$message-blob`
103+
104+```hoon
105++$ message-blob @udmessageblob
106+```
107+
108+Unfragmented message blob.
109+
110+## `$message-num`
111+
112+```hoon
113++$ message-num @udmessagenum
114+```
115+
116+Message count.
117+
118+## `$public-key`
119+
120+```hoon
121++$ public-key @uwpublickey
122+```
123+
124+A peer's public key.
125+
126+## `$symmetric-key`
127+
128+```hoon
129++$ symmetric-key @uwsymmetrickey
130+```
131+
132+A symmetric key for encrypting messages to a peer. This is produced by performing an elliptic curve Diffie-Hellman using our private key and the peer's public key.
133+
134+## `$ack`
135+
136+```hoon
137++$ ack
138+ $% [%ok ~]
139+ [%nack ~]
140+ [%naxplanation =error]
141+ ==
142+```
143+
144+A message acknowledgement.
145+
146+- `%ok` - Positive acknowledgement.
147+- `%nack` - Negative acknowledgement.
148+- `%naxplanation` - Nack trace.
149+
150+## `$ship-state`
151+
152+```hoon
153++$ ship-state
154+ $% [%alien alien-agenda]
155+ [%known peer-state]
156+ ==
157+```
158+
159+All Ames knows about a peer.
160+
161+- `%alien` - No PKI data, so enqueue actions to perform once we learn it.
162+- `%known` - We know their `life` and public keys, so we have a channel.
163+
164+## `$alien-agenda`
165+
166+```hoon
167++$ alien-agenda
168+ $: messages=(list [=duct =plea])
169+ packets=(set =blob)
170+ heeds=(set duct)
171+ ==
172+```
173+
174+What to do when Ames learns a peer's life and keys.
175+
176+- `messages` - [$plea](#plea)s local vanes have asked Ames to send.
177+- `packets` - Packets we've tried to send.
178+- `heeds` - Local tracking requests; passed through into [$peer-state](#peer-state).
179+
180+## `$peer-state`
181+
182+```hoon
183++$ peer-state
184+ $: $: =symmetric-key
185+ =life
186+ =public-key
187+ sponsor=ship
188+ ==
189+ route=(unit [direct=? =lane])
190+ =qos
191+ =ossuary
192+ snd=(map bone message-pump-state)
193+ rcv=(map bone message-sink-state)
194+ nax=(set [=bone =message-num])
195+ heeds=(set duct)
196+ ==
197+```
198+
199+State for a peer with known life and keys.
200+
201+- `route` - Transport-layer destination for packets to the peer.
202+- `qos` - Quality of service; connection status to the peer.
203+- `ossuary` - [$bone](#bone) to `duct` mapper.
204+- `snd` - Per-`bone` message pumps to send messages as fragments.
205+- `rcv` - Per-`bone` message sinks to assemble messages from fragments.
206+- `nax` - Unprocessed nacks (negative acknowledgments).
207+- `heeds` - Listeners for `%clog` notifications.
208+
209+## `$qos`
210+
211+```hoon
212++$ qos
213+ $~ [%unborn *@da]
214+ [?(%live %dead %unborn) last-contact=@da]
215+```
216+
217+Quality of service; how is the connection to a peer doing?
218+
219+- `%live` - Peer is ok.
220+- `%dead` - Peer is not responding.
221+- `%unborn` - Peer is sunken.
222+- `last-contact` - Last time Ames heard from the peer, or if `%unborn`, the time when we first started tracking then.
223+
224+## `$ossuary`
225+
226+```hoon
227++$ ossuary
228+ $: =next=bone
229+ by-duct=(map duct bone)
230+ by-bone=(map bone duct)
231+ ==
232+```
233+
234+[$bone](#bone) to `duct` mapping, `next` is the next `bone` to map to a `duct`.
235+
236+## `$message-pump-state`
237+
238+```hoon
239++$ message-pump-state
240+ $: current=_`message-num`1
241+ next=_`message-num`1
242+ unsent-messages=(qeu message-blob)
243+ unsent-fragments=(list static-fragment)
244+ queued-message-acks=(map message-num ack)
245+ =packet-pump-state
246+ ==
247+```
248+
249+Persistent state for a `|message-pump`.
250+
251+- `current`- Sequence number of earliest message sent or being sent.
252+- `next` - Sequence number of next message to send.
253+- `unsent-messages` - Messages to be sent after current message.
254+- `unsent-fragments` - Fragments of current message waiting for sending.
255+- `queued-message-acks` - Future message acks to be applied after current.
256+- `packet-pump-state` - State of corresponding `|packet-pump`.
257+
258+## `$static-fragment`
259+
260+```hoon
261++$ static-fragment
262+ $: =message-num
263+ num-fragments=fragment-num
264+ =fragment-num
265+ =fragment
266+ ==
267+```
268+
269+A packet; a fragment of a message and metadata.
270+
271+## `$packet-pump-state`
272+
273+```hoon
274++$ packet-pump-state
275+ $: next-wake=(unit @da)
276+ live=(tree [live-packet-key live-packet-val])
277+ metrics=pump-metrics
278+ ==
279+```
280+
281+Persistent state for a `|packet-pump`.
282+
283+- `next-wake` - Last timer we've set, or null.
284+- `live` - Packets in flight; sent but not yet acked.
285+- `metrics` - Congestion control information.
286+
287+## `$pump-metrics`
288+
289+```hoon
290++$ pump-metrics
291+ $: rto=_~s1
292+ rtt=_~s1
293+ rttvar=_~s1
294+ ssthresh=_10.000
295+ cwnd=_1
296+ num-live=@ud
297+ counter=@ud
298+ ==
299+```
300+
301+Congestion control state for a `|packet-pump`.
302+
303+- `rto` - Retransmission timeout.
304+- `rtt` - Roundtrip time estimate, low-passed using EWMA.
305+- `rttvar` - Mean deviation of `rtt`, also low-passed with EWMA.
306+- `num-live` - How many packets sent, awaiting ack.
307+- `ssthresh` - Slow-start threshold.
308+- `cwnd` - Congestion window; max unacked packets.
309+
310+## `$live-packet`
311+
312+```hoon
313++$ live-packet
314+ $: key=live-packet-key
315+ val=live-packet-val
316+ ==
317+```
318+
319+A packet in flight, as tracked in the [$packet-pump-state](#packet-pump-state).
320+
321+## `$live-packet-key`
322+
323+```hoon
324++$ live-packet-key
325+ $: =message-num
326+ =fragment-num
327+ ==
328+```
329+
330+Identifier of a packet in flight.
331+
332+## `$live-packet-val`
333+
334+```hoon
335++$ live-packet-val
336+ $: packet-state
337+ num-fragments=fragment-num
338+ =fragment
339+ ==
340+```
341+
342+Content and metadata about a packet in flight.
343+
344+## `$packet-state`
345+
346+```hoon
347++$ packet-state
348+ $: last-sent=@da
349+ retries=@ud
350+ skips=@ud
351+ ==
352+```
353+
354+Sending statistics about a packet in flight.
355+
356+## `$message-sink-state`
357+
358+```hoon
359++$ message-sink-state
360+ $: last-acked=message-num
361+ last-heard=message-num
362+ pending-vane-ack=(qeu [=message-num message=*])
363+ live-messages=(map message-num partial-rcv-message)
364+ nax=(set message-num)
365+ ==
366+```
367+
368+State of a `|message-sink` to assemble received messages.
369+
370+- `last-acked` - Highest [$message-num](#message-num) Ames has fully acknowledged.
371+- `last-heard` - Highest `message-num` Ames has heard all fragments for.
372+- `pending-vane-ack` - Heard but not processed by local vane.
373+- `live-messages` - Partially received messages.
374+
375+## `$partial-rcv-message`
376+
377+```hoon
378++$ partial-rcv-message
379+ $: num-fragments=fragment-num
380+ num-received=fragment-num
381+ fragments=(map fragment-num fragment)
382+ ==
383+```
384+
385+A message for which Ames has received some fragments.
386+
387+- `num-fragments` - Total number of fragments in the message.
388+- `num-received` - How many fragments Ames has received so far.
389+- `fragments` - The received fragments themselves.
content/docs/arvo/ames/scry.mdnew file+126
@@ -0,0 +1,126 @@
1++++
2+title = "Scry Reference"
3+weight = 4
4+template = "doc.html"
5++++
6+
7+Here are the scry endpoints of Ames. All of them take a `%x` `care` and require the `desk` in the path prefix be empty, so the general format is `.^([type] %ax /=//=/[some-path])`.
8+
9+## /protocol/version
10+
11+A scry with a `%x` `care` and a `path` of `/protocol/version` will return the current Ames protocol version as a `@`.
12+
13+#### Example
14+
15+```
16+> .^(@ %ax /=//=/protocol/version)
17+0
18+```
19+
20+## /peers
21+
22+A scry with a `%x` `care` and a `path` of `/peers` will return all ships that Ames is aware of. The type returned is a `(map ship ?(%alien %known))`, where `%known` means we have PKI data for them and `%alien` means we don't.
23+
24+#### Example
25+
26+```
27+> .^((map ship ?(%alien %known)) %ax /=//=/peers)
28+{[p=~wet q=%known] [p=~nes q=%known]}
29+```
30+
31+## /peers/[ship]
32+
33+A scry with a `%x` `care` and a `path` of `/peers/[ship]` where `[ship]` is a ship name like `~dopzod` will return everything Ames knows about that ship, or crash if the ship is unknown to Ames. The type returned is a [$ship-state](/docs/arvo/ames/data-types#ship-state).
34+
35+#### Example
36+
37+```
38+> .^(ship-state:ames %ax /=//=/peers/~nes)
39+[ %known
40+ [ symmetric-key=0wEF.5-Mp4.ehBxk.a-ktl.CAUHq.~XNVq.AfPFk.TwBbj.rc7MS
41+ life=1
42+ public-key=0w9R.IG6Km.CQfuL.lP9Da.l~kh1.lOHzV.xactk.1ybiB.hekW~.VC2d0.DDRsU.h6GHl.PKmRX.p3u2-.vO4Hg.QTOlp.A4AI0.uGPVy
43+ sponsor=~nes
44+ ]
45+ route=[~ [direct=%.y lane=[%.y p=~nes]]]
46+ qos=[%dead last-contact=~2021.8.9..16.11.36..fdbc]
47+ ossuary
48+ [ next-bone=4
49+ by-duct={[p=~[/gall/sys/way/~nes/hood /gall/use/hood/0w2.4d7EV/out/~nes/hood/helm/hi/~nes /dill //term/1] q=0]}
50+ by-bone={[p=0 q=~[/gall/sys/way/~nes/hood /gall/use/hood/0w2.4d7EV/out/~nes/hood/helm/hi/~nes /dill //term/1]]}
51+ ]
52+ snd
53+ { [ p=0
54+ q
55+ [ current=2
56+ next=3
57+ unsent-messages={}
58+ unsent-fragments=~
59+ queued-message-acks={}
60+ packet-pump-state
61+ [ next-wake=[~ ~2021.8.17..02.21.14..3d23]
62+ live={[[message-num=2 fragment-num=0] [last-sent=~2021.8.17..02.19.14..3d23 retries=2.255 skips=0] num-fragments=1 fragment=0w2.QJ1qS.JzaQn.w7rMp.IzuTJ.7M7aP.-1s~1]}
63+ metrics=[rto=~m2 rtt=~s1 rttvar=~s1 ssthresh=1 cwnd=1 num-live=1 counter=1]
64+ ]
65+ ]
66+ ]
67+ }
68+ rcv={}
69+ nax={}
70+ heeds={~[/gall/sys/lag /dill //term/1]}
71+]
72+```
73+
74+## /peers/[ship]/forward-lane
75+
76+A scry with a `%x` `care` and a `path` of `/peers/[ship]/forward-lane` where `[ship]` is a ship name like `~dopzod` will return outbound routes to the given ship, or `~` if there are none. The type returned is a `(list lane:ames)`, see [$lane](/docs/arvo/ames/data-types#lane) for type details.
77+
78+#### Examples
79+
80+```
81+> .^((list lane:ames) %ax /=//=/peers/~nes/forward-lane)
82+~[[%.y p=~nes]]
83+```
84+
85+```
86+> .^((list lane:ames) %ax /=//=/peers/~nec/forward-lane)
87+~
88+```
89+
90+## /bones/[ship]
91+
92+A scry with a `%x` `care` and a `path` of `/bones/[ship]` where `[ship]` is a ship name like `~dopzod` will return inbound and outbound [$bone](/docs/arvo/ames/data-types#bone)s, which index message flows. If the ship in question is unknown to Ames, the scry will fail. The type returned is `[snd=(set bone) rcv=(set bone)]`.
93+
94+#### Example
95+
96+```
97+> .^([snd=(set bone) rcv=(set bone)] %ax /=//=/bones/~nes)
98+[snd={0} rcv={}]
99+```
100+
101+## /snd-bones/[ship]/[bone]
102+
103+A scry with a `%x` `care` and a `path` of `/snd-bones/[ship]/[bone]`, where `[ship]` is a ship name like `~dopzod` and `[bone]` is an outbound [$bone](/docs/arvo/ames/data-types#bone), will return message flow details for that `bone`. If the ship in question is unknown to Ames or the `bone` does not exist, the scry will fail. The type returned is a [$message-pump-state](/docs/arvo/ames/data-types#message-pump-state) wrapped in a `vase`.
104+
105+#### Example
106+
107+```
108+> !< message-pump-state:ames .^(vase %ax /=//=/snd-bones/~nes/0)
109+[ current=2
110+ next=3
111+ unsent-messages={}
112+ unsent-fragments=~
113+ queued-message-acks={}
114+ packet-pump-state
115+ [ next-wake=[~ ~2021.8.17..02.27.14..aaff]
116+ live
117+ { [ [message-num=2 fragment-num=0]
118+ [last-sent=~2021.8.17..02.25.14..aaff retries=2.258 skips=0]
119+ num-fragments=1
120+ fragment=0w2.QJ1qS.JzaQn.w7rMp.IzuTJ.7M7aP.-1s~1
121+ ]
122+ }
123+ metrics=[rto=~m2 rtt=~s1 rttvar=~s1 ssthresh=1 cwnd=1 num-live=1 counter=1]
124+ ]
125+]
126+```
content/docs/arvo/ames/tasks.mdnew file+193
@@ -0,0 +1,193 @@
1++++
2+title = "API Reference"
3+weight = 3
4+template = "doc.html"
5++++
6+
7+In this document we describe the public interface for Ames. Namely, we describe
8+each `task` that Ames can be `%pass`ed, and which `gift`(s) Ames can `%give` in return.
9+
10+Some `task`s appear to have more than one arm associated to them, e.g. there are
11+four `+on-hear` arms. We denote this where it occurs, but always refer to the
12+`+on-hear:event-core` arm.
13+
14+Ames `task`s can be naturally divided into two categories: messaging tasks and
15+system/lifecycle tasks.
16+
17+## Messaging Tasks
18+
19+### `%hear`
20+
21+```hoon
22+[%hear =lane =blob]
23+```
24+
25+`%hear` handles raw packet receipt.
26+
27+This `task` only ever originates from Unix. It does the initial processing of a packet, namely by passing the raw packet information to `+decode-packet` which deserializes the packet and giving that data and the origin of the packet to `+on-hear-packet`, which begins the transformation of the packet into a new event in the form of a `+event-core`.
28+
29+There are multiple `+on-hear` arms in `ames.hoon`. Here we refer to `+on-hear:event-core`, as that is the one called by a `%hear` `task`. The other ones are used primarily for ack and nack processing, or receiving message fragments.
30+
31+`%hear` takes in a [$blob](/docs/arvo/ames/data-types#blob), which is essentially a large atom (around 1kB or less) that is the raw data of the message, and a [$lane](/docs/arvo/ames/data-types#lane), which is the origin of the message (typically an IP address).
32+
33+#### Returns
34+
35+`%hear` can trigger a number of possible returns. It can trigger the release of zero or more additional packets via `%send` `gift`s. It may also trigger a `%boon` or `%plea` `gift` (collectively referred to as a `%memo` within Ames) to a local vane in the case of a completed message.
36+
37+### `%heed`
38+
39+```hoon
40+[%heed =ship]
41+```
42+
43+A vane can pass Ames a `%heed` `task` to request Ames track a peer's responsiveness. If our `%boon`s to it start backing up locally, Ames will `give` a `%clog` back to the requesting vane containing the unresponsive peer's Urbit address.
44+
45+Stop tracking a peer by sending Ames a [%jilt](#jilt) `task`.
46+
47+The `ship` field specifies the peer to be tracked.
48+
49+#### Returns
50+
51+If the `ship` is indeed being unresponsive, as measured by backed up `%boon`s,
52+Ames will `give` a `%clog` `gift` to the requesting vane containing the
53+unresponsive peer's urbit address.
54+
55+### `%jilt`
56+
57+```hoon
58+[%jilt =ship]
59+```
60+
61+`%jilt` stops tracking a potentially unresponsive peer that was previously being
62+tracked as a result of the [%heed](#heed) `task`.
63+
64+There are two `+on-jilt` arms, this `task` utilizes `+on-hear:event-core`.
65+
66+The `ship` field specifies the peer we want to stop tracking.
67+
68+#### Returns
69+
70+This `task` returns no `gift`s.
71+
72+### `%plea`
73+
74+```hoon
75+[%plea =ship =plea:ames]
76+```
77+
78+`%plea` is the `task` used to instruct Ames to send a message. It extends the
79+`%pass`/`%give` semantics across the network. As such, it is the most
80+fundamental `task` in Ames and the primary reason for its existence.
81+
82+Ames also `pass`es a `%plea` `note` to another vane when it receives a message on a
83+"forward flow" from a peer, originally passed from one of the peer's vanes to the
84+peer's Ames.
85+
86+Ultimately `%plea` causes `%send` `gift`(s) to be sent to Unix, which tells
87+Unix to send packets. In terms of `%pass`/`%give` semantics, this is in
88+response to the `%born` `task`, which came along the Unix `duct`, rather than a
89+response to the `%plea`.
90+
91+A `%plea` `task` takes in the `ship` the `plea` is addressed to, and a [$plea](/docs/arvo/ames/data-types.md#plea).
92+
93+#### Returns
94+
95+This `task` returns no `gift`s.
96+
97+## System Tasks
98+
99+### `%born`
100+
101+```hoon
102+[%born ~]
103+```
104+
105+Each time you start your Urbit, the Arvo kernel calls the `%born` `task` for Ames.
106+
107+#### Returns
108+
109+In response to a `%born` `task`, Ames `%give`s Jael a `%turf` `gift`.
110+
111+The `duct` along which `%born` comes is Ames' only duct to Unix, so `%send`
112+`gift`s (which are instructions for Unix to send a packet) are also returned in
113+response to `%born`.
114+
115+### `%init`
116+
117+```hoon
118+[%init ~]
119+```
120+
121+`%init` is called a single time during the very first boot process, immediately
122+after the [larval stage](/docs/arvo/overview#larval-stage-core)
123+is completed. This initializes the vane. Jael is initialized first, followed by
124+other vanes such as Ames.
125+
126+In response to receiving the `%init` `task`, Ames subscribes to the information
127+contained by Jael.
128+
129+#### Returns
130+
131+```hoon
132+=~ (emit duct %pass /turf %j %turf ~)
133+ (emit duct %pass /private-keys %j %private-keys ~)
134+```
135+
136+`%init` sends two moves that subscribe to `%turf` and `%private-keys` in Jael.
137+
138+### `%sift`
139+
140+```hoon
141+[%sift ships=(list ship)]
142+```
143+
144+This `task` filters debug output by ship. This `task` is used internally when the `|ames-sift` `hood` generator is run from the dojo.
145+
146+The `ships` field specifies the ships for which debug output is desired.
147+
148+#### Returns
149+
150+This `task` returns no `gift`s.
151+
152+### `%spew`
153+
154+```hoon
155+[%spew veb=(list verb)]
156+```
157+
158+Sets verbosity toggles on debug output. This `task` is used internally when the `|ames-verb` `hood` generator is run from the dojo.
159+
160+`%spew` takes in a `list` of [$verb](/docs/arvo/ames/data-types#verb), which are verbosity flags for Ames.
161+
162+`%spew` flips each toggle given in `veb`.
163+
164+#### Returns
165+
166+This `task` returns no `gift`s.
167+
168+### `%stir`
169+
170+```hoon
171+[%stir arg=@t]
172+```
173+
174+A `%stir` `task` starts timers for any flows that lack them.
175+
176+The `arg` field is unused.
177+
178+#### Returns
179+
180+This `task` returns no `gift`s.
181+
182+### `%vega`
183+
184+```hoon
185+[%vega ~]
186+```
187+
188+`%vega` is called whenever the kernel is updated. Ames currently does not do
189+anything in response to this.
190+
191+#### Returns
192+
193+This `task` returns no `gift`s.
content/docs/arvo/behn/examples.md+2−2
@@ -39,7 +39,7 @@ Below is a thread which will take a `@dr` as its argument and `%pass`es Behn a `
3939(pure:m !>(~))
4040```
4141
42−Save the thread to `/ted/wait.hoon` and `|commit %home`. Then we can try running the thread with a `@dr` of `~s2`:
42+Save the thread to `/ted/wait.hoon` and `|commit %base`. Then we can try running the thread with a `@dr` of `~s2`:
4343
4444```
4545> -wait ~s2
@@ -84,7 +84,7 @@ Below is a variation on the [%wake](#wake) thread. It takes a `@dr` as its argum
8484(pure:m !>(~))
8585```
8686
87−Save the above thread to `/ted/rest.hoon`, and `|commit %home`. Let's try run it with an argument of `~s2`:
87+Save the above thread to `/ted/rest.hoon`, and `|commit %base`. Let's try run it with an argument of `~s2`:
8888
8989```
9090> -rest ~s2
content/docs/arvo/clay/architecture.md+43−120
@@ -4,26 +4,25 @@ weight = 2
44template = "doc.html"
55+++
66
7−Clay is the primary filesystem for the [Arvo](/docs/arvo/overview) operating system,
8−which is the [core](/docs/glossary/core/) of an urbit. The architecture of Clay is
9−intrinsically connected with Arvo, but for this section we assume no knowledge of
10−either Arvo or Urbit. We will point out only those features of
11−Arvo that are necessary for an understanding of Clay, and we will
12−do so only when they arise.
7+Clay is the primary filesystem for the [Arvo](/docs/arvo/overview)
8+operating system, which is the [core](/docs/glossary/core/) of an
9+urbit. The architecture of Clay is intrinsically connected with Arvo,
10+but for this section we assume no knowledge of either Arvo or Urbit.
11+We will point out only those features of Arvo that are necessary for
12+an understanding of Clay, and we will do so only when they arise.
1313
1414The first relevant feature of Arvo is that it is a deterministic
15−system where input and output are defined as a series of events
16−and effects. The state of Arvo is simply a pure function of its event
17−log. None of the effects from an event are emitted until the
18−event is entered in the log and persisted, either to disk or
19−another trusted source of persistence, such as a Kafka cluster.
20−Consequently, Arvo is a single-level store: everything in its
21−state is persistent.
15+system where input and output are defined as a series of events and
16+effects. The state of Arvo is simply a pure function of its event log.
17+None of the effects from an event are emitted until the event is
18+entered in the log and persisted, either to disk or another trusted
19+source of persistence, such as a Kafka cluster. Consequently, Arvo is
20+a single-level store: everything in its state is persistent.
2221
2322In a more traditional OS, everything in RAM can be erased at any
2423time by power failure, and is always erased on reboot. Thus, a
2524primary purpose of a filesystem is to ensure files persist across
26−power failures and reboots. In Arvo, both power failures and
25+power failures and reboots. In Arvo, both power failures and
2726reboots are special cases of suspending computation, which is
2827done safely since our event log is already persistent. Therefore,
2928Clay is not needed in Arvo for persistence. Why, then, do we have a
@@ -37,7 +36,7 @@ tree. It is easy and intuitive to read from and write to a
3736filesystem tree.
3837
3938Second, Clay has a distributed revision-control system baked into
40−it. Traditional filesystems are not revision controlled, so
39+it. Traditional filesystems are not revision controlled, so
4140userspace software -- such as git -- is written on top of them to
4241do so. Clay natively provides the same functionality as modern
4342DVCSes, and more.
@@ -47,25 +46,25 @@ it supports typed data and is referentially transparent.
4746
4847### Revision Control
4948
50−Every urbit has one or more `desk`s, which are independently
51−revision-controlled branches. Each `desk` contains its own `mark`
49+Every urbit has one or more desks, which are independently
50+revision-controlled branches. Each desk contains its own `mark`
5251definitions, apps, and so forth.
5352
54−Traditionally, an urbit has at least a `%home` `desk` and `%kids` `desk`. The
55−`%home` `desk` has all the system software from the distribution, along with your
56−personal files. The `%home` `desk` is a fork of the `%kids` desk of whichever ship
57−you download [OTAs](/docs/glossary/ota-updates) from - typically your sponsor,
58−but theoretically may be any ship. You will also find references to a `%base`
59−`desk` - which is not a real `desk`, rather it just a hash associated to the
60−`desk` from which your `%home` `desk` was forked.
53+Traditionally, an Urbit ship has at least a `%base` desk, and usually
54+`%garden` and `%landscape` desks. The `%base` desk has the kernel and
55+base system software. The `%garden` desk has software pertaining to
56+the home screen. The `%landscape` desk contains software for the
57+Groups app. The `%base` desk is a fork of the `%base` desk of
58+whichever ship you download system updates from - typically your
59+sponsor, but theoretically may be any ship.
6160
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
61+A desk is a series of numbered commits, the most recent of which
62+represents the current state of the desk. A commit is composed of
6463(1) an absolute time when it was created, (2) a list of zero or
6564more parents, and (3) a map from paths to data.
6665
6766Most commits have exactly one parent, but the initial commit on a
68−`desk` may have zero parents, and merge commits have more than one
67+desk may have zero parents, and merge commits have more than one
6968parent.
7069
7170The non-metadata is stored as a `map` of `path`s to data. It's
@@ -88,10 +87,10 @@ only on the data within and not on whether or not it's stored
8887directly, so we may on occasion rearrange the contents of the
8988blob store for performance reasons.
9089
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,
90+Recall that a desk is a series of numbered commits. Not every
91+commit in a desk must be numbered. For example, if the `%base` desk
92+has had 50 commits since `%foo` was forked from it, then a merge
93+from `%base` to `%foo` will only add a single revision number to home,
9594although the full commit history will be accessible by traversing
9695the parentage of the individual commits.
9796
@@ -101,25 +100,25 @@ the topmost commit is always numbered, and every numbered commit
101100is an ancestor of every later numbered commit.
102101
103102There are three ways to refer to particular commits in the
104−revision history. Firstly, one can use the revision number.
103+revision history. Firstly, one can use the revision number.
105104Secondly, one can use any absolute time between the one numbered
106105commit and the next (inclusive of the first, exclusive of the
107−second). Thirdly, every `desk` has a `map` of labels to revision
106+second). Thirdly, every desk has a `map` of labels to revision
108107numbers. These labels may be used to refer to specific commits.
109108
110109Additionally, Clay is a global filesystem, so data on other urbits
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
110+is easily accessible the same way as data on our local urbit. In
111+general, the path to a particular revision of a desk is
112+`/~urbit-name/desk-name/revision`. Thus, to get `/try/readme/md`
113+from revision 5 of the `%base` desk on `~sampel-sipnym`, we refer to
114+`/~sampel-sipnym/base/5/try/readme/md`. Clay's namespace is thus
116115global and referentially transparent.
117116
118117### A Typed Filesystem
119118
120119Since Clay is a general filesystem for storing data of arbitrary
121120types, in order to revision control correctly it needs to be
122−aware of types all the way through. Traditional revision control
121+aware of types all the way through. Traditional revision control
123122does an excellent job of handling source code, so for source code
124123we act very similar to traditional revision control. The
125124challenge is to handle other data similarly well.
@@ -145,7 +144,7 @@ branches and merged at will.
145144Suppose Alice is tasked with touching up a picture, improving the
146145color balance, adjusting the contrast, and so forth, while Bob
147146has the job of cropping the picture to fit where it's needed and
148−adding textual overlay. Without type-aware revision control,
147+adding textual overlay. Without type-aware revision control,
149148these changes must be made serially, requiring Alice and Bob to
150149explicitly coordinate their efforts. With type-aware revision
151150control, these operations may be performed in parallel, and then
@@ -168,87 +167,11 @@ different sentences may be flagged as a conflict. In general,
168167prose should be diffed by sentence, not by line.
169168
170169As far as we are aware, Clay is the first generalized,
171−type-aware revision control system. We'll go into the workings
170+type-aware revision control system. We'll go into the workings
172171of this system in some detail.
173172
174173### Marks
175174
176−Central to a typed filesystem is the idea of types. In Clay, we
177−call these `mark`s. A `mark` is a file that defines a type,
178−conversion routines to and from the `mark`, and diff, patch, and
179−merge routines.
180−
181−For example, a `%txt` mark may be a list of lines of text, and it
182−may include conversions to `%mime` to allow it to be serialized
183−and sent to a browser or to the Unix filesystem. It will also
184−include Hunt-McIlroy diff, patch, and merge algorithms.
185−
186−A `%json` `mark` would be defined as a JSON object in the code, and
187−it would have a parser to convert from `%txt` and a printer to
188−convert back to `%txt`. The diff, patch, and merge algorithms are
189−fairly straightforward for JSON, though they're very different
190−from the text ones.
191−
192−More formally, a `mark` is a core with three [arms](/docs/glossary/arm/): `+grab`,
193−`+grow`, and `+grad`. In `+grab` is a series of functions to
194−convert from other `mark`s to the given `mark`. In `+grow` is a
195−series of functions to convert from the given `mark` to other
196−`mark`s. In `+grad` is `+diff`, `+pact`, `+join`, and `+mash`, and
197−`+form`.
198−
199−The types are as follows, in an informal pseudocode:
200−
201−```
202− ++ grab:
203− ++ mime: <mime> -> <mark-type>
204− ++ txt: <txt> -> <mark-type>
205− ...
206− ++ grow:
207− ++ mime: <mark-type> -> <mime>
208− ++ txt: <mark-type> -> <txt>
209− ...
210− ++ grad
211− ++ form: <mark-type>
212− ++ diff: (<mark-type>, <mark-type>) -> <diff-type>
213− ++ pact: (<mark-type>, <diff-type>) -> <mark-type>
214− ++ join: (<diff-type>, <diff-type>) -> <diff-type> or NULL
215− ++ mash: (<diff-type>, <diff-type>) -> <diff-type>
216−```
217−
218−These types are basically what you would expect. Not every `mark`
219−has each of these functions defined -- all of them are optional
220−in the general case.
221−
222−In general, for a particular `mark`, the `+grab` and `+grow` entries
223−(if they exist) should be inverses of each other.
224−
225−In `+grad`, `+diff` takes two instances of a `mark` and produces a diff of them
226−whose `mark` is given by `+form`. `+pact` takes an instance of a `mark` and
227−patches it with the given diff. `+join` takes two diffs and attempts to merge
228−them into a single diff. If there are conflicts, it produces null. `+mash` takes
229−two diffs and forces a merge, annotating any conflicts.
230−
231−In general, if `+diff` called with A and B produces diff D, then
232−`+pact` called with A and D should produce B. Also, if `+join`
233−of two diffs does not produce null, then `+mash` of the same
234−diffs should produce the same result.
235−
236−Alternately, instead of `+diff`, `+pact`, `+join`, and
237−`+mash`, a `mark` can provide the same functionality by defining
238−`+grad` to be the name of another `mark` to which we wish to
239−delegate the revision control responsibilities. Then, before
240−running any of those functions, Clay will convert to the other
241−`mark`, and convert back afterward. For example, the `%hoon` `mark`
242−is revision-controlled in the same way as `%txt`, so its `+grad`
243−is simply `++ grad %txt`. Of course, `+txt` must be defined in
244−`+grow` and `+grab` as well.
245−
246−Every file in Clay has a `mark`, and that `mark` must have a
247−fully-functioning `+grad`. `Mark`s are used for more than just
248−Clay, and other `mark`s don't need a `+grad`, but if a piece of
249−data is to be saved to Clay, we must know how to revision-control
250−it.
251−
252−Additionally, if a file is to be synced out to Unix, then it must
253−have conversion routines to and from the `%mime` `mark`.
254−
175+Central to a typed filesystem is the idea of file types. In Clay, we
176+call these `mark`s. See the [Marks](/docs/arvo/clay/marks/marks)
177+section for more details.
content/docs/arvo/clay/clay.md+4−1
@@ -5,7 +5,6 @@ template = "doc.html"
55aliases = ["/docs/learn/arvo/clay/"]
66+++
77
8−
98Our filesystem.
109
1110`%clay` is version-controlled, referentially-transparent, and global.
@@ -56,3 +55,7 @@ Details of the various `task`s you can use to interact with Clay.
5655[Examples](/docs/arvo/clay/examples)
5756
5857Example usage of the various Clay `task`s.
58+
59+[Marks](/docs/arvo/clay/marks/marks)
60+
61+Details of `mark`s as well as a guide to writing them and their usage.
content/docs/arvo/clay/data-types.md+2−9
@@ -68,7 +68,6 @@ to th pier) and `beam` is a domestic Clay directory.
6868
6969`pud` is an update that's waiting on a kernel upgrade.
7070
71−
7271#### `$room`, filesystem per domestic ship
7372
7473```hoon
@@ -93,8 +92,7 @@ set of `desk`s on this ship, mapped to their `desk` state.
9392+$ desk @tas
9493```
9594
96−This is the name of a branch of the filesystem. The default `desk`s are `%home`
97−and `%kids`. More may be created by simply referencing them. `desk`s have
95+This is the name of a branch of the filesystem. The default `desk`s are `%base`, `%garden`, `%landscape`, `%webterm` and `%bitcoin`. Desks have
9896independent histories and states, and they may be
9997[merged](/docs/arvo/clay/using#merging) into each other.
10098
@@ -167,7 +165,6 @@ Like a `rave` but with provisions to store current versions for `%next` and `%ma
167165Generally used when we store a request in our state somewhere. This is so that
168166we can determine whether new versions actually affect the path we're subscribed to.
169167
170−
171168#### `$mood:clay`, single subscription request
172169
173170```hoon
@@ -194,7 +191,6 @@ any of its children.
194191 +$ care ?(%a %b %c %d %e %f %p %r %s %t %u %v %w %x %y %z) :: clay submode
195192```
196193
197−
198194This specifies what type of information is requested in a subscription
199195or a scry.
200196
@@ -258,7 +254,6 @@ contents while `q.fil` is the data itself.
258254this is empty. The keys are the names of the children and the values
259255are, recursively, the nodes themselves.
260256
261−
262257### `$arch`, shallow filesystem node
263258
264259```hoon
@@ -275,6 +270,7 @@ those directories.
275270The child directories are given by a `map` to null rather than a `set` so that the
276271ordering of the `map` will be the same as it is for an `axal`, allowing
277272efficient conversion for when the heavier node is needed.
273+
278274```hoon
279275++ axal
280276 |$ [item]
@@ -400,7 +396,6 @@ is all the subscribers from our ship to the foreign `desk`.
400396`regs` are `(map path rule)`, and so `per` is a `map` of read permissions by
401397`path` and `pew` is a `map` of write permissions by `path`.
402398
403−
404399#### `$rind`, foreign request manager
405400
406401```hoon
@@ -547,7 +542,6 @@ blob, and `r` is the delta.
547542`%direct` is the case where we simply have the data directly. `q` is the data.
548543These almost always come from the creation of a file.
549544
550−
551545#### `+urge`, list change
552546
553547```hoon
@@ -685,4 +679,3 @@ commit itself.
685679revision number, whichever is smaller.
686680
687681`lar` is the set of new commits, and `bar` is the set of new content.
688−
content/docs/arvo/clay/examples.md+99−102
@@ -6,7 +6,7 @@ template = "doc.html"
66
77This document contains a number of examples of interacting with Clay using its various `task`s. Sections correspond to the general details in the [API Reference](/docs/arvo/clay/tasks) document.
88
9−Most examples will either use `|pass` to just send a `task` or the following thread to send a `task` and take the resulting `gift`. You can save the following thread to the `ted` directory of your `%home` `desk`:
9+Most examples will either use `|pass` to just send a `task` or the following thread to send a `task` and take the resulting `gift`. You can save the following thread to the `ted` directory of the `%base` `desk` on a fake ship:
1010
1111`send-task-take-gift.hoon`
1212
@@ -40,7 +40,7 @@ Here we'll look at reading files by passing Clay a `%warp` `task` with a `%sing`
4040Using the `send-task-take-gift.hoon` thread, let's try reading `gen/hood/hi.hoon`:
4141
4242```
43−> -send-task-take-gift [%warp our %home ~ %sing %x da+now /gen/hood/hi/hoon]
43+> -send-task-take-gift [%warp our %base ~ %sing %x da+now /gen/hood/hi/hoon]
4444```
4545
4646You should see something like this as the output:
@@ -49,7 +49,7 @@ You should see something like this as the output:
4949[ %writ
5050 p
5151 [ ~
52− [ p=[p=%x q=[%da p=~2021.5.20..23.37.50..e79b] r=%home]
52+ [ p=[p=%x q=[%da p=~2021.5.20..23.37.50..e79b] r=%base]
5353 q=/gen/hood/hi/hoon
5454 r
5555 [ p=%hoon
@@ -67,11 +67,11 @@ You should see something like this as the output:
6767The `cage` in the `riot` of the `%writ` contains the file's data due to our use of an `%x` `care`. It needn't be `%x` though. If we change it to `%u`, for example, we'll get a `?` `cage` instead:
6868
6969```
70−> -send-task-take-gift [%warp our %home ~ %sing %x da+now /gen/hood/hi/hoon]
70+> -send-task-take-gift [%warp our %base ~ %sing %x da+now /gen/hood/hi/hoon]
7171[ %writ
7272 p
7373 [ ~
74− [ p=[p=%u q=[%da p=~2021.5.20..23.42.21..bb33] r=%home]
74+ [ p=[p=%u q=[%da p=~2021.5.20..23.42.21..bb33] r=%base]
7575 q=/gen/hood/hi/hoon
7676 r=[p=%flag q=[#t/?(%.y %.n) q=0]]
7777 ]
@@ -90,27 +90,27 @@ Here we'll look at subscribing to the next version of a file by passing Clay a `
9090Using the `send-task-take-gift.hoon` thread, let's subscribe to the next version of `foo.txt`:
9191
9292```
93−> -send-task-take-gift [%warp our %home ~ %next %x da+now /foo/txt]
93+> -send-task-take-gift [%warp our %base ~ %next %x da+now /foo/txt]
9494```
9595
96−Now, in unix, create a file called `foo.txt` in the root of the `home` directory of your ship. In the dojo, hit backspace to disconnect the thread from the dojo prompt and run `|commit %home`. You should see something like:
96+Now, in unix, create a file called `foo.txt` in the root of the `base` directory of your ship. In the dojo, hit backspace to disconnect the thread from the dojo prompt and run `|commit %base`. You should see something like:
9797
9898```
99−> |commit %home
99+> |commit %base
100100>=
101−[%writ p=[~ [p=[p=%x q=[%ud p=3] r=%home] q=/foo/txt r=[p=%txt q=[#t/*'' q=0]]]]]
102−+ /~zod/home/3/foo/txt
101+[%writ p=[~ [p=[p=%x q=[%ud p=3] r=%base] q=/foo/txt r=[p=%txt q=[#t/*'' q=0]]]]]
102++ /~zod/base/3/foo/txt
103103```
104104
105105As you can see, the `riot` in the `%writ` includes a `cage` with the data of `/foo/txt` due to our use of an `%x` `care`.
106106
107−Now run the thread again, and this time delete the file in unix and again `|commit %home` in the dojo. You should see:
107+Now run the thread again, and this time delete the file in unix and again `|commit %base` in the dojo. You should see:
108108
109109```
110−> |commit %home
110+> |commit %base
111111>=
112112[%writ p=~]
113−- /~zod/home/4/foo/txt
113+- /~zod/base/4/foo/txt
114114```
115115
116116You can see the `riot` is just `~` due to the file being deleted.
@@ -141,7 +141,7 @@ This thread will subscribe to `/foo/txt` with an `%x` `care` and `/bar/txt` with
141141 [%u /bar/txt]
142142 ==
143143;< =bowl:strand bind:m get-bowl:strandio
144−=/ =task:clay [%warp our.bowl %home ~ %mult da+now.bowl files]
144+=/ =task:clay [%warp our.bowl %base ~ %mult da+now.bowl files]
145145=/ =card:agent:gall [%pass /mult %arvo %c task]
146146;< ~ bind:m (send-raw-card:strandio card)
147147;< response=(pair wire sign-arvo) bind:m take-sign-arvo:strandio
@@ -149,27 +149,27 @@ This thread will subscribe to `/foo/txt` with an `%x` `care` and `/bar/txt` with
149149(pure:m !>(~))
150150```
151151
152−Save the above to `ted/sub-mult.hoon`, `|commit %home` and run with `-sub-mult`. Now, create `foo.txt` and `bar.txt` in your home directory, hit backspace in the dojo to disconnect the thread and run `|commit %home`. You should see something like:
152+Save the above to `ted/sub-mult.hoon`, `|commit %base` and run with `-sub-mult`. Now, create `foo.txt` and `bar.txt` in your base directory, hit backspace in the dojo to disconnect the thread and run `|commit %base`. You should see something like:
153153
154154```
155−> |commit %home
155+> |commit %base
156156>=
157157[%wris p=[%da p=~2021.4.27..06.07.08..5ec4] q={[p=%u q=/bar/txt] [p=%x q=/foo/txt]}]
158−+ /~zod/home/151/foo/txt
159−+ /~zod/home/151/bar/txt
158++ /~zod/base/151/foo/txt
159++ /~zod/base/151/bar/txt
160160```
161161
162162You'll notice that, unlike a `%writ`, the `%wris` doesn't give you the data. It merely tells you the `care`s and `path`s of the files that changed. If you need to actually get the data, you can just scry or send a request for the files in question.
163163
164−Now, run the thread again, open `bar.txt` in an editor, modify its contents, save it and `|commit %home`. You'll notice you didn't receive a `%wris`. This is because we subscribed to `/bar/txt` with `%u` care and its existence didn't change.
164+Now, run the thread again, open `bar.txt` in an editor, modify its contents, save it and `|commit %base`. You'll notice you didn't receive a `%wris`. This is because we subscribed to `/bar/txt` with `%u` care and its existence didn't change.
165165
166−Lastly, delete `foo.txt` and `|commit %home`. You should see something like:
166+Lastly, delete `foo.txt` and `|commit %base`. You should see something like:
167167
168168```
169−> |commit %home
169+> |commit %base
170170>=
171171[%wris p=[%da p=~2021.4.27..06.15.03..0da4] q={[p=%x q=/foo/txt]}]
172−- /~zod/home/153/foo/txt
172+- /~zod/base/153/foo/txt
173173```
174174
175175As you can see, a relevant change to any of the subscribed files will trigger a response, not just when all of them change.
@@ -182,7 +182,7 @@ Here's a breakdown of the `task` we sent:
182182
183183Here we'll look at subscribing to a range of changes to a `desk` by passing Clay a `%warp` `task` with a `%many` `rave` and receiving `%writ` `gift`s when changes occur.
184184
185−This thread will subscribe to changes to your `%home` `desk` for the next three minutes. The `track` is `%.y` so it will only inform you of changes, not send the full `nako`. It will only get updates if the specified file exists. It contains a `main-loop` that will take an arbitrary number of `sign`s and print them out in the dojo. Since it never ends, you'll need to stop it with the `:spider|kill` command in the dojo.
185+This thread will subscribe to changes to your `%base` `desk` for the next three minutes. The `track` is `%.y` so it will only inform you of changes, not send the full `nako`. It will only get updates if the specified file exists. It contains a `main-loop` that will take an arbitrary number of `sign`s and print them out in the dojo. Since it never ends, you'll need to stop it with the `:spider|kill` command in the dojo.
186186
187187`sub-many.hoon`
188188
@@ -213,30 +213,30 @@ This thread will subscribe to changes to your `%home` `desk` for the next three
213213 (strand-fail:strand %no-arg ~)
214214=/ =path u.uarg
215215;< =bowl:strand bind:m get-bowl:strandio
216−=/ =task:clay [%warp our.bowl %home ~ %many %.y da+now.bowl da+(add ~m3 now.bowl) path]
216+=/ =task:clay [%warp our.bowl %base ~ %many %.y da+now.bowl da+(add ~m3 now.bowl) path]
217217=/ =card:agent:gall [%pass /many %arvo %c task]
218218;< ~ bind:m (send-raw-card:strandio card)
219219;< ~ bind:m take-sign-loop
220220(pure:m !>(~))
221221```
222222
223−Make sure `foo.txt` doesn't exist in the root of your `%home` `desk`. Save this to `ted/sub-many.hoon`, `|commit %home`, run it like `-sub-many /foo/txt`, and hit backspace in the dojo to free up the dojo prompt. Now, add a file called `bar.txt` to your `desk` and `|commit %home`. You should see something like:
223+Make sure `foo.txt` doesn't exist in the root of your `%base` `desk`. Save this to `ted/sub-many.hoon`, `|commit %base`, run it like `-sub-many /foo/txt`, and hit backspace in the dojo to free up the dojo prompt. Now, add a file called `bar.txt` to your `desk` and `|commit %base`. You should see something like:
224224
225225```
226−> |commit %home
226+> |commit %base
227227>=
228−+ /~zod/home/260/bar/txt
228++ /~zod/base/260/bar/txt
229229```
230230
231−Notice you've received no `%writ` from Clay. This is because `/foo/txt` doesn't exist. Now, create `foo.txt` and `|commit %home` again. You should see:
231+Notice you've received no `%writ` from Clay. This is because `/foo/txt` doesn't exist. Now, create `foo.txt` and `|commit %base` again. You should see:
232232
233233```
234−> |commit %home
234+> |commit %base
235235>=
236236[ p=/many
237− q=[%clay [%writ p=[~ [p=[p=%w q=[%ud p=261] r=%home] q=/ r=[p=%null q=[#t/@n q=0]]]]]]
237+ q=[%clay [%writ p=[~ [p=[p=%w q=[%ud p=261] r=%base] q=/ r=[p=%null q=[#t/@n q=0]]]]]]
238238]
239−+ /~zod/home/261/foo/txt
239++ /~zod/base/261/foo/txt
240240```
241241
242242Now that `/foo/txt` exists it will inform you of updates. Note that if you delete `/foo/txt` again it will again stop sending updates.
@@ -244,24 +244,24 @@ Now that `/foo/txt` exists it will inform you of updates. Note that if you delet
244244Now try adding `baz.txt`:
245245
246246```
247−> |commit %home
247+> |commit %base
248248>=
249249[ p=/many
250− q=[%clay [%writ p=[~ [p=[p=%w q=[%ud p=262] r=%home] q=/ r=[p=%null q=[#t/@n q=0]]]]]]
250+ q=[%clay [%writ p=[~ [p=[p=%w q=[%ud p=262] r=%base] q=/ r=[p=%null q=[#t/@n q=0]]]]]]
251251]
252−+ /~zod/home/262/baz/txt
252++ /~zod/base/262/baz/txt
253253```
254254
255255Now wait until the three minutes is up and try making a change, for example deleting `baz.txt`:
256256
257257```
258−> |commit %home
258+> |commit %base
259259>=
260260[ p=/many
261− q=[%clay [%writ p=[~ [p=[p=%w q=[%ud p=264] r=%home] q=/ r=[p=%null q=[#t/@n q=0]]]]]]
261+ q=[%clay [%writ p=[~ [p=[p=%w q=[%ud p=264] r=%base] q=/ r=[p=%null q=[#t/@n q=0]]]]]]
262262]
263263[p=/many q=[%clay [%writ p=~]]]
264−- /~zod/home/263/baz/txt
264+- /~zod/base/263/baz/txt
265265```
266266
267267You can see that along with the normal `%writ` it's also sent a second `%writ` with a null `riot` to indicate the subscription has ended. This is because it has now passed the end of the range of `case`s to which you subscribed.
@@ -289,10 +289,10 @@ This thread will subscribe to the `%next` version of `/foo/txt`, then immediatel
289289=/ m (strand ,vase)
290290^- form:m
291291;< =bowl:strand bind:m get-bowl:strandio
292−=/ =task:clay [%warp our.bowl %home ~ %next %x da+now.bowl /foo/txt]
292+=/ =task:clay [%warp our.bowl %base ~ %next %x da+now.bowl /foo/txt]
293293=/ =card:agent:gall [%pass /next %arvo %c task]
294294;< ~ bind:m (send-raw-card:strandio card)
295−=. task [%warp our.bowl %home ~]
295+=. task [%warp our.bowl %base ~]
296296=. card [%pass /next %arvo %c task]
297297;< ~ bind:m (send-raw-card:strandio card)
298298;< =riot:clay bind:m (take-writ:strandio /next)
@@ -300,12 +300,12 @@ This thread will subscribe to the `%next` version of `/foo/txt`, then immediatel
300300(pure:m !>(~))
301301```
302302
303−Save the above to `ted/stop-sub.hoon`, `|commit %home`, run it with `-stop-sub` and hit backspace to detach it from the dojo prompt. Now, add `foo.txt` to the root of your `%home` `desk` and `|commit %home`. You should see:
303+Save the above to `ted/stop-sub.hoon`, `|commit %base`, run it with `-stop-sub` and hit backspace to detach it from the dojo prompt. Now, add `foo.txt` to the root of your `%base` `desk` and `|commit %base`. You should see:
304304
305305```
306−> |commit %home
306+> |commit %base
307307>=
308−+ /~zod/home/266/foo/txt
308++ /~zod/base/266/foo/txt
309309```
310310
311311As you can see we've received no `%writ`. We can thus conclude the subscription has successfully been cancelled.
@@ -327,11 +327,11 @@ Here we'll look at adding a file by sending Clay a `%info` `task` containing a `
327327Let's try adding a `foo.txt` file with 'foo' as its contents:
328328
329329```
330−> |pass [%c [%info %home %& [/foo/txt %ins %txt !>(~['foo'])]~]]
331−+ /~zod/home/5/foo/txt
330+> |pass [%c [%info %base %& [/foo/txt %ins %txt !>(~['foo'])]~]]
331++ /~zod/base/5/foo/txt
332332```
333333
334−If you have a look in the home of your pier you'll see there's now a file called `foo.txt` with the text `foo` in it.
334+If you have a look in the base of your pier you'll see there's now a file called `foo.txt` with the text `foo` in it.
335335
336336We've created the `cage` of the content like `[%txt !>(~['foo'])]`, if you want to write something besides a text file you'd just give it the appropriate `mark` and `vase`.
337337
@@ -346,11 +346,11 @@ Here we'll look at deleting a file by sending Clay a `%info` `task` containing a
346346Let's try deleting the `foo.txt` file created in the [previous example](#ins):
347347
348348```
349−> |pass [%c [%info %home %& [/foo/txt %del ~]~]]
350−- /~zod/home/6/foo/txt
349+> |pass [%c [%info %base %& [/foo/txt %del ~]~]]
350+- /~zod/base/6/foo/txt
351351```
352352
353−If you have a look in the home of your pier you'll see the `foo.txt` file is now gone.
353+If you have a look in the base of your pier you'll see the `foo.txt` file is now gone.
354354
355355Here's a breakdown of the `task` we sent:
356356
@@ -384,21 +384,21 @@ Since `soba` is just a `list` of `miso`, you can add a bunch of `miso` and they'
384384 [/bar/txt %del ~]
385385 [/baz/txt %del ~]
386386 ==
387−;< ~ bind:m (send-raw-card:strandio [%pass /info %arvo %c %info %home %& soba-a])
388−;< ~ bind:m (send-raw-card:strandio [%pass /info %arvo %c %info %home %& soba-b])
387+;< ~ bind:m (send-raw-card:strandio [%pass /info %arvo %c %info %base %& soba-a])
388+;< ~ bind:m (send-raw-card:strandio [%pass /info %arvo %c %info %base %& soba-b])
389389(pure:m !>(~))
390390```
391391
392−Save to `ted/multi-change.hoon`, `|commit %home`, and run:
392+Save to `ted/multi-change.hoon`, `|commit %base`, and run:
393393
394394```
395395> -multi-change
396−+ /~zod/home/37/foo/txt
397−+ /~zod/home/37/bar/txt
398−+ /~zod/home/37/baz/txt
399−- /~zod/home/38/foo/txt
400−- /~zod/home/38/bar/txt
401−- /~zod/home/38/baz/txt
396++ /~zod/base/37/foo/txt
397++ /~zod/base/37/bar/txt
398++ /~zod/base/37/baz/txt
399+- /~zod/base/38/foo/txt
400+- /~zod/base/38/bar/txt
401+- /~zod/base/38/baz/txt
402402```
403403
404404## Manage Mounts
@@ -413,44 +413,41 @@ Using the `send-task-take-gift.hoon` thread, let's make such a request:
413413
414414```
415415> -send-task-take-gift [%boat ~]
416−[%hill p=~[%home]]
416+[%hill p=~[%base]]
417417```
418418
419419### `%mont`
420420
421421Here we'll look at mounting `desk`s, directories and files to unix by sending Clay a `%mont` `task`.
422422
423−Let's first try mounting our `%kids` desk:
423+Let's first try mounting our `%garden` desk:
424424
425425```
426−> |pass [%c [%mont %kids [our %kids da+now] /]]
426+> |pass [%c [%mont %garden [our %garden da+now] /]]
427427```
428428
429−If you look in your pier, you should now see a `kids` folder which contains the contents of that `desk`.
429+If you look in your pier, you should now see a `garden` folder which contains the contents of that `desk`.
430430
431431If we make a `%boat` request as detailed in the [%boat](#boat) section, we'll now see the mount point listed:
432432
433433```
434434> -send-task-take-gift [%boat ~]
435−[%hill p=~[%kids %home]]cruz gift. It looks like:
436−
437−[%cruz cez=(map @ta crew)] :: permission groups
438−The cez is just a map from group name to crew
435+[%hill p=~[%garden %base]]
439436```
440437
441438Note the mount point doesn't need to match a `desk`, file or directory. We can also do:
442439
443440```
444−> |pass [%c [%mont %wibbly-wobbly [our %home da+now] /]]
441+> |pass [%c [%mont %wibbly-wobbly [our %base da+now] /]]
445442```
446443
447−And you'll now see that there's a `wibbly-wobbly` folder with the contents of the `%home` `desk`. You'll also notice we can mount the same file or directory more than once. There's no problem having `%home` mounted to both `home` and `wibbly-wobbly`. The only requirement is that their mount points be unique.
444+And you'll now see that there's a `wibbly-wobbly` folder with the contents of the `%base` `desk`. You'll also notice we can mount the same file or directory more than once. There's no problem having `%base` mounted to both `base` and `wibbly-wobbly`. The only requirement is that their mount points be unique.
448445
449446Let's try mounting a subdirectory and a single folder:
450447
451448```
452−> |pass [%c [%mont %gen [our %home da+now] /gen]]
453−> |pass [%c [%mont %hi [our %home da+now] /gen/hood/hi]]
449+> |pass [%c [%mont %gen [our %base da+now] /gen]]
450+> |pass [%c [%mont %hi [our %base da+now] /gen/hood/hi]]
454451```
455452
456453If you look in your pier you'll now see a `gen` folder with the contents of `/gen` and a `hi.hoon` file by itself. Notice how the file extension has been automatically added.
@@ -459,10 +456,10 @@ If you look in your pier you'll now see a `gen` folder with the contents of `/ge
459456
460457Here we'll look at unmounting `desk`s, directories and files by sending Clay a `%ogre` `task`.
461458
462−Let's unmount what we mounted in the [%mont](#mont) section. First we'll unmount the `%kids` desk:
459+Let's unmount what we mounted in the [%mont](#mont) section. First we'll unmount the `%garden` desk:
463460
464461```
465−|pass [%c [%ogre %kids]]
462+|pass [%c [%ogre %garden]]
466463```
467464
468465Our custom mount point `%wibbly-wobbly`:
@@ -480,8 +477,8 @@ And the single `hi.hoon` we previously mounted by specifying its mount point `%h
480477If we specify a non-existent mount point it will fail with an error printed to the dojo like:
481478
482479```
483−> |pass [%c [%ogre %kids]]
484−[%not-mounted %kids]
480+> |pass [%c [%ogre %foo]]
481+[%not-mounted %foo]
485482```
486483
487484If we give it an unmounted `beam` it will not print an error but still won't work.
@@ -492,11 +489,11 @@ Here we'll look at committing changed files by sending Clay a `%dirk` `task`.
492489
493490This `task` performs the same function as the `|commit` dojo command.
494491
495−With your `%home` `desk` mounted, try adding a file and send a `%dirk` to commit the change:
492+With your `%base` `desk` mounted, try adding a file and send a `%dirk` to commit the change:
496493
497494```
498−> |pass [%c [%dirk %home]]
499−+ /~zod/home/12/foo/txt
495+> |pass [%c [%dirk %base]]
496++ /~zod/base/12/foo/txt
500497```
501498
502499Clay will print the changed files to the dojo with a leading `+`, `-` or `:` to indicate a new file, deleted file and changed file respectively.
@@ -514,7 +511,7 @@ Here we'll look at merging `desk`s by sending Clay a `%merg` `task` and receivin
514511First, using the `send-task-take-gift.hoon` thread, let's try creating a new `desk`:
515512
516513```
517−> -send-task-take-gift [%merg %foo our %home da+now %init]
514+> -send-task-take-gift [%merg %foo our %base da+now %init]
518515[%mere p=[%.y p={}]]
519516```
520517
@@ -522,15 +519,15 @@ Now if we scry for our `desk`s we'll see `%foo` is there:
522519
523520```
524521> .^((set desk) %cd /===)
525−{%home %foo %kids}
522+{%bitcoin %base %landscape %webterm %garden %foo}
526523```
527524
528525Next, we'll create a merge conflict and try a couple of things. Mount `%foo` with `|mount /=foo=`, then add a `foo.txt` to both `desk`s but with different text in each and `|commit` them.
529526
530−Now we'll try merging `%home` into `%foo` with a `%mate` strategy:
527+Now we'll try merging `%base` into `%foo` with a `%mate` strategy:
531528
532529```
533−> -send-task-take-gift [%merg %foo our %home da+now %mate]
530+> -send-task-take-gift [%merg %foo our %base da+now %mate]
534531[ /foo
535532 [ %clay
536533 [ %mere
@@ -549,14 +546,14 @@ Now we'll try merging `%home` into `%foo` with a `%mate` strategy:
549546As you can see, the merge has failed. Let's try again with a `%meld` strategy:
550547
551548```
552−> -send-task-take-gift [%merg %foo our %home da+now %meld]
549+> -send-task-take-gift [%merg %foo our %base da+now %meld]
553550[/foo [%clay [%mere p=[%.y p={/foo/txt}]]]]
554551```
555552
556553Now the merge has succeeded and the `%mere` notes the file with a merge conflict. If we try with a `%only-that` strategy:
557554
558555```
559−> -send-task-take-gift [%merg %foo our %home da+now %only-that]
556+> -send-task-take-gift [%merg %foo our %base da+now %only-that]
560557[/foo [%clay [%mere p=[%.y p={}]]]]
561558: /~zod/foo/6/foo/txt
562559```
@@ -566,10 +563,10 @@ Now the merge has succeeded and the `%mere` notes the file with a merge conflict
566563Next, let's look at subscribing for future changes. Since the `case` is specified explicitly in the `%merge` `task`, we can set it in the future:
567564
568565```
569−> -send-task-take-gift [%merg %foo our %home da+(add ~m2 now) %only-that]
566+> -send-task-take-gift [%merg %foo our %base da+(add ~m2 now) %only-that]
570567```
571568
572−Now change the text in the `foo.txt` in the `%home` `desk`, hit backspace to detach the thread and `|commit %home`. After the two minutes pass you should see:
569+Now change the text in the `foo.txt` in the `%base` `desk`, hit backspace to detach the thread and `|commit %base`. After the two minutes pass you should see:
573570
574571```
575572[/foo [%clay [%mere p=[%.y p={}]]]]
@@ -589,7 +586,7 @@ Here we'll look at setting permissions by sending Clay a `%perm` `task`.
589586First, let's allow `~nes` to read `/gen/hood/hi/hoon`:
590587
591588```
592−> |pass [%c [%perm %home /gen/hood/hi/hoon %r ~ %white (sy [%.y ~nes]~)]]
589+> |pass [%c [%perm %base /gen/hood/hi/hoon %r ~ %white (sy [%.y ~nes]~)]]
593590```
594591
595592...and we'll do a `%p` scry to see that the permission was set:
@@ -602,7 +599,7 @@ First, let's allow `~nes` to read `/gen/hood/hi/hoon`:
602599You can see that `~nes` is now in the read whitelist. Next, let's try a write permission:
603600
604601```
605−> |pass [%c [%perm %home /ted %w ~ %white (sy [%.y ~nes]~)]]
602+> |pass [%c [%perm %base /ted %w ~ %white (sy [%.y ~nes]~)]]
606603```
607604
608605You can see `~nes` can now write to `/ted`:
@@ -624,7 +621,7 @@ Since we've set it for the whole `/ted` directory, if we check a file inside it
624621Now let's try setting both read and write permissions:
625622
626623```
627−> |pass [%c [%perm %home /gen/help/hoon %rw `[%black (sy [%.y ~nes]~)] `[%white (sy [%.y ~nes]~)]]]
624+> |pass [%c [%perm %base /gen/help/hoon %rw `[%black (sy [%.y ~nes]~)] `[%white (sy [%.y ~nes]~)]]]
628625```
629626
630627```
@@ -637,7 +634,7 @@ Lastly, let's look at deleting a permission rule we've previously set. To do tha
637634For example, to remove a read permission (or write if you specify `%w`):
638635
639636```
640−> |pass [%c [%perm %home /gen/help/hoon %r ~]]
637+> |pass [%c [%perm %base /gen/help/hoon %r ~]]
641638```
642639
643640```
@@ -648,7 +645,7 @@ For example, to remove a read permission (or write if you specify `%w`):
648645...and to remove both read and write at the same time:
649646
650647```
651−> |pass [%c [%perm %home /gen/help/hoon %rw ~ ~]]
648+> |pass [%c [%perm %base /gen/help/hoon %rw ~ ~]]
652649```
653650
654651```
@@ -692,8 +689,8 @@ Here we'll look at retrieving a list of all files and directories in all `desk`s
692689First we'll set a couple of permissions for the `foo` group we created in the [%cred](#cred) section:
693690
694691```
695−> |pass [%c [%perm %home /gen/hood/hi/hoon %w ~ %white (sy [%.n 'foo']~)]]
696−> |pass [%c [%perm %home /ted %w ~ %white (sy [%.n 'foo']~)]]
692+> |pass [%c [%perm %base /gen/hood/hi/hoon %w ~ %white (sy [%.n 'foo']~)]]
693+> |pass [%c [%perm %base /ted %w ~ %white (sy [%.n 'foo']~)]]
697694```
698695
699696Notice we use a `%.n` in the `whom` to indicate a group rather than the `%.y` of a ship.
@@ -704,7 +701,7 @@ Now we'll use the `send-task-take-gift.hoon` thread to try `%crow`:
704701> -send-task-take-gift [%crow 'foo']
705702[ %croz
706703 rus
707− { [ p=%home
704+ { [ p=%base
708705 q
709706 [ r={}
710707 w
@@ -725,29 +722,29 @@ See the [Foreign Ships](/docs/arvo/clay/tasks#foreign-ships) section of the [API
725722
726723Here we'll look at reading files on a foreign ship by sending Clay a `%warp` `task` with a foreign ship in the `wer` field and receiving a `%writ` `gift` in response.
727724
728−We'll use a fake ~nes as the the foreign ship and a fake ~zod as the local ship.
725+We'll use a fake `~nes` as the the foreign ship and a fake `~zod` as the local ship.
729726
730−First we'll set permissions on the foreign ship. Create a file called `foo.txt` in the `%home` of ~nes, then send a `%perm` request to allow ~zod to read and write the file:
727+First we'll set permissions on the foreign ship. Create a file called `foo.txt` in the `%base` of ~nes, then send a `%perm` request to allow ~zod to read and write the file:
731728
732729```
733−> |pass [%c [%perm %home /foo/txt %rw `[%white (sy [%.y ~zod]~)] `[%white (sy [%.y ~zod]~)]]]
730+> |pass [%c [%perm %base /foo/txt %rw `[%white (sy [%.y ~zod]~)] `[%white (sy [%.y ~zod]~)]]]
734731```
735732
736−If we scry the file for its permissions with a `%p` `care`, we'll see ~zod is now whitelisted:
733+If we scry the file for its permissions with a `%p` `care`, we'll see `~zod` is now whitelisted:
737734
738735```
739736> .^([r=dict:clay w=dict:clay] %cp /===/foo/txt)
740737[r=[src=/foo/txt rul=[mod=%white who=[p={~zod} q={}]]] w=[src=/foo/txt rul=[mod=%white who=[p={~zod} q={}]]]]
741738```
742739
743−Back on ~zod: Using the `send-task-take-gift.hoon` thread, send a `%x` read request for `/foo/txt` on ~nes like:
740+Back on `~zod`: Using the `send-task-take-gift.hoon` thread, send a `%x` read request for `/foo/txt` on ~nes like:
744741
745742```
746−> -send-task-take-gift [%warp ~nes %home ~ %sing %x da+now /foo/txt]
743+> -send-task-take-gift [%warp ~nes %base ~ %sing %x da+now /foo/txt]
747744[ %writ
748745 p
749746 [ ~
750− [ p=[p=%x q=[%da p=~2021.5.3..08.24.22..9ce7] r=%home]
747+ [ p=[p=%x q=[%da p=~2021.5.3..08.24.22..9ce7] r=%base]
751748 q=/foo/txt
752749 r=[p=%txt q=[#t/txt=*'' q=[7.303.014 0]]]
753750 ]
@@ -758,11 +755,11 @@ Back on ~zod: Using the `send-task-take-gift.hoon` thread, send a `%x` read requ
758755As you can see, we've received a `%writ` containing the requested data just as we would with a local request. Let's try a `%u`:
759756
760757```
761−> -send-task-take-gift [%warp ~nes %home ~ %sing %u da+now /foo/txt]
758+> -send-task-take-gift [%warp ~nes %base ~ %sing %u da+now /foo/txt]
762759[ %writ
763760 p
764761 [ ~
765− [ p=[p=%u q=[%da p=~2021.5.3..08.26.32..88cf] r=%home]
762+ [ p=[p=%u q=[%da p=~2021.5.3..08.26.32..88cf] r=%base]
766763 q=/foo/txt
767764 r=[p=%flag q=[#t/?(%.y %.n) q=0]]
768765 ]
@@ -773,7 +770,7 @@ As you can see, we've received a `%writ` containing the requested data just as w
773770If we send a `%d` request however, it will crash:
774771
775772```
776−> -send-task-take-gift [%warp ~nes %home ~ %sing %d da+now /foo/txt]
773+> -send-task-take-gift [%warp ~nes %base ~ %sing %d da+now /foo/txt]
777774call: failed
778775/sys/vane/clay/hoon:<[4.085 3].[4.314 5]>
779776...
content/docs/arvo/clay/marks/_index.mdnew file+23
@@ -0,0 +1,23 @@
1++++
2+title = "Marks"
3+weight = 10
4+sort_by = "weight"
5+template = "sections/docs/chapters.html"
6+insert_anchor_links = "right"
7++++
8+
9+[Overview](/docs/arvo/clay/marks/marks)
10+
11+Overview of `mark`s.
12+
13+[Writing Marks](/docs/arvo/clay/marks/writing-marks)
14+
15+A practical walk-through of writing a `mark` file.
16+
17+[Using Marks](/docs/arvo/clay/marks/using-marks)
18+
19+Details of using `mark` conversion gates and `mark` cores in your own code.
20+
21+[Examples](/docs/arvo/clay/marks/examples)
22+
23+The example code used in the Writing Marks guide.
content/docs/arvo/clay/marks/examples.mdnew file+248
@@ -0,0 +1,248 @@
1++++
2+title = "Examples"
3+weight = 4
4+template = "doc.html"
5++++
6+
7+These are the files used in the [Writing Marks](/docs/arvo/clay/marks/writing-marks) guide.
8+
9+## `/lib/csv/hoon`
10+
11+```hoon
12+|%
13+++ validate :: All rows same length?
14+ |= csv=(list (list @t))
15+ ^- ?
16+ =/ result
17+ %+ roll csv
18+ |= [row=(list @t) =flag ref=(unit @ud)]
19+ ?. flag
20+ [flag ref]
21+ ?~ ref
22+ [flag `(lent row)]
23+ ?. =(u.ref (lent row))
24+ [%.n ref]
25+ [flag ref]
26+ flag.result
27+++ en-csv :: csv -> atom (to mime)
28+ |= csv=(list (list @t))
29+ |^ ^- @t
30+ (cat 3 (crip (join '\0a' (turn csv en-row))) '\0a')
31+ ++ en-row :: encode row
32+ |= row=(list @t)
33+ ^- @t
34+ (crip (join ',' (turn row en-field)))
35+ ++ en-field :: encode field
36+ |= field=@t
37+ ^- @t
38+ %+ rash
39+ field
40+ %+ cook
41+ |= =tape
42+ ^- @t
43+ ?~ tape ''
44+ ?: =('"' i.tape)
45+ (cat 3 (crip tape) '"')
46+ (crip tape)
47+ ;~ pose
48+ (full (star ;~(less (mask "\",\0a\0d") next)))
49+ ;~ plug
50+ (easy '"')
51+ (star ;~(pose (cold '""' doq) next))
52+ ==
53+ ==
54+ --
55+++ de-csv :: atom -> csv (from mime)
56+ |= dat=@t
57+ |^ ^- (list (list @t))
58+ =/ parsed (parse dat)
59+ ?. (validate parsed)
60+ ~|(%mixed-col-count !!)
61+ parsed
62+ ++ parse :: parse cord
63+ |= dat=@t
64+ |^ ^- (list (list @t))
65+ %+ rash
66+ dat
67+ %+ most
68+ ;~(pose (jest '\0d\0a') (mask "\0a\0d"))
69+ (most com parse-field)
70+ ++ parse-field :: parse field from cord
71+ |^
72+ %+ cook
73+ |=(a=tape (crip a))
74+ ;~(pose unenclosed enclosed)
75+ ++ unenclosed :: unquoted field
76+ ;~ sfix
77+ (star ;~(less (mask "\",\0a\0d") next))
78+ ;~ pose
79+ ;~ plug
80+ ;~(pose (jest '\0d\0a') (mask "\0a\0d"))
81+ ;~(less next (easy ~))
82+ ==
83+ ;~(less doq (easy ~))
84+ ==
85+ ==
86+ ++ enclosed :: quoted field
87+ |^
88+ ;~ sfix
89+ (ifix [prefix suffix] content)
90+ ;~ pose
91+ ;~(simu (mask ",\0a\0d") (easy ~))
92+ ;~ plug
93+ ;~(pose (jest '\0d\0a') (mask "\0a\0d"))
94+ ;~(less next (easy ~))
95+ ==
96+ ;~(less next (easy ~))
97+ ==
98+ ==
99+ ++ content :: quoted field contents
100+ %- star
101+ ;~ pose
102+ (cold '"' (jest '""'))
103+ %+ cold '\0a'
104+ ;~(pose (jest '\0d\0a') (just '\0d'))
105+ ;~(less doq next)
106+ ==
107+ ++ prefix ;~(pose ;~(plug (star ace) doq) doq) :: quoted field prefix
108+ ++ suffix ;~(pose ;~(plug doq (star ace)) doq) :: quoted field suffix
109+ --
110+ --
111+ --
112+ --
113+++ csv-join
114+ |= [ali=(urge:clay (list @t)) bob=(urge:clay (list @t))]
115+ ^- (unit (urge:clay (list @t)))
116+ |^
117+ =. ali (clean ali)
118+ =. bob (clean bob)
119+ |- ^- (unit (urge:clay (list @t)))
120+ ?~ ali `bob
121+ ?~ bob `ali
122+ ?- -.i.ali
123+ %&
124+ ?- -.i.bob
125+ %&
126+ ?: =(p.i.ali p.i.bob)
127+ %+ bind $(ali t.ali, bob t.bob)
128+ |=(cud=(urge:clay (list @t)) [i.ali cud])
129+ ?: (gth p.i.ali p.i.bob)
130+ %+ bind $(p.i.ali (sub p.i.ali p.i.bob), bob t.bob)
131+ |=(cud=(urge:clay (list @t)) [i.bob cud])
132+ %+ bind $(ali t.ali, p.i.bob (sub p.i.bob p.i.ali))
133+ |=(cud=(urge:clay (list @t)) [i.ali cud])
134+ ::
135+ %|
136+ ?: =(p.i.ali (lent p.i.bob))
137+ %+ bind $(ali t.ali, bob t.bob)
138+ |=(cud=(urge:clay (list @t)) [i.bob cud])
139+ ?: (gth p.i.ali (lent p.i.bob))
140+ %+ bind $(p.i.ali (sub p.i.ali (lent p.i.bob)), bob t.bob)
141+ |=(cud=(urge:clay (list @t)) [i.bob cud])
142+ ~
143+ ==
144+ ::
145+ %|
146+ ?- -.i.bob
147+ %|
148+ ?. =(i.ali i.bob)
149+ ~
150+ %+ bind $(ali t.ali, bob t.bob)
151+ |=(cud=(urge:clay (list @t)) [i.ali cud])
152+ ::
153+ %&
154+ ?: =(p.i.bob (lent p.i.ali))
155+ %+ bind $(ali t.ali, bob t.bob)
156+ |=(cud=(urge:clay (list @t)) [i.ali cud])
157+ ?: (gth p.i.bob (lent p.i.ali))
158+ %+ bind $(ali t.ali, p.i.bob (sub p.i.bob (lent p.i.ali)))
159+ |=(cud=(urge:clay (list @t)) [i.ali cud])
160+ ~
161+ ==
162+ ==
163+ ++ clean :: clean
164+ |= wig=(urge:clay (list @t))
165+ ^- (urge:clay (list @t))
166+ ?~ wig ~
167+ ?~ t.wig wig
168+ ?: ?=(%& -.i.wig)
169+ ?: ?=(%& -.i.t.wig)
170+ $(wig [[%& (add p.i.wig p.i.t.wig)] t.t.wig])
171+ [i.wig $(wig t.wig)]
172+ ?: ?=(%| -.i.t.wig)
173+ $(wig [[%| (welp p.i.wig p.i.t.wig) (welp q.i.wig q.i.t.wig)] t.t.wig])
174+ [i.wig $(wig t.wig)]
175+ --
176+--
177+```
178+
179+## `/mar/csv/hoon`
180+
181+```hoon
182+/+ *csv
183+|_ csv=(list (list @t))
184+++ grab
185+ |%
186+ ++ mime |=((pair mite octs) (de-csv q.q))
187+ ++ noun
188+ |= n=*
189+ ^- (list (list @t))
190+ =/ result ((list (list @t)) n)
191+ ?> (validate result)
192+ result
193+ --
194+++ grow
195+ |%
196+ ++ mime
197+ ?> (validate csv)
198+ [/text/csv (as-octs:mimes:html (en-csv csv))]
199+ ++ noun
200+ ?> (validate csv)
201+ csv
202+ --
203+++ grad
204+ |%
205+ ++ form %csv-diff
206+ ++ diff
207+ |= bob=(list (list @t))
208+ ^- (urge:clay (list @t))
209+ ?> (validate csv)
210+ ?> (validate bob)
211+ (lusk:differ csv bob (loss:differ csv bob))
212+ ++ pact
213+ |= dif=(urge:clay (list @t))
214+ ^- (list (list @t))
215+ =/ result (lurk:differ csv dif)
216+ ?> (validate result)
217+ result
218+ ++ join
219+ |= $: ali=(urge:clay (list @t))
220+ bob=(urge:clay (list @t))
221+ ==
222+ ^- (unit (urge:clay (list @t)))
223+ (csv-join ali bob)
224+ ++ mash
225+ |= $: [ship desk (urge:clay (list @t))]
226+ [ship desk (urge:clay (list @t))]
227+ ==
228+ ^- (urge:clay (list @t))
229+ ~|(%csv-mash !!)
230+ --
231+--
232+```
233+
234+## `/mar/csv-diff/hoon`
235+
236+```hoon
237+|_ dif=(urge:clay (list @t))
238+++ grab
239+ |%
240+ ++ noun (urge:clay (list @t))
241+ --
242+++ grow
243+ |%
244+ ++ noun dif
245+ --
246+++ grad %noun
247+--
248+```
content/docs/arvo/clay/marks/marks.mdnew file+59
@@ -0,0 +1,59 @@
1++++
2+title = "Overview"
3+weight = 1
4+template = "doc.html"
5++++
6+
7+Clay is a typed filesystem, and we call these file types `mark`s. When talking about Hoon and Arvo we'll often talk of types like `@ud`, `(list @t)`, etc. A `mark` will specify such a type for its files, but it does more than just that - it also defines conversion routines to and from other `mark`s, as well as diff, patch, and merge routines.
8+
9+For example, a `%txt` `mark` defines the type of a `%txt` file as a `wain` (a `(list @t)`). It defines a conversion function to a `%mime` `mark` to allow it to be serialized and sent to a browser or to the Unix filesystem. It also includes Hunt-McIlroy diff, patch, and merge algorithms. Conversion functions will be different for different `mark`s, as will things like diff algorithms. An image file like a `%png`, for example, just replaces the old blob of data with the new one rather than implementing a complex binary diff and patch algorithm, so how these functions are implemented depends on the file type and use case.
10+
11+`mark` files are stored in the `/mar` directory. The `path` of the `%txt` `mark`, for example, is `/mar/txt/hoon`.
12+
13+A `mark` is a door (a core with a sample) with three arms: `+grab`, `+grow`, and `+grad`. The door's sample defines its type. In `+grab` is a series of functions to convert from other `mark`s to the given `mark`. In `+grow` is a series of functions to convert from the given `mark` to other `mark`s. In `+grad` is `+diff`, `+pact`, `+join`, `+mash`, and `+form`.
14+
15+Here's its basic structure in an informal pseudocode:
16+
17+```
18+|_ <mark-type>
19+++ grab:
20+ ++ noun: <noun> -> <mark-type>
21+ ++ mime: <mime> -> <mark-type>
22+ ++ txt: <txt> -> <mark-type>
23+ ...
24+++ grow:
25+ ++ noun: <mark-type> -> <noun>
26+ ++ mime: <mark-type> -> <mime>
27+ ++ txt: <mark-type> -> <txt>
28+ ...
29+++ grad
30+ ++ form: <diff-mark>
31+ ++ diff: (<mark-type>, <mark-type>) -> <diff-type>
32+ ++ pact: (<mark-type>, <diff-type>) -> <mark-type>
33+ ++ join: (<diff-type>, <diff-type>) -> <diff-type> or NULL
34+ ++ mash: (<diff-type>, <diff-type>) -> <diff-type>
35+```
36+
37+These types are basically what you would expect. In `+grab`, only a `+noun` arm is mandatory, the rest are optional. The `+grow` arm itself is optional, as are any arms within it. In `+grad`, all arms are mandatory unless revision control is delegated to another `mark`, which we'll discuss later.
38+
39+In general, for a particular `mark`, the `+grab` and `+grow` entries should be inverses of each other. They needn't be symmetrical though - you may want to be able to convert from your `mark` to `%json` but not from `%json` to your `mark`, for example.
40+
41+In `+grad`, `+diff` takes two instances of a `mark` and produces a diff of them whose `mark` is given by `+form`. `+pact` takes an instance of a `mark` and patches it with the given diff. In general, if `+diff` called with A and B produces diff D, then `+pact` called with A and D should produce B.
42+
43+`+join` takes two diffs and attempts to merge them into a single diff. If there are conflicts, it produces null. `+mash` takes two diffs and forces a merge, even if there are conflicts. How your `+mash` function force-merges conflicting diffs is up to you. The `%txt` `mark` annotates any conflicts, for example, but there may be other ways. If `+join` of two diffs does not produce null, then `+mash` of the same diffs should produce the same result. Note that `+mash` is not used by Clay in its ordinary filesystem operations, so you may wish to leave it as a dummy arm that crashes if called.
44+
45+Alternately, instead of `+form`, `+diff`, `+pact`, `+join`, and `+mash`, a `mark` can provide the same functionality by defining `+grad` to be the name of another `mark` to which we wish to delegate the revision control responsibilities. Then, before running any of those functions, Clay will convert to the other `mark`, and convert back afterward. For example, the `%hoon` `mark` is revision-controlled in the same way as `%txt`, so its `+grad` is simply `++ grad %txt`. Of course, `+txt` must be defined in `+grow` and `+grab` as well.
46+
47+We mentioned that `+noun` is the only mandatory arm in `+grab`, but there are a couple of others that, while not mandatory, are of particular interest.
48+
49+The first is a `+mime` arm for converting to and from the `%mime` `mark`. When you `|commit` a file to a `desk` mounted to Unix, Clay will receive the data as a `%mime` `mark`, and then convert it to the `mark` matching the file extension. It will perform the same operation in reverse when mounting a `desk` to Unix. For this reason, any `mark` you wish to be able to access from the Unix filesystem should have `%mime` conversion routines. In certain cases (such as the scry interface), Eyre will also need to convert your `mark` to a `%mime` in order to encode it in an HTTP response, so you may require a `+mime` arm for that reason as well.
50+
51+The second case of interest is the `+json` arm for converting to and from a `%json` `mark`. If, for example, you want to write a Gall agent to which you can subscribe through Eyre's channel system, it must produce data with a `mark` containing `%json` conversion routines. If it doesn't, Eyre will not be able to deliver the data to the subscribed HTTP client in the SSE stream.
52+
53+## Sections
54+
55+[Writing Marks](/docs/arvo/clay/marks/writing-marks) - A practical walk-through of writing a `mark` file.
56+
57+[Using Marks](/docs/arvo/clay/marks/using-marks) - Details of using `mark` conversion gates and `mark` cores in your own code.
58+
59+[Examples](/docs/arvo/clay/marks/examples) - The example code used in the Writing Marks guide.
content/docs/arvo/clay/marks/using-marks.mdnew file+240
@@ -0,0 +1,240 @@
1++++
2+title = "Using Marks"
3+weight = 3
4+template = "doc.html"
5++++
6+
7+In the last document, [Writing Marks](/docs/arvo/clay/marks/writing-marks), we walked through writing `mark` files and touched on how Clay handles them. They needn't just be left to background vane processes though, you can also use them yourself in your code.
8+
9+There are two kinds of cores that Clay can build for you: A `mark` conversion gate and a `mark` core. Each has two kinds: Statically typed and dynamically typed. Clay has a `care` for producing each of these:
10+
11+- `%b` - Build a dynamically typed `mark` core.
12+- `%c` - Build a dynamically typed `mark` conversion gate.
13+- `%e` - Build a statically typed `mark` core.
14+- `%f` - Build a statically typed `mark` conversion gate.
15+
16+You can either use these by `%pass`ing Clay a [%warp task](/docs/arvo/clay/tasks#warp) with the appropriate `care`, or else with a [Clay scry](/docs/arvo/clay/scry). In the examples here we've used the latter.
17+
18+## mark conversion gates
19+
20+`mark` conversion gates simply convert from one `mark` to another.
21+
22+### Static
23+
24+A static `mark` conversion gate looks like `$-(a b)`, where `a` is the type of the `mark` you're converting _from_, and `b` is type of the `mark` you're converting _to_. For example, a `mark` conversion gate from `%txt` to `%mime` would look like `$-(wain mime)`. You'd simply feed it a `wain` and get a `$mime` in return.
25+
26+#### Example
27+
28+We get our `%txt` to `%mime` `mark` conversion gate with a `%f` scry like so:
29+
30+```
31+> =txt-to-mime .^($-(wain mime) %cf /===/txt/mime)
32+```
33+
34+Note we had to specify the type of the gate as `$-(wain mime)` in the scry - if the type returned by the scry doesn't match that specification it'll fail. This is where a statically typed `mark` conversion gate differs from the dynamically typed gate, which we'll discuss later.
35+
36+Now that we have our conversion gate, we can just call it with a valid `wain` and we'll get our `$mime` in return:
37+
38+```
39+> (txt-to-mime ~['foo'])
40+[p=/text/plain q=[p=3 q=7.303.014]]
41+```
42+
43+### Dynamic
44+
45+A dynamically typed `mark` conversion gate is called a `$tube:clay`, and looks like:
46+
47+```hoon
48++$ tube $-(vase vase)
49+```
50+
51+As you can see from the type definition, it takes and returns a `vase` rather than needing the types explicitly defined. Rather than failing on a type mismatch when the scry is performed, it'll instead fail when it's actually run and fed a `vase` of the wrong type. Apart from handling `vase`s, it otherwise behaves the same as a statically typed `mark` conversion gate.
52+
53+#### Example
54+
55+We get our `%txt` to `%mime` `$tube` with a `%c` scry like so:
56+
57+```
58+> =txt-mime-tube .^(tube:clay %cc /===/txt/mime)
59+```
60+
61+And then we can again feed it the `wain` that a `%txt` `mark` wants, only this time it's wrapped in a `vase`:
62+
63+```
64+> !< mime (txt-mime-tube !>(~['foo']))
65+[p=/text/plain q=[p=3 q=7.303.014]]
66+```
67+
68+We then get our `$mime` back, but also in a `vase`.
69+
70+## mark cores
71+
72+While a `mark` conversion gate is built from functions defined in `+grab` and `+grow`, a `mark` core gives you everything in `+grad` so you can create diffs, merge diffs, patch files, etc. An extra arm `+vale` is also included that lets you convert a `noun` to the type the `%mark` takes by running the `+noun` arm of `+grab` in the original `mark` file.
73+
74+### Static
75+
76+A statically typed `mark` core is a `(nave:clay a b)` where `a` is the type of the `mark` and `b` is the type for diffs (which is the type of the `mark` specified in `+form:grad`). For example, a static `mark` core for a `%txt` `mark` looks like `(nave:clay wain (urge:clay cord))`.
77+
78+`+nave:clay` looks like this in full:
79+
80+```hoon
81+++ nave
82+ |$ [typ dif]
83+ $_
84+ ^?
85+ |%
86+ ++ diff |~([old=typ new=typ] *dif)
87+ ++ form *mark
88+ ++ join |~([a=dif b=dif] *(unit (unit dif)))
89+ ++ mash
90+ |~ [a=[ship desk dif] b=[ship desk dif]]
91+ *(unit dif)
92+ ++ pact |~([typ dif] *typ)
93+ ++ vale |~(noun *typ)
94+ --
95+```
96+
97+In brief, the arms of the core do the following:
98+
99+- `+form` - `mark` for diffs.
100+- `+vale` - Clam `noun` to the `mark`'s type.
101+- `+diff` - Create diff of two files.
102+- `+pact` - Patch a file with a diff.
103+- `+join` - Merge two diffs, returning `~` if there's a conflict.
104+- `+mash` - Force merge of two diffs.
105+
106+#### Examples
107+
108+First we get the `%txt` `mark` core with a `%e` scry:
109+
110+```
111+> =txt-nave .^((nave:clay wain (urge:clay cord)) %ce /===/txt)
112+```
113+
114+Note we specified the `mark` type `wain` and diff type `(urge:clay cord)` in the `nave` returned by the scry.
115+
116+We can see the `mark` for diffs with `+form`:
117+
118+```
119+> form.txt-nave
120+%txt-diff
121+```
122+
123+To clam a noun to the type of the `mark` (a `wain` in the case of a `%txt` `mark`), we can call `+vale` with a `noun`:
124+
125+```
126+> (vale:txt-nave ~['foo' 'bar'])
127+<|foo bar|>
128+```
129+
130+We can create a diff of two files with `+diff`:
131+
132+```
133+> (diff:txt-nave ~['foo' 'bar' 'baz'] ~['foo' 'zoo' 'baz'])
134+~[[%.y p=1] [%.n p=<|bar|> q=<|zoo|>] [%.y p=1]]
135+```
136+
137+Let's create some more diffs for experimentation:
138+
139+```
140+> =diff-a (diff:txt-nave ~['foo' 'bar' 'baz'] ~['foo' 'zoo' 'baz'])
141+> =diff-b (diff:txt-nave ~['foo' 'bar' 'baz'] ~['zap' 'bar' 'baz'])
142+> =diff-c (diff:txt-nave ~['foo' 'bar' 'baz'] ~['foo' 'bla' 'baz'])
143+```
144+
145+If we try merging diffs `a` and `b` with `+join`, we get a new merged diff back in a `unit`:
146+
147+```
148+> (join:txt-nave diff-a diff-b)
149+[~ [~ ~[[%.n p=<|foo|> q=<|zap|>] [%.n p=<|bar|> q=<|zoo|>] [%.y p=1]]]]
150+```
151+
152+If we try merging diffs `a` and `c` however, we get `~` because of a conflict:
153+
154+```
155+> (join:txt-nave diff-a diff-c)
156+[~ ~]
157+```
158+
159+If we run `+mash` on `a` and `b` we get the same diff as with `+join` (sans the `unit`):
160+
161+```
162+> (mash:txt-nave [our %home diff-a] [our %blah diff-b])
163+[~ ~[[%.n p=<|foo|> q=<|zap|>] [%.n p=<|bar|> q=<|zoo|>] [%.y p=1]]]
164+```
165+
166+If we `+mash` `a` and `c`, however, we get a diff with the conflict annotated rather than just `~`:
167+
168+```
169+> (mash:txt-nave [our %home diff-a] [our %blah diff-c])
170+[ ~
171+ ~[
172+ [%.y p=1]
173+ [ %.n
174+ p=<|bar|>
175+ q
176+ <|>>>>>>>>>>>> ~zod/home zoo ++++++++++++ bar ------------ bla <<<<<<<<<<<< ~zod/blah|>
177+ ]
178+ [%.y p=1]
179+ ]
180+]
181+```
182+
183+Note that the `%txt` `mark` annotates conflicts, but there are no specific rules around how the `+mash` arm should force-merge conflicting diffs apart from that it must return a valid diff, however the `mark` specified in `+form` defines that.
184+
185+Finally, we can patch our `wain` with diff `a` and get a new, modified `wain`:
186+
187+```
188+> (pact:txt-nave ~['foo' 'bar' 'baz'] diff-a)
189+<|foo zoo baz|>
190+```
191+
192+### Dynamic
193+
194+A dynamically typed `mark` core is a `$dais:clay`, which looks like:
195+
196+```hoon
197++$ dais
198+ $_ ^|
199+ |_ sam=vase
200+ ++ diff |~(new=_sam *vase)
201+ ++ form *mark
202+ ++ join |~([a=vase b=vase] *(unit (unit vase)))
203+ ++ mash
204+ |~ [a=[ship desk diff=vase] b=[ship desk diff=vase]]
205+ *(unit vase)
206+ ++ pact |~(diff=vase sam)
207+ ++ vale |~(noun sam)
208+ --
209+```
210+
211+It has the same arms as the statically typed `mark` core, the difference is that it takes and returns `vase`s rather than the data directly. Additionally, it's a door rather than an ordinary core, and takes the type of the `mark` wrapped in a `vase` as its argument.
212+
213+#### Examples
214+
215+We can get a `%txt` `mark` `dais` with a `%b` scry:
216+
217+```
218+> =txt-dais .^(dais:clay %cb /===/txt)
219+```
220+
221+Its `+form` arm functions the same as a static core:
222+
223+```
224+> form.txt-dais
225+%txt-diff
226+```
227+
228+So does `+vale` except it returns a `vase`:
229+
230+```
231+> !< wain (vale:txt-dais ~['foo' 'bar'])
232+<|foo bar|>
233+```
234+
235+All the other arms also deal in `vase`s. Because it's a door, the `+pact` and `+diff` arms take the original file in a `vase` as the door sample rather than being given directly to the arm. Calling `+diff` arm, for example, works like so:
236+
237+```
238+> !< (urge:clay cord) (~(diff txt-dais !>(~['foo' 'bar'])) !>(~['foo' 'baz']))
239+~[[%.y p=1] [%.n p=<|bar|> q=<|baz|>]]
240+```
content/docs/arvo/clay/marks/writing-marks.mdnew file+333
@@ -0,0 +1,333 @@
1++++
2+title = "Writing Marks"
3+weight = 2
4+template = "doc.html"
5++++
6+
7+Here we'll walk through a practical example of writing a `mark` file.
8+
9+We'll create a `mark` for CSV (comma separated values) files, a simple format for storing tabular data in a text file. Note that there's already a `csv.hoon` `mark` and library, but we'll create new ones for demonstrative purposes. It shouldn't be an issue to overwrite the existing ones on a fakezod.
10+
11+CSV files separate fields with commas and rows with line breaks. They look something like:
12+
13+```
14+foo,bar,baz
15+blah,blah,blah
16+1,2,3
17+```
18+
19+There is a little complexity surrounding special characters in fields and line endings, but otherwise the only other rule is that all rows must have the same number of fields. You can refer to [RFC4180 on the IETF website](https://datatracker.ietf.org/doc/html/rfc4180) for more details.
20+
21+We'll represent such a structure in Hoon as a `(list (list @t))` like:
22+
23+```hoon
24+[['foo' 'bar' 'baz' ~] ['blah' 'blah' 'blah' ~] ['1' '2' '3' ~] ~]
25+```
26+
27+We could perhaps create the type with a `$|` rune to include row-length validation in the mold itself, but a `(list (list @t))` is simpler for demonstrative purposes.
28+
29+## A simple mark
30+
31+Let's begin with the simplest `mark` file:
32+
33+```hoon
34+|_ csv=(list (list @t))
35+++ grab
36+ |%
37+ ++ noun (list (list @t))
38+ --
39+++ grow
40+ |%
41+ ++ noun csv
42+ --
43+++ grad %noun
44+--
45+```
46+
47+The door takes a `(list (list @t))` as its sample, and we've given it a face of `csv` so we can easily reference it. Note its face could be anything, it needn't be the name of our `mark`. When we're doing something with data that has a `%csv` `mark` like converting it to another `mark` or creating a diff, this is where our data will reside.
48+
49+Next we have the `+grab` arm of our door, which contains a core with arms for converting _to_ our `mark` _from_ other `mark`s. We've given it one arm for the `%noun` `mark` - the most generic `mark` which will take any `noun`. Our `+noun` arm will simply clam whatever it's given with the `(list (list @t))` `mold`.
50+
51+Next is the `+grow` arm which does the inverse of `+grab`, converting _from_ our `mark` _to_ another `mark`. We've also given it a `+noun` arm, this time it will simply return the door's sample named `csv`, which is of course already a `noun`.
52+
53+Note that the `+noun` arm is _mandatory_ in `+grab`. Clay cannot build a `mark` core without it. Conversion arms for any other `mark`s apart from `%noun` are optional.
54+
55+Finally we have the `+grad` arm. This arm specifies functions for revision control like creating diffs, patching files and so on. In our case, rather than writing all those functions, we've just delegated those tasks to the `%noun` `mark`. We can do this because we've specified conversion routines to and from the `%noun` `mark` in our `+grow` and `+grab` arms. When we modify a file with a `%csv` `mark`, Clay will convert our data to a `%noun` `mark`, execute the necessary `+grad` functions from the `%noun` `mark` file, and then convert it back to a `%csv` `mark` again.
56+
57+So now we have a valid `%csv` `mark` file. If we save this as `csv.hoon` in the `/mar` directory we could store `%csv` data in Clay. This may be sufficient for some applications, but what if we want to import a CSV file from Unix or elsewhere? In the next section, we'll look at conversions to and from a `%mime` `mark` to address this.
58+
59+## `%mime` conversions
60+
61+The `$mime` type represents raw data from Unix or elsewhere. For example, if a text file from Unix containing the word `foo` were converted to a `$mime` type in Urbit, it would look something like:
62+
63+```hoon
64+[/text/plain q=[p=3 q=7.303.014]]
65+```
66+
67+`/text/plain` is its [MIME type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types) and `p.q` is the byte-length of `q.q`, which is the data itself as an `atom`.
68+
69+The `%mime` `mark` is used by Clay to store and convert `$mime` data. It's an important `mark` for moving files from Unix to Urbit and vice versa. When you add a file to a `desk` you have mounted to Unix and `|commit` the change, Clay will first receive the file as a `%mime` `mark`, then convert from a `%mime` to whatever `mark` matches the file extension. For example, `foo.txt` will be converted from `%mime` to `%txt`. Additionally, data fetched by Iris over HTTP will come in as a `$mime-data:http`, which is an unvalidated form of `$mime` that you may wish to convert to a `%mime` `mark` and then to another `mark`. Likewise with Eyre, some of the lower-level interfaces receive HTTP requests with `$mime-data:http` in them.
70+
71+So with the nature of the `%mime` `mark` hopefully now clear, the reason we want conversion methods to and from `%mime` in our `%csv` `mark` is so we can import CSV files from Unix and vice versa.
72+
73+Since a CSV file on Unix will just be a long string with ASCII or UTF-8 encoding, we can treat `q.q` in the `$mime` as a `cord`, and thus write a parser to convert it to a `(list (list @t))`. For this purpose, here's a library: `csv.hoon`, which you can view in full on the [Examples](/docs/arvo/clay/marks/examples#libcsvhoon) page.
74+
75+The library contains four functions:
76+
77+- `+de-csv` - Parse a CSV `cord` to a `(list (list @t))`.
78+- `+en-csv` - Encode a `(list (list @t))` as a CSV `cord`.
79+- `+validate` - Check all rows of `(list (list @t))` are the same length.
80+- `+csv-join` - Ignore this for now, we'll use it later on.
81+
82+The decoding and encoding arms use parsing functions from the Hoon standard library. It's not important to be familiar with parsing in Hoon for our purposes here, but you can have a look at the [Parsing Guide](/docs/hoon/guides/parsing) in the Hoon documentation if you're interested. The important thing to note is that `+de-csv` takes a valid CSV-format `@t` and returns a `(list (list @t))`, and `+en-csv` does the reverse - it takes a `(list (list @t))` and returns a CSV-format `@t`.
83+
84+Let's try the library in the dojo. After we've added it to `/lib` and run `|commit`, we can build the file:
85+
86+```
87+> =csv -build-file %/lib/csv/hoon
88+```
89+
90+...try decode a CSV-format `@t`:
91+
92+```
93+> (de-csv:csv 'foo,bar,baz\0ablah,blah,blah\0a1,2,3')
94+~[<|foo bar baz|> <|blah blah blah|> <|1 2 3|>]
95+```
96+
97+...and try encode a `(list (list @t))` as a CSV-format `@t`:
98+
99+```
100+> (en-csv:csv [['foo' 'bar' 'baz' ~] ['blah' 'blah' 'blah' ~] ['1' '2' '3' ~] ~])
101+'foo,bar,baz\0ablah,blah,blah\0a1,2,3\0a'
102+```
103+
104+With that working, we can add an import for our library to our `%csv` `mark` defintion and add a `+mime` arm to both our `+grab` and `+grow` arms:
105+
106+```hoon
107+/+ *csv
108+|_ csv=(list (list @t))
109+++ grab
110+ |%
111+ ++ mime |=((pair mite octs) (de-csv q.q))
112+ ++ noun
113+ |= n=*
114+ ^- (list (list @t))
115+ =/ result ((list (list @t)) n)
116+ ?> (validate result)
117+ result
118+ --
119+++ grow
120+ |%
121+ ++ mime
122+ ?> (validate csv)
123+ [/text/csv (as-octs:mimes:html (en-csv csv))]
124+ ++ noun
125+ ?> (validate csv)
126+ csv
127+ --
128+++ grad %noun
129+--
130+```
131+
132+In `+grab` we've added a `+mime` arm to convert _from_ a `%mime` `mark` _to_ our `%csv` `mark`. It's a simple gate that takes a `$mime` (specified as `(pair mite octs)` to avoid conflict with the arm name), runs the data through the `+de-csv` function and returns a `(list (list @t))` of the CSV data.
133+
134+We've also added a `+mime` arm to `+grow` for converting _from_ our `%csv` `mark` _to_ a `%mime` `mark`. We encode our `(list (list @t))` `csv` sample with our `+en-csv` function and then run that through `as-octs:mimes:html` to get a `$octs` (so it has the byte-length). We also add the `/text/csv` MIME type so it's a valid `$mime`.
135+
136+Additionally, we've used the `+validate` function in a few places to make sure our CSV data has consistent row lengths.
137+
138+If we save the above mark file as `csv.hoon` in `/mar` and `|commit %home`, we should now be able to import CSV files into Urbit. Let's give it a go. In the root of our `%home` `desk`, let's add a file named `foo.csv` with the following contents:
139+
140+```
141+foo,bar,baz
142+blah,blah,blah
143+1,2,3
144+```
145+
146+If we now `|commit %home`, we should see it's been successfully added:
147+
148+```
149+> |commit %home
150+>=
151++ /~zod/home/4/foo/csv
152+```
153+
154+And if we try reading the file with the `-read` thread:
155+
156+```
157+> -read [%x our %home da+now /foo/csv]
158+~[<|foo bar baz|> <|blah blah blah|> <|1 2 3|>]
159+```
160+
161+We can see our `%csv` `mark` has successfully converted our `foo.csv` file to a `(list (list @t))` when it was imported.
162+
163+Let's try the other direction now. We can create a new `bar.csv` files in the root of `%home` from the dojo like so:
164+
165+```
166+> */bar/csv ~[['abc' 'def' ~] ['ghi' 'jkl' ~]]
167++ /~zod/home/5/bar/csv
168+```
169+
170+And if we check it in the terminal on the Unix side we can see it's been correctly encoded:
171+
172+```
173+> cat zod/home/bar.csv
174+abc,def
175+ghi,jkl
176+```
177+
178+So now our `%csv` `mark` lets us move data in and out of Urbit. In the next section, we'll look at the `+grad` arm in more detail.
179+
180+## `+grad`
181+
182+So far we've just delegated `+grad` functions to the `%noun` `mark`, but now we'll look at writing our own.
183+
184+For demonstrative purposes, we can just poach the algorithms used in the `+grad` arm of the `%txt` `mark` and modify them to take our `(list (list @t))` type instead of a `wain`. It's not the most efficient algorithm for a CSV file but it'll do the job.
185+
186+Our diff format will be a `(urge:clay (list @t))`, and we'll use some `differ` functions from `zuse.hoon` like `+loss`, `+lusk` and `+lurk` to produce diffs and apply patches.
187+
188+The [csv.hoon library](/docs/arvo/clay/marks/examples#libcsvhoon) we imported also contains a `+csv-join` function which we'll use in the `+join` arm, just to save space here.
189+
190+Here's the new `%csv` `mark` defintion:
191+
192+```hoon
193+/+ *csv
194+|_ csv=(list (list @t))
195+++ grab
196+ |%
197+ ++ mime |=((pair mite octs) (de-csv q.q))
198+ ++ noun
199+ |= n=*
200+ ^- (list (list @t))
201+ =/ result ((list (list @t)) n)
202+ ?> (validate result)
203+ result
204+ --
205+++ grow
206+ |%
207+ ++ mime
208+ ?> (validate csv)
209+ [/text/csv (as-octs:mimes:html (en-csv csv))]
210+ ++ noun
211+ ?> (validate csv)
212+ csv
213+ --
214+++ grad
215+ |%
216+ ++ form %csv-diff
217+ ++ diff
218+ |= bob=(list (list @t))
219+ ^- (urge:clay (list @t))
220+ ?> (validate csv)
221+ ?> (validate bob)
222+ (lusk:differ csv bob (loss:differ csv bob))
223+ ++ pact
224+ |= dif=(urge:clay (list @t))
225+ ^- (list (list @t))
226+ =/ result (lurk:differ csv dif)
227+ ?> (validate result)
228+ result
229+ ++ join
230+ |= $: ali=(urge:clay (list @t))
231+ bob=(urge:clay (list @t))
232+ ==
233+ ^- (unit (urge:clay (list @t)))
234+ (csv-join ali bob)
235+ ++ mash
236+ |= $: [ship desk (urge:clay (list @t))]
237+ [ship desk (urge:clay (list @t))]
238+ ==
239+ ^- (urge:clay (list @t))
240+ ~|(%csv-mash !!)
241+ --
242+--
243+```
244+
245+In our modified `+grad` arm, we've replaced the `%noun` delegation with a core containing five arms: `+form`, `+diff`, `+pact`, `+join`, and `+mash`. These arms are all required for a valid `+grad` if it's not delegated to another `mark`. We'll now look at each in detail.
246+
247+### `+form`
248+
249+```hoon
250+++ form %csv-diff
251+```
252+
253+`+form` simply specifies the `mark` of the diff file that may be produced by other `+grad` functions. If your diff is the same type as your `mark`, it could just specify itself like `%csv`. In our case our diff is a `(urge:clay (list @t))` rather than a `(list (list @t))`, so we need a separate mark file for the diff itself.
254+
255+Here's another `mark` file which can be saved as `csv-diff.hoon` in `/mar`:
256+
257+```hoon
258+|_ dif=(urge:clay (list @t))
259+++ grab
260+ |%
261+ ++ noun (urge:clay (list @t))
262+ --
263+++ grow
264+ |%
265+ ++ noun dif
266+ --
267+++ grad %noun
268+--
269+```
270+
271+It's very bare-bones, we just need it for our `%csv` `mark` to work. In our `%csv` `mark`, we've specified it as `%csv-diff` in `+form`.
272+
273+### `+diff`
274+
275+```hoon
276+++ diff
277+ |= bob=(list (list @t))
278+ ^- (urge:clay (list @t))
279+ ?> (validate csv)
280+ ?> (validate bob)
281+ (lusk:differ csv bob (loss:differ csv bob))
282+```
283+
284+This arm produces the diff of two `%csv` files. The first `%csv` file will be given as the sample of the parent door, which if you'll recall we gave a face of `csv`. The second `%csv` file will be given as the sample of the gate in `+diff`, which we've named `bob` here. We then just produce the diff of these two files and return it as the type of the mark specified in `+form`, which in our case is `(urge:clay (list @t))` for a `%csv-diff`. Clay will use `+diff` when a file is revised, so it doesn't have to store a whole new copy of the file each time it's modified.
285+
286+### `+pact`
287+
288+```hoon
289+++ pact
290+ |= dif=(urge:clay (list @t))
291+ ^- (list (list @t))
292+ =/ result (lurk:differ csv dif)
293+ ?> (validate result)
294+ result
295+```
296+
297+`+pact` patches a `%csv` file with the given diff. Its gate takes a diff and applies it to the `%csv` given as the sample of the parent door (which we gave a face of `csv`). If the patch succeeds, it will return a new `%csv` file - a valid `(list (list @t))`. When we read a file that's been modified in Clay, Clay will apply all the diffs it has with `+pact` and return the resulting file.
298+
299+### `+join`
300+
301+```hoon
302+++ join
303+ |= $: ali=(urge:clay (list @t))
304+ bob=(urge:clay (list @t))
305+ ==
306+ ^- (unit (urge:clay (list @t)))
307+ (csv-join ali bob)
308+```
309+
310+The `+join` arm merges two different diffs. It takes them both as the sample of its gate (which we've named `ali` and `bob`), and returns a new diff wrapped in a `unit` like `(unit (urge:clay (list @t)))`. The `unit` will be `~` if the merge failed due to a conflict. This is used by Clay in some cases when `desk`s are merged. If diff merges are not possible for your use case, you could just have it always return `~`.
311+
312+### `+mash`
313+
314+```hoon
315+++ mash
316+ |= $: [ship desk (urge:clay (list @t))]
317+ [ship desk (urge:clay (list @t))]
318+ ==
319+ ^- (urge:clay (list @t))
320+ ~|(%csv-mash !!)
321+```
322+
323+This is like `+join` except it forces a diff merge even if there's a conflict. Rather than returning a `unit`, it just returns the diff - a `(urge:clay (list @t))` in our case. Also unlike `+join`, it takes the `ship` and `desk` each diff came from as well as the diff itself.
324+
325+The `+mash` arm is not used by Clay in its file revision operations, so it's safe to just make it a dummy arm that crashes as we've done here. If you were to use it, it would likely just be used manually in an agent, thread or generator.
326+
327+An example of its use would be the `%txt` `mark`, which includes a proper `+mash` function that produces a diff with any conflicts annotated, though how you have `+mash` handle conficts would depend on your use case. If there were no conflicts between the two diffs, it should produce the same diff as the `+join` arm.
328+
329+## Conclusion
330+
331+So there you have it, a fully functional `mark` for CSV files. A `mark` file can be as complex or as simple as you'd like, they're very flexible depending on your use case. Additional conversion methods can always be added as they're needed. For example, with just a few lines of code we could add arms for converting CSV files to `%json` or `%txt` and vice versa.
332+
333+In the next document, we'll look at building and using `mark` cores and `mark` conversion gates in our own code.
content/docs/arvo/clay/scry.md+6−6
@@ -8,7 +8,7 @@ The various Clay scries are specified by a `care`, which is a single character c
88
99```
1010> /===
11−[~.~zod ~.home ~.~2021.4.26..02.29.03..d31b ~]
11+[~.~zod ~.base ~.~2021.4.26..02.29.03..d31b ~]
1212```
1313
1414## %a - Build hoon.
@@ -51,7 +51,7 @@ Example:
5151
5252```
5353> .^((set desk) %cd /===)
54−{%home %kids}
54+{%bitcoin %base %landscape %webterm %garden}
5555```
5656
5757## %e - Static mark core.
@@ -213,12 +213,12 @@ This will return the most recent revision number of a `desk` that has been fully
213213Example:
214214
215215```
216−> .^(=cass:clay %cs /(scot %p (sein:title our now our))/kids/1/late)
216+> .^(=cass:clay %cs /(scot %p (sein:title our now our))/base/1/late)
217217cass=[ud=50 da=~2021.4.22..10.38.50..57a8]
218218```
219219
220220```
221−> .^(=cass:clay %cs /~sampel/kids/1/late)
221+> .^(=cass:clay %cs /~sampel/base/1/late)
222222cass=[ud=0 da=~2000.1.1]
223223```
224224
@@ -229,12 +229,12 @@ This will return the mergebase (i.e. most recent common ancestor) between two `d
229229Examples:
230230
231231```
232−> .^((list tako:clay) %cs /===/base/(scot %p (sein:title our now our))/kids)
232+> .^((list tako:clay) %cs /===/base/(scot %p (sein:title our now our))/base)
233233~[102.787.244.596.033.419.950.995.540.301.493.841.569.518.772.322.508.085.465.561.801.703.148.627.263.473]
234234```
235235
236236```
237−> .^((list tako:clay) %cs /===/base/~sampel/kids)
237+> .^((list tako:clay) %cs /===/base/~sampel/base)
238238~
239239```
240240
content/docs/arvo/clay/tasks.md+2−2
@@ -108,7 +108,7 @@ This subscribes to all changes to a `desk` for the specified range of `case`s. N
108108If the `track` is `%.y` it will just return a `%writ` like:
109109
110110```hoon
111−[%writ p=[~ [p=[p=%w q=[%ud p=256] r=%home] q=/ r=[p=%null q=[#t/@n q=0]]]]]
111+[%writ p=[~ [p=[p=%w q=[%ud p=256] r=%base] q=/ r=[p=%null q=[#t/@n q=0]]]]]
112112```
113113
114114...that merely informs you of a change. If you want the actual data you'll have to request it separately.
@@ -494,7 +494,7 @@ Note that if you're reading a whole `desk` or directory, all subfolders and file
494494
495495To merge a foreign `desk` into a local one, you just send Clay a `%merg` `task` (as you would for a local merge) and specify the foreign ship in the `her` field. For details on making such requests, see the [Merge Desks](#merge-desks) section.
496496
497−The foreign ship will respond only if correct permissions have been set. See the [Permissions](#permissions) section for details. By default, a ship's `%kids` desk is set to be publicly readable, so unless permissions have been manually modified, you should be able to merge from any `%kids` `desk`.
497+The foreign ship will respond only if correct permissions have been set. See the [Permissions](#permissions) section for details.
498498
499499Note that all subfolders and individual files within the `desk` must permit your reading in order for the merge to succeed. If even one file does not permit you reading it, the remote ship will not respond to the request at all.
500500
content/docs/arvo/clay/using.md+67−61
@@ -6,50 +6,51 @@ template = "doc.html"
66
77### Reading and Subscribing
88
9−When reading from Clay, there are three types of requests. A
10−`%sing` request asks for data at single revsion. A `%next`
9+When reading from Clay, there are three types of requests. A
10+`%sing` request asks for data at single revsion. A `%next`
1111request asks to be notified the next time there's a change to
12−given file. A `%many` request asks to be notified on every
12+given file. A `%many` request asks to be notified on every
1313change in a `desk` for a range of changes.
1414
1515For `%sing` and `%next`, there are generally three things to be
16−queried. A `%u` request simply checks for the existence of a
17−file at a path. A `%x` request gets the data in the file at a
18−path. A `%y` request gets a hash of the data in the file at the
19−path combined with all its children and their data. Thus, `%y`
16+queried. A `%u` request simply checks for the existence of a
17+file at a path. A `%x` request gets the data in the file at a
18+path. A `%y` request gets a hash of the data in the file at the
19+path combined with all its children and their data. Thus, `%y`
2020of a node changes if it or any of its children change.
2121
22−A `%sing` request is fulfilled immediately if possible. If the
22+A `%sing` request is fulfilled immediately if possible. If the
2323requested revision is in the future, or is on another ship for
2424which we don't have the result cached, we don't respond
25−immediately. If the requested revision is in the future, we wait
26−until the revision happens before we respond to the request. If
25+immediately. If the requested revision is in the future, we wait
26+until the revision happens before we respond to the request. If
2727the request is for data on another ship, we pass on the request
28−to the other ship. In general, Clay subscriptions, like most
28+to the other ship. In general, Clay subscriptions, like most
2929things in Urbit, aren't guaranteed to return immediately.
3030They'll return when they can, and they'll do so in a
3131referentially transparent manner.
3232
3333A `%next` request checks the query at the given revision, and it
3434produces the result of the query the next time it changes, along
35−with the revision number when it changes. Thus, a `%next` of a
35+with the revision number when it changes. Thus, a `%next` of a
3636`%u` is triggered when a file is added or deleted, a `%next` of a
3737`%x` is triggered when a file is added, deleted, or changed, and
3838a `%next` of a `%y` is triggered when a file or any of its
3939children is added, deleted, or changed.
4040
4141A `%many` request is triggered every time the given `desk` has a
42−new revision. Unlike a `%next`, a `%many` has both a start and
43−an end revision, after which it stops returning. For `%next`, a
42+new revision. Unlike a `%next`, a `%many` has both a start and
43+an end revision, after which it stops returning. For `%next`, a
4444single change is reported, and if the caller wishes to hear of
45−the next change, it must resubscribe. For `%many`, every revision
46−from the start to the end triggers a response. Since a `%many`
45+the next change, it must resubscribe. For `%many`, every revision
46+from the start to the end triggers a response. Since a `%many`
4747request doesn't ask for any particular data, there aren't `%u`,
4848`%x`, and `%y` versions for it.
4949
5050### Unix sync
5151
5252Usage:
53+
5354```
5455|mount %/path/to/directory %mount-point
5556|commit %mount-point
@@ -76,123 +77,128 @@ be automatically committed with `|autocommit %mount-point`.
7677### Merging
7778
7879Usage:
80+
7981```
8082|merge %target-desk ~source-ship %source-desk
8183|merge %target-desk ~source-ship %source-desk, =gem %strategy
8284|merge %target-desk ~source-ship %source-desk, =cas ud+5
8385```
8486
85−Clay supports various merge strategies. A "commit" is a snapshot of
86−the files with a list of parents plus a date. Most commits have
87−one parent; a "merge" commit is a commit with two parents. The
88−%home `desk` starts with an initial commit with no parents; commits
87+Clay supports various merge strategies. A "commit" is a snapshot of
88+the files with a list of parents plus a date. Most commits have
89+one parent; a "merge" commit is a commit with two parents. The
90+`%base` `desk` starts with an initial commit with no parents; commits
8991with several parents ("octopus merges") are possible but we don't
9092generate them right now.
91−
93+
9294Unless otherwise specified, all of the following create a new commit
9395with the source and destination commits as parents.
94−
95−Several strategies need a "merge-base". They find it by identifying
96−the most recent common ancestor of the two `desk`s. If none, fail
96+
97+Several strategies need a "merge-base". They find it by identifying
98+the most recent common ancestor of the two `desk`s. If none, fail
9799with `%merge-no-merge-base`; if there are two or more, pick one.
98100
99101#### Strategies
100−
101−**`%init`**: the only way to create a `desk`. Not a true merge, since it
102+
103+**`%init`**: the only way to create a `desk`. Not a true merge, since it
102104simply assigns the source commit to the destination.
103−
105+
104106**`%fine`**: if source or destination are in the ancestry of each other,
105−use the newer one; else abort. If the destination is ahead of the
106−source, succeed but do nothing. If the source is ahead of the
107+use the newer one; else abort. If the destination is ahead of the
108+source, succeed but do nothing. If the source is ahead of the
107109destination, assign the next revision number to the source commit.
108110Some call this "fast-forward".
109−
111+
110112**`%meet`**: combine changes, failing if both sides changed the same file.
111113Specifically, take diff(merge-base,source) and
112114diff(merge-base,destination) and combine them as long as those diffs
113115touch different files.
114−
116+
115117**`%mate`**: combine changes, failing if both sides changed the same part
116−of a file. Identical to `%meet`, except that some marks, like `%hoon`,
118+of a file. Identical to `%meet`, except that some marks, like `%hoon`,
117119allow intelligent merge of changes to different parts of a file.
118−
120+
119121**`%meld`**: combine changes; if both sides changed the same part of a
120122file, use the version of the file in the merge-base.
121−
123+
122124**`%only-this`**: create a merge commit with exactly the contents of the
123125destination `desk`.
124−
126+
125127**`%only-that`**: create a merge commit with exactly the contents of the
126128source commit.
127−
129+
128130**`%take-this`**: create a merge commit with exactly the contents of the
129131destination `desk` except take any files from the source commit which
130132are not in the destination `desk`.
131−
133+
132134**`%take-that`**: create a merge commit with exactly the contents of the
133135source commit except preserve any files from the destination `desk`
134136which are not in the source commit.
135−
137+
136138**`%meet-this`**: merge as in `%meet`, except if both sides changed the same
137139file, use the version in the destination `desk`.
138−
140+
139141**`%meet-that`**: merge as in `%meet`, except if both sides changed the same
140142file, use the version in the source commit.
141−
143+
142144#### Examples and notes:
143−
145+
144146The most common merge strategy is `%mate`, which is a normal 3-way
145147merge which aborts on conflict.
146−
147−`%take-that` is useful to "force" an OTA. After running `%take-that`,
148+
149+`%take-that` is useful to "force" an OTA. After running `%take-that`,
148150you're guaranteed to have exactly the files in the source commit plus
149151any files you separately added.
150−
151−We speak of merging into a destination *`desk`* from a source *commit*
152+
153+We speak of merging into a destination _`desk`_ from a source _commit_
152154because while you can only merge on top of a `desk`, you can merge from
153−historical commits. For example,
154−```
155−|merge %old our %home, =cas ud+5, =gem %init
155+historical commits. For example,
156+
157+```
158+|merge %old our %base, =cas ud+5, =gem %init
156159```
157−will create a new `desk` called `%old` with the 5th commit in `%home`.
160+
161+will create a new `desk` called `%old` with the 5th commit in `%base`.
158162You can revert the contents of a `desk` to what they were yesterday
159163with
164+
160165```
161−|merge %home our %home, =cas da+(sub now ~d1), =gem %only-that
166+|merge %base our %base, =cas da+(sub now ~d1), =gem %only-that
162167```
163−
168+
164169Note this is a normal `%only-that merge`, which means you're creating a
165−*new* commit with the old *contents*.
166−
170+_new_ commit with the old _contents_.
171+
167172`%meld` is rarely used on its own, however if you specify `%auto` or
168173omit the merge strategy, `%kiln` will run a `%meld` merge into a scratch
169174`desk` and then annotate the conflicts there.
170−
175+
171176If you resolve merge conflicts manually, for example by mounting the
172177`desk`s, copying the files in Unix and then running `|commit`, you
173−should usually run an `%only-this merge`. This will not change the
178+should usually run an `%only-this merge`. This will not change the
174179newly-fixed contents of your `desk`, but it will record that the merge
175180happened so that those conflicts don't reappear in later merges.
176−
181+
177182If you get a `%merge-no-merge-base` error, this means you're trying to
178−merge two `desk`s which have no common ancestors. You need to give
183+merge two `desk`s which have no common ancestors. You need to give
179184them a common ancestor by choosing a merge strategy which doesn't
180185need a merge-base, like `%only-this`, `%only-that`, `%take-this`, or
181186`%take-that`.
182−
187+
183188`%take-this` could be useful to install 3rd party software, but you
184189couldn't get subsequent updates this way, since the files would
185−already exist in the destination `desk`. Something like "take only
190+already exist in the destination `desk`. Something like "take only
186191the files which aren't in my OTA source or any other 3rd party app"
187−would be basically correct. This would require a parameter listing
192+would be basically correct. This would require a parameter listing
188193the `desk`s to not conflict with.
189−
194+
190195`%meet-this` and `%meet-that` imply the existence of `%mate-this` and
191196`%mate-that`, but those don't exist yet.
192197
193198### Autosync
194199
195200Usage:
201+
196202```
197203|sync %target-desk ~source-ship %source-desk
198204```
content/docs/arvo/concepts/_index.md+4
@@ -8,6 +8,10 @@ insert_anchor_links = "right"
88
99Other concepts related to the way Arvo works.
1010
11+## [Scries](/docs/arvo/concepts/scries)
12+
13+Details of performing scries.
14+
1115## [Subscriptions](/docs/arvo/concepts/subscriptions)
1216
1317Urbit relies heavily on subscriptions throughout the stack. We strongly prefer reactive data flow compared to querying or polling, which is why for example our equivalent to git natively supports subscriptions to its data.
content/docs/arvo/concepts/scry.mdnew file+77
@@ -0,0 +1,77 @@
1++++
2+title = "Scries"
3+weight = 40
4+template = "doc.html"
5++++
6+
7+### What is a scry?
8+
9+A scry is a read-only request to Arvo's global namespace.
10+
11+Vanes and agents define _scry endpoints_ which allow one to request data from their respective states. The endpoints can process the data in any way before returning it, but they cannot alter the actual state - scries can _only_ read, not modify.
12+
13+### Why scry?
14+
15+The subject available in something like a Gall agent or thread contains a great many functions and structures from the standard library as well as `zuse` and `lull`, but it does not include any of the actual data stored elsewhere in the ship. All it has is its own state, a `bowl` and any `card`s it has been passed. Ordinarily, in order to access such data, one would need to `%poke` or `%watch` other agents, or `%pass` `task`s to vanes, then wait for a response. Arvo's scry system is the one exception to this; it allows direct retrieval of data from other vanes or agents in situ, from any context, without any of the normal messaging rigmarole.
16+
17+### How do I scry?
18+
19+Scries are performed exclusively with the dotket rune: `.^`
20+
21+For details of its usage, see the [dotket](/docs/hoon/reference/rune/dot#-dotket) section of the Nock rune documentation. In addition to the dotket documentation, below is a colour-coded diagram breaking down the structure of a dotket scry expression with some additional notes.
22+
23+![Scry diagram](https://media.urbit.org/docs/arvo/scry-diagram-v2.svg)
24+
25+One further note on `care`s (which can sometimes be confusing): While `care`s are part of the global namespace, they're most extensively used by Clay in particular. In Clay, `care`s specify Clay submodules with specific behaviour, and are used both in scries as well as `task`s and `gift`s. For example, a `%x` `care` reads the data of a file, a `%p` `care` reads file permissions, and so forth. To see all of Clay's `care`s and what they do, you can refer to Clay's [Scry Reference](/docs/arvo/clay/scry).
26+
27+Most other vanes also make use of `care`s in their scry endpoints. While such vanes don't have corresponding submodules with strictly defined behaviour like Clay, the `care`s still confer the general nature of the endpoint. The most widely used `care` is `%x`, which implies reading data in a general sense. Gall has special handling of `%x` scries as described in the [Gall agents](#gall-agents) section below, but otherwise `care`s have no special behaviour for non-Clay vanes (though they must still be included if the endpoint specifies it).
28+
29+### What can I scry?
30+
31+There are two places where scry endpoints are defined:
32+
33+#### Vanes
34+
35+Each of Arvo's eight vanes (kernel modules) include a `+scry` arm which defines that vane's scry endpoints. The number of endpoints and extent of data available varies between vanes. For example, Clay has a very extensive set of scry endpoints which provide read access to all files in all desks across all revisions, as well as the ability to build files, perform `mark` conversions, and various other functions. Jael provides access to a great deal of PKI data. On the other hand, Dill has only a couple of endpoints which are mostly useful for debugging, and Iris has none at all (apart from standard memory reporting endpoints you'd not typically use in your applications).
36+
37+To explore what scry endpoints are available for vanes, you can refer to the Scry Reference section of each vane in the [Arvo](/docs/arvo/overview) section of the documents.
38+
39+#### Gall agents
40+
41+Gall has a single scry endpoint of its own to check for the existence of an agent, but otherwise all Gall scries are passed through to one of the agents it manages. The target agent to scry is specified in place of the `desk` as described in the diagram above. Each Gall agent includes a `+on-peek` arm that defines its own scry endpoints. For example, `%graph-store` has a number of scry endpoints to access the data it stores, such as chat messages and the like.
42+
43+Gall agents can expose scry endpoints with any `care`, but most commonly they'll take a `%x` `care`. Gall handles `%x` scries specially - it expects an extra field at the end of the `path` that specifies a `mark`. Gall will attempt to perform a `mark` conversion from the `mark` returned by the scry endpoint to the `mark` specified. Note the trailing `mark` in the `path` will not be passed through to the agent itself.
44+
45+### What is an endpoint?
46+
47+"Endpoint" refers to a specific scry path in a vane or agent. They will sometimes informally be noted in documentation or source comments like `/x/foo/bar/baz` or maybe just `/foo/bar/baz`. The first part of the former example is the `care`, then the rest is the `path` portion as noted in the diagram earlier.
48+
49+If an agent's scry endpoints don't have formal documentation, you may need to refer to the `+on-peek` arm in its source code to determine its endpoints. While there's no exact pattern that's consistent across different agents, the general pattern will be some initial tests and conversions followed by a `?+` rune, whose cases will typically correspond to the endpoints. The `+on-peek` arm always return a `(unit (unit cage))` (a `cage` is a cell of `[mark vase]`), so each endpoint will typically finish by composing such a structure.
50+
51+Here's an example from the `+on-peek` arm of `%graph-store`:
52+
53+```hoon
54+ [%x %keys ~]
55+:- ~ :- ~ :- %graph-update-2
56+!>(`update:store`[now.bowl [%keys ~(key by graphs)]])
57+```
58+
59+The case in the beginning says it takes a `%x` `care` and has a `path` of `/keys`. Additionally, it returns data with a `mark` of `%graph-update-2`. Assuming we wanted the `%graph-update-2` `mark` converted to a `%json` `mark`, our scry would be composed along the lines of:
60+
61+```hoon
62+.^(json %gx /(scot %p our)/graph-store/(scot %da now)/keys/json)
63+```
64+
65+### Web scries
66+
67+The webserver vane Eyre has a system which allows clients like web browsers to perform scries over HTTP. For details, refer to the [Scry section of Eyre's External API Reference](/docs/arvo/eyre/external-api-ref#scry).
68+
69+### Further reading
70+
71+[dotket](/docs/hoon/reference/rune/dot#-dotket) - Documentation of the `.^` rune which performs scries.
72+
73+[Arvo](/docs/arvo/overview) - Each vane has a Scry Reference section with details of their endpoints as well as examples.
74+
75+[Eyre's External API Reference](/docs/arvo/eyre/external-api-ref#scry) - Documentation of Eyre's scry system which allows web clients to perform scries over HTTP.
76+
77+[The Gall Guide](/docs/userspace/gall-guide) - The Gall tutorial includes a section about `+on-peek` and writing scry endpoints.
content/docs/arvo/concepts/subscriptions.md+43−43
@@ -4,7 +4,7 @@ weight = 50
44template = "doc.html"
55+++
66
7−Urbit relies heavily on subscriptions throughout the stack. We strongly
7+Urbit relies heavily on subscriptions throughout the stack. We strongly
88prefer reactive data flow compared to querying or polling, which is why
99for example our equivalent to git natively supports subscriptions to its
1010data.
@@ -12,7 +12,7 @@ data.
1212We have many application-level styles of subscription, but we only have
1313three true subscription types in Arvo, named for the vane they're
1414implemented in: Clay subscriptions (filesystem), Gall subscriptions
15−(applications), and Jael subscriptions (Urbit ID info). They're at
15+(applications), and Jael subscriptions (Urbit ID info). They're at
1616three different points in the idea maze of subscriptions, and we'll
1717encounter each of them here.
1818
@@ -28,9 +28,9 @@ later request.
2828### Exactly-once updates
2929
3030Some subscriptions need the subscriber to receive each update separately
31−instead of collapsing them into a single diff. Sometimes a subscription
31+instead of collapsing them into a single diff. Sometimes a subscription
3232is really a sequence of commands, in which case there's no meaningful
33−way to collapse them. Similarly, software updates may be expected to be
33+way to collapse them. Similarly, software updates may be expected to be
3434applied in order.
3535
3636### Syncing data
@@ -38,79 +38,79 @@ applied in order.
3838Other times, it's more natural to think of a subscription as
3939communicating a data structure, where the only goal is to keep the data
4040structure on the subscriber's side up-to-date with what's on the
41−publisher's side. In this case, it's perfectly fine to collapse several
41+publisher's side. In this case, it's perfectly fine to collapse several
4242updates into one large update, or even to resend the entire data
43−structure. Partial updates exist only as an optimization.
43+structure. Partial updates exist only as an optimization.
4444
4545For this sort of subscription, we commonly use terms like "diff" instead
4646of "message" or "update", and we say that we "apply a diff" instead of
47−"process an update". We also often identify the subscription with the
47+"process an update". We also often identify the subscription with the
4848data structure itself.
4949
5050## Memory pressure
5151
5252Naively implemented, subscriptions pose a memory leak risk if the
5353subscriber can't receive updates as fast as the publisher wants to send
54−them. This commonly happens when the subscriber goes offline for an
55−extended period of time (possibly forever; especially for comets). It's
54+them. This commonly happens when the subscriber goes offline for an
55+extended period of time (possibly forever; especially for comets). It's
5656sufficient to bound the amount of memory dedicated to any particular
5757subscriber.
5858
5959In a synchronous system, you don't have to worry about what happens if
60−one side or the other ceases to be available. All of our subscriptions,
60+one side or the other ceases to be available. All of our subscriptions,
6161though, can happen between ships.
6262
6363### Small data
6464
6565For particularly low-volume subscriptions, it may be acceptable to
66−ignore the problem. Jael uses this approach, since the only time it's
66+ignore the problem. Jael uses this approach, since the only time it's
6767used across ships is to update moon keys, which is very low-volume and
68−less than 1KB per update. If these subscriptions are used for more,
68+less than 1KB per update. If these subscriptions are used for more,
6969this strategy will have to be revisited.
7070
7171### Buffers
7272
73−A common solution to this problem is the venerable buffer. If more than
74−N updates need to be sent, start dropping updates. There are several
73+A common solution to this problem is the venerable buffer. If more than
74+N updates need to be sent, start dropping updates. There are several
7575options for what to do when the buffer is full and the publisher wishes
7676to send another message:
7777
78−- Drop the oldest message. Particularly suitable for systems where new
79−messages obsolete old ones. For example, if you just need the latest
80−ticker price for an asset, you could use a buffer size of one and
81−replaced it any time you have a new price.
78+- Drop the oldest message. Particularly suitable for systems where new
79+ messages obsolete old ones. For example, if you just need the latest
80+ ticker price for an asset, you could use a buffer size of one and
81+ replaced it any time you have a new price.
8282
83−- Don't add the new message to the buffer. Semantically this is usually
84−less helpful, but mechanically it can be simpler and reduce memory
85−churn, since the buffer stops changing and new messages are simply
86−ignored.
83+- Don't add the new message to the buffer. Semantically this is usually
84+ less helpful, but mechanically it can be simpler and reduce memory
85+ churn, since the buffer stops changing and new messages are simply
86+ ignored.
8787
88−- Drop the newest message and close the subscription. Unlike the
89−previous two, this is compatible with the principle of exactly-once
90−messaging. Specifically, it preserves the guarantee that you won't
91−receive two non-consecutive subscription updates, at the cost of making
92−you resubscribe if you fall behind.
88+- Drop the newest message and close the subscription. Unlike the
89+ previous two, this is compatible with the principle of exactly-once
90+ messaging. Specifically, it preserves the guarantee that you won't
91+ receive two non-consecutive subscription updates, at the cost of making
92+ you resubscribe if you fall behind.
9393
94−Gall subscriptions use the last of these. The buffer is bounded by a
94+Gall subscriptions use the last of these. The buffer is bounded by a
9595simple heuristic, and when a subscription exceeds that buffer, it is
9696closed and the app is expected to resubscribe when they come back
97−online. Note that even though the subscription is closed, messages in
97+online. Note that even though the subscription is closed, messages in
9898flight cannot be removed until they've been acknowledged since Ames
9999guarantees exactly-once messaging, so those last few messages will be
100100stuck in memory until the subscriber comes back online.
101101
102102Buffers are commonly bounded by size, but this puts constraints on the
103−types of messages may be sent. They may also be bounded in time: if the
103+types of messages may be sent. They may also be bounded in time: if the
104104subscriber stops taking messages for at least X time, the buffer is
105−full. Gall taks a hybrid approach; currently the heuristic is that the
105+full. Gall taks a hybrid approach; currently the heuristic is that the
106106buffer counts as full if it has at least five messages and it has been
10710730 seconds since a message was acknowledged.
108108
109109### One at a time
110110
111−Another scheme is to avoid multi-message subscriptions. Instead of
111+Another scheme is to avoid multi-message subscriptions. Instead of
112112allowing the subscriber to subscribe to all future updates on a path,
113−allow them to "subscribe" to the *next* update only. When they get that
113+allow them to "subscribe" to the _next_ update only. When they get that
114114update, they subscribe to the new next update, so that they ultimately
115115get every message.
116116
@@ -122,41 +122,41 @@ This is near the theoretical ideal for memory usage, since you'll never
122122queue up several messages to send to the subscriber.
123123
124124It also encourages processing each update in order rather than zooming
125−forward from time to time. It's possible (if a little awkward) to
125+forward from time to time. It's possible (if a little awkward) to
126126simulate this with buffers though, and it's possible to allow zooming
127127forward in the one-at-a-time scheme by having the requests be "most
128128recent after update N" instead of "next after update N".
129129
130130This scheme is at its strongest, then, when you're already storing
131131intermediate states or updates, or when you don't care about
132−intermediate states and always send the most recent one. Otherwise,
132+intermediate states and always send the most recent one. Otherwise,
133133buffers are a convenient place to temporarily store updates that you
134−don't want to store internally. Of course, if it's semantically
134+don't want to store internally. Of course, if it's semantically
135135important that you give each update separately, buffers won't save you
136136from having to store the intermediate updates, since they may fill up.
137137
138138Another conceptual advantage is that it has no notion of "connectivity".
139−It operates forever in a single mode. By contrast, buffer-based
139+It operates forever in a single mode. By contrast, buffer-based
140140solutions must keep track of whether the buffer is full and react to
141−that. This increases complexity in the system, and complexity is the
141+that. This increases complexity in the system, and complexity is the
142142great evil.
143143
144144The biggest disadvantage of this system is that it takes much longer to
145−process many small updates. With buffers, the publisher could have a
145+process many small updates. With buffers, the publisher could have a
146146dozen small updates in flight at the same time, while in this scheme
147147they would only send one at a time, waiting for a response between each
148−one. Losing this pipelining can be quite significant for some
148+one. Losing this pipelining can be quite significant for some
149149applications, but for low-volume subscriptions (certainly anything that
150150updates less than once per minute) this will have no noticeable effect.
151151
152−Clay uses this scheme. It's low-volume, it stores all previous states
152+Clay uses this scheme. It's low-volume, it stores all previous states
153153anyway (since it's a revision-control system), and it's sometimes
154154important to get updates one at a time (for example when downloading OTA
155−software updates). Ships that send OTA updates often have many ships
155+software updates). Ships that send OTA updates often have many ships
156156subscribed to them, and the updates themselves may be large, so it's
157157important they don't queue up when ships inevitably disappear.
158158
159159I tend to think most Gall subscriptions should follow this pattern as
160−well. Our most latency-sensitive subscriptions are chat messages, and
160+well. Our most latency-sensitive subscriptions are chat messages, and
161161while I haven't tested it, I would guess that even those wouldn't be
162162affected by this scheme.
content/docs/arvo/dill/_index.md+16
@@ -5,3 +5,19 @@ sort_by = "weight"
55template = "sections/docs/chapters.html"
66insert_anchor_links = "right"
77+++
8+
9+[Overview](/docs/avro/dill/dill)
10+
11+A brief overview of the Dill vane.
12+
13+[API Reference](/docs/arvo/dill/tasks)
14+
15+The `task`s Dill takes and the `gift`s it returns.
16+
17+[Scry Reference](/docs/arvo/dill/scry)
18+
19+The scry endpoints of Dill.
20+
21+[Data Types](/docs/arvo/dill/data-types)
22+
23+Reference documentation of the data types used by Dill.
content/docs/arvo/dill/data-types.mdnew file+187
@@ -0,0 +1,187 @@
1++++
2+title = "Data Types"
3+weight = 4
4+template = "doc.html"
5++++
6+
7+Here are the data types used by Dill, as defined in `/sys/lull.hoon`.
8+
9+## `$blew`
10+
11+```hoon
12+ +$ blew [p=@ud q=@ud]
13+```
14+
15+Terminal dimension; `p` is columns, `q` is rows. This structure is passed to Dill by the runtime in a [%blew](/docs/arvo/dill/tasks#blew) `task` whenever the dimensions of the terminal changes.
16+
17+## `$belt`
18+
19+```hoon
20++$ belt
21+ $? bolt
22+ $% [%mod mod=?(%ctl %met %hyp) key=bolt]
23+ [%txt p=(list @c)]
24+ [%ctl p=@c]
25+ [%met p=@c]
26+ == ==
27+```
28+
29+Terminal client input.
30+
31+A `$belt` is passed to Dill in a [%belt](/docs/arvo/dill/tasks#belt) `task` by the runtime whenever there is input, such as a user typing in the console. This is only used between the terminal client and Dill, a [$dill-belt](#dill-belt) is used between Dill and Arvo.
32+
33+May either be a [$bolt](#bolt) or one of:
34+
35+- `%mod` - Modifier (Ctrl, Meta or Hyper) plus [key].
36+- `%txt` - A series of characters
37+- `%ctl` - Ctrl+[key], deprecated in favour of `%mod`.
38+- `%met` - Meta+[key], deprecated in favour of `%mod`.
39+
40+## `$bolt`
41+
42+```hoon
43++$ bolt
44+ $@ @c
45+ $% [%aro p=?(%d %l %r %u)]
46+ [%bac ~]
47+ [%del ~]
48+ [%hit r=@ud c=@ud]
49+ [%ret ~]
50+ ==
51+```
52+
53+Simple input.
54+
55+Either a single simple character or one of:
56+
57+- `%aro` - Arrow keys.
58+- `%bac` - Backspace key.
59+- `%del` - Delete key.
60+- `%hit` - Mouse click - `r` is row and `c` is column. Note these are zero-indexed, with `[0 0]` being the _bottom left_ corner.
61+- `%ret` - Return (Enter) key.
62+
63+## `$blit`
64+
65+```hoon
66++$ blit
67+ $% [%bel ~]
68+ [%clr ~]
69+ [%hop p=@ud]
70+ [%klr p=stub]
71+ [%lin p=(list @c)]
72+ [%mor ~]
73+ [%sag p=path q=*]
74+ [%sav p=path q=@]
75+ [%url p=@t]
76+ ==
77+```
78+
79+Terminal client output.
80+
81+A `$blit` is given to the terminal client by Dill in a `%blit` `gift` when it wants to print some text, clear the screen, go _ding_ or what have you.
82+
83+This is only used between Dill and the terminal client, a [$dill-blit](#dill-blit) is used instead between Arvo and Dill.
84+
85+A `$blit` is one of:
86+
87+- `%bel` - Ring the terminal bell.
88+- `%clr` - Clear the screen.
89+- `%hop` - Set cursor position, `p` specifies its position on the prompt line.
90+- `%klr` - Set styled line, the `$stub` specifies the text and style.
91+- `%lin` - Set current line, `p` contains the text.
92+- `%mor` - Newline.
93+- `%sag` - Save to jamfile, typically in `/[pier]/.urb/put/`. `p` is `/[path]/[filename]/[extension]`. For example, `/foo/bar` will save it in `/[pier]/.urb/put/foo.bar`, `/a/b/c/foo/bar` will save it in `/[pier]/.urb/put/a/b/c/foo.bar`, and `/foo` will save it in `/[pier]/.urb/put.foo`. `q` is the `noun` to `jam` and save in the file.
94+- `%sav` - Save to file. Same behaviour as `%sag` except `q` is an `atom` rather than a `noun` and therefore doesn't need to be `jam`med. The `atom` is written to disk as if it were the bytestring in the tail of an `$octs`. That is, `%sav`ing the `cord` `'abcdef'`, whose `@ux` value is `0x6665.6463.6261`, results in a unix file whose hex dump renders as `61 62 63 64 65 66`.
95+- `%url` - Activate URL, `p` is the URL.
96+
97+## `$dill-belt`
98+
99+```hoon
100++$ dill-belt
101+ $% [%aro p=?(%d %l %r %u)]
102+ [%bac ~]
103+ [%cru p=@tas q=(list tank)]
104+ [%ctl p=@]
105+ [%del ~]
106+ [%hey ~]
107+ [%met p=@]
108+ [%ret ~]
109+ [%rez p=@ud q=@ud]
110+ [%txt p=(list @c)]
111+ [%yow p=gill:gall]
112+ ==
113+```
114+
115+Terminal input for Arvo.
116+
117+While [$belt](#belt) is used between the terminal client and Dill, `$dill-belt` is used between Dill and Arvo.
118+
119+a `$dill-belt` is one of:
120+
121+- `%aro` - Arrow keys.
122+- `%bac` - Backspace key.
123+- `%cru` - Echo error, `p` is an error `@tas` and `q` is a traceback.
124+- `%ctl` - Ctrl+[key].
125+- `%del` - Delete key.
126+- `%hey` - Refresh.
127+- `%met` - Meta+[key].
128+- `%ret` - Return key (Enter).
129+- `%rez` - Terminal resized, `p` is columns and `q` is rows.
130+- `%txt` - Text input.
131+- `%yow` - Connect to app.
132+
133+## `$dill-blit`
134+
135+```hoon
136++$ dill-blit
137+ $% [%bel ~]
138+ [%clr ~]
139+ [%hop p=@ud]
140+ [%klr p=stub]
141+ [%mor p=(list dill-blit)]
142+ [%pom p=stub]
143+ [%pro p=(list @c)]
144+ [%qit ~]
145+ [%out p=(list @c)]
146+ [%sag p=path q=*]
147+ [%sav p=path q=@]
148+ [%url p=@t]
149+ ==
150+```
151+
152+Terminal output from Arvo.
153+
154+While [$blit](#blit) is used between Dill and the terminal client, `$dill-blit` is used between Arvo and Dill.
155+
156+A `$dill-blit` is one of:
157+
158+- `%bel` - Terminal bell.
159+- `%clr` - Clear screen.
160+- `%hop` - Set cursor position, `p` is its horizontal position on the prompt line.
161+- `%klr` - Styled text, the `$stub` specifies both the text and style.
162+- `%mor` - Multiple `$dill-blit`.
163+- `%pom` - Styled prompt, the `$stub` specifies both the text and style.
164+- `%pro` - Set prompt, `p` is the text for the prompt.
165+- `%qit` - Close console.
166+- `%out` - Print text.
167+- `%sag` - Save `noun` to jamfile. See [$blit](#blit) section for further details.
168+- `%sav` - Save `atom` to file. See [$blit](#blit) section for further details.
169+- `%url` - Activate URL.
170+
171+## `$flog`
172+
173+```hoon
174++$ flog
175+ $% [%crop p=@ud]
176+ [%crud p=@tas q=(list tank)]
177+ [%heft ~]
178+ [%meld ~]
179+ [%pack ~]
180+ [%text p=tape]
181+ [%verb ~]
182+ ==
183+```
184+
185+Wrapped Dill `task`s.
186+
187+These are a subset of Dill's `task`s which can be wrapped in a `%flog` `task`. See the [API Reference](/docs/arvo/dill/tasks) document for details of each of these `task`s.
content/docs/arvo/dill/dill-api.mddeleted−366
@@ -1,366 +0,0 @@
1−+++
2−title = "API Reference"
3−weight = 10
4−template = "doc.html"
5−+++
6−
7−In this document we describe the public interface for Dill. Namely, we describe
8−each `task` that Dill can be `pass`ed, and which `gift`(s) Dill can `give` in return.
9−
10−Dill is unique among vanes since it is technically the first vane to be booted (though we
11−regard Jael as the "true" first vane). As a result, there are four `task`s in
12−`task:able:dill` for which Dill acts only as a middleman that passes the `task`s
13−directly to the Arvo kernel. Thus we have split this document into a [Dill
14−tasks](#dill-tasks) section and an [Arvo tasks](#arvo-tasks) section.
15−
16−## Dill Tasks
17−
18−
19−### `%belt`
20−
21−Every keystroke entered into the console triggers a `%belt` `task` for Dill which contains information about the keystroke, such as which key was pressed
22−and from which terminal.
23−
24−#### Accepts
25−
26−`%belt` `task`s come in a number of different types, corresponding to different
27−keystrokes. You can find this list in `+dill-belt` in `zuse.hoon`.
28−
29−```hoon
30−++ dill-belt :: new belt
31− $% {$aro p/?($d $l $r $u)} :: arrow key
32− {$bac ~} :: true backspace
33− {$cru p/@tas q/(list tank)} :: echo error
34− {$ctl p/@} :: control-key
35− {$del ~} :: true delete
36− {$hey ~} :: refresh
37− {$met p/@} :: meta-key
38− {$ret ~} :: return
39− {$rez p/@ud q/@ud} :: resize, cols, rows
40− {$txt p/(list @c)} :: utf32 text
41− {$yow p/gill:gall} :: connect to app
42− == ::
43−```
44−
45−#### Returns
46−
47−Dill returns no `gift` in response to a `%belt` `task`.
48−
49−
50−### `%blew`
51−
52−This `task` is called whenever the terminal emulator is resized, so that Dill can adjust
53−the text output to fit the new window size.
54−
55−#### Accepts
56−
57−```hoon
58−[p=@ud q=@ud]
59−```
60−
61−`p` is the number of columns and `q` is the number of rows.
62−
63−#### Returns
64−
65−Dill returns no `gift` in response to a `%blew` `task`.
66−
67−
68−### `%boot`
69−
70−This `task` is used only once, when Arvo first enters the [adult
71−stage](/docs/arvo/overview#structural-interface-core). Dill is
72−technically the first vane to be activated, via the `%boot` `task`, which then
73−send Jael (considered the the "true" first vane) an `%init` `task`, which then goes on to
74−call `%init` `task`s for other vanes (including Dill).
75−
76−#### Accepts
77−
78−`%boot` takes an argument that is either `%dawn` or `%fake`. `%dawn` is the one
79−used in any typical scenario and activates the ordinary vane initialization
80−process outlined above, while `%fake` is a debugging tool.
81−
82−#### Returns
83−
84−`%boot` does not return a `gift`.
85−
86−
87−
88−### `%crud`
89−
90−This `task` is used by Dill to produce error reports. It prints the received
91−error message(s) (a `(list tank)`) to the terminal. The level of detail of the
92−error message is set by `$log-level`, which is either `%hush`, `%soft`, or `%loud`.
93−
94−#### Accepts
95−
96−```hoon
97−[err=@tas tac=(list tank)]
98−```
99−
100−`err` is the type of error and `tac` is the associated error message.
101−
102−#### Returns
103−
104−`%crud` does not return a `gift`.
105−
106−
107−### `%flog`
108−
109−A `%flog` `task` is a wrapper over a `task` sent by another vane. Dill removes the wrapper
110−and sends the bare `task` to itself over the default `duct`.
111−
112−#### Accepts
113−
114−`%flog` `task`s can take any valid Dill `task` as an argument.
115−
116−#### Returns
117−
118−`%flog` never returns a `gift` on its own, but the wrapped `task` might.
119−
120−#### Example
121−
122−`%crud` `task`s from other vanes are typically passed to Dill wrapped in a
123−`%flog` `task` to print errors to the terminal.
124−
125−
126−
127−### `%flow`
128−
129−This `task` is not used.
130−
131−
132−### `%hail`
133−
134−`%hail` refreshes the terminal by sending an empty message to the default duct
135−for Dill,
136−causing the terminal to redraw itself (?)
137−
138−#### Accepts
139−
140−```hoon
141−[ ~ ]
142−```
143−
144−#### Returns
145−
146−`%hail` returns no `gift`s.
147−
148−
149−### `%heft`
150−
151−`%heft` causes Dill to `pass` a `%wegh` `task` to all other vanes (but not to
152−itself), thus obtaining a complete digest of Arvo's memory usage.
153−
154−#### Accepts
155−
156−```hoon
157−[ ~ ]
158−```
159−
160−#### Returns
161−
162−`%heft` does not directly return any `gift`s, but each `%wegh` `task` sent will
163−return a `%mass` `gift`.
164−
165−
166−### `%hook`
167−
168−This task is not used.
169−
170−
171−### `%harm`
172−
173−This `task` is not used.
174−
175−
176−### `%init`
177−
178−This `task` is called only once, when Arvo first enters the [adult
179−stage](/docs/arvo/overview#structural-interface-core). It performs
180−initial setup for Dill, such as setting the width of the console.
181−
182−Note that this is not actually the first `task` passed to Dill - see [%boot](#%boot).
183−
184−#### Accepts
185−
186−`%init` takes no arguments.
187−
188−#### Returns
189−
190−`%init` returns no `gift`s.
191−
192−
193−### `%knob`
194−
195−`%knob` sets the verbosity level for each error tag.
196−
197−#### Accepts
198−
199−```hoon
200−[tag=@tas level=log-level]
201−```
202−
203−`tag` is the error tag. `level` is the verbosity, set to either `%hush`,
204−`%soft`, or `%loud`.
205−
206−#### Returns
207−
208−`%knob` does not return a gift.
209−
210−
211−
212−
213−### `%noop`
214−
215−`%noop` does nothing - it stands for "no operation".
216−
217−#### Accepts
218−
219−```hoon
220−[ ~ ]
221−```
222−
223−#### Returns
224−
225−This `task`, predictably, returns nothing.
226−
227−#### Example
228−
229−This can be useful if a shell command requires a Dill `task` but you don't want
230−Dill to do anything.
231−
232−
233−
234−### `%talk`
235−
236−This `task` is not used.
237−
238−### `%text`
239−
240−This `task` prints a `tape` to the dojo by first converting it from a UTF8
241−`tape` to a `list` of UTF32 codepoints (`@c`'s) and then recursively popping off a character from the
242−`tape` and sending it to to Unix to be printed into the terminal via a `%blit` event.
243−
244−#### Accepts
245−
246−```hoon
247−[p=tape]
248−```
249−
250−#### Returns
251−
252−This `task` returns zero or more `%blit` `gift`s, each containing a .
253−
254−
255−### `%trim`
256−
257−`%trim` is a common vane `task` used to reduce memory usage. However, it does
258−nothing for Dill.
259−
260−#### Accepts
261−
262−```hoon
263−[p=@ud]
264−```
265−
266−This is a common parameter for `%trim` `task`s across all vanes but does nothing
267−for Dill.
268−
269−#### Returns
270−
271−This `task` returns no `gift`s.
272−
273−
274−
275−### `%vega`
276−
277−This is a common vane `task` used to inform the vane that the kernel has been
278−upgraded. Dill does not do anything in response to this.
279−
280−#### Accepts
281−
282−```hoon
283−[ ~ ]
284−```
285−
286−#### Returns
287−
288−This `task` returns no `gift`s.
289−
290−
291−
292−## Arvo tasks
293−
294−These `task`s live in `task:able:dill` but are passed directly to the Arvo
295−kernel for processing.
296−
297−### `%lyra`
298−
299−This `task` updates the kernel.
300−
301−#### Accepts
302−
303−```hoon
304−[p=@t q=@t]
305−```
306−
307−`p` is the contents of the new `hoon.hoon` and `q` is the contents of the new `arvo.hoon`.
308−
309−#### Returns
310−
311−This `task` returns no `gift`s.
312−
313−
314−### `%pack`
315−
316−This `task` defragments and deduplicates Arvo's memory. This is ultimately
317−performed by the interpreter so you won't find the code in `arvo.hoon` but
318−rather under `c3__pack` in `urbit/worker/main.c`.
319−
320−#### Accepts
321−
322−```hoon
323−[ ~ ]
324−```
325−
326−#### Returns
327−
328−This `task` returns no `gift`s.
329−
330−
331−### `%veer`
332−
333−This `task` is used to install `zuse` and vanes. It is handled by `+veer` in
334−`arvo.hoon`.
335−
336−#### Accepts
337−
338−```hoon
339−[p=@ta q=path r=@t]
340−```
341−
342−`p` is the vane letter, `q` is the formal `path` to the
343−vane, and `r` is the source code for the vane. The vane letter is `%` followed
344−by the first letter of the vane in lowercase, such as `%d` for Dill. `p=%$` in
345−the case of `zuse`.
346−
347−#### Returns
348−
349−This `task` returns no `gift`s.
350−
351−
352−### `%verb`
353−
354−This `task` toggles verbose mode for all of Arvo, which is located here since
355−Dill is the vane that prints errors. To be precise, `%verb` toggles the laconic
356−bit `lac` in the [Arvo state](/docs/arvo/overview#the-state).
357−
358−#### Accepts
359−
360−```hoon
361−[ ~ ]
362−```
363−
364−#### Returns
365−
366−This `task` returns no `gift`s.
content/docs/arvo/dill/dill.md+35−18
@@ -4,21 +4,38 @@ weight = 1
44template = "doc.html"
55aliases = ["/docs/learn/arvo/dill/"]
66+++
7−Our terminal driver.
8−
9−Unix sends keyboard events to `%dill` from either the console or telnet,
10−and `%dill` produces terminal output. The only app that should directly
11−talk to `%dill` is the terminal app. Command-line apps are run by,
12−receive input from, and produce output to, the `%shell` app, which is
13−controlled by `%terminal`, which talks to `%dill`, which talks to unix.
14−Clay also uses `%dill` directly to print out the filesystem change
15−events, but this is questionable behavior.
16−
17−`%dill` has two main components. First, it controls the terminal on a
18−very basic, event-by-event level. This includes keeping track of things
19−like the dimensions of the terminal, the prompt type (plain text or
20−password), which duct to produce effects on, and so forth. Second, it
21−handles terminal events, keystroke by keystroke. Most characters are
22−simply pushed onto the buffer and blitted to the screen, but some
23−characters, including control-modified keys, arrow keys, etc. require
24−special handling. Most of the readline functionality is in `%dill`.
7+
8+The terminal driver vane.
9+
10+Keyboard events and the like from Unix are received by Dill as [%belt](/docs/arvo/dill/tasks#belt) `task`s, and Dill sends `%blit` `gift`s containing [$blit](/docs/arvo/dill/data-types#blit)s back to the runtime to be displayed in the Unix terminal. The manner of interacting with Dill differs depending on whether you're in userspace or kernelspace, as we'll explore below.
11+
12+## Kernelspace
13+
14+For technical reasons, Dill performs a handful of system tasks related to booting a ship and some memory operations. Aside from those, other Vanes mostly just pass Dill [tasks](/docs/arvo/dill/tasks) to print error messages and the like to the terminal.
15+
16+## Userspace
17+
18+Unlike in kernelspace, userspace applications are unlikely to `%pass` Dill `task`s directly. Instead, Dill looks at things in terms of sessions. A session is a pipeline between a client and a handler, where:
19+
20+- The client is an external input source and output sink; a terminal with with dimensions and so forth.
21+- The handler is an application in Urbit that interprets input, maybe does something with it, maybe produces output to be displayed in the client, etc.
22+
23+There are plans for Dill to support multiple independent sessions (i.e. independent terminal clients displaying and processing different information at the same time), but at this stage Dill only supports a single session. The client for this default session is just the Unix terminal via the Urbit runtime. The handler for the default session is the `%hood` app, whose `drum` module does the heavy lifting.
24+
25+`drum` is the CLI app manager. By default you'll have a couple of CLI applications running—`%dojo` and `%chat-cli`—which you can switch between with `ctrl+x`. You may also have additional CLI apps which you have attached with the `|link` command. It's `drum` that keeps track of which one is active, which one input should be routed to, which one should be displayed, what each prompt should look like, and so forth. Dill itself is oblivious to the distinction between these CLI apps. It only sees the default session with `drum`, so it just passes all input to `drum` and display whatever `drum` gives it.
26+
27+While `drum` talks with Dill in `$dill-belt`s and `$dill-blit`s, it talks to CLI apps with `$sole-action`s and `$sole-event`s, which are defined in the `sole` library. For more information on the `sole` library and the related `shoe` library, and for information on how to build CLI apps, you can refer to the [CLI app tutorial](/docs/hoon/guides/cli-tutorial).
28+
29+To give a basic idea of how keyboard events flow through these systems and produce terminal output, here's a diagram showing the messages in pseudo-Hoon:
30+
31+![Dill userspace diagram](https://media.urbit.org/docs/arvo/dill/dill-userspace.svg)
32+
33+You can use a [move trace](/docs/arvo/tutorials/move-trace) to get a hands-on feel for this data flow.
34+
35+## Sections
36+
37+[API Reference](/docs/arvo/dill/tasks) - The `task`s Dill takes and the `gift`s it returns.
38+
39+[Scry Reference](/docs/arvo/dill/scry) - The scry endpoints of Dill.
40+
41+[Data Types](/docs/arvo/dill/data-types) - Reference documentation of the data types used by Dill.
content/docs/arvo/dill/scry.mdnew file+45
@@ -0,0 +1,45 @@
1++++
2+title = "Scry Reference"
3+weight = 3
4+template = "doc.html"
5++++
6+
7+Here are the scry endpoints of Dill. They take a `%x` `care` and require the `desk` in the path prefix be empty, so the general format is `.^([type] %dx /=//=/[some-path])`.
8+
9+Dill only has a couple of scry endpoints, both of which begin with `/session//`. The empty `//` would be where the target session would be specified, but at this stage Dill can only return a result for the default session, so it's always empty.
10+
11+## /sessions//line
12+
13+A scry with a `care` of `%x` and a `path` of `/sessions//line` returns the current text of the prompt line of the default session. The type returned is a [$blit](/docs/arvo/dill/data-types#blit).
14+
15+#### Example
16+
17+```
18+> .^(blit:dill %dx /=//=/sessions//line)
19+[ %lin
20+ p
21+ ~[
22+ ~-~~
23+ ~-z
24+ ~-o
25+ ~-d
26+ ~-~3a.
27+ ~-d
28+ ~-o
29+ ~-j
30+ ~-o
31+ ...truncated for brevity...
32+ ]
33+]
34+```
35+
36+## /sessions//cursor
37+
38+A scry with a `care` of `%x` and a `path` of `/sessions//cursor` returns the current horizontal position of the cursor in the default session. The type returned is a `@ud`.
39+
40+#### Example
41+
42+```
43+> .^(@ud %dx /=//=/sessions//cursor)
44+44
45+```
content/docs/arvo/dill/tasks.mdnew file+342
@@ -0,0 +1,342 @@
1++++
2+title = "API Reference"
3+weight = 2
4+template = "doc.html"
5++++
6+
7+In this document we describe the public interface for Dill. Namely, we describe each `task` that Dill can be `pass`ed, and which `gift`(s) Dill can `give` in return.
8+
9+## `%belt`
10+
11+```hoon
12+[%belt p=belt]
13+```
14+
15+Terminal input.
16+
17+The runtime sends a `%belt` `task` to Dill whenever there is input in the terminal, such as a keystroke.
18+
19+The [$belt](/docs/arvo/dill/data-types#belt) in `p` contains the input such as which key was pressed.
20+
21+Dill will convert the `$belt` into a [$dill-belt](/docs/arvo/dill/data-types#dill-belt) and `%poke` the session handler (typically `drum`) with it.
22+
23+This `task` would not typically be used from userspace.
24+
25+#### Returns
26+
27+Dill returns no `gift` in response to a `%belt` `task`.
28+
29+## `%blew`
30+
31+```hoon
32+[%blew p=blew]
33+```
34+
35+Terminal resized.
36+
37+The runtime passes Dill a `%blew` `task` whenever the terminal is resized.
38+
39+The [$blew](/docs/arvo/dill/data-types#blew) specifies the new dimensions.
40+
41+Dill will convert the `$blew` into a `%rez` [$dill-belt](/docs/arvo/dill/data-types#dill-belt) and `%poke`s the session handler (typically `drum`) with it.
42+
43+This `task` would not typically be used from userspace.
44+
45+#### Returns
46+
47+Dill returns no `gift` in response to a `%blew` `task`.
48+
49+## `%boot`
50+
51+```hoon
52+[%boot lit=? p=*]
53+```
54+
55+This `task` is used only once, when Arvo first enters the [adult stage](/docs/arvo/overview#structural-interface-core). Dill is technically the first vane to be activated, via the `%boot` `task`, which then sends Jael (considered the "true" first vane) the `%dawn` or `%fake` `task` wrapped in the `%boot` `task`. Jael then goes on to call `%init` `task`s for other vanes (including Dill).
56+
57+`lit` specifies whether to boot in lite mode. `p` is either a [%dawn](/docs/arvo/jael/data-types#dawn) or [%fake](/docs/arvo/jael/tasks#fake) `task:jael`. `%dawn` is for an ordinary boot and `%fake` is for booting a fake ship.
58+
59+This `task` would not be used from userspace.
60+
61+#### Returns
62+
63+Dill returns no `gift` in response to a `%boot` `task`, but it will `%pass` the wrapped `%dawn` or `%fake` `task` to Jael.
64+
65+## `%crop`
66+
67+```hoon
68+[%crop p=@ud]
69+```
70+
71+Trim kernel state.
72+
73+This `task` is the same as the [%trim](#trim) `task`. Like `%trim`, Dill does nothing with it.
74+
75+#### Returns
76+
77+Dill returns no `gift` in response to a `%crop` `task`.
78+
79+## `%crud`
80+
81+```hoon
82+[%crud p=@tas q=(list tank)]
83+```
84+
85+Print error.
86+
87+Dill prints the given error to the terminal. The verbosity for the particular `@tas` error tag specified in `p` is determined by the `level` set by a [%knob](#knob) `task` - either `%hush`, `%soft` or `%loud`. The default is `%loud`, where it will print the full `(list tank)` specified in `q`. See [%knob](#knob) for details of verbosity levels.
88+
89+#### Returns
90+
91+Dill does not return a `gift` in response to a `%crud` `task`.
92+
93+## `%flee`
94+
95+```hoon
96+[%flee session=~]
97+```
98+
99+Unwatch a session to which you've previously subscribed with [%view](#view).
100+
101+The ability to specify a session is not yet implemented in Dill, so `session` is always `~`, the default session.
102+
103+#### Returns
104+
105+Dill does not return a `gift` in response to a `%flee` `task`.
106+
107+## `%flog`
108+
109+```hoon
110+[%flog p=flog]
111+```
112+
113+A `%flog` `task` is a wrapper over a `task` sent by another vane. Dill removes the wrapper and sends the bare `task` to itself over the default `duct`.
114+
115+A `%flog` `task` takes a [$flog](/docs/arvo/dill/data-types#flog) as its argument. A `$flog` is a subset of Dill's `task`s.
116+
117+#### Returns
118+
119+Dill does not return a `gift` in response to a `%flog` `task`.
120+
121+## `%flow`
122+
123+```hoon
124+[%flow p=@tas q=(list gill:gall)]
125+```
126+
127+Terminal config.
128+
129+This `task` is not used.
130+
131+## `%hail`
132+
133+```hoon
134+[%hail ~]
135+```
136+
137+Refresh.
138+
139+Dill converts a `%hail` `task` into a `%hey` [$dill-belt](/docs/arvo/dill/data-types#dill-belt) and `%poke`s the session handler (typically `drum`) with it to handle the refresh.
140+
141+This `task` would not be used from userspace.
142+
143+#### Returns
144+
145+Dill returns no `gift` in response to a `%hail` `task`.
146+
147+## `%heft`
148+
149+```hoon
150+[%heft ~]
151+```
152+
153+Produce memory report.
154+
155+When Dill receives a `%heft` `task` it passes Arvo a `%whey` `waif` to obtain a memory report and prints it to the terminal.
156+
157+#### Returns
158+
159+Dill does not return a `gift` in response to a `%heft` `task`.
160+
161+## `%hook`
162+
163+```hoon
164+[%hook ~]
165+```
166+
167+This terminal hung up.
168+
169+This task is not used.
170+
171+## `%harm`
172+
173+```hoon
174+[%harm ~]
175+```
176+
177+All terminals hung up.
178+
179+This `task` is not used.
180+
181+## `%init`
182+
183+```hoon
184+[%init ~]
185+```
186+
187+This `task` is called only once, when Arvo first enters the [adult stage](/docs/arvo/overview#structural-interface-core). It performs initial setup for Dill, such as setting the width of the console.
188+
189+Note that this is not actually the first `task` passed to Dill - see [%boot](#%boot).
190+
191+This `task` would not be used from userspace.
192+
193+#### Returns
194+
195+Dill does not return a `gift` in response to a `%init` `task`.
196+
197+## `%meld`
198+
199+```
200+[%meld ~]
201+```
202+
203+Deduplicate persistent state.
204+
205+Dill asks the runtime to perform the memory deduplication.
206+
207+#### Returns
208+
209+Dill does not return a `gift` in response to a `%meld` `task`.
210+
211+## `%noop`
212+
213+```hoon
214+[%noop ~]
215+```
216+
217+No operation.
218+
219+A `%noop` `task` does nothing, as the name implies.
220+
221+#### Returns
222+
223+Dill does not return a `gift` in response to a `%noop` `task`.
224+
225+## `%pack`
226+
227+```hoon
228+[%pack ~]
229+```
230+
231+Defragment persistent state.
232+
233+Dill asks the runtime to perform the defragmentation.
234+
235+#### Returns
236+
237+Dill does not return a `gift` in response to a `%meld` `task`.
238+
239+## `%talk`
240+
241+```hoon
242+[%talk p=tank]
243+```
244+
245+This `task` is not used.
246+
247+## `%text`
248+
249+```hoon
250+[%text p=tape]
251+```
252+
253+Print `tape` to terminal.
254+
255+Upon receiving a `%text` `task`, Dill will convert the `tape` given in `p` to a `(list @c)` and give it to the runtime in a `%blit` `gift` including a `%lin` [$blit](/docs/arvo/dill/data-types#blit).
256+
257+#### Returns
258+
259+Dill does not return a `gift` in response to a `%text` `task`, but it does give a `%blit` `gift` to the runtime which looks like:
260+
261+```hoon
262+[%blit p=(list blit)]
263+```
264+
265+## `%view`
266+
267+```hoon
268+[%view session=~]
269+```
270+
271+Watch session.
272+
273+A `%view` `task` subscribes for a copy of all `%blit` `gift`s which Dill `%give`s for the default session. This `task` is used by the `%herm` app so it can convert the `$blit`s to JSON and render them in the web terminal.
274+
275+The ability to specify a session is not yet implemented in Dill, so `session` is always `~`, the default session.
276+
277+#### Returns
278+
279+Dill will `%give` a copy of all `%blit`s for the default session. A `%blit` `gift` is:
280+
281+```hoon
282+[%blit p=(list blit)]
283+```
284+
285+## `%trim`
286+
287+```hoon
288+[%trim p=@ud]
289+```
290+
291+`%trim` is a common vane `task` used to reduce memory usage. It does nothing for Dill because Dill only keeps a minimal necessary state.
292+
293+#### Returns
294+
295+Dill does not return a `gift` in response to a `%trim` `task`.
296+
297+## `%vega`
298+
299+```hoon
300+[%vega ~]
301+```
302+
303+This is a common vane `task` used to inform the vane that the kernel has been
304+upgraded. Dill does not do anything in response to this.
305+
306+This `task` would not be used from userspace.
307+
308+#### Returns
309+
310+Dill returns no `gift` in response to a `%vega` `task`.
311+
312+## `%verb`
313+
314+```hoon
315+[%verb ~]
316+```
317+
318+This `task` toggles verbose mode for all of Arvo, which is located here since
319+Dill is the vane that prints errors. To be precise, `%verb` toggles the laconic
320+bit `lac` in the [Arvo state](/docs/arvo/overview#the-state) by passing a `%verb` `waif` to Arvo.
321+
322+#### Returns
323+
324+Dill does not return a `gift` in response to a `%verb` `task`.
325+
326+## `%knob`
327+
328+```hoon
329+[%knob tag=term level=?(%hush %soft %loud)]
330+```
331+
332+`%knob` sets the verbosity level for each error tag. The error `tag` can be any `@tas`. The given `tag` and `level` will be added to Dill's `veb` which maps tags to levels. Subsequent [%crud](#crud) `task`s will then print with the specified verbosity.
333+
334+The `level`s behave like so:
335+
336+- `%hush` - Completely silent, print nothing.
337+- `%soft` - Just print `crud: %error-tag event failed`, ignore any `tang` given in the `%crud`.
338+- `%loud` - Print the `%soft` message as well as the full `tang` given in the `%crud` `task`.
339+
340+#### Returns
341+
342+Dill does not return a `gift` in response to a `%knob` `task`.
content/docs/arvo/eyre/_index.md+1−1
@@ -26,6 +26,6 @@ The scry endpoints of Eyre.
2626
2727Reference documentation of the various data types used by Eyre.
2828
29−## [Examples](/docs/arvo/eyre/examples)
29+## [Guide](/docs/arvo/eyre/guide)
3030
3131Practical examples of the different ways of using Eyre.
content/docs/arvo/eyre/external-api-ref.md+4−4
@@ -4,7 +4,7 @@ weight = 2
44template = "doc.html"
55+++
66
7−This document contains reference information about Eyre's external APIs including [the channel system](#channels) and [scries](#scry). Each section will also have practical examples in the [Examples](/docs/arvo/eyre/examples) document.
7+This document contains reference information about Eyre's external APIs including [the channel system](#channels) and [scries](#scry). Each section will also have practical examples in the [Guide](/docs/arvo/eyre/guide) document.
88
99## Authentication
1010
@@ -14,7 +14,7 @@ To use Eyre's channel system, run threads or perform scries you must first obtai
1414| ----------- | -------------------------------------- | ---------- | ----------------------------------------------------------------------------------- |
1515| `POST` | `password=lidlut-tabwed-pillex-ridrup` | `/~/login` | The password is your web login code which can be obtained with `+code` in the dojo. |
1616
17−See the [examples](/docs/arvo/eyre/examples#authenticating) for an example of how to do this using the curl.
17+See the [Guide](/docs/arvo/eyre/guide#authenticating) for an example of how to do this using the curl.
1818
1919Eyre's response will include a `set-cookie` header like:
2020
@@ -51,7 +51,7 @@ All the events that Eyre sends you on a channel must be [ack](#ack)ed so that Ey
5151
5252When you're finished with a channel, you can send Eyre a [delete action](#delete-channel) to close it.
5353
54−See the [Using the Channel System](/docs/arvo/eyre/examples#using-the-channel-system) section of the [Examples](/docs/arvo/eyre/examples) document for a practical example.
54+See the [Using the Channel System](/docs/arvo/eyre/guide#using-channels) section of the [Guide](/docs/arvo/eyre/guide) document for a practical example.
5555
5656### HTTP Requests
5757
@@ -352,7 +352,7 @@ The `{mark}` is the type you want returned. It needn't just be `json` as with th
352352
353353If your session cookie is invalid or missing, Eyre will respond with a 403 Forbidden status. If the scry endpoint cannot be found, Eyre will respond with a 404 Missing status. If the `mark` conversions can't be done, Eyre will respond with a 500 Internal Server Error status. Otherwise, Eyre will respond with a 200 OK status with the requested data in the body of the HTTP response.
354354
355−See the [Scrying](/docs/arvo/eyre/examples#scrying) section of the [Examples](/docs/arvo/eyre/examples) document for a practical example.
355+See the [Scrying](/docs/arvo/eyre/guide#scrying) section of the [Guide](/docs/arvo/eyre/guide) document for a practical example.
356356
357357## Spider
358358
content/docs/arvo/eyre/eyre.md+5−5
@@ -18,7 +18,7 @@ Eyre's channel system is the primary way of interacting with Gall agents from ou
1818
1919The channel system is designed to be extremely simple with just a handful of `action` and `response` JSON objects to deal. Essentially it's a thin layer on top of the underlying Gall agent interface. You can poke agents, subscribe for updates, etc, just like you would from within Urbit.
2020
21−Detailed documentation of the channel system's JSON API is provided in the [External API Reference](/docs/arvo/eyre/external-api-ref) document with corresponding examples in the [Examples](/docs/arvo/eyre/examples#using-the-channel-system) document.
21+Detailed documentation of the channel system's JSON API is provided in the [External API Reference](/docs/arvo/eyre/external-api-ref) document with corresponding examples in the [Guide](/docs/arvo/eyre/guide#using-the-channel-system) document.
2222
2323## Scrying
2424
@@ -34,19 +34,19 @@ Spider (the Gall agent that manages threads) has an Eyre binding that allows you
3434
3535Generators, which are like Hoon scripts, can also be used through Eyre. Rather than having a predefined JSON API, they instead handle HTTP requests and return HTTP responses directly, and are therefore a more complex case that you're less likely to use.
3636
37−Their usage is explained in the [%serve](/docs/arvo/eyre/tasks#serve) section of the [Internal API Reference](/docs/arvo/eyre/tasks) documentation and a practical example is provided in the [Generators](/docs/arvo/eyre/examples#generators) section of the [Examples](/docs/arvo/eyre/examples) document.
37+Their usage is explained in the [%serve](/docs/arvo/eyre/tasks#serve) section of the [Internal API Reference](/docs/arvo/eyre/tasks) documentation and a practical example is provided in the [Generators](/docs/arvo/eyre/guide#generators) section of the [Guide](/docs/arvo/eyre/guide) document.
3838
3939## Direct HTTP Handling With Gall Agents
4040
4141As well as the [Channel System](#the-channel-system) and [Scries](#scrying), it's also possible for Gall agents to deal directly with HTTP requests. This method is much more complicated than the channel system so you're unlikely to use it unless you want to build a custom HTTP-based API or something like that.
4242
43−This method is explained in the [%connect](/docs/arvo/eyre/tasks#connect) section of the [Internal API Reference](/docs/arvo/eyre/tasks) document and a detailed example is provided in the [Direct HTTP Handling With Gall Agents](/docs/arvo/eyre/examples#direct-http-handling-with-gall-agents) section of the [Examples](/docs/arvo/eyre/examples) document.
43+This method is explained in the [%connect](/docs/arvo/eyre/tasks#connect) section of the [Internal API Reference](/docs/arvo/eyre/tasks) document and a detailed example is provided in the [Agents: Direct HTTP](/docs/arvo/eyre/guide#agents-direct-http) section of the [Guide](/docs/arvo/eyre/guide) document.
4444
4545## Cross-Origin Resource Sharing
4646
4747Eyre supports both simple [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) requests and OPTIONS preflight requests. It has a CORS registry with three categories - `approved`, `rejected` and `requests`. Eyre will respond positively for origins in its `approved` list and negatively for all others. Eyre will add origins in requests that it doesn't have in either its `approved` or `rejected` lists to its `requests` list. Eyre always allows all methods and headers over CORS.
4848
49−There are three generators - `+cors-registry`, `|cors-approve`, and `|cors-reject` to view, approve, and deny origins respectively from the dojo. Eyre also has [tasks](/docs/arvo/eyre/tasks) to [approve](/docs/arvo/eyre/tasks#approve-origin) and [reject](/docs/arvo/eyre/tasks#reject-origin) origins programmatically, and a number of [scry endpoints](/docs/arvo/eyre/scry) to query them. Examples are also included in the [Managing CORS Origins](/docs/arvo/eyre/examples#managing-cors-origins) section of the Examples document.
49+There are three generators - `+cors-registry`, `|cors-approve`, and `|cors-reject` to view, approve, and deny origins respectively from the dojo. Eyre also has [tasks](/docs/arvo/eyre/tasks) to [approve](/docs/arvo/eyre/tasks#approve-origin) and [reject](/docs/arvo/eyre/tasks#reject-origin) origins programmatically, and a number of [scry endpoints](/docs/arvo/eyre/scry) to query them. Examples are also included in the [Managing CORS Origins](/docs/arvo/eyre/guide#managing-cors-origins) section of the Guide document.
5050
5151## Sections
5252
@@ -58,4 +58,4 @@ There are three generators - `+cors-registry`, `|cors-approve`, and `|cors-rejec
5858
5959[Data Types](/docs/arvo/eyre/data-types) - Reference documentation of the various data types used by Eyre.
6060
61−[Examples](/docs/arvo/eyre/examples) - Practical examples of the different ways of using Eyre.
61+[Guide](/docs/arvo/eyre/guide) - Practical examples of the different ways of using Eyre.
content/docs/arvo/eyre/examples.md → content/docs/arvo/eyre/guide.mdrenamed+29−23
@@ -1,16 +1,22 @@
11+++
2−title = "Examples"
2+title = "Guide"
33weight = 6
44template = "doc.html"
55+++
66
7−This documents contains practical examples of the various ways of interacting with Eyre.
7+This document walks through practical examples of the various ways of interacting with Eyre. The [Basic](#basic) sections goes over the common methods of interacting through Eyre from an HTTP client, and the [Advanced](#advanced) section explains how to handle HTTP directly with generators and Gall agents.
88
99General documentation of the `task`s and methods described here are available in the [External API Reference](/docs/arvo/eyre/external-api-ref) document and the [Internal API Reference](/docs/arvo/eyre/tasks) document.
1010
11−## Authenticating
11+## Basic
1212
13−In most cases we must obtain a valid session cookie by [authenticating](/docs/arvo/eyre/external-api-ref#authentication) with our web login code (which can be obtained by running `+code` in the dojo) before we can use Eyre's interfaces (such as the channel system or scry interface).
13+Eyre's channel system is the typical way of interacting with Gall agents from an HTTP client. It provides a simple JSON API for actions like pokes, watches, etc, and an SSE event stream for subscription updates. Additionally, Eyre has a scry interface so you can retrieve data in a more ad-hoc manner. These examples use `curl` to be more language agnostic and to show the nitty-gritty details. In practice you'd probably use an "airlock" library (like [http-api](https://github.com/urbit/urbit/tree/master/pkg/npm/http-api) for Javascript) which abstracts things like ack'ing events, incrementing event IDs, manually composing the JSON for actions, etc.
14+
15+It's advisable to have a read through the [External API Reference](/docs/arvo/eyre/external-api-ref) before going through these examples.
16+
17+### Authenticating
18+
19+You must have a valid session cookie in order to use Eyre's interfaces (such as the channel system or scry interface). If your HTTP client is served from your ship, your browser will automatically add the session cookie it obtained upon login, so there's no need to worry about authentication in practice. If your client does not run in the browser or is not served by your ship, [authenticating](/docs/arvo/eyre/external-api-ref#authentication) with your web login code (which can be obtained by running `+code` in the dojo) is necessary.
1420
1521Here we'll try authenticating with the default fakezod code.
1622
@@ -32,7 +38,7 @@ set-cookie: urbauth-~zod=0v3.j2062.1prp1.qne4e.goq3h.ksudm; Path=/; Max-Age=6048
3238
3339The `urbauth-....` cookie can be now be included in subsequent requests (e.g. to the channel system) by providing it in a Cookie HTTP header.
3440
35−## Using The Channel System
41+### Using Channels
3642
3743Here we'll look at a practical example of Eyre's channel system. You can refer to the [Channels](/docs/arvo/eyre/external-api-ref#channels) section of the [External API Reference](/docs/arvo/eyre/external-api-ref) document for relevant details.
3844
@@ -147,7 +153,7 @@ curl --header "Content-Type: application/json" \
147153
148154With our channel deleted, we can now close the connection on the client side.
149155
150−## Scrying
156+### Scrying
151157
152158Here we'll look at performing scries through Eyre. You can refer to the [Scry](/docs/arvo/eyre/external-api-ref#scry) section of the [External API Reference](/docs/arvo/eyre/external-api-ref) document for relevant details.
153159
@@ -198,12 +204,16 @@ Server: urbit/vere-1.5
198204set-cookie: urbauth-~zod=0v1.1pseu.tq7hs.hps2t.ltaf1.tmqjm; Path=/; Max-Age=604800
199205content-type: text/html
200206
201−<html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>There was an error while handling the request for /foo/bar/baz.json.</p><code>no scry result</code></body></html>
207+&lt;html>&lt;head>&lt;title>404 Not Found&lt;/title>&lt;/head>&lt;body>&lt;h1>Not Found&lt;/h1>&lt;p>There was an error while handling the request for /foo/bar/baz.json.&lt;/p>&lt;code>no scry result&lt;/code>&lt;/body>&lt;/html>
202208```
203209
204−## Direct HTTP Handling With Gall Agents
210+## Advanced
205211
206−In many cases you'll just want to interact with Gall agents through the JSON API of the channel system, but it's also possible to bypass all that and just deal with HTTP requests directly. Here we'll take a look at how that practically works.
212+Rather than using things like Eyre's channel system described in the [Basic](#basic) section, it's possible to handle HTTP requests directly in Gall agents or generators. This is useful if you want to implement a custom API or work with `sail` to dynamically compose HTML inside an agent.
213+
214+### Agents: Direct HTTP
215+
216+Here we'll look at handling HTTP requests directly in Gall agents rather than using Eyre's channel system.
207217
208218You can refer to the [%connect](/docs/arvo/eyre/tasks#connect) section of the [Internal API Reference](/docs/arvo/eyre/tasks) document for relevant details.
209219
@@ -244,7 +254,7 @@ Note that this example does a lot of things manually for demonstrative purposes.
244254 ~& [mark req]
245255 ?+ method.request.q.req
246256 =/ data=octs
247− (as-octs:mimes:html '<h1>405 Method Not Allowed</h1>')
257+ (as-octs:mimes:html '&lt;h1>405 Method Not Allowed&lt;/h1>')
248258 =/ content-length=@t
249259 (crip ((d-co:co 1) p.data))
250260 =/ =response-header:http
@@ -262,7 +272,7 @@ Note that this example does a lot of things manually for demonstrative purposes.
262272 ::
263273 %'GET'
264274 =/ data=octs
265− (as-octs:mimes:html '<h1>Hello, World!</h1>')
275+ (as-octs:mimes:html '&lt;h1>Hello, World!&lt;/h1>')
266276 =/ content-length=@t
267277 (crip ((d-co:co 1) p.data))
268278 =/ =response-header:http
@@ -309,19 +319,15 @@ Note that this example does a lot of things manually for demonstrative purposes.
309319Save the above to `/app/eyre-agent.hoon`. Commit it:
310320
311321```
312−> |commit %home
322+> |commit %base
313323>=
314−+ /~zod/home/2/app/eyre-agent/hoon
324++ /~zod/base/2/app/eyre-agent/hoon
315325```
316326
317327...and start it:
318328
319329```
320−> |start %eyre-agent
321−>=
322−gall: loading %eyre-agent
323−activated app home/eyre-agent
324−[unlinked from [p=~zod q=%eyre-agent]]
330+> |rein %base [& %eyre-agent]
325331```
326332
327333Now, first we need to bind a URL to our app. In the `++ on-poke` arm, our agent will send a [%connect](/docs/arvo/eyre/tasks#connect) `task` to Eyre when poked with `%bind`:
@@ -368,7 +374,7 @@ Content-Type: text/html
368374Content-Length: 22
369375transfer-encoding: chunked
370376
371−<h1>Hello, World!</h1>%
377+&lt;h1>Hello, World!&lt;/h1>%
372378```
373379
374380...which has succeed! This is because the `+on-poke` arm tests for http GET requests and responds with `Hello, World!` when it sees one:
@@ -376,7 +382,7 @@ transfer-encoding: chunked
376382```hoon
377383 %'GET'
378384=/ data=octs
379− (as-octs:mimes:html '<h1>Hello, World!</h1>')
385+ (as-octs:mimes:html '&lt;h1>Hello, World!&lt;/h1>')
380386=/ content-length=@t
381387 (crip ((d-co:co 1) p.data))
382388=/ =response-header:http
@@ -424,13 +430,13 @@ Eyre subscribed to /http-response/~.eyre_0v3.1knjk.l544e.5uds6.fn9l2.f8929.
424430
425431This is a very rudimentary app but it demonstrates the basic mechanics of dealing with HTTP requests and serving responses.
426432
427−## Generators
433+### Generators
428434
429435Here we'll look at running a generator via Eyre. Eyre doesn't have a mediated JSON API for generators, instead it just passes through the HTTP request and returns the HTTP response composed by the generator.
430436
431437You can refer to the [%serve](/docs/arvo/eyre/tasks#serve) section of the [Internal API Reference](/docs/arvo/eyre/tasks) document for relevant details.
432438
433−Here's a very simple generator that will just echo back the body of the request (if available) along with the current datetime. You can save it in the `/gen` directory and `|commit %home`.
439+Here's a very simple generator that will just echo back the body of the request (if available) along with the current datetime. You can save it in the `/gen` directory and `|commit %base`.
434440
435441Note that this example does some things manually for demonstrative purposes. In practice you'd likely want to use a library like `/lib/server.hoon` to cut down on boilerplate code.
436442
@@ -478,7 +484,7 @@ The [$binding](/docs/arvo/eyre/data-types#binding) specifies the site and URL pa
478484Let's bind our generator to the `/mygen` URL path with the `|pass` command in the dojo:
479485
480486```
481−|pass [%e [%serve `/mygen %home /gen/eyre-gen/hoon ~]]
487+|pass [%e [%serve `/mygen %base /gen/eyre-gen/hoon ~]]
482488```
483489
484490Note that Eyre responds with a `%bound` `gift` to indicate whether the binding succeeded but `|pass` doesn't take such responses so it's not shown.
content/docs/arvo/eyre/tasks.md+5−5
@@ -6,7 +6,7 @@ template = "doc.html"
66
77This document details all the `task`s you're likely to use to interact with Eyre, as well as the `gift`s you'll receive in response.
88
9−The primary way of interacting with Eyre is from the outside with HTTP requests. As a result, most of its `task`s are only used internally and you're unlikely to need to deal with them directly. The ones you may want to use in certain cases are [%connect](#connect), [%serve](#serve), [%disconnect](#disconnect), [%approve-origin](#approve-origin) and [%reject-origin](#reject-origin), and they are also demonstrated in the [Examples](/docs/arvo/eyre/examples) document. The rest are just documented for completeness.
9+The primary way of interacting with Eyre is from the outside with HTTP requests. As a result, most of its `task`s are only used internally and you're unlikely to need to deal with them directly. The ones you may want to use in certain cases are [%connect](#connect), [%serve](#serve), [%disconnect](#disconnect), [%approve-origin](#approve-origin) and [%reject-origin](#reject-origin), and they are also demonstrated in the [Guide](/docs/arvo/eyre/guide) document. The rest are just documented for completeness.
1010
1111Many of the types referenced are detailed in the [Data Types](/docs/arvo/eyre/data-types) document. It may also be useful to look at the `+eyre` section of `/sys/lull.hoon` in Arvo where these `task`s, `gift`s and data structures are defined.
1212
@@ -110,7 +110,7 @@ The `accepted` field says whether the binding succeeded and the `binding` is the
110110
111111#### Example
112112
113−See the [Direct HTTP Handling With Gall Agents](/docs/arvo/eyre/examples#direct-http-handling-with-gall-agents) section of the [Examples](/docs/arvo/eyre/examples) document for an example.
113+See the [Agents: Direct HTTP](/docs/arvo/eyre/guide#agents-direct-http) section of the [Guide](/docs/arvo/eyre/guide) document for an example.
114114
115115## `%serve`
116116
@@ -146,7 +146,7 @@ Eyre will return a `%bound` `gift` as described at the end of the [%connect](#co
146146
147147#### Example
148148
149−See the [Generators](/docs/arvo/eyre/examples#generators) section of the [Examples](/docs/arvo/eyre/examples) document for an example.
149+See the [Generators](/docs/arvo/eyre/guide#generators) section of the [Guide](/docs/arvo/eyre/guide) document for an example.
150150
151151## `%disconnect`
152152
@@ -192,7 +192,7 @@ Eyre returns no `gift` in response to a `%approve-origin` `task`.
192192
193193#### Example
194194
195−See the [Managing CORS Origins](/docs/arvo/eyre/examples#managing-cors-origins) section of the [Examples](/docs/arvo/eyre/examples) document for an example.
195+See the [Managing CORS Origins](/docs/arvo/eyre/guide#managing-cors-origins) section of the [Guide](/docs/arvo/eyre/guide) document for an example.
196196
197197## `%reject-origin`
198198
@@ -210,4 +210,4 @@ Eyre returns no `gift` in response to a `%reject-origin` `task`.
210210
211211#### Example
212212
213−See the [Managing CORS Origins](/docs/arvo/eyre/examples#managing-cors-origins) section of the [Examples](/docs/arvo/eyre/examples) document for an example.
213+See the [Managing CORS Origins](/docs/arvo/eyre/guide#managing-cors-origins) section of the [Guide](/docs/arvo/eyre/guide) document for an example.
content/docs/arvo/gall/data-types.mdnew file+492
@@ -0,0 +1,492 @@
1++++
2+title = "Data Types"
3+weight = 5
4+template = "doc.html"
5++++
6+
7+This document describes the data types for Gall defined in `lull.hoon`.
8+
9+## `bitt`
10+
11+```hoon
12++$ bitt (map duct (pair ship path))
13+```
14+
15+Incoming subscriptions.
16+
17+This is the structure Gall uses to keep track of subscribers to our Gall agent.
18+The `sup` field of a [`bowl`](#bowl) contains the `bitt` for our agent.
19+
20+## `boat`
21+
22+```hoon
23++$ boat
24+ %+ map [=wire =ship =term]
25+ [acked=? =path]
26+```
27+
28+Outgoing subscriptions.
29+
30+This is the structure Gall uses to keep track of subscriptions our agent has
31+initiated. The `wex` field of a [`bowl`](#bowl) contails the `boat` for that
32+agent.
33+
34+The `wire` field is the `wire` which [`sign:agent`](#signagent)s will come in on.
35+The `ship` and `term` fields are the ship and the name of the agent to which our
36+agent has subscribed.
37+
38+The `acked` field is `%.y` if they have acknowledged our subscription request,
39+and `%.n` if they have not. The `path` field is the `path` on the other agent to
40+which our agent has subscribed.
41+
42+## `bowl`
43+
44+```hoon
45++$ bowl :: standard app state
46+ $: $: our=ship :: host
47+ src=ship :: guest
48+ dap=term :: agent
49+ == ::
50+ $: wex=boat :: outgoing subs
51+ sup=bitt :: incoming subs
52+ == ::
53+ $: act=@ud :: change number
54+ eny=@uvJ :: entropy
55+ now=@da :: current time
56+ byk=beak :: load source
57+ == == ::
58+```
59+
60+Additional agent state.
61+
62+A `bowl` is given to the agent core each time an event comes in. The fields are
63+as follows:
64+
65+- `our`: Our ship.
66+- `src`: The ship from which the current request originated.
67+- `dap`: The name of our agent.
68+- `wex`: Outgoing subscriptions. That is, subscriptions our agent has initiated.
69+ See the [`boat`](#boat) section for details of the type.
70+- `sup`: Incoming subscriptions. That is, subscriptions others have made to our
71+ agent. See the [`bitt`](#bitt) section for details of the type.
72+- `act`: The total number of [`move`](/docs/arvo/overview#move)s our agent has
73+ processed so far.
74+- `eny`: 512 bits of entropy.
75+- `now`: The current date-time.
76+- `byk`: The ship, desk and `case` in Clay from which this agent was loaded. The
77+ `case` will be `[%da @da]` where the `@da` is the when the agent was loaded. A
78+ `beak` is a triple of `[ship desk case]`.
79+
80+## `dude`
81+
82+```hoon
83++$ dude term
84+```
85+
86+Agent name.
87+
88+## `gill`
89+
90+```hoon
91++$ gill (pair ship term)
92+```
93+
94+A general contact: A pair of the ship and agent name.
95+
96+## `scar`
97+
98+```hoon
99++$ scar
100+ $: p=@ud
101+ q=(map duct bone)
102+ r=(map bone duct)
103+ ==
104+```
105+
106+Opaque duct - used internally.
107+
108+## `suss`
109+
110+```hoon
111++$ suss (trel dude @tas @da)
112+```
113+
114+Configuration report.
115+
116+## `well`
117+
118+```hoon
119++$ well (pair desk term)
120+```
121+
122+Desk and agent.
123+
124+## `neat`
125+
126+```hoon
127++$ neat
128+ $% [%arvo =note-arvo]
129+ [%agent [=ship name=term] =deal]
130+ [%pyre =tang]
131+ ==
132+```
133+
134+Like a [`note:agent`](#noteagent), except the `%agent` case has a [`deal`](#deal) instead
135+of just a [`task:agent`](#taskagent). This is used for messages that come in over the
136+network and would not be used manually.
137+
138+## `deal`
139+
140+```hoon
141++$ deal
142+ $% [%raw-poke =mark =noun]
143+ task:agent
144+ ==
145+```
146+
147+Like a [`task:agent`](#taskagent) but with the additional case of a raw poke.
148+This is used for messages that come in over the network and would not be used
149+manually.
150+
151+## `unto`
152+
153+```hoon
154++$ unto
155+ $% [%raw-fact =mark =noun]
156+ sign:agent
157+ ==
158+```
159+
160+Like a [`sign:agent`](#signagent) but with the additional case of a raw fact.
161+This is used for messages that come in over the network and would not be used
162+manually.
163+
164+## `agent`
165+
166+```hoon
167+++ agent
168+ =< form
169+ |%
170+```
171+
172+Container for Gall agent types. The most significant arm is
173+[`form:agent`](#formagent), which specifies the structure of the agent itself.
174+There are also some additional structures defined here, mostly defining the
175+kinds of messages agents can send. The different arms of the core in `agent`
176+are considered separately below.
177+
178+### `step:agent`
179+
180+```hoon
181++$ step (quip card form)
182+```
183+
184+A cell of [`card:agent`](#cardagent)s to be sent and a new agent state. This is the
185+type returned by most arms of an agent. A `(quip a b)` is the same as `[(list a) b]`, it's just a more convenient way to specify it.
186+
187+### `card:agent`
188+
189+```hoon
190++$ card (wind note gift)
191+```
192+
193+An effect - typically a message to be sent to another agent or vane. A list of
194+these are returned by most agent arms along with a new state in a
195+[`step:agent`](#stepagent). A `wind` is the following:
196+
197+```hoon
198+++ wind
199+ |$ [a b]
200+ $% [%pass p=path q=a]
201+ [%slip p=a]
202+ [%give p=b]
203+ ==
204+```
205+
206+Gall will not allow a `%slip`, so in practice a `card` will be one of:
207+
208+- `[%pass path note]`
209+- `[%give gift]`
210+
211+For `%pass`, `p` specifies the `wire` on which a response should be returned.
212+See [`note:agent`](#noteagent) and [`gift:agent`](#giftagent) below for details of their
213+types.
214+
215+### `note:agent`
216+
217+```hoon
218++$ note
219+ $% [%agent [=ship name=term] =task]
220+ [%arvo note-arvo]
221+ [%pyre =tang]
222+ ==
223+```
224+
225+The type for messages initiated by our agent. This is opposed to
226+[`gift:agent`](#giftagent), which is the type for responding to other agents or
227+vanes, or for sending out updates to subscribers. The three cases are:
228+
229+- `%agent`: Poke another agent, subscribe to another agent, or cancel a
230+ subscription to another agent. The `ship` and `name` fields are the ship and
231+ agent to which the `task` should be sent. The `task` is the request itself,
232+ see [`task:agent`](#taskagent) below for its possible types.
233+- `%arvo`: Pass a `task` to a vane. The type of a `note-arvo` is:
234+ ```hoon
235+ +$ note-arvo
236+ $~ [%b %wake ~]
237+ $% [%a task:ames]
238+ [%b task:behn]
239+ [%c task:clay]
240+ [%d task:dill]
241+ [%e task:eyre]
242+ [%g task:gall]
243+ [%i task:iris]
244+ [%j task:jael]
245+ [%$ %whiz ~]
246+ [@tas %meta vase]
247+ ==
248+ ```
249+ You can refer to the `/sys/lull.hoon` source code for all the possible vane
250+ tasks, or see each vane's API Reference section in the [Arvo
251+ documentation](/docs/arvo/overview)
252+- `%pyre`: This is for aborting side-effects initiated during agent
253+ installation. The `tang` is an error message.
254+
255+A `note:agent` is always wrapped in a `%pass` [`card:agent`](#cardagent).
256+
257+### `task:agent`
258+
259+```hoon
260++$ task
261+ $% [%watch =path]
262+ [%watch-as =mark =path]
263+ [%leave ~]
264+ [%poke =cage]
265+ [%poke-as =mark =cage]
266+ ==
267+```
268+
269+The types of messages initiated by our agent and sent to another agent. This is
270+in contrast to [`gift:agent`](#giftagent)s, which are responses to incoming
271+messages from agents or updates to agents already subscribed. The five kinds
272+are:
273+
274+- `%watch`: Subscribe to `path` on the target ship and agent.
275+- `%watch-as`: Same as `%watch`, except you ask the target's Gall to convert
276+ subscription updates to the `mark` you specified rather than just giving you
277+ the `mark` produced by the agent.
278+- `%leave`: Cancel subscription. The particular subscription to cancel will be
279+ determined by the `wire` given in the `p` field of the containing `%pass`
280+ [`card:agent`](#cardagent).
281+- `%poke`: Poke the target ship and agent with the given `cage`, which is a pair
282+ of `[mark vase]`.
283+- `%poke-as`: Same as `%poke`, except the `cage` will be converted to the
284+ specified `mark` before sending.
285+
286+A `task:agent` is always wrapped in a `%pass` [`card:agent`](#cardagent).
287+
288+### `gift:agent`
289+
290+```hoon
291++$ gift
292+ $% [%fact paths=(list path) =cage]
293+ [%kick paths=(list path) ship=(unit ship)]
294+ [%watch-ack p=(unit tang)]
295+ [%poke-ack p=(unit tang)]
296+ ==
297+```
298+
299+The types of messages our agent can either send in response to messages from
300+other agents, or send to subscribed agents. This is in contrast to
301+[`task:agent`](#taskagent)s, which are messages to other agents our agent
302+initiates rather than sends in response. The four kinds are:
303+
304+- `%fact`: An update to existing subscribers. The `paths` field specifies which
305+ subscription paths the update should go out to. The `cage` is the data, and is
306+ a `[mark vase]`.
307+- `%kick`: Kick subscriber, ending their subscription. The `paths` field
308+ specifies which paths the subscriber should be kicked from, and the `ship`
309+ field specifies the ship to kick. If the `ship` field is null, all subscribers
310+ on the specified paths are kicked. Gall will automatically remove the
311+ subscription from our agent's [`bitt`](#bitt) (inbound subscription `map`),
312+ and subscriber will no longer receive updates on the `path`s in question.
313+- `%watch-ack`: Acknowledge a subscription request. If `p` is null, it's an ack
314+ (positive acknowledgement), and if `p` is non-null, it's a nack (negative
315+ acknowledgement). Simply crashing will caused Gall to nack a subscription
316+ request, and not crashing but not explicitly producing a `%watch-ack` `gift`
317+ will cause Gall to ack a subscription request. Therefore, you'd typically only
318+ explicitly produce a `%watch-ack` `gift` if you wanted to nack a subscription
319+ request with a custom error in the `tang`.
320+- `%poke-ack`: Acknowledge a poke. If `p` is null, it's an ack, and if `p` is
321+ non-null, it's a nack. Simply crashing will cause Gall to nack a poke, and not
322+ crashing but not explicitly producing a `%poke-ack` `gift` will cause Gall to
323+ ack a poke. Therefore, you'd typically only explicitly produce a `%poke-ack`
324+ `gift` if you wanted to nack a poke with a custom error in the `tang`.
325+
326+A `gift:agent` is always wrapped in a `%give` [`card:agent`](#cardagent).
327+
328+### `sign:agent`
329+
330+```hoon
331++$ sign
332+ $% [%poke-ack p=(unit tang)]
333+ [%watch-ack p=(unit tang)]
334+ [%fact =cage]
335+ [%kick ~]
336+ ==
337+```
338+
339+A `sign` is like a [`gift:agent`](#giftagent) but it's something that comes
340+_in_ to our agent from another agent rather than something we send out. The
341+possible types are:
342+
343+- `%poke-ack`: Another agent has acked (positively acknowledged) or nacked
344+ (negatively acknowledged) a `%poke` [`task:agent`](#taskagent) we previously
345+ sent. It's an ack if `p` is null and a nack if `p` is non-null. The `tang`
346+ contains an error or traceback if it's a nack.
347+- `%watch-ack`: Another agent has acked or nacked a `%watch`
348+ [`task:agent`](#taskagent) (subscription request) we previously sent. It's an
349+ ack if `p` is null and a nack if `p` is non-null. The `tang` contains an error
350+ or traceback if it's a nack. If it's a nack, Gall will automatically remove
351+ the subscription from our agent's [`boat`](#boat) (outbound subscription
352+ map).
353+- `%fact`: An update from another agent to which we've previously subscribed
354+ with a `%watch` [`task:agent`](#taskagent) (subscription request). The `cage`
355+ contains the data, and is a `[mark vase]`.
356+- `%kick`: Our subscription to another agent has been ended, and we'll no longer
357+ receive updates. A `%kick` may be intentional, but it may also happen due to
358+ certain network conditions or other factors. As a result, it's best to try and
359+ resubscribe with another `%watch` [`task:agent`](#taskagent), and if they
360+ nack the `%watch`, we can conclude it was intentional and give up.
361+
362+### `form:agent`
363+
364+```hoon
365+++ form
366+ $_ ^|
367+ |_ bowl
368+ ++ on-init
369+ *(quip card _^|(..on-init))
370+ ::
371+ ++ on-save
372+ *vase
373+ ::
374+ ++ on-load
375+ |~ old-state=vase
376+ *(quip card _^|(..on-init))
377+ ::
378+ ++ on-poke
379+ |~ [mark vase]
380+ *(quip card _^|(..on-init))
381+ ::
382+ ++ on-watch
383+ |~ path
384+ *(quip card _^|(..on-init))
385+ ::
386+ ++ on-leave
387+ |~ path
388+ *(quip card _^|(..on-init))
389+ ::
390+ ++ on-peek
391+ |~ path
392+ *(unit (unit cage))
393+ ::
394+ ++ on-agent
395+ |~ [wire sign]
396+ *(quip card _^|(..on-init))
397+ ::
398+ ++ on-arvo
399+ |~ [wire sign-arvo]
400+ *(quip card _^|(..on-init))
401+ ::
402+ ++ on-fail
403+ |~ [term tang]
404+ *(quip card _^|(..on-init))
405+ --
406+--
407+```
408+
409+This defines the structure of the agent itself. The agent is a door with a [`bowl`](#bowl) as its sample and exactly ten arms. Below we'll describe each arm briefly.
410+
411+#### `on-init`
412+
413+- Accepts: Nothing.
414+- Produces: [`step:agent`](#stepagent)
415+
416+This arm is called when the agent is initially installed.
417+
418+#### `on-poke`
419+
420+- Accepts: `cage`
421+- Produces: [`step:agent`](#stepagent)
422+
423+This arm is called when another agent pokes our agent.
424+
425+#### `on-watch`
426+
427+- Accepts: `path`
428+- Produces: [`step:agent`](#stepagent)
429+
430+This arm is called when another agent subscribes to our agent.
431+
432+#### `on-leave`
433+
434+- Accepts: `path`
435+- Produces: [`step:agent`](#stepagent)
436+
437+This arm is called when another agent unsubscribes from a subscription path on
438+our agent.
439+
440+#### `on-peek`
441+
442+- Accepts: `path`
443+- Produces: `(unit (unit cage))`
444+
445+This arm is called when a [scry](/docs/arvo/concepts/scry) is performed on our
446+agent.
447+
448+#### `on-agent`
449+
450+- Accepts: `[wire sign:agent]`
451+- Produces: [`step:agent`](#stepagent)
452+
453+This arm is called when another agent give our agent a
454+[`sign:agent`](#signagent).
455+
456+#### `on-arvo`
457+
458+- Accepts: `[wire sign-arvo]`
459+- Produces: [`step:agent`](#stepagent)
460+
461+This arm is called when a vane gives our agent a `gift`. A `sign-arvo` is:
462+
463+```hoon
464++$ sign-arvo
465+ $% [%ames gift:ames]
466+ $: %behn
467+ $% gift:behn
468+ $>(%wris gift:clay)
469+ $>(%writ gift:clay)
470+ $>(%mere gift:clay)
471+ $>(%unto gift:gall)
472+ ==
473+ ==
474+ [%clay gift:clay]
475+ [%dill gift:dill]
476+ [%eyre gift:eyre]
477+ [%gall gift:gall]
478+ [%iris gift:iris]
479+ [%jael gift:jael]
480+ ==
481+```
482+
483+You can refer to the `/sys/lull.hoon` source code, or the API Reference of each
484+vane in the [Arvo documentation](/docs/arvo/overview).
485+
486+#### `on-fail`
487+
488+- Accepts: `[term tang]`
489+- Produces: [`step:agent`](#stepagent)
490+
491+This arm is called if certain errors occur in Gall, such as if our agent tries
492+to create a duplicate subscription.
content/docs/userspace/gall/gall-api.md → content/docs/arvo/gall/gall-api.mdrenamed+24−24
@@ -1,6 +1,6 @@
11+++
22title = "API Reference"
3−weight = 10
3+weight = 3
44template = "doc.html"
55+++
66
@@ -296,7 +296,7 @@ List of cards and new agent
296296
297297Expose state for saving.
298298
299−This arm is called immediately before the agent is upgraded. It packages the
299+This arm is called immediately before the agent is upgraded. It packages the
300300permament state of the agent in a vase for the next version of the agent.
301301Unlike most handlers, this cannot produce effects. It is not a gate and has no input.
302302
@@ -319,7 +319,7 @@ Unlike most handlers, this cannot produce effects. It is not a gate and has no i
319319
320320Application upgrade.
321321
322−This arm is called immediately after the agent is upgraded. It receives
322+This arm is called immediately after the agent is upgraded. It receives
323323a vase of the state of the previously-running version of the agent, obtained
324324from `+on-save`, which allows it to cleanly upgrade from the old agent.
325325
@@ -362,7 +362,7 @@ List of cards and new agent
362362
363363Handle application poke.
364364
365−This arm is called when the agent is "poked". The input is a cage, so
365+This arm is called when the agent is "poked". The input is a cage, so
366366it's a pair of a mark and a dynamic vase.
367367
368368#### Accepts
@@ -445,16 +445,16 @@ List of cards and new agent.
445445Handle new subscriber.
446446
447447This arm is called when a program wants to subscribe to the agent on a
448−particular path. The agent may or may not need to perform setup steps
449−to intialize the subscription. It may produce a `%give`
448+particular path. The agent may or may not need to perform setup steps
449+to intialize the subscription. It may produce a `%give`
450450`%subscription-result` to the subscriber to get it up to date, but after
451451this event is complete, it cannot give further updates to a specific
452−subscriber. It must give all further updates to all subscribers on a
452+subscriber. It must give all further updates to all subscribers on a
453453specific path.
454454
455455If this arm crashes, then the subscription is immediately terminated.
456456More specifcally, it never started -- the subscriber will receive a
457−negative `%watch-ack`. You may also produce an explicit `%kick` to
457+negative `%watch-ack`. You may also produce an explicit `%kick` to
458458close the subscription without crashing -- for example, you could
459459produce a single update followed by a `%kick`.
460460
@@ -501,11 +501,11 @@ Handle unsubscribe.
501501
502502This arm is called when a program becomes unsubscribed to you.
503503Subscriptions may close because the subscriber intentionally
504−unsubscribed, but they also could be closed by an intermediary. For
504+unsubscribed, but they also could be closed by an intermediary. For
505505example, if a subscription is from another ship which is currently
506506unreachable, Ames may choose to close the subscription to avoid queueing
507−updates indefinitely. If the program crashes while processing an
508−update, this may also generate an unsubscription. You should consider
507+updates indefinitely. If the program crashes while processing an
508+update, this may also generate an unsubscription. You should consider
509509subscriptions to be closable at any time.
510510
511511#### Accepts
@@ -540,8 +540,8 @@ List of cards and new agent.
540540Handle scry request.
541541
542542This arm is called when a program reads from the agent's "scry"
543−namespace, which should be referentially transparent. Unlike most
544−handlers, this cannot perform IO, and it cannot change the state. All
543+namespace, which should be referentially transparent. Unlike most
544+handlers, this cannot perform IO, and it cannot change the state. All
545545it can do is produce a piece of data to the caller, or not.
546546
547547#### Accepts
@@ -568,8 +568,8 @@ The path being scryed for.
568568```
569569
570570If this arm produces `[~ ~ data]`, then `data` is the value at the the
571−given path. If it produces `[~ ~]`, then there is no data at the given
572−path and never will be. If it produces `~`, then we don't know yet whether
571+given path. If it produces `[~ ~]`, then there is no data at the given
572+path and never will be. If it produces `~`, then we don't know yet whether
573573there is or will be data at the given path. The head of the path is known as the
574574`care`. Requests with a care of `%x` should return a vase that matches or is
575575convertible to the mark at the end of the scry request. This mark is not
@@ -625,8 +625,8 @@ Handle `%pass` card
625625This arm is called to handle responses to `%pass` cards to other agents.
626626It will be one of the following types of response:
627627
628−- `%poke-ack`: acknowledgment (positive or negative) of a poke. If the
629− value is `~`, then the poke succeeded. If the value is `[~ tang]`,
628+- `%poke-ack`: acknowledgment (positive or negative) of a poke. If the
629+ value is `~`, then the poke succeeded. If the value is `[~ tang]`,
630630 then the poke failed, and a printable explanation (eg a stack trace)
631631 is given in the `tang`.
632632
@@ -716,7 +716,7 @@ This arm is called to handle responses for `%pass` cards to vanes.
716716`wire` is the wire from the `++gift` that triggered `++on-arvo`.
717717
718718`sign` is the response from the vane. The list of possible responses from the
719−vanes is statically defined in sys/zuse.hoon (grep for `++ sign-arvo`).
719+vanes is statically defined in sys/zuse.hoon (grep for `++ sign-arvo`).
720720
721721#### Returns
722722
@@ -761,9 +761,9 @@ List of cards and new agent.
761761Handle error.
762762
763763If an error happens in `+on-poke`, the crash report goes into the
764−`%poke-ack` response. Similarly, if an error happens in
764+`%poke-ack` response. Similarly, if an error happens in
765765`+on-subscription`, the crash report goes into the `%watch-ack`
766−response. If a crash happens in any of the other handlers, the report
766+response. If a crash happens in any of the other handlers, the report
767767is passed into this arm.
768768
769769#### Accepts
@@ -821,9 +821,9 @@ subscription content for all subscribers on a given path.
821821```
822822
823823`(list path)` is a list of the paths to send the update on. If no path is
824− given, then the update is only given to the program that instigated the
825− request. Typical use of this mode is in `+on-watch` to give an initial update
826− to a new subscriber to get them up to date.
824+given, then the update is only given to the program that instigated the
825+request. Typical use of this mode is in `+on-watch` to give an initial update
826+to a new subscriber to get them up to date.
827827
828828`cage` is a cage of the subscription update.
829829
@@ -938,7 +938,7 @@ This note is given to subscribe to an application at a path
938938
939939Unsubscribe from an application.
940940
941− This note is passed to unsubscribe from an application. It should be passed on
941+This note is passed to unsubscribe from an application. It should be passed on
942942the same wire that the corresponding `%watch` note for the subscription was
943943passed on.
944944
content/docs/userspace/gall/gall.md → content/docs/arvo/gall/gall.mdrenamed

The content is the same.

content/docs/arvo/gall/overview.mddeleted−11
@@ -1,11 +0,0 @@
1−+++
2−title = "Overview"
3−weight = 1
4−template = "doc.html"
5−+++
6−
7−**Gall** is the application-management [vane](/docs/glossary/vane). Userspace apps –⁠ daemons, really –⁠ are started, stopped, and sandboxed by Gall. Gall provides developers with a consistent interface for connecting their app to [Arvo](/docs/arvo/arvo). It allows applications and other vanes to send messages to applications and subscribe to data streams. Messages coming into Gall are routed to the intended application, and the response comes back along the same route. If the intended target is on another [ship](/docs/glossary/ship), Gall will route it behind the scenes through [Ames](/docs/arvo/ames/ames) to the other ship.
8−
9−Gall is located at `/home/sys/vane/gall.hoon` within Arvo.
10−
11−For more details, see the [userspace](/docs/userspace/gall/gall) section.
content/docs/arvo/iris/example.md+1−1
@@ -4,7 +4,7 @@ weight = 4
44template = "doc.html"
55+++
66
7−Here we'll look at a simple example of fetching a remote HTTP resource with Iris. We'll use the following thread, which you can save in the `/ted` directory of your `%home` desk:
7+Here we'll look at a simple example of fetching a remote HTTP resource with Iris. We'll use the following thread, which you can save in the `/ted` directory of your `%base` desk:
88
99`iris-thread.hoon`
1010
content/docs/arvo/jael/examples.md+3−3
@@ -32,7 +32,7 @@ Here we'll look at subscribing to private key updates from Jael. We'll use a thr
3232(pure:m !>(~))
3333```
3434
35−Save the above thread in the `/ted` directory of your `%home` desk and `|commit %home`.
35+Save the above thread in the `/ted` directory of your `%base` desk and `|commit %base`.
3636
3737Now let's run the thread:
3838
@@ -106,7 +106,7 @@ Here's a thread that performs these actions:
106106
107107Note this example was performed on a comet as a fake ship won't have the required information in Jael.
108108
109−Save the above thread in the `/ted` directory and `|commit %home`. The thread takes a `ship` as an argument, so we'll try to subscribe to pubkey updates for `~dopzod`. Let's run the thread:
109+Save the above thread in the `/ted` directory and `|commit %base`. The thread takes a `ship` as an argument, so we'll try to subscribe to pubkey updates for `~dopzod`. Let's run the thread:
110110
111111```
112112> -sub-pub ~dopzod
@@ -197,7 +197,7 @@ Here's a simple thread that'll pass Jael a `%turf` `task`, take the `%turf` `gif
197197(pure:m !>(~))
198198```
199199
200−Save in in the `/ted` directory of your ship and `|commit %home`. Next, let's try running it:
200+Save in in the `/ted` directory of your ship and `|commit %base`. Next, let's try running it:
201201
202202```
203203> -turf
content/docs/arvo/overview.md+2−2
@@ -45,7 +45,7 @@ Arvo is designed to avoid the usual state of complex event networks: event spagh
4545
4646Unlike any other popular operating system, it is possible for a single human to understand every aspect of Arvo due to its compact size. The entire Urbit stack is around 30,000 lines of code, while the Arvo kernel is only about 1,000 lines of code. We strive for a small codebase because the difficulty in administering a system is roughly proportional to the size of its code base.
4747
48−## An operating function
48+## An operating function {#operating-function}
4949
5050Arvo is the world's first _purely functional_ operating system, and as such it may reasonably be called an _operating function_. The importance of understanding this design choice and its relevance to the overarching goal cannot be understated. If you knew only a single thing about Arvo, let it be this.
5151
@@ -543,7 +543,7 @@ As of this writing, we have nine vanes, which each provide the following service
543543- [Eyre](/docs/arvo/eyre/eyre): an http server. Unix sends http messages to `%eyre`, and `%eyre` produces http messages in response.
544544- [Ford](/docs/arvo/ford/ford): a build system also utilized for marks
545545 (file types) and debugging.
546−- [Gall](/docs/userspace/gall/gall): manages our userspace applications. `%gall` keeps state and manages subscribers.
546+- [Gall](/docs/arvo/gall/gall): manages our userspace applications. `%gall` keeps state and manages subscribers.
547547- [Iris](/docs/arvo/iris/iris): an http client.
548548- [Jael](/docs/arvo/jael/jael): storage for Azimuth information.
549549
content/docs/arvo/reference/filesystem.md+65−31
@@ -4,34 +4,39 @@ weight = 20
44template = "doc.html"
55+++
66
7−Here we describe what each of the primary folders present in the `%home` `desk`
8−are used for. This organization is merely a convention, and the exact location
9−of any file does not affect its operation. That being said, some [Ford
10−runes](/docs/arvo/ford/ford) are designed with this structure in mind, and
11−applications such as dojo look in specific folders for code to run. Furthermore,
12−this organization is not perfectly adhered to - sometimes you may find structure
13−definitions in `/lib`, for example.
7+Here we describe what each of the primary folders present in a Clay desk. This
8+organization is merely a convention, and the exact location of any file does not
9+affect its operation. That being said, some [Ford runes](/docs/arvo/ford/ford)
10+are designed with this structure in mind, and applications such as dojo and
11+spider look in specific folders for code to run. Furthermore, this organization
12+is not perfectly adhered to - sometimes you may find structure definitions in
13+`/lib`, for example.
1414
1515- `/app` contains userspace applications, i.e. [Gall
16− agents](/docs/userspace/gall/gall).
17−- `/gen` contains generators. Many applications make use of generators, but
18− also each generator in this folder may be run from dojo using `+`. For
19− example, `/gen/foo/hoon` is run with `+foo`.
16+ agents](/docs/arvo/gall/gall).
17+- `/gen` contains generators. Many applications make use of generators, but also
18+ each generator in this folder may be run from dojo using `+`. For example,
19+ `/gen/foo/hoon` in the `%base` desk is run with `+foo`. Generators on desks
20+ other than `%base` can be run with `+desk!generator` like `+garden!foo`.
2021- `/lib` contains libraries that may be shared by multiple agents, threads,
2122 generators, etc. However, this is not the location of the standard libraries
2223 (see `/sys`). Libraries are imported from `/lib` with `/+`.
23−- `/mar` contains [mark](/docs/arvo/clay/architecture#marks) definitions.
24+- `/mar` contains [mark](/docs/arvo/clay/marks/marks) definitions.
2425- `/sur` contains shared [structure](/docs/hoon/reference/rune/) definitions.
25− Whenever you expect structures to be used by code across multiple files, it
26− is recommended to place their shared structures in `/sur`. Structures are
26+ Whenever you expect structures to be used by code across multiple files, it is
27+ recommended to place their shared structures in `/sur`. Structures are
2728 imported from `/sur` with `/-`.
28−- `/sys` contains the code that defines the kernel and standard libraries.
29− `/sys/vane` contains the code for the vanes, aka kernel modules. `/sys` is
30− the exception to the rule - structures and functions that are central to
31− Hoon, Arvo, and its vanes, are all located within this folder rather than in
32− `/lib` and `/sur`. See [below](#sys) for more information on `/sys`.
33−- `/ted` contains [threads](/docs/userspace/threads/overview). These may be
34− run from dojo using `-`. For example, `/ted/foo/hoon` is run with `-foo`.
29+- `/sys` contains the code that defines the kernel and standard libraries. Note
30+ that only the `%base` desk should contain these `/sys` files, other desks
31+ omit the directory and instead just depend on `%base`. `/sys/vane` contains
32+ the code for the vanes, aka kernel modules. `/sys` is the exception to the
33+ rule - structures and functions that are central to Hoon, Arvo, and its vanes,
34+ are all located within this folder rather than in `/lib` and `/sur`. See
35+ [below](#sys) for more information on `/sys`.
36+- `/ted` contains [threads](/docs/userspace/threads/overview). These may be run
37+ from dojo using `-`. For example, `/ted/foo/hoon` on the `%base` desk is run
38+ with `-foo`. Threads on desks other than the `%base` desk can be run with
39+ `-desk!thread` like `-garden!foo`.
3540- `/tests` contains unit tests intended to be run using the `test` thread. To
3641 run a particular test `+test-bar` in `/tests/foo.hoon` in dojo, enter `-test %/tests/foo/test-bar ~`. If a file is specified, every test in that file will
3742 run. If a folder is specified, every test in that folder will run.
@@ -39,9 +44,10 @@ definitions in `/lib`, for example.
3944## `/sys` {#sys}
4045
4146`/sys` contains four files: `hoon.hoon`, `arvo.hoon`, `lull.hoon`, and
42−`zuse.hoon`. These are the files used to construct kernelspace. The chain of
43−dependencies is `hoon.hoon` -> `arvo.hoon` -> `lull.hoon` -> `zuse.hoon`. We
44−give a brief description of each of them.
47+`zuse.hoon`. These are the files used to construct kernelspace. Only the `%base`
48+desk contains these files, other desks omit the `/sys` directory and instead
49+just depend on `%base`. The chain of dependencies is `hoon.hoon` -> `arvo.hoon`
50+-> `lull.hoon` -> `zuse.hoon`. We give a brief description of each of them.
4551
4652- `hoon.hoon` contains the Hoon compiler and the [Hoon standard
4753 library](/docs/hoon/reference/stdlib/table-of-contents). The Hoon
@@ -58,12 +64,40 @@ give a brief description of each of them.
5864 of `arvo.hoon`.
5965- `lull.hoon` primarily contains structures shared among the kernel and its
6066 vanes, as well as a few functions. In particular, this includes the
61− definitions of the `card`s utilized by each vane, each of which are
62− documented in their respective documentation. `lull.hoon` is loaded by the
63− kernel during the [larval stage](/docs/arvo/overview#larval-stage-core)
64− in order to prepare to create the vanes. `arvo.hoon` is the subject of `lull.hoon`.
67+ definitions of the `task`s and `gift`s utilized by each vane, each of which
68+ are documented in their respective documentation. `lull.hoon` is loaded by the
69+ kernel during the [larval stage](/docs/arvo/overview#larval-stage-core) in
70+ order to prepare to create the vanes. `arvo.hoon` is the subject of
71+ `lull.hoon`.
6572- `zuse.hoon` is the Arvo standard library. It consists primarily of functions
6673 shared by the kernel and vanes, such as the ones related to
67− [cryptography](/docs/arvo/reference/cryptography). `zuse.hoon` is loaded
68− by the larval kernel following `lull.hoon`. `lull.hoon` is the subject of
69− `zuse.hoon`. Then `zuse` is the subject of the vanes.
74+ [cryptography](/docs/arvo/reference/cryptography). `zuse.hoon` is loaded by
75+ the larval kernel following `lull.hoon`. `lull.hoon` is the subject of
76+ `zuse.hoon`. Then `zuse` is the subject of the vanes. Some of the functions in
77+ Zuse are documented [here](/docs/hoon/reference/zuse/table-of-contents).
78+
79+## Desks
80+
81+A desk is an independently revision-controlled branch of a ship that uses the
82+Clay filesystem. Each desk contains its own apps, mark definitions, files, and
83+so forth. The basic filesystem structure is the same for all desks, with the
84+exception that only the `%base` desk contains a [`/sys`](#sys) directory.
85+Additionally, there are a handful of special files related to the management of
86+desks and their Gall agents:
87+
88+- `sys.kelvin` - This specifies the version of Arvo the desk is compatible with.
89+ This file is mandatory in all desks.
90+- `desk.bill` - This file specifies the Gall agents on a desk which should be
91+ automatically started when it's installed. This file may be omitted if there
92+ are no agents to start.
93+- `desk.docket-0` - This file configures the tile,
94+ [glob](/docs/userspace/dist/glob) and other metadata for apps with a
95+ front-end. This file may be omitted if the desk does not have a tile or
96+ front-end to be installed. This file is versioned so the number appended may
97+ change in the future as changes to its specification are made. See the [Docket
98+ File](/docs/userspace/dist/docket) documentation for more details.
99+- `desk.ship` - This specifies the original publisher of the desk and is useful
100+ if a desk is being republished. It is optional and may be omitted.
101+
102+For more details of creating and distributing desks, see the
103+[Distribution](/docs/userspace/dist/dist) documentation.
content/docs/azimuth/_index.md+26−7
@@ -6,17 +6,36 @@ template = "sections/docs/chapters.html"
66insert_anchor_links = "right"
77+++
88
9−
10−## [Azimuth](/docs/azimuth/azimuth)
9+### [Azimuth](/docs/azimuth/azimuth)
1110
1211An overview of the Ethereum-based public key infrastructure utilized by Urbit.
1312
14−## [Life and Rift](/docs/azimuth/azimuth)
13+### [Urbit HD Wallet](/docs/azimuth/hd-wallet)
14+
15+Azimuth has its own optional hierarchical deterministic wallet system, often
16+referred to as a "master ticket".
17+
18+### [Data Flow](/docs/azimuth/flow)
19+
20+Diagrams and explanations of how data flows between Bridge and the various
21+components inside Urbit involved with layer 2.
22+
23+### [Azimuth.eth](/docs/azimuth/azimuth-eth)
1524
16−An explanation of how Azimuth keeps track of the most recent set of networking
17−keys necessary to communicate with a ship.
25+A description of the `azimuth.eth` smart contract, which is the data store for
26+Azimuth.
1827
19−## [Advanced Azimuth Tools](/docs/azimuth/advanced-azimuth-tools)
28+### [Ecliptic.eth](/docs/azimuth/ecliptic)
2029
21−Expert-level tooling for generating, signing, and sending Azimuth-related
30+A description of the `ecliptic.eth` smart contract, which is the business logic
31+for `azimuth.eth`. This includes an overview of all function calls available.
32+
33+### [Advanced Azimuth Tools](/docs/azimuth/advanced-azimuth-tools)
34+
35+Expert-level tooling for generating, signing, and sending layer 1 Azimuth-related
2236transactions from within Urbit itself.
37+
38+### [Life and Rift](/docs/azimuth/azimuth)
39+
40+An explanation of how Azimuth indexes networking keys and breaches to keep track
41+of the most recent set of networking keys necessary to communicate with a ship.
content/docs/azimuth/advanced-azimuth-tools.md+82−25
@@ -1,19 +1,43 @@
11+++
22title = "Advanced Azimuth Tools"
3−weight = 4
3+weight = 7
44template = "doc.html"
55+++
66
7−This document outlines some advanced techniques for generating, signing, and sending Azimuth-related transactions from within Urbit itself. It's strongly discouraged to do this unless you're very confident as Azimuth transactions are permanent and will cost ETH to complete. However, until you upload a signed transaction to the blockchain no transaction will take place so it's safe to explore these tools. It will also be very helpful to have at least a rudimentary understanding of Hoon in order to read and modify parts of the code.
8−
9−First you will want to [boot a fakezod](https://urbit.org/using/develop/#creating-a-development-ship). You can do this with your live running ship but at this time this will need you to modify the code so it's best to do this on a ship you can make mistakes on.
10−
11−Be sure to have mounted your home desk so you can easily edit files on it.
12−The first edit that will probably need to be made is in [`app/claz.hoon`](https://github.com/urbit/urbit/blob/85435e9a81e105809d5d381b5d34fae1d4daa3b8/pkg/arvo/app/claz.hoon#L14). The listed url will need to be changed to a valid Ethereum endpoint. infura.io provides an Ethereum API that you can use.
13−
14−The second change that may potentially be needed is to modify the [gas limit](https://github.com/urbit/urbit/blob/85435e9a81e105809d5d381b5d34fae1d4daa3b8/pkg/arvo/app/claz.hoon#L179). This number here is the maximum number of gas units that will be used. In future this will be configurable but for now you may need to change this manually. For a guide to what to set it to you can use the [constants in bridge](https://github.com/urbit/bridge/blob/29f4a14869489481a950a1af53f583d751897444/src/lib/constants.js#L23) as a guide based on what action you are going to be performing. The maximum cost of your transaction will be the maximum gas units multiplied by the gwei you're going to set later. You'll need at least this much in your account.
15−
16−Once you have made these changes be sure to run `|commit %home` to get them into your ship.
7+This document outlines some advanced techniques for generating, signing, and
8+sending Azimuth-related transactions from within Urbit itself. It's strongly
9+discouraged to do this unless you're very confident as Azimuth transactions are
10+permanent and will cost ETH to complete. However, until you upload a signed
11+transaction to the blockchain no transaction will take place so it's safe to
12+explore these tools. It will also be very helpful to have at least a rudimentary
13+understanding of Hoon in order to read and modify parts of the code.
14+
15+These tools are currently only available for layer 1 transactions. Tooling for
16+layer 2 transactions is forthcoming.
17+
18+First you will want to [boot a
19+fakezod](https://urbit.org/using/develop/#creating-a-development-ship). You can
20+do this with your live running ship but at this time this will need you to
21+modify the code so it's best to do this on a ship you can make mistakes on.
22+
23+Be sure to have mounted your home desk so you can easily edit files on it. The
24+first edit that will probably need to be made is in
25+[`app/claz.hoon`](https://github.com/urbit/urbit/blob/85435e9a81e105809d5d381b5d34fae1d4daa3b8/pkg/arvo/app/claz.hoon#L14).
26+The listed url will need to be changed to a valid Ethereum endpoint. infura.io
27+provides an Ethereum API that you can use.
28+
29+The second change that may potentially be needed is to modify the [gas
30+limit](https://github.com/urbit/urbit/blob/85435e9a81e105809d5d381b5d34fae1d4daa3b8/pkg/arvo/app/claz.hoon#L179).
31+This number here is the maximum number of gas units that will be used. In future
32+this will be configurable but for now you may need to change this manually. For
33+a guide to what to set it to you can use the [constants in
34+bridge](https://github.com/urbit/bridge/blob/29f4a14869489481a950a1af53f583d751897444/src/lib/constants.js#L23)
35+as a guide based on what action you are going to be performing. The maximum cost
36+of your transaction will be the maximum gas units multiplied by the gwei you're
37+going to set later. You'll need at least this much in your account.
38+
39+Once you have made these changes be sure to run `|commit %home` to get them into
40+your ship.
1741
1842Next run `|start %claz` after which you'll be able to generate transactions.
1943
@@ -21,27 +45,45 @@ Next run `|start %claz` after which you'll be able to generate transactions.
2145:claz [%generate %/spawn/eth-txs %mainnet author %single %spawn ~ship to]
2246```
2347
24−Here we have an example of generating a transaction to spawn a ship. Something to note is that for this to be successful you'll need to actually have the right to spawn the ship in question. Let's break down the command.
48+Here we have an example of generating a transaction to spawn a ship. Something
49+to note is that for this to be successful you'll need to actually have the right
50+to spawn the ship in question. Let's break down the command.
2551
2652
2753`%generate` is how all commands to `claz` are going to start.
2854
2955`%/spawn/eth-txs` is simply the path for the output file
3056
31−`%mainnet` specifies which network this is going to sent out on. Other options are possible including the test-net `%ropsten`.
57+`%mainnet` specifies which network this is going to sent out on. Other options
58+are possible including the test-net `%ropsten`.
3259
33−`author` here is an Ethereum address that is issuing the transaction. It will need to be written in `@ux` notation, e.g. `0x3b17.d097.d9dd.711e.4ef8.517a.bbf1.8b2b.a643.81fe`.
60+`author` here is an Ethereum address that is issuing the transaction. It will
61+need to be written in `@ux` notation, e.g.
62+`0x3b17.d097.d9dd.711e.4ef8.517a.bbf1.8b2b.a643.81fe`.
3463
35−`%single` specifies what kind of batch that will be created. If you are going to do multiple transactions you will need to either set this to `%more` followed by a _list_ of batches, or generate the next transaction after having submitted the previous one to the blockchain.
64+`%single` specifies what kind of batch that will be created. If you are going to
65+do multiple transactions you will need to either set this to `%more` followed by
66+a _list_ of batches, or generate the next transaction after having submitted the
67+previous one to the blockchain.
3668
37−`[%spawn ~ship to]` is the transaction we want to issue. The arguments are will vary based on the transaction. `~ship` will be the ship to be spawned. `to` is the Ethereum address to spawn the ship to.
69+`[%spawn ~ship to]` is the transaction we want to issue. The arguments are will
70+vary based on the transaction. `~ship` will be the ship to be spawned. `to` is
71+the Ethereum address to spawn the ship to.
3872
39−You will want to read [`/sur/claz.hoon`](https://github.com/urbit/urbit/blob/85435e9a81e105809d5d381b5d34fae1d4daa3b8/pkg/arvo/sur/claz.hoon).
40−This will contain more details about the various kinds of transactions you can perform particularly `++call`
73+You will want to read
74+[`/sur/claz.hoon`](https://github.com/urbit/urbit/blob/85435e9a81e105809d5d381b5d34fae1d4daa3b8/pkg/arvo/sur/claz.hoon).
75+This will contain more details about the various kinds of transactions you can
76+perform particularly `++call`
4177
42−After running this command you should find a csv file at the output path you specified. You can examine this file to learn how they are constructed. You are able to modify the nonces, gas limit and price without changing the functionality of the transaction but it's not important for this guide.
78+After running this command you should find a csv file at the output path you
79+specified. You can examine this file to learn how they are constructed. You are
80+able to modify the nonces, gas limit and price without changing the
81+functionality of the transaction but it's not important for this guide.
4382
44−This file can now be signed and uploaded. At this point, you can transfer this file to an airgapped machine which has your keys, if you want. If you choose to do that you will need to download the `urbit` binary as well as the most recent pill file or a copy of the fakezod pier you have already booted.
83+This file can now be signed and uploaded. At this point, you can transfer this
84+file to an airgapped machine which has your keys, if you want. If you choose to
85+do that you will need to download the `urbit` binary as well as the most recent
86+pill file or a copy of the fakezod pier you have already booted.
4587
4688For this guide, we'll continue on the same ship.
4789
@@ -53,16 +95,31 @@ Run `|start %eth-sender` and then you can use it to sign the transaction file.
5395
5496Let's break this down again.
5597
56−`%sign` is the action we are going to perform here. `eth-sender` can also be used to submit batches of transactions to the network in various ways, but details on that are outside of the scope of this guide.
98+`%sign` is the action we are going to perform here. `eth-sender` can also be
99+used to submit batches of transactions to the network in various ways, but
100+details on that are outside of the scope of this guide.
57101
58102`%/spawn-signed/txt` is the path to the output file.
59103
60−`%/spawn/eth-txs` is the path to the transaction file we generated earlier. It will need to be accessible so don't forget to `|commit %home` if you moved it to a different pier.
104+`%/spawn/eth-txs` is the path to the transaction file we generated earlier. It
105+will need to be accessible so don't forget to `|commit %home` if you moved it to
106+a different pier.
61107
62−`%/mykey/txt` is the path to your private key file. It should contain your private key beginning with 0x and followed by a hex string with no dots, and where capital letters are fine. This file is most likely the reason you will want to use an airgapped machine so that your private key never touches a networked computer. Opsec is left to the reader.
108+`%/mykey/txt` is the path to your private key file. It should contain your
109+private key beginning with 0x and followed by a hex string with no dots, and
110+where capital letters are fine. This file is most likely the reason you will
111+want to use an airgapped machine so that your private key never touches a
112+networked computer. Opsec is left to the reader.
63113
64−`~[40 80]` is a list of gas prices, in gwei; a signed transaction file will be created for each one listed. Here we just specify 40 and 80 gwei. You may want to adjust this list based on current Ethereum network traffic and your time preference for the transactions.
114+`~[40 80]` is a list of gas prices, in gwei; a signed transaction file will be
115+created for each one listed. Here we just specify 40 and 80 gwei. You may want
116+to adjust this list based on current Ethereum network traffic and your time
117+preference for the transactions.
65118
66119Now you should have one file in your pier for each gwei costs.
67120
68−To actually transmit the transaction, paste the contents of one of these files into https://etherscan.io/pushTx or whatever other transmission system you would like to use. **This is the action that will actually cost you ETH and perform the transaction on the network. Only do this step if you want to actually perform the action.**
121+To actually transmit the transaction, paste the contents of one of these files
122+into https://etherscan.io/pushTx or whatever other transmission system you would
123+like to use. **This is the action that will actually cost you ETH and perform
124+the transaction on the network. Only do this step if you want to actually
125+perform the action.**
content/docs/azimuth/azimuth-eth.mdnew file+158
@@ -0,0 +1,158 @@
1++++
2+title = "Azimuth.eth"
3+weight = 5
4+template = "doc.html"
5++++
6+
7+[Azimuth.eth](https://etherscan.io/address/azimuth.eth) is used for storing all
8+data related to Azimuth points and their ownership, and should be considered to
9+be the ledger for Azimuth. This contract is just a data store - it only contains
10+the bare minimum of business logic. See [Ecliptic.eth](/docs/azimuth/ecliptic)
11+for the contract containing the business logic for this ledger. `Azimuth.eth`
12+cannot be modified directly by [galaxy vote](/docs/glossary/upgrade) - they are
13+only eligible to modify the Ecliptic.
14+
15+## Global state {#global}
16+
17+The global state of `Azimuth.eth` is given by the following.
18+
19+```solidity
20+ // points: per point, general network-relevant point state
21+ //
22+ mapping(uint32 => Point) public points;
23+
24+ // rights: per point, on-chain ownership and permissions
25+ //
26+ mapping(uint32 => Deed) public rights;
27+
28+ // operators: per owner, per address, has the right to transfer ownership
29+ // of all the owner's points (ERC721)
30+ //
31+ mapping(address => mapping(address => bool)) public operators;
32+
33+ // dnsDomains: base domains for contacting galaxies
34+ //
35+ // dnsDomains[0] is primary, the others are used as fallbacks
36+ //
37+ string[3] public dnsDomains;
38+```
39+
40+Urbit ID's are formalized as [ERC-721 non-fungible
41+tokens](https://eips.ethereum.org/EIPS/eip-721) and are indexed by a number
42+between `0` and `2^32-1`, e.g. a `uint32`. There are two data structures
43+associated to a given `uint32`: a `Point` and a `Deed`.
44+
45+## `Point`s {#points}
46+
47+A `Point` contains data about networking keys and sponsorship status, arranged
48+in the following `struct`:
49+
50+```solidity
51+ struct Point
52+ {
53+ // encryptionKey: (curve25519) encryption public key, or 0 for none
54+ //
55+ bytes32 encryptionKey;
56+ //
57+ // authenticationKey: (ed25519) authentication public key, or 0 for none
58+ //
59+ bytes32 authenticationKey;
60+ //
61+ // spawned: for stars and galaxies, all :active children
62+ //
63+ uint32[] spawned;
64+ //
65+ // hasSponsor: true if the sponsor still supports the point
66+ //
67+ bool hasSponsor;
68+
69+ // active: whether point can be linked
70+ //
71+ // false: point belongs to prefix, cannot be configured or linked
72+ // true: point no longer belongs to prefix, can be configured and linked
73+ //
74+ bool active;
75+
76+ // escapeRequested: true if the point has requested to change sponsors
77+ //
78+ bool escapeRequested;
79+
80+ // sponsor: the point that supports this one on the network, or,
81+ // if :hasSponsor is false, the last point that supported it.
82+ // (by default, the point's half-width prefix)
83+ //
84+ uint32 sponsor;
85+
86+ // escapeRequestedTo: if :escapeRequested is true, new sponsor requested
87+ //
88+ uint32 escapeRequestedTo;
89+
90+ // cryptoSuiteVersion: version of the crypto suite used for the pubkeys
91+ //
92+ uint32 cryptoSuiteVersion;
93+
94+ // keyRevisionNumber: incremented every time the public keys change
95+ //
96+ uint32 keyRevisionNumber;
97+
98+ // continuityNumber: incremented to indicate network-side state loss
99+ //
100+ uint32 continuityNumber;
101+ }
102+```
103+
104+## `Deed`s {#deeds}
105+
106+A `Deed` says which Ethereum address owns a given `Point` as well as several
107+[proxies](/docs/using/id/proxies) for that `Point`.
108+
109+```solidity
110+struct Deed
111+ {
112+ // owner: address that owns this point
113+ //
114+ address owner;
115+
116+ // managementProxy: 0, or another address with the right to perform
117+ // low-impact, managerial operations on this point
118+ //
119+ address managementProxy;
120+
121+ // spawnProxy: 0, or another address with the right to spawn children
122+ // of this point
123+ //
124+ address spawnProxy;
125+
126+ // votingProxy: 0, or another address with the right to vote as this point
127+ //
128+ address votingProxy;
129+
130+ // transferProxy: 0, or another address with the right to transfer
131+ // ownership of this point
132+ //
133+ address transferProxy;
134+ }
135+```
136+
137+## Other state {#other}
138+
139+Finally, each Ethereum address may set for itself a number of `operators`, as
140+defined and required by the [ERC-721
141+standard](https://ethereum.org/en/developers/docs/standards/tokens/erc-721/).
142+These are for third party brokers/wallets/auctioneers/etc such as
143+[OpenSea](http://opensea.io), which facilitate exchange of ERC-721 tokens.
144+
145+`Azimuth.eth` also contains some other state—`dnsDomains`—which are domain names by
146+which the IP address of a galaxy may be looked up, e.g. `zod.urbit.org` resolves
147+to `35.247.119.159`. This is used for bootstrapping the network from DNS. Three
148+domains may be listed here, but as of today they are all `urbit.org`. This may
149+only be updated by the owner of Ecliptic, but arguably each galaxy ought to be
150+able to set its own domain name and so we do not expect this to remain the case
151+forever.
152+
153+All data in this ledger is stored and processed locally on your ship by the
154+[`%azimuth` Gall agent](/docs/azimuth/flow#azimuth), including [layer
155+2](/docs/azimuth/l2/layer2) data. Because state transitions resulting from layer 2
156+transactions are not included in this ledger, in general the local store will
157+differ from what is kept in `Azimuth.eth`.
158+
content/docs/azimuth/azimuth.md+126−137
@@ -5,145 +5,134 @@ template = "doc.html"
55aliases = ["/docs/learn/azimuth"]
66+++
77
8−Azimuth is a general-purpose public-key infrastructure (PKI) on the Ethereum blockchain, used as a platform for _Urbit identities_. You need such an identity to use the Arvo network.
8+Azimuth is a general-purpose public-key infrastructure (PKI) on the Ethereum
9+blockchain, used as a platform for _Urbit identities_. You need such an identity
10+to use the Arvo network.
911
10−The primary way to interact with Azimuth is through our [Bridge](https://github.com/urbit/bridge) application and the node libraries that it depends on, [azimuth-js](https://github.com/urbit/azimuth-js) and [urbit-key-generation](https://github.com/urbit/urbit-key-generation). Take a look at the source and play around, or see [Getting Started](/getting-started/).
12+The primary way to interact with Azimuth is through
13+[Bridge](https://github.com/urbit/bridge) and the node libraries that it depends
14+on, [azimuth-js](https://github.com/urbit/azimuth-js) and
15+[urbit-key-generation](https://github.com/urbit/urbit-key-generation). Take a
16+look at the source and play around, or see [Getting Started](/getting-started/).
1117
1218## Arvo vs. Azimuth
1319
14−Urbit is a project, not a single computer system. It has multiple components: Arvo, the operating system; and Azimuth, the identity system. Let's compare them.
20+Urbit is a project, not a single computer system. It has multiple components:
21+Arvo, the operating system, and Azimuth, the identity system. Let's compare
22+them.
23+
24+**Arvo** is an operating system that provides the software for a personal
25+server. These personal servers together constitute the peer-to-peer Arvo
26+network. To make this network work on the social level, Arvo is built to work
27+with a system of scarce and immutable identities.
28+
29+**Azimuth** is the public-key infrastructure built to be a system of scarce and
30+immutable identities. It consists of a suite of [smart contracts on the Ethereum
31+blockchain](https://github.com/urbit/azimuth) as well as [several
32+apps](/docs/azimuth/flow) run locally on your urbit. Togeter, they determine
33+which Ethereum addresses own which Urbit ID's as well as the public keys needed
34+to communicate with those ID's. All identity-related operations, such as
35+transfers, are governed by Azimuth. Azimuth isn't built strictly for Arvo -- the
36+smart contracts on Ethereum are sufficient to be used as a generalized identity
37+system for other projects. Azimuth is considered to be the technical
38+nomenclature for the PKI, while Urbit ID is the common nomenclature.
39+
40+These otherwise-parallel systems meet when you want to connect to the Arvo
41+network. Your Arvo personal server, called your _ship_, needs to be able to
42+prove cryptographically that it is who it says it is. This proof comes in the
43+form of a keyfile, derived from your identity, that you use to start your ship.
44+
45+A metaphor might help illustrate the relationship between these two systems: the
46+Arvo network is the neighborhood that you live in; Azimuth is the bank vault
47+that stores the deed to your house.
48+
49+## Smart contracts
50+
51+Azimuth consists of the following smart contracts:
52+
53+ - [Azimuth.eth](https://etherscan.io/address/azimuth.eth)
54+ `0x223c067f8cf28ae173ee5cafea60ca44c335fecb`: contains all on-chain state for
55+ Azimuth. Most notably, ownership and public keys. Can't be modified directly,
56+ you must use the Ecliptic.
57+ - [Ecliptic.eth](https://etherscan.io/address/ecliptic.eth):
58+ `0x9ef27de616154FF8B38893C59522b69c7Ba8A81c ` is used as an interface for
59+ interacting with your points on-chain. Allows you to configure keys, transfer
60+ ownership, etc.
61+ - [Polls](https://etherscan.io/address/0x7fecab617c868bb5996d99d95200d2fa708218e4):
62+ `0x7fecab617c868bb5996d99d95200d2fa708218e4` registers votes by the Galactic
63+ Senate on proposals. These can be either static documents or Ecliptic
64+ upgrades.
65+ - [Linear Star
66+ Release](https://etherscan.io/address/0x86cd9cd0992f04231751e3761de45cecea5d1801):
67+ facilitates the release of blocks of stars to their owners over a period of
68+ time.
69+ - [Conditional Star
70+ Release](https://etherscan.io/address/0x8c241098c3d3498fe1261421633fd57986d74aea):
71+ `0x8c241098c3d3498fe1261421633fd57986d74aea` facilitates the release of
72+ blocks of stars to their owners based on milestones.
73+ - [Claims](https://etherscan.io/address/0xe7e7f69b34d7d9bd8d61fb22c33b22708947971a):
74+ `0xe7e7f69b34d7d9bd8d61fb22c33b22708947971a` allows point owners to make
75+ claims about (for example) their identity, and associate that with their
76+ point.
77+ - [Censures](https://etherscan.io/address/0x325f68d32bdee6ed86e7235ff2480e2a433d6189):
78+ `0x325f68d32bdee6ed86e7235ff2480e2a433d6189` simple reputation management,
79+ allowing galaxies and stars to flag points for negative reputation.
80+ - [Delegated
81+ Sending](https://etherscan.io/address/0xf6b461fe1ad4bd2ce25b23fe0aff2ac19b3dfa76):
82+ enables network-effect like distributing of planets.
83+
84+Walkthroughs of some of the smart contracts are linked to [below](#other).
85+
86+## Naive rollups
87+
88+In 2021, Tlon introduced a new system to Azimuth intended to reduce gas costs
89+for working with Urbit ID and friction associated with using cryptocurrency in
90+general called **naive rollups**, often referred to as **layer 2** or L2. This system
91+allows batches of Azimuth transactions to be submitted together as a single
92+transaction using an Urbit node known as a "roller". The PKI state transitions
93+resulting from these transactions are computed locally by your urbit rather than
94+by the [Ethereum Virtual Machine](https://ethereum.org/en/developers/docs/evm/).
95+
96+Due to the dramatically reduced cost, Tlon offers their own roller that is free
97+for ordinary public use. This enables new users to get started with a permanent
98+Azimuth identity without any prior knowledge of Ethereum, cryptocurrency, or
99+blockchains. However, anybody can run a roller, and even using your own ship as
100+a roller to submit single transactions results in significant savings.
101+
102+A casual overview of the naive rollups system can be found on the
103+[blog](/blog/rollups). Developers are encouraged to read our Layer 2
104+documentation, starting with the [Layer 2 Overview](/docs/azimuth/l2/layer2).
105+
106+## Other resources {#other}
107+
108+### [Urbit HD Wallet](/docs/azimuth/hd-wallet)
109+
110+Azimuth has its own optional hierarchical deterministic wallet system, often
111+referred to as a "master ticket".
112+
113+### [Data Flow](/docs/azimuth/flow)
114+
115+Diagrams and explanations of how data flows between Bridge and the various
116+components inside Urbit involved with Azimuth and L2.
117+
118+### [Azimuth.eth](/docs/azimuth/azimuth-eth)
119+
120+A description of the `azimuth.eth` smart contract, which is the data store for
121+Azimuth.
122+
123+### [Ecliptic.eth](/docs/azimuth/ecliptic)
124+
125+A description of the `ecliptic.eth` smart contract, which is the business logic
126+for `azimuth.eth`. This includes an overview of all function calls available.
127+
128+### [Advanced Azimuth Tools](/docs/azimuth/advanced-azimuth-tools)
129+
130+Expert-level tooling for generating, signing, and sending layer 1 Azimuth
131+transactions from within Urbit itself.
132+
133+### [Life and Rift](/docs/azimuth/azimuth)
134+
135+An explanation of how Azimuth indexes networking keys revisions and breaches to
136+keep track of the most recent set of networking keys necessary to communicate
137+with a ship.
15138
16−**Arvo** is an operating system that provides the software for a personal server. These personal servers together constitute the peer-to-peer Arvo network. To make this network work on the social level, Arvo is built to work with a system of scarce and immutable identities.
17−
18−**Azimuth** is the public-key infrastructure built to be such a system. A suite of smart-contracts on the Ethereum blockchain, Azimuth determines which Ethereum addresses own which Azimuth identities, called _Urbit identities_, or just _identities_. All identity-related operations, such as transfers, are governed at this layer. But Azimuth isn't built strictly for Arvo -- it could be used as a generalized identity system for other projects.
19−
20−These otherwise-parallel systems meet when you want to connect to the Arvo network. Your Arvo personal server, called your _ship_, needs to be able to prove cryptographically that it is who it says it is. This proof comes in the form of a keyfile, derived from your identity, that you use to start your ship.
21−
22−A metaphor might help illustrate the relationship between these two systems: the Arvo network is the neighborhood that you live in; Azimuth is the bank vault that stores the deed to your house.
23−
24−## The Urbit HD Wallet
25−
26−Owners of Urbit identities need safeguards that allow for the use of Urbit without jeopardizing cryptographic ownership of their assets. Toward this end, we created the **Urbit Hierarchical Deterministic (HD) Wallet** for the storage of identities. The Urbit HD Wallet is not one key-pair, but a system of related key-pairs that each have distinct powers, from setting networking keys for communicating in the Arvo network to transferring ownership of identities.
27−
28−The Urbit HD Wallet's derivation paths have a hierarchical structure, so that
29−keys with different powers can be physically separated. A "master ticket" can
30−[re-derive the entire wallet](#hd-wallet-generation) in case of loss. The
31−encryption and authentication keys that identities ships use to sign messages
32−within the network are also derived from the wallet.
33−
34−Another HD wallet option you may wish to utilize to store your Urbit are hardware
35−wallets such as Trezor or Ledger. We compare this method to the Urbit HD wallet
36−[below](#hardware-hd-wallet).
37−
38−Urbit HD wallets are composed of the following items, which are each assigned to their own individual Ethereum key-pairs.
39−
40−### Master Ticket
41−
42−Think of your master ticket like a very high-value password. The master ticket is the secret code from which all of your other keys are derived. Technically, your master ticket is seed entropy. You should never share it with anyone, and store it very securely. This ticket can derive all of your other keys: your ownership key and all of the related proxies.
43−
44−### Ownership Address
45−
46−An ownership address has all rights over the assets deeded to it. These rights are on-chain actions described and implemented in [Ecliptic](/docs/glossary/ecliptic), Azimuth's suite of governing smart-contracts.
47−
48−### Proxies
49−
50−Proxy addresses allow you to execute non-ownership related actions like spawning child identities, voting, and setting networking keys without jeopardizing the keys you've designated with ownership rights. Setting proxy rights is optional, but it is recommended for on-chain actions you will execute more frequently.
51−
52−- **Management Proxy**
53−
54− Can configure or set Arvo networking keys and conduct sponsorship related
55− operations.
56−
57−- **Voting Proxy**
58−
59− Galaxies only. Galaxies are the part of the [Galactic Senate](/docs/glossary/senate), and this means
60− they can cast votes on new proposals including changes to Ecliptic.
61−
62−- **Spawn Proxy**
63−
64− For stars and galaxies only. Can create new child identities.
65−
66−### HD wallet generation
67−
68−Your Urbit HD wallet is generated from a `@q` seed called `T`, which looks
69−something like `~sampel-ticket-bucbel-sipnem`. This is the string known as your
70−"Master Ticket" that you input into Bridge to sign in. This is put through a
71−series of algorithms that ultimately generate your keys and the Ethereum addresses at which they are stored.
72−
73−![](https://media.urbit.org/fora/proposals/UP-8.jpg)
74−
75−First, your `@q` is converted into a numeric value `E` as an intermediary step
76−by adding [salt](<https://en.wikipedia.org/wiki/Salt_(cryptography)>). Then by
77−adding additional salts, `E` is converted into a set of BIP39 seed phrases -
78−these are 24 word mnemonic sequences used to generate Ethereum wallets. You end up
79−with one seed phrase for each proxy associated with your ship, and these seed
80−phrases are then used to generate Ethereum wallets.
81−
82−One of the wallets will store your Azimuth point, an [ERC-721](#erc-721) token,
83−which will be known as your ownership address. Bridge then automatically uses
84−your ownership address to assign the other proxies to the other wallets
85−generated.
86−
87−### ERC-721
88−
89−Most Ethereum tokens use the ERC-20 standard for smart contracts. Urbit identities
90−are, however, essentially different from most Ethereum tokens, due to identities not
91−being fungible. Since any two stars will handle social-networking realities in a
92−different way, they will carry a different reputation.
93−
94−The ERC-721 standard, having been made specifically to provide a smart-contract
95−interface for non-fungible assets, serves our needs well. This is the standard
96−that we use for deeding Urbit identities.
97−
98−Identities, and all of their blockchain operations, are governed by Ecliptic. Ecliptic is an Ethereum smart-contract that governs identity state and the
99−ownership, spawn, management, and voting rights affiliated with your identities.
100−
101−For the technical implementation details, take a look at Azimuth's
102−[Github repository](https://github.com/urbit/azimuth).
103−
104−## Hardware HD wallet
105−
106−You may also store your Urbit using a hardware HD wallet such as a Trezor or
107−Ledger. This option is used instead of a master ticket - it is a totally
108−separate process from that outlined above. How hardware wallets work are
109−outside of the scope of this document, but here we explain how you may utilize
110−your hardware wallet in a similar fashion to the Urbit HD wallet.
111−
112−A hardware HD wallet is generated from a seed phrase that should be thought of
113−as analogous to the `@q` `T` used to generate the Urbit HD wallet in the above
114−diagram. This seed phrase is a human readable sequence of words that may be used
115−to generate private keys to a near-limitless number of wallets created by adding
116−salt. Some hardware
117−wallets also allow an additional passphrase to go into the generation of these
118−wallets. The seed phrase and passphrase should be considered equal in
119−value to the master ticket `T`- never share these with anyone!
120−
121−In order to use your hardware wallet as your Urbit wallet, you first need to
122−generate a set of addresses on which you would like to store your Azimuth point
123−and proxies. Consult your wallet vendor on how to do this. Then login to Bridge
124−using your current method (likely a master ticket) and transfer ownership to the
125−wallet address you generated on your hardware wallet for ownership.
126−
127−Next, login to Bridge using your hardware wallet. While Bridge supports Trezor
128−and Ledger natively, this may require using Metamask as an intermediary anyways,
129−depending on which firmware you are running. Then [accept the
130−transfer](/using/id/using-bridge#accept-your-transfer). Your Azimuth
131−point is now stored on your hardware wallet.
132−
133−To finish the process, use Bridge to set your management, voting, and spawn
134−proxies to the other addresses you generated as applicable. You are now using
135−your hardware HD wallet in an analogous fashion to the Urbit HD wallet.
136−
137−## Heightened security practices
138−
139−A common security pattern is to have "hot" and "cold" wallets. For higher value
140−points such as stars and galaxies, you may consider having your ownership
141−address live on a "cold" wallet that never touches an
142−internet-connected computer, and the various proxies on a "hot" wallet that is
143−permitted to connect to internet-connected devices. This could be accomplished
144−with multiple hardware wallets, a combination of paper and hardware wallet, a
145−hardware cold wallet and Metamask hot wallet, etc.
146−
147−One tool useful for this setup is `claz`, located at `app/claz.hoon`. `claz` is
148−used for making and signing Bridge transactions from an offline computer. A
149−guide to using `claz` is forthcoming.
content/docs/azimuth/ecliptic.mdnew file+436
@@ -0,0 +1,436 @@
1++++
2+title = "Ecliptic.eth"
3+weight = 6
4+template = "doc.html"
5++++
6+
7+[Ecliptic.eth](https://etherscan.io/address/ecliptic.eth) holds the business
8+logic for the ledger kept by `Azimuth.eth`. It may be modified by [galaxy
9+vote](/docs/glossary/upgrade). This determines things such as what the various
10+proxies are capable of, how keys are changed, or verifying that a request is
11+valid.
12+
13+`Ecliptic.eth` uses external contracts such as
14+[Azimuth.eth](/docs/azimuth/azimuth-eth) and
15+[Polls](https://github.com/urbit/azimuth/blob/master/contracts/Polls.sol) for
16+data storage so that it can easily be replaced in case the logic needs to be
17+changed without affecting the data. These data contracts are owned by
18+`Ecliptic.eth`, and this ownership is passed to the new Ecliptic contract
19+whenever it is replaced. Thus it is advised for clients to not store Ecliptic's
20+contract address directly, but instead ask the `Azimuth.eth` contract for its
21+`owner` attribute to ensure that transactions are sent to the latest Ecliptic
22+contract. Alternatively, the [ENS](https://ens.domains/) name `Ecliptic.eth`
23+will always resolve to the latest Ecliptic.
24+
25+You can read about [Urbit's first
26+upgrade](https://github.com/urbit/azimuth/pull/35) to Ecliptic, which occurred
27+in the summer of 2021, [here](https://urbit.org/blog/first-contract). The
28+[second](https://github.com/urbit/azimuth/pull/43) occurred later in the year
29+and consisted of several small modifications to ready the PKI for the
30+introduction of [naive rollups](/docs/azimuth/l2/layer2).
31+
32+`Ecliptic.eth` implements the [ERC-721](https://eips.ethereum.org/EIPS/eip-721)
33+interface for non-fungible tokens, as well as the
34+[ERC-165](https://eips.ethereum.org/EIPS/eip-165) standard for interface
35+detection.
36+
37+There are currently [28 functions](#write) which may be called to write to
38+the Ecliptic, and [17 functions](#read) to read data from the Ecliptic. Many of these
39+have a corresponding [layer 2 action](/docs/azimuth/l2/l2-actions), and/or can be
40+performed using [Bridge](/using/id/using-bridge). We note these facts where
41+applicable.
42+
43+## Write functions {#write}
44+
45+Here we briefly describe each function in `Ecliptic.eth` which allows one to write
46+data to Ethereum. These can be called using
47+[Etherscan](https://etherscan.io/address/ecliptic.eth#writeContract), but
48+the most common functions may be called from within Bridge.
49+
50+We only document here the write functions specific to `Ecliptic.eth` and not the
51+standard functions that are part of the ERC-721 or ERC-165 interfaces.
52+
53+### `Point`s interface
54+
55+These functions are available to each owner of a
56+[`Point`](/docs/azimuth/azimuth-eth#points), and a subset of them are available
57+to its [proxies](#proxies). All of these actions may be performed from Bridge.
58+
59+#### `configureKeys`
60+
61+```solidity
62+ function configureKeys(uint32 _point,
63+ bytes32 _encryptionKey,
64+ bytes32 _authenticationKey,
65+ uint32 _cryptoSuiteVersion,
66+ bool _discontinuous)
67+```
68+
69+Configure `_point` with network public keys `_encryptionKey`,
70+`_authenticationKey`, and corresponding `_cryptoSuiteVersion`, incrementing the
71+`Point`'s [`keyRevisionNumber`](/docs/azimuth/azimuth-eth#points) if the keys
72+have changed and `continuityNumber` number if `_discontinuous` is set to true
73+(see [Life and Rift](/docs/azimuth/life-and-rift)).
74+
75+Corresponds to the layer 2 `%configure-keys` action.
76+
77+#### `spawn`
78+
79+```solidity
80+ function spawn(uint32 _point, address _target)
81+```
82+
83+Spawn `_point`, then either give, or allow `_target` to take, ownership of `_point`.
84+
85+If `_target` is the `:msg.sender`, `_target` owns the `_point` right away.
86+otherwise, `_target` becomes the transfer proxy of `_point`.
87+
88+Requirements:
89+ - `_point` must not be active
90+ - `_point` must not be a planet with a galaxy prefix
91+ - `_point`'s prefix must be linked and under its spawn limit
92+ - `:msg.sender` must be either the owner of `_point`'s prefix, or an authorized spawn proxy for it
93+
94+Corresponds to the layer 2 `%spawn` action.
95+
96+#### `transferPoint`
97+
98+```solidity
99+ function transferPoint(uint32 _point, address _target, bool _reset)
100+```
101+
102+Transfer `_point` to `_target`, clearing all permissions data and keys if
103+`_reset` is true. `_reset` set to makes this transaction a
104+[breach](/using/id/guide-to-breaches), and thus this action increments the
105+[`continuityNumber`](/docs/azimuth/azimuth-eth#points) of `_point`, and usually
106+the `keyRevisionNumber` as well (see [Life and
107+Rift](/docs/azimuth/life-and-rift)).
108+
109+Requirements:
110+ - `:msg.sender` must be either `_point`'s current owner, authorized to transfer
111+ `_point`, or authorized to transfer the current owner's points (i.e. is
112+ listed as an ERC-721 operator in [`operators`](/docs/azimuth/azimuth-eth#other)).
113+ - `_target` must not be the zero address.
114+
115+Corresponds to the layer 2 `%transfer-point` action.
116+
117+#### `escape`
118+
119+```solidity
120+ function escape(uint32 _point, uint32 _sponsor)
121+```
122+
123+Request escape as `_point` to `_sponsor`.
124+
125+If an escape request is already active, this overwrites the existing request.
126+
127+Requirements:
128+ - `:msg.sender` must be the owner or manager of `_point`,
129+ - `_point` must be able to escape to `_sponsor` as per to `canEscapeTo()`
130+
131+ Corresponds to the layer 2 `%escape` action.
132+
133+#### `cancelEscape`
134+
135+```solidity
136+ function cancelEscape(uint32 _point)
137+```
138+
139+Cancel the currently set escape for `_point`.
140+
141+Corresponds to the layer 2 `%cancel-escape` action.
142+
143+#### `adopt`
144+
145+```solidity
146+ function adopt(uint32 _point)
147+```
148+
149+As the relevant sponsor, accept the `_point`.
150+
151+Requirements:
152+ - `:msg.sender` must be the owner or management proxy
153+ of `_point`'s requested sponsor
154+
155+Corresponds to the layer 2 `%adopt` action.
156+
157+#### `reject`
158+
159+```solidity
160+ function reject(uint32 _point)
161+```
162+
163+As the relevant sponsor, deny the `_point`'s `adopt` request.
164+
165+Requirements:
166+ - `:msg.sender` must be the owner or management proxy
167+ of `_point`'s requested sponsor
168+
169+Corresponds to the layer 2 `%reject` action.
170+
171+#### `detach`
172+
173+```solidity
174+ function detach(uint32 _point)
175+```
176+
177+As the `_sponsor`, stop sponsoring the `_point`.
178+
179+Requirements:
180+ - `:msg.sender` must be the owner or management proxy
181+ of `_point`'s current sponsor
182+
183+Corresponds to the layer 2 `%detach` action.
184+
185+Unlike all other layer 1 actions, layer 1 sponsors may use a layer 1 `detach` on
186+a layer 2 sponsee. See the [Layer 2](/docs/azimuth/l2/layer2#sponsorship)
187+section for more detail. The detach action available in Bridge is a layer 2
188+action, so a layer 1 detach must be done
189+[manually](https://etherscan.io/address/ecliptic.eth#writeContract).
190+
191+### Proxy management {#proxies}
192+
193+These functions are used to manage the various
194+[proxies](/docs/using/id/proxies). All of these actions may be performed from Bridge.
195+
196+#### `setManagementProxy`
197+
198+```solidity
199+ function setManagementProxy(uint32 _point, address _manager)
200+```
201+
202+Configure the management proxy for `_point`.
203+
204+The management proxy may perform "reversible" operations on
205+behalf of the owner. This includes public key configuration and
206+operations relating to sponsorship.
207+
208+Requirements:
209+ - `:msg.sender` must be either `_point`'s current owner or the management proxy.
210+
211+Corresponds to the layer 2 `%set-management-proxy` action.
212+
213+#### `setSpawnProxy`
214+
215+```solidity
216+ function setSpawnProxy(uint16 _prefix, address _spawnProxy)
217+```
218+
219+Give `_spawnProxy` the right to spawn points with the prefix `_prefix` using the
220+`spawn` function.
221+
222+Requirements:
223+ - `:msg.sender` must be either `_point`'s current owner or the spawn proxy.
224+
225+Corresponds to the layer 2 `%set-spawn-proxy` action.
226+
227+#### `setVotingProxy`
228+
229+```solidity
230+ function setVotingProxy(uint8 _galaxy, address _voter)
231+```
232+
233+Configure the voting proxy for `_galaxy`.
234+
235+The voting proxy is allowed to start polls and cast votes on the point's behalf.
236+
237+Requirements:
238+ - `:msg.sender` must be either `_point`'s current owner or the voting proxy.
239+
240+There is no corresponding layer 2 action since voting must occur on layer 1.
241+
242+#### `setTransferProxy`
243+
244+```solidity
245+ function setTransferProxy(uint32 _point, address _transferProxy)
246+```
247+
248+Give `_transferProxy` the right to transfer `_point`.
249+
250+Requirements:
251+ - `:msg.sender` must be either `_point`'s current owner, an operator for the
252+ current owner, or the transfer proxy.
253+
254+Corresponds to the layer 2 `%set-transfer-proxy` action.
255+
256+### Poll actions
257+
258+Most of these are functions only available to galaxies. They are related to
259+[voting](/docs/glossary/voting). As voting does not occur on layer 2, there are
260+no corresponding layer 2 actions for poll actions.
261+
262+Upgrade and document polls last for 30 days, or once a majority is achieved,
263+whichever comes first. If a majority (129) of yes or no votes is achieved, the
264+final vote cast in favor of the winning option also triggers `updateUpgradePoll`
265+or `updateDocumentPoll` as appropriate. Otherwise, if a quorum of 64 votes is
266+achieved, with a majority voting for yes, and the 30 day voting period has
267+expired, then _any_ Ethereum address may call `updateUpgradePoll` or
268+`updateDocumentPoll` as appropriate.
269+
270+#### `startUpgradePoll`
271+
272+```solidity
273+ function startUpgradePoll(uint8 _galaxy, EclipticBase _proposal)
274+```
275+
276+As `_galaxy`, start a poll for the Ecliptic upgrade `_proposal`.
277+
278+Requirements:
279+ - `:msg.sender` must be the owner or voting proxy of `_galaxy`,
280+ - the `_proposal` must expect to be upgraded from this specific
281+ contract, as indicated by its `previousEcliptic` attribute.
282+
283+This action must be performed manually - it is not available in Bridge.
284+
285+#### `startDocumentPoll`
286+
287+```solidity
288+ function startDocumentPoll(uint8 _galaxy, bytes32 _proposal)
289+```
290+
291+As `_galaxy`, start a poll for the `_proposal`. Document polls last for 30 days,
292+or once a majority is achieved, whichever comes first.
293+
294+The `_proposal` argument is the keccak-256 hash of any arbitrary
295+document or string of text.
296+
297+This action must be performed manually - it is not available in Bridge.
298+
299+#### `castUpgradeVote`
300+
301+```solidity
302+ function castUpgradeVote(uint8 _galaxy,
303+ EclipticBase _proposal,
304+ bool _vote)
305+```
306+
307+As `_galaxy`, cast a `_vote` on the Ecliptic upgrade `_proposal`.
308+
309+`_vote` is true when in favor of the proposal, false otherwise.
310+
311+This action may be performed from Bridge.
312+
313+#### `castDocumentVote`
314+
315+```solidity
316+ function castDocumentVote(uint8 _galaxy, bytes32 _proposal, bool _vote)
317+```
318+
319+As `_galaxy`, cast a `_vote` on the `_proposal`.
320+
321+`_vote` is true when in favor of the proposal, false otherwise.
322+
323+This action may be performed from Bridge.
324+
325+#### `updateUpgradePoll`
326+
327+```solidity
328+ function updateUpgradePoll(EclipticBase _proposal)
329+```
330+
331+Check whether the `_proposal` has achieved majority, upgrading to it if it has.
332+Any Ethereum address may call this function.
333+
334+This action eiher occurs as part of a vote that achieves a majority, or must be
335+performed manually. It is not available in Bridge.
336+
337+#### `updateDocumentPoll`
338+
339+```solidity
340+ function updateDocumentPoll(bytes32 _proposal)
341+```
342+
343+Check whether the `_proposal` has achieved majority. Any Ethereum address may
344+call this function.
345+
346+This action eiher occurs as part of a vote that achieves a majority, or must be
347+performed manually. It is not available in Bridge.
348+
349+### Contract owner operations
350+
351+The following functions may only be performed by the owner of the contract.
352+There are only two such functions, one of which is to spawn galaxies. As all
353+galaxies have already been spawned, it is no longer of any use. Thus only
354+`setDnsDomains` is relevant today.
355+
356+#### `createGalaxy`
357+
358+```solidity
359+ function createGalaxy(uint8 _galaxy, address _target)
360+```
361+
362+Grant `_target` ownership of the `_galaxy` and register it for voting. Galaxies
363+are given by a `uint8`, and since all 256 galaxies have already been spawned,
364+this function has no valid arguments.
365+
366+#### `setDnsDomains`
367+
368+```solidity
369+ function setDnsDomains(string _primary, string _secondary, string _tertiary)
370+```
371+
372+Sets 3 DNS domains by which galaxy IP addresses may be looked up as part of the
373+bootstrap process to get on the network. Currently, all three domains are `urbit.org`.
374+
375+## Read functions {#read}
376+
377+Here we briefly describe each function in the Ecliptic which allows one to read
378+data from the contract. These can be called using
379+[Etherscan](https://etherscan.io/address/ecliptic.eth#readContract).
380+
381+We only document here the read functions specific to Ecliptic and not the
382+standard functions that are part of the ERC-721 or ERC-165 interfaces.
383+
384+#### `depositAddress`
385+
386+This returns the deposit address for [layer 2](/docs/azimuth/l2/layer2), which is
387+`0x1111111111111111111111111111111111111111`. Ships sent to this address are
388+controlled on layer 2 instead of via Ecliptic.
389+
390+#### `canEscapeTo`
391+
392+```solidity
393+ function canEscapeTo(uint32 _point, uint32 _sponsor)
394+```
395+
396+Returns a `bool` that is true if `_point` could try to escape to `_sponsor`.
397+
398+#### `azimuth`
399+
400+Returns the address of the [Azimuth.eth](/docs/azimuth/azimuth-eth) contract: `0x223c067f8cf28ae173ee5cafea60ca44c335fecb`.
401+
402+#### `claims`
403+
404+Returns the address of the
405+[Claims](https://etherscan.io/address/0xe7e7f69b34d7d9bd8d61fb22c33b22708947971a)
406+contract: `0x1df4ea30e0b1359c9692a161c5f30cd1a6b64ebf`.
407+
408+#### `polls`
409+
410+Returns the address of the
411+[Polls](https://etherscan.io/address/0x7fecab617c868bb5996d99d95200d2fa708218e4)
412+contract: `0x7fecab617c868bb5996d99d95200d2fa708218e4`.
413+
414+#### `previousEcliptic`
415+
416+Returns the address of the previous Ecliptic address.
417+
418+#### `getSpawnLimit`
419+
420+```solidity
421+ function getSpawnLimit(uint32 _point, uint256 _time)
422+```
423+
424+Returns a `uint32` that is the total number of children the `_point` is allowed
425+to spawn at `_time`.
426+
427+There is no limit for galaxies. Instead, for most galaxies, all stars have
428+already been spawned and placed into one of the lockup contracts: [Linear Star
429+Release](https://etherscan.io/address/0x86cd9cd0992f04231751e3761de45cecea5d1801)
430+and [Conditional Star
431+Release](https://etherscan.io/address/0x8c241098c3d3498fe1261421633fd57986d74aea).
432+
433+Beginning in 2019, stars may spawn at most 1024 planets. This limit doubles
434+every subsequent year until the maximum is reached. However, this limit is not
435+currently implemented on [Layer 2](/docs/azimuth/l2/layer2).
436+
content/docs/azimuth/flow.mdnew file+232
@@ -0,0 +1,232 @@
1++++
2+title = "Azimuth Data Flow"
3+weight = 4
4+template = "doc.html"
5++++
6+
7+This document summarizes the various components involved with Azimuth and
8+how they communicate with each other. This also constitutes an explanation for
9+how Urbit implements the data flow of naive rollups.
10+
11+## Bridge
12+
13+The primary way in which users interact with Azimuth is via
14+[Bridge](https://bridge.urbit.org). Bridge is responsible for collecting
15+transactions from users, signing them, and forwarding them to a roller via an
16+HTTP API.
17+
18+## Azimuth
19+
20+Azimuth was originally defined as a set of smart contracts on Ethereum that
21+defines the [state](/docs/azimuth/azimuth-eth) and [business
22+logic](/docs/azimuth/ecliptic) of the PKI for layer 1. With the introduction of
23+naive rollups, this has also come to include the set of components used for
24+dealing with the PKI within Urbit, as now the complete PKI state is stored
25+offchain (though this state is derived entirely from on-chain data). The
26+following sections outline what each component is responsible for and how it
27+communicates with the others.
28+
29+The Gall agents involved with Azimuth are summarized as follows:
30+ - [`%azimuth`](#azimuth) - obtains and holds PKI state.
31+ - [`%azimuth-rpc`](#azimuth-rpc) - JSON RPC-API for `%azimuth`.
32+ - [`%eth-watcher`](#eth-watcher) - Ethereum event log collector.
33+ - [`%roller`](#roller) - submits batches of L2 transactions to Ethereum.
34+ - [`%roller-rpc`](#roller-rpc) - JSON RPC-API for `%roller`.
35+
36+The transaction processing library is [`/lib/naive.hoon`](#naive).
37+
38+### Gall agents
39+
40+#### `%azimuth` {#azimuth}
41+
42+`%azimuth`, located at `/app/azimuth.hoon`, is a Gall agent and thread handler
43+responsible for finding Azimuth transactions gathered by `%eth-watcher`,
44+keeping track of the PKI state, and exposing that data via scries.
45+
46+The following diagram illustrates `%azimuth`'s and `%eth-watcher`'s role in the system.
47+
48+![Azimuth components](https://media.urbit.org/docs/layer2/l2-azimuth-azimuth.svg)
49+
50+The state held by `%azimuth` is the following.
51+
52+```hoon
53+++ app-state
54+ $: %3
55+ url=@ta
56+ whos=(set ship)
57+ nas=^state:naive
58+ own=owners
59+ logs=(list =event-log:rpc:ethereum)
60+ ==
61+```
62+
63+`whos` is the set of ships currently known by Azimuth. `nas` is the PKI state,
64+as defined in [`naive.hoon`](#naive). `own` is a `jug` of Ethereum addresses and
65+the set of ships owned by that address. `logs` is a list of all Azimuth-related
66+Ethereum event logs known by the ship.
67+
68+Scries can be inferred from the `+on-peek` arm:
69+
70+```hoon
71+++ on-peek
72+ |= =path
73+ ^- (unit (unit cage))
74+ ?+ path (on-peek:def path)
75+ [%x %logs ~] ``noun+!>(logs.state)
76+ [%x %nas ~] ``noun+!>(nas.state)
77+ [%x %dns ~] ``noun+!>(dns.nas.state)
78+ [%x %own ~] ``noun+!>(own.state)
79+ ==
80+```
81+
82+#### `%azimuth-rpc` {#azimuth-rpc}
83+
84+`%azimuth-rpc`, located at `app/azimuth-rpc.hoon`, is a JSON RPC-API for getting
85+`point` and `dns` data from the Azimuth PKI state kept by `%azimuth`.
86+
87+#### `%eth-watcher` {#eth-watcher}
88+
89+`%eth-watcher`, located at `/app/eth-watcher.hoon`, is responsible for listening
90+to an Ethereum node and collecting event logs from it. It is general-purpose and
91+not particular to Azimuth. It sends collected transactions to `+on-agent` in
92+`%azimuth`, which then obtains the resulting PKI state transitions by passing them to
93+[`naive.hoon`](#naive).
94+
95+[![Eth-watcher](https://media.urbit.org/docs/layer2/roller-agents.png)](https://media.urbit.org/docs/layer2/roller-agents.png)
96+
97+#### `%roller` {#roller}
98+
99+`%roller`, stored at `/app/roller.hoon`, is a Gall agent responsible for
100+collecting and submitting batches of layer 2 transactions to the Ethereum
101+blockchain. Among other things, it keeps
102+track of a list of pending transactions to be sent, transactions it has sent
103+that are awaiting confirmation, history of transactions sent organized by
104+Ethereum address, and when the next batch of transactions will be sent. See also
105+[Rollers](/docs/azimuth/l2/roller) for more information on the roller.
106+
107+The following diagram illustrates how the roller interacts with Bridge and
108+Ethereum at a high level.
109+
110+[![High level overview](https://media.urbit.org/docs/layer2/l2-high.png)](https://media.urbit.org/docs/layer2/l2-high.png)
111+
112+The relationship between the roller and other agents is outlined in the
113+following diagram.
114+
115+[![Roller](https://media.urbit.org/docs/layer2/roller-agents.png)](https://media.urbit.org/docs/layer2/roller-agents.png)
116+
117+`%roller` has a number of scries available, intended primarily to
118+display data to the end user in Bridge. They can be inferred from the `+on-peek`
119+arm:
120+
121+```hoon
122+ ++ on-peek
123+ |= =path
124+ ^- (unit (unit cage))
125+ |^
126+ ?+ path ~
127+ [%x %pending ~] ``noun+!>(pending)
128+ [%x %pending @ ~] (pending-by i.t.t.path)
129+ [%x %tx @ %status ~] (status i.t.t.path)
130+ [%x %history @ ~] (history i.t.t.path)
131+ [%x %nonce @ @ ~] (nonce i.t.t.path i.t.t.t.path)
132+ [%x %spawned @ ~] (spawned i.t.t.path)
133+ [%x %next-batch ~] ``atom+!>(next-batch)
134+ [%x %point @ ~] (point i.t.t.path)
135+ [%x %points @ ~] (points i.t.t.path)
136+ [%x %config ~] config
137+ [%x %chain-id ~] ``atom+!>(chain-id)
138+ ==
139+```
140+
141+This app is not responsible for communicating with Bridge via HTTP. Instead, that is
142+handled by `%roller-rpc`. The scries are also communicated to Bridge via
143+`%roller-rpc`.
144+
145+#### `%roller-rpc`
146+
147+`%roller-rpc`, stored at `/app/roller-rpc.hoon`, is a very simple Gall app responsible for receiving HTTP RPC-API
148+calls, typically sent from other Urbit ID users via Bridge. It then translates
149+these API calls from JSON to a format understood by `%roller` and
150+forwards them to `%roller`. This app
151+does not keep any state - its only purpose is to act as an intermediary between
152+Bridge and `%roller`. See [here](/docs/azimuth/l2/layer2-api) for more
153+information on the JSON RPC-API.
154+
155+### `naive.hoon` {#naive}
156+
157+`/lib/naive.hoon` consists of a gate whose sample is a `verifier`, `chain-id=@ud`,
158+`state`, and `input`, which outputs a cell of `[effects state]`. This is the
159+transition function which updates the state of the PKI stored in `%azimuth`
160+which handles state transitions caused by both layer 1 and layer 2 transactions.
161+A high-level overview of how `naive.hoon` functions can be found
162+[here](/docs/azimuth/l2/layer2#layer-2).
163+
164+A `verifier` is a gate whose sample is of the form `[dat=octs v=@ r=@ s=@]` and
165+which returns `(unit address)`:
166+
167+```hoon
168++$ verifier $-([dat=octs v=@ r=@ s=@] (unit address))
169+```
170+
171+The `verifier` in use by `naive.hoon` runs the keccak hash function on `dat` to
172+verify that `dat` is data signed by the ECDSA signature given by the `[v r s]`
173+tuple, according to the format for signed transactions outlined in the
174+[bytestring format](/docs/azimuth/l2/bytestring) documentation.
175+
176+`chain-id` is the ID used by the Ethereum blockchain, which is `1337`. See [bytestring
177+format](/docs/azimuth/l2/bytestring) for more information. This is used so that
178+e.g. transactions on the Ropsten test network cannot be replayed on the mainnet.
179+
180+`state` is the current state of the PKI. This is structured similarly to the
181+state held in [Azimuth.eth](/docs/azimuth/azimuth-eth), but will differ in
182+general since `state` takes into account layer 2 transactions as well. See the
183+[Layer 2 Overview](/docs/azimuth/l2/layer2#state) for more on how PKI state is handled.
184+
185+```hoon
186++$ state
187+ $: =points
188+ =operators
189+ dns=(list @t)
190+ ==
191++$ points (tree [ship point])
192+++ point
193+ $: :: domain
194+ ::
195+ =dominion
196+ ::
197+ :: ownership
198+ ::
199+ $= own
200+ $: owner=[=address =nonce]
201+ spawn-proxy=[=address =nonce]
202+ management-proxy=[=address =nonce]
203+ voting-proxy=[=address =nonce]
204+ transfer-proxy=[=address =nonce]
205+ ==
206+ ::
207+ :: networking
208+ ::
209+ $= net
210+ $: rift=@ud
211+ =keys
212+ sponsor=[has=? who=@p]
213+ escape=(unit @p)
214+ ==
215+ ==
216++$ dominion ?(%l1 %l2 %spawn)
217++$ operators (jug address address)
218+```
219+
220+`points` should be self-explanatory if you are already familiar with the
221+structure of [Azimuth.eth](/docs/azimuth/azimuth-eth). The only new addition is
222+`dominion`, whose value says
223+whether a ship is on layer 1, layer 2, or layer 1 with a layer 2 spawn proxy.
224+See [Layer 2 actions](/docs/azimuth/l2/l2-actions) for an overview of how
225+`dominion` determines the PKI actions available to a ship.
226+
227+`operators` already existed on layer 1 and are defined as a part of the [ERC-721
228+standard](https://eips.ethereum.org/EIPS/eip-721).
229+
230+`dns` is a list of DNS entries by which galaxy IP addresses may be looked up. At
231+present, this is always `~['urbit.org' 'urbit.org' 'urbit.org']`.
232+
content/docs/azimuth/hd-wallet.mdnew file+137
@@ -0,0 +1,137 @@
1++++
2+title = "Urbit HD Wallet"
3+weight = 3
4+template = "doc.html"
5++++
6+
7+Owners of Urbit identities need safeguards that allow for the use of Urbit
8+without jeopardizing cryptographic ownership of their assets. Toward this end,
9+we created the **Urbit Hierarchical Deterministic (HD) Wallet** for the storage
10+of identities. The Urbit HD Wallet is not one key-pair, but a system of related
11+key-pairs that each have distinct powers, from setting networking keys for
12+communicating in the Arvo network to transferring ownership of identities.
13+
14+The Urbit HD Wallet's derivation paths have a hierarchical structure, so that
15+keys with different powers can be physically separated. A "master ticket" can
16+[re-derive the entire wallet](#hd-wallet-generation) in case of loss. The
17+encryption and authentication keys that identities ships use to sign messages
18+within the network are also derived from the wallet.
19+
20+Another HD wallet option you may wish to utilize to store your Urbit are
21+hardware wallets such as Trezor or Ledger. We compare this method to the Urbit
22+HD wallet [below](#hardware-hd-wallet).
23+
24+Urbit HD wallets are composed of the following items, which are each assigned to
25+their own individual Ethereum key-pairs.
26+
27+### Master Ticket
28+
29+Think of your master ticket like a very high-value password. The master ticket
30+is the secret code from which all of your other keys are derived. Technically,
31+your master ticket is a cryptographic seed. You should never share it with anyone, and
32+store it very securely. This ticket can derive all of your other keys: your
33+ownership key and all of the related proxies.
34+
35+### Ownership Address
36+
37+An ownership address has all rights over the assets deeded to it. These rights
38+are on-chain actions described and implemented in
39+[Ecliptic](/docs/glossary/ecliptic), Azimuth's suite of governing
40+smart-contracts.
41+
42+### Proxies
43+
44+Each permanent Urbit ID can designate one or more
45+[proxies](/docs/using/id/proxies), which are Ethereum addresses capable of a
46+limited subset of Urbit ID transactions, such as spawning planets or rotating
47+keys. The HD wallet automatically generates additional addresses utilized as
48+proxies according to what is appropriate for your Urbit ID.
49+
50+### HD wallet generation
51+
52+Your Urbit HD wallet is generated from a `@q` seed called `T`, which looks
53+something like `~sampel-ticket-bucbel-sipnem`. This is the string known as your
54+"Master Ticket" that you input into Bridge to sign in. This is put through a
55+series of algorithms that ultimately generate your keys and the Ethereum
56+addresses at which they are stored.
57+
58+![](https://media.urbit.org/fora/proposals/UP-8.jpg)
59+
60+First, your `@q` is converted into a numeric value `E` as an intermediary step
61+by adding [salt](<https://en.wikipedia.org/wiki/Salt_(cryptography)>). Then by
62+adding additional salts, `E` is converted into a set of BIP39 seed phrases -
63+these are 24 word mnemonic sequences used to generate Ethereum wallets. You end
64+up with one seed phrase for each proxy associated with your ship, and these seed
65+phrases are then used to generate Ethereum wallets.
66+
67+One of the wallets will store your Azimuth point, an [ERC-721](#erc-721) token,
68+which will be known as your ownership address. Bridge then automatically uses
69+your ownership address to assign the other proxies to the other wallets
70+generated.
71+
72+### ERC-721
73+
74+Most Ethereum tokens use the ERC-20 standard for smart contracts. Urbit
75+identities are, however, essentially different from most Ethereum tokens, due to
76+identities not being fungible. Since any two stars will handle social-networking
77+realities in a different way, they will carry a different reputation.
78+
79+The ERC-721 standard, having been made specifically to provide a smart-contract
80+interface for non-fungible assets, serves our needs well. This is the standard
81+that we use for deeding Urbit identities.
82+
83+Identities, and all of their blockchain operations, are governed by Ecliptic.
84+Ecliptic is an Ethereum smart-contract that governs identity state and the
85+ownership, spawn, management, and voting rights affiliated with your identities.
86+
87+For the technical implementation details, take a look at Azimuth's [Github
88+repository](https://github.com/urbit/azimuth).
89+
90+## Hardware HD wallet
91+
92+You may also store your Urbit using a hardware HD wallet such as a Trezor or
93+Ledger. This option is used instead of a master ticket - it is a totally
94+separate process from that outlined above. How hardware wallets work are outside
95+of the scope of this document, but here we explain how you may utilize your
96+hardware wallet in a similar fashion to the Urbit HD wallet.
97+
98+A hardware HD wallet is generated from a seed phrase that should be thought of
99+as analogous to the `@q` `T` used to generate the Urbit HD wallet in the above
100+diagram. This seed phrase is a human readable sequence of words that may be used
101+to generate private keys to a near-limitless number of wallets created by adding
102+salt. Some hardware wallets also allow an additional passphrase to go into the
103+generation of these wallets. The seed phrase and passphrase should be considered
104+equal in value to the master ticket `T`- never share these with anyone!
105+
106+In order to use your hardware wallet as your Urbit wallet, you first need to
107+generate a set of addresses on which you would like to store your Azimuth point
108+and proxies. Consult your wallet vendor on how to do this. Then login to Bridge
109+using your current method (likely a master ticket) and transfer ownership to the
110+wallet address you generated on your hardware wallet for ownership.
111+
112+Next, login to Bridge using your hardware wallet. While Bridge supports Trezor
113+and Ledger natively, this may require using Metamask as an intermediary anyways,
114+depending on which firmware you are running. Then [accept the
115+transfer](/using/id/using-bridge#accept-your-transfer). Your Azimuth point is
116+now stored on your hardware wallet.
117+
118+To finish the process, use Bridge to set your management, voting, and spawn
119+proxies to the other addresses you generated as applicable. You are now using
120+your hardware HD wallet in an analogous fashion to the Urbit HD wallet.
121+
122+## Heightened security practices
123+
124+A common security pattern is to have "hot" and "cold" wallets. For higher value
125+points such as stars and galaxies, you may consider having your ownership
126+address live on a "cold" wallet that never touches an internet-connected
127+computer, and the various proxies on a "hot" wallet that is permitted to connect
128+to internet-connected devices. This could be accomplished with multiple hardware
129+wallets, a combination of paper and hardware wallet, a hardware cold wallet and
130+Metamask hot wallet, etc. See the [User Manual](/using/id/hd-wallet) for
131+concrete suggestions on security practices.
132+
133+One tool useful for this setup is `claz`, located at `app/claz.hoon`. `claz` is
134+used for making and signing Bridge transactions from an offline computer. A
135+guide to using `claz` is available [here](/docs/azimuth/advanced-azimuth-tools).
136+
137+
content/docs/azimuth/l2/_index.mdnew file+35
@@ -0,0 +1,35 @@
1++++
2+title = "Layer 2"
3+weight = 800
4+sort_by = "weight"
5+template = "sections/docs/chapters.html"
6+insert_anchor_links = "right"
7++++
8+
9+Documentation of the technical details of naive rollups, our Layer 2 solution
10+for the reduction of Urbit ID gas prices and friction associated with the usage
11+of cryptocurrency.
12+
13+### [Layer 2 Overview](/docs/azimuth/l2/layer-2)
14+
15+A high-level technical description of the functionality of the naive rollups
16+"Hoon smart contract" and associated apps, such as Bridge and the roller.
17+
18+### [Layer 2 Actions](/docs/azimuth/l2/l2-actions)
19+
20+An exhaustive list of what Azimuth actions can be performed for any given tuple
21+`(ship rank, layer 2 status)`.
22+
23+### [Transaction Format](/docs/azimuth/l2/bytestring)
24+
25+The bytestring format for layer 2 transactions and batches.
26+
27+### [Rollers](/docs/azimuth/l2/roller)
28+
29+How rollers work.
30+
31+### [Roller HTTP RPC API](/docs/azimuth/l2/layer2-api)
32+
33+Documentation on the HTTP RPC API used for Urbit to communicate with Bridge to
34+manage layer 2 transactions.
35+
content/docs/azimuth/l2/bytestring.mdnew file+201
@@ -0,0 +1,201 @@
1++++
2+title = "Transaction Format"
3+weight = 8
4+template = "doc.html"
5++++
6+
7+This document gives the bytestring format for layer 2 transactions and batches.
8+
9+[Recall](/docs/azimuth/l2/layer2.md) that a layer 2 transaction is a compact
10+representation of an Azimuth action (format given below), along with a 65-byte
11+ECDSA signature. A `batch` is an atom that is a concatenation of one or more
12+layer 2 transactions and associated signatures. This atom is what is posted on
13+the Ethereum blockchain by a roller.
14+
15+We remark that each transaction from a given ship in a batch needs a separate
16+signature, since data such as the nonce are not included in the transaction but
17+are used in the signature. Thus a ship cannot submit multiple transactions with
18+a single signature for all of them - a different signature is needed for each
19+transaction.
20+
21+## Byte format
22+
23+We describe the byte format of a `batch` and its components in the following.
24+All atoms described here are read by the parser as little-endian - i.e. it reads
25+the last digit first and proceeds backwards.
26+
27+For the purposes of concatenation, all atoms are encoded using `octs=(pair @ud
28+@)`, which is a way to represent atoms with a fixed width in order to account
29+for leading zeroes. Here `@ud` will be the length of the atom in bytes, while
30+the `@` is actual atom.
31+
32+### Batches {#batch}
33+
34+A `batch` is an atom that is the concatenation of several raw transactions,
35+which are themselves atoms. `naive.hoon` starts reading the `batch` from the end
36+and working backwards (little-endian). A `batch` looks like:
37+
38+```
39+action-n
40+signature-n
41+action-(n-1)
42+signature-(n-1)
43+...
44+action-2
45+signature-2
46+action-1
47+signature-1
48+```
49+
50+Be careful to distinguish between an "action" and an "unsigned transaction". An
51+action is a short bytestring that describes an Azimuth action as given in the
52+[following section](#actions), while an unsigned transaction is an action plus
53+the nonce, chain ID, header. Actions are what are submitted to Ethereum, while
54+unsigned transactions are what are signed and used as the signatures in the
55+above `batch` format. When `naive.hoon` parses a batch it adds the appropriate
56+nonce, chain ID, and header to a given action and uses that to verify the
57+corresponding signature, rather than just the action itself. This reduces the
58+number of bytes in the batch, making transactions cheaper.
59+
60+### Actions {#actions}
61+
62+The byte format of an action as they appear in a `batch` is as
63+follows. They are parsed by the `+parse-tx` arm in `naive.hoon`.
64+
65+```
66+remainder: arguments
67+7 bits: operation
68+4 bytes: ship sending the transaction
69+5 bits: padding
70+3 bits: proxy
71+```
72+
73+The `proxy` is an atom between `0` and `4`, which corresponds as follows:
74+```
75+%0 %own
76+%1 %spawn
77+%2 %manage
78+%3 %vote
79+%4 %transfer
80+```
81+Note that `%vote` proxies are not supported by layer 2.
82+
83+The ship is its `@p` encoded as an `@`. As we are working with fixed width
84+atoms, the full 4 bytes is used, even if the bit length of the `@p` is shorter.
85+
86+The operation is an atom between `0` and `10` corresponding as follows:
87+
88+```
89+%0 %transfer-point
90+%1 %spawn
91+%2 %configure-keys
92+%3 %escape
93+%4 %cancel-escape
94+%5 %adopt
95+%6 %reject
96+%7 %detach
97+%8 %set-management-proxy
98+%9 %set-spawn-proxy
99+%10 %set-transfer-proxy
100+```
101+
102+Since the operation is represented with 7 bits, to complete the byte the
103+arguments either use the remaining bit as a binary flag or as padding.
104+
105+#### `%transfer-point`
106+
107+```
108+20 bytes: address to transfer to
109+1 bit: breach?
110+```
111+
112+#### `%spawn`
113+
114+As before, the length of the ship argument is always 4 bytes.
115+
116+```
117+20 bytes: address to set transfer proxy of spawned ship to
118+4 bytes: ship to spawn
119+1 bit: padding
120+```
121+
122+#### `%configure-keys`
123+
124+```
125+4 bytes: crypto suite
126+32 bytes: encryption public key
127+32 bytes: authentication public key
128+1 bit: breach?
129+```
130+
131+#### `%escape`, `%cancel-escape`, `%adopt`, `%reject`, `%detach`
132+
133+Each of these actions have the same argument - a single ship. Again, the length
134+of the ship argument is always 4 bytes.
135+
136+```
137+4 bytes: ship
138+1 bit: padding
139+```
140+
141+#### `%set-management-proxy`, `%set-spawn-proxy`, `%set-transfer-proxy`
142+
143+Each of these actions have the same argument - an Ethereum address:
144+
145+```
146+20 bytes: address
147+1 bit: padding
148+```
149+
150+### Unsigned transactions {#unsigned}
151+
152+An unsigned transaction is an atom consisting of the concatentation of an Ethereum signed
153+message header, an Urbit ID header, a chain ID, a nonce, and an action. This has the following format:
154+
155+```hoon
156+%: cad 3
157+ 26^'\19Ethereum Signed Message:\0a'
158+ (met 3 len)^len
159+ 14^'UrbitIDV1Chain'
160+ (met 3 chain-t)^chain-t
161+ 1^':'
162+ 4^nonce
163+ action
164+ ~
165+==
166+```
167+
168+Here `+cad` is a gate in `/lib/tiny.hoon` that concatenates atoms given in `octs` format. The
169+argument `3` is a `bloq` size meaning `2^3=8` bits (one byte), and the head of
170+each cell (which are `octs`) in the arguments that follow is the number of blocks (number of bytes
171+in this scenario) of each entry, with the tail being the actual data.
172+
173+`len` is the length measured in bytes of everything following it except the
174+signature. `chain-t` is the chain ID, which is to distinguish between e.g. the
175+Ethereum test net and main net, to ensure that transaction used in one cannot be
176+rebroadcast on the other (see
177+[EIP-155](https://eips.ethereum.org/EIPS/eip-155)). We note that `len` and
178+`chain-t` are both ASCII decimals (`@t` in Hoon), while `nonce` and `action` are
179+`@ud`s.
180+
181+Again we emphasize that unsigned transactions are _not_ what is submitted in a
182+batch - an [action](#actions) and a [signature](#signatures) are. A ship
183+submitting a layer 2 transaction to a roller signs an unsigned transaction and
184+this signature is included along with the action, which does not include the
185+additional data listed above. When a ship determines whether or not a given
186+layer 2 action is valid, it adds the additional data to the action to form an
187+unsigned transaction and verifies the signature against that.
188+
189+### Signatures {#signatures}
190+
191+The signature is a 65-byte ECDSA signature as described in
192+[EIP-191](https://eips.ethereum.org/EIPS/eip-191) and is compatible with
193+`personal_sign`. The precise format of the signature depends on which wallet was
194+used to sign it. Layer 2 supports all major signature formats, including
195+Metamask, Trezor, Ledger, and others. Signatures in batches are obtained by signing
196+an [unsigned transaction](#unsigned).
197+
198+Because of the format of signatures, it may have leading zeroes resulting in a
199+64-byte signature, and so it is important to use `octs` to ensure that it is
200+interpreted as being 65 bytes.
201+
content/docs/azimuth/l2/l2-actions.mdnew file+183
@@ -0,0 +1,183 @@
1++++
2+title = "Layer 2 Actions"
3+weight = 6
4+template = "doc.html"
5++++
6+
7+There are a total of eleven layer 2 actions, each corresponding to a familiar
8+[layer 1 action](/docs/azimuth/ecliptic): `%transfer-point`, `%spawn`,
9+`%configure-keys`, `%escape`, `%cancel-escape`, `%adopt`, `%reject`, `%detach`,
10+`%set-management-proxy`, `%set-spawn-proxy`, and `%set-transfer-proxy`.
11+Descriptions of what these actions do may be found by searching for them at
12+[Azimuth.eth](/docs/azimuth/azimuth-eth).
13+
14+Once a ship moves to layer 2, the owner will still utilize the same private keys
15+they used before the transfer to perform Azimuth actions. This includes the ownership
16+key as well as proxies. Stars and galaxies may move their spawn proxy to layer 2
17+while otherwise remaining on layer 1, but it is not possible to transfer only
18+the management proxy to layer 2; it may only happen as a side-effect of
19+transferring ownership to layer 2.
20+
21+### Moving a pre-existing ship to L2
22+
23+In order to move your ship from layer 1 to layer 2, transfer ownership of your
24+ship to the address `0x1111111111111111111111111111111111111111`. The easiest
25+way to accomplish this is using [Bridge](/docs/glossary/bridge). The Azimuth
26+smart contracts interpret any ship at this address as being on layer 2.
27+
28+### Dominion
29+
30+Layer 2 Azimuth data for a given ship includes which layer that ship is on. We
31+call this the ship's _dominion_. There are three dominions: `%l1`, `l2`, and
32+`%spawn`. Planets may exist in dominion `%l1` or `%l2`, stars may exist in any
33+of the three dominions, and galaxies may exist in dominion `%l1` or `%spawn`. We
34+detail what this means in each case in the following.
35+
36+### Planets
37+
38+*Permitted dominions:* `%l1`, `%l2`.
39+
40+#### `%l1` planets
41+
42+*Permitted layer 2 actions:*
43+ - owner: `%escape`, `%cancel-escape`
44+ - management proxy: `%escape`, `%cancel-escape`
45+ - transfer proxy: none
46+
47+A planet in dominion `%l1` is said to exist on layer 1, which is the default
48+state for all planets prior to the introduction of naive rollups. In addition to
49+the ordinary layer 1 Azimuth actions a planet can perform, they may also choose to
50+`%escape` or `%cancel-escape` on layer 2 using either their ownership key or
51+[management proxy](/docs/glossary/proxies). See the [layer 2 sponsorship](/docs/azimuth/l2/layer2#sponsorship)
52+section for more information on layer 1 ships performing layer 2
53+sponsorship actions.
54+
55+Layer 1 planets may also move to dominion `%l2` by depositing their ownership to
56+the layer 2 deposit address.
57+
58+#### `%l2` planets
59+
60+*Permitted layer 2 actions:*
61+ - owner: `%transfer-point`, `%configure-keys`,
62+`%escape`, `%cancel-escape`, `%set-management-proxy`, `%set-transfer-proxy`
63+ - management proxy: `%configure-keys`, `%escape`, `%cancel-escape`,
64+`%set-management-proxy`
65+ - transfer proxy: `%transfer-point`, `%set-transfer-proxy`
66+
67+A planet in dominion `%l2` is said to exist on layer 2. A planet may be on layer
68+2 either by previously being a layer 1 planet deposited to the layer 2 address,
69+or by being spawned by a star in dominion `%spawn` or `%l2`, in which case it
70+will always be on layer 2.
71+
72+A layer 2 planet is no longer capable of performing any layer 1 actions, and
73+cannot move to layer 1.
74+
75+### Stars
76+
77+*Permitted dominions:* `%l1`, `%spawn`, `%l2`.
78+
79+#### `%l1` stars
80+
81+*Permitted layer 2 actions:*
82+ - owner: `%escape`, `%cancel-escape`, `%adopt`,
83+`%reject`, `%detach`
84+ - management proxy: `%escape`, `%cancel-escape`, `%adopt`,
85+`%reject`, `%detach`
86+ - spawn proxy: none
87+ - transfer proxy: none
88+
89+A star in dominion `%l1` is said to exist on layer 1, which is the default state
90+for all stars prior to the introduction of naive rollups. In addition to the
91+ordinary Azimuth actions a star can perform, they may also perform any
92+sponsorship-related actions on layer 2.
93+
94+A `%l1` dominion star may move to dominion `%spawn` by depositing its spawn proxy to the
95+layer 2 deposit address, or may move to dominion `%l2` by depositing its ownership
96+to the layer 2 deposit address. Both actions are irreversible.
97+
98+#### `%spawn` stars
99+
100+*Permitted layer 2 actions:*
101+ - owner: `%escape`, `%cancel-escape`, `%adopt`,
102+`%reject`, `%detach`, `%spawn`, `%set-spawn-proxy`
103+ - management proxy: `%escape`,
104+`%cancel-escape`, `%adopt`, `%reject`, `%detach`
105+ - spawn proxy: `%spawn`,
106+`%set-spawn-proxy`
107+ - transfer proxy: none
108+
109+A star in dominion `%spawn` is said to exist on layer 1.
110+
111+A star in dominion `%spawn` may spawn planets directly on layer 2, but will no
112+longer be able to spawn layer 1 planets and will no longer be able to set its
113+spawn proxy on layer 1. All other layer 1 Azimuth actions may still be performed
114+by the star.
115+
116+A star moving from `%l1` to `%spawn` has no effect on sponsorship status of any
117+of its sponsored planets. Moving to `%spawn` from `%l1` is currently
118+irreversible - the only further change to dominion permitted is moving to `%l2`.
119+
120+#### `%l2` stars
121+
122+*Permitted layer 2 actions:*
123+ - owner: `%transfer-point`, `%spawn`, `%configure-keys`, `%escape`,
124+`%cancel-escape`, `%adopt`, `%reject`, `%detach`, `%set-management-proxy`,
125+`%set-spawn-proxy`,`%set-transfer-proxy`
126+ - management proxy: `%escape`,
127+`%cancel-escape`, `%adopt`, `%reject`, `%detach`, `%configure-keys`,
128+`%set-management-proxy`
129+ - spawn proxy: `%spawn`, `%set-spawn-proxy`
130+ - transfer proxy: `%transfer-point`, `%set-transfer-proxy`
131+
132+A star in dominion `%l2` is said to exist on layer 2. A star may exist on layer
133+2 by being deposited to the layer 2 deposit address from layer 1, or by being
134+spawned by a `%spawn` dominion galaxy.
135+
136+A star in dominion `%l2` cannot perform any layer 1 actions.
137+
138+### Galaxies
139+
140+*Permitted dominions:* `%l1`, `%spawn`.
141+
142+#### `%l1` galaxies
143+
144+*Permitted layer 2 actions:*
145+ - owner: `%adopt`, `%reject`, `%detach`
146+ - management proxy: `%adopt`, `%reject`, `%detach`
147+ - spawn proxy: none
148+ - transfer proxy: none
149+ - voting proxy: none.
150+
151+A galaxy in dominion `%l1` is said to exist on layer 1, which is the default state
152+for all galaxies prior to the introduction of naive rollups. In addition to the
153+ordinary Azimuth actions a galaxy can perform, they may also perform any
154+sponsorship-related actions on layer 2. `%l1` galaxies can perform all the usual
155+layer 1 Azimuth actions, and may also perform layer 2 sponsorship actions.
156+
157+A `%l1` dominion galaxy may move to dominion `%spawn` by depositing its spawn proxy to the
158+layer 2 deposit address. This action is irreversible. Note, however that the
159+majority of galaxies already have all of their stars spawned in the [Linear
160+Star Release
161+Contract](https://etherscan.io/address/0x86cd9cd0992f04231751e3761de45cecea5d1801).
162+Layer 2 has no interactions with this contract - all stars released in this
163+manner are `%l1` dominion stars. Moving to the `%spawn` dominion has no effect
164+on sponsorship status.
165+
166+#### `%spawn` galaxies
167+
168+*Permitted layer 2 actions:*
169+ - owner: `%adopt`, `%reject`, `%detach`, `%spawn`,
170+`%set-spawn-proxy`
171+ - management proxy: `%adopt`, `%reject`, `%detach`
172+ - spawn proxy: `%spawn`, `%set-spawn-proxy`
173+ - transfer proxy: none
174+ - voting proxy: none
175+
176+Galaxies may either remain on layer 1, or, similar to stars, they may
177+deposit their spawn proxy to layer 2. They cannot move their ownership,
178+management proxy, or voting proxy to layer 2. However, as with stars,
179+sponsorship actions may be performed on layer 2 using the ownership or
180+management proxies regardless of the dominion status of the galaxy.
181+
182+
183+
content/docs/azimuth/l2/layer2-api.mdnew file+14
@@ -0,0 +1,14 @@
1++++
2+title = "Roller HTTP RPC-API"
3+weight = 10
4+template = "doc.html"
5++++
6+
7+With the introduction of Layer 2 arrived a new set of Gall agents equipped with
8+an HTTP RPC-API primarily intended for interacting with Bridge. The
9+documentation for this API is coming soon.
10+
11+The set of API calls available is summarized in the following diagram.
12+
13+[![JSON RPC-API](https://media.urbit.org/docs/layer2/l2-json-rpc.svg)](https://media.urbit.org/docs/layer2/l2-json-rpc.svg)
14+
content/docs/azimuth/l2/layer2.mdnew file+402
@@ -0,0 +1,402 @@
1++++
2+title = "Layer 2 Overview"
3+weight = 5
4+template = "doc.html"
5++++
6+
7+This document provides technical details on Azimuth's "Layer 2" scaling solution
8+for Azimuth, known more formally as "naive rollups". We focus here primarily on the
9+"Hoon smart contract" located at `/lib/naive.hoon` in your ship's pier, as well
10+as other proximal topics.
11+
12+This is intended for developers that desire a deeper understanding of how this
13+protocol works, how secure it is, and how to extract data from layer 2 to obtain
14+a complete picture of the Arvo network.
15+
16+This is not intended for everyday users who only wish to know how
17+to either transfer their ship to layer 2 or perform layer 2 actions. For that,
18+see ((bridge documentation yet to be written)). For a casual overview of the
19+rationale and functionality of layer 2, please see this [blog
20+post](/blog/rollups). For more information on how Azimuth works more generally,
21+including interactions with Bridge and Ethereum, see the page on [Azimuth data flow](/docs/azimuth/flow).
22+
23+This page is also not where to find instruction on how to run your own "aggregator"/"roller".
24+Documentation for this process is forthcoming. However, this page does contain
25+essential background information for anybody in this category.
26+
27+## Summary
28+
29+Naive rollups were developed in response to rising gas costs for performing
30+Azimuth actions. They also serve the dual purpose of making onboarding easier,
31+as it is now possible to acquire a planet and get on Urbit without any knowledge
32+of Ethereum or cryptocurrency.
33+
34+In this section we give a high-level summary of how naive rollups function and
35+how they affect the end user. Later sections elaborate on this summary.
36+
37+### Layer 1
38+
39+We briefly review how "Layer 1", i.e. the [Azimuth](/docs/glossary/azimuth) smart
40+contract suite, functions. An update to the Azimuth PKI data stored on your urbit
41+occurs with four steps:
42+
43+ 1. A transaction is posted to the Ethereum blockchain.
44+ 2. The [Ethereum Virtual Machine](https://ethereum.org/en/developers/docs/evm/)
45+ calculates the resulting state transition and checks its validity, then
46+ updates the state if it is a valid transition.
47+ 3. Your urbit downloads the new state from an Ethereum node.
48+ 4. Your urbit makes the final decision on whether the new state is valid.
49+
50+By default, step four always succeeds. It has always been possible in theory for
51+your urbit to dispute what it read on Ethereum, but there has never been any
52+reason to do so.
53+
54+### Layer 2 {#layer-2}
55+
56+Layer 1 still functions identically today as it did before naive rollups. Naive
57+rollups work via the following process.
58+
59+ 1. A batch of one or more transactions is posted to the Ethereum blockchain by
60+ an urbit node called a roller or aggregator.
61+ 2. Your urbit downloads the transactions from an Ethereum node.
62+ 3. Your urbit computes the resulting state transitions from the transactions
63+ and checks them for validity.
64+ 4. Your urbit updates its locally stored Azimuth state using state transitions
65+ from the batch that have been deemed valid.
66+
67+ In comparison with Layer 1, the EVM no longer checks the validity or computes
68+ the state transitions for any given transaction. It is now being used solely as
69+ a database of submitted transactions, and the business logic of computing what
70+ these transactions mean has been offloaded to your urbit. Thus we think of
71+ `naive.hoon` as being the first "Hoon smart contract". You could also consider
72+steps 3 and 4 of the Layer 2 process as being a fattening of the trivial step 4
73+ of the layer 1 process.
74+
75+Here we briefly elaborate on the layer 2 steps, but see below for more technical
76+detail.
77+
78+A roller is any urbit node - even a moon, comet, or fakezod will do - to which
79+batches of transactions are submitted. You could use your own ship as a roller
80+if you wanted. The roller collects batches of transactions from whichever
81+parties they choose and submits them to the Ethereum blockchain all at once.
82+We expect this to either happen on a regular interval, or once some minimum
83+threshold of transactions is reached, but the decision on when to submit is
84+ultimately up to the roller.
85+
86+Computing the resulting state transitions obtained from downloaded Ethereum
87+transactions is done using `/lib/naive.hoon`, which is a gate that accepts both layer
88+1 transaction logs and layer 2 batches, and then computes the resulting state
89+transitions and updates the ship's internal Azimuth data held in
90+the Gall agent `/app/azimuth.hoon` accordingly.
91+
92+### Savings in gas costs
93+
94+There are several dimensions by which naive rollups saves on gas over layer 1.
95+They are:
96+
97+ 1. Gas is not spent on instructing the EVM to compute state transitions and
98+ confirm validity.
99+ 2. Layer 2 Azimuth state is not stored on Ethereum, so the only data storage
100+ gas costs is for the transactions themselves.
101+ 3. Layer 2 transactions are written in a highly compressed form. E.g., instead
102+ of calling the spawn action by name, it is simply referred to as action `%1`.
103+ 4. By collecting multiple layer 2 transactions and submitting them as a single
104+ "batch transaction", additional gas savings are achieved by not needing to
105+ duplicate information such as which smart contract the transactions are
106+ intended for.
107+
108+Put together, these create a reduction in gas costs of at least 65x when adding
109+a transaction to a sufficiently large batch (approximately 30 or more
110+transactions). A single transaction submitted as a batch is approximately 5x
111+cheaper, while 10 transaction submitted as a batch is approximately 30x cheaper.
112+Thus using one's own ship to submit a single-transaction batch is still a
113+cost-saving measure.
114+
115+### One way trip
116+
117+Moving to layer 2 is a one-way trip for now. This means that once a ship moves
118+to layer 2, it cannot be moved back to layer 1. We believe it to be technically
119+possible to engineer a return trip, and expect that someday this will be the
120+case, but there are no plans to implement this in the near future.
121+
122+## Interacting with L2
123+
124+Layer 2 ships can perform the same actions on layer 2 that they could on
125+layer 1, but are no longer able to perform any layer 1 actions. Layer 1 ships
126+can also perform a subset of layer 2 actions - namely the ones related to
127+sponsorship.
128+
129+For a complete list of what layer 2 actions each ship rank, layer, and proxy can
130+perform, see [Layer 2 Actions](/docs/azimuth/l2/l2-actions). For an explicit
131+description of the byte format of Layer 2 Ethereum transaction, see [Bytestring format](/docs/azimuth/l2/bytestring).
132+
133+### Sponsorship {#sponsorship}
134+
135+Due to the possibility of sponsors and sponsees existing on different layers,
136+the precise logic of how sponsorship works is complex. However, under common
137+circumstances it is simple.
138+
139+If either the sponsor or sponsee are on layer 2, then sponsorship actions must
140+occur on layer 2. The only exception to this is detaching. A sponsor on layer 1
141+may perform a layer 1 detach action on a layer 2 sponsee, and this will result
142+in the sponsee having no sponsor on layer 1, and layer 2 as well if they were
143+the sponsor on layer 2. This is necessary to simplify the logic, but it also
144+guarantees that there is no hard requirement to ever utilize layer 2. Without
145+this exception, sponsors with sponsees that move to layer 2 would be forced to
146+detach them as a layer 2 action if they wanted to cease sponsorship. This would
147+also have an unacceptable impact on ships owned by [smart contracts](#smart-contracts).
148+
149+If both sponsor and sponsee are on layer 1 then sponsorship actions may occur on
150+either layer. As long as all sponsorship actions betweeen the two parties occur
151+on a single layer, behavior will be as expected.
152+
153+In most cases this is sufficient to understand how sponsorship works. However
154+there are a number of edge cases that make this more complicated that developers
155+may need to concern themselves with in scenarios where layer 1 sponsor and
156+sponsees are mixing layer 1 and layer 2 actions. In the [Sponsorship state
157+transitions](#sponsorship-state-transitions) section below, we give a table that
158+shows how the sponsor and escape status of a ship changes according to which
159+actions are taken.
160+
161+### Smart contracts {#smart-contracts}
162+
163+Smart contracts are unable to own layer 2 ships, and thus cannot sign layer 2
164+transactions. This creates a hard requirement that layer 1 ships be allowed to
165+perform a layer 1 detach operation on a layer 2 ships.
166+
167+## Azimuth state {#state}
168+
169+The introduction of layer 2 presents additional complication in understanding
170+Azimuth state. In order to be precise we define the following terminology:
171+
172+ - _Layer 1 Azimuth state_ refers to the state of Azimuth as reflected on the
173+ Ethereum blockchain. This excludes all layer 2 transactions. Depositing to
174+ layer 2 is considered a layer 1 action, so the layer 1 Azimuth state is aware
175+ of which ships are on layer 2, but is blind to everything that happens to
176+ them afterward.
177+ - _Layer 2 Azimuth state_ refers to the state of Azimuth as stored in
178+ `/app/azimuth.hoon` on your ship. The state here takes into account
179+ transactions that occur on both layers. No distinction between the
180+ layers is made in the state here - e.g. a ship only has one sponsor in Layer 2
181+ Azimuth state, not a layer 1 sponsor and a layer 2 sponsor. This is the state
182+ actually in use by Urbit. Layer 1 Azimuth state is now only an input for
183+ generating Layer 2 Azimuth state, so any time a ship needs to check e.g. the
184+ public key of a ship (regardless of which layer it is on), it will check the
185+ Layer 2 Azimuth state, not the Layer 1 Azimuth state.
186+ - _Layer-2-Only Azimuth state_ refers to the state of Azimuth as reflected
187+ solely by layer 2 transactions. This state is not explicitly stored anywhere,
188+ but is computed as part of the process to create the Layer 2 Azimuth state.
189+ We do not make any further references to this state, but it is important to
190+ keep in mind conceptually.
191+
192+Layer 1 Azimuth state is computed by the Ethereum Virtual Machine. Layer 2
193+Azimuth state is computed by taking in the Layer 1 Azimuth state and modifying
194+it according to layer 2 transactions using `/lib/naive.hoon`. When we are being
195+precise about which state we are referring to we will utilize capitalization as above.
196+
197+Layer 2 Azimuth state is held by the Azimuth Gall app located at
198+`/lib/azimuth.hoon`. Layer 1 and layer 2 state are not held separately - your
199+ship holds only one canonical Azimuth state, generated by parsing both layer 1
200+and layer 2 Ethereum transactions using `/lib/naive.hoon`. It is important to
201+keep in mind that Layer 1 Azimuth state is entirely unaware of Layer 2 Azimuth
202+state. Thus, for instance, the Azimuth PKI on Ethereum (Layer 1 Azimuth state)
203+may claim that the sponsor of `~sampel-palnet` is `~marzod`, while the Azimuth
204+state held on your ship (Layer 2 Azimuth state) claims that the sponsor of
205+`~sampel-palnet` is `~dopzod`. Under this circumstance, this would mean that the
206+sponsor of `~sampel-palnet` was `~marzod` before `~sampel-palnet` was deposited
207+to layer 2, and thus the Azimuth PKI on Ethereum will forever reflect this.
208+
209+For more information on how Azimuth state is handled, including how this
210+integrates with Bridge and Ethereum, see [Azimuth data flow](/docs/azimuth/flow).
211+
212+### Sponsorship state transitions
213+
214+When either a sponsor or sponsee is on layer 2, then all sponsorship actions
215+occur on layer 2 and layer 1 Azimuth state is ignored. The exception to this, as
216+noted [above](#sponsorship), is when a layer 1 sponsor performs a layer 1 detach
217+action on a layer 2 sponsee. Furthermore, any time a ship moves from layer 1 to
218+layer 2, its sponsorship status is automatically maintained in layer 2.
219+
220+The only potentially complicated scenario is when both sponsee and (potential)
221+sponsor exist on layer 1. Then because layer 1 actions can modify layer 2 state,
222+careful consideration is required for interactions that mix the two. If you
223+and your sponsor/sponsee are not mixing layer 1 and layer 2 sponsorship actions
224+between yourselves, then you have nothing to worry about and may safely ignore this
225+section.
226+
227+But, for instance, if both `~sampel-palnet` and `~dopzod` are on layer 1, it is
228+technically possible for `~sampel-palnet` to escape to `~dopzod` on layer 1, and
229+then `~dopzod` can accept the escape on layer 2. This will result in `~dopzod`
230+appearing as the sponsor in the Layer 2 Azimuth state (and thus be
231+`~sampel-palnet`'s "true" sponsor), and the sponsor in the Layer 1 Azimuth state
232+will remain unchanged. While it is difficult to imagine a good reason to do
233+this, developers working with layer 2 need to keep in mind these edge cases and
234+ought to read on.
235+
236+In the following table, columns `E_1` and `S_1` represent the escape status and
237+sponsor of a given ship as reflected by the Layer 1 Azimuth state. Columns `E_2`
238+and `S_2` represent the escape status and sponsor of a given ship as reflected
239+in the Layer 2 Azimuth State. The "true" escape status and sponsor of a ship is
240+always what is listed in the Layer 2 Azimuth state. In other words, at the end
241+of the day, `S_2` is always the sponsor that matters, but layer 1 actions can
242+affect the values of `E_2` and `S_2`.
243+
244+A tar `*` entry represents any value and if an event shows a transition
245+from `*` to `*` that means that value is not altered by the transition. The
246+transitions marked with `!!` are prohibited by the layer 1 Azimuth smart
247+contract and thus never occur. `A1` and `A2` represent two distinct ships.
248+
249+```
250+Event | E_1 | E_2 | S_1 | S_2 | -> | E_1 | E_2 | S_1 | S_2
251+L1-escape A1 | * | * | * | * | -> | A1 | A1 | * | *
252+L1-cancel A1 | ~ | * | * | * | -> !! :: no cancel if not escaping
253+L1-cancel A1 | A1 | * | * | * | -> | ~ | ~ | * | *
254+L1-adopt A1 | A1 | * | * | * | -> | ~ | ~ | A1 | A2
255+L1-adopt A1 | ~ | * | * | * | -> !! :: no adopt if not escaping
256+L1-adopt A1 | A2 | * | * | * | -> !! :: no adopt if not escaping
257+L1-detach A1 | * | * | A1 | A1 | -> | * | * | ~ | ~
258+L1-detach A1 | * | * | A1 | A2 | -> | * | * | ~ | A2
259+L1-detach A1 | * | * | A1 | ~ | -> | * | * | ~ | ~
260+L2-escape A1 | * | * | * | * | -> | * | A1 | * | *
261+L2-cancel A1 | * | * | * | * | -> | * | ~ | * | *
262+L2-adopt A1 | * | A1 | * | * | -> | * | ~ | * | A1
263+L2-adopt A1 | * | A2 | * | * | -> | * | A2 | * | *
264+L2-adopt A1 | * | ~ | * | * | -> | * | ~ | * | *
265+L2-reject A1 | * | A1 | * | * | -> | * | ~ | * | *
266+L2-reject A1 | * | A2 | * | * | -> | * | A2 | * | *
267+L2-reject A1 | * | ~ | * | * | -> | * | ~ | * | *
268+L2-detach A1 | * | * | * | A1 | -> | * | * | * | ~
269+L2-detach A1 | * | * | * | A2 | -> | * | * | * | A2
270+L2-detach A1 | * | * | * | ~ | -> | * | * | * | ~
271+```
272+
273+## Aggregators
274+
275+An "aggregator" or "roller" is any Urbit node that collects signed layer 2
276+transactions (typically via `/app/azimuth-rpc.hoon`), combines them into a
277+"batch", and then submits the batch as an Ethereum transaction. Any urbit can be
278+a roller, including moons, comets, and even fakezods. You can also use your own
279+ship as a roller.
280+
281+Tlon has set up our own roller that is free to use by the community. Using
282+Bridge, a ship may submit X transactions to Tlon's roller per Y period free of
283+charge. Tlon's roller submits on a regular schedule: a submission occurs when a
284+total of A layer 2 transactions have been submitted to it since the the previous
285+submitted Ethereum transaction, or every Z time, whichever occurs first.
286+
287+There are no security risks in utilizing an aggregator. The transactions you
288+submit to it are signed with your private key, and so if an aggregator alters
289+them the signature will no longer match and `naive.hoon` will reject it as an
290+invalid transaction. The worst an aggregator can do is not submit your transaction.
291+
292+## Multi-keyfiles
293+
294+As part of the layer 2 upgrade, Tlon has expanded the role of
295+[keyfiles](/docs/glossary/keyfile). One of our goals with layer 2 was to reduce
296+the amount of friction experienced when getting onto Urbit. The enormous
297+reduction in fees has made a new boot method which allows instantaneous sale of
298+layer 2 planets or stars to be cost effective.
299+
300+The ideal situation would be for the end user to be able to buy or receive a
301+planet and immediately boot it without having to wait for an aggregator to
302+submit a transaction that spawns the planet. In order to bring about this
303+circumstance, "multi-keyfiles" have been introduced.
304+
305+Multi-keyfiles are keyfiles used to boot an urbit for first time that contains
306+more than one set of keys, the purpose of which is to initially utilize one set
307+of keys on a temporary basis, and then the other set of keys soon after. This
308+works as follows. A star owner prespawns a number of layer 2 planets ready to be
309+sold at any time for which they posess the initial key. When a user acquires a
310+planet from a star owner, the star owner immediately hands the initial keys to
311+boot the planet to the buyer. The buyer then queues a transaction at a roller to
312+rotate the keys to a new value only known by the buyer (this step is performed
313+automatically by Bridge). The buyer then downloads a keyfile from Bridge
314+containing both keys and uses that to boot their planet for the first time.
315+After the transaction setting the new keys is submitted by the roller to
316+Ethereum, the purchased planet will automatically switch to them once it reads
317+the corresponding transaction from Ethereum.
318+
319+This process introduces a short period of time in which both the buyer and
320+seller are in possession of the keys of a planet. A malicious seller could
321+theoretically sell a planet to more than one party in this time period. However,
322+they would quickly be found out as two identical ships on the network
323+immediately creates problems, and the seller's reputation would be tarnished.
324+Due to the expense or effort needed to acquire a star, this seems an unlikely
325+scenario as the reward is much less than the cost. Nonetheless, buyers should
326+always make an effort to purchase from a reputable star, as is the case with all
327+transactions in life. If you want to be absolutely sure that you've received the
328+planet, just wait for the batch to be sent and confirmed.
329+
330+Multi-keyfiles were possible before layer 2, but as the cost of configuring keys
331+was comparable to the cost of buying a planet, they were not practical.
332+
333+## Security measures
334+
335+In the process of designing naive rollups, we felt it to be of the utmost
336+importance that there not be any loss in the security of a layer 2 ship over a
337+layer 1 ship. In this section we outline several relevant facets of Urbit as
338+well as particular measures that were taken to ensure that naive rollups were
339+free of bugs and exploits. We think of `naive.hoon` as being the first "Hoon
340+smart contract", and thus its functionality needs to be as rock-solid and
341+guaranteed as the Azimuth Ethereum smart contracts.
342+
343+### Arvo is deterministic
344+
345+Crucial to the functionality of Ethereum smart contracts is that they work the
346+same way every time since the Ethereum Virtual Machine is deterministic.
347+Similarly, as the state of Arvo is evolved via [a single pure
348+function](/docs/arvo/overview#an-operating-function), Arvo is deterministic as
349+well. This property makes it well-suited for cases where side effects are
350+unacceptable such as smart contracts, and thus `naive.hoon` is worthy of the
351+name "Hoon smart contract".
352+
353+### Restricted standard library
354+
355+A standard security practice is to reduce the surface area of attack to be as
356+minimal as possible. One common source of exploits among all programming
357+languages are issues with the standard library of functions, and this is one factor
358+that leads to the existence of multiple implementations of standard library functions for
359+a given programming language. For instance, `glibc` is the most widely used
360+standard library for the C programming language, but sheer size gives a large
361+surface area in which to find exploits. Thus, other standard libraries have been
362+written such as `musl` that are much smaller, and some argue to be more secure
363+at least partially due to fewer lines of code. Hoon is not yet popular enough to have
364+multiple standard library implementations, but `naive.hoon` shucks the usual
365+standard library and so its subject contains only the exact standard library
366+functions needed for it to function. This library is known as `tiny` and is
367+found at `/lib/tiny.hoon`.
368+
369+### Unit tests
370+
371+`naive.hoon` is among the most well-tested software in Urbit. The test suite,
372+which may be run with `-test %/lib/tests/naive ~` from dojo, is larger than any
373+other test suite both in number of lines of code and number of tests. We believe
374+branch coverage to be at or very close to 100%
375+
376+### Nonces
377+
378+In the Layer 2 Azimuth state, each proxy belonging to a given ship (including
379+the ownership "proxy") has a non-negative integer associated to it called a
380+"nonce". Each transaction submitted by a given proxy also have a nonce value. If
381+the current nonce of a proxy in the Layer 2 Azimuth state is `n`, then only a
382+transaction from that proxy with a nonce of `n+1` will be considered valid.
383+Otherwise the transaction is discarded. A valid transaction, by which we
384+mean one in which the nonce and signature are correct, will increment the nonce
385+of the proxy in the Layer 2 Azimuth state by one once processed by `naive.hoon`.
386+Note that "valid transactions" also include ones where the action will fail,
387+such as a planet attempting to `%spawn` another planet. For the purposes of
388+incrementing the nonce, only the nonce and signature matter.
389+
390+The use of nonces prevents "replay attacks", which is when a malicious party collects
391+valid transactions and attempts to resubmit them in order to perform the action
392+again. Since a valid transaction increments the nonce associated to the proxy
393+that submitted it, it is only ever possible for a given transaction to alter the
394+Layer 2 Azimuth state once.
395+
396+The use of nonces also eliminates potential issues caused by submitting a
397+transaction to more than one roller. This might happen if the first roller
398+submitted to is taking too long for your liking, and you want to try again with
399+another. If both rollers end up submitting the transaction, only the first one
400+will succeed, as the second one will be ignored by `naive.hoon` for having the
401+wrong nonce.
402+
content/docs/azimuth/l2/roller.mdnew file+66
@@ -0,0 +1,66 @@
1++++
2+title = "Rollers"
3+weight = 9
4+template = "doc.html"
5++++
6+
7+Here we outline how the naive rollup rollers work. This page is only a quick
8+summary - the full documentation of the API is coming soon.
9+
10+## Overview
11+
12+The following diagram illustrates the most important parts of the plumbing
13+present in the roller.
14+
15+[![Roller internals](https://media.urbit.org/docs/layer2/roller-internal.png)](https://media.urbit.org/docs/layer2/roller-internal.png)
16+
17+We elaborate on the components of this diagram below.
18+
19+## `%roller-rpc`
20+
21+The roller communicates with the outside world via a JSON-RPC API, which is
22+implemented with a Gall agent `%roller-rpc`. This is how Bridge communicates
23+with a roller. See the [RPC
24+documentation](https://documenter.getpostman.com/view/16338962/Tzm3nx7x#5a698656-8e7e-433f-9eff-1c6047b9eace)
25+for detailed information on the API.
26+
27+## `%roller`
28+
29+`%roller` is the Gall agent which collects layer 2 Azimuth **transactions**, which
30+are a concatenation of an
31+[action](/docs/azimuth/l2/bytestrings#actions) and a
32+[signature](/docs/azimuth/l2/bytestrings#signatures) and forms them into
33+[batches](/docs/azimuth/l2/bytestrings#batch) to be submitted periodically to the
34+Ethereum blockchain.
35+
36+### Transaction format
37+
38+See [Bytestring Format](/docs/azimuth/l2/bytestring) for a technical description of
39+how layer 2 transactions are formatted.
40+
41+### Pending transactions
42+
43+`%roller` maintains in its state a list of transactions that have been submitted
44+to it since the most recent roll it submitted to Ethereum. These are referred to as
45+**pending transactions**.
46+
47+### Signing the batch
48+
49+Each pending transaction already includes a signature from its sender, but the roller
50+itself must also sign the entire batch of transactions with its private key to
51+submit it as a single Ethereum transaction. This signed batch is known as a **roll**.
52+
53+### Predicted state
54+
55+Once a roll has been submitted to an Ethereum node, there is a waiting period
56+before a miner includes it in a block.
57+
58+During this waiting period, the roller applies the submitted batch to the
59+locally held Azimuth state to get a predicted state. This predicted state is
60+presented to the user in Bridge, such as to show which points a given address owns.
61+
62+### Timer
63+
64+Each roller may choose to submit rolls on a regular basis, periodically
65+and/or whenever a certain number of pending transactions is reached.
66+
content/docs/azimuth/life-and-rift.md+7−5
@@ -1,6 +1,6 @@
11+++
22title = "Life and Rift"
3−weight = 3
3+weight = 8
44template = "doc.html"
55+++
66
@@ -13,10 +13,12 @@ and [Jael](/docs/arvo/jael/jael-api) to ensure that communication between
1313ships is always done with the most recent set of networking keys, and that
1414networking state is appropriately reset when a breach has occurred.
1515
16−Every ship begins with a `life` and `rift` of 0. For
17−galaxies, stars, and planets, these values are stored in the Azimuth PKI, while
18−for moons, these values are stored by their parent. Comets cannot change their
19−networking keys, nor can they breach, and so their `life` and `rift` are always 0.
16+Every ship begins with a `life` and `rift` of 0. For galaxies, stars, and
17+planets, these values are stored in the [Azimuth
18+PKI](/docs/azimuth/azimuth-eth#points) as `keyRevisionNumber` and
19+`continuityNumber`, while for moons, these values are stored by their parent.
20+Comets cannot change their networking keys, nor can they breach, and so their
21+`life` and `rift` are always 0.
2022
2123You can check your current `life` and `rift` number by running the `+keys our`
2224generator in dojo. You can inspect another ship's `life` and `rift` by running
content/docs/development/develop.md+4−4
@@ -13,7 +13,7 @@ contribute to. At a high level, you can:
1313- [Build clients](#clients), which use Urbit as their back-end to store data and
1414 interact with the network
1515- [Develop agents](#agents), or more precisely [_gall_
16− agents](/docs/userspace/gall/gall), which are written in [Hoon](/docs/hoon/)
16+ agents](/docs/arvo/gall/gall), which are written in [Hoon](/docs/hoon/)
1717 and can best be thought of as microservices
1818- [Contribute to Urbit's core](#core), which involves contributing to Urbit
1919 itself &mdash; either the operating system
@@ -60,8 +60,8 @@ library called `shoe`, which you can learn more about
6060Gall agents can be best thought of as individual services with a
6161statically-typed interface and built-in database. They're written in
6262[Hoon](/docs/hoon/overview) and all conform to a specific
63−[interface](/docs/userspace/gall/gall-api) that's defined by the kernel vane
64−called [Gall](/docs/userspace/gall/gall).
63+[interface](/docs/arvo/gall/gall-api) that's defined by the kernel vane
64+called [Gall](/docs/arvo/gall/gall).
6565
6666Applications built on Urbit utilize a collection of different agents, each of
6767which handle specific functionality. The [Landscape
@@ -70,7 +70,7 @@ to see how this pattern works in practice.
7070
7171If you want to learn how to build gall agents, your best bet is to first [learn
7272the Hoon programming language](/docs/hoon/hoon-school/), and then follow that
73−up with the [Gall guide](/docs/userspace/gall/tutorial).
73+up with the [Gall guide](/docs/userspace/gall-guide).
7474
7575### Contribute to Urbit Core {#core}
7676
content/docs/development/environment.md+269−20
@@ -8,25 +8,7 @@ template = "doc.html"
88This guide covers best practices for preparing your environment to develop
99within the Urbit ecosystem.
1010
11−## Creating a development ship
12−
13−To do work with Hoon, we recommended using a "fake" ship -- one that's not
14−connected to the network.
15−
16−Because such a ship has no presence on the network, you don't need an Azimuth
17−identity. You just need to have [installed the Urbit binary](/getting-started).
18−
19−To create a fake ship named `~zod`, run the command below. You can replace `zod`
20−with any valid Urbit ship-name.
21−
22−```
23−./urbit -F zod
24−```
25−
26−This should take a couple of minutes, during which you should see a block of boot
27−messages, starting with the Urbit version number.
28−
29−## Hoon support in text editors
11+## Text editors
3012
3113A variety of plugins have been built to provide support for the Hoon language in
3214different text editors:
@@ -61,4 +43,271 @@ with [hoon-mode.el](https://github.com/urbit/hoon-mode.el).
6143
6244Vim is free and open-source and runs on all major operating systems. It is
6345available [here](https://www.vim.org/). Hoon support is available with
64−[hoon.vim](https://github.com/urbit/hoon.vim) and is maintained by Tlon.
46+[hoon.vim](https://github.com/urbit/hoon.vim).
47+
48+## Development ships
49+
50+### Creating a fake ship
51+
52+To do work with Hoon, we recommended using a "fake" ship — one that's not
53+connected to the network.
54+
55+Because such a ship has no presence on the network, you don't need an Azimuth
56+identity. You just need to have [installed the Urbit binary](/getting-started/cli).
57+
58+To create a fake ship named `~zod`, run the command below. You can replace `zod`
59+with any valid Urbit ship-name.
60+
61+```
62+./urbit -F zod
63+```
64+
65+This should take a couple of minutes, during which you should see a block of boot
66+messages, starting with the Urbit version number.
67+
68+### Fake ship networking
69+
70+Fake ships on the same machine can automatically talk to one another. Having
71+created a fakezod, you can create a fake `~bus` the same way:
72+
73+```
74+./urbit -F bus
75+```
76+
77+Now in the fakezod's dojo, try:
78+
79+```
80+> |hi ~bus
81+>=
82+hi ~bus successful
83+```
84+
85+### Faster fake ship booting
86+
87+While working with Hoon, you'll often want to delete an old fake ship and
88+recreate a fresh one. Rather than having to wait a few minutes for the fresh
89+ship to be initialised, you can instead create a backup copy of a fake ship.
90+That way you can just delete the current copy, replace it with the backup, and
91+reboot in a matter of seconds.
92+
93+To do this, boot a fresh fake ship like usual, but with a different name:
94+
95+```
96+./urbit -F zod -c zod.new
97+```
98+
99+Once it's finished booting, it's a good idea to mount its desks so you don't
100+have to do it again each time. In the dojo:
101+
102+```
103+> |mount %base
104+>=
105+> |mount %garden
106+>=
107+> |mount %landscape
108+>=
109+> |mount %bitcoin
110+>=
111+> |mount %webterm
112+>=
113+```
114+
115+Next, shut the ship down with `ctrl+D`. Then, copy the pier and start using the
116+copy instead:
117+
118+```
119+cp -r zod.new zod
120+./urbit zod
121+```
122+
123+Now whenever you want a fresh fakezod, you can just shut it down and do:
124+
125+```
126+rm -r zod
127+cp -r zod.new zod
128+./urbit zod
129+```
130+
131+## Working with desks
132+
133+If you're just working in the dojo or experimenting with generators, committing
134+to the `%base` desk on a fake ship is fine. If you're working on a Gall agent or
135+developing a desk for distribution, you'll most likely want to work on a
136+separate desk and it's slightly more complicated.
137+
138+### Mount a desk
139+
140+To mount a desk to Unix so you can add files, you just need to run the `|mount`
141+command in the dojo and specify the name of the desk to mount:
142+
143+```
144+|mount %base
145+```
146+
147+The desk will now appear in the root of your pier (zod in this case):
148+
149+```
150+zod
151+└── base
152+```
153+
154+You can unmount it again by running the `|unmount` command in the dojo:
155+
156+```
157+|unmount %base
158+```
159+
160+### Create a new desk
161+
162+To create a new desk, you'll need to merge from an existing one, typically
163+`%base`. In the dojo, run the following (you can change `%mydesk` to your
164+preferred name):
165+
166+```
167+|merge %mydesk our %base
168+```
169+
170+If you now mount it, you'll have `/mydesk` directory in your pier with all the
171+files of the `%base` desk inside. You can then delete the contents, copy in your
172+own files and `|commit` it.
173+
174+Desks must contain all the `mark` files, libraries, etc, that they need. A
175+`sys.kelvin` file is mandatory, and there are a few `mark` files necessary as
176+well. In the next couple of sections we'll look at different ways to populate a
177+new desk with the necessary files.
178+
179+### Minimal desk
180+
181+This is the absolute minimal desk you'll be able to commit:
182+
183+```
184+skeleton
185+├── mar
186+│ ├── hoon.hoon
187+│ ├── kelvin.hoon
188+│ ├── mime.hoon
189+│ ├── noun.hoon
190+│ ├── txt-diff.hoon
191+│ └── txt.hoon
192+└── sys.kelvin
193+```
194+
195+`sys.kelvin` specifies the kernel kelvin version with which the desk is
196+compatible. You can copy it across from the `%base` desk, or just run the
197+following in the terminal from within the desk directory:
198+
199+```sh
200+echo "[%zuse 419]" > sys.kelvin
201+```
202+
203+The other `mark` files can just be copied across from the `%base` desk.
204+
205+### Using dev desks
206+
207+If you're working on something more complex, for example a desk with agents and
208+a front-end, there will be a number of `mark` files, libraries, etc, that will
209+be necessary. Rather than having to manually copy all the files from the
210+relevant default desks, the [urbit git repo](https://github.com/urbit/urbit)
211+includes some dev desks which can be used as a base. To get these, make sure you
212+have git installed and then clone the repo:
213+
214+```
215+git clone https://github.com/urbit/urbit ~/git/urbit
216+```
217+
218+If you now change to the `~/git/urbit/pkg` directory, you'll see the source for
219+the default desks, among other things:
220+
221+```
222+cd ~/git/urbit/pkg
223+```
224+
225+The desks ending in `-dev`, like `base-dev` and `garden-dev`, contain files for
226+interfacing with those respective desks. If you're creating a new desk that has
227+a tile and front-end, for example, you might like to use `base-dev` and
228+`garden-dev` as a base. To create such a base, there's a `symbolic-merge.sh`
229+script included in the directory. You can use it like so:
230+
231+```
232+./symbolic-merge base-dev mydesk
233+./symbolic-merge garden-dev mydesk
234+```
235+
236+After running that, you'll have a `mydesk` desk in the `pkg` directory that
237+contains the symlinked files from both those dev desks. To copy the files into
238+your pier, you can create and mount a mydesk desk in the dojo:
239+
240+```
241+|merge %mydesk our %base
242+|mount %mydesk
243+```
244+
245+Then, you can go into your pier:
246+
247+```
248+cd /path/to/fake/zod
249+```
250+
251+Delete the contents of `mydesk`:
252+
253+```
254+rm -r mydesk/*
255+```
256+
257+And then copy in the contents of the desk you created:
258+
259+```
260+cp -rL ~/git/urbit/pkg/mydesk/* mydesk
261+```
262+
263+Note you have to use `cp -rL` rather than just `cp -r` because the
264+`symbolic-merge.sh` script creates symlinks, so the `L` flag is to resolve them
265+and copy the actual files.
266+
267+Now you can just add a `sys.kelvin` file:
268+
269+```
270+echo "[%zuse 419]" > mydesk/sys.kelvin
271+```
272+
273+And you'll be able to mount the desk with `|commit %mydesk`.
274+
275+## Project organization
276+
277+When you're developing a desk, it's best to structure your working directory
278+with the same hierarchy as a real desk. For example, `~/project/mydesk` might
279+look like:
280+
281+```
282+mydesk
283+├── app
284+│ └── foo.hoon
285+├── desk.bill
286+├── desk.docket-0
287+├── lib
288+│ └── foo.hoon
289+├── mar
290+│ └── foo
291+│ ├── action.hoon
292+│ └── update.hoon
293+├── sur
294+│ └── foo.hoon
295+└── sys.kelvin
296+
297+```
298+
299+That way, whenever you want to test your changes, you can just copy it across to
300+your pier like:
301+
302+```
303+cp -ruv mydesk/* /path/to/fake/zod/mydesk
304+```
305+
306+And then just commit it in the dojo:
307+
308+```
309+|commit %mydesk
310+```
311+
312+If you're [using dev desks](#using-dev-desks) as a base, it's best to keep those
313+files separate from your own code.
content/docs/development/precepts.md+1−1
@@ -135,7 +135,7 @@ We’ll start with a brief description of many principles, then we’ll go into
135135
136136<img class="ba" src="https://media.urbit.org/site/posts/essays/pre-03.jpg">
137137
138−### B: Specific Design
138+### B: Specific Design {#specific}
139139
1401401) Always ack a dupe; never ack an ack.
141141
content/docs/glossary/aqua.md−4
@@ -10,7 +10,3 @@ category = "arvo"
1010Aqua is a [Gall](/docs/glossary/gall) app that runs an [Arvo](/docs/glossary/arvo) instance or instances in userspace. It pretends to be [Vere](/docs/glossary/vere), and as such it loads [Pills](/docs/glossary/pill) to boot up a virtual ship or fleet of ships and then manages them from within the parent Arvo instance. Running tests for a virtual fleet of Aqua ships is done using [pH](/docs/glossary/ph).
1111
1212Aqua is jetted with the usual [Nock](/docs/glossary/nock) interpreter and thus virtual ships do not run any slower than the parent ship.
13−
14−### Further Reading
15−
16−- [The Gall tutorial](/docs/userspace/gall/gall): A technical guide to the Gall vane.
content/docs/glossary/azimuth.md+27−6
@@ -3,16 +3,37 @@ title = "Azimuth"
33template = "doc.html"
44+++
55
6−**Azimuth** is Urbit's identity layer, built as a suite of smart contracts on the Ethereum blockchain. It is Urbit's method of securing digital identities that are required to use the [Arvo](/docs/glossary/arvo) peer-to-peer network, without the need for a central authority. Azimuth identities exist as non-fungible tokens, which are owned by Ethereum addresses and can be transferred between such addresses. Identities can use the [claims](/docs/glossary/claims) contract to make assertions – real-world or otherwise – about their owner.
6+**Azimuth** is Urbit's identity layer, built as a suite of smart contracts on
7+the Ethereum blockchain and several apps run locally on your
8+[ship](/docs/glossary/ship). It is Urbit's method of securing digital identities
9+that are required to use the [Arvo](/docs/glossary/arvo) peer-to-peer network,
10+without the need for a central authority. Azimuth identities exist as
11+non-fungible tokens, which are owned by Ethereum addresses and can be
12+transferred between such addresses. Identities can use the
13+[claims](/docs/glossary/claims) contract to make assertions – real-world or
14+otherwise – about their owner.
715
8−The primary way to interact with Azimuth and to manage your identities is through our [Bridge](https://bridge.urbit.org) application. Bridge is a front-end for [Ecliptic](/docs/glossary/ecliptic), the Azimuth contract that's used to perform actions on the blockchain.
16+The primary way to interact with Azimuth and to manage your identities is
17+through our [Bridge](https://bridge.urbit.org) application. Bridge is a
18+front-end for [Ecliptic](/docs/glossary/ecliptic), the Azimuth contract that's
19+used to perform actions on the blockchain.
920
10−There are a limited number of Azimuth identities which results in identities having value. This allows for identities to function as reputation primitives, since such scarcity creates an economic incentive for identities to remain static and to keep the network friendly. Undesirable behavior – spamming, scamming, and malware-spreading - will generally result in a [censure](/docs/glossary/censure) from [galaxies](/docs/glossary/galaxy) and [stars](/docs/glossary/star), marking the bad actor.
21+There are a limited number of Azimuth identities which results in identities
22+having value. This allows for identities to function as reputation primitives,
23+since such scarcity creates an economic incentive for identities to remain
24+static and to keep the network friendly. Undesirable behavior – spamming,
25+scamming, and malware-spreading - will generally result in a
26+[censure](/docs/glossary/censure) from [galaxies](/docs/glossary/galaxy) and
27+[stars](/docs/glossary/star), marking the bad actor.
1128
12−It should be noted that Azimuth isn't built just for Arvo. It can be used as an identity system for other projects.
29+It should be noted that Azimuth isn't built just for Arvo. It can be used as an
30+identity system for other projects.
1331
1432### Further Reading
1533
16−- [The Azimuth concepts page](/docs/azimuth/advanced-azimuth-tools): A more in-depth explanation of Azimuth, including information the storage of Urbit identities.
17−- [Install instructions](/getting-started/): Guide to installing Urbit, which includes instructions on booting with your Urbit identity.
34+- [The Azimuth concepts page](/docs/azimuth/azimuth): A more in-depth
35+ explanation of Azimuth.
36+- [Install instructions](/getting-started/): Guide to installing Urbit, which
37+ includes instructions on booting with your Urbit identity.
1838- [Understanding Urbit ID](/understanding-urbit/urbit-id)
39+
content/docs/glossary/desk.md+1−1
@@ -8,7 +8,7 @@ category = "arvo"
88
99A **desk** is an independently revision-controlled branch of a [ship](/docs/glossary/ship) that uses the [Clay](/docs/glossary/clay) filesystem. Each desk contains its own apps, [mark](/docs/glossary/mark) definitions, files, and so forth.
1010
11−Traditionally a ship has at least a base desk and a home desk. The base desk has all the system software from the distribution, and the home desk is a fork of base with all the items specific to the user of the ship. A desk is a series of numbered commits, the most recent of which represents the current state of the desk. A commit is composed of `1` an absolute time when it was created, `2` a list of zero or more parents, and `3` a map from paths to data.
11+Traditionally a ship has at least a `%base` desk, and typically `%garden` and `%landscape` desk among others. The `%base` desk has the kernel and base system software, while other desks are usually each for different apps. A desk is a series of numbered commits, the most recent of which represents the current state of the desk. A commit is composed of `1` an absolute time when it was created, `2` a list of zero or more parents, and `3` a map from paths to data.
1212
1313### Further Reading
1414
content/docs/glossary/dojo.md+2−1
@@ -11,4 +11,5 @@ The other default command-line app is [Chat](/docs/glossary/chat). To switch bet
1111and [Chat](/docs/glossary/chat) press Ctrl-X. The Dojo is the first thing you encounter after successfully booting your [ship](/docs/glossary/ship).
1212
1313### Further Reading
14−- [Hoon Tutorial Lesson 1.1: Setup](/docs/hoon/hoon-school/setup): A great way to get started with using Hoon in the Dojo.
14+
15+- [Hoon Tutorial Lesson 1.1: Introduction](/docs/hoon/hoon-school/intro): A great way to get started with using Hoon in the Dojo.
content/docs/glossary/gall.md+2−1
@@ -14,4 +14,5 @@ Gall is located at `/home/sys/vane/gall.hoon` within Arvo.
1414
1515- [The Hoon Tutorial](/docs/hoon/hoon-school/): Our guide to learning the Hoon programming language that will give you the foundation necessary for app development.
1616 - [Lesson 2.7: Gall](/docs/hoon/hoon-school/gall): A Hoon Tutorial lesson that explains how to write a simple Gall app.
17−- [The Gall tutorial](/docs/userspace/gall/gall): A technical guide to the Gall vane.
17+- [Gall vane documentation](/docs/arvo/gall/gall): Documentation of the Gall vane.
18+- [Gall Guide](/docs/userspace/gall-guide): A tutorial for writing Gall agents.
content/docs/glossary/hdwallet.md+2−1
@@ -14,4 +14,5 @@ If a proxy or ownership address is compromised or has its keys lost, it can alwa
1414
1515### Further Reading
1616
17−- [The Azimuth concepts page](/docs/azimuth/advanced-azimuth-tools): A more in-depth explanation of Azimuth, including information about the HD wallet.
17+- [The Azimuth concepts page](/docs/azimuth/azimuth): A more in-depth explanation of Azimuth.
18+- [Urbit HD Wallet](/docs/azimuth/hd-wallet): An in-depth explanation of the HD wallet.
content/docs/glossary/proxies.md+6−1
@@ -6,7 +6,12 @@ template = "doc.html"
66category = "azimuth"
77+++
88
9−**Proxies** are Ethereum addresses in the [Urbit HD Wallet](/docs/glossary/hdwallet) system that have limited powers. They are lower-powered "siblings" of the ownership key, which has the sole power to transfer the assigned Urbit identity. Using [Bridge](/docs/glossary/bridge), you can change the Ethereum addresses used for your proxies.
9+**Proxies** are Ethereum addresses in the [Urbit ID](/docs/glossary/azimuth)
10+system that have limited powers. They are lower-powered "siblings" of the
11+ownership key, which has the sole power to transfer the assigned Urbit identity.
12+Using [Bridge](/docs/glossary/bridge), you can change the Ethereum addresses
13+used for your proxies. If you use the [Urbit HD
14+wallet](/docs/glossary/hdwallet), your proxies have already been set.
1015
1116There are three types of proxy.
1217
content/docs/glossary/rollups.mdnew file+30
@@ -0,0 +1,30 @@
1++++
2+title = "Naive rollups"
3+template = "doc.html"
4+[extra]
5+category = "azimuth"
6++++
7+
8+**Naive rollups**, also referred to as **layer 2**, is an upgrade to
9+[Azimuth](/docs/glossary/azimuth) implemented in 2021 that reduces Ethereum gas
10+costs associated with Urbit ID transactions and friction associated with using
11+cryptocurrency in general.
12+
13+This system allows batches of Urbit ID transactions to be submitted together as
14+a single transaction using an urbit node known as a "roller". The PKI state
15+transitions resulting from these transactions are computed locally by your
16+[ship](/docs/glossary/ship) rather than by the [Ethereum Virtual
17+Machine](https://ethereum.org/en/developers/docs/evm/).
18+
19+Due to the dramatically reduced cost, Tlon offers their own roller that is free
20+for ordinary public use. This enables new users to get started with a permanent
21+Urbit ID without any prior knowledge of Ethereum, cryptocurrency, or
22+blockchains.
23+
24+### Further reading
25+
26+- [The Gang Solves the Gas Crisis](/blog/rollups): A casual overview of how
27+naive rollups works.
28+- Pilot's Guide to layer 2 : insert link
29+- [Layer 2 Overview](/docs/azimuth/l2/layer2): where developers should go to learn
30+about the technical details of naive rollups.
content/docs/hoon/guides/_index.md+4
@@ -11,3 +11,7 @@ insert_anchor_links = "right"
1111## [CLI Apps](/docs/hoon/guides/cli-tutorial)
1212
1313## [Parsing](/docs/hoon/guides/parsing)
14+
15+## [Strings](/docs/hoon/guides/strings)
16+
17+## [JSON](/docs/hoon/guides/json-guide)
content/docs/hoon/guides/json-guide.mdnew file+511
@@ -0,0 +1,511 @@
1++++
2+title = "JSON"
3+weight = 4
4+template = "doc.html"
5++++
6+
7+If you are working on a Gall agent with any kind of web interface, it's likely you will encounter the problem of converting Hoon data structures to JSON and vice versa. This is what we'll look at in this document.
8+
9+Urbit represents JSON data with the `$json` structure (defined in `lull.hoon`). You can refer to the [json type](#the-json-type) section below for details.
10+
11+JSON data on the web is encoded in text, so Urbit has two functions in `zuse.hoon` for dealing with this:
12+
13+- [`+en-json:html`](/docs/hoon/reference/zuse/2e_2-3#en-jsonhtml) - For printing `$json` to a text-encoded form.
14+- [`+de-json:html`](/docs/hoon/reference/zuse/2e_2-3#de-jsonhtml) - For parsing text-encoded JSON to a `$json` structure.
15+
16+You typically want `$json` data converted to some other `noun` structure or vice versa, so Urbit has three collections of functions for this purpose, also in `zuse.hoon`:
17+
18+- [`+enjs:format`](/docs/hoon/reference/zuse/2d_1-5#enjsformat) - Functions for converting various atoms and structures to `$json`.
19+- [`+dejs:format`](/docs/hoon/reference/zuse/2d_6#dejsformat) - Many "reparsers" for converting `$json` data to atoms and other structures.
20+- [`+dejs-soft:format`](/docs/hoon/reference/zuse/2d_7#dejs-softformat) - Largely the same as `+dejs:format` except its reparsers produce `unit`s which are null upon failure rather than simply crashing.
21+
22+The relationship between these types and functions look like this:
23+
24+![json diagram](https://media.urbit.org/docs/json-diagram.svg)
25+
26+Note this diagram is a simplification - the `+dejs:format` and `+enjs:format` collections in particular are tools to be used in writing conversion functions rather than simply being used by themselves, but it demonstrates the basic relationships. Additionally, it is less common to do printing/parsing manually - this would typically be handled automatically by Eyre, though it may be necessary if you're retrieving JSON data via the web client vane Iris.
27+
28+### In practice
29+
30+A typical Gall agent will have a number of structures defined in a file in the `/sur` directory. These will define the type of data it expects to be `%poke`ed with, the type of data it will `%give` to subscribers, and the type of data its scry endpoints produce.
31+
32+If the agent only interacts with other agents inside Urbit, it may just use a `%noun` `mark`. If, however, it needs to talk to a web interface of some kind, it usually must handle `$json` data with a `%json` mark.
33+
34+Sometimes an agent's interactions with a web interface are totally distinct from its interactions with other agents. If so, the agent could just have separate scry endpoints, poke handlers, etc, that directly deal with `$json` data with a `%json` mark. In such a case, you can include `$json` encoding/decoding functions directly in the agent or associated libraries, using the general techniques demonstrated in the [$json encoding and decoding example](#json-encoding-and-decoding-example) section below.
35+
36+If, on the other hand, you want a unified interface (whether interacting with a web client or within Urbit), a different approach is necessary. Rather than taking or producing either `%noun` or `%json` marked data, custom `mark` files can be created which specify conversion methods for both `%noun` and `%json` marked data.
37+
38+With this approach, an agent would take and/or produce data with some `mark` like `%my-custom-mark`. Then, when the agent must interact with a web client, the webserver vane Eyre can automatically convert `%my-custom-mark` to `%json` or vice versa. This way the agent only ever has to handle the `%my-custom-mark` data. This approach is used by `%graph-store` with its `%graph-update-2` mark, for example, and a number of other agents.
39+
40+For details of creating a `mark` file for this purpose, the [mark file example](#mark-file-example) section below walks through a practical example.
41+
42+## The `$json` type
43+
44+Urbit represents JSON data with the `$json` structure (defined in `/sys/lull.hoon`):
45+
46+```hoon
47++$ json :: normal json value
48+ $@ ~ :: null
49+ $% [%a p=(list json)] :: array
50+ [%b p=?] :: boolean
51+ [%o p=(map @t json)] :: object
52+ [%n p=@ta] :: number
53+ [%s p=@t] :: string
54+ == ::
55+```
56+
57+The correspondence of `$json` to JSON types is fairly self-evident, but here's a table comparing the two for additional clarity:
58+
59+| JSON Type | `$json` Type | JSON Example | `$json` Example |
60+| :-------- | :--------------------- | ------------------------- | :----------------------------------------------------------- |
61+| Null | `~` | `null` | `~` |
62+| Boolean | `[%b p=?]` | `true` | `[%b p=%.y]` |
63+| Number | `[%n p=@ta]` | `123` | `[%n p=~.123]` |
64+| String | `[%s p=@t]` | `"foo"` | `[%s p='foo']` |
65+| Array | `[%a p=(list json)]` | `["foo",123]` | `[%a p=~[[%s p='foo'] [%n p=~.123]]]` |
66+| Object | `[%o p=(map @t json)]` | `{"foo":"xyz","bar":123}` | `[%o p={[p='bar' q=[%n p=~.123]] [p='foo' q=[%s p='xyz']]}]` |
67+
68+Since the `$json` `%o` object and `%a` array types may themselves contain any `$json`, you can see how JSON structures of arbitrary complexity can be represented. Note the `%n` number type is a `@ta` rather than something like a `@ud` that you might expect. This is because JSON's number type may be either an integer or floating point, so it's left as a `knot` which can then be parsed to a `@ud` or `@rd` with the appropriate [`+dejs:format`](/docs/hoon/reference/zuse/2d_6) function.
69+
70+## `$json` encoding and decoding example
71+
72+Let's have a look at a practical example. Here's a core with three arms. It has the structure arm `$user`, and then two more: `+to-js` converts a `$user` structure to `$json`, and `+from-js` does the opposite. Usually we'd define the structure in a separate `/sur` file, but for simplicity it's all in the one core.
73+
74+#### `json-test.hoon`
75+
76+```hoon
77+|%
78++$ user
79+ $: username=@t
80+ name=[first=@t mid=@t last=@t]
81+ joined=@da
82+ email=@t
83+ ==
84+++ to-js
85+ |= usr=user
86+ |^ ^- json
87+ %- pairs:enjs:format
88+ :~
89+ ['username' s+username.usr]
90+ ['name' name]
91+ ['joined' (sect:enjs:format joined.usr)]
92+ ['email' s+email.usr]
93+ ==
94+ ++ name
95+ :- %a
96+ :~
97+ [%s first.name.usr]
98+ [%s mid.name.usr]
99+ [%s last.name.usr]
100+ ==
101+ --
102+++ from-js
103+ =, dejs:format
104+ ^- $-(json user)
105+ %- ot
106+ :~
107+ [%username so]
108+ [%name (at ~[so so so])]
109+ [%joined du]
110+ [%email so]
111+ ==
112+--
113+```
114+
115+### Try it out
116+
117+First we'll try using our `$json` encoding/decoding library, and afterwards we'll take a closer look at its construction. To begin, save the code above in `/lib/json-test.hoon` of the `%base` desk on a fake ship and `|commit` it:
118+
119+```
120+> |commit %base
121+>=
122++ /~zod/base/5/lib/json-test/hoon
123+```
124+
125+Then we need to build it so we can use it. We'll give it a face of `user-lib`:
126+
127+```
128+> =user-lib -build-file %/lib/json-test/hoon
129+```
130+
131+Let's now create an example of a `$user` structure:
132+
133+```
134+> =usr `user:user-lib`['john456' ['John' 'William' 'Smith'] now 'john.smith@example.com']
135+> usr
136+[ username='john456'
137+ name=[first='John' mid='William' last='Smith']
138+ joined=~2021.9.12..09.47.58..1b65
139+ email='john.smith@example.com'
140+]
141+```
142+
143+Now we can try calling the `+to-js` function with our data to convert it to `$json`:
144+
145+```
146+> =usr-json (to-js:user-lib usr)
147+> usr-json
148+[ %o
149+ p
150+ { [p='email' q=[%s p='john.smith@example.com']]
151+ [p='name' q=[%a p=~[[%s p='John'] [%s p='William'] [%s p='Smith']]]]
152+ [p='username' q=[%s p='john456']]
153+ [p='joined' q=[%n p=~.1631440078]]
154+ }
155+]
156+```
157+
158+Let's also see how that `$json` would look as real JSON encoded in text. We can do that with `+en-json:html`:
159+
160+```
161+> (crip (en-json:html (to-js:user-lib usr)))
162+'{"joined":1631440078,"username":"john456","name":["John","William","Smith"],"email":"john.smith@example.com"}'
163+```
164+
165+Finally, let's try converting the `$json` back to a `$user` again with our `+from-js` arm:
166+
167+```
168+> (from-js:user-lib usr-json)
169+[ username='john456'
170+ name=[first='John' mid='William' last='Smith']
171+ joined=~2021.9.12..09.47.58
172+ email='john.smith@example.com'
173+]
174+```
175+
176+### Analysis
177+
178+#### Converting to `$json`
179+
180+Here's our arm that converts a `$user` structure to `$json`:
181+
182+```hoon
183+++ to-js
184+ |= usr=user
185+ |^ ^- json
186+ %- pairs:enjs:format
187+ :~
188+ ['username' s+username.usr]
189+ ['name' name]
190+ ['joined' (sect:enjs:format joined.usr)]
191+ ['email' s+email.usr]
192+ ==
193+ ++ name
194+ :- %a
195+ :~
196+ [%s first.name.usr]
197+ [%s mid.name.usr]
198+ [%s last.name.usr]
199+ ==
200+ --
201+```
202+
203+There are different ways we could represent our `$user` structure as JSON, but in this case we've opted to encapsulate it in an object and have the `name` as an array (since JSON arrays preserve order).
204+
205+[`+enjs:format`](/docs/hoon/reference/zuse/2d_1-5#enjsformat)includes the convenient [`+pairs`](/docs/hoon/reference/zuse/2d_1-5#pairsenjsformat) function, which converts a list of `[@t json]` to an object containing those key-value pairs. We've used this to assemble the final object. Note that if you happen to have only a single key-value pair rather than a list, you can use [`+frond`](/docs/hoon/reference/zuse/2d_1-5#frondenjsformat) instead of `+pairs`.
206+
207+For the `joined` field, we've used the [`+sect`](/docs/hoon/reference/zuse/2d_1-5#sectenjsformat) function from `+enjs` to convert the `@da` to a Unix seconds timestamp in a `$json` number. The `+sect` function, like others in `+enjs`, takes in a noun (in this case a `@da`) and produces `$json` (in this case a `[%n @ta]` number). `+enjs` contains a handful of useful functions like this, but for the rest we've just hand-made the `$json` structure. This is fairly typical when encoding `$json`, it's usually [decoding](#converting-from-json) that makes more extensive use of the `$json` utility functions in `+format`.
208+
209+For the `name` field we've just formed a cell of `%a` and a list of `$json` strings, since a `$json` array is `[%a p=(list json)]`. Note we've separated this part into its own arm and wrapped the whole thing in a `|^` - a core with a `$` arm that's computed immediately. This is simply for readability - our structure here is quite simple but when dealing with deeply-nested `$json` structures or complex logic, having a single giant function can quickly become unwieldy.
210+
211+#### Converting from `$json`
212+
213+Here's our arm that converts `$json` to our `$user` structure:
214+
215+```hoon
216+++ from-js
217+ =, dejs:format
218+ ^- $-(json user)
219+ %- ot
220+ :~
221+ [%username so]
222+ [%name (at ~[so so so])]
223+ [%joined du]
224+ [%email so]
225+ ==
226+```
227+
228+This is the inverse of the [encoding](#converting-to-json) function described in the previous section.
229+
230+We make extensive use of [`+dejs:format`](/docs/hoon/reference/zuse/2d_6) functions here, so we've used `=,` to expose the namespace and allow succinct `+dejs` function calls.
231+
232+We use the [`+ot`](/docs/hoon/reference/zuse/2d_6#otdejsformat) function from `+dejs:format` to decode the `$json` object to a n-tuple. It's a wet gate that takes a list of pairs of keys and other `+dejs` functions and produces a new gate that takes the `$json` to be decoded (which we've given it in `jon`).
233+
234+The [`+so`](/docs/hoon/reference/zuse/2d_6#sodejsformat) functions just decode `$json` strings to `cord`s. The [`+at`](/docs/hoon/reference/zuse/2d_6#atdejsformat) function converts a `$json` array to a tuple, decoding each element with the respective function given in its argument list. Like `+ot`, `+at` is also a wet gate that produces a gate that takes `$json`. In our case we've used `+so` for each element, since they're all strings.
235+
236+For `joined`, we've used the [`+du`](/docs/hoon/reference/zuse/2d_6#dudejsformat) function, which converts a Unix seconds timestamp in a `$json` number to a `@da` (it's basically the inverse of the `+sect:enjs:format` we used earlier).
237+
238+Notice how `+ot` takes in other `+dejs` functions in its argument. One of its arguments includes the `+at` function which itself takes in other `+dejs` functions. There are several `+dejs` functions like this that allow complex nested JSON structures to be decoded. For other examples of common `+dejs` functions like this, see the [More `+dejs`](#more-dejs) section below.
239+
240+There are dozens of different functions in [`+dejs:format`](/docs/hoon/reference/zuse/2d_6) that will cover a great many use cases. If there isn't a `+dejs` function for a particular case, you can also just write a custom function - it just has to take `$json`. Note there's also the [`+dejs-soft:format`](/docs/hoon/reference/zuse/2d_7) functions - these are similar to `+dejs` functions except they produce `unit`s rather than simply crashing if decoding fails.
241+
242+## More `+dejs`
243+
244+We looked at the commonly used `+ot` function in the [first example](#converting-from-json), now let's look at a couple more common `+dejs` functions.
245+
246+### `+of`
247+
248+The [`+of`](/docs/hoon/reference/zuse/2d_6#ofdejsformat) function takes an object containing a single key-value pair, decodes the value with the corresponding `+dejs` function in a key-function list, and produces a key-value tuple. This is useful when there are multiple possible objects you might receive, and tagged unions are a common data structure in hoon.
249+
250+Let's look at an example. Here's a gate that takes in some `$json`, decodes it with an `+of` function that can handle three possible objects, casts the result to a tagged union, switches against its head with `?-`, performs some transformation and finally returns the result. You can save it as `gen/of-test.hoon` in the `%base` desk of a fake ship and `|commit %base`.
251+
252+#### `of-test.hoon`
253+
254+```hoon
255+|= jon=json
256+|^ ^- @t
257+=/ =fbb
258+ (to-fbb jon)
259+?- -.fbb
260+ %foo (cat 3 +.fbb '!!!')
261+ %bar ?:(+.fbb 'Yes' 'No')
262+ %baz :((cury cat 3) p.fbb q.fbb r.fbb)
263+==
264++$ fbb
265+ $% [%foo @t]
266+ [%bar ?]
267+ [%baz p=@t q=@t r=@t]
268+ ==
269+++ to-fbb
270+=, dejs:format
271+%- of
272+:~ foo+so
273+ bar+bo
274+ baz+(at ~[so so so])
275+==
276+--
277+```
278+
279+Let's try it:
280+
281+```
282+> +of-test (need (de-json:html '{"foo":"Hello"}'))
283+'Hello!!!'
284+
285+> +of-test (need (de-json:html '{"bar":true}'))
286+'Yes'
287+
288+> +of-test (need (de-json:html '{"baz":["a","b","c"]}'))
289+'abc'
290+```
291+
292+### `+ou`
293+
294+The [`+ou`](/docs/hoon/reference/zuse/2d_6#oudejsformat) function decodes a `$json` object to an n-tuple using the matching functions in a key-function list. Additionally, it lets you set some key-value pairs in an object as optional and others as mandatory. The mandatory ones crash if they're missing and the optional ones are replaced with a given noun.
295+
296+`+ou` is different to other `+dejs` functions - the functions it takes are `$-((unit json) grub)` rather than the usual `$-(json grub)` of most `+dejs` functions. There are only two `+dejs` functions that fit this - [`+un`](/docs/hoon/reference/zuse/2d_6#undejsformat) and [`+uf`](/docs/hoon/reference/zuse/2d_6#ufdejsformat). These are intended to be used with `+ou` - you would wrap each function in the key-function list of `+ou` with either `+un` or `+uf`.
297+
298+`+un` crashes if its argument is `~`. `+ou` gives functions a `~` if the matching key-value pair is missing in the `$json` object, so `+un` crashes if the key-value pair is missing. Therefore, `+un` lets you set key-value pairs as mandatory.
299+
300+`+uf` takes two arguments - a noun and a `+dejs` function. If the `(unit json)` it's given by `+ou` is `~`, it produces the noun it was given rather than the product of the `+dejs` function. This lets you specify key-value pairs as optional, replacing missing ones with whatever you want.
301+
302+Let's look at a practical example. Here's a generator you can save in the `%base` desk of a fake ship in `gen/ou-test.hoon` and `|commit %base`. It takes in a `$json` object and produces a triple. The `+ou` in `+decode` has three key-function pairs - the first two are mandatory and the last is optional, producing the bunt of a set if the `%baz` key is missing.
303+
304+#### `ou-test.hoon`
305+
306+```hoon
307+|= jon=json
308+|^ ^- [@t ? (set @ud)]
309+(decode jon)
310+++ decode
311+=, dejs:format
312+%- ou
313+:~ foo+(un so)
314+ bar+(un bo)
315+ baz+(uf *(set @ud) (as ni))
316+==
317+--
318+```
319+
320+Let's try it:
321+
322+```
323+> +ou-test (need (de-json:html '{"foo":"hello","bar":true,"baz":[1,2,3,4]}'))
324+['hello' %.y {1 2 3 4}]
325+
326+> +ou-test (need (de-json:html '{"foo":"hello","bar":true}'))
327+['hello' %.y {}]
328+
329+> +ou-test (need (de-json:html '{"foo":"hello"}'))
330+[%key 'bar']
331+dojo: hoon expression failed
332+```
333+
334+### `+su`
335+
336+The [`+su`](/docs/hoon/reference/zuse/2d_6#sudejsformat) function parses a string with the given parsing `rule`. Hoon's functional parsing library is very powerful and lets you create arbitrarily complex parsers. JSON will often have data types encoded in strings, so this function can be very useful. The writing of parsers is outside the scope of this guide, but you can see the [Parsing Guide](/docs/hoon/guides/parsing) and sections 4e to 4j of the standard library documentation for details.
337+
338+Here are some simple examples of using `+su` to parse strings:
339+
340+```
341+> `@ux`((su:dejs:format hex) s+'deadbeef1337f00D')
342+0xdead.beef.1337.f00d
343+
344+> `(list @)`((su:dejs:format (most lus dem)) s+'1+2+3+4')
345+~[1 2 3 4]
346+
347+> `@ub`((su:dejs:format ven) s+'+>-<->+<+')
348+0b11.1000.1101
349+```
350+
351+Here's a more complex parser that will parse a GUID like `824e7749-4eac-9c00-db16-4cb816cd6f19` to a `@ux`:
352+
353+#### `su-test.hoon`
354+
355+```hoon
356+|= jon=json
357+^- @ux
358+%. jon
359+%- su:dejs:format
360+%+ cook
361+|= parts=(list [step @])
362+^- @ux
363+(can 3 (flop parts))
364+;~ plug
365+ (stag 4 ;~(sfix (bass 16 (stun 8^8 six:ab)) hep))
366+ (stag 2 ;~(sfix qix:ab hep))
367+ (stag 2 ;~(sfix qix:ab hep))
368+ (stag 2 ;~(sfix qix:ab hep))
369+ (stag 6 (bass 16 (stun 12^12 six:ab)))
370+ (easy ~)
371+==
372+```
373+
374+Save it in the `/gen` directory of the `%base` desk and `|commit` it. We can then try it with:
375+
376+```
377+> +su-test s+'5323a61d-0c26-d8fa-2b73-18cdca805fd8'
378+0x5323.a61d.0c26.d8fa.2b73.18cd.ca80.5fd8
379+```
380+
381+If we delete the last character it'll no longer be a valid GUID and the parsing will fail:
382+
383+```
384+> +su-test s+'5323a61d-0c26-d8fa-2b73-18cdca805fd'
385+/gen/su-test/hoon:<[2 1].[16 3]>
386+/gen/su-test/hoon:<[3 1].[16 3]>
387+{1 36}
388+syntax error
389+dojo: naked generator failure
390+```
391+
392+## `mark` file example
393+
394+Here's a simple `mark` file for the `$user` structure we created in the [first example](#json-encoding-and-decoding-example). It imports the [json-test.hoon](#json-testhoon) library we created and saved in our `%base` desk's `/lib` directory.
395+
396+#### `user.hoon`
397+
398+```hoon
399+/+ *json-test
400+|_ usr=user
401+++ grab
402+ |%
403+ ++ noun user
404+ ++ json from-js
405+ --
406+++ grow
407+ |%
408+ ++ noun usr
409+ ++ json (to-js usr)
410+ --
411+++ grad %noun
412+--
413+```
414+
415+The [Marks section](/docs/arvo/clay/marks/marks) of the Clay documentation covers `mark` files comprehensively and is worth reading through if you want to write a mark file.
416+
417+In brief, a mark file contains a `door` with three arms. The door's sample type is the type of the data in question - in our case the `$user` structure. The `+grab` arm contains methods for converting _to_ our mark, and the `+grow` arm contains methods for converting _from_ our mark. The `+noun` arms are mandatory, and then we've added `+json` arms which respectively call the `+from-js` and `+to-js` functions from our `json-test.hoon` library. The final `+grad` arm defines various revision control functions, in our case we've delegated these to the `%noun` mark.
418+
419+From this mark file, Clay can build mark conversion gates between the `%json` mark and our `%user` mark, allowing the conversion of `$json` data to a `$user` structure and vice versa.
420+
421+### Try it out
422+
423+First, we'll save the code above as `user.hoon` in the `/mar` directory our of `%base` desk:
424+
425+```
426+> |commit %base
427+>=
428++ /~zod/base/9/mar/user/hoon
429+```
430+
431+Let's quickly create a `$json` object to work with:
432+
433+```
434+> =jon (need (de-json:html '{"joined":1631440078,"username":"john456","name":["John","William","Smith"],"email":"john.smith@example.com"}'))
435+> jon
436+[ %o
437+ p
438+ { [p='email' q=[%s p='john.smith@example.com']]
439+ [p='name' q=[%a p=~[[%s p='John'] [%s p='William'] [%s p='Smith']]]]
440+ [p='username' q=[%s p='john456']]
441+ [p='joined' q=[%n p=~.1631440078]]
442+ }
443+]
444+```
445+
446+We'll also build our library so we can use its types from the dojo:
447+
448+```
449+> =user-lib -build-file %/lib/json-test/hoon
450+```
451+
452+Now we can ask Clay to build a mark conversion gate from a `%json` mark to our `%user` mark. We'll use a scry with a `%f` `care` which produces a static mark conversion gate:
453+
454+```
455+> =json-to-user .^($-(json user:user-lib) %cf /===/json/user)
456+```
457+
458+Let's try converting our `$json` to a `$user` structure with our new mark conversion gate:
459+
460+```
461+> =usr (json-to-user jon)
462+> usr
463+[ username='john456'
464+ name=[first='John' mid='William' last='Smith']
465+ joined=~2021.9.12..09.47.58
466+ email='john.smith@example.com'
467+]
468+```
469+
470+Now let's try the other direction. We'll again scry Clay to build a static mark conversion gate, this time _from_ `%user` _to_ `%json` rather than the reverse:
471+
472+```
473+> =user-to-json .^($-(user:user-lib json) %cf /===/user/json)
474+```
475+
476+Let's test it out by giving it our `$user` data:
477+
478+```
479+> (user-to-json usr)
480+[ %o
481+ p
482+ { [p='email' q=[%s p='john.smith@example.com']]
483+ [p='name' q=[%a p=~[[%s p='John'] [%s p='William'] [%s p='Smith']]]]
484+ [p='username' q=[%s p='john456']]
485+ [p='joined' q=[%n p=~.1631440078]]
486+ }
487+]
488+```
489+
490+Finally, let's see how that looks as JSON encoded in text:
491+
492+```
493+> (crip (en-json:html (user-to-json usr)))
494+'{"joined":1631440078,"username":"john456","name":["John","William","Smith"],"email":"john.smith@example.com"}'
495+```
496+
497+Usually (though not in all cases) these mark conversions will be performed implicitly by Gall or Eyre and you'd not deal with the mark conversion gates directly, but it's still informative to see them work explicitly.
498+
499+## Further reading
500+
501+[The Zuse library reference](/docs/hoon/reference/zuse/table-of-contents) - This includes documentation of the JSON parsing, printing, encoding and decoding functions.
502+
503+[The Marks section of the Clay documentation](/docs/arvo/clay/marks/marks) - Comprehensive documentation of `mark`s.
504+
505+[The External API Reference section of the Eyre documentation](/docs/arvo/eyre/external-api-ref) - Details of the webserver vane Eyre's external API.
506+
507+[The Iris documentation](/docs/arvo/iris/iris) - Details of the web client vane Iris, which may be used to fetch external JSON data among other things.
508+
509+[Strings Guide](/docs/hoon/guides/strings) - Atom printing functions like `+scot` will often be useful for JSON encoding - see the [Encoding in Text](/docs/hoon/guides/strings#encoding-in-text) section for usage.
510+
511+[Parsing Guide](/docs/hoon/guides/parsing) - Learn how to write functional parsers in hoon which can be used with `+su`.
content/docs/hoon/guides/parsing.md+48−21
@@ -9,6 +9,8 @@ knowledge of parsing is required, and we will explain the basic structure of how
99parsing works in a purely functional language such as Hoon before moving on to
1010how it is implemented in Hoon.
1111
12+**Note:** For JSON printing/parsing and encoding/decoding, see the [JSON Guide](/docs/hoon/guides/json-guide).
13+
1214## What is parsing? {#what-is-parsing}
1315
1416A program which takes a raw sequence of characters as an input and produces a data
@@ -42,20 +44,24 @@ the parsing routine on the string `"1"` and looks for an integer, and so it
4244returns the integer `1`. However, taking into account what was said above about
4345parsers returning the unparsed portion of the string as well, we should
4446represent this return as a tuple. So we should expect something like this:
47+
4548```
4649> (parse "1" integer)
4750[1 ""]
4851> (parse "123" integer)
4952[1 "23"]
5053```
54+
5155What if we wish to parse the rest of the string? We would need to apply the
5256`parse` function again:
57+
5358```
5459> (parse (parse "123" integer) integer)
5560[12 "3"]
5661> (parse (parse (parse "123" integer) integer) integer)
5762[123 ""]
5863```
64+
5965So we see that we can parse strings larger than one character by stringing
6066together parsing functions for single characters. Thus in addition to parsing
6167functions for single input characters, we want _parser combinators_ that
@@ -75,15 +81,14 @@ are quite a few), but ought to be
7581sufficient to get started with parsing in Hoon and be equipped to discover the
7682remainder yourself.
7783
78−
7984## Basic types
8085
8186In this section we discuss the types most commonly used for Hoon parsers. In short:
8287
83− - A `hair` is the position in the text the parser is at,
84− - A `nail` is parser input,
85− - An `edge` is parser output,
86− - A `rule` is a parser.
88+- A `hair` is the position in the text the parser is at,
89+- A `nail` is parser input,
90+- An `edge` is parser output,
91+- A `rule` is a parser.
8792
8893### `hair`
8994
@@ -102,6 +107,7 @@ is in case it hits something unexpected during parsing.
102107```hoon
103108++ nail [p=hair q=tape]
104109```
110+
105111We recall from our [discussion above](#what-is-parsing) that parsing functions must keep
106112track of both what has been parsed and what has yet to be parsed. Thus a `nail`
107113consists of both a `hair`, giving the line and column up to which the input
@@ -122,6 +128,7 @@ what has theoretically already been parsed up to that point.
122128```hoon
123129++ edge [p=hair q=(unit [p=* q=nail])]
124130```
131+
125132An `edge` is the output of a parser. If parsing succeeded, `p` is the location
126133of the original input `tape `up to which the text has been parsed. If parsing
127134failed, `p` will be the first `hair` at which parsing failed.
@@ -136,6 +143,7 @@ of what is to be parsed. If `q` is not null, `p` and `p.q.q` are identical.
136143```hoon
137144++ rule _|:($:nail $:edge)
138145```
146+
139147A `rule` is a gate which takes in a `nail` and returns an `edge` - in other
140148words, a parser.
141149
@@ -160,6 +168,7 @@ of the input `nail`.
160168> edg
161169[p=[p=1 q=2] q=[~ [p='a' q=[p=[p=1 q=2] q="bc"]]]]
162170```
171+
163172We note that `p.edg` is `[p=1 q=2]`, indicating that the next character to be
164173parsed is in line 1, column 2. `q.edg` is not null, indicating that parsing
165174succeeded. `p.q.edg` is `'a'`, which is the result of the parse. `p.q.q.edg` is the same as `p.edg`, which is always the case for
@@ -167,11 +176,13 @@ succeeded. `p.q.edg` is `'a'`, which is the result of the parse. `p.q.q.edg` is
167176`q.q.edg` is `"bc"`, which is the part of the input `tape` that has yet to be parsed.
168177
169178Now let's see what happens when parsing fails.
179+
170180```
171181> =edg ((just 'b') [[1 1] "abc"])
172182> edg
173183[p=[p=1 q=1] q=~]
174184```
185+
175186Now we have that `p.edg` is the same as the input `hair`, `[1 1]`, meaning the
176187parser has not advanced since parsing failed. `q.edg` is null, indicating that
177188parsing has failed.
@@ -186,11 +197,13 @@ produces a `rule` that attempts to match that `cord` against the beginning of
186197the input.
187198
188199Let's see what happens when we successfully parse the entire input `tape`.
200+
189201```
190202> =edg ((jest 'abc') [[1 1] "abc"])
191203> edg
192204[p=[p=1 q=4] q=[~ [p='abc' q=[p=[p=1 q=4] q=""]]]]
193205```
206+
194207`p.edg` is `[p=1 q=4]`, indicating that the next character to be parsed is at
195208line 1, column 4. Of course, this does not exist since the input `tape` was only
1962093 characters long, so this actually indicates that the entire `tape` has been
@@ -199,21 +212,25 @@ successfully parsed (since the `hair` does not advance in the case of failure).
199212remains to be parsed.
200213
201214What happens if we only match some of the input `tape`?
215+
202216```
203217> =edg ((jest 'ab') [[1 1] "abc"])
204218> edg
205219[p=[p=1 q=3] q=[~ [p='ab' q=[p=[p=1 q=3] q="c"]]]]
206220```
221+
207222Now we have that the result, `p.q.edg`, is `'ab'`, while the remainder `q.q.q.edg`
208223is `"c"`. So `+jest` has successfully parsed the first two characters, while the
209224last character remains. Furthermore, we still have the information that the
210225remaining character was in line 1 column 3 from `p.edg` and `p.q.q.edg`.
211226
212227What happens when `+jest` fails?
228+
213229```
214230> ((jest 'bc') [[1 1] "abc"])
215231[p=[p=1 q=1] q=~]
216232```
233+
217234Despite the fact that `'bc'` appears in `"abc"`, because it was not at the
218235beginning the parse failed. We will see in [parser
219236combinators](#parser-combinators) how to modify this `rule` so that it
@@ -237,6 +254,7 @@ replaces the parsing result with `cus`.
237254
238255Here we see that `p.q` of the `edge` returned by the `rule` created with `+cold`
239256is `%foo`.
257+
240258```
241259> ((cold %foo (just 'a')) [[1 1] "abc"])
242260[p=[p=1 q=2] q=[~ u=[p=%foo q=[p=[p=1 q=2] q="bc"]]]]
@@ -246,7 +264,6 @@ One common scenario where `+cold` sees play is when writing [command line
246264interface (CLI) apps](/docs/hoon/guides/cli-tutorial). We usher the
247265reader there to find an example where `+cold` is used.
248266
249−
250267### `+knee`
251268
252269Another important function in the parser builder library is `+knee`, used for building
@@ -254,7 +271,6 @@ recursive parsers. We delay discussion of `+knee` to the
254271[section below](#recursive-parsers) as more context is needed to explain it
255272properly.
256273
257−
258274## Outside callers
259275
260276Since `hair`s, `nail`s, etc. are only utilized within the context of writing
@@ -295,7 +311,6 @@ For additional information including additional examples see [4g: Parsing (Outsi
295311For the remainder of this tutorial we will make use of `+scan` so that we do not
296312need to deal directly with `nail`s except where it is ilustrative to do so.
297313
298−
299314### Parsing atoms
300315
301316[Recall](/docs/hoon/hoon-school/lists) that `cord`s are atoms with the aura
@@ -312,7 +327,6 @@ The standard library provides a number of gates that take a `rule` and
312327produce a new modified `rule` according to some process. We call these _parser modifiers_. These are
313328documented among the [parser builders](/docs/hoon/reference/stdlib/4f).
314329
315−
316330### `+ifix`
317331
318332`+ifix` modifies a `rule` so that it matches that `rule` only when it is
@@ -322,11 +336,11 @@ surrounded on both sides by text that matches a pair of `rule`s, which is discar
322336> (scan "(42)" (ifix [pal par] (jest '42')))
323337'42'
324338```
339+
325340`+pal` and `+par` are shorthand for `(just '(')` and `(just ')')`, respectively. All
326341ASCII glyphs have counterparts of this sort, documented
327342[here](/docs/hoon/reference/stdlib/4h).
328343
329−
330344### `+star` {#star}
331345
332346`+star` is used to apply a `rule` repeatedly. Recall that `+just` only parses
@@ -343,7 +357,9 @@ We can use `+star` to get the rest of the `tape`:
343357> ((star (just 'a')) [[1 1] "aaa"])
344358[p=[p=1 q=4] q=[~ [p=[i='a' t=<|a a|>] q=[p=[p=1 q=4] q=""]]]]
345359```
360+
346361and we note that the parsing ceases when it fails.
362+
347363```
348364> ((star (just 'a')) [[1 1] "aaab"])
349365[p=[p=1 q=4] q=[~ [p=[i='a' t=<|a a|>] q=[p=[p=1 q=4] q="b"]]]]
@@ -358,9 +374,11 @@ combinators](/docs/hoon/reference/stdlib/4e). First we introduce a few
358374combinators, then we examine more closely how `;~` is used to chain them together.
359375
360376The syntax to combine `rule`s is
377+
361378```hoon
362379;~(combinator rule1 rule2 ... ruleN)
363380```
381+
364382The `rule`s are composed together using the combinator as an
365383intermediate function, which takes product of a `rule` (an `edge`) and a `rule` and turns
366384it into a sample (a `nail`) for the next `rule` to handle. We elaborate on this
@@ -409,42 +427,46 @@ take this opportunity to think about it carefully.
409427The `rule` created by `;~(combinator [list rule])` may be understood
410428inductively. To do this, let's consider the base case where our `[list rule]` has only a
411429single entry.
430+
412431```
413432> (scan "star" ;~(plug (jest 'star')))
414433'star'
415434```
435+
416436Our output is identical to that given by `scan "star" (jest 'star')`. This is to
417437be expected. The combinator `+plug` is specifically used for chaining together
418438`rule`s in the `[list rule]`, but if there is only one `rule`, there is nothing
419439to chain. Thus, swapping out `+plug` for another combinator makes no difference here:
440+
420441```
421442> (scan "star" ;~(pose (jest 'star')))
422443'star'
423444> (scan "star" ;~((glue com) (jest 'star')))
424445'star'
425446```
447+
426448`;~` and the combinator only begin to play a role once the `[list rule]` has at
427449least two elements. So let's look at an example done with `+plug`, the simplest
428450combinator.
451+
429452```
430453> (scan "star" ;~(plug (jest 'st') (jest 'ar')))
431454['st' 'ar']
432455```
456+
433457Our return suggests that we first parsed `"star"` with the `rule` `(jest 'st')` and passed
434−the resulting `edge` to `(jest 'ar')` - in other words, we called `+plug` on `(jest
435−'st')` and the `edge` returned once it had been used to parse `"star"`. Thus
458+the resulting `edge` to `(jest 'ar')` - in other words, we called `+plug` on `(jest 'st')` and the `edge` returned once it had been used to parse `"star"`. Thus
436459`+plug` was the glue that allowed us to join the two `rule`s, and `;~` performed
437460the gluing operation. And so, swapping `+plug` for `+pose` results in a crash,
438461which clues us into the fact that the combinator now has an effect since there
439462is more than one `rule`.
463+
440464```
441465> (scan "star" ;~(pose (jest 'st') (jest 'ar')))
442466{1 3}
443467syntax error
444468```
445469
446−
447−
448470## Parsing numbers
449471
450472Functions for parsing numbers are documented in [4j: Parsing (Bases and Base
@@ -461,15 +483,19 @@ for parsing decimal numbers.
461483## Recursive parsers
462484
463485Naively attempting to write a recursive `rule`, i.e. like
486+
464487```
465488> |-(;~(pose den ;~(pose $ (easy ~))))
466489```
490+
467491results in an error.
492+
468493```
469494-find.,.+6
470495-find.,.+6
471496rest-loop
472497```
498+
473499Thus some special sauce is required, the `+knee` function.
474500
475501`+knee` takes in a noun that is the default value of the parser, typically given
@@ -494,7 +520,6 @@ the parser to improve performance. In [parsing arithmetic
494520expressions](#parsing-arithmetic-expressions) we will be writing a recursive
495521parser making use of `+knee` and `~+` throughout.
496522
497−
498523# Parsing arithmetic expressions
499524
500525In this section we will be applying what we have learned to write a parser for
@@ -514,6 +539,7 @@ for arithmetic expressions informally.
514539First lets look at the code we're going to use, and then dive into explaining
515540it. If you'd like to follow along, save the following as `expr-parse.hoon` in
516541your `gen/` folder.
542+
517543```hoon
518544:: expr-parse: parse arithmetic expressions
519545::
@@ -544,9 +570,10 @@ your `gen/` folder.
544570```
545571
546572Informally, the grammar here is:
547− - A factor is either an integer or an expression surrounded by parentheses.
548− - A term is either a factor or a factor times a term.
549− - An expression is either a term or a term plus an expression.
573+
574+- A factor is either an integer or an expression surrounded by parentheses.
575+- A term is either a factor or a factor times a term.
576+- An expression is either a term or a term plus an expression.
550577
551578### Factors, terms, and expressions
552579
@@ -568,8 +595,7 @@ for expressions.
568595A _factor_ is either a decimal number or an expression surrounded by parentheses. Put
569596into Hoon terms, a decimal number is parsed by the `rule` `+dem` and an
570597expression is parsed by removing the surrounding parentheses and then passing
571−the result to the expression parser arm `+expr`, given by the `rule` `(ifix [pal
572−par] expr)`. Since we want to parse our expression with one or the other, we
598+the result to the expression parser arm `+expr`, given by the `rule` `(ifix [pal par] expr)`. Since we want to parse our expression with one or the other, we
573599chain these two `rule`s together using the monadic applicator rune `;~` along
574600with `+pose`, which says to try each rule in succession until one of them works.
575601
@@ -578,6 +604,7 @@ recursive rule. Thus we need to make use of `+knee`. The first argument for
578604`+knee` is `*@ud`, since our final answer should be a `@ud`.
579605
580606Then follows the definition of the gate utilized by `+knee`:
607+
581608```hoon
582609 |. ~+
583610 ;~ pose
@@ -585,6 +612,7 @@ Then follows the definition of the gate utilized by `+knee`:
585612 (ifix [pal par] expr)
586613 ==
587614```
615+
588616`~+` is used to cache the parser, so that it does not need to be computed over
589617and over again. Then it follows the `rule` we described above.
590618
@@ -615,7 +643,6 @@ accomplish this:
615643The rest of the `+expr` arm is structured just like how `+factor` is, and for
616644the same reasons.
617645
618−
619646#### Parsing terms
620647
621648A _term_ is either a factor times a term or a factor. This is handled similarly
content/docs/hoon/guides/strings.mdnew file+531
@@ -0,0 +1,531 @@
1++++
2+title = "Strings"
3+weight = 4
4+template = "doc.html"
5++++
6+
7+This document discusses hoon's two main string types: `cord`s (as well as its
8+subsets `knot` and `term`) and `tape`s. The focus of this
9+document is on their basic properties, syntax and the most common text-related
10+functions you'll regularly encounter. In particular, it discusses conversions
11+and the encoding/decoding of atom auras in strings.
12+
13+Hoon has a system for writing more elaborate functional parsers, but that is not
14+touched on here. Instead, see the [Parsing](/docs/hoon/guides/parsing) guide.
15+Hoon also has a type for UTF-32 strings, but those are rarely used and not
16+discussed in this document.
17+
18+There are a good deal more text manipulation functions than are discussed here.
19+See the [Further Reading](#further-reading) section for details.
20+
21+## `tape`s vs. text atoms
22+
23+As mentioned, urbit mainly deals with two kinds of strings: `tape`s and
24+`cord`/`knot`/`term`s. The former is a list of individual UTF-8 characters.
25+The latter three encode UTF-8 strings in a single atom.
26+
27+Cords may contain any UTF-8 characters, while `knot`s and `term`s only allow a
28+smaller subset. Each of these are discussed below in the [Text
29+atoms](#text-atoms) section.
30+
31+Text atoms like `cord`s are more efficient to store and move around. They are
32+also more efficient to manipulate with simple bitwise operations. Their downside
33+is that UTF-8 characters vary in their byte-length. ASCII characters are all
34+8-bit, but others can occupy up to four bytes. Accounting for this variation in
35+character size can complicate otherwise simple functions. Tapes, on the other
36+hand, don't have this problem because each character is a separate item in the
37+list, regardless of it byte-length. This fact makes it much easier to process
38+tapes in non-trivial ways with simple list functions.
39+
40+In light of this, a general rule of thumb is to use cords for simple things like
41+storing chat messages or exchanging them over the network. If text requires
42+complex processing on the other hand, it is generally easier with tapes. Note
43+there _are_ cord manipulation functions in the standard library, so you needn't
44+always convert cords to tapes for processing, it just depends on the case.
45+
46+Next we'll look at these different types of strings in more detail.
47+
48+## Text atoms
49+
50+### `cord`
51+
52+A [`cord`](/docs/hoon/reference/stdlib/2q#cord) has an aura of `@t`. It denotes
53+UTF-8 text encoded in an atom, little-endian. That is, the first character in
54+the text is the least-significant byte. A cord may contain any UTF-8 characters,
55+there are no restrictions.
56+
57+The `hoon` syntax for a cord is some text wrapped in single-quotes like:
58+
59+```hoon
60+'This is a cord!'
61+```
62+
63+single-quotes and backslashes must be escaped with a backslash like:
64+
65+```hoon
66+'\'quotes\' \\backslashes\\'
67+```
68+
69+Characters can also be entered as hex, they just have to be escaped by a
70+backslash. For example, `'\21\21\21'` will render as `'!!!'`. This is useful for
71+entering special characters such as line breaks like `'foo\0abar'`.
72+
73+Cords divided over multiple lines are allowed. There are two ways to do this.
74+The first is to start and end with three single-quotes like:
75+
76+```hoon
77+'''
78+foo
79+bar
80+baz
81+'''
82+```
83+
84+The line endings will be encoded Unix-style as line feed characters like:
85+
86+```hoon
87+'foo\0abar\0abaz'
88+```
89+
90+The second is to begin with a single-quote like usual, then break the line by
91+ending it with a backslash and start the next line with a forward-slash like:
92+
93+```hoon
94+'foo\
95+/bar\
96+/baz'
97+```
98+
99+This will be parsed to:
100+
101+```hoon
102+'foobarbaz'
103+```
104+
105+### `knot`
106+
107+A [`knot`](/docs/hoon/reference/stdlib/2q#knot) has an aura of `@ta`, and is a
108+subset of a [`cord`](#cord). It allows lower-case letters, numbers, and four
109+special characters: Hyphen, tilde, underscore and period. Its restricted set of
110+characters is intended to be URL-safe.
111+
112+The `hoon` syntax for a knot is a string containing any of the aforementioned
113+characters prepended with `~.` like:
114+
115+```hoon
116+~.abc-123.def_456~ghi
117+```
118+
119+### `term`
120+
121+A [`term`](/docs/hoon/reference/stdlib/2q#term) has an aura of `@tas`, and is a
122+subset of a [`knot`](#knot). It only allows lower-case letters, numbers, and
123+hyphens. Additionally, the first character cannot be a hyphen or number. This is
124+a very restricted text atom, and is intended for naming data structures and the
125+like.
126+
127+The `hoon` syntax for a term is a string conforming to the prior description,
128+prepended with a `%` like:
129+
130+```hoon
131+%foo-123
132+```
133+
134+#### A note about `term` type inference
135+
136+There is actually an even more restricted text atom form with the same `%foo`
137+syntax as a term, where the type of the text is the text itself. For example, in
138+the dojo:
139+
140+```
141+> `%foo`%foo
142+%foo
143+```
144+
145+The hoon parser will, by default, infer the type of `%foo`-style syntax this
146+way. If we try with the dojo type printer:
147+
148+```
149+> ? %foo
150+ %foo
151+%foo
152+```
153+
154+This type-as-itself is used for many things, such as unions like:
155+
156+```hoon
157+?(%foo %bar %bas)
158+```
159+
160+In order to give `%foo` the more generic `@tas` aura, it must be explicitly
161+upcast like:
162+
163+```
164+> ? `@tas`%foo
165+ @tas
166+%foo
167+```
168+
169+This is something to be wary of. For example, if you wanted to form a `(set @tas)` you might think to do:
170+
171+```hoon
172+(silt (limo ~[%foo %bar %baz]))
173+```
174+
175+However, this will actually form a set of the union `?(%foo %bar %baz)` due to
176+the specificity of type inference:
177+
178+```
179+> ? (silt (limo ~[%foo %bar %baz]))
180+ ?(%~ [?(n=%bar n=%baz n=%foo) l=nlr(?(%bar %baz %foo)) r=nlr(?(%bar %baz %foo))])
181+[n=%baz l={%bar} r={%foo}]
182+```
183+
184+One further note about the type-as-itself form: Ocassionally you may wish to
185+form a union of strings which contain characters disallowed in `term`s. To get
186+around this, you can enclose the text after the `%` with single-quotes like
187+`%'HELLO!'`.
188+
189+### Aura type validity
190+
191+The hoon parser will balk at `cord`s, `knot`s and `term`s containing invalid
192+characters. However, because they're merely auras, any atom can be cast to them.
193+When cast (or clammed), they will **not** be validated in terms of whether the
194+characters are allowed in the specified aura.
195+
196+For example, you can do this:
197+
198+```
199+> `@tas`'!%* $@&'
200+%!%* $@&
201+```
202+
203+This means you cannot rely on mere aura-casting if you need the text to conform
204+to the specified aura's restrictions. Instead, there are a couple of function in
205+the standard library to check text aura validity:
206+[`+sane`](/docs/hoon/reference/stdlib/4b#sane) and
207+[`+sand`](/docs/hoon/reference/stdlib/4b#sane).
208+
209+The `+sane` function takes an argument of either `%ta` or `%tas` to validate
210+`@ta` and `@tas` respectively (you can technically give it `%t` for `@t` too but
211+there's no real point). It will return `%.y` if the given atom is valid for the
212+given aura, and `%.n` if it isn't. For example:
213+
214+```
215+> ((sane %tas) 'foo')
216+%.y
217+> ((sane %tas) 'foo!')
218+%.n
219+```
220+
221+The `+sand` function does the same thing, but rather than returning a `?` it
222+returns a `unit` of the given atom, or `~` if validation failed. For example:
223+
224+```
225+> `(unit @tas)`((sand %tas) 'foo')
226+[~ %foo]
227+> `(unit @tas)`((sand %tas) 'foo!')
228+~
229+```
230+
231+## `tape`
232+
233+A [`tape`](/docs/hoon/reference/stdlib/2q#tape) is the other
234+main string type in hoon. Rather than a single atom, it's instead a list of
235+individual `@tD` characters (the `D` specifies a bit-length of 8, see the
236+[Auras](/docs/hoon/reference/auras#bitwidth) documentation for
237+details). The head of the list is the first character in the string.
238+
239+The `hoon` syntax for a tape is some text wrapped in double-quotes like:
240+
241+```hoon
242+"This is a tape!"
243+```
244+
245+Double-quotes, backslashes and left-braces must be escaped by a backslash
246+character:
247+
248+```hoon
249+"\"double-quotes\" \\backslash\\ left-brace:\{"
250+```
251+
252+Like with `cord`s, characters can also be entered as hex escaped by a backslash
253+so `"\21\21\21"` renders as `"!!!"`.
254+
255+Tapes divided over multiple lines are allowed. Unlike [`cord`](#cord)s, there is
256+only one way to do this, which is by starting and ending with three
257+double-quotes like:
258+
259+```hoon
260+"""
261+foo
262+bar
263+baz
264+"""
265+```
266+
267+The line endings will be encoded Unix-style as line feed characters like:
268+
269+```hoon
270+"foo\0abar\0abaz"
271+```
272+
273+As mentioned earlier, tapes are lists of single characters:
274+
275+```
276+> `tape`~['f' 'o' 'o']
277+"foo"
278+```
279+
280+This means they can be manipulated with ordinary list functions:
281+
282+```
283+> `tape`(turn "foobar" succ)
284+"gppcbs"
285+```
286+
287+### Interpolation
288+
289+Tapes, unlike cords, allow string interpolation. Arbitrary `hoon` may be
290+embedded in the tape syntax and its product will be included in the resulting
291+tape. There are two ways to do it:
292+
293+#### Manual
294+
295+In the first case, the code to be evaluated is enclosed in braces. The type of
296+the product of the code must itself be a tape. For example, if the `@p` of our
297+ship is stored in `our`, simply doing `"{our}"` will fail because its type will
298+be `@p` rather than `tape`. Instead, we must explicitly use the
299+[`+scow`](/docs/hoon/reference/stdlib/4m#scow) function to
300+render `our` as a tape:
301+
302+```
303+> "{(scow %p our)}"
304+"~zod"
305+```
306+
307+Another example:
308+
309+```
310+> "[{(scow %p our)} {(scow %da now)}]"
311+"[~zod ~2021.10.3..08.59.10..2335]"
312+```
313+
314+#### Automatic
315+
316+Rather than having to manually render data as a `tape`, angle brackets _inside_
317+the braces tell the interpreter to automatically pretty-print the product of the
318+expression as a tape. This way we needn't use functions like `+scow` and can
319+just reference things like `our` directly:
320+
321+```
322+> "{<our>}"
323+~zod
324+```
325+
326+Another example:
327+
328+```
329+> "{<(add 1 2)>}"
330+"3"
331+```
332+
333+And another:
334+
335+```
336+> "{<our now>}"
337+"[~zod ~2021.10.3..09.01.14..1654]"
338+```
339+
340+## Conversions
341+
342+Tapes can easily be converted to cords and vice versa. There are two stdlib
343+functions for this purpose: [`+crip`](/docs/hoon/reference/stdlib/4b#crip) and
344+[`+trip`](/docs/hoon/reference/stdlib/4b#trip). The former converts a `tape` to
345+a `cord` and the latter does the opposite. For example:
346+
347+```
348+> (crip "foobar")
349+'foobar'
350+> (trip 'foobar')
351+"foobar"
352+```
353+
354+Knots and terms can also be converted to tapes with `+trip`:
355+
356+```
357+> (trip %foobar)
358+"foobar"
359+> (trip ~.foobar)
360+"foobar"
361+```
362+
363+Likewise, the output of `+crip` can be cast to a knot or term:
364+
365+```
366+> `@tas`(crip "foobar")
367+%foobar
368+> `@ta`(crip "foobar")
369+~.foobar
370+> `@tas`(need ((sand %tas) (crip "foobar")))
371+%foobar
372+```
373+
374+## Encoding in text
375+
376+It's common to encode atoms in cords or knots, particularly when constructing a
377+[scry](/docs/arvo/concepts/scry) [`path`](/docs/hoon/reference/stdlib/2q#path)
378+or just a `path` in general. There are two main functions for this purpose:
379+[`+scot`](/docs/hoon/reference/stdlib/4m#scot) and
380+[`+scow`](/docs/hoon/reference/stdlib/4m#scow). The former produces a `knot`,
381+and the latter produces a `tape`. Additionally, there are two more functions for
382+encoding `path`s in cords and tapes respectively:
383+[`+spat`](/docs/hoon/reference/stdlib/4m#spat) and
384+[`+spud`](/docs/hoon/reference/stdlib/4m#spud).
385+
386+### `+scot` and `+spat`
387+
388+`+scot` encodes atoms of various auras in a `knot` (or `cord`/`term` with
389+casting). It takes two arguments: the aura in a `@tas` and the atom to be
390+encoded. For example:
391+
392+```
393+> (scot %p ~zod)
394+~.~zod
395+
396+> (scot %da now)
397+~.~2021.10.4..07.35.54..6d41
398+
399+> (scot %ux 0xaa.bbbb)
400+~.0xaa.bbbb
401+```
402+
403+Note the aura of the atom needn't actually match the specified aura:
404+
405+```
406+> (scot %ud ~zod)
407+~.0
408+```
409+
410+Hoon can of course be evaluated in its arguments as well:
411+
412+```
413+> (scot %ud (add 1 1))
414+~.2
415+```
416+
417+You'll most commonly see this used in constructing a `path` like:
418+
419+```
420+> /(scot %p our)/garden/(scot %da now)/foo/(scot %ud 123.456)
421+[~.~zod %garden ~.~2021.10.4..07.43.14..a556 %foo ~.123.456 ~]
422+
423+> `path`/(scot %p our)/garden/(scot %da now)/foo/(scot %ud 123.456)
424+/~zod/garden/~2021.10.4..07.43.23..9a0f/foo/123.456
425+```
426+
427+`+spat` simply encodes a `path` in a cord like:
428+
429+```
430+> (spat /foo/bar/baz)
431+'/foo/bar/baz'
432+```
433+
434+### `+scow` and `+spud`
435+
436+`+scow` is the same as [`+scot`](#scot-and-spat) except it produces a tape
437+rather than a knot. For example:
438+
439+```
440+> (scow %p ~zod)
441+"~zod"
442+
443+> (scow %da now)
444+"~2021.10.4..07.45.25..b720"
445+
446+> (scow %ux 0xaa.bbbb)
447+"0xaa.bbbb"
448+```
449+
450+`+spud` simply encodes a `path` in a tape:
451+
452+```
453+> (spud /foo/bar/baz)
454+"/foo/bar/baz"
455+```
456+
457+## Decoding from text
458+
459+For decoding atoms of particular auras encoded in cords, there are three
460+functions: [`+slat`](/docs/hoon/reference/stdlib/4m#slat),
461+[`+slav`](/docs/hoon/reference/stdlib/4m#slav), and
462+[`+slaw`](/docs/hoon/reference/stdlib/4m#slaw). Additionally, there is
463+[`+stab`](/docs/hoon/reference/stdlib/4m#stab) for decoding a cord to a path.
464+
465+`+slav` parses the given cord with the aura specified as a `@tas`, crashing if
466+the parsing failed. For example:
467+
468+```
469+> `@da`(slav %da '~2021.10.4..11.26.54')
470+~2021.10.4..11.26.54
471+
472+> `@p`(slav %p '~zod')
473+~zod
474+
475+> (slav %p 'foo')
476+dojo: hoon expression failed
477+```
478+
479+`+slaw` is like `+slav` except it produces a `unit` which is null if parsing
480+failed, rather than crashing. For example:
481+
482+```
483+> `(unit @da)`(slaw %da '~2021.10.4..11.26.54')
484+[~ ~2021.10.4..11.26.54]
485+
486+> `(unit @p)`(slaw %p '~zod')
487+[~ ~zod]
488+
489+> (slaw %p 'foo')
490+~
491+```
492+
493+`+slat` is a curried version of `+slaw`, meaning it's given the aura and
494+produces a new gate which takes the actual cord. For example:
495+
496+```
497+> `(unit @da)`((slat %da) '~2021.10.4..11.26.54')
498+[~ ~2021.10.4..11.26.54]
499+
500+> `(unit @p)`((slat %p) '~zod')
501+[~ ~zod]
502+
503+> ((slat %p) 'foo')
504+~
505+```
506+
507+Finally, `+stab` parses a cord containing a path to a `path`. For example:
508+
509+```
510+> (stab '/foo/bar/baz')
511+/foo/bar/baz
512+```
513+
514+## Futher reading
515+
516+- [Parsing](/docs/hoon/guides/parsing) - A guide to writing fully-fledged
517+ functional parsers in hoon.
518+
519+- [Auras](/docs/hoon/reference/auras) - Details of auras in hoon.
520+
521+- [stdlib 2b: List logic](/docs/hoon/reference/stdlib/2b) - Standard library
522+ functions for manipulating lists, which are useful for dealing with tapes.
523+
524+- [stdlib 2q: Molds and Mold-builders](/docs/hoon/reference/stdlib/2q) - Several
525+ text types are defined in this section of the standard library.
526+
527+- [stdlib 4b: Text processing](/docs/hoon/reference/stdlib/4b) - Standard
528+ library functions for manipulating and converting tapes and strings.
529+
530+- [stdlib 4m: Formatting functions](/docs/hoon/reference/stdlib/4m) - Standard
531+ library functions for encoding and decoding atom auras in strings.
content/docs/hoon/hoon-school/_index.md+28−33
@@ -7,36 +7,31 @@ aliases = ["/docs/byte/0/", "/docs/byte", "/docs/learn/hoon/hoon-tutorial/"]
77insert_anchor_links = "right"
88+++
99
10−This series is designed to teach you Hoon without assuming you have an extensive
11−programming background. In fact, you should be able to follow much of it even if
12−you have no programming experience at all, though of course experience helps. We
13−strongly encourage you to try out all the examples of each lesson. These lessons
14−are meant for the beginner, but they aren't meant to be skimmed. Each lesson
15−falls into one of two categories: **readings**, which are prose-heavy
16−explanations of Hoon fundamentals, and **walkthroughs**, which are line-by-line
17−explanations of example programs. Walkthroughs are found between readings,
18−offering a practical implementation of the concepts taught in the reading
19−before.
20−
21−If you're curious about why Urbit is written in this new language, we recommend
22−reading the [Hoon overview](/docs/hoon/overview) that covers the high-level
23−design decisions behind the language.
24−
25−Chapter 1 introduces and explains the fundamental concepts you need in order to
26−understand Hoon's semantics.
27−
28−Hoon is a "subject-oriented" programming language &mdash; every expression of
29−Hoon is evaluated relative to a **subject**. The subject is a piece of data that
30−represents the environment, or the context, of an expression. After reading
31−Chapter 1 you should understand what the subject is and how to refer to its
32−various parts. In this chapter you'll also learn about
33−**[cores](/docs/glossary/core/)**, which are an important data structure in
34−Hoon. Once you get the hang of [cores](/docs/glossary/core/) you'll be able to
35−write your own functions in Hoon.
36−
37−Chapter 2 covers the type system, writing basic apps, and the workings of the
38−Arvo kernel.
39−
40−You should also consider enrolling in Hooniversity, a regularly held
41−community-run course which follows along the Hoon School curriculum and may be
42−found at [Hooniversity](https://hooniversity.org/).
10+- [1.1 Introduction](https://urbit.org/docs/hoon/hoon-school/intro)
11+- [1.1.1 Walkthrough: List of Numbers](https://urbit.org/docs/hoon/hoon-school/list-of-numbers)
12+- [1.2 Nouns](https://urbit.org/docs/hoon/hoon-school/nouns)
13+- [1.3 Hoon Syntax](https://urbit.org/docs/hoon/hoon-school/hoon-syntax)
14+- [1.3.1 Walkthrough: Conditionals](https://urbit.org/docs/hoon/hoon-school/conditionals)
15+- [1.4 Gates (Hoon Functions)](https://urbit.org/docs/hoon/hoon-school/gates)
16+- [1.4.1 Walkthrough: Recursion](https://urbit.org/docs/hoon/hoon-school/recursion)
17+- [1.5 Lists](https://urbit.org/docs/hoon/hoon-school/lists)
18+- [1.5.1 Walkthrough: Fibonacci Sequence](https://urbit.org/docs/hoon/hoon-school/fibonacci)
19+- [1.6 The Subject and Its Legs](https://urbit.org/docs/hoon/hoon-school/the-subject-and-its-legs)
20+- [1.6.1 Walkthrough: Ackermann Function](https://urbit.org/docs/hoon/hoon-school/ackermann)
21+- [1.7 Arms and Cores](https://urbit.org/docs/hoon/hoon-school/arms-and-cores)
22+- [1.7.1 Walkthrough: Caesar Cipher](https://urbit.org/docs/hoon/hoon-school/caesar)
23+- [1.8 Doors](https://urbit.org/docs/hoon/hoon-school/doors)
24+- [1.8.1 Bank Account](https://urbit.org/docs/hoon/hoon-school/bank-account)
25+- [1.9 Generators](https://urbit.org/docs/hoon/hoon-school/generators)
26+- [2.1 Atoms, Auras, and Simple Cell Types](https://urbit.org/docs/hoon/hoon-school/atoms-auras-and-simple-cell-types)
27+- [2.2 Type Checking and Type Inference](https://urbit.org/docs/hoon/hoon-school/type-checking-and-type-inference)
28+- [2.3 Structures and Complex Types](https://urbit.org/docs/hoon/hoon-school/structures-and-complex-types)
29+- [2.3.1 Walkthrough: Libraries](https://urbit.org/docs/hoon/hoon-school/libraries)
30+- [2.3.2 Molds](https://urbit.org/docs/hoon/hoon-school/molds)
31+- [2.4 Standard Library: Trees, Sets, and Maps](https://urbit.org/docs/hoon/hoon-school/trees-sets-and-maps)
32+- [2.5 Type Polymorphism](https://urbit.org/docs/hoon/hoon-school/type-polymorphism)
33+- [2.5.1 Walkthrough: Iron Polymorphism and Wet Polymorphism](https://urbit.org/docs/hoon/hoon-school/iron-polymorphism)
34+- [2.5.2 Walkthrough: Lead Polymorphism](https://urbit.org/docs/hoon/hoon-school/lead-polymorphism)
35+- [2.6 Behn](https://urbit.org/docs/hoon/hoon-school/behn)
36+- [2.7 Gall](https://urbit.org/docs/hoon/hoon-school/gall)
37+- [2.7.1 Gall Walkthrough: Egg Timer](https://urbit.org/docs/hoon/hoon-school/egg-timer)
content/docs/hoon/hoon-school/caesar.md+25−25
@@ -27,7 +27,7 @@ information. Implementing it in a program is just a fun exercise.
2727Below is a generator that performs a Caesar cipher on a tape. This example
2828isn't the most compact implementation of such a cipher in Hoon, but it
2929demonstrates important principles that more laconic code would not. Save it as
30−`caesar.hoon` in your `/gen` directory.
30+`caesar.hoon` in the `/gen` directory of your `%base` desk.
3131
3232```hoon
3333!:
@@ -131,7 +131,7 @@ itself before reading the explanation.
131131The `!:` in the first line of the above code enables a full stack trace in the
132132event of an error.
133133
134−`|= [msg=tape steps=@ud]` creates a [gate](/docs/glossary/gate/) that takes a cell. The head of this cell
134+`|= [msg=tape steps=@ud]` creates a [gate](/docs/glossary/gate/) that takes a cell. The head of this cell
135135is a `tape`, which is a string type that's a list of `cord`s. Tapes are represented
136136as text surrounded by double-quotes, such as this: `"a tape"`. We give this input
137137tape the face `msg`. The tail of our cell is a `@ud` -- an unsigned decimal [atom](/docs/glossary/atom/)
@@ -141,7 +141,7 @@ tape the face `msg`. The tail of our cell is a `@ud` -- an unsigned decimal [ato
141141second child expression as the subject. In this case, we evaluate the
142142expressions in the code chunk below against the [core](/docs/glossary/core/) declared later, which
143143allows us reference the core's contained [arms](/docs/glossary/arm/) before they are defined. Without
144−`=<`, we would need to put the code chunk below at the bottom of our program. In Hoon, as previously
144+`=<`, we would need to put the code chunk below at the bottom of our program. In Hoon, as previously
145145stated, we always want to keep the longer code towards the bottom of our programs - `=<` helps us do that.
146146
147147```hoon
@@ -150,19 +150,19 @@ stated, we always want to keep the longer code towards the bottom of our program
150150(unshift msg steps)
151151```
152152
153−`=. msg (cass msg)` changes the input string `msg` to lowercases. `=.` changes
153+`=. msg (cass msg)` changes the input string `msg` to lowercases. `=.` changes
154154the leg of the subject to something else. In our case, the leg to be changed is
155155`msg`, and the thing to replace it is `(cass msg)`. `cass` is a standard-library
156156gate that converts uppercase letters to lowercase.
157157
158−`:- (shift msg steps)` and `(unshift msg steps)` simply composes a
158+`:- (shift msg steps)` and `(unshift msg steps)` simply composes a
159159cell of a right-shifted cipher and a left-shifted cipher of our original message.
160160We will see how this is done using the core described below, but this is the final
161161output of our generator.
162162
163163`|%` creates a `core`, the second child of `=<`. Everything after `|%` is part of that
164164second child `core`, and will be used as the subject of the first child of `=<`, described
165−above. The various parts, or `arm`s, of the `core` are denoted by `++` beneath it, for
165+above. The various parts, or `arm`s, of the `core` are denoted by `++` beneath it, for
166166instance:
167167
168168```hoon
@@ -174,21 +174,21 @@ instance:
174174```
175175
176176The `rotation` arm takes takes a specified number of characters off of a tape and
177−puts them on the end of the tape. We're going to use this to create our shifted alphabet,
177+puts them on the end of the tape. We're going to use this to create our shifted alphabet,
178178based on the number of `steps` given as an argument to our gate.
179179
180−`|= [my-alphabet=tape my-steps=@ud]` creates a gate that takes two arguments: `my-alphabet`, a `tape`,
180+`|= [my-alphabet=tape my-steps=@ud]` creates a gate that takes two arguments: `my-alphabet`, a `tape`,
181181and `my-steps`, a `@ud`.
182182
183−`=/ length=@ud (lent my-alphabet)` stores the length of `my-alphabet` to make the following
183+`=/ length=@ud (lent my-alphabet)` stores the length of `my-alphabet` to make the following
184184code a little clearer.
185185
186186`trim` is a a gate from the standard library that splits a tape at into two
187−parts at a specified position. So `=+ (trim (mod my-steps length) my-alphabet)` splits the
187+parts at a specified position. So `=+ (trim (mod my-steps length) my-alphabet)` splits the
188188tape `my-alphabet` into two parts, `p` and `q`, which are now directly available in the subject.
189189We call the modulus operation `mod` to make sure that the point at which we split our `tape` is
190190a valid point inside of `my-alphabet` even if `my-steps` is greater than `length`, the length of
191−`my-alphabet`. Try trim in the dojo:
191+`my-alphabet`. Try trim in the dojo:
192192
193193```
194194> (trim 2 "abcdefg")
@@ -221,42 +221,42 @@ A `map` is a type equivalent to a dictionary in other languages: it's a data str
221221associates a key with a value. If, for example, we wanted to have an association
222222between `a` and 1 and `b` and 2, we could use a `map`.
223223
224−`|= [a=tape b=tape]` builds a gate that takes two tapes, `a` and `b`, as its
224+`|= [a=tape b=tape]` builds a gate that takes two tapes, `a` and `b`, as its
225225sample.
226226
227−`^- (map @t @t)` casts the gate to a `map` with a `cord` (or `@t`) key and a `cord`
227+`^- (map @t @t)` casts the gate to a `map` with a `cord` (or `@t`) key and a `cord`
228228value.
229229
230230You might wonder, if our gate in this arm takes `tape`s, why then are we producing
231231a map of `cord` keys and values?
232232
233−As we discussed earlier, a `tape` is a list of `cord`s. In this case what we are going to do
233+As we discussed earlier, a `tape` is a list of `cord`s. In this case what we are going to do
234234is map a single element of a `tape` (either our alphabet or shifted-alphabet) to an element of
235−a different `tape` (either our shifted-alphabet or our alphabet). This pair will therefore be
236−a pair of `cord`s. When we go to use this `map` to convert our incoming `msg`, we will take
235+a different `tape` (either our shifted-alphabet or our alphabet). This pair will therefore be
236+a pair of `cord`s. When we go to use this `map` to convert our incoming `msg`, we will take
237237each element (`cord`) of our `msg` `tape`, use it as a `key` when accessing our `map` and get
238238the corresponding `value` from that position in the `map`. This is how we're going to encode
239239or decode our `msg` `tape`.
240240
241−`=| chart=(map @t @t)` adds a [noun](/docs/glossary/noun/) to the subject with the default value of
241+`=| chart=(map @t @t)` adds a [noun](/docs/glossary/noun/) to the subject with the default value of
242242the `(map @t @t)` type, and gives that noun the face `chart`.
243243
244−`?. =((lent key-position) (lent value-result))` checks if the two `tape`s are the same length. If not,
245−the program crashes with an error message of `%uneven-lengths`, using `|~ %uneven-lengths !!`.
244+`?. =((lent key-position) (lent value-result))` checks if the two `tape`s are the same length. If not,
245+the program crashes with an error message of `%uneven-lengths`, using `|~ %uneven-lengths !!`.
246246
247247If the two `tape`s are of the same length, we continue on to create a trap.
248248`|-` creates a [trap](/docs/glossary/trap/), a gate that is called immediately.
249249
250−`?: |(?=(~ key-position) ?=(~ value-result))` checks if either `tape` is empty. If this is true, the
250+`?: |(?=(~ key-position) ?=(~ value-result))` checks if either `tape` is empty. If this is true, the
251251`map-maker` arm is finished and can return `chart`, the `map` that we have been
252252creating.
253253
254254If the above test finds that the `tape`s are not empty, we trigger a recursion
255255that constructs our `map`: `$(chart (~(put by chart) i.a i.b), a t.a, b t.b)`.
256256This code recursively adds an entry in our `map` where the head of the `tape` `a`
257−maps to the value of the head of `tape` `b` with `~(put by chart)`, our calling
257+maps to the value of the head of `tape` `b` with `~(put by chart)`, our calling
258258of the `put` arm of the `by` map-engine core (note that `~(<wing> <door> <sample>`) is
259−a shorthand for `%~ <wing> <door> <sample>` (see the [Calls % ('cen')](/docs/hoon/reference/rune/cen#censig)
259+a shorthand for `%~ <wing> <door> <sample>` (see the [Calls % ('cen')](/docs/hoon/reference/rune/cen#censig)
260260documentation for more information). The recursion also "consumes"
261261those heads with every iteration by changing `a` and `b` to their tails using `a t.a, b t.b`.
262262
@@ -271,7 +271,7 @@ first.
271271 (~(put by (map-maker key-position value-result)) ' ' ' ')
272272```
273273
274−`|= [key-position=tape value-result=tape]` creates a gate that takes two `tapes`.
274+`|= [key-position=tape value-result=tape]` creates a gate that takes two `tapes`.
275275
276276We use the `put` arm of the `by` core on the next line, giving it a `map` produced
277277by the `map-maker` arm that we created before as its sample. This adds an entry to the
@@ -300,12 +300,12 @@ that we can use to encode and decode messages.
300300In both cases, we create a gate that accepts a `@ud` named `steps`.
301301
302302In `encoder`:
303−`=/ value-tape=tape (rotation alpha steps)` creates a `value-tape` noun by calling `rotation`
303+`=/ value-tape=tape (rotation alpha steps)` creates a `value-tape` noun by calling `rotation`
304304on `alpha`. `alpha` is our arm which contains a `tape` of the entire alphabet. The
305305`value-tape` will be the list of `value`s in our `map`.
306306
307307In `decoder`:
308−`=/ key-tape (rotation alpha steps)` does the same work, but when passed to `space-adder`
308+`=/ key-tape (rotation alpha steps)` does the same work, but when passed to `space-adder`
309309it will be the list of `key`s in our `map`.
310310
311311`(space-adder alpha value-tape)`, for `encoder`, and `(space-adder key-tape alpha)`, for
content/docs/hoon/hoon-school/egg-timer.md+33−28
@@ -5,10 +5,10 @@ template = "doc.html"
55aliases = ["/docs/learn/hoon/hoon-tutorial/egg-timer/"]
66+++
77
8−The Arvo operating system is divided up into modules called vanes. Gall is the vane responsible for providing an API for building stateful applications in Urbit. Gall is a complex system that takes a lot of getting used to, so let's dip our toes in with a simple egg-timer app.
8+The Arvo operating system is divided up into modules called vanes. Gall is the vane responsible for providing an API for building stateful applications in Urbit. Gall is a complex system that takes a lot of getting used to, so let's dip our toes in with a simple egg-timer app.
99
10−The following code sample should be saved as `/home/app/egg-timer.hoon`
11−After committing: `|start %egg-timer` and poke with `:egg-timer ~s10`
10+The following code sample should be saved as `/base/app/egg-timer.hoon`
11+After committing: `|rein %base [& %egg-timer]` and poke with `:egg-timer ~s10`
1212
1313```hoon
1414/+ default-agent
@@ -46,7 +46,7 @@ After committing: `|start %egg-timer` and poke with `:egg-timer ~s10`
4646--
4747```
4848
49−The first thing to notice is that we are creating a core (`|%`) and a door (`|_`). This is a typical style for Gall programming wherein types are defined in the first core and your application is defined in the following door.
49+The first thing to notice is that we are creating a core (`|%`) and a door (`|_`). This is a typical style for Gall programming wherein types are defined in the first core and your application is defined in the following door.
5050Our door will have type `agent:gall` as specified in `sys/zuse.hoon`
5151
5252```hoon
@@ -55,10 +55,10 @@ Our door will have type `agent:gall` as specified in `sys/zuse.hoon`
5555--
5656```
5757
58−The core here defines only one type: `card`.
59−A `card` is a request to Arvo to do something for us. In this case, the only card used will be a `%wait` request to Behn which we'll discuss later.
58+The core here defines only one type: `card`.
59+A `card` is a request to Arvo to do something for us. In this case, the only card used will be a `%wait` request to Behn which we'll discuss later.
6060
61−It's important to note that the name `card` is technically arbitrary. By convention, however, you will see it called `card` practically everywhere.
61+It's important to note that the name `card` is technically arbitrary. By convention, however, you will see it called `card` practically everywhere.
6262
6363The sample of the door(`|_`) is:
6464
@@ -66,12 +66,12 @@ The sample of the door(`|_`) is:
6666=bowl:gall
6767```
6868
69−You can find the full definition of `bowl` in `sys/zuse.hoon`, but for now it's enough to know that includes contextual data used by Gall with particular faces. Below are some important such faces:
69+You can find the full definition of `bowl` in `sys/zuse.hoon`, but for now it's enough to know that includes contextual data used by Gall with particular faces. Below are some important such faces:
7070
71−- `our` The ship this code is running on
72−- `src` The ship the current event originated from
73−- `eny` Guaranteed-fresh entropy
74−- `now` The current time
71+- `our` The ship this code is running on
72+- `src` The ship the current event originated from
73+- `eny` Guaranteed-fresh entropy
74+- `now` The current time
7575
7676We give `bowl:gall` the face `bowl`.
7777Additionally, we use `+*` to create two structures for future use:
@@ -80,10 +80,11 @@ Additionally, we use `+*` to create two structures for future use:
8080+* this .
8181 def ~(. (default-agent this %.n) bowl)
8282```
83+
8384`this` is our current context(the door).
8485`def` uses `default-agent` to produce a standard `gall:agent` door, from which we will instance default definitions for our unused arms.
8586
86−All Gall agents have a fixed set of 10 arms. In this trivial case, we will specify only two and use the default definitions from `default-agent` for the remaining arms.
87+All Gall agents have a fixed set of 10 arms. In this trivial case, we will specify only two and use the default definitions from `default-agent` for the remaining arms.
8788
8889```hoon
8990++ on-poke
@@ -94,33 +95,34 @@ All Gall agents have a fixed set of 10 arms. In this trivial case, we will spec
9495 [%pass /egg-timer %arvo %b %wait (add now.bowl t)]~
9596```
9697
97−The `++on-poke` arm evaluates to a gate which takes a sample `[mark vase]`. `mark` is a type specification and `vase` is a cell of `[specification value]`
98+The `++on-poke` arm evaluates to a gate which takes a sample `[mark vase]`. `mark` is a type specification and `vase` is a cell of `[specification value]`
9899Note: since `++on-poke` may take many different samples, it would be prudent to add a `%noun` mark check here.
99−In this example, we assume that our sample will contain a `@dr` and pull it from the `vase` with `=/ t !<(@dr vase)`
100+In this example, we assume that our sample will contain a `@dr` and pull it from the `vase` with `=/ t !<(@dr vase)`
100101`@dr` is an aura for a 128-bit relative date. Here are a few examples.
101102
102−- `~s17` 17 seconds
103−- `~m20` 20 minutes
103+- `~s17` 17 seconds
104+- `~m20` 20 minutes
104105- `~m13s37` 13 minutes, 37 seconds
105−- `~d42` 42 days
106+- `~d42` 42 days
106107
107108As a matter of good type hygiene, we explicitly cast the output of this gate with `^-` to ensure we are producing the correct structure for Gall to handle.
108−Our specification is `(quip card _this)` which produces a type, `[(list card) _this]`. Note that `_this` is irregular form of `$_(this)` which normalizes to the type of `this`, our door.
109+Our specification is `(quip card _this)` which produces a type, `[(list card) _this]`. Note that `_this` is irregular form of `$_(this)` which normalizes to the type of `this`, our door.
109110
110−Next we use the `:_` rune which is the inverted form of `:-`, the cell construction rune.
111+Next we use the `:_` rune which is the inverted form of `:-`, the cell construction rune.
111112
112113```hoon
113114:_ this
114115 [%pass /egg-timer %arvo %b %wait (add now.bowl t)]~
115116```
117+
116118Our card should follow the basic form `[%pass /my/wire a-note]`
117119In this case, our card will ask Arvo to `%pass` a note along the wire `/egg-timer` to Behn(`%b`) containing a `%wait` request.
118120Behn will start a timer for us, and will respond along our wire, `/egg-timer`.
119121
120−`now.bowl` is the current time of type `@da`, and `t` was declared as `@dr`. Because they are both atoms, we can add `now` and `t` to produce an atom that is `t` units of time into the future from `now`. That produced atom can be interpreted as a `@da`.
122+`now.bowl` is the current time of type `@da`, and `t` was declared as `@dr`. Because they are both atoms, we can add `now` and `t` to produce an atom that is `t` units of time into the future from `now`. That produced atom can be interpreted as a `@da`.
121123The calculated time will be passed via Arvo to Behn with instruction to `%wait @da`, i.e., to set a timer.
122124
123−That's all for our `++on-poke` arm. But what about when the timer goes off? Behn will create a `gift`, a similar construct to our `card` which will be dispatched back to us via Gall in the `++on-arvo` arm.
125+That's all for our `++on-poke` arm. But what about when the timer goes off? Behn will create a `gift`, a similar construct to our `card` which will be dispatched back to us via Gall in the `++on-arvo` arm.
124126
125127```hoon
126128++ on-arvo
@@ -130,20 +132,22 @@ That's all for our `++on-poke` arm. But what about when the timer goes off? Be
130132 ~& "Timer went off!"
131133 [~ this]
132134```
133−`++on-arvo` evaluates to a gate whose sample is a cell of `wire` and `sign-arvo` here given default faces. The syntax of `=wire` is a shortcut for `wire=wire`; it's a common pattern to shadow the name of a type when you only have one instance of the type and are not going to refer to the type itself.
134−A `wire` is an alias for a path. Our `wire` will be the path we provided in our `++on-poke` card. If we needed to do something particular depending on which request triggered this Arvo card, we could use the wire to do so.
135135
136−Note: since multiple vanes can send many sorts of cards via `++on-arvo`, it would be prudent to check if `sign-arvo` is `[%b %wake *]`. Since our trivial example assumes the card is `%wake` from Behn, we will forgo that better practice here.
136+`++on-arvo` evaluates to a gate whose sample is a cell of `wire` and `sign-arvo` here given default faces. The syntax of `=wire` is a shortcut for `wire=wire`; it's a common pattern to shadow the name of a type when you only have one instance of the type and are not going to refer to the type itself.
137+A `wire` is an alias for a path. Our `wire` will be the path we provided in our `++on-poke` card. If we needed to do something particular depending on which request triggered this Arvo card, we could use the wire to do so.
138+
139+Note: since multiple vanes can send many sorts of cards via `++on-arvo`, it would be prudent to check if `sign-arvo` is `[%b %wake *]`. Since our trivial example assumes the card is `%wake` from Behn, we will forgo that better practice here.
140+
141+Next we have the same cast we used in `++on-poke` to make sure we produce the correct type for Gall. `(quip card _this)` resolves to a type `[(list card) _this]`
137142
138−Next we have the same cast we used in `++on-poke` to make sure we produce the correct type for Gall. `(quip card _this)` resolves to a type `[(list card) _this]`
139143```
140144~& "Timer went off!"
141145```
142146
143−`~&` is the debugging printf rune. Here we're using it to output a message. We could, however, modify this line of code to do any other computation when `++on-arvo` is called.
147+`~&` is the debugging printf rune. Here we're using it to output a message. We could, however, modify this line of code to do any other computation when `++on-arvo` is called.
144148
145149We need to produce a noun of type `(quip card _this)` i.e., `[(list card) _this]`.
146−In this case, we will not produce any card or change application state. Therefore we simply produce a cell of a null list and our original context, `[~ this]`.
150+In this case, we will not produce any card or change application state. Therefore we simply produce a cell of a null list and our original context, `[~ this]`.
147151
148152```hoon
149153++ on-init on-init:def
@@ -156,4 +160,5 @@ In this case, we will not produce any card or change application state. Therefo
156160++ on-fail on-fail:def
157161--
158162```
163+
159164Finally, we define the remaining 8 unused but required Gall Agent armsas instances of the default arms provided in `/lib/default-agent.hoon`.
content/docs/hoon/hoon-school/generators.md+13−14
@@ -16,9 +16,8 @@ There are three kinds of generators: naked, `%say`, and `%ask`. There also used
1616### Naked Generators
1717
1818A naked generator is simply a `gate`; that is, it is an anonymous function that
19−takes a `sample` (argument) and produces a [noun](/docs/glossary/noun/). All you need to do is write a
20−`gate` and put it into a file in the `/gen` directory. Let's take a look at a
21−very simple one:
19+takes a `sample` (argument) and produces a [noun](/docs/glossary/noun/). All you
20+need to do is write a `gate` and put it into a file in the `/gen` directory of a desk on your ship. Let's take a look at a very simple one:
2221
2322```hoon
2423|= a=*
@@ -26,7 +25,8 @@ a
2625```
2726
2827This generator takes one argument of any noun and produces it without any
29−changes. Once you put this into a file named `echo.hoon` in the `/gen` directory, you must make your ship recognize the change by inputting `|commit %home` in the dojo. You can then run it from the dojo:
28+changes. Put this into a file named `echo.hoon` in the `/gen` directory of your
29+`%base` desk. You must make your ship recognize the change by inputting `|commit %base` in the dojo. You can then run it from the dojo:
3030
3131```
3232> +echo 42
@@ -64,7 +64,7 @@ generator to see something more familiar:
6464```
6565
6666Now let's create a generator with two arguments instead of one. Save the code
67−below as `add.hoon` in the `/gen` directory.
67+below as `add.hoon` in the `/gen` directory of your `%base` desk.
6868
6969```hoon
7070|= [a=@ud b=@ud]
@@ -104,7 +104,7 @@ So, more formally, a `%say` generator is a `cell`. The head of that cell is the
104104output data and the `mark` describing that data.
105105
106106Below is an example of a `%say` generator. Save it to `add.hoon` in the `/gen`
107−directory.
107+directory of your `%base` desk.
108108
109109```hoon
110110:- %say
@@ -133,7 +133,7 @@ Recall that the rune `:-` produces a cell, with the first following expression
133133as its head and the second following expression as its tail.
134134
135135The expression above creates a cell with `%say` as the head. The tail is
136−the `|= *` expression on the line that follows.
136+the `|= *` expression on the line that follows.
137137
138138```hoon
139139|= *
@@ -141,10 +141,10 @@ the `|= *` expression on the line that follows.
141141(add 40 2)
142142```
143143
144−`|= *` constructs a [gate](/docs/glossary/gate/) that takes a noun. This [gate](/docs/glossary/gate/) will itself produce a
144+`|= *` constructs a [gate](/docs/glossary/gate/) that takes a noun. This [gate](/docs/glossary/gate/) will itself produce a
145145`cask`, which is cell formed by the prepending `:-`. The head of that `cask` is
146146`%noun` and the tail is the rest of the program, `(add 40 2)`. The tail of the
147−`cask` will be our actual data produced by the body of the program: in this
147+`cask` will be our actual data produced by the body of the program: in this
148148case, just adding 40 and 2 together.
149149
150150#### `%say` generators with arguments
@@ -216,7 +216,7 @@ second part, besides its position:
216216```
217217
218218Let's look at an example that uses all three parts. Save the code below in a
219−file called `dice.hoon` in your `/gen` directory.
219+file called `dice.hoon` in the `/gen` directory of your `%base` desk.
220220
221221```hoon
222222:- %say
@@ -311,7 +311,7 @@ to explain how this kind of generator works.
311311##### `%ask` example
312312
313313The code below is an `%ask` generator that checks if the user inputs "blue" when
314−prompted. Save it as `axe.hoon` in `/gen`.
314+prompted. Save it as `axe.hoon` in the `/gen` directory of your `%base` desk.
315315
316316```hoon
317317/- sole
@@ -379,7 +379,7 @@ This code might be familiar. Just as with their `%say` cousins, `%ask`
379379generators need to produce a `cell`, the head of which specifies what kind of
380380generator we are running.
381381
382−With `|= *`, we create a gate and ignore the standard arguments we are given,
382+With `|= *`, we create a gate and ignore the standard arguments we are given,
383383because we're not using them.
384384
385385```hoon
@@ -434,7 +434,6 @@ use to prompt the user. In the case of our example, we use `"color: "`.
434434**`produce`** is used to construct the output of the generator. In our example,
435435we produce a `tang`.
436436
437−
438437```hoon
439438|= t=tape
440439```
@@ -458,4 +457,4 @@ This is a [known issue](https://github.com/urbit/arvo/issues/840) to be resolved
458457
459458## Conclusion
460459
461−You've now reached the end of Chapter 1 of the Hoon tutorial. Ideally you should have a fair understanding of the fundamental concepts of subject-oriented programming: limbs, legs, faces, wings, arms, cores, gates, and [doors](/docs/glossary/door/). If you can master these concepts you should have little or no trouble learning to write substantial Hoon programs.
460+You've now reached the end of Chapter 1 of the Hoon tutorial. Ideally you should have a fair understanding of the fundamental concepts of subject-oriented programming: limbs, legs, faces, wings, arms, cores, gates, and [doors](/docs/glossary/door/). If you can master these concepts you should have little or no trouble learning to write substantial Hoon programs.
content/docs/hoon/hoon-school/hoon-syntax.md+1−1
@@ -254,7 +254,7 @@ The irregular form of the `.=` rune is just `=( )`:
254254%.y
255255```
256256
257−The examples above have another irregular form: `(add 11 11)`. This is the irregular form of `%+`, which calls a [gate](/docs/glossary/gate/) (i.e., a Hoon function) with two arguments for the sample.
257+The examples above contain another irregular form: `(add 11 11)`. This is the irregular form of `%+`, which calls a [gate](/docs/glossary/gate/) (i.e., a Hoon function) with two arguments for the sample.
258258
259259```
260260> %+ add 11 11
content/docs/hoon/hoon-school/intro.mdnew file+121
@@ -0,0 +1,121 @@
1++++
2+title = "1.1 Introduction"
3+weight = 1
4+template = "doc.html"
5+aliases = ["/docs/learn/hoon/hoon-tutorial/setup/"]
6++++
7+
8+This series is designed to teach you Hoon without assuming you have an extensive
9+programming background. In fact, you should be able to follow much of it even if
10+you have no programming experience at all, though of course experience helps. We
11+strongly encourage you to try out all the examples of each lesson. These lessons
12+are meant for the beginner, but they aren't meant to be skimmed. Each lesson
13+falls into one of two categories: **readings**, which are prose-heavy
14+explanations of Hoon fundamentals, and **walkthroughs**, which are line-by-line
15+explanations of example programs. Walkthroughs are found between readings,
16+offering a practical implementation of the concepts taught in the reading
17+before.
18+
19+If you're curious about why Urbit is written in this new language, we recommend
20+reading the [Hoon overview](/docs/hoon/overview) that covers the high-level
21+design decisions behind the language.
22+
23+Chapter 1 introduces and explains the fundamental concepts you need in order to
24+understand Hoon's semantics.
25+
26+Hoon is a "subject-oriented" programming language — every expression of
27+Hoon is evaluated relative to a **subject**. The subject is a piece of data that
28+represents the environment, or the context, of an expression. After reading
29+Chapter 1 you should understand what the subject is and how to refer to its
30+various parts. In this chapter you'll also learn about
31+**[cores](/docs/glossary/core/)**, which are an important data structure in
32+Hoon. Once you get the hang of [cores](/docs/glossary/core/) you'll be able to
33+write your own functions in Hoon.
34+
35+Chapter 2 covers the type system, writing basic apps, and the workings of the
36+Arvo kernel.
37+
38+## Environment Setup
39+
40+Before beginning, you'll need to get a development ship running and configure an
41+appropriate editor. See the [Environment Setup](/docs/development/environment)
42+guide for details.
43+
44+## Getting started
45+
46+Once you've created your development ship, let's try a basic command. Type `(add 2 2)` at the prompt and hit return. Your screen now shows:
47+
48+```
49+fake: ~zod
50+ames: czar: ~zod on 31337 (localhost only)
51+http: live (insecure, public) on 80
52+http: live (insecure, loopback) on 12321
53+> (add 2 2)
54+4
55+~zod:dojo>
56+```
57+
58+You just used a function from the Hoon standard library, `add`. Next, quit Urbit
59+with `ctrl-d`:
60+
61+```
62+> (add 2 2)
63+4
64+~zod:dojo>
65+$
66+```
67+
68+Your ship isn't running anymore and you're back at your computer's normal
69+terminal prompt. If your ship is `~zod`, then you can restart the ship by
70+typing:
71+
72+```sh
73+urbit zod
74+```
75+
76+## Another Noun
77+
78+You've already used a standard library function to produce one value, in the
79+Dojo. Now that your ship is running again, let's try another. Enter the number
80+`17`.
81+
82+We won't show the `~zod:dojo> ` prompt from here on out. We'll just show the
83+echoed command along with its result.
84+
85+You'll see:
86+
87+```
88+> 17
89+17
90+```
91+
92+You asked Dojo to evaluate `17` and it echoed the number back at you. This value
93+is a "noun". We'll talk more about [nouns](/docs/glossary/noun/) in [Lesson
94+1.2](/docs/hoon/hoon-school/nouns), but first let's write a very basic program.
95+
96+## Generators
97+
98+Generators are the most straightforward way to write Hoon programs. They are a
99+concept in Arvo, and involve saving Hoon code in a `.hoon` text file. While they
100+aren't strictly part of the Hoon language, we'll be dealing with generators
101+throughout this tutorial.
102+
103+The simplest type of generator is the **naked generator**. All naked generators
104+are `gates`: functions that take an argument and produce an output. To create a
105+generator, all you need to do is write a `gate`, save it in a `.hoon` file, and
106+add it to the `/gen` directory of a desk on your ship.
107+
108+To be able to add files easily, you'll need to mount a desk to the Unix
109+filesystem. We'll use the `%base` desk throughout Hoon School since we're using
110+a fake ship, but note a different one would be more suitable on a live ship. To
111+mount `%base`, just run `|mount %base` in the dojo. If you look in your
112+[pier](/docs/glossary/pier), you should now see a `base` folder. Once you've added
113+the `.hoon` file in `base/gen`, you'll need to run `|commit %base` in the dojo
114+so the new file is recognised by your ship. To run a generator named
115+`mygen.hoon`, you would type `+mygen <argument>` in your ship's dojo. If you
116+added it to a desk other than `%base`, you can run `+desk!mygen <argument>`
117+where `desk` is the desk you put it in.
118+
119+If this doesn't make sense yet, that's okay. In the [next
120+lesson](/docs/hoon/hoon-school/list-of-numbers), we will walk you through an
121+example `gate` that is run as a generator.
content/docs/hoon/hoon-school/list-of-numbers.md+3−3
@@ -20,7 +20,7 @@ Below is a simple Hoon program that takes a single number `n` from the user as i
2020$(count (add 1 count)) :: 8
2121```
2222
23−As we mentioned in the previous lesson, the easiest way to use such a program is to run it as a _generator_. Mount your desk `|mount %` (if you didn't do it before), saving a file in the `/home/gen` directory of your ship and commiting these changes `|commit %home` allows you to run it from your ship's Dojo (command line) as a generator. Save the above code there as `list.hoon`. Now you can run it in the Dojo with the command below (remember, without the `>`):
23+As we mentioned in the previous lesson, the easiest way to use such a program is to run it as a _generator_. Mount your `%base` desk with `|mount %base` (if you didn't do it before), saving a file in the `base/gen` directory of your ship and commiting these changes `|commit %base` allows you to run it from your ship's Dojo (command line) as a generator. Save the above code there as `list.hoon`. Now you can run it in the Dojo with the command below (remember, without the `>`):
2424
2525`> +list 5`
2626
@@ -89,7 +89,7 @@ In this case, the rune specifies that our gate's output must be `(list @)` -- th
8989
9090`?:` is a rune that evaluates whether its first child is `true` or `false`. If that child is `true`, the program branches to the second child. If it's `false`, it branches to the third child. `?:` takes three children.
9191
92−`=(end count)` checks if the user's input equals to the `count` value that we're incrementing to build the list. If these values are equal, we want to end the program, because our list has been built out to where it needs to be. Note that this expression is, in fact, a rune expression, just written a different way than you've seen so far. `=(end count)` is an _irregular form_ of `.= end count`, different in looks but identical in operation. `.=` is a rune that checks for the equality of its two children, and produces a `true` or `false` based on what it finds.
92+`=(end count)` checks if the user's input equals to the `count` value that we're incrementing to build the list. If these values are equal, we want to end the program, because our list has been built out to where it needs to be. Note that this expression is, in fact, a rune expression, just written a different way than you've seen so far. `=(end count)` is an _irregular form_ of `.= end count`, different in looks but identical in operation. `.=` is a rune that checks for the equality of its two children, and produces a `true` or `false` based on what it finds.
9393
9494`~` simply represents the `null` value. The program branches here if on line 5 it finds that `end` equals `count`. Lists in Hoon always end with `~`, so we need this to be the last thing we put in our list.
9595
@@ -97,7 +97,7 @@ In this case, the rune specifies that our gate's output must be `(list @)` -- th
9797
9898`:-` is a rune that creates a **cell**, an ordered pair of two values, such as `[1 2]`. It takes two children.
9999
100−In our case, `:- count` creates a cell out of whatever value is stored in `count`, and then with the product of line 8.
100+In our case, `:- count` creates a cell out of whatever value is stored in `count`, and then with the product of line 8.
101101
102102## Line 8
103103
content/docs/hoon/hoon-school/recursion.md+7−8
@@ -19,8 +19,8 @@ would be:
1919
2020Let's implement a factorial calculator in Hoon. To do so, we'll write a
2121recursive `gate` (Hoon's equivalent of a function) to perform the relevant
22−computation. Save the code below as `factorial.hoon` in your ship's `/gen`
23−directory.
22+computation. Save the code below as `factorial.hoon` in the `/gen` directory of
23+the `%base` desk on your ship.
2424
2525```hoon
2626|= n=@ud
@@ -185,11 +185,10 @@ skips the first match of a name.
185185### Exercises
186186
1871871. Write a recursive gate that produces the first _n_
188−[Fibonacci numbers](https://en.wikipedia.org/wiki/Fibonacci_number)
188+ [Fibonacci numbers](https://en.wikipedia.org/wiki/Fibonacci_number)
189189
1901902. Write a recursive gate that produces a list of moves to solve the
191−[Tower of Hanoi problem](https://en.wikipedia.org/wiki/Tower_of_Hanoi).
192−Disks are stacked on a pole by decreasing order of size. Move all of the
193−disks from one pole to another with a third pole as a spare, moving one
194−disc at a time, without putting a larger disk on top of a smaller disk.
195−
191+ [Tower of Hanoi problem](https://en.wikipedia.org/wiki/Tower_of_Hanoi).
192+ Disks are stacked on a pole by decreasing order of size. Move all of the
193+ disks from one pole to another with a third pole as a spare, moving one
194+ disc at a time, without putting a larger disk on top of a smaller disk.
content/docs/hoon/hoon-school/setup.mddeleted−105
@@ -1,105 +0,0 @@
1−+++
2−title = "1.1 Setup"
3−weight = 1
4−template = "doc.html"
5−aliases = ["/docs/learn/hoon/hoon-tutorial/setup/"]
6−+++
7−
8−Before we begin working on Hoon, you should first (1) have Urbit installed and (2) boot a ship that you can use for trying out Hoon examples. Interactive learning is far superior to passive reading.
9−
10−## What is an urbit?
11−
12−An **urbit** is an Urbit virtual computer with persistent state that can connect to the Urbit network. (Note the lowercase `u` here. "Urbit" is the entire software stack, whereas "an urbit" is a local instance.) Each urbit is associated with a unique number that plays three distinct roles: (1) it's an address on the Urbit network, (2) it's a cryptographic identity, and (3) it's (in principle) a human memorable name. Normally an urbit's name is represented as a string starting with `~`, as in `~zod` or `~taglux-nidsep`.
13−
14−These may not look like numbers, but they are. Each urbit name is written in a base-256 format, where each "digit" is a syllable. Imagine your phone number as a pronounceable string which sounds like a name in a foreign language. An ordinary user-level urbit is a "planet", and it's named by a 32-bit number. The latter is represented as a four-syllable string; e.g., the planet name `~taglux-nidsep` is the number 6,095,360.
15−
16−## Installing Urbit
17−
18−You can install Urbit on any Mac or Unix machine; if you're just trying out Urbit or creating a development ship, you can follow the steps for creating a development ship [here](/docs/development/environment). On Windows, make a virtual Linux machine using VirtualBox or a similar tool.
19−
20−Once you're finished, you can [boot your very own ship](/getting-started/). While you can develop in Hoon on your own ship on the live network, we strongly suggest developing on a development ship first.
21−
22−## Getting started
23−
24−Once you've created your development ship, let's try a basic command. Type `(add 2 2)` at the prompt and hit return. Your screen now shows:
25−
26−```
27−fake: ~zod
28−ames: czar: ~zod on 31337 (localhost only)
29−http: live (insecure, public) on 80
30−http: live (insecure, loopback) on 12321
31−> (add 2 2)
32−4
33−~zod:dojo>
34−```
35−
36−You just used a function from the Hoon standard library, `add`. Next, quit Urbit with `ctrl-d`:
37−
38−```
39−> (add 2 2)
40−4
41−~zod:dojo>
42−$
43−```
44−
45−Your ship isn't running anymore and you're back at your computer's normal terminal prompt. If your ship is `~zod`, then you can restart the ship by typing:
46−
47−```sh
48−urbit zod
49−```
50−
51−## Another Noun
52−
53−You've already used a standard library function to produce one value, in the Dojo. Now that your ship is running again, let's try another. Enter the number `17`.
54−
55−> We won't show the `~zod:dojo> ` prompt from here on out. We'll just show the echoed command along with its result.
56−
57−You'll see:
58−
59−```
60−> 17
61−17
62−```
63−
64−You asked Dojo to evaluate `17` and it echoed the number back at you. This value is a "noun". We'll talk more about [nouns](/docs/glossary/noun/) in [Lesson 1.2](/docs/hoon/hoon-school/nouns), but first let's write a very basic program.
65−
66−## Generators
67−
68−Generators are the most straightforward way to write Hoon programs. They are a concept in Arvo, and involve saving Hoon code in a `.hoon` text file. While they aren't strictly part of the Hoon language, we'll be dealing with generators throughout this tutorial.
69−
70−The simplest type of generator is the **naked generator**. All naked generators are `gates`: functions that take an argument and produce an output. Before creating a generator you need to [mount](/getting-started/) your `desk` to Unix. To create a generator, all you need to do is write a `gate` and put it into a file in the `/home/gen/` directory of your ship as a `.hoon` file. (Assuming you've already mounted with `|mount /=home=`.) After this, you need to run `|commit %home` in Dojo and the new file will be recognized by your ship. To run a generator named `mygen.hoon`, you would type `+mygen <argument>` in your ship's Dojo.
71−
72−If this doesn't make sense yet, that's okay. In the [next lesson](/docs/hoon/hoon-school/list-of-numbers), we will walk you through an example `gate` that is run as a generator.
73−
74−## Text editors
75−
76−Writing code in any language is typically done using a text editor, but common programs like Notepad, Microsoft Word, or OpenOffice Writer are not suitable for programming. You'll want instead a text editor that is specifically designed for writing code. This will assist with things such as colorizing keywords, finding patterns, matching parentheses and brackets, etc.
77−
78−Below is a complete list of text editors that have support for Hoon [syntax highlighting](https://en.wikipedia.org/wiki/Syntax_highlighting) -- an important tool for any programming language. For each of these editors, you'll need to download the editor and then you'll need to install some additional syntax-highlighter package. The process for adding Hoon support differs for every editor. For most newbie-friendly text editors, this is easily accomplished from within the editor itself, and you'll learn how to do so following a newbie tutorial for that editor.
79−
80−If you are brand new to programming, don't think too much about which editor to use; any of the newbie-friendly options will suit you.
81−
82−### Newbie-friendly text editors
83−
84−These editors are easy to use for first-time coders.
85−
86−#### Atom
87−Atom is free and open-source and runs on all major operating systems. It is available [here](https://atom.io/). A package for Hoon support is maintained by Tlon and may be obtained using the package manager within the editor by searching for `Hoon`.
88−
89−#### Sublime
90−Sublime is closed-source, but may be downloaded for free and there is no enforced time limit for evaluation. It runs on all major operating systems. It is available [here](https://www.sublimetext.com/).
91−
92−#### Visual Studio Code
93−Visual Studio Code is free and open-source and runs on all major operating systems. It is available [here](https://code.visualstudio.com/). Hoon support may be acquired in the Extensions menu within the editor by searching for `Hoon`.
94−
95−### Advanced text editors
96−
97−These text editors have a high learning curve and are only recommended for experienced programmers.
98−
99−#### Emacs
100−
101−Emacs is free and open-source and runs on all major operating systems. It is available [here](https://www.gnu.org/software/emacs/). Hoon support is available with [hoon-mode.el](https://github.com/urbit/hoon-mode.el).
102−
103−#### Vim
104−
105−Vim is free and open-source and runs on all major operating systems. It is available [here](https://www.vim.org/). Hoon support is available with [hoon.vim](https://github.com/urbit/hoon.vim) and is maintained by Tlon.
content/docs/hoon/hoon-school/type-polymorphism.md+81−81
@@ -5,9 +5,9 @@ template = "doc.html"
55aliases = ["/docs/learn/hoon/hoon-tutorial/type-polymorphism/"]
66+++
77
8−There are many cases in which one may want to write a function that accepts as input various different types of data. Such a function is said to be [polymorphic](https://en.wikipedia.org/wiki/Polymorphism_%28computer_science%29). ("Polymorphism" = "many forms"; so polymorphic functions accept many forms of data as input.)
8+There are many cases in which one may want to write a function that accepts as input various different types of data. Such a function is said to be [polymorphic](https://en.wikipedia.org/wiki/Polymorphism_%28computer_science%29). ("Polymorphism" = "many forms"; so polymorphic functions accept many forms of data as input.)
99
10−One relatively trivial form of polymorphism involves sub-typing. A [gate](/docs/glossary/gate/) whose sample is a raw `noun` can accept any Hoon data structure as input -- it's just that the sample will only be treated as a raw [noun](/docs/glossary/noun/). For example, consider the `copy` gate below:
10+One relatively trivial form of polymorphism involves sub-typing. A [gate](/docs/glossary/gate/) whose sample is a raw `noun` can accept any Hoon data structure as input -- it's just that the sample will only be treated as a raw [noun](/docs/glossary/noun/). For example, consider the `copy` gate below:
1111
1212```
1313> =copy |=(a=* [a a])
@@ -22,39 +22,39 @@ One relatively trivial form of polymorphism involves sub-typing. A [gate](/docs
2222[[72 101 108 108 111 33 0] [72 101 108 108 111 33 0]]
2323```
2424
25−`copy` takes the input, `a`, and returns a cell of `[a a]`. Because every piece of Hoon data is a noun, anything can be taken as input. Every other type in Hoon is a sub-type of `noun`. But the output of `copy` is always going to be just a cell of nouns; the type information of the original input value is not preserved by the gate. Consider the `tape` in the last example: `"Hello!"` was pretty-printed in the dojo as a raw noun, not as a string. So `copy` is a relatively uninteresting polymorphic function.
25+`copy` takes the input, `a`, and returns a cell of `[a a]`. Because every piece of Hoon data is a noun, anything can be taken as input. Every other type in Hoon is a sub-type of `noun`. But the output of `copy` is always going to be just a cell of nouns; the type information of the original input value is not preserved by the gate. Consider the `tape` in the last example: `"Hello!"` was pretty-printed in the dojo as a raw noun, not as a string. So `copy` is a relatively uninteresting polymorphic function.
2626
2727In this lesson we'll go over Hoon's support for more interesting polymorphic functions.
2828
2929## Polymorphic Properties of Cores
3030
31−Hoon supports type polymorphism at the [core](/docs/glossary/core/) level. That is, each core has certain polymorphic properties that are tracked and maintained as metadata by Hoon's type system. (See `+$ type` of `hoon.hoon`.) These properties determine the extent to which a core can be used as an interface for values of various types.
31+Hoon supports type polymorphism at the [core](/docs/glossary/core/) level. That is, each core has certain polymorphic properties that are tracked and maintained as metadata by Hoon's type system. (See `+$ type` of `hoon.hoon`.) These properties determine the extent to which a core can be used as an interface for values of various types.
3232
33−This is rather vaguely put so far. We can clarify by talking more specifically about the kinds of polymorphism supported in Hoon. There are two kinds of type polymorphism for cores: [genericity](https://en.wikipedia.org/wiki/Generic_programming), to include certain kinds of [parametric polymorphism](https://en.wikipedia.org/wiki/Parametric_polymorphism); and [variance polymorphism](https://en.wikipedia.org/wiki/Covariance_and_contravariance_%28computer_science%29), which involves making use of special sub-typing rules for cores.
33+This is rather vaguely put so far. We can clarify by talking more specifically about the kinds of polymorphism supported in Hoon. There are two kinds of type polymorphism for cores: [genericity](https://en.wikipedia.org/wiki/Generic_programming), to include certain kinds of [parametric polymorphism](https://en.wikipedia.org/wiki/Parametric_polymorphism); and [variance polymorphism](https://en.wikipedia.org/wiki/Covariance_and_contravariance_%28computer_science%29), which involves making use of special sub-typing rules for cores.
3434
35−If you don't understand these very well, that's okay. We'll explain them. Let's begin with the former.
35+If you don't understand these very well, that's okay. We'll explain them. Let's begin with the former.
3636
3737## Dry vs. Wet Cores
3838
39−To review briefly, a **core** is a pair of `[battery payload]`. The **battery** contains the various [arms](/docs/glossary/arm/) of the core (code), and the **payload** contains all the data needed to evaluate those arms correctly (data). Every arm is evaluated with its parent core as the subject. A **gate** (i.e., a Hoon function) is a core with exactly one arm named `$` and with a [payload](/docs/glossary/payload/) of the form: `[sample context]`. The **sample** is reserved for the function's argument value, and the **context** is any other data needed to evaluate `$` correctly.
39+To review briefly, a **core** is a pair of `[battery payload]`. The **battery** contains the various [arms](/docs/glossary/arm/) of the core (code), and the **payload** contains all the data needed to evaluate those arms correctly (data). Every arm is evaluated with its parent core as the subject. A **gate** (i.e., a Hoon function) is a core with exactly one arm named `$` and with a [payload](/docs/glossary/payload/) of the form: `[sample context]`. The **sample** is reserved for the function's argument value, and the **context** is any other data needed to evaluate `$` correctly.
4040
41−There are two kinds of cores: **dry** and **wet**. Dry cores, which are more typical, _don't_ make use of **genericity**. Wet cores do. In order to understand generic functions in Hoon, you have to understand the difference between dry and wet cores.
41+There are two kinds of cores: **dry** and **wet**. Dry cores, which are more typical, _don't_ make use of **genericity**. Wet cores do. In order to understand generic functions in Hoon, you have to understand the difference between dry and wet cores.
4242
43−The cores produced with the `|=`, `|-`, `|%`, and `|_` runes, among others, are all dry. The cores produced with the `|*` and `|@` runes are wet. (`|*` and `|@` are the wet versions of `|=` and `|%`, respectively.)
43+The cores produced with the `|=`, `|-`, `|%`, and `|_` runes, among others, are all dry. The cores produced with the `|*` and `|@` runes are wet. (`|*` and `|@` are the wet versions of `|=` and `|%`, respectively.)
4444
45−Briefly, the difference between dry and wet cores has to do with how they're treated at compile time, for type inference and type checking. During the type check, the product type of each arm is inferred. For computing a dry arm type, it's assumed that the arm's subject type is of the original parent core. For computing a wet arm type, the parent core type is used, except that the payload value may vary from the original type.
45+Briefly, the difference between dry and wet cores has to do with how they're treated at compile time, for type inference and type checking. During the type check, the product type of each arm is inferred. For computing a dry arm type, it's assumed that the arm's subject type is of the original parent core. For computing a wet arm type, the parent core type is used, except that the payload value may vary from the original type.
4646
47−Because of this, wet gates can be used as functions that take different input types at different call sites. We'll go over the dry/wet distinction in more detail below and explain why it matters.
47+Because of this, wet gates can be used as functions that take different input types at different call sites. We'll go over the dry/wet distinction in more detail below and explain why it matters.
4848
4949### Dry Cores
5050
51−A core's payload can change from its original value. In fact, this happens in the typical function call -- the default sample is replaced with an input value. How can we ensure that the core's arms are able to run correctly, that the payload type is still appropriate despite whatever changes it has undergone?
51+A core's payload can change from its original value. In fact, this happens in the typical function call -- the default sample is replaced with an input value. How can we ensure that the core's arms are able to run correctly, that the payload type is still appropriate despite whatever changes it has undergone?
5252
53−There is a type check for each arm of a dry core, intended to verify that the arm's parent core has a payload of the correct type. In this section we'll describe that type check, starting with typical gate usage.
53+There is a type check for each arm of a dry core, intended to verify that the arm's parent core has a payload of the correct type. In this section we'll describe that type check, starting with typical gate usage.
5454
55−When the `$` arm of a dry gate is evaluated it takes its parent core -- the dry gate itself -- as the subject, often with a modified sample _value_. But any change in sample _type_ should be conservative; the modified sample value must be of the same type as the default sample value (or possibly a subtype). When the `$` arm is evaluated it should have a subject of a type it knows how to use.
55+When the `$` arm of a dry gate is evaluated it takes its parent core -- the dry gate itself -- as the subject, often with a modified sample _value_. But any change in sample _type_ should be conservative; the modified sample value must be of the same type as the default sample value (or possibly a subtype). When the `$` arm is evaluated it should have a subject of a type it knows how to use.
5656
57−For illustration, consider the gate created by `add`, a function in the Hoon standard library. The structure of the `add` gate is as follows:
57+For illustration, consider the gate created by `add`, a function in the Hoon standard library. The structure of the `add` gate is as follows:
5858
5959```
6060 add
@@ -64,7 +64,7 @@ For illustration, consider the gate created by `add`, a function in the Hoon sta
6464 sample context
6565```
6666
67−The `add` code depends on the fact that there are two [atoms](/docs/glossary/atom/) in the sample: the numbers to be added together. Hence, it is appropriate that only a cell of atoms is permitted for the sample. We can look at the default sample of `add` at address `+6`:
67+The `add` code depends on the fact that there are two [atoms](/docs/glossary/atom/) in the sample: the numbers to be added together. Hence, it is appropriate that only a cell of atoms is permitted for the sample. We can look at the default sample of `add` at address `+6`:
6868
6969```
7070> +6:add
@@ -85,28 +85,28 @@ Any other type of value in the sample results in a `nest-fail` crash:
8585nest-fail
8686```
8787
88−This function call attempts to create a modified copy of the `add` gate, replacing the original sample `[0 0]` with `[12 "hello"]`, then evaluate the `$` arm of this modified core. (We ignore the `a` and `b` faces for now.) But this piece of code failed to compile; the type system knew to reject it.
88+This function call attempts to create a modified copy of the `add` gate, replacing the original sample `[0 0]` with `[12 "hello"]`, then evaluate the `$` arm of this modified core. (We ignore the `a` and `b` faces for now.) But this piece of code failed to compile; the type system knew to reject it.
8989
90−How does it know? The type system keeps track of two copies of the payload type for each core:
90+How does it know? The type system keeps track of two copies of the payload type for each core:
9191
92−+ The original payload type, i.e., the type of the payload when the core was first created. In the case of `add`, the original sample type is a cell of atoms, `[@ @]`. This original type information is always preserved, regardless of the argument values used to call `add`.
93−+ The current payload type, i.e., the type of the payload after any substitutions or other changes have been made. In the last `add` call, `(add 12 "hello")`, the sample would be a cell whose head is an `@ud`, and whose tail is a `tape`.
92+- The original payload type, i.e., the type of the payload when the core was first created. In the case of `add`, the original sample type is a cell of atoms, `[@ @]`. This original type information is always preserved, regardless of the argument values used to call `add`.
93+- The current payload type, i.e., the type of the payload after any substitutions or other changes have been made. In the last `add` call, `(add 12 "hello")`, the sample would be a cell whose head is an `@ud`, and whose tail is a `tape`.
9494
95−The type check at compile time compares these two types, and if the current payload type doesn't nest under the original payload, the compile fails with a `nest-fail` crash. (E.g., a cell of type `[@ud tape]` doesn't nest under `[@ @]`.) Otherwise, the original payload _type_ is used for evaluation, even though the original sample _value_ has been replaced. So the arm of a dry core is guaranteed to run with exactly the same subject type each time it is evaluated.
95+The type check at compile time compares these two types, and if the current payload type doesn't nest under the original payload, the compile fails with a `nest-fail` crash. (E.g., a cell of type `[@ud tape]` doesn't nest under `[@ @]`.) Otherwise, the original payload _type_ is used for evaluation, even though the original sample _value_ has been replaced. So the arm of a dry core is guaranteed to run with exactly the same subject type each time it is evaluated.
9696
97−The type check for each arm in a dry core can be understood as implementing a version of the ["Liskov substitution principle"](https://en.wikipedia.org/wiki/Liskov_substitution_principle). The arm works for some (originally defined) payload type `P`. Payload type `Q` nests under `P`. Therefore the arm works for `Q` as well, though for type inference purposes the payload is treated as a `P`. The inferred type of the arm is based on the assumption that it's evaluated with a subject type exactly like that of its original parent core -- i.e., whose payload is of type `P`.
97+The type check for each arm in a dry core can be understood as implementing a version of the ["Liskov substitution principle"](https://en.wikipedia.org/wiki/Liskov_substitution_principle). The arm works for some (originally defined) payload type `P`. Payload type `Q` nests under `P`. Therefore the arm works for `Q` as well, though for type inference purposes the payload is treated as a `P`. The inferred type of the arm is based on the assumption that it's evaluated with a subject type exactly like that of its original parent core -- i.e., whose payload is of type `P`.
9898
9999### Wet Cores (Genericity)
100100
101−The type checking and inference rules for arms are a bit different for wet cores. Whereas the dry arm is understood as having _exactly_ its parent core type for its subject, wet arms can be evaluated with payloads of various types.
101+The type checking and inference rules for arms are a bit different for wet cores. Whereas the dry arm is understood as having _exactly_ its parent core type for its subject, wet arms can be evaluated with payloads of various types.
102102
103103Let's start again with a typical function call.
104104
105−When a function call occurs on a wet arm, the [call site](https://en.wikipedia.org/wiki/Call_site) argument value type is used as the sample type -- not the original parent core sample type. Correspondingly, the inferred type of a wet arm depends, among other things, on the type of the argument value -- i.e., the modified sample value type of the core, not the original sample. Thus, the inferred product type typically varies from one call site to another.
105+When a function call occurs on a wet arm, the [call site](https://en.wikipedia.org/wiki/Call_site) argument value type is used as the sample type -- not the original parent core sample type. Correspondingly, the inferred type of a wet arm depends, among other things, on the type of the argument value -- i.e., the modified sample value type of the core, not the original sample. Thus, the inferred product type typically varies from one call site to another.
106106
107−The arms of wet cores must be able to handle subjects of various types -- they are interestingly polymorphic in a way that dry cores cannot be. The Hoon code that defines each wet arm must be [generic](https://en.wikipedia.org/wiki/Generic_programming) with respect to the sample type.
107+The arms of wet cores must be able to handle subjects of various types -- they are interestingly polymorphic in a way that dry cores cannot be. The Hoon code that defines each wet arm must be [generic](https://en.wikipedia.org/wiki/Generic_programming) with respect to the sample type.
108108
109−An example will clarify how wet gates work. Recall the `copy` gate from earlier in the lesson:
109+An example will clarify how wet gates work. Recall the `copy` gate from earlier in the lesson:
110110
111111```
112112> =copy |=(a=* [a a])
@@ -121,7 +121,7 @@ An example will clarify how wet gates work. Recall the `copy` gate from earlier
121121[[72 101 108 108 111 33 0] [72 101 108 108 111 33 0]]
122122```
123123
124−This gate is dry (as are all cores produced with `|=`), and so the inferred type of the product is determined based on the original core sample type. In this case, that's a raw noun, `*`. The dojo pretty-printer therefore has no way of knowing that the product of the last `copy` call should be printed as a pair of `tape`s -- it just sees a pair of nouns. If we want the original type information preserved, we must use a wet gate, which can be produced with `|*`:
124+This gate is dry (as are all cores produced with `|=`), and so the inferred type of the product is determined based on the original core sample type. In this case, that's a raw noun, `*`. The dojo pretty-printer therefore has no way of knowing that the product of the last `copy` call should be printed as a pair of `tape`s -- it just sees a pair of nouns. If we want the original type information preserved, we must use a wet gate, which can be produced with `|*`:
125125
126126```
127127> =wet-copy |*(a=* [a a])
@@ -136,7 +136,7 @@ This gate is dry (as are all cores produced with `|=`), and so the inferred type
136136["Hello!" "Hello!"]
137137```
138138
139−We see that the type information about the `tape` literal `"Hello!"` is preserved in the last function call, as desired. The original sample value of `wet-copy` is replaced with `"Hello!"`, and the original sample type is ignored in favor of the new sample type, `tape`. So the inferred arm type is a cell of `tape`s, which the dojo pretty-printer handles appropriately.
139+We see that the type information about the `tape` literal `"Hello!"` is preserved in the last function call, as desired. The original sample value of `wet-copy` is replaced with `"Hello!"`, and the original sample type is ignored in favor of the new sample type, `tape`. So the inferred arm type is a cell of `tape`s, which the dojo pretty-printer handles appropriately.
140140
141141In fact, `wet-copy` can take a Hoon value of any type you like.
142142
@@ -155,7 +155,7 @@ For another example, consider the following gate that switches the order of the
155155[0b1101 0xbeef]
156156```
157157
158−Not only does `switch` reverse the order of the values, it also reverses their respective types, as desired. The dry version of switch is not as useful:
158+Not only does `switch` reverse the order of the values, it also reverses their respective types, as desired. The dry version of switch is not as useful:
159159
160160```
161161> =dry-switch |=([a=* b=*] [b a])
@@ -176,9 +176,9 @@ But `switch` can't take just any input:
176176-find.b
177177```
178178
179−It must take a cell, not an atom. So it's certainly possible to write a wet gate that doesn't take all possible input types.
179+It must take a cell, not an atom. So it's certainly possible to write a wet gate that doesn't take all possible input types.
180180
181−It is good practice to include a cast in all gates, even wet gates. But in many cases the desired output type depends on the input type. How can we cast appropriately? Often we can cast by example, using the input values themselves. For example, we can rewrite `switch` as:
181+It is good practice to include a cast in all gates, even wet gates. But in many cases the desired output type depends on the input type. How can we cast appropriately? Often we can cast by example, using the input values themselves. For example, we can rewrite `switch` as:
182182
183183```
184184> =switch |*([a=* b=*] ^+([b a] [b a]))
@@ -187,7 +187,7 @@ It is good practice to include a cast in all gates, even wet gates. But in many
187187[0xbeef "Hello"]
188188```
189189
190−As is the case with dry arms, there is a type-check associated with each wet arm. Or, rather, there are potentially many checks for each wet arm, one for each wing in the code that resolves to a wet arm. The product type of that arm is inferred at each call site, using the argument value type given at that site. If the type inference doesn't go through -- e.g., if there is a cast that doesn't succeed relative to the call site argument value -- then the compile will crash with a `nest-fail`. Otherwise the type check goes through with the inferred type of the wet arm at that call site. So the product type of a wet gate can differ from one call site to another, as we saw with `switch` above.
190+As is the case with dry arms, there is a type-check associated with each wet arm. Or, rather, there are potentially many checks for each wet arm, one for each wing in the code that resolves to a wet arm. The product type of that arm is inferred at each call site, using the argument value type given at that site. If the type inference doesn't go through -- e.g., if there is a cast that doesn't succeed relative to the call site argument value -- then the compile will crash with a `nest-fail`. Otherwise the type check goes through with the inferred type of the wet arm at that call site. So the product type of a wet gate can differ from one call site to another, as we saw with `switch` above.
191191
192192### Parametric Polymorphism and `|$`
193193
@@ -197,10 +197,10 @@ list of molds and produces a new mold. Here we take another look at this rune as
197197an implementation of **parametric polymorphism** in Hoon.
198198
199199For example, we have `list`s, `tree`s, and `set`s in Hoon, which are each
200−defined in `hoon.hoon` as wet gate mold builders. Take a moment to see for
201−yourself. Each `++` arm is followed by `|$` and a list of labels for input
202−types inside brackets `[ ]`. After that subexpression comes another that
203−defines a type that is parametrically polymorphic with respect to the input values. For example, here is the definition of `list` from `hoon.hoon`:
200+defined in `hoon.hoon` as wet gate mold builders. Take a moment to see for
201+yourself. Each `++` arm is followed by `|$` and a list of labels for input
202+types inside brackets `[ ]`. After that subexpression comes another that
203+defines a type that is parametrically polymorphic with respect to the input values. For example, here is the definition of `list` from `hoon.hoon`:
204204
205205```hoon
206206++ list
@@ -213,9 +213,9 @@ defines a type that is parametrically polymorphic with respect to the input valu
213213 $@(~ [i=item t=(list item)])
214214```
215215
216−The `|$` rune is especially useful for defining [containers](https://en.wikipedia.org/wiki/Container_%28abstract_data_type%29) of various kinds. Indeed, `list`s, `tree`s, and `set`s are all examples of containers. You can have a `(list @)`, a `(list ^)`, a `(list *)`, and so on. Or a `(tree @)`, a `(tree ^)`, a `(tree *)`, etc. And the same for `set`.
216+The `|$` rune is especially useful for defining [containers](https://en.wikipedia.org/wiki/Container_%28abstract_data_type%29) of various kinds. Indeed, `list`s, `tree`s, and `set`s are all examples of containers. You can have a `(list @)`, a `(list ^)`, a `(list *)`, and so on. Or a `(tree @)`, a `(tree ^)`, a `(tree *)`, etc. And the same for `set`.
217217
218−One nice thing about containers defined by `|$` is that they nest in the expected way. Intuitively a `(list @)` should nest under `(list *)`, because `@` nests under `*`. And so it does:
218+One nice thing about containers defined by `|$` is that they nest in the expected way. Intuitively a `(list @)` should nest under `(list *)`, because `@` nests under `*`. And so it does:
219219
220220```
221221> =a `(list @)`~[11 22 33]
@@ -251,7 +251,7 @@ Let's clear the dojo subject by unbinding the faces we've used up to now in the
251251
252252## Core Variance
253253
254−Let's say you want to write a function that takes a gate as one (or more) of its arguments. It's not hard to imagine useful cases of this. Consider `turn` from the Hoon standard library, which applies an arbitrary function to each item in a list and returns a modified list:
254+Let's say you want to write a function that takes a gate as one (or more) of its arguments. It's not hard to imagine useful cases of this. Consider `turn` from the Hoon standard library, which applies an arbitrary function to each item in a list and returns a modified list:
255255
256256```
257257> =b `(list @)`~[2 3 4 5]
@@ -265,9 +265,9 @@ Let's say you want to write a function that takes a gate as one (or more) of its
265265=b
266266```
267267
268−It's quite useful to be able to pass cores as arguments. But let's think about how to write a function that accepts a core as input. How do we define a sample so that it accepts a core?
268+It's quite useful to be able to pass cores as arguments. But let's think about how to write a function that accepts a core as input. How do we define a sample so that it accepts a core?
269269
270−We _could_ define the sample by example -- i.e., with `$_`, or `_` for short -- using a core. Consider the following, in which `mycore` is the example core and `apply` is function that accepts gates:
270+We _could_ define the sample by example -- i.e., with `$_`, or `_` for short -- using a core. Consider the following, in which `mycore` is the example core and `apply` is function that accepts gates:
271271
272272```
273273> =mycore =>([12 13] |=(a=@ +(a)))
@@ -284,47 +284,47 @@ We _could_ define the sample by example -- i.e., with `$_`, or `_` for short --
284284123
285285```
286286
287−This works, but in fact `apply` is a very brittle function. It can only take as input a core whose payload is exactly like, or a subtype of, the payload of `mycore`:
287+This works, but in fact `apply` is a very brittle function. It can only take as input a core whose payload is exactly like, or a subtype of, the payload of `mycore`:
288288
289289```
290290> (apply 15 |=(a=@ (mul 2 a)))
291291nest-fail
292292```
293293
294−A core created in one place of your code isn't likely to have the same payload as a core produced elsewhere, unless you intentionally define it so that it does. This generally isn't practical, so we need another way to indicate that we want a core as input.
294+A core created in one place of your code isn't likely to have the same payload as a core produced elsewhere, unless you intentionally define it so that it does. This generally isn't practical, so we need another way to indicate that we want a core as input.
295295
296−Why did the last example crash? To understand this, you need to understand the the different variance properties a core can have. These properties determine the nesting and type inference rules associated with each core.
296+Why did the last example crash? To understand this, you need to understand the the different variance properties a core can have. These properties determine the nesting and type inference rules associated with each core.
297297
298298The basic question to be answered is: when does one core type nest under another?
299299
300−The battery nesting rules for dry cores are relatively straightforward, and they're the same for all cores, regardless of variance properties. Let `A` and `B` be two cores. The type of `B` nests under the type of `A` only if two conditions are met: (i) the batteries of `A` and `B` have exactly the same tree shape, and (ii) the product type of each `B` arm nests under the product type of the corresponding `A` arm.
300+The battery nesting rules for dry cores are relatively straightforward, and they're the same for all cores, regardless of variance properties. Let `A` and `B` be two cores. The type of `B` nests under the type of `A` only if two conditions are met: (i) the batteries of `A` and `B` have exactly the same tree shape, and (ii) the product type of each `B` arm nests under the product type of the corresponding `A` arm.
301301
302−The payload types of `A` and `B` must also be checked. Certain payload nesting rules apply to all cores, if `B` is to nest under `A`: (i) if `A` is wet then `B` must also be wet; (ii) the original payload type of `A` must mutually nest with the current payload type of `A` (i.e., these types nest under each other); and (iii) the current payload type of `B` must nest under the original payload type of `B`.
302+The payload types of `A` and `B` must also be checked. Certain payload nesting rules apply to all cores, if `B` is to nest under `A`: (i) if `A` is wet then `B` must also be wet; (ii) the original payload type of `A` must mutually nest with the current payload type of `A` (i.e., these types nest under each other); and (iii) the current payload type of `B` must nest under the original payload type of `B`.
303303
304304### The Four Kinds of Cores: Gold, Iron, Zinc, and Lead
305305
306306But there are different sets of nesting rules for finishing the payload type check, depending on the variance properties of the core.
307307
308−There are four kinds of cores: **gold** (invariant payload), **iron** (contravariant sample), **zinc** (covariant sample), and **lead** (bivariant sample). Information about the kind of core is tracked by the Hoon type system.
308+There are four kinds of cores: **gold** (invariant payload), **iron** (contravariant sample), **zinc** (covariant sample), and **lead** (bivariant sample). Information about the kind of core is tracked by the Hoon type system.
309309
310310Their nesting rules in brief:
311311
312−+ If `A` is a gold core, then core `B` nests under it only if `B` is gold and the payload of `B` doesn't vary in type from the payload of `A`. The payload `B` is **invariant** (i.e., neither co- nor contravariant) relative to the payload of an `A` it nests under. Gold cores have a read-write payload.
313−+ If `A` is an iron core, then core `B` nests under it only if `B` is gold or iron and the sample of `A` nests under the sample of `B`. Notice that the nesting direction of the samples is the opposite of the nesting direction of the cores. I.e., the sample types are **contravariant** with respect to the iron core types. Iron cores have a write-only sample and an opaque context. ("Opaque" means neither read nor write.)
314−+ If `A` is a zinc core, then core `B` nests under it only if `B` is gold or zinc and the sample of `B` nests under the sample of `A`. Notice that the nesting direction of the samples is the same as the nesting direction of the cores. I.e., the sample types are **covariant** with respect to the zinc core types. Zinc cores have a read-only sample and an opaque context.
315−+ If `A` is a lead core, then core `B` nests under it without any additional payload check beyond those described in the previous section. It trivially follows that the payload type both co- and contravaries with respect to the lead core types (hence lead cores are **bivariant**). Lead cores have an opaque payload.
312+- If `A` is a gold core, then core `B` nests under it only if `B` is gold and the payload of `B` doesn't vary in type from the payload of `A`. The payload `B` is **invariant** (i.e., neither co- nor contravariant) relative to the payload of an `A` it nests under. Gold cores have a read-write payload.
313+- If `A` is an iron core, then core `B` nests under it only if `B` is gold or iron and the sample of `A` nests under the sample of `B`. Notice that the nesting direction of the samples is the opposite of the nesting direction of the cores. I.e., the sample types are **contravariant** with respect to the iron core types. Iron cores have a write-only sample and an opaque context. ("Opaque" means neither read nor write.)
314+- If `A` is a zinc core, then core `B` nests under it only if `B` is gold or zinc and the sample of `B` nests under the sample of `A`. Notice that the nesting direction of the samples is the same as the nesting direction of the cores. I.e., the sample types are **covariant** with respect to the zinc core types. Zinc cores have a read-only sample and an opaque context.
315+- If `A` is a lead core, then core `B` nests under it without any additional payload check beyond those described in the previous section. It trivially follows that the payload type both co- and contravaries with respect to the lead core types (hence lead cores are **bivariant**). Lead cores have an opaque payload.
316316
317317Let's go through each kind more carefully.
318318
319319#### Gold Cores (Invariant)
320320
321−By default, most cores are gold. This includes the cores produced with the `|%`, `|=`, `|_`, and `|-` runes, among others.
321+By default, most cores are gold. This includes the cores produced with the `|%`, `|=`, `|_`, and `|-` runes, among others.
322322
323−Assume that `A` is a gold core and that `B` is some other core. The type of `B` nests under the type of `A` only if the original payload types of each mutually nest -- i.e., the original payload type of `A` nests under the original payload type of `B`, and _vice versa_. Furthermore, only gold cores nest under other gold cores; so `B` must be gold to nest under `A`.
323+Assume that `A` is a gold core and that `B` is some other core. The type of `B` nests under the type of `A` only if the original payload types of each mutually nest -- i.e., the original payload type of `A` nests under the original payload type of `B`, and _vice versa_. Furthermore, only gold cores nest under other gold cores; so `B` must be gold to nest under `A`.
324324
325−These payload nesting rules are the strictest ones for cores. The payload type is neither covariant nor contravariant; when type-checking against a gold core, the target payload cannot vary at all in type. Consequently, it is type-safe to modify every part of the payload: gold cores have a read-write payload.
325+These payload nesting rules are the strictest ones for cores. The payload type is neither covariant nor contravariant; when type-checking against a gold core, the target payload cannot vary at all in type. Consequently, it is type-safe to modify every part of the payload: gold cores have a read-write payload.
326326
327−Usually it makes sense to cast for a gold core type when you're treating a core as a state machine. The check ensures that the payload, which includes the relevant state, doesn't vary in type. To see state machines that involve casts for gold cores, see Chapter 2 of the Hoon tutorial.
327+Usually it makes sense to cast for a gold core type when you're treating a core as a state machine. The check ensures that the payload, which includes the relevant state, doesn't vary in type. To see state machines that involve casts for gold cores, see Chapter 2 of the Hoon tutorial.
328328
329329Let's look at simpler examples here, using the `^+` rune:
330330
@@ -344,7 +344,7 @@ nest-fail
344344nest-fail
345345```
346346
347−The first cast goes through because the right-hand gold core has the same sample type as the left-hand gold core. The sample types mutually nest. The second cast fails because the right-hand sample type is more specific than the left-hand sample type. (Not all cells, `^`, are pairs of atoms, `[@ @]`.) And the third cast fails because the right-hand sample type is broader than the left-hand sample type. (Not all nouns, `*`, are cells, `^`.)
347+The first cast goes through because the right-hand gold core has the same sample type as the left-hand gold core. The sample types mutually nest. The second cast fails because the right-hand sample type is more specific than the left-hand sample type. (Not all cells, `^`, are pairs of atoms, `[@ @]`.) And the third cast fails because the right-hand sample type is broader than the left-hand sample type. (Not all nouns, `*`, are cells, `^`.)
348348
349349Two more examples:
350350
@@ -356,15 +356,15 @@ Two more examples:
356356nest-fail
357357```
358358
359−In these examples, the `=>` rune is used to give each core a simple context. The context of the left-hand core in each case is a pair of atoms, `[@ @]`. The first cast goes through because the right-hand core also has a pair of atoms as its context. The second cast fails because the right-hand core has the wrong type of context -- three atoms, `[@ @ @]`.
359+In these examples, the `=>` rune is used to give each core a simple context. The context of the left-hand core in each case is a pair of atoms, `[@ @]`. The first cast goes through because the right-hand core also has a pair of atoms as its context. The second cast fails because the right-hand core has the wrong type of context -- three atoms, `[@ @ @]`.
360360
361361#### Iron Cores (Contravariant)
362362
363−Assume that `A` is an iron core and `B` is some other core. The type of `B` nests under the type of `A` only if the original sample type of `A` nests under the original sample type of `B`. That is, `B`'s sample type must be equivalent or more general than the sample type of `A`. Furthermore, `B` must be either iron or gold to nest under `A`.
363+Assume that `A` is an iron core and `B` is some other core. The type of `B` nests under the type of `A` only if the original sample type of `A` nests under the original sample type of `B`. That is, `B`'s sample type must be equivalent or more general than the sample type of `A`. Furthermore, `B` must be either iron or gold to nest under `A`.
364364
365−The context type of `B` isn't checked at all; and because of the nesting rules it isn't type-safe to do type-inference on the sample of an iron gate. Thus, there are certain restrictions on iron cores that preserve type safety: (i) the context of an iron core is opaque, meaning that it cannot be written-to or read-from; and (ii) the iron core payload is write-only.
365+The context type of `B` isn't checked at all; and because of the nesting rules it isn't type-safe to do type-inference on the sample of an iron gate. Thus, there are certain restrictions on iron cores that preserve type safety: (i) the context of an iron core is opaque, meaning that it cannot be written-to or read-from; and (ii) the iron core payload is write-only.
366366
367−Iron gates are particularly useful when you want to pass gates (having various payload types) to other gates. We can illustrate this use with a very simple example. Save the following as `gatepass.hoon` in the `gen` directory of your urbit's pier:
367+Iron gates are particularly useful when you want to pass gates (having various payload types) to other gates. We can illustrate this use with a very simple example. Save the following as `gatepass.hoon` in the `gen` directory of your `%base` desk:
368368
369369```hoon
370370|= a=_^|(|=(@ 15))
@@ -373,9 +373,9 @@ Iron gates are particularly useful when you want to pass gates (having various p
373373(add b 20)
374374```
375375
376−This generator is mostly very simple. Everything about it should be clear except possibly the first line.
376+This generator is mostly very simple. Everything about it should be clear except possibly the first line.
377377
378−The first line defines the sample as an iron gate and gives it the face `a`. The function as a whole is for taking some gate as input, calling it by passing it the value `10`, adding `20` to it, and returning the result. Let's try it out in the dojo:
378+The first line defines the sample as an iron gate and gives it the face `a`. The function as a whole is for taking some gate as input, calling it by passing it the value `10`, adding `20` to it, and returning the result. Let's try it out in the dojo:
379379
380380```
381381> +gatepass |=(a=@ +(a))
@@ -388,16 +388,16 @@ The first line defines the sample as an iron gate and gives it the face `a`. Th
38838850
389389```
390390
391−But we still haven't fully explained the first line of the code. What does `_^|(|=(@ 15))` mean? The inside portion is clear enough -- `|=(@ 15)` produces a normal (i.e., gold) gate that takes an atom and returns `15`. The `^|` rune is used to turn gold gates to iron. (Reverse alchemy!) And the `_` character turns that iron gate value into a structure, i.e. a type. So the whole subexpression means, roughly: "the same type as an iron gate whose sample is an atom, `@`, and whose product is another atom, `@`". The context isn't checked at all. This is good, because that allows us to accept gates defined and produced in drastically different environments. Let's try passing a gate with a different context:
391+But we still haven't fully explained the first line of the code. What does `_^|(|=(@ 15))` mean? The inside portion is clear enough -- `|=(@ 15)` produces a normal (i.e., gold) gate that takes an atom and returns `15`. The `^|` rune is used to turn gold gates to iron. (Reverse alchemy!) And the `_` character turns that iron gate value into a structure, i.e. a type. So the whole subexpression means, roughly: "the same type as an iron gate whose sample is an atom, `@`, and whose product is another atom, `@`". The context isn't checked at all. This is good, because that allows us to accept gates defined and produced in drastically different environments. Let's try passing a gate with a different context:
392392
393393```
394394> +gatepass =>([22 33] |=(a=@ +(a)))
39539531
396396```
397397
398−Yup, it still works. You can't do that with a gold core sample!
398+Yup, it still works. You can't do that with a gold core sample!
399399
400−There's a simpler way to define an iron sample. Revise the first line of `gatepass.hoon` to the following:
400+There's a simpler way to define an iron sample. Revise the first line of `gatepass.hoon` to the following:
401401
402402```hoon
403403|= a=$-(@ @)
@@ -406,15 +406,15 @@ There's a simpler way to define an iron sample. Revise the first line of `gatep
406406(add b 20)
407407```
408408
409−If you test it you'll find that the generator behaves the same as it did before the edits. The `$-` rune is used to create an iron gate structure, i.e., an iron gate type. The first expression defines the desired sample type, and the second subexpression defines the gate's desired output type.
409+If you test it you'll find that the generator behaves the same as it did before the edits. The `$-` rune is used to create an iron gate structure, i.e., an iron gate type. The first expression defines the desired sample type, and the second subexpression defines the gate's desired output type.
410410
411−The sample type of an iron gate is contravariant. This means that, when doing a cast with some iron gate, the desired gate must have either the same sample type or a superset.
411+The sample type of an iron gate is contravariant. This means that, when doing a cast with some iron gate, the desired gate must have either the same sample type or a superset.
412412
413413Why is this a useful nesting rule for passing gates?
414414
415−Let's say you're writing a function `F` that takes as input some gate `G`. Let's also say you want `G` to be able to take as input any **mammal**. The code of `F` is going to pass arbitrary **mammals** to `G`, so that `G` needs to know how to handle all **mammals** correctly. You can't pass `F` a gate that only takes **dogs** as input, because `F` might call it with a **cat**. But `F` can accept a gate that takes all **animals** as input, because a gate that can handle any **animal** can handle **any mammal**.
415+Let's say you're writing a function `F` that takes as input some gate `G`. Let's also say you want `G` to be able to take as input any **mammal**. The code of `F` is going to pass arbitrary **mammals** to `G`, so that `G` needs to know how to handle all **mammals** correctly. You can't pass `F` a gate that only takes **dogs** as input, because `F` might call it with a **cat**. But `F` can accept a gate that takes all **animals** as input, because a gate that can handle any **animal** can handle **any mammal**.
416416
417−Iron cores are designed precisely with this purpose in mind. The reason that the sample is write-only is that we want to be able to assume, within function `F`, that the sample of `G` is a **mammal**. But that might not be true when `G` is first passed into `F` -- the default value of `G` could be another **animal**, say, a **lizard**. So we restrict looking into the sample of `G` by making the sample write-only. The illusion is maintained and type safety secured.
417+Iron cores are designed precisely with this purpose in mind. The reason that the sample is write-only is that we want to be able to assume, within function `F`, that the sample of `G` is a **mammal**. But that might not be true when `G` is first passed into `F` -- the default value of `G` could be another **animal**, say, a **lizard**. So we restrict looking into the sample of `G` by making the sample write-only. The illusion is maintained and type safety secured.
418418
419419Let's illustrate iron core nesting properties:
420420
@@ -441,9 +441,9 @@ nest-fail
441441
442442(As before, we use the `^|` rune to turn gold gates iron.)
443443
444−The first cast goes through because the two gates have the same sample type. The second cast fails because the right-hand gate has a more specific sample type than the left-hand gate does. If you're casting for a gate that accepts any cell, `^`, it's because we want to be able to pass any cell to it. A gate that is only designed for pairs of atoms, `[@ @]`, can't handle all such cases, naturally. The third cast goes through because the right-hand gate sample type is broader than the left-hand gate sample type. A gate that can take any noun as its sample, `*`, works just fine if we choose only to pass it cells, `^`.
444+The first cast goes through because the two gates have the same sample type. The second cast fails because the right-hand gate has a more specific sample type than the left-hand gate does. If you're casting for a gate that accepts any cell, `^`, it's because we want to be able to pass any cell to it. A gate that is only designed for pairs of atoms, `[@ @]`, can't handle all such cases, naturally. The third cast goes through because the right-hand gate sample type is broader than the left-hand gate sample type. A gate that can take any noun as its sample, `*`, works just fine if we choose only to pass it cells, `^`.
445445
446−We mentioned previously that an iron core has a write-only sample and an opaque core. Let's prove it.
446+We mentioned previously that an iron core has a write-only sample and an opaque core. Let's prove it.
447447
448448Let's define a trivial gate with a context of `[g=22 h=44 .]`, convert it to iron with `^|`, and bind it to `iron-gate` in the dojo:
449449
@@ -457,14 +457,14 @@ Let's define a trivial gate with a context of `[g=22 h=44 .]`, convert it to iro
45745733
458458```
459459
460−Not a complicated function, but it serves our purposes. Normally (i.e., with gold cores) we can look at a context value `p` of some gate `q` with a wing expression: `p.q`. Not so with the iron gate:
460+Not a complicated function, but it serves our purposes. Normally (i.e., with gold cores) we can look at a context value `p` of some gate `q` with a wing expression: `p.q`. Not so with the iron gate:
461461
462462```
463463> g.iron-gate
464464-find.g.iron-gate
465465```
466466
467−And usually we can look at the sample value using the face given in the gate definition. Not in this case:
467+And usually we can look at the sample value using the face given in the gate definition. Not in this case:
468468
469469```
470470> a.iron-gate
@@ -505,11 +505,11 @@ Let's clear up the dojo subject by unbinding `iron-gate`:
505505
506506Zinc cores are mirror versions of iron cores.
507507
508−Assume that `A` is a zinc core and `B` is some other core. The type of `B` nests under the type of `A` only if the original sample type of `B` nests under the original sample type of `A`. That is, the target core sample type must be equivalent or a subset of the cast core sample type. Furthermore, `B` must be either zinc or gold to nest under `A`.
508+Assume that `A` is a zinc core and `B` is some other core. The type of `B` nests under the type of `A` only if the original sample type of `B` nests under the original sample type of `A`. That is, the target core sample type must be equivalent or a subset of the cast core sample type. Furthermore, `B` must be either zinc or gold to nest under `A`.
509509
510−As with iron cores, the context of zinc cores is opaque -- they cannot be written-to or read-from. The sample of a zinc core is read-only. That means, among other things, that zinc cores cannot be used for function calls. Function calls in Hoon involve a change to the sample (the default sample is replaced with the argument value), which is disallowed as type-unsafe for zinc cores.
510+As with iron cores, the context of zinc cores is opaque -- they cannot be written-to or read-from. The sample of a zinc core is read-only. That means, among other things, that zinc cores cannot be used for function calls. Function calls in Hoon involve a change to the sample (the default sample is replaced with the argument value), which is disallowed as type-unsafe for zinc cores.
511511
512−We can illustrate the casting properties of zinc cores with a few examples. The `^&` rune is used to convert gold cores to zinc:
512+We can illustrate the casting properties of zinc cores with a few examples. The `^&` rune is used to convert gold cores to zinc:
513513
514514```
515515> ^+(^&(|=(^ 15)) |=(^ 16))
@@ -532,9 +532,9 @@ We can illustrate the casting properties of zinc cores with a few examples. The
532532nest-fail
533533```
534534
535−The first two casts succeed because the right-hand core sample type is either the same or a subset of the left-hand core sample type. The last one fails because the right-hand sample type is a superset.
535+The first two casts succeed because the right-hand core sample type is either the same or a subset of the left-hand core sample type. The last one fails because the right-hand sample type is a superset.
536536
537−Even though you can't function call a zinc core, the arms of a zinc core can be computed and the sample can be read. Let's test this with a zinc gate of our own:
537+Even though you can't function call a zinc core, the arms of a zinc core can be computed and the sample can be read. Let's test this with a zinc gate of our own:
538538
539539```
540540> =zinc-gate ^& |=(a=_22 (add 10 a))
@@ -557,11 +557,11 @@ Let's clear up the dojo subject again:
557557
558558#### Lead Cores (Bivariant)
559559
560−Lead cores have more permissive nesting rules than either iron or zinc cores. There is no restriction on which payload types nest. That means, among other things, that the payload type of a lead core is both covariant and contravariant ('bivariant').
560+Lead cores have more permissive nesting rules than either iron or zinc cores. There is no restriction on which payload types nest. That means, among other things, that the payload type of a lead core is both covariant and contravariant ('bivariant').
561561
562−In order to preserve type safety when working with lead cores, a severe restriction is needed. The whole payload of a lead core is opaque -- the payload can neither be written-to or read-from. For this reason, as was the case with zinc cores, lead cores cannot be called as functions.
562+In order to preserve type safety when working with lead cores, a severe restriction is needed. The whole payload of a lead core is opaque -- the payload can neither be written-to or read-from. For this reason, as was the case with zinc cores, lead cores cannot be called as functions.
563563
564−The arms of a lead core can still be evaluated, however. We can use the `^?` rune to convert a gold, iron, or zinc core to lead:
564+The arms of a lead core can still be evaluated, however. We can use the `^?` rune to convert a gold, iron, or zinc core to lead:
565565
566566```
567567> =lead-gate ^? |=(a=_22 (add 10 a))
content/docs/hoon/reference/_index.md+6−3
@@ -36,15 +36,18 @@ The full story on Hoon's type system.
3636
3737A list of aura types for atoms.
3838
39−### [Runes](/docs/hoon/reference/rune/)
39+## [Runes](/docs/hoon/reference/rune/)
4040
4141Syntax and semantics for Hoon's rune system.
4242
43−### [Limbs and Wings](/docs/hoon/reference/limbs/)
43+## [Limbs and Wings](/docs/hoon/reference/limbs/)
4444
4545How to find data inside Hoon subjects.
4646
47−### [Standard Library](/docs/hoon/reference/stdlib/)
47+## [Standard Library](/docs/hoon/reference/stdlib/)
4848
4949Reference material for the Hoon standard library.
5050
51+## [Zuse](/docs/hoon/reference/zuse/)
52+
53+Reference material for the Zuse library.
content/docs/hoon/reference/cheat-sheet.md+3−13
@@ -5,24 +5,14 @@ template = "doc.html"
55aliases = ["docs/reference/cheat-sheet/"]
66+++
77
8−Download the cheat sheet PDF [here](https://storage.googleapis.com/media.urbit.org/docs/hoon-cheat-sheet-2020-07-24.pdf).
8+Download the cheat sheet PDF [here](https://media.urbit.org/docs/hooncard-unbranded-2021-09-12.pdf)
99
1010We've found it's useful to have a quick reference of Hoon's syntax always at
11−hand. So above is a download link to a Hoon cheatsheet .pdf. It's missing a
12−few of the literal syntaxes, but it covers the most common ones.
11+hand. So above is a download link to a Hoon cheatsheet PDF.
1312
14−This doesn't list any of the Ford runes, although there is now at least
15−some documentation for those [here](/docs/arvo/ford/ford).
16−
17−The following runes also exist, but are currently undocumented and not listed in
13+The following rune also exists, but is currently undocumented and not listed in
1814the cheat sheet:
1915
2016```
21−!: :: turn on debugging printfs
22−!. :: turn off debugging printfs
23−!; :: using the "type of type", emit the type for an expression
24−!, :: emit AST of expression
2517$* :: bunt (irregular form is *)
26−^. :: use gate to transform type
27−^& :: zinc (covariant) -- see the docs on advanced types
2818```
content/docs/hoon/reference/rune/ket.md+12−3
@@ -63,9 +63,18 @@ Regular: **1-fixed**.
6363
6464##### Discussion
6565
66−A mold is an idempotent gate that is guaranteed to produce a noun of that type. If an input value isn't of the correct type, the bunt value of that type is returned. (See `^*`.)
67−
68−`^:` is used to produce a gate that is much like a mold, except that instead of producing a bunt value when the input value is of the wrong type, it crashes.
66+A mold is an idempotent gate that is guaranteed to produce a noun of that type.
67+If an input value isn't of the correct type, the bunt value of that type is
68+returned. (See `^*`.)
69+
70+`^:` is used to produce a gate that is much like a mold, except that instead of
71+producing a bunt value when the input value is of the wrong type, it crashes.
72+
73+One may expect that `^:(path /foo)` would result in a syntax error since `^:`
74+only takes one child, but instead it will parse as `=< ^ %:(path /foo)`. Since
75+`:` is the irregular syntax for `=<` this is is parsed as "get `^` (i.e. the
76+mold for cells) from a subject of `(path /foo)`", with `:` being the irregular
77+syntax for `=<`.
6978
7079##### Examples
7180
content/docs/hoon/reference/rune/mic.md+1−1
@@ -157,7 +157,7 @@ tl;dr -- `;+` converts a `manx` to a `marl`.
157157
158158`;+` is a Sail rune. Sail is a part of Hoon used for creating and operating on nouns that represent XML nodes. With the appropriate rendering pipeline, a Sail document can be used to generate a static website.
159159
160−In Sail a single XML node is represented by a `manx`. A single `<p>` node `manx` can be produced in the following way:
160+In Sail a single XML node is represented by a `manx`. A single <code>&lt;p&gt;</code> node `manx` can be produced in the following way:
161161
162162```
163163> ;p: This will be rendered as an XML node.
content/docs/hoon/reference/rune/tis.md+9−3
@@ -423,11 +423,11 @@ Regular: **running**.
423423
424424### `=*` "tistar"
425425
426−`[%tstr p=term q=hoon r=hoon]`: define a macro.
426+`[%tstr p=term q=hoon r=hoon]`: define a deferred expression.
427427
428428##### Produces
429429
430−`r`, compiled with a subject in which `p` is a macro for `q`.
430+`r`, compiled with a subject in which `p` is a deferred expression for `q`.
431431
432432##### Syntax
433433
@@ -435,7 +435,13 @@ Regular: **3-fixed**.
435435
436436##### Discussion
437437
438−The difference between macroing and pinning is that pinning changes the subject, but for macroing the subject noun stays the same. The macro'd expression, `q`, is recorded in the type information of `p`. `q` is calculated every time you use the `p` macro.
438+`=*` assigns a name to an expression that will be evaluated in each place the
439+name is dereferenced. This allows you to "write" through it to the original
440+subject `axis`. `q` is recorded in the type information of `p`, and `q` is
441+calculated every time you use `p`.
442+
443+This rune has some similarities with macros, and some similarities with aliases,
444+but it is not really either.
439445
440446##### Examples
441447
content/docs/hoon/reference/rune/zap.md+1−1
@@ -196,7 +196,7 @@ The syntax difference is that a test for equality takes two subexpressions, and
196196##### Produces
197197
198198`q`, if `p` is greater than or equal to the Hoon kelvin version.
199−(Versions count down; the current version is 141.)
199+(Versions count down; the current version is 140.)
200200
201201##### Syntax
202202
content/docs/hoon/reference/stdlib/1a.md+403−284
@@ -4,7 +4,7 @@ weight = 1
44template = "doc.html"
55+++
66
7−### `++add`
7+## `++add`
88
99Add
1010
@@ -23,41 +23,54 @@ An [`atom`](/docs/glossary/atom).
2323#### Source
2424
2525```hoon
26− ++ add
27− ~/ %add
28− |= [a=@ b=@]
29− ^- @
30− ?: =(0 a) b
31− $(a (dec a), b +(b))
26+++ add
27+ ~/ %add
28+ |= [a=@ b=@]
29+ ^- @
30+ ?: =(0 a) b
31+ $(a (dec a), b +(b))
3232```
3333
3434#### Examples
3535
3636```
37− > (add 2 2)
38− 4
37+> (add 2 2)
38+4
39+```
3940
40− > (add 1 1.000.000)
41− 1.000.001
41+```
42+> (add 1 1.000.000)
43+1.000.001
44+```
4245
43− > (add 1.333 (mul 2 2))
44− 1.337
46+```
47+> (add 1.333 (mul 2 2))
48+1.337
49+```
4550
46− > (add 'a' 4)
47− 101
51+```
52+> (add 'a' 4)
53+101
54+```
4855
49− > (add 'a' 'b')
50− 195
56+```
57+> (add 'a' 'b')
58+195
59+```
5160
52− > (add 0xc 0xf)
53− 27
61+```
62+> (add 0xc 0xf)
63+27
64+```
5465
55− > `@ux`(add 0xc 0xf)
56− 0x1b
66+```
67+> `@ux`(add 0xc 0xf)
68+0x1b
5769```
5870
5971---
60−### `++dec`
72+
73+## `++dec`
6174
6275Decrement
6376
@@ -74,41 +87,47 @@ An [`atom`](/docs/glossary/atom).
7487#### Source
7588
7689```hoon
77− ++ dec
78− ~/ %dec
79− |= a=@
80− ~| %decrement-underflow
81− ?< =(0 a)
82− =+ b=0
83− |- ^- @
84− ?: =(a +(b)) b
85− $(b +(b))
90+++ dec
91+ ~/ %dec
92+ |= a=@
93+ ~_ leaf+"decrement-underflow"
94+ ?< =(0 a)
95+ =+ b=0
96+ |- ^- @
97+ ?: =(a +(b)) b
98+ $(b +(b))
8699```
87100
88101#### Examples
89102
90103```
91− > (dec 7)
92− 6
93−
94− > (dec 0)
95− ! decrement-underflow
96− ! exit
104+> (dec 7)
105+6
106+```
97107
98− > (dec 'b')
99− 97
100− > `@t`(dec 'b')
101− 'a'
108+```
109+> (dec 0)
110+! decrement-underflow
111+! exit
112+```
102113
103− > (dec 0xc)
104− 11
105− > `@ux`(dec 0xc)
106− 0xb
114+```
115+> (dec 'b')
116+97
117+> `@t`(dec 'b')
118+'a'
107119```
108120
121+```
122+> (dec 0xc)
123+11
124+> `@ux`(dec 0xc)
125+0xb
126+```
109127
110128---
111−### `++div`
129+
130+## `++div`
112131
113132Divide
114133
@@ -127,43 +146,52 @@ An [`atom`](/docs/glossary/atom).
127146#### Source
128147
129148```hoon
130− ++ div
131− ~/ %div
132− |: [a=`@`1 b=`@`1]
133− ^- @
134− ~_ leaf+"divide-by-zero"
135− ?< =(0 b)
136− =+ c=0
137− |-
138− ?: (lth a b) c
139− $(a (sub a b), c +(c))
149+++ div
150+ ~/ %div
151+ |: [a=`@`1 b=`@`1]
152+ ^- @
153+ ~_ leaf+"divide-by-zero"
154+ ?< =(0 b)
155+ =+ c=0
156+ |-
157+ ?: (lth a b) c
158+ $(a (sub a b), c +(c))
140159```
141160
142161#### Examples
143162
144163```
145− > (div 4 2)
146− 2
164+> (div 4 2)
165+2
166+```
147167
148− > (div 17 8)
149− 2
168+```
169+> (div 17 8)
170+2
171+```
150172
151− > (div 20 30)
152− 0
173+```
174+> (div 20 30)
175+0
176+```
153177
154− > (div 'ab' 'a')
155− 259
156− > `@`'ab'
157− 25.185
158− > `@`a
159− 97
178+```
179+> (div 'ab' 'a')
180+259
181+> `@`'ab'
182+25.185
183+> `@`a
184+97
185+```
160186
161− > (div 0x9f 0x29)
162− 6
187+```
188+> (div 0x9f 0x29)
189+6
163190```
164191
165192---
166−### `++dvr`
193+
194+## `++dvr`
167195
168196Divide with remainder
169197
@@ -182,38 +210,47 @@ A cell of [`atoms`](/docs/glossary/atom).
182210#### Source
183211
184212```hoon
185− ++ dvr
186− ~/ %dvr
187− |= [a=@ b=@]
188− ^- [p=@ q=@]
189− [(div a b) (mod a b)]
213+++ dvr
214+ ~/ %dvr
215+ |= [a=@ b=@]
216+ ^- [p=@ q=@]
217+ [(div a b) (mod a b)]
190218```
191219
192220#### Examples
193221
194222```
195− > (dvr 17 8)
196− [p=2 q=1]
223+> (dvr 17 8)
224+[p=2 q=1]
225+```
197226
198− > (dvr 17 6)
199− [p=2 q=5]
227+```
228+> (dvr 17 6)
229+[p=2 q=5]
230+```
200231
201− > (dvr 18 6)
202− [p=3 q=0]
232+```
233+> (dvr 18 6)
234+[p=3 q=0]
235+```
203236
204− > (dvr 4 2)
205− [p=2 q=0]
237+```
238+> (dvr 4 2)
239+[p=2 q=0]
240+```
206241
207− > (dvr 'ab 'a')
208− [p=259 q=62]
209− > `@`'a'
210− 97
211− > `@`'ab'
212− 25.185
242+```
243+> (dvr 'ab 'a')
244+[p=259 q=62]
245+> `@`'a'
246+97
247+> `@`'ab'
248+25.185
213249```
214250
215251---
216−### `++gte`
252+
253+## `++gte`
217254
218255Greater-than/equal
219256
@@ -232,28 +269,33 @@ A flag.
232269#### Source
233270
234271```hoon
235− ++ gte
236− ~/ %gte
237− |= [a=@ b=@]
238− ^- ?
239− !(lth a b)
272+++ gte
273+ ~/ %gte
274+ |= [a=@ b=@]
275+ ^- ?
276+ !(lth a b)
240277```
241278
242279#### Examples
243280
244281```
245− > (gte 100 10)
246− %.y
282+> (gte 100 10)
283+%.y
284+```
247285
248− > (gte 4 4)
249− %.y
286+```
287+> (gte 4 4)
288+%.y
289+```
250290
251− > (gte 3 4)
252− %.n
291+```
292+> (gte 3 4)
293+%.n
253294```
254295
255296---
256−### `++gth`
297+
298+## `++gth`
257299
258300Greater-than
259301
@@ -272,29 +314,33 @@ A flag.
272314#### Source
273315
274316```hoon
275− ++ gth
276− ~/ %gth
277− |= [a=@ b=@]
278− ^- ?
279− !(lte a b)
317+++ gth
318+ ~/ %gth
319+ |= [a=@ b=@]
320+ ^- ?
321+ !(lte a b)
280322```
281323
282−
283324#### Examples
284325
285326```
286− > (gth 'd' 'c')
287− %.y
327+> (gth 'd' 'c')
328+%.y
329+```
288330
289− > (gth ~h1 ~m61)
290− %.n
331+```
332+> (gth ~h1 ~m61)
333+%.n
334+```
291335
292− > (gth 'steak' 'brisket')
293− %.n
336+```
337+> (gth 'steak' 'brisket')
338+%.n
294339```
295340
296341---
297−### `++lte`
342+
343+## `++lte`
298344
299345Less-than/equal
300346
@@ -313,45 +359,56 @@ A flag.
313359#### Source
314360
315361```hoon
316− ++ lte
317− ~/ %lte
318− |= [a=@ b=@]
319− |(=(a b) (lth a b))
362+++ lte
363+ ~/ %lte
364+ |= [a=@ b=@]
365+ |(=(a b) (lth a b))
320366```
321367
322368#### Examples
323369
324370```
325− > (lte 4 5)
326− %.y
327−
328− > (lte 5 4)
329− %.n
330−
331− > (lte 5 5)
332− %.y
371+> (lte 4 5)
372+%.y
373+```
333374
334− > (lte 0 0)
335− %.y
375+```
376+> (lte 5 4)
377+%.n
378+```
336379
380+```
381+> (lte 5 5)
382+%.y
383+```
337384
338− > (lte 'a' 'b')
339− %.y
340− > `@`'a'
341− 97
342− > `@`'b'
343− 98
385+```
386+> (lte 0 0)
387+%.y
388+```
344389
345− > (lte 'abraham' 'bob')
346− %.n
390+```
391+> (lte 'a' 'b')
392+%.y
393+> `@`'a'
394+97
395+> `@`'b'
396+98
397+```
347398
348− > (lte ~m61 ~h1)
349− %.n
399+```
400+> (lte 'abraham' 'bob')
401+%.n
350402```
351403
404+```
405+> (lte ~m61 ~h1)
406+%.n
407+```
352408
353409---
354−### `++lth`
410+
411+## `++lth`
355412
356413Less-than
357414
@@ -370,46 +427,57 @@ A flag.
370427#### Source
371428
372429```hoon
373− ++ lth
374− ~/ %lth
375− |= [a=@ b=@]
376− ^- ?
377− ?& !=(a b)
378− |-
379− ?| =(0 a)
380− ?& !=(0 b)
381− $(a (dec a), b (dec b))
382− == == ==
430+++ lth
431+ ~/ %lth
432+ |= [a=@ b=@]
433+ ^- ?
434+ ?& !=(a b)
435+ |-
436+ ?| =(0 a)
437+ ?& !=(0 b)
438+ $(a (dec a), b (dec b))
439+ == == ==
383440```
384441
385442#### Examples
386443
387444```
388− > (lth 4 5)
389− %.y
445+> (lth 4 5)
446+%.y
447+```
390448
391− > (lth 5 4)
392− %.n
449+```
450+> (lth 5 4)
451+%.n
452+```
393453
394− > (lth 5 5)
395− %.n
454+```
455+> (lth 5 5)
456+%.n
457+```
396458
397− > (lth 5 0)
398− %.n
459+```
460+> (lth 5 0)
461+%.n
462+```
399463
400− > (lth 'a' 'b')
401− %.y
402− > `@`'a'
403− 97
404− > `@`'b'
405− 98
464+```
465+> (lth 'a' 'b')
466+%.y
467+> `@`'a'
468+97
469+> `@`'b'
470+98
471+```
406472
407− > (lth 'abraham' 'bob')
408− %.n
473+```
474+> (lth 'abraham' 'bob')
475+%.n
409476```
410477
411478---
412−### `++max`
479+
480+## `++max`
413481
414482Maximum
415483
@@ -428,44 +496,59 @@ An [`atom`](/docs/glossary/atom).
428496#### Source
429497
430498```hoon
431− ++ max
432− ~/ %max
433− |= [a=@ b=@]
434− ^- @
435− ?: (gth a b) a
436− b
499+++ max
500+ ~/ %max
501+ |= [a=@ b=@]
502+ ^- @
503+ ?: (gth a b) a
504+ b
437505```
438506
439507#### Examples
440508
441509```
442− > (max 10 100)
443− 100
510+> (max 10 100)
511+100
512+```
444513
445− > (max 10.443 9)
446− 10.443
514+```
515+> (max 10.443 9)
516+10.443
517+```
447518
448− > (max 1 1)
449− 1
519+```
520+> (max 1 1)
521+1
522+```
450523
451− > (max 'abraham' 'bob')
452− 30.787.873.400.840.801
524+```
525+> (max 'abraham' 'bob')
526+30.787.873.400.840.801
527+```
453528
454− > `@t`(max 'abraham' 'bob')
455− 'abraham'
529+```
530+> `@t`(max 'abraham' 'bob')
531+'abraham'
532+```
456533
457− > `@t`(max 'abraham' 'benjamin')
458− 'benjamin'
534+```
535+> `@t`(max 'abraham' 'benjamin')
536+'benjamin'
537+```
459538
460− > `@dr`(max ~m6 ~h1)
461− ~h1
539+```
540+> `@dr`(max ~m6 ~h1)
541+~h1
542+```
462543
463− >`@ux`(max 0xe1 0x1e)
464− 0xe1
544+```
545+>`@ux`(max 0xe1 0x1e)
546+0xe1
465547```
466548
467549---
468−### `++min`
550+
551+## `++min`
469552
470553Minimum
471554
@@ -484,42 +567,54 @@ An [`atom`](/docs/glossary/atom).
484567#### Source
485568
486569```hoon
487− ++ min
488− ~/ %min
489− |= [a=@ b=@]
490− ^- @
491− ?: (lth a b) a
492− b
570+++ min
571+ ~/ %min
572+ |= [a=@ b=@]
573+ ^- @
574+ ?: (lth a b) a
575+ b
493576```
494577
495578#### Examples
496579
497580```
498− > (min 10 100)
499− 10
500−
501− > (min 10.443 9)
502− 9
581+> (min 10 100)
582+10
583+```
503584
504− > (min 1 1)
505− 1
585+```
586+> (min 10.443 9)
587+9
588+```
506589
507− > (min 'abraham' 'bob')
508− 6.451.042
590+```
591+> (min 1 1)
592+1
593+```
509594
510− > `@t`(min 'abraham' 'bob')
511− 'bob'
595+```
596+> (min 'abraham' 'bob')
597+6.451.042
598+```
512599
513− > `@t`(min 'abraham' 'benjamin')
514− 'abraham'
600+```
601+> `@t`(min 'abraham' 'bob')
602+'bob'
603+```
515604
516− > `@dr`(min ~m6 ~h1)
517− ~m6
605+```
606+> `@t`(min 'abraham' 'benjamin')
607+'abraham'
518608```
519609
610+```
611+> `@dr`(min ~m6 ~h1)
612+~m6
613+```
520614
521615---
522−### `++mod`
616+
617+## `++mod`
523618
524619Modulus
525620
@@ -538,39 +633,48 @@ An [`atom`](/docs/glossary/atom).
538633#### Source
539634
540635```hoon
541− ++ mod
542− ~/ %mod
543− |: [a=`@`1 b=`@`1]
544− ^- @
545− ?< =(0 b)
546− (sub a (mul b (div a b)))
636+++ mod
637+ ~/ %mod
638+ |: [a=`@`1 b=`@`1]
639+ ^- @
640+ ?< =(0 b)
641+ (sub a (mul b (div a b)))
547642```
548643
549644#### Examples
550645
551646```
552− > (mod 5 2)
553− 1
647+> (mod 5 2)
648+1
649+```
554650
555− > (mod 5 5)
556− 0
651+```
652+> (mod 5 5)
653+0
654+```
557655
558− > (mod 2 5)
559− 2
656+```
657+> (mod 2 5)
658+2
659+```
560660
561− > (mod 40 20)
562− 0
661+```
662+> (mod 40 20)
663+0
664+```
563665
564− > `@`'c'
565− 99
566− >`@`'a'
567− 97
568− > (mod 'c' 'a')
569− 2
666+```
667+> `@`'c'
668+99
669+>`@`'a'
670+97
671+> (mod 'c' 'a')
672+2
570673```
571674
572675---
573−### `++mul`
676+
677+## `++mul`
574678
575679Multiply
576680
@@ -589,39 +693,45 @@ An [`atom`](/docs/glossary/atom).
589693#### Source
590694
591695```hoon
592− ++ mul
593− ~/ %mul
594− |: [a=`@`1 b=`@`1]
595− ^- @
596− =+ c=0
597− |-
598− ?: =(0 a) c
599− $(a (dec a), c (add b c))
696+++ mul
697+ ~/ %mul
698+ |: [a=`@`1 b=`@`1]
699+ ^- @
700+ =+ c=0
701+ |-
702+ ?: =(0 a) c
703+ $(a (dec a), c (add b c))
600704```
601705
602706#### Examples
603707
604708```
605− > (mul 3 4)
606− 12
607−
608− > (mul 0 1)
609− 0
709+> (mul 3 4)
710+12
711+```
610712
611− > `@`'a'
612− 97
613− > `@`'b'
614− 98
615− > (mul 'a' 'b')
616− 9.506
713+```
714+> (mul 0 1)
715+0
716+```
617717
618− >`@ux`(mul 0x1f 0xe)
619− 0x1b2
718+```
719+> `@`'a'
720+97
721+> `@`'b'
722+98
723+> (mul 'a' 'b')
724+9.506
620725```
621726
727+```
728+>`@ux`(mul 0x1f 0xe)
729+0x1b2
730+```
622731
623732---
624−### `++sub`
733+
734+## `++sub`
625735
626736Subtract
627737
@@ -640,41 +750,50 @@ An [`atom`](/docs/glossary/atom).
640750#### Source
641751
642752```hoon
643− ++ sub
644− ~/ %sub
645− |= [a=@ b=@]
646− ~_ leaf+"subtract-underflow"
647− ^- @
648− ?: =(0 b) a
649− $(a (dec a), b (dec b))
753+++ sub
754+ ~/ %sub
755+ |= [a=@ b=@]
756+ ~_ leaf+"subtract-underflow"
757+ ^- @
758+ ?: =(0 b) a
759+ $(a (dec a), b (dec b))
650760```
651761
652−
653762#### Examples
654763
655764```
656− > (sub 10 5)
657− 5
765+> (sub 10 5)
766+5
767+```
658768
659− > (sub 243 44)
660− 199
769+```
770+> (sub 243 44)
771+199
772+```
661773
662− > (sub 5 0)
663− 5
774+```
775+> (sub 5 0)
776+5
777+```
664778
665− > (sub 0 5)
666− ! subtract-underflow
667− ! exit
779+```
780+> (sub 0 5)
781+! subtract-underflow
782+! exit
783+```
668784
669− > (sub 'c' 'a')
670− 2
671− > `@`'c'
672− 99
673− > `@`'a'
674− 97
785+```
786+> (sub 'c' 'a')
787+2
788+> `@`'c'
789+99
790+> `@`'a'
791+97
792+```
675793
676− > (sub 0x1f 0xe)
677− 17
678− > `@ux`(sub 0x1f 0xe)
679− 0x11
680−```
794+```
795+> (sub 0x1f 0xe)
796+17
797+> `@ux`(sub 0x1f 0xe)
798+0x11
799+```
content/docs/hoon/reference/stdlib/1b.md+125−89
@@ -7,7 +7,7 @@ template = "doc.html"
77Check out the Nock [explanation](/docs/nock/) for more
88information on the tree-addressing system.
99
10−### `++cap`
10+## `++cap`
1111
1212Tree head
1313
@@ -15,7 +15,6 @@ Tests whether the tree address `a` is in the head or the tail of a [`noun`](/doc
1515Produces the constant [`atom`](/docs/glossary/atom) `%2` if it is within the head (subtree `+2`), or
1616the constant [`atom`](/docs/glossary/atom) `%3` if it is within the tail (subtree `+3`).
1717
18−
1918#### Accepts
2019
2120`a` is an [`atom`](/docs/glossary/atom).
@@ -27,46 +26,57 @@ A constant [`atom`](/docs/glossary/atom).
2726#### Source
2827
2928```hoon
30− ++ cap
31− ~/ %cap
32− |= a=@
33− ^- ?($2 $3)
34− ?- a
35− $2 %2
36− $3 %3
37− ?(%0 %1) !!
38− * $(a (div a 2))
39− ==
29+++ cap
30+ ~/ %cap
31+ |= a=@
32+ ^- ?(%2 %3)
33+ ?- a
34+ %2 %2
35+ %3 %3
36+ ?(%0 %1) !!
37+ * $(a (div a 2))
38+ ==
4039```
4140
4241#### Examples
4342
4443```
45− > (cap 4)
46− %2
44+> (cap 4)
45+%2
46+```
4747
48− > (cap 6)
49− %3
48+```
49+> (cap 6)
50+%3
51+```
5052
51− > (cap (add 10 9))
52− %2
53+```
54+> (cap (add 10 9))
55+%2
56+```
5357
54− > (cap 1) ::address '1' is in neither the head nor the tail
55− ! exit
58+```
59+> (cap 1) ::address '1' is in neither the head nor the tail
60+! exit
61+```
5662
57− > (cap 0x40))
58− %2
59− > `@`0x40
60− 64
63+```
64+> (cap 0x40))
65+%2
66+> `@`0x40
67+64
68+```
6169
62− > (cap 'a')
63− %3
64− > `@`'a'
65− 97
70+```
71+> (cap 'a')
72+%3
73+> `@`'a'
74+97
6675```
6776
6877---
69−### `++mas`
78+
79+## `++mas`
7080
7181Address within head/tail
7282
@@ -84,51 +94,66 @@ An [`atom`](/docs/glossary/atom).
8494#### Source
8595
8696```hoon
87− ++ mas
88− ~/ %mas
89− |= a=@
90− ^- @
91− ?- a
92− 1 !!
93− 2 1
94− 3 1
95− * (add (mod a 2) (mul $(a (div a 2)) 2))
96− ==
97+++ mas
98+ ~/ %mas
99+ |= a=@
100+ ^- @
101+ ?- a
102+ ?(%2 %3) 1
103+ ?(%0 %1) !!
104+ * (add (mod a 2) (mul $(a (div a 2)) 2))
105+ ==
97106```
98107
99108#### Examples
100109
101110```
102− > (mas 3)
103− 1
111+> (mas 3)
112+1
113+```
104114
105− > (mas 4)
106− 2
115+```
116+> (mas 4)
117+2
118+```
107119
108− > (mas 5)
109− 3
110− > (cap 5) ::`(cap a)` computes whether address `a` is in the head or the tail
111− %2
120+```
121+> (mas 5)
122+3
123+> (cap 5) ::`(cap a)` computes whether address `a` is in the head or the tail
124+%2
125+```
112126
113− > (mas 7)
114− 3
115− > (cap 7)
116− %3
127+```
128+> (mas 7)
129+3
130+> (cap 7)
131+%3
132+```
117133
118− > (mas 11)
119− 7
134+```
135+> (mas 11)
136+7
137+```
120138
121− > (mas (mas 11))
122− 3
139+```
140+> (mas (mas 11))
141+3
142+```
123143
124− > (cap (mas 6))
125− %3
144+```
145+> (cap (mas 6))
146+%3
147+```
126148
127− > (mas 0)
128− ! exit ::address `0` is in neither the head nor the tail
149+```
150+> (mas 0) ::address `0` is in neither the head nor the tail
151+! exit
152+```
129153
130− > (mas 1)
131− ! exit ::address `1` is in neither the head nor the tail
154+```
155+> (mas 1) ::address `1` is in neither the head nor the tail
156+! exit
132157```
133158
134159#### Discussion
@@ -166,7 +191,8 @@ Notice how the old values in the head (subtree `+2`) were not illustrated in
166191this case, because `+7` is within the tail (subtree `+3`).
167192
168193---
169−### `++peg`
194+
195+## `++peg`
170196
171197Address within address
172198
@@ -186,43 +212,54 @@ An [`atom`](/docs/glossary/atom).
186212#### Source
187213
188214```hoon
189− ++ peg
190− ~/ %peg
191− |= [a=@ b=@]
192− ?< =(0 a)
193− ^- @
194− ?- b
195− $1 a
196− $2 (mul a 2)
197− $3 +((mul a 2))
198− * (add (mod b 2) (mul $(b (div b 2)) 2))
199− ==
215+++ peg
216+ ~/ %peg
217+ |= [a=@ b=@]
218+ ?< =(0 a)
219+ ^- @
220+ ?- b
221+ %1 a
222+ %2 (mul a 2)
223+ %3 +((mul a 2))
224+ * (add (mod b 2) (mul $(b (div b 2)) 2))
225+ ==
200226```
201227
202228#### Examples
203229
204230```
205− > (peg 4 1)
206− 4
207−
208− > (peg 1 4)
209− 4
231+> (peg 4 1)
232+4
233+```
210234
211− > (peg 4 2)
212− 8
235+```
236+> (peg 1 4)
237+4
238+```
213239
214− > (peg 4 8)
215− 32
240+```
241+> (peg 4 2)
242+8
243+```
216244
217− > (peg 4 (4 2))
218− 32
245+```
246+> (peg 4 8)
247+32
248+```
219249
220− > (peg 8 45)
221− 269
250+```
251+> (peg 4 (4 2))
252+32
253+```
222254
223− > (cap (peg 4 2)) ::`(cap a)` computes whether address `a` is in the head or the tail
224− %2
255+```
256+> (peg 8 45)
257+269
258+```
225259
260+```
261+> (cap (peg 4 2)) ::`(cap a)` computes whether address `a` is in the head or the tail
262+%2
226263```
227264
228265#### Discussion
@@ -269,5 +306,4 @@ Notice how relative address `+4` is at the same position as absolute address
269306 (continues...)
270307```
271308
272−
273309---
content/docs/hoon/reference/stdlib/1c.md+201−122
@@ -4,7 +4,7 @@ weight = 3
44template = "doc.html"
55+++
66
7−### `$bite`
7+## `+$bite`
88
99Atom slice specifier.
1010
@@ -42,7 +42,7 @@ supplied, it defaults to a value of 1.
4242 0
4343```
4444
45−### `$bloq`
45+## `+$bloq`
4646
4747Blocksize
4848
@@ -105,33 +105,40 @@ See the [bit arithmetic](/docs/hoon/reference/stdlib/2c) section for operations
105105
106106---
107107
108−### `++each`
108+## `++each`
109109
110110Mold of fork between two types
111111
112112A mold generator. Produces a discriminated fork between two types, defaulting to
113−`a`.
113+`this`.
114114
115115#### Source
116116
117− ++ each
118− |*([a=mold b=mold] $%([$| p=b] [$& p=a]))
119−
117+```hoon
118+++ each
119+ |$ [this that]
120+ $% [%| p=that]
121+ [%& p=this]
122+ ==
123+```
120124
121125#### Examples
122126
123127```
124− > ? *(each cord time)
125− ?({$.y p/@t} {$.n p/@da})
126− [%.y p='']
128+> ? *(each cord time)
129+ ?([%.y p=@t] [%.n p=@da])
130+[%.y p='']
131+```
127132
128− > ? *(each * tape)
129− ?({$.y p/*} {$.n p/""})
130− [%.y p=0]
133+```
134+> ? *(each * tape)
135+ ?([%.y p=*] [%.n p=""])
136+[%.y p=0]
131137```
132138
133139---
134−### `++gate`
140+
141+## `++gate`
135142
136143Function
137144
@@ -139,7 +146,6 @@ A [`core`](/docs/glossary/core) with one arm, `$`--the empty name--which transfo
139146product noun. If used dryly as a type, the subject must have a sample type of
140147`*`.
141148
142−
143149#### Source
144150
145151```hoon
@@ -150,16 +156,23 @@ product noun. If used dryly as a type, the subject must have a sample type of
150156#### Examples
151157
152158```
153− > ? gate
154− <1.rdl {* <31.ohr 1.jmk $143>}>
155− <1.rdl {* <31.ohr 1.jmk $143>}>
159+> ? gate
160+ <1.ddq [* <46.hgz 1.pnw %140>]>
161+<1.ddq [* <46.hgz 1.pnw %140>]>
162+```
156163
157− > (`gate`|=(a=* [a 'b']) 1)
158− [1 98]
164+```
165+> (`gate`|=(a=* [a 'b']) 1)
166+[1 98]
167+```
159168
160− > (`gate`|=(a=@ [a 'b']) 1)
161− ! nest-fail
162− ! exit
169+```
170+> (`gate`|=(a=@ [a 'b']) 1)
171+mint-nice
172+-need.@
173+-have.*
174+nest-fail
175+dojo: hoon expression failed
163176```
164177
165178#### Discussion
@@ -171,43 +184,51 @@ mathematical sense. Any `gate` normalizes to an iron `gate`.
171184See also: [`++lift`](/docs/hoon/reference/stdlib/2a#lift), [`++cork`](/docs/hoon/reference/stdlib/2n#cork)
172185
173186---
174−### `++list`
187+
188+## `++list`
175189
176190List
177191
178192A mold generator. Generates a mold of a null-terminated list of a
179193homogenous type.
180194
181−
182195#### Source
183196
184197```hoon
185− ++ list
186− |*(a=mold $@($~ (lest a)))
198+++ list
199+ |$ [item]
200+ $@(~ [i=item t=(list item)])
187201```
188202
189203#### Examples
190204
191205```
192− > *(list)
193− ~
194−
195− > `(list @)`"abc"
196− ~[97 98 99]
206+> *(list)
207+~
208+```
197209
198− > (snag 0 "abc")
199− 'a'
210+```
211+> `(list @)`"abc"
212+~[97 98 99]
213+```
200214
201− > `(list @)`[1 2 'j' ~]
202− ~[1 2 106]
215+```
216+> (snag 0 "abc")
217+'a'
218+```
203219
204220```
221+> `(list @)`[1 2 'j' ~]
222+~[1 2 106]
223+```
224+
205225#### Discussion
206226
207227See also: [`++turn`](/docs/hoon/reference/stdlib/2b#turn), [`++snag`](/docs/hoon/reference/stdlib/2b#snag)
208228
209229---
210−### `++lone`
230+
231+## `++lone`
211232
212233Face on mold
213234
@@ -216,56 +237,68 @@ A mold generator. Puts face of `p` on the passed-in mold.
216237#### Source
217238
218239```hoon
219− ++ lone
220− |*(a=mold [p=a])
240+++ lone
241+ |$ [item]
242+ p=item
221243```
222244
223245#### Examples
224246
225247```
226− > ? *cord
227− @t
228− ''
229− > ? *(lone cord)
230− p/@t
231− p=''
248+> ? *cord
249+@t
250+''
251+```
252+
253+```
254+> ? *(lone cord)
255+ p=@t
256+p=''
257+```
258+
259+```
260+> ? *(lone @)
261+ p=@
262+p=0
263+```
232264
233− > ? *(lone @)
234− p/@
235− p=0
236− > ? *@
237− @
238− 0
265+```
266+> ? *@
267+ @
268+0
239269```
240270
241271---
242−### `++pair`
272+
273+## `++pair`
243274
244275Mold of pair of types
245276
246277A mold generator. Produces a tuple of two of the types passed in.
247278
248−
249279#### Source
250280
251281```hoon
252− ++ pair
253− |*([a=mold b=mold] [p=a q=b])
282+++ pair
283+ |$ [head tail]
284+ [p=head q=tail]
254285```
255286
256287#### Examples
257288
258289```
259− > *(pair ? cord)
260− [p=%.y q='']
261−
262− > *(pair tape @)
263− [p="" q=0]
290+> *(pair ? cord)
291+[p=%.y q='']
292+```
264293
294+```
295+> *(pair tape @)
296+[p="" q=0]
265297```
266298
267299---
268−### `++pole`
300+
301+## `++pole`
269302
270303Faceless [`list`](/docs/hoon/reference/stdlib/1c#list)
271304
@@ -274,24 +307,26 @@ A mold generator. A [`list`](/docs/hoon/reference/stdlib/1c#list) without the fa
274307#### Source
275308
276309```hoon
277− ++ pole
278− |*(a=mold $@($~ [a (pole a)]))
310+++ pole
311+ |$ [item]
312+ $@(~ [item (pole item)])
279313```
280314
281−
282315#### Examples
283316
284317```
285− > =/(a "asdf" ?>(?=(^ a) `(lest @tD)`a))
286− [i='a' t=[i='s' t=[i='d' t=[i='f' t=~]]]]
287−
288− > `(pole char)`"asdf"
289− ['a' ['s' ['d' ['f' ~]]]]
318+> =/(a "asdf" ?>(?=(^ a) `(lest @tD)`a))
319+[i='a' t=[i='s' t=[i='d' t=[i='f' t=~]]]]
290320```
291321
322+```
323+> `(pole char)`"asdf"
324+['a' ['s' ['d' ['f' ~]]]]
325+```
292326
293327---
294−### `++qual`
328+
329+## `++qual`
295330
296331Mold of 4-type tuple
297332
@@ -300,43 +335,49 @@ A mold generator. Produces a tuple of four of the types passed in.
300335#### Source
301336
302337```hoon
303− ++ qual
304− |* [a=mold b=mold c=mold d=mold]
305− [p=a q=b r=c s=d]
338+++ qual
339+ |$ [first second third fourth]
340+ [p=first q=second r=third s=fourth]
306341```
307342
308343#### Examples
309344
310345```
311− > *(qual date time tape cord)
312− [p=[[a=%.y y=0] m=0 t=[d=0 h=0 m=0 s=0 f=~]] q=~292277024401-.1.1 r="" s='']
346+> *(qual date time tape cord)
347+[p=[[a=%.y y=0] m=0 t=[d=0 h=0 m=0 s=0 f=~]] q=~2000.1.1 r="" s='']
348+```
313349
314− > *(qual (list @) @u @ud @ux)
315− [p=~ q=0 r=0 s=0x0]
350+```
351+> *(qual (list @) @u @ud @ux)
352+[p=~ q=0 r=0 s=0x0]
316353```
317354
318355---
319−### `++quip`
356+
357+## `++quip`
320358
321359Mold of pair of [`list`](/docs/hoon/reference/stdlib/1c#list) and type
322360
323−A mold generator. Produces a tuple of a [`list`](/docs/hoon/reference/stdlib/1c#list) of `a` and the mold of `b`.
361+A mold generator. Produces a tuple of a [`list`](/docs/hoon/reference/stdlib/1c#list) of `item` and the mold of `state`.
324362
325363#### Source
326364
327365```hoon
328− ++ quip
329− |*([a=mold b=mold] [(list a) b])
366+++ quip
367+ |$ [item state]
368+ [(list item) state]
330369```
331370
332371#### Examples
333372
334373```
335− > *(quip @ _'hi')
336− [~ 'hi']
374+> *(quip @ _'hi')
375+[~ 'hi']
376+```
337377
338− > `(quip @ @ux)`[[1 2 3 4 ~] 0x10]
339− [~[1 2 3 4] 0x10]
378+```
379+> `(quip @ @ux)`[[1 2 3 4 ~] 0x10]
380+[~[1 2 3 4] 0x10]
340381```
341382
342383#### Discussion
@@ -345,7 +386,33 @@ A common pattern in Hoon code is to return a `list` of changes, along with a
345386new state. You'll often see `quip` used in Gall apps.
346387
347388---
348−### `++trap`
389+
390+## `++step`
391+
392+Atom size or offset, in [bloq](#bloq)s.
393+
394+#### Source
395+
396+```
397+++ step
398+ _`@u`1
399+```
400+
401+#### Examples
402+
403+```
404+> `step`0
405+0
406+```
407+
408+```
409+> `step`2
410+2
411+```
412+
413+---
414+
415+## `++trap`
349416
350417[`Core`](/docs/glossary/core) with one arm `$`
351418
@@ -354,26 +421,31 @@ A trap is a [`core`](/docs/glossary/core) with one arm `$`.
354421#### Source
355422
356423```hoon
357− ++ trap
358− |*(a=mold _|?(*a))
424+++ trap
425+ |$ [product]
426+ _|?($:product)
359427```
360428
361429#### Examples
362430
363431```
364− > (*trap)
365− <1?dxy 1.oeg {a/<1|rbb {* <31.ohr 1.jmk $143>}> <31.ohr 1.jmk $143>}>
366−
367− > *(*trap)
368− 0
432+> (*trap)
433+<1?ruo 1.mhl [product=<1|xpg [* * *]> <46.hgz 1.pnw %140>]>
434+```
369435
370− > (|.(42))
371− 42
436+```
437+> *(*trap)
438+0
372439```
373440
441+```
442+> (|.(42))
443+42
444+```
374445
375446---
376−### `++tree`
447+
448+## `++tree`
377449
378450Tree mold generator
379451
@@ -383,20 +455,21 @@ left/right sub `tree` of the same type. Pretty-printed with `{}`.
383455#### Source
384456
385457```hoon
386− ++ tree
387− |*(a=mold $@($~ [n=a l=(tree a) r=(tree a)]))
458+++ tree
459+ |$ [node]
460+ $@(~ [n=node l=(tree node) r=(tree node)])
388461```
389462
390463#### Examples
391464
392465```
393− > `(tree [@ tape])`[[1 "hi"] [[2 "bye"] ~ ~] ~]
394− {[2 "bye"] [1 "hi"]}
466+> `(tree [@ tape])`[[1 "hi"] [[2 "bye"] ~ ~] ~]
467+{[2 "bye"] [1 "hi"]}
395468```
396469
397−
398470---
399−### `++trel`
471+
472+## `++trel`
400473
401474Mold of three types
402475
@@ -405,49 +478,55 @@ A mold generator. A mold of the tuple of the three types passed in.
405478#### Source
406479
407480```hoon
408− ++ trel
409− |*([a=mold b=mold c=mold] [p=a q=b r=c])
481+++ trel
482+ |$ [first second third]
483+ [p=first q=second r=third]
410484```
411485
412486#### Examples
413487
414488```
415− > *(trel @ud @t @s)
416− [p=0 q='' r=--0]
489+> *(trel @ud @t @s)
490+[p=0 q='' r=--0]
491+```
417492
418− > *(trel cord bloq tape)
419− [p='' q=0 r=""]
493+```
494+> *(trel cord bloq tape)
495+[p='' q=0 r=""]
420496```
421497
422498---
423−### `++unit`
499+
500+## `++unit`
424501
425502Maybe
426503
427−A mold generator. A `unit` is either `~` or `[~ u=a]`, where `a` is the
504+A mold generator. A `unit` is either `~` or `[~ u=item]`, where `item` is the
428505type that was passed in.
429506
430−
431507#### Source
432508
433509```hoon
434− ++ unit
435− |*(a=mold $@($~ [$~ u=a]))
510+++ unit
511+ |$ [item]
512+ $@(~ [~ u=item])
436513```
437514
438515#### Examples
439516
440517```
441− > ? *(unit time)
442− ?({$~ u/@da} $~)
443− ~
518+> ? *(unit time)
519+ u(@da)
520+~
521+```
444522
445− > =a |= a=@
446− ^- (unit @)
447− ?~ a ~
448− [~ a]
449− > (a 2)
450− [~ u=2]
523+```
524+> =a |= a=@
525+ ^- (unit @)
526+ ?~ a ~
527+ [~ a]
528+> (a 2)
529+[~ 2]
451530```
452531
453532#### Discussion
content/docs/hoon/reference/stdlib/2a.md+298−131
@@ -4,7 +4,7 @@ weight = 4
44template = "doc.html"
55+++
66
7−### `++biff`
7+## `++biff`
88
99[`Unit`](/docs/hoon/reference/stdlib/1c#unit) as argument
1010
@@ -24,25 +24,27 @@ A [`unit`](/docs/hoon/reference/stdlib/1c#unit).
2424#### Source
2525
2626```hoon
27− ++ biff
28− |* [a=(unit) b=$-(* (unit))]
29− ?~ a ~
30− (b u.a)
27+++ biff
28+ |* [a=(unit) b=$-(* (unit))]
29+ ?~ a ~
30+ (b u.a)
3131```
3232
3333#### Examples
3434
3535```
36− > (biff (some 5) |=(a=@ (some (add a 2))))
37− [~ u=7]
38−
39− > (biff ~ |=(a=@ (some (add a 2))))
40− ~
36+> (biff (some 5) |=(a=@ (some (add a 2))))
37+[~ u=7]
4138```
4239
40+```
41+> (biff ~ |=(a=@ (some (add a 2))))
42+~
43+```
4344
4445---
45−### `++bind`
46+
47+## `++bind`
4648
4749Non-unit function to [`unit`](/docs/hoon/reference/stdlib/1c#unit), producing [`unit`](/docs/hoon/reference/stdlib/1c#unit)
4850
@@ -63,27 +65,28 @@ A [`unit`](/docs/hoon/reference/stdlib/1c#unit).
6365#### Source
6466
6567```hoon
66− ++ bind
67− |* [a=(unit) b=gate]
68− ?~ a ~
69− [~ u=(b u.a)]
68+++ bind
69+ |* [a=(unit) b=gate]
70+ ?~ a ~
71+ [~ u=(b u.a)]
7072```
7173
72−
7374#### Examples
7475
7576```
76− > (bind ((unit @) [~ 97]) ,@t)
77− [~ u='a']
78−
79− > =a |=(a=@ (add a 1))
80− > (bind ((unit @) [~ 2]) a)
81− [~ u=3]
77+> (bind ((unit @) [~ 97]) ,@t)
78+[~ u='a']
8279```
8380
81+```
82+> =a |=(a=@ (add a 1))
83+> (bind ((unit @) [~ 2]) a)
84+[~ u=3]
85+```
8486
8587---
86−### `++bond`
88+
89+## `++bond`
8790
8891Replace null
8992
@@ -103,11 +106,11 @@ Either the product of `a` or the value inside of [`unit`](/docs/hoon/reference/s
103106#### Source
104107
105108```hoon
106− ++ bond
107− |* a=(trap)
108− |* b=(unit)
109− ?~ b $:a
110− u.b
109+++ bond
110+ |* a=(trap)
111+ |* b=(unit)
112+ ?~ b $:a
113+ u.b
111114```
112115
113116#### Examples
@@ -117,14 +120,16 @@ Either the product of `a` or the value inside of [`unit`](/docs/hoon/reference/s
117120 1.024
118121 > ((bond |.((bex 10))) ~)
119122 1.024
123+```
120124
125+```
121126 > ((bond |.((bex 10))) (slaw %ud '123'))
122127 123
123128```
124129
125−
126130---
127−### `++both`
131+
132+## `++both`
128133
129134Group [`unit`](/docs/hoon/reference/stdlib/1c#unit) values into pair
130135
@@ -145,31 +150,36 @@ A [`unit`](/docs/hoon/reference/stdlib/1c#unit) of the two initial values.
145150#### Source
146151
147152```hoon
148− ++ both
149− |* [a=(unit) b=(unit)]
150− ?~ a ~
151− ?~ b ~
152− [~ u=[u.a u.b]]
153+++ both
154+ |* [a=(unit) b=(unit)]
155+ ?~ a ~
156+ ?~ b ~
157+ [~ u=[u.a u.b]]
153158```
154159
155160#### Examples
156161
157162```
158− > (both (some 1) (some %b))
159− [~ u=[1 %b]]
163+> (both (some 1) (some %b))
164+[~ u=[1 %b]]
165+```
160166
161− > (both ~ (some %b))
162− ~
167+```
168+> (both ~ (some %b))
169+~
163170```
164171
165172---
166−### `++clap`
167173
168−Apply function to two [`units`](/docs/hoon/reference/stdlib/1c#unit)
174+## `++clap`
175+
176+Combine two [`units`](/docs/hoon/reference/stdlib/1c#unit) with function
169177
170178Applies a binary function `c`--which does not usually accept or produce a
171179[`unit`](/docs/hoon/reference/stdlib/1c#unit)-- to the values of two [`units`](/docs/hoon/reference/stdlib/1c#unit), `a` and `b`, producing a [`unit`](/docs/hoon/reference/stdlib/1c#unit).
172180
181+If `a` is null, produces `b`. If `b` is null, produces `a`. Otherwise, produces the produce of `c` in a `unit`.
182+
173183#### Accepts
174184
175185`a` is a [`unit`](/docs/hoon/reference/stdlib/1c#unit).
@@ -185,32 +195,82 @@ A [`unit`](/docs/hoon/reference/stdlib/1c#unit).
185195#### Source
186196
187197```hoon
188− ++ clap :: combine
189− |* [a=(unit) b=(unit) c=_|=(^ +<-)]
190− ?~ a b
191− ?~ b a
192− [~ u=(c u.a u.b)]
198+++ clap
199+ |* [a=(unit) b=(unit) c=_=>(~ |=(^ +<-))]
200+ ?~ a b
201+ ?~ b a
202+ [~ u=(c u.a u.b)]
193203```
194204
195205#### Examples
196206
197207```
198− > =u ((unit @t) [~ 'a'])
199− > =v ((unit @t) [~ 'b'])
200− > (clap u v |=([a=@t b=@t] (welp (trip a) (trip b))))
201− [~ u="ab"]
208+> (clap ~ `'b' |=([a=@tD b=@tD] `tape`[a b ~]))
209+[~ u='b']
210+```
211+
212+```
213+> (clap `'a' ~ |=([a=@tD b=@tD] `tape`[a b ~]))
214+[~ u='a']
215+```
216+
217+```
218+> (clap `'a' `'b' |=([a=@tD b=@tD] `tape`[a b ~]))
219+[~ u="ab"]
220+```
221+
222+---
223+
224+## `++clef`
225+
226+Compose two [`units`](/docs/hoon/reference/stdlib/1c#unit) with function
227+
228+Applies a binary function `c`--which does not usually accept [`units`](/docs/hoon/reference/stdlib/1c#unit)-- to the values of two [`units`](/docs/hoon/reference/stdlib/1c#unit), `a` and `b`, producing a [`unit`](/docs/hoon/reference/stdlib/1c#unit).
229+
230+If `a` or `b` are null, produces null. Otherwise, produces the produce of `c`.
231+
232+#### Accepts
233+
234+`a` is a `unit`.
235+
236+`b` is a `unit`.
237+
238+`c` is a `gate` that takes a `cell` and produces a `unit`.
239+
240+#### Produces
241+
242+A `unit`.
243+
244+#### Source
245+
246+```hoon
247+++ clef
248+ |* [a=(unit) b=(unit) c=_=>(~ |=(^ `+<-))]
249+ ?~ a ~
250+ ?~ b ~
251+ (c u.a u.b)
252+```
253+
254+#### Examples
202255
203− > =a ((unit @u) [~ 1])
204− > =b ((unit @u) [~ 2])
205− > =c |=([a=@ b=@] (add a b))
256+```
257+> (clef ~ `'b' |=([a=@tD b=@tD] `(unit tape)`[~ [a b ~]]))
258+~
259+```
206260
207− > (clap a b c)
208− [~ 3]
261+```
262+> (clef `'a' ~ |=([a=@tD b=@tD] `(unit tape)`[~ [a b ~]]))
263+~
209264```
210265
266+```
267+> (clef `'a' `'b' |=([a=@tD b=@tD] `(unit tape)`[~ [a b ~]]))
268+[~ "ab"]
269+```
211270
212271---
213−### `++drop`
272+
273+## `++drop`
214274
215275[`Unit`](/docs/hoon/reference/stdlib/1c#unit) to list
216276
@@ -227,27 +287,29 @@ A list.
227287#### Source
228288
229289```hoon
230− ++ drop :: enlist
231− |* a=(unit)
232− ?~ a ~
233− [i=u.a t=~]
290+++ drop
291+ |* a=(unit)
292+ ?~ a ~
293+ [i=u.a t=~]
234294```
235295
236296#### Examples
237297
238298```
239− > =a ((unit @) [~ 97])
240− > (drop a)
241− [i=97 t=~]
242−
243− > =a ((unit @) [~])
244− > (drop a)
245− ~
299+> =a ((unit @) [~ 97])
300+> (drop a)
301+[i=97 t=~]
246302```
247303
304+```
305+> =a ((unit @) [~])
306+> (drop a)
307+~
308+```
248309
249310---
250−### `++fall`
311+
312+## `++fall`
251313
252314Give [`unit`](/docs/hoon/reference/stdlib/1c#unit) a default value
253315
@@ -266,32 +328,125 @@ Either a [`noun`](/docs/glossary/noun) `b` or the unwrapped value of [`unit`](/d
266328#### Source
267329
268330```hoon
269− ++ fall :: default
270− |* [a=(unit) b=*]
271− ?~(a b u.a)
331+++ fall
332+ |* [a=(unit) b=*]
333+ ?~(a b u.a)
334+```
335+
336+#### Examples
337+
338+```
339+> (fall ~ 'a')
340+'a'
341+> (fall [~ u=0] 'a')
342+0
343+```
344+
345+---
346+
347+## `++flit`
348+
349+Make filter
350+
351+Accepts gate `a` which produces a `?`. Applies `a` to `b`, producing `b` wrapped in a `unit` if true, otherwise produces null.
352+
353+`+flit` is a wet gate that takes `a` and produces a new wet gate that takes `b`.
354+
355+#### Accepts
356+
357+`a` is a `gate` which produces `?`, and is the sample of the outer wet gate.
358+
359+`b` is any `noun`, and is the sample of the inner wet gate.
360+
361+#### Produces
362+
363+`(unit [type])`, where `[type]` is the type of `b`.
364+
365+#### Source
366+
367+```hoon
368+++ flit
369+ |* a=$-(* ?)
370+ |* b=*
371+ ?.((a b) ~ [~ u=b])
372+```
373+
374+#### Examples
375+
376+```
377+> =f (flit |=(=@ud ?:(=(ud 1) %.y %.n)))
378+> (f 1)
379+[~ 1]
380+> (f 2)
381+~
382+```
383+
384+---
385+
386+## `++hunt`
387+
388+First of units
389+
390+Apply binary gate `ord`, which produces a `?`, to units `a` and `b`. Produce `a` if true and `b` if false. If `a` is null, produce `b`. If `b` is null, produce `a`.
391+
392+This allows selecting between two units by some rule.
393+
394+#### Accepts
395+
396+`ord` is a `$-(^ ?)` - a binary gate that produces `?`.
397+
398+`a` is a `unit`.
399+
400+`b` is a `unit`.
401+
402+#### Produces
403+
404+A `unit`.
405+
406+#### Source
407+
408+```hoon
409+++ hunt
410+ |* [ord=$-(^ ?) a=(unit) b=(unit)]
411+ ^- %- unit
412+ $? _?>(?=(^ a) u.a)
413+ _?>(?=(^ b) u.b)
414+ ==
415+ ?~ a b
416+ ?~ b a
417+ ?:((ord u.a u.b) a b)
272418```
273419
274420#### Examples
275421
276422```
277− > (fall ~ 'a')
278− 'a'
279− > (fall [~ u=0] 'a')
280− 0
423+> (hunt gte ~ `20)
424+[~ 20]
425+```
426+
427+```
428+> (hunt gte `10 ~)
429+[~ 10]
430+```
431+
432+```
433+> (hunt gte `10 `20)
434+[~ 20]
281435```
282436
283437---
284−### `++lift`
438+
439+## `++lift`
285440
286441Curried bind
287442
288−Accepts a `++gate` `a` and produces a function that accepts [`unit`](/docs/hoon/reference/stdlib/1c#unit)
443+Accepts function `a` and produces a function that accepts [`unit`](/docs/hoon/reference/stdlib/1c#unit)
289444`b` to which it applies `a`. Used when you want a function that does not accept
290445or produce a [`unit`](/docs/hoon/reference/stdlib/1c#unit) to both accept and produce a [`unit`](/docs/hoon/reference/stdlib/1c#unit).
291446
292447#### Accepts
293448
294−`a` is a gate.
449+`a` is a `mold`.
295450
296451`b` is a [`unit`](/docs/hoon/reference/stdlib/1c#unit).
297452
@@ -302,25 +457,27 @@ A [`unit`](/docs/hoon/reference/stdlib/1c#unit).
302457#### Source
303458
304459```hoon
305− ++ lift :: lift gate (fmap)
306− |* a=gate :: flipped
307− |* b=(unit) :: curried
308− (bind b a) :: bind
460+++ lift
461+ |* a=mold
462+ |* b=(unit)
463+ (bind b a)
309464```
310465
311466#### Examples
312467
313468```
314− > ((lift dec) `(unit @)`~)
315− ~
316−
317− > ((lift dec) `(unit @)`[~ 20])
318− [~ 19]
469+> ((lift dec) `(unit @)`~)
470+~
319471```
320472
473+```
474+> ((lift dec) `(unit @)`[~ 20])
475+[~ 19]
476+```
321477
322478---
323−### `++mate`
479+
480+## `++mate`
324481
325482Choose
326483
@@ -343,36 +500,40 @@ A [`unit`](/docs/hoon/reference/stdlib/1c#unit) or crash.
343500#### Source
344501
345502```hoon
346− ++ mate :: choose
347− |* [a=(unit) b=(unit)]
348− ?~ b a
349− ?~ a b
350− ?.(=(u.a u.b) ~|('mate' !!) a)
503+++ mate
504+ |* [a=(unit) b=(unit)]
505+ ?~ b a
506+ ?~ a b
507+ ?.(=(u.a u.b) ~>(%mean.'mate' !!) a)
351508```
352509
353510#### Examples
354511
355512```
356− > =a ((unit @) [~ 97])
357− > =b ((unit @) [~ 97])
358− > (mate a b)
359− [~ 97]
360−
361− > =a ((unit @) [~ 97])
362− > =b ((unit @) [~])
363− > (mate a b)
364− [~ 97]
513+> =a ((unit @) [~ 97])
514+> =b ((unit @) [~ 97])
515+> (mate a b)
516+[~ 97]
517+```
365518
366− > =a ((unit @) [~ 97])
367− > =b ((unit @) [~ 98])
368− > (mate a b)
369− ! 'mate'
370− ! exit
519+```
520+> =a ((unit @) [~ 97])
521+> =b ((unit @) [~])
522+> (mate a b)
523+[~ 97]
371524```
372525
526+```
527+> =a ((unit @) [~ 97])
528+> =b ((unit @) [~ 98])
529+> (mate a b)
530+! 'mate'
531+! exit
532+```
373533
374534---
375−### `++need`
535+
536+## `++need`
376537
377538Unwrap [`unit`](/docs/hoon/reference/stdlib/1c#unit)
378539
@@ -389,31 +550,36 @@ Either the unwrapped value of `a` (`u.a`), or crash.
389550#### Source
390551
391552```hoon
392− ++ need :: demand
393− |* a=(unit)
394− ?~ a ~|(%need !!)
395− u.a
553+++ need
554+ ~/ %need
555+ |* a=(unit)
556+ ?~ a ~>(%mean.'need' !!)
557+ u.a
396558```
397559
398560#### Examples
399561
400562```
401− > =a ((unit [@t @t]) [~ ['a' 'b']])
402− > (need a)
403− ['a' 'b']
404−
405− > =a ((unit @ud) [~ 17])
406− > (need a)
407− 17
563+> =a ((unit [@t @t]) [~ ['a' 'b']])
564+> (need a)
565+['a' 'b']
566+```
408567
409− > =a ((unit @) [~])
410− > (need a)
411− ! exit
568+```
569+> =a ((unit @ud) [~ 17])
570+> (need a)
571+17
412572```
413573
574+```
575+> =a ((unit @) [~])
576+> (need a)
577+! exit
578+```
414579
415580---
416−### `++some`
581+
582+## `++some`
417583
418584Wrap value in a [`unit`](/docs/hoon/reference/stdlib/1c#unit)
419585
@@ -430,20 +596,21 @@ A [`unit`](/docs/hoon/reference/stdlib/1c#unit).
430596#### Source
431597
432598```hoon
433− ++ some :: lift (pure)
434− |* a=*
435− [~ u=a]
599+++ some
600+ |* a=*
601+ [~ u=a]
436602```
437603
438604#### Examples
439605
440606```
441− > (some ['a' 'b'])
442− [~ u=['a' 'b']]
443−
444− > (some &)
445− [~ u=%.y]
607+> (some ['a' 'b'])
608+[~ u=['a' 'b']]
446609```
447610
611+```
612+> (some &)
613+[~ u=%.y]
614+```
448615
449616---
content/docs/hoon/reference/stdlib/2b.md+664−431
@@ -4,7 +4,53 @@ weight = 5
44template = "doc.html"
55+++
66
7−### `++fand`
7+## `++bake`
8+
9+**Note:** This function isn't specifically a list function but is included in section 2b of the standard library so is documented here for completeness.
10+
11+Convert wet gate `f` to a dry gate by specifying argument mold `a`.
12+
13+`+bake` is a wet gate that takes a wet gate and produces a dry gate.
14+
15+#### Accepts
16+
17+`f` is a `gate`.
18+
19+`a` is a `mold`.
20+
21+#### Produces
22+
23+A dry `gate` whose sample type is `a`.
24+
25+#### Source
26+
27+```hoon
28+++ bake
29+ |* [f=gate a=mold]
30+ |= arg=a
31+ (f arg)
32+```
33+
34+#### Examples
35+
36+```
37+> =wet-gate |*(a=* [a a])
38+> (wet-gate 42)
39+[42 42]
40+> (wet-gate ['foo' 'bar'])
41+[['foo' 'bar'] 'foo' 'bar']
42+> =dry-gate (bake wet-gate @ud)
43+> (dry-gate 42)
44+[42 42]
45+> (dry-gate ['foo' 'bar'])
46+-need.@ud
47+-have.[@t @t]
48+nest-fail
49+```
50+
51+---
52+
53+## `++fand`
854
955All indices in `list`
1056
@@ -24,42 +70,48 @@ A `list`.
2470#### Source
2571
2672```hoon
27− ++ fand
28− ~/ %fand
29− |= [nedl=(list) hstk=(list)]
30− =| i=@ud
31− =| fnd=(list @ud)
32− |- ^+ fnd
33− =+ [n=nedl h=hstk]
34− |-
35− ?: |(?=($~ n) ?=($~ h))
36− (flop fnd)
37− ?: =(i.n i.h)
38− ?~ t.n
39− ^$(i +(i), hstk +.hstk, fnd [i fnd])
40− $(n t.n, h t.h)
41− ^$(i +(i), hstk +.hstk)
73+++ fand
74+ ~/ %fand
75+ |= [nedl=(list) hstk=(list)]
76+ =| i=@ud
77+ =| fnd=(list @ud)
78+ |- ^+ fnd
79+ =+ [n=nedl h=hstk]
80+ |-
81+ ?: |(?=(~ n) ?=(~ h))
82+ (flop fnd)
83+ ?: =(i.n i.h)
84+ ?~ t.n
85+ ^$(i +(i), hstk +.hstk, fnd [i fnd])
86+ $(n t.n, h t.h)
87+ ^$(i +(i), hstk +.hstk)
4288```
4389
4490#### Examples
4591
4692```
47− > (fand ~[3] ~[1 2 3])
48− ~[2]
49−
50− > (fand ~[4] ~[1 2 3])
51− ~
93+> (fand ~[3] ~[1 2 3])
94+~[2]
95+```
5296
53− > (fand ~['a'] "cbabab")
54− ~[2 4]
97+```
98+> (fand ~[4] ~[1 2 3])
99+~
100+```
55101
56− > (fand "ba" "cbabab")
57− ~[1 3]
102+```
103+> (fand ~['a'] "cbabab")
104+~[2 4]
58105```
59106
107+```
108+> (fand "ba" "cbabab")
109+~[1 3]
110+```
60111
61112---
62−### `++find`
113+
114+## `++find`
63115
64116First index in `list`
65117
@@ -79,43 +131,52 @@ The `unit` of an atom.
79131#### Source
80132
81133```hoon
82− ++ find
83− ~/ %find
84− |= [nedl=(list) hstk=(list)]
85− =| i=@ud
86− |- ^- (unit @ud)
87− =+ [n=nedl h=hstk]
88− |-
89− ?: |(?=($~ n) ?=($~ h))
90− ~
91− ?: =(i.n i.h)
92− ?~ t.n
93− `i
94− $(n t.n, h t.h)
95− ^$(i +(i), hstk +.hstk)
134+++ find
135+ ~/ %find
136+ |= [nedl=(list) hstk=(list)]
137+ =| i=@ud
138+ |- ^- (unit @ud)
139+ =+ [n=nedl h=hstk]
140+ |-
141+ ?: |(?=(~ n) ?=(~ h))
142+ ~
143+ ?: =(i.n i.h)
144+ ?~ t.n
145+ `i
146+ $(n t.n, h t.h)
147+ ^$(i +(i), hstk +.hstk)
96148```
97149
98150#### Examples
99151
100152```
101− > (find [3]~ ~[1 2 3])
102− [~ u=2]
153+> (find [3]~ ~[1 2 3])
154+[~ u=2]
155+```
103156
104− > (find [4]~ ~[1 2 3])
105− ~
157+```
158+> (find [4]~ ~[1 2 3])
159+~
160+```
106161
107− > (find ['c']~ "cbabab")
108− [~ u=0]
162+```
163+> (find ['c']~ "cbabab")
164+[~ u=0]
165+```
109166
110− > (find "ab" "cbabab")
111− [~ u=1]
167+```
168+> (find "ab" "cbabab")
169+[~ u=2]
170+```
112171
113− > (find "bab" "cbabab")
114− [~ u=2]
172+```
173+> (find "bab" "cbabab")
174+[~ u=1]
115175```
116176
117177---
118−### `++flop`
178+
179+## `++flop`
119180
120181Reverse
121182
@@ -132,31 +193,33 @@ A `list`.
132193#### Source
133194
134195```hoon
135− ++ flop
136− ~/ %flop
137− |* a=(list)
138− => .(a (homo a))
139− ^+ a
140− =+ b=`_a`~
141− |-
142− ?~ a b
143− $(a t.a, b [i.a b])
196+++ flop
197+ ~/ %flop
198+ |* a=(list)
199+ => .(a (homo a))
200+ ^+ a
201+ =+ b=`_a`~
202+ |-
203+ ?~ a b
204+ $(a t.a, b [i.a b])
144205```
145206
146−
147207#### Examples
148208
149209```
150− > =a [1 2 3 ~]
151− > (flop a)
152− ~[3 2 1]
210+> =a [1 2 3 ~]
211+> (flop a)
212+~[3 2 1]
213+```
153214
154− > (flop (flop a))
155− ~[1 2 3]
215+```
216+> (flop (flop a))
217+~[1 2 3]
156218```
157219
158220---
159−### `++gulf`
221+
222+## `++gulf`
160223
161224List from range
162225
@@ -176,24 +239,28 @@ a `list`.
176239#### Source
177240
178241```hoon
179− ++ gulf
180− |= [a=@ b=@]
181− ^- (list @)
182− ?:(=(a +(b)) ~ [a $(a +(a))])
242+++ gulf
243+ |= [a=@ b=@]
244+ ?> (lte a b)
245+ |- ^- (list @)
246+ ?:(=(a +(b)) ~ [a $(a +(a))])
183247```
184248
185249#### Examples
186250
187251```
188− > (gulf 1 6)
189− ~[1 2 3 4 5 6]
252+> (gulf 1 6)
253+~[1 2 3 4 5 6]
254+```
190255
191− > `(list @t)`(gulf 99 106)
192− <|c d e f g h i j|>
256+```
257+> `(list @t)`(gulf 99 106)
258+<|c d e f g h i j|>
193259```
194260
195261---
196−### `++homo`
262+
263+## `++homo`
197264
198265Homogenize
199266
@@ -212,7 +279,7 @@ a `list`.
212279#### Source
213280
214281```hoon
215−++ homo :: homogenize
282+++ homo
216283 |* a=(list)
217284 ^+ =< $
218285 |@ ++ $ ?:(*? ~ [i=(snag 0 a) t=$])
@@ -223,23 +290,60 @@ a `list`.
223290#### Examples
224291
225292```
226− > lyst
227− [i=1 t=[i=97 t=[i=2 t=[i=98 t=[i=[~ u=10] t=~]]]]]
293+> lyst
294+[i=1 t=[i=97 t=[i=2 t=[i=98 t=[i=[~ u=10] t=~]]]]]
295+> (homo lyst)
296+~[1 97 2 98 [~ u=10]]
297+```
298+
299+```
300+> =a (limo [1 2 3 ~])
301+> a
302+[i=1 t=[i=2 t=[i=3 t=~]]]
303+> (homo a)
304+~[1 2 3]
305+```
306+
307+---
308+
309+## `++into`
310+
311+Insert item at index
312+
313+Accepts a `list` `a`, an atom `b`, and a noun `c`, producing the list of `a` with the item `c` inserted at index `b`.
228314
229− > (homo lyst)
230− ~[1 97 2 98 [~ u=10]]
315+#### Accepts
316+
317+`a` is a list.
318+
319+`b` is a atom.
320+
321+`c` is a noun.
322+
323+#### Produces
324+
325+the list of `a` with the item `c` inserted at index `b`.
326+
327+#### Source
328+
329+```hoon
330+++ into
331+ ~/ %into
332+ |* [a=(list) b=@ c=*]
333+ ^+ a
334+ (weld (scag b a) [c (slag b a)])
335+```
231336
232− > =a (limo [1 2 3 ~])
233− > a
234− [i=1 t=[i=2 t=[i=3 t=~]]]
337+#### Examples
235338
236− > (homo a)
237− ~[1 2 3]
339+```
340+> (into (limo ~[2 3 4]) 1 11)
341+~[2 11 3 4]
238342```
239343
240344---
241345
242−### `++join`
346+## `++join`
243347
244348Constructs a new `list`, placing `sep` between every element of `lit`.
245349
@@ -256,29 +360,32 @@ a `list`.
256360#### Source
257361
258362```hoon
259− ++ join
260− |* [sep=* lit=(list)]
261− =. sep `_?>(?=(^ lit) i.lit)`sep
262− ?~ lit ~
263− =| out=(list _?>(?=(^ lit) i.lit))
264− |- ^+ out
265− ?~ t.lit
266− (flop [i.lit out])
267− $(out [sep i.lit out], lit t.lit)
363+++ join
364+ |* [sep=* lit=(list)]
365+ =. sep `_?>(?=(^ lit) i.lit)`sep
366+ ?~ lit ~
367+ =| out=(list _?>(?=(^ lit) i.lit))
368+ |- ^+ out
369+ ?~ t.lit
370+ (flop [i.lit out])
371+ $(out [sep i.lit out], lit t.lit)
268372```
269373
270374#### Examples
271375
272376```
273− > (join ' ' "hoon")
274− "h o o n"
377+> (join ' ' "hoon")
378+"h o o n"
379+```
275380
276− > (join 0 `(list @)`~[1 2 3])
277− ~[1 0 2 0 3]
381+```
382+> (join 0 `(list @)`~[1 2 3])
383+~[1 0 2 0 3]
278384```
279385
280386---
281−### `++lent`
387+
388+## `++lent`
282389
283390List length
284391
@@ -295,29 +402,31 @@ an atom.
295402#### Source
296403
297404```hoon
298− ++ lent
299− ~/ %lent
300− |= a=(list)
301− ^- @
302− =+ b=0
303− |-
304− ?~ a b
305− $(a t.a, b +(b))
405+++ lent
406+ ~/ %lent
407+ |= a=(list)
408+ ^- @
409+ =+ b=0
410+ |-
411+ ?~ a b
412+ $(a t.a, b +(b))
306413```
307414
308415#### Examples
309416
310417```
311− > (lent [1 2 3 4 ~]))
312− 4
313−
314− > (lent [1 'a' 2 'b' (some 10) ~])
315− 5
418+> (lent [1 2 3 4 ~]))
419+4
316420```
317421
422+```
423+> (lent [1 'a' 2 'b' (some 10) ~])
424+5
425+```
318426
319427---
320−### `++levy`
428+
429+## `++levy`
321430
322431Logical "and" on list
323432
@@ -336,31 +445,32 @@ A boolean.
336445#### Source
337446
338447```hoon
339− ++ levy
340− ~/ %levy :: all of
341− |* [a=(list) b=$-(* ?)]
342− |- ^- ?
343− ?~ a &
344− ?. (b i.a) |
345− $(a t.a)
448+++ levy
449+ ~/ %levy
450+ |* [a=(list) b=$-(* ?)]
451+ |- ^- ?
452+ ?~ a &
453+ ?. (b i.a) |
454+ $(a t.a)
346455```
347456
348457#### Examples
349458
350459```
351− > =a |=(a=@ (lte a 1))
352− > (levy `(list @)`[0 1 2 1 ~] a)
353− %.n
354−
355− > =a |=(a=@ (lte a 3))
356− > (levy `(list @)`[0 1 2 1 ~] a)
357− %.y
460+> =a |=(a=@ (lte a 1))
461+> (levy `(list @)`[0 1 2 1 ~] a)
462+%.n
358463```
359464
465+```
466+> =a |=(a=@ (lte a 3))
467+> (levy `(list @)`[0 1 2 1 ~] a)
468+%.y
469+```
360470
361471---
362472
363−### `++lien`
473+## `++lien`
364474
365475Logical "or" on list
366476
@@ -376,30 +486,32 @@ every element of `++list` `a`.
376486#### Source
377487
378488```hoon
379− ++ lien
380− ~/ %lien
381− |* [a=(list) b=$-(* ?)]
382− |- ^- ?
383− ?~ a |
384− ?: (b i.a) &
385− $(a t.a)
489+++ lien
490+ ~/ %lien
491+ |* [a=(list) b=$-(* ?)]
492+ |- ^- ?
493+ ?~ a |
494+ ?: (b i.a) &
495+ $(a t.a)
386496```
387497
388498#### Examples
389499
390500```
391− > =a |=(a=@ (gte a 1))
392− > (lien `(list @)`[0 1 2 1 ~] a)
393− %.y
394−
395− > =a |=(a=@ (gte a 3))
396− > (lien `(list @)`[0 1 2 1 ~]) a)
397− %.n
501+> =a |=(a=@ (gte a 1))
502+> (lien `(list @)`[0 1 2 1 ~] a)
503+%.y
398504```
399505
506+```
507+> =a |=(a=@ (gte a 3))
508+> (lien `(list @)`[0 1 2 1 ~]) a)
509+%.n
510+```
400511
401512---
402−### `++limo`
513+
514+## `++limo`
403515
404516List Constructor
405517
@@ -416,7 +528,7 @@ A `++list`.
416528#### Source
417529
418530```hoon
419−++ limo :: listify
531+++ limo
420532 |* a=*
421533 ^+ =< $
422534 |@ ++ $ ?~(a ~ ?:(*? [i=-.a t=$] $(a +.a)))
@@ -427,18 +539,18 @@ A `++list`.
427539#### Examples
428540
429541```
430− > (limo [1 2 3 ~])
431− [i=1 t=[i=2 t=[i=3 t=~]]]
542+> (limo [1 2 3 ~])
543+[i=1 t=[i=2 t=[i=3 t=~]]]
432544```
433545
434−
435546---
436−### `++murn`
547+
548+## `++murn`
437549
438550Maybe transform
439551
440552Passes each member of `list` `a` to gate `b`, which must produce a
441−`unit`. Produces a new list with all the results that do not produce
553+`unit`. Produces a new list with all the results that do not produce
442554`~`.
443555
444556#### Accepts
@@ -454,28 +566,28 @@ A unit.
454566#### Source
455567
456568```hoon
457− ++ murn :: maybe transform
458− ~/ %murn
459− |* [a=(list) b=$-(* (unit))]
460− |-
461− ?~ a ~
462− =+ c=(b i.a)
463− ?~ c
464− $(a t.a)
465− [i=u.c t=$(a t.a)]
569+++ murn
570+ ~/ %murn
571+ |* [a=(list) b=$-(* (unit))]
572+ => .(a (homo a))
573+ |- ^- (list _?>(?=(^ a) (need (b i.a))))
574+ ?~ a ~
575+ =/ c (b i.a)
576+ ?~ c $(a t.a)
577+ [+.c $(a t.a)]
466578```
467579
468580#### Examples
469581
470582```
471− > =a |=(a=@ ?.((gte a 2) ~ (some (add a 10))))
472− > (murn `(list @)`[0 1 2 3 ~] a)
473− [i=12 t=[i=13 t=~]]
583+> =a |=(a=@ ?.((gte a 2) ~ (some (add a 10))))
584+> (murn `(list @)`[0 1 2 3 ~] a)
585+[i=12 t=[i=13 t=~]]
474586```
475587
476−
477588---
478−### `++oust`
589+
590+## `++oust`
479591
480592Remove
481593
@@ -493,25 +605,27 @@ A `++list`.
493605#### Source
494606
495607```hoon
496− ++ oust :: remove
497− ~/ %oust
498− |* [[a=@ b=@] c=(list)]
499− (weld (scag a c) (slag (add a b) c))
608+++ oust
609+ ~/ %oust
610+ |* [[a=@ b=@] c=(list)]
611+ (weld (scag +<-< c) (slag (add +<-< +<->) c))
500612```
501613
502614#### Examples
503615
504616```
505− > (oust [4 5] "good day, urbit!")
506− "good urbit!"
507−
508− > (oust [2 2] `(list @)`[1 2 3 4 ~])
509− ~[1 2]
617+> (oust [4 5] "good day, urbit!")
618+"good urbit!"
510619```
511620
621+```
622+> (oust [2 2] `(list @)`[1 2 3 4 ~])
623+~[1 2]
624+```
512625
513626---
514−### `++reap`
627+
628+## `++reap`
515629
516630Replicate
517631
@@ -530,30 +644,71 @@ A list.
530644#### Source
531645
532646```hoon
533− ++ reap :: replicate
534− ~/ %reap
535− |* [a=@ b=*]
536− |- ^- (list _b)
537− ?~ a ~
538− [b $(a (dec a))]
647+++ reap
648+ ~/ %reap
649+ |* [a=@ b=*]
650+ |- ^- (list _b)
651+ ?~ a ~
652+ [b $(a (dec a))]
539653```
540654
541655#### Examples
542656
543657```
544− > (reap 20 %a)
545− ~[%a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a]
658+> (reap 20 %a)
659+~[%a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a]
660+```
546661
547− > (reap 5 ~s1)
548− ~[~s1 ~s1 ~s1 ~s1 ~s1]
662+```
663+> (reap 5 ~s1)
664+~[~s1 ~s1 ~s1 ~s1 ~s1]
665+> `@dr`(roll (reap 5 ~s1) add)
666+~s5
667+```
668+
669+---
549670
550− > `@dr`(roll (reap 5 ~s1) add)
551− ~s5
671+## `++rear`
672+
673+Last item of list
674+
675+Produces the last item in list `a`, crashing if `a` is null.
676+
677+#### Accepts
678+
679+`a` is a `list`.
680+
681+#### Produces
682+
683+The type of the last element in `a`.
684+
685+#### Source
686+
687+```hoon
688+++ rear
689+ ~/ %rear
690+ |* a=(list)
691+ ^- _?>(?=(^ a) i.a)
692+ ?> ?=(^ a)
693+ ?: =(~ t.a) i.a
694+ $(a t.a)
552695```
553696
697+#### Examples
698+
699+```
700+> (rear ~[1 2 3])
701+3
702+```
703+
704+```
705+> (rear ~)
706+dojo: hoon expression failed
707+```
554708
555709---
556−### `++reel`
710+
711+## `++reel`
557712
558713Right fold
559714
@@ -582,30 +737,31 @@ The accumulator, which is a noun.
582737#### Source
583738
584739```hoon
585− ++ reel
586− ~/ %reel
587− |* [a=(list) b=_|=([* *] +<+)]
588− |- ^+ +<+.b
589− ?~ a
590− +<+.b
591− (b i.a $(a t.a))
740+++ reel
741+ ~/ %reel
742+ |* [a=(list) b=_=>(~ |=([* *] +<+))]
743+ |- ^+ ,.+<+.b
744+ ?~ a
745+ +<+.b
746+ (b i.a $(a t.a))
592747```
593748
594749#### Examples
595750
596751```
597− > (reel `(list @)`[1 2 3 4 5 ~] add)
598− 15
752+> (reel `(list @)`[1 2 3 4 5 ~] add)
753+15
599754
600− > (reel `(list @)`[6 3 1 ~] sub)
601− 4
755+> (reel `(list @)`[6 3 1 ~] sub)
756+4
602757
603− > (reel `(list @)`[3 6 1 ~] sub)
604− ! subtract-underflow
605− ! exit
758+> (reel `(list @)`[3 6 1 ~] sub)
759+! subtract-underflow
760+! exit
606761```
607762
608763`+mul`'s default sample is 1, so calling `+reel` with `+mul` yields the expected behavior:
764+
609765```
610766> *mul
6117671
@@ -613,22 +769,38 @@ The accumulator, which is a noun.
613769> (reel `(list @)`~[1 2 3 4] mul)
61477024
615771```
772+
616773However, if you build a gate that uses `+mul` like so, the sample defaults to 0
617774since that is the bunt of `@`:
775+
618776```
619777> (reel `(list @)`~[1 2 3 4] |=([a=@ b=@] (mul a b)))
6207780
621779```
780+
622781We can fix this with `|:`:
782+
623783```
624784> (reel `(list @)`~[1 2 3 4] |:([a=1 b=1] (mul a b)))
62578524
626786```
627787
788+If you check the definition of `+mul`, you'll see that it also utilizes this
789+pattern.
790+
791+We can check explicitly what sequence of operations `+reel` performs like this:
792+```
793+> =f |: [l='e_l' r='e_r']
794+ ^- @t
795+ :((cury cat 3) '(' l '*' r ')')
796+> (reel "abcde" f)
797+'(a*(b*(c*(d*(e*e_r)))))'
798+```
628799
629800
630801---
631−### `++roll`
802+
803+## `++roll`
632804
633805Left fold
634806
@@ -657,13 +829,13 @@ The accumulator, which is a noun.
657829#### Source
658830
659831```hoon
660− ++ roll :: left fold
661− ~/ %roll
662− |* [a=(list) b=_|=([* *] +<+)]
663− |- ^+ +<+.b
664− ?~ a
665− +<+.b
666− $(a t.a, b b(+<+ (b i.a +<+.b)))
832+++ roll
833+ ~/ %roll
834+ |* [a=(list) b=_=>(~ |=([* *] +<+))]
835+ |- ^+ ,.+<+.b
836+ ?~ a
837+ +<+.b
838+ $(a t.a, b b(+<+ (b i.a +<+.b)))
667839```
668840
669841#### Examples
@@ -681,6 +853,7 @@ q=4
681853```
682854
683855`+mul`'s default sample is 1, so calling `+roll` with `+mul` yields the expected behavior:
856+
684857```
685858> *mul
6868591
@@ -688,21 +861,49 @@ q=4
688861> (roll `(list @)`~[1 2 3 4] mul)
68986224
690863```
864+
691865However, if you build a gate that uses `+mul` like so, the sample defaults to 0
692866since that is the bunt of `@`:
867+
693868```
694869> (roll `(list @)`~[1 2 3 4] |=([a=@ b=@] (mul a b)))
6958700
696871```
872+
697873We can fix this with `|:`:
874+
698875```
699876> (roll `(list @)`~[1 2 3 4] |:([a=1 b=1] (mul a b)))
70087724
701878```
879+If you check the definition of `+mul`, you'll see that it also utilizes this
880+pattern.
702881
882+We can check explicitly what sequence of operations `+roll` performs like this:
883+```
884+> =f |: [l='e_l' r='e_r']
885+ ^- @t
886+ :((cury cat 3) '(' l '*' r ')')
887+> (roll "abcde" f)
888+'(e*(d*(c*(b*(a*e_r)))))
889+```
890+This is in contrast to what one might expect:
891+```
892+> =foldl
893+ |* [l=(list) f=$-([* *] *)]
894+ ^- f
895+ ?~ l +<-.f
896+ %= $
897+ +<-.f (f +<-.f i.l)
898+ l t.l
899+ ==
900+> (foldl "abcde" f)
901+'(((((e_l*a)*b)*c)*d)*e)'
902+```
703903
704904---
705−### `++scag`
905+
906+## `++scag`
706907
707908Prefix
708909
@@ -722,27 +923,29 @@ A list of the same type as `b`.
722923#### Source
723924
724925```hoon
725− ++ scag :: prefix
726− ~/ %scag
727− |* [a=@ b=(list)]
728− |- ^+ b
729− ?: |(?=(~ b) =(0 a)) ~
730− [i.b $(b t.b, a (dec a))]
926+++ scag
927+ ~/ %scag
928+ |* [a=@ b=(list)]
929+ |- ^+ b
930+ ?: |(?=(~ b) =(0 a)) ~
931+ [i.b $(b t.b, a (dec a))]
731932```
732933
733934#### Examples
734935
735936```
736− > (scag 2 `(list @)`[1 2 3 4 ~])
737− [i=1 t=~[2]]
738−
739− > (scag 10 `(list @)`[1 2 3 4 ~])
740− [i=1 t=~[2 3 4]]
937+> (scag 2 `(list @)`[1 2 3 4 ~])
938+[i=1 t=~[2]]
741939```
742940
941+```
942+> (scag 10 `(list @)`[1 2 3 4 ~])
943+[i=1 t=~[2 3 4]]
944+```
743945
744946---
745−### `++skid`
947+
948+## `++skid`
746949
747950Separate
748951
@@ -765,27 +968,26 @@ A cell of two lists.
765968#### Source
766969
767970```hoon
768− ++ skid :: separate
769− ~/ %skid
770− |* [a=(list) b=$-(* ?)]
771− |- ^+ [p=a q=a]
772− ?~ a [~ ~]
773− =+ c=$(a t.a)
774− ?:((b i.a) [[i.a p.c] q.c] [p.c [i.a q.c]])
971+++ skid
972+ ~/ %skid
973+ |* [a=(list) b=$-(* ?)]
974+ |- ^+ [p=a q=a]
975+ ?~ a [~ ~]
976+ =+ c=$(a t.a)
977+ ?:((b i.a) [[i.a p.c] q.c] [p.c [i.a q.c]])
775978```
776979
777−
778980#### Examples
779981
780982```
781− > =a |=(a=@ (gth a 1))
782− > (skid `(list @)`[0 1 2 3 ~] a)
783− [p=[i=2 t=~[3]] q=[i=0 t=~[1]]]
983+> =a |=(a=@ (gth a 1))
984+> (skid `(list @)`[0 1 2 3 ~] a)
985+[p=[i=2 t=~[3]] q=[i=0 t=~[1]]]
784986```
785987
786−
787988---
788−### `++skim`
989+
990+## `++skim`
789991
790992Suffix
791993
@@ -806,25 +1008,26 @@ A list.
8061008#### Source
8071009
8081010```hoon
809− ++ skim :: only
810− ~/ %skim
811− |* [a=(list) b=$-(* ?)]
812− |-
813− ^+ a
814− ?~ a ~
815− ?:((b i.a) [i.a $(a t.a)] $(a t.a))
1011+++ skim
1012+ ~/ %skim
1013+ |* [a=(list) b=$-(* ?)]
1014+ |-
1015+ ^+ a
1016+ ?~ a ~
1017+ ?:((b i.a) [i.a $(a t.a)] $(a t.a))
8161018```
8171019
8181020#### Examples
8191021
8201022```
821− > =a |=(a=@ (gth a 1))
822− > (skim `(list @)`[0 1 2 3 ~] a)
823− [i=2 t=~[3]]
1023+> =a |=(a=@ (gth a 1))
1024+> (skim `(list @)`[0 1 2 3 ~] a)
1025+[i=2 t=~[3]]
8241026```
8251027
8261028---
827−### `++skip`
1029+
1030+## `++skip`
8281031
8291032Except
8301033
@@ -845,26 +1048,26 @@ A list of the same type as `a`.
8451048#### Source
8461049
8471050```hoon
848− ++ skip :: except
849− ~/ %skip
850− |* [a=(list) b=$-(* ?)]
851− |-
852− ^+ a
853− ?~ a ~
854− ?:((b i.a) $(a t.a) [i.a $(a t.a)])
1051+++ skip
1052+ ~/ %skip
1053+ |* [a=(list) b=$-(* ?)]
1054+ |-
1055+ ^+ a
1056+ ?~ a ~
1057+ ?:((b i.a) $(a t.a) [i.a $(a t.a)])
8551058```
8561059
8571060#### Examples
8581061
8591062```
860− > =a |=(a=@ (gth a 1))
861− > (skip `(l)`[0 1 2 3 ~]) a)
862− [i=0 t=[i=1 t=~]]
1063+> =a |=(a=@ (gth a 1))
1064+> (skip `(l)`[0 1 2 3 ~]) a)
1065+[i=0 t=[i=1 t=~]]
8631066```
8641067
865−
8661068---
867−### `++slag`
1069+
1070+## `++slag`
8681071
8691072Suffix
8701073
@@ -884,27 +1087,27 @@ A list of the same type as `b`.
8841087#### Source
8851088
8861089```hoon
887− ++ slag :: suffix
888− ~/ %slag
889− |* [a=@ b=(list)]
890− |- ^+ b
891− ?: =(0 a) b
892− ?~ b ~
893− $(b t.b, a (dec a))
1090+++ slag
1091+ ~/ %slag
1092+ |* [a=@ b=(list)]
1093+ |- ^+ b
1094+ ?: =(0 a) b
1095+ ?~ b ~
1096+ $(b t.b, a (dec a))
8941097```
8951098
8961099#### Examples
8971100
8981101```
899− > (slag 2 (limo [1 2 3 4 ~]))
900− [i=3 t=[i=4 t=~]]
901− > (slag 1 (limo [1 2 3 4 ~]))
902− [i=2 t=[i=3 t=[i=4 t=~]]]
1102+> (slag 2 (limo [1 2 3 4 ~]))
1103+[i=3 t=[i=4 t=~]]
1104+> (slag 1 (limo [1 2 3 4 ~]))
1105+[i=2 t=[i=3 t=[i=4 t=~]]]
9031106```
9041107
905−
9061108---
907−### `++snag`
1109+
1110+## `++snag`
9081111
9091112Index
9101113
@@ -924,134 +1127,144 @@ Produces an element of `b`, or crashes if no element exists at that index.
9241127#### Source
9251128
9261129```hoon
927− ++ snag :: index
928− ~/ %snag
929− |* [a=@ b=(list)]
930− |-
931− ?~ b
932− ~|('snag-fail' !!)
933− ?: =(0 a) i.b
934− $(b t.b, a (dec a))
1130+++ snag
1131+ ~/ %snag
1132+ |* [a=@ b=(list)]
1133+ |- ^+ ?>(?=(^ b) i.b)
1134+ ?~ b
1135+ ~_ leaf+"snag-fail"
1136+ !!
1137+ ?: =(0 a) i.b
1138+ $(b t.b, a (dec a))
9351139```
9361140
9371141#### Examples
9381142
9391143```
940− > (snag 2 "asdf")
941− ~~d
942− > (snag 0 `(list @ud)`~[1 2 3 4])
943− 1
1144+> (snag 2 "asdf")
1145+'d'
9441146```
9451147
1148+```
1149+> (snag 0 `(list @ud)`~[1 2 3 4])
1150+1
1151+```
9461152
9471153---
948−### `++snoc`
9491154
950−Append
1155+## `++snap`
9511156
952−Accepts a `++list` `a` and a noun `b`, producing the list of `b` appended to `a`.
1157+Replace item at index
1158+
1159+Accepts a `list` `a`, an atom `b`, and a noun `c`, producing the list of `a` with the item at index `b` replaced with `c`.
9531160
9541161#### Accepts
9551162
9561163`a` is a list.
9571164
958−`b` is a noun.
1165+`b` is a atom.
1166+
1167+`c` is a noun.
9591168
9601169#### Produces
9611170
962−Produces a list of `b` appended to `a`.
1171+the list of `a` with the item at index `b` replaced with `c`.
9631172
9641173#### Source
9651174
9661175```hoon
967− ++ snoc
968− |* [a/(list) b/*]
969− (weld a ^+(a [b]~))
1176+++ snap
1177+ ~/ %snap
1178+ |* [a=(list) b=@ c=*]
1179+ ^+ a
1180+ (weld (scag b a) [c (slag +(b) a)])
9701181```
9711182
9721183#### Examples
9731184
9741185```
975− > `tape`(zing (snoc `(list tape)`~["a" "bc" "def"] "g"))
976− "abcdefg"
977− > (snoc `(list @ud)`~[1 2 3] 4)
978− ~[1 2 3 4]
1186+> (snap (limo ~[2 3 4]) 1 11)
1187+~[2 11 4]
9791188```
9801189
9811190---
982−### `++snap`
9831191
984−Replace item at index
1192+## `++snip`
9851193
986−Accepts a `list` `a`, an atom `b`, and a noun `c`, producing the list of `a` with the item at index `b` replaced with `c`.
1194+Drop tail off list
9871195
988−#### Accepts
1196+Removes the last element from list `a`.
9891197
990−`a` is a list.
991−
992−`b` is a atom.
993−
994−`c` is a noun.
1198+#### Accepts
9951199
1200+`a` is a `list`.
9961201
9971202#### Produces
9981203
999−the list of `a` with the item at index `b` replaced with `c`.
1204+A `list`.
10001205
10011206#### Source
10021207
10031208```hoon
1004− ++ snap
1005− |* [a/(list) b/@ c/*]
1006− ^+ a
1007− (weld (scag b a) [c (slag +(b) a)])
1209+++ snip
1210+ ~/ %snip
1211+ |* a=(list)
1212+ ^+ a
1213+ ?~ a ~
1214+ ?: =(~ t.a) ~
1215+ [i.a $(a t.a)]
10081216```
10091217
10101218#### Examples
10111219
10121220```
1013− > (snap (limo ~[2 3 4]) 1 11)
1014− ~[2 11 4]
1221+> `tape`(snip "foobar")
1222+"fooba"
1223+```
1224+
1225+```
1226+> (snip ~)
1227+~
10151228```
10161229
10171230---
1018−### `++into`
10191231
1020−Insert item at index
1232+## `++snoc`
10211233
1022−Accepts a `list` `a`, an atom `b`, and a noun `c`, producing the list of `a` with the item `c` inserted at index `b`.
1234+Append
1235+
1236+Accepts a `++list` `a` and a noun `b`, producing the list of `b` appended to `a`.
10231237
10241238#### Accepts
10251239
10261240`a` is a list.
10271241
1028−`b` is a atom.
1029−
1030−`c` is a noun.
1031−
1242+`b` is a noun.
10321243
10331244#### Produces
10341245
1035−the list of `a` with the item `c` inserted at index `b`.
1246+Produces a list of `b` appended to `a`.
10361247
10371248#### Source
10381249
10391250```hoon
1040− ++ into
1041− |* [a/(list) b/@ c/*]
1042− ^+ a
1043− (weld (scag b a) [c (slag b a)])
1251+++ snoc
1252+ |* [a=(list) b=*]
1253+ (weld a ^+(a [b]~))
10441254```
10451255
10461256#### Examples
10471257
10481258```
1049− > (into (limo ~[2 3 4]) 1 11)
1050− ~[2 11 3 4]
1259+> `tape`(zing (snoc `(list tape)`~["a" "bc" "def"] "g"))
1260+"abcdefg"
1261+> (snoc `(list @ud)`~[1 2 3] 4)
1262+~[1 2 3 4]
10511263```
10521264
10531265---
1054−### `++sort`
1266+
1267+## `++sort`
10551268
10561269Quicksort
10571270
@@ -1072,28 +1285,29 @@ A list
10721285#### Source
10731286
10741287```hoon
1075− ++ sort !. :: quicksort
1076− ~/ %sort
1077− |* [a=(list) b=$-([* *] ?)]
1078− => .(a ^.(homo a))
1079− |- ^+ a
1080− ?~ a ~
1081− %+ weld
1082− $(a (skim t.a |=(c/_i.a (b c i.a))))
1083− ^+ t.a
1084− [i.a $(a (skim t.a |=(c/_i.a !(b c i.a))))]
1288+++ sort !.
1289+ ~/ %sort
1290+ |* [a=(list) b=$-([* *] ?)]
1291+ => .(a ^.(homo a))
1292+ |- ^+ a
1293+ ?~ a ~
1294+ =+ s=(skid t.a |:(c=i.a (b c i.a)))
1295+ %+ weld
1296+ $(a p.s)
1297+ ^+ t.a
1298+ [i.a $(a q.s)]
10851299```
10861300
10871301#### Examples
10881302
10891303```
1090− > (sort `(list @)`[0 1 2 3 ~] gth)
1091− ~[3 2 1 0]
1304+> (sort `(list @)`[0 1 2 3 ~] gth)
1305+~[3 2 1 0]
10921306```
10931307
1094−
10951308---
1096−### `++spin` {#spin}
1309+
1310+## `++spin` {#spin}
10971311
10981312Gate to list, with state
10991313
@@ -1118,35 +1332,39 @@ A pair of a list and a noun.
11181332#### Source
11191333
11201334```hoon
1121− ++ spin
1122− ~/ %spin
1123− |* [a=(list) b=* c=_|=(^ [** +<+])]
1124− => .(c `$-([_?>(?=(^ a) i.a) _b] [_-:(c) _b])`c)
1125− =/ acc=(list _-:(c)) ~
1126− |- ^- (pair _acc _b)
1127− ?~ a
1128− [(flop acc) b]
1129− =^ res b (c i.a b)
1130− $(acc [res acc], a t.a)
1335+++ spin
1336+ ~/ %spin
1337+ |* [a=(list) b=* c=_|=(^ [** +<+])]
1338+ => .(c `$-([_?>(?=(^ a) i.a) _b] [_-:(c) _b])`c)
1339+ =/ acc=(list _-:(c)) ~
1340+ |- ^- (pair _acc _b)
1341+ ?~ a
1342+ [(flop acc) b]
1343+ =^ res b (c i.a b)
1344+ $(acc [res acc], a t.a)
11311345```
11321346
11331347#### Examples
11341348
11351349```
1136− > %^ spin (limo ~[4 5 6]) :: Trivial example -- does nothing with the state
1137− 0
1138− |=([n=@ a=@] [n a])
1139− [p=~[4 5 6] q=0]
1350+> %^ spin (limo ~[4 5 6]) :: Trivial example -- does nothing with the state
1351+ 0
1352+ |=([n=@ a=@] [n a])
1353+[p=~[4 5 6] q=0]
1354+```
11401355
1141− > %^ spin (limo ~[4 5 6]) :: Form a pair with `p` as the index and `q` as the list element
1142− 0
1143− |=([n=@ a=@] [`(pair)`[a n] +(a)])
1144− [p=~[[p=0 q=4] [p=1 q=5] [p=2 q=6]] q=3]
1356+```
1357+> %^ spin (limo ~[4 5 6]) :: Form a pair with `p` as the index and `q` as the list element
1358+ 0
1359+ |=([n=@ a=@] [`(pair)`[a n] +(a)])
1360+[p=~[[p=0 q=4] [p=1 q=5] [p=2 q=6]] q=3]
1361+```
11451362
1146− > %^ spin (reap 10 0) :: Create 10 random numbers less than `10`
1147− ~(. og eny)
1148− |=([n=@ rng=_og] (rads:rng 10))
1149− [p=~[7 8 6 0 1 5 4 7 9 3] q=<4.rvi {a/@uvJ <51.qyl 129.pdd 41.mac 1.ane $141>}>]
1363+```
1364+> %^ spin (reap 10 0) :: Create 10 random numbers less than `10`
1365+ ~(. og eny)
1366+ |=([n=@ rng=_og] (rads:rng 10))
1367+[p=~[7 8 6 0 1 5 4 7 9 3] q=<4.rvi {a/@uvJ <51.qyl 129.pdd 41.mac 1.ane $141>}>]
11501368```
11511369
11521370#### Discussion
@@ -1155,10 +1373,9 @@ A pair of a list and a noun.
11551373with entropy (`eny`). The head of the product is the random number, the tail
11561374is the continuation of the RNG.
11571375
1158−
1159−
11601376---
1161−### `++spun` {#spun}
1377+
1378+## `++spun` {#spun}
11621379
11631380Gate to list, with state
11641381
@@ -1183,28 +1400,30 @@ A list.
11831400#### Source
11841401
11851402```hoon
1186− ++ spun
1187− ~/ %spun
1188− |* [a=(list) b=_|=(^ [** +<+])]
1189− p:(spin a +<+.b b)
1403+++ spun
1404+ ~/ %spun
1405+ |* [a=(list) b=_|=(^ [** +<+])]
1406+ p:(spin a +<+.b b)
11901407```
11911408
11921409#### Examples
11931410
11941411```
1195− > %+ spun (limo ~[4 5 6]) :: `p` as the index and `q` as the list element
1196− |=([n=@ a=@] [`(pair)`[a n] +(a)])
1197− ~[[p=0 q=4] [p=1 q=5] [p=2 q=6]]
1198−
1199− > =l (limo ~[7 8 9])
1200− > %+ spun (limo ~[4 5 6]) :: joins two lists into a list of pairs
1201− |=([n=@ a=@] [`(pair)`[(snag a l) n] +(a)])
1202− ~[[p=7 q=4] [p=8 q=5] [p=9 q=6]]
1412+> %+ spun (limo ~[4 5 6]) :: `p` as the index and `q` as the list element
1413+ |=([n=@ a=@] [`(pair)`[a n] +(a)])
1414+~[[p=0 q=4] [p=1 q=5] [p=2 q=6]]
12031415```
12041416
1417+```
1418+> =l (limo ~[7 8 9])
1419+> %+ spun (limo ~[4 5 6]) :: joins two lists into a list of pairs
1420+ |=([n=@ a=@] [`(pair)`[(snag a l) n] +(a)])
1421+~[[p=7 q=4] [p=8 q=5] [p=9 q=6]]
1422+```
12051423
12061424---
1207−### `++swag`
1425+
1426+## `++swag`
12081427
12091428Infix
12101429
@@ -1226,24 +1445,26 @@ A list of the same type as `c`.
12261445#### Source
12271446
12281447```hoon
1229− ++ swag
1230− |* [[a=@ b=@] c=(list)]
1231− (scag +<-> (slag +<-< c))
1448+++ swag
1449+ |* [[a=@ b=@] c=(list)]
1450+ (scag +<-> (slag +<-< c))
12321451```
12331452
12341453#### Examples
12351454
12361455```
1237− > (swag [2 5] "roly poly")
1238− "ly po"
1239−
1240− > (swag [2 2] (limo [1 2 3 4 ~]))
1241− [i=3 t=[i=4 t=~]]
1456+> (swag [2 5] "roly poly")
1457+"ly po"
12421458```
12431459
1460+```
1461+> (swag [2 2] (limo [1 2 3 4 ~]))
1462+[i=3 t=[i=4 t=~]]
1463+```
12441464
12451465---
1246−### `++turn`
1466+
1467+## `++turn`
12471468
12481469Gate to list
12491470
@@ -1263,23 +1484,27 @@ A list.
12631484#### Source
12641485
12651486```hoon
1266− ++ turn
1267− ~/ %turn
1268− |* [a=(list) b=gate]
1269− |-
1270− ?~ a ~
1271− [i=(b i.a) t=$(a t.a)]
1487+++ turn
1488+ ~/ %turn
1489+ |* [a=(list) b=gate]
1490+ => .(a (homo a))
1491+ ^- (list _?>(?=(^ a) (b i.a)))
1492+ |-
1493+ ?~ a ~
1494+ [i=(b i.a) t=$(a t.a)]
12721495```
12731496
12741497#### Examples
12751498
12761499```
1277− > (turn (limo [104 111 111 110 ~]) @t)
1278− <|h o o n|>
1500+> (turn (limo [104 111 111 110 ~]) @t)
1501+<|h o o n|>
1502+```
12791503
1280− > =a |=(a=@ (add a 4))
1281− > (turn (limo [1 2 3 4 ~]) a)
1282− ~[5 6 7 8]
1504+```
1505+> =a |=(a=@ (add a 4))
1506+> (turn (limo [1 2 3 4 ~]) a)
1507+~[5 6 7 8]
12831508```
12841509
12851510#### Discussion
@@ -1287,7 +1512,8 @@ A list.
12871512`turn` is Hoon's version of 'map' in Haskell.
12881513
12891514---
1290−### `++weld`
1515+
1516+## `++weld`
12911517
12921518Concatenate
12931519
@@ -1300,28 +1526,30 @@ Concatenate two `++list`s `a` and `b`.
13001526#### Source
13011527
13021528```hoon
1303− ++ weld
1304− ~/ %weld
1305− |* [a=(list) b=(list)]
1306− => .(a ^.(homo a), b ^.(homo b))
1307− |- ^+ b
1308− ?~ a b
1309− [i.a $(a t.a)]
1529+++ weld
1530+ ~/ %weld
1531+ |* [a=(list) b=(list)]
1532+ => .(a ^.(homo a), b ^.(homo b))
1533+ |- ^+ b
1534+ ?~ a b
1535+ [i.a $(a t.a)]
13101536```
13111537
13121538#### Examples
13131539
13141540```
1315− > (weld "urb" "it")
1316− "urbit"
1317−
1318− > (weld (limo [1 2 ~]) (limo [3 4 ~]))
1319− ~[1 2 3 4]
1541+> (weld "urb" "it")
1542+"urbit"
13201543```
13211544
1545+```
1546+> (weld (limo [1 2 ~]) (limo [3 4 ~]))
1547+~[1 2 3 4]
1548+```
13221549
13231550---
1324−### `++welp`
1551+
1552+## `++welp`
13251553
13261554Perfect weld
13271555
@@ -1341,7 +1569,7 @@ A list.
13411569#### Source
13421570
13431571```hoon
1344−++ welp :: faceless weld
1572+++ welp
13451573 ~/ %welp
13461574 =| [* *]
13471575 |@
@@ -1355,23 +1583,27 @@ A list.
13551583#### Examples
13561584
13571585```
1358− > (welp "foo" "bar")
1359− "foobar"
1360−
1361− > (welp ~[60 61 62] ~[%a %b %c])
1362− [60 61 62 %a %b %c ~]
1586+> (welp "foo" "bar")
1587+"foobar"
1588+```
13631589
1364− > ? (welp ~[60 61 62] ~[%a %b %c])
1365− {@ud @ud @ud $a $b $c $~}
1366− [60 61 62 %a %b %c ~]
1590+```
1591+> (welp ~[60 61 62] ~[%a %b %c])
1592+[60 61 62 %a %b %c ~]
13671593
1368− > (welp [sa+1 so+2 ~] si=3)
1369− [[%sa 1] [%so 2] si=3]
1594+> ? (welp ~[60 61 62] ~[%a %b %c])
1595+ {@ud @ud @ud $a $b $c $~}
1596+[60 61 62 %a %b %c ~]
13701597```
13711598
1599+```
1600+> (welp [sa+1 so+2 ~] si=3)
1601+[[%sa 1] [%so 2] si=3]
1602+```
13721603
13731604---
1374−### `++zing`
1605+
1606+## `++zing`
13751607
13761608Turns a `++list` of lists into a single list by promoting the elements of
13771609each sublist into the higher.
@@ -1387,7 +1619,7 @@ A list.
13871619#### Source
13881620
13891621```hoon
1390−++ zing :: promote
1622+++ zing
13911623 ~/ %zing
13921624 =| *
13931625 |@
@@ -1398,15 +1630,16 @@ A list.
13981630 --
13991631```
14001632
1401−
14021633#### Examples
14031634
14041635```
1405− > (zing (limo [(limo ['a' 'b' 'c' ~]) (limo ['e' 'f' 'g' ~]) (limo ['h' 'i' 'j' ~]) ~]))
1406− ~['a' 'b' 'c' 'e' 'f' 'g' 'h' 'i' 'j']
1636+> (zing (limo [(limo ['a' 'b' 'c' ~]) (limo ['e' 'f' 'g' ~]) (limo ['h' 'i' 'j' ~]) ~]))
1637+~['a' 'b' 'c' 'e' 'f' 'g' 'h' 'i' 'j']
1638+```
14071639
1408− > (zing (limo [(limo [1 'a' 2 'b' ~]) (limo [3 'c' 4 'd' ~]) ~]))
1409− ~[1 97 2 98 3 99 4 100]
1640+```
1641+> (zing (limo [(limo [1 'a' 2 'b' ~]) (limo [3 'c' 4 'd' ~]) ~]))
1642+~[1 97 2 98 3 99 4 100]
14101643```
14111644
14121645---
content/docs/hoon/reference/stdlib/2c.md+713−637
@@ -4,15 +4,15 @@ weight = 6
44template = "doc.html"
55+++
66
7−### `++bex`
7+## `++bex`
88
99Binary exponent
1010
11−Computes the result of `2^a`, producing an atom.
11+Computes the result of `2^a`, where `a` is a block size (see [$bloq](/docs/hoon/reference/stdlib/1c#bloq)), producing an atom.
1212
1313#### Accepts
1414
15−`a` is an atom.
15+`a` is an `bloq`.
1616
1717#### Produces
1818
@@ -21,30 +21,34 @@ An atom.
2121#### Source
2222
2323```hoon
24− ++ bex
25− ~/ %bex
26− |= a=@
27− ^- @
28− ?: =(0 a) 1
29− (mul 2 $(a (dec a)))
24+++ bex
25+ ~/ %bex
26+ |= a=bloq
27+ ^- @
28+ ?: =(0 a) 1
29+ (mul 2 $(a (dec a)))
3030```
3131
3232#### Examples
3333
3434```
35− > (bex 4)
36− 16
35+> (bex 4)
36+16
37+```
3738
38− > (bex (add 19 1))
39− 1.048.576
39+```
40+> (bex (add 19 1))
41+1.048.576
42+```
4043
41− > (bex 0)
42− 1
44+```
45+> (bex 0)
46+1
4347```
4448
4549---
4650
47−### `++can`
51+## `++can`
4852
4953Assemble
5054
@@ -54,9 +58,12 @@ value.
5458
5559#### Accepts
5660
57−`a` is a block size (see [`++bloq`](/docs/hoon/reference/stdlib/1c)).
61+`a` is a block size (see [`$bloq`](/docs/hoon/reference/stdlib/1c#bloq)).
5862
59−`b` is a `list` of length-value pairs, `p` and `q`.
63+`b` is a `list` of length-value pairs, `p` and `q`:
64+
65+- `p` is a [step](/docs/hoon/reference/stdlib/1c/#step).
66+- `q` is a `@`.
6067
6168#### Produces
6269
@@ -65,45 +72,59 @@ An atom.
6572#### Source
6673
6774```hoon
68− ++ can
69− ~/ %can
70− |= [a=bloq b=(list [p=@ q=@])]
71− ^- @
72− ?~ b 0
73− (add (end a p.i.b q.i.b) (lsh a p.i.b $(b t.b)))
75+++ can
76+ ~/ %can
77+ |= [a=bloq b=(list [p=step q=@])]
78+ ^- @
79+ ?~ b 0
80+ (add (end [a p.i.b] q.i.b) (lsh [a p.i.b] $(b t.b)))
7481```
7582
7683#### Examples
7784
7885```
79− > `@ub`21 :: @ub is the binary aura
80− 0b1.0101
86+> `@ub`21 :: @ub is the binary aura
87+0b1.0101
88+```
8189
82− > `@ub`(can 3 ~[[1 21]])
83− 0b1.0101
90+```
91+> `@ub`(can 3 ~[[1 21]])
92+0b1.0101
93+```
8494
85− > `@ub`(can 3 ~[[1 1]])
86− 0b1
95+```
96+> `@ub`(can 3 ~[[1 1]])
97+0b1
98+```
8799
88− > `@ub`(can 0 ~[[1 255]])
89− 0b1
100+```
101+> `@ub`(can 0 ~[[1 255]])
102+0b1
103+```
90104
91− > `@ux`(can 3 [3 0xc1] [1 0xa] ~) :: @ux is the hexadecimal aura
92− 0xa00.00c1
105+```
106+> `@ux`(can 3 [3 0xc1] [1 0xa] ~) :: @ux is the hexadecimal aura
107+0xa00.00c1
108+```
93109
94− > `@ux`(can 3 [3 0xc1] [1 0xa] [1 0x23] ~)
95− 0x23.0a00.00c1
110+```
111+> `@ux`(can 3 [3 0xc1] [1 0xa] [1 0x23] ~)
112+0x23.0a00.00c1
113+```
96114
97− > `@ux`(can 4 [3 0xc1] [1 0xa] [1 0x23] ~)
98− 0x23.000a.0000.0000.00c1
115+```
116+> `@ux`(can 4 [3 0xc1] [1 0xa] [1 0x23] ~)
117+0x23.000a.0000.0000.00c1
118+```
99119
100− > `@ux`(can 3 ~[[1 'a'] [2 'bc']])
101− 0x63.6261
120+```
121+> `@ux`(can 3 ~[[1 'a'] [2 'bc']])
122+0x63.6261
102123```
103124
104125---
105126
106−### `++cat`
127+## `++cat`
107128
108129Concatenate
109130
@@ -112,7 +133,7 @@ atom.
112133
113134#### Accepts
114135
115−`a` is a block size (see [`++bloq`](/docs/hoon/reference/stdlib/1c)).
136+`a` is a block size (see [`$bloq`](/docs/hoon/reference/stdlib/1c#bloq)).
116137
117138`b` is an atom.
118139
@@ -125,49 +146,43 @@ An atom.
125146#### Source
126147
127148```hoon
128− ++ cat
129− ~/ %cat
130− |= [a=bloq b=@ c=@]
131− (add (lsh a (met a b) c) b)
149+++ cat
150+ ~/ %cat
151+ |= [a=bloq b=@ c=@]
152+ (add (lsh [a (met a b)] c) b)
132153```
133154
134155#### Examples
135156
136157```
137− > `@ub`(cat 3 1 0) :: @ub is the binary aura
138− 0b1
139−
140− > `@ub`(cat 0 1 1)
141− 0b11
142−
143− > `@ub`(cat 0 2 1)
144− 0b110
145−
146− > `@ub`(cat 2 1 1)
147− 0b1.0001
148−
149− > `@ub`256
150− 0b1.0000.0000
151−
152− > `@ub`255
153− 0b1111.1111
154−
155− > `@ub`(cat 3 256 255)
156− 0b1111.1111.0000.0001.0000.0000
157−
158− > `@ub`(cat 2 256 255)
159− 0b1111.1111.0001.0000.0000
160−
161− > (cat 3 256 255)
162− 16.711.936
158+> `@ub`(cat 3 1 0) :: @ub is the binary aura
159+0b1
160+> `@ub`(cat 0 1 1)
161+0b11
162+> `@ub`(cat 0 2 1)
163+0b110
164+> `@ub`(cat 2 1 1)
165+0b1.0001
166+```
163167
164− > (cat 2 256 255)
165− 1.044.736
168+```
169+> `@ub`256
170+0b1.0000.0000
171+> `@ub`255
172+0b1111.1111
173+> `@ub`(cat 3 256 255)
174+0b1111.1111.0000.0001.0000.0000
175+> `@ub`(cat 2 256 255)
176+0b1111.1111.0001.0000.0000
177+> (cat 3 256 255)
178+16.711.936
179+> (cat 2 256 255)
180+1.044.736
166181```
167182
168183---
169184
170−### `++cut`
185+## `++cut`
171186
172187Slice
173188
@@ -176,11 +191,12 @@ Slices `c` blocks of size `a` that are positioned `b` blocks from the end of
176191
177192#### Accepts
178193
179−`a` is a block size (see [`++bloq`](/docs/hoon/reference/stdlib/1c)).
194+`a` is a block size (see [`$bloq`](/docs/hoon/reference/stdlib/1c)).
180195
181−`b` is an atom.
196+`[b c]` where:
182197
183−`c` is an atom.
198+- `b` is a [step](/docs/hoon/reference/stdlib/1c#step).
199+- `c` is a [step](/docs/hoon/reference/stdlib/1c#step).
184200
185201`d` is an atom.
186202
@@ -191,43 +207,42 @@ An atom.
191207#### Source
192208
193209```hoon
194− ++ cut
195− ~/ %cut
196− |= [a=bloq [b=@u c=@u] d=@]
197− (end a c (rsh a b d))
210+++ cut
211+ ~/ %cut
212+ |= [a=bloq [b=step c=step] d=@]
213+ (end [a c] (rsh [a b] d))
198214```
199215
200216#### Examples
201217
202218```
203− > (cut 0 [1 1] 2)
204− 1
205−
206− > (cut 0 [2 1] 4)
207− 1
208−
209− > `@t`(cut 3 [0 3] 'abcdefgh')
210− 'abc'
211−
212− > `@t`(cut 3 [1 3] 'abcdefgh') :: @t is the cord aura
213− 'bcd'
214−
215− > `@ub`(cut 0 [0 3] 0b1111.0000.1101) :: @ub is the binary aura
216− 0b101
217−
218− > `@ub`(cut 0 [0 6] 0b1111.0000.1101)
219− 0b1101
219+> (cut 0 [1 1] 2)
220+1
221+> (cut 0 [2 1] 4)
222+1
223+```
220224
221− > `@ub`(cut 0 [4 6] 0b1111.0000.1101)
222− 0b11.0000
225+```
226+> `@t`(cut 3 [0 3] 'abcdefgh') :: @t is the cord aura
227+'abc'
228+> `@t`(cut 3 [1 3] 'abcdefgh')
229+'bcd'
230+```
223231
224− > `@ub`(cut 0 [3 6] 0b1111.0000.1101)
225− 0b10.0001
232+```
233+> `@ub`(cut 0 [0 3] 0b1111.0000.1101) :: @ub is the binary aura
234+0b101
235+> `@ub`(cut 0 [0 6] 0b1111.0000.1101)
236+0b1101
237+> `@ub`(cut 0 [4 6] 0b1111.0000.1101)
238+0b11.0000
239+> `@ub`(cut 0 [3 6] 0b1111.0000.1101)
240+0b10.0001
226241```
227242
228243---
229244
230−### `++end`
245+## `++end`
231246
232247Tail
233248
@@ -235,8 +250,8 @@ Produces an atom by taking the last `step` blocks of size `bloq` from `b`.
235250
236251#### Accepts
237252
238−`a` is an atom slice specifier (see [`++bite`](/docs/hoon/reference/stdlib/1c#bite)),
239−which is a block size (see [`++bloq`](/docs/hoon/reference/stdlib/1c#bloq))
253+`a` is an atom slice specifier (see [`$bite`](/docs/hoon/reference/stdlib/1c#bite)),
254+which is a block size (see [`$bloq`](/docs/hoon/reference/stdlib/1c#bloq))
240255with optional block count.
241256
242257`b` is an atom.
@@ -248,56 +263,51 @@ An atom.
248263#### Source
249264
250265```hoon
251− ++ end
252− ~/ %end
253− |= [a=bite b=@]
254− =/ [=bloq =step] ?^(a a [a *step])
255− (mod b (bex (mul (bex bloq) step)))
266+++ end
267+ ~/ %end
268+ |= [a=bite b=@]
269+ =/ [=bloq =step] ?^(a a [a *step])
270+ (mod b (bex (mul (bex bloq) step)))
256271```
257272
258273#### Examples
259274
260275```
261− > (end [2 2] 255)
262− 255
263−
264− > (end [3 1] 255)
265− 255
266−
267− > (end 3 255)
268− 255
269−
270− > (end 3 256)
271− 0
272−
273− > `@ub`12 :: @ub is the binary aura
274− 0b1100
275−
276− > `@ub`(end [0 3] 12)
277− 0b100
278−
279− > (end [0 3] 12)
280− 4
281−
282− > `@ub`(end [1 3] 12)
283− 0b1100
284−
285− > (end [1 3] 12)
286− 12
287−
288− > `@ux`'abc' :: @ux is the hexademical aura
289− 0x63.6261
276+> (end [2 2] 255)
277+255
278+> (end [3 1] 255)
279+255
280+> (end 3 255)
281+255
282+> (end 3 256)
283+0
284+```
290285
291− > `@ux`(end [3 2] 'abc')
292− 0x6261
286+```
287+> `@ub`12 :: @ub is the binary aura
288+0b1100
289+> `@ub`(end [0 3] 12)
290+0b100
291+> (end [0 3] 12)
292+4
293+> `@ub`(end [1 3] 12)
294+0b1100
295+> (end [1 3] 12)
296+12
297+```
293298
294− > `@t`(end [3 2] 'abc') :: @t is the cord aura
295− 'ab'
299+```
300+> `@ux`'abc' :: @ux is the hexademical aura
301+0x63.6261
302+> `@ux`(end [3 2] 'abc')
303+0x6261
304+> `@t`(end [3 2] 'abc') :: @t is the cord aura
305+'ab'
296306```
297307
298308---
299309
300−### `++fil`
310+## `++fil`
301311
302312Fill bloqstream
303313
@@ -305,9 +315,9 @@ Produces an atom by repeating `c` for `b` blocks of size `a`.
305315
306316#### Accepts
307317
308−`a` is a block size (see [`++bloq`](/docs/hoon/reference/stdlib/1c)).
318+`a` is a block size (see [`$bloq`](/docs/hoon/reference/stdlib/1c#bloq)).
309319
310−`b` is an atom.
320+`b` is a [step](/docs/hoon/reference/stdlib/1c#step).
311321
312322`c` is an atom.
313323
@@ -318,38 +328,48 @@ An atom.
318328#### Source
319329
320330```hoon
321− ++ fil
322− |= [a=bloq b=@u c=@]
323− =+ n=0
324− =+ d=c
325− |- ^- @
326− ?: =(n b)
327− (rsh a 1 d)
328− $(d (add c (lsh a 1 d)), n +(n))
331+++ fil
332+ ~/ %fil
333+ |= [a=bloq b=step c=@]
334+ =| n=@ud
335+ =. c (end a c)
336+ =/ d c
337+ |- ^- @
338+ ?: =(n b)
339+ (rsh a d)
340+ $(d (add c (lsh a d)), n +(n))
329341```
330342
331343#### Examples
332344
333345```
334− > `@t`(fil 3 5 %a) :: @t is the cord (string) aura
335− 'aaaaa'
346+> `@t`(fil 3 5 %a) :: @t is the cord (string) aura
347+'aaaaa'
348+```
336349
337− > `@t`(fil 5 10 %ceeb)
338− 'ceebceebceebceebceebceebceebceebceebceeb'
350+```
351+> `@t`(fil 5 10 %ceeb)
352+'ceebceebceebceebceebceebceebceebceebceeb'
353+```
339354
340− > `@t`(fil 4 10 %eced)
341− 'ʇʇʇʇʇʇʇʇʇʇed'
355+```
356+> `@t`(fil 4 10 'eced')
357+'ecececececececececec'
358+```
342359
343− > `@tas`(fil 4 10 %bf) :: @tas is the term aura
344− %bfbfbfbfbfbfbfbfbfbf
360+```
361+> `@tas`(fil 4 10 %bf) :: @tas is the term aura
362+%bfbfbfbfbfbfbfbfbfbf
363+```
345364
346− > `@ub`(fil 2 6 1) :: @ub is the binary aura
347− 0b1.0001.0001.0001.0001.0001
365+```
366+> `@ub`(fil 2 6 1) :: @ub is the binary aura
367+0b1.0001.0001.0001.0001.0001
348368```
349369
350370---
351371
352−### `++lsh`
372+## `++lsh`
353373
354374Left-shift
355375
@@ -357,8 +377,8 @@ Produces an atom by left-shifting `b` by `step` blocks of size `bloq`.
357377
358378#### Accepts
359379
360−`a` is an atom slice specifier (see [`++bite`](/docs/hoon/reference/stdlib/1c#bite)),
361−which is a block size (see [`++bloq`](/docs/hoon/reference/stdlib/1c#bloq))
380+`a` is an atom slice specifier (see [`$bite`](/docs/hoon/reference/stdlib/1c#bite)),
381+which is a block size (see [`$bloq`](/docs/hoon/reference/stdlib/1c#bloq))
362382with optional block count.
363383
364384`b` is an atom.
@@ -370,41 +390,38 @@ An atom.
370390#### Source
371391
372392```hoon
373− ++ lsh
374− ~/ %lsh
375− |= [a=bite b=@]
376− =/ [=bloq =step] ?^(a a [a *step])
377− (mul b (bex (mul (bex bloq) step)))
393+++ lsh
394+ ~/ %lsh
395+ |= [a=bite b=@]
396+ =/ [=bloq =step] ?^(a a [a *step])
397+ (mul b (bex (mul (bex bloq) step)))
378398```
379399
380400#### Examples
381401
382402```
383− > `@ub`1 :: @ub is the binary aura
384− 0b1
385−
386− > `@ub`(lsh [0 1] 1)
387− 0b10
388−
389− > (lsh [0 1] 1)
390− 2
391−
392− > (lsh 0 1)
393− 2
394−
395− > `@ub`255
396− 0b1111.1111
397−
398− > `@ub`(lsh [3 1] 255)
399− 0b1111.1111.0000.0000
403+> `@ub`1 :: @ub is the binary aura
404+0b1
405+> `@ub`(lsh [0 1] 1)
406+0b10
407+> (lsh [0 1] 1)
408+2
409+> (lsh 0 1)
410+2
411+```
400412
401− > (lsh [3 1] 255)
402− 65.280
413+```
414+> `@ub`255
415+0b1111.1111
416+> `@ub`(lsh [3 1] 255)
417+0b1111.1111.0000.0000
418+> (lsh [3 1] 255)
419+65.280
403420```
404421
405422---
406423
407−### `++met`
424+## `++met`
408425
409426Measure
410427
@@ -412,45 +429,47 @@ Computes the number of blocks of size `a` in `b`, producing an atom.
412429
413430#### Accepts
414431
415−`a` is a block size (see [`++bloq`](/docs/hoon/reference/stdlib/1c)).
432+`a` is a block size (see [`$bloq`](/docs/hoon/reference/stdlib/1c/bloq)).
416433
417434`b` is an atom.
418435
419436#### Source
420437
421438```hoon
422− ++ met
423− ~/ %met
424− |= [a=bloq b=@]
425− ^- @
426− =+ c=0
427− |-
428− ?: =(0 b) c
429− $(b (rsh a 1 b), c +(c))
439+++ met
440+ ~/ %met
441+ |= [a=bloq b=@]
442+ ^- @
443+ =+ c=0
444+ |-
445+ ?: =(0 b) c
446+ $(b (rsh a b), c +(c))
430447```
431448
432449#### Examples
433450
434451```
435− > (met 0 1)
436− 1
437−
438− > (met 0 2)
439− 2
440−
441− > (met 3 255)
442− 1
452+> (met 0 1)
453+1
454+> (met 0 2)
455+2
456+```
443457
444− > (met 3 256)
445− 2
458+```
459+> (met 3 255)
460+1
461+> (met 3 256)
462+2
463+```
446464
447− > (met 3 'abcde')
448− 5
465+```
466+> (met 3 'abcde')
467+5
449468```
450469
451470---
452471
453−### `++rap`
472+## `++rap`
454473
455474Assemble non-zero
456475
@@ -469,41 +488,39 @@ An atom.
469488#### Source
470489
471490```hoon
472− ++ rap
473− ~/ %rap
474− |= [a=bloq b=(list @)]
475− ^- @
476− =+ ~
477− ?~ b 0
478− (cat a i.b $(b t.b))
491+++ rap
492+ ~/ %rap
493+ |= [a=bloq b=(list @)]
494+ ^- @
495+ ?~ b 0
496+ (cat a i.b $(b t.b))
479497```
480498
481499#### Examples
482500
483501```
484− > `@ub`(rap 2 [1 2 3 4 ~]) :: @ub is the binary aura
485− 0b100.0011.0010.0001
486−
487− > `@ub`(rap 1 [1 2 3 4 ~])
488− 0b1.0011.1001
489−
490− > (rap 0 [0 0 0 ~])
491− 0
492−
493− > (rap 0 [1 0 1 ~])
494− 3
495−
496− > `@ub`3
497− 0b11
498−
499− > (rap 0 [0 1 0 0 1 2 ~])
500− 11
502+> `@ub`(rap 2 [1 2 3 4 ~]) :: @ub is the binary aura
503+0b100.0011.0010.0001
504+> `@ub`(rap 1 [1 2 3 4 ~])
505+0b1.0011.1001
506+```
501507
502− > (rap 0 [1 1 2 ~])
503− 11
508+```
509+> (rap 0 [0 0 0 ~])
510+0
511+> (rap 0 [1 0 1 ~])
512+3
513+```
504514
505− > `@ub`11
506− 0b1011
515+```
516+> `@ub`3
517+0b11
518+> (rap 0 [0 1 0 0 1 2 ~])
519+11
520+> (rap 0 [1 1 2 ~])
521+11
522+> `@ub`11
523+0b1011
507524```
508525
509526#### Discussion
@@ -512,7 +529,7 @@ Any element of the value `0` is not included in concatenation.
512529
513530---
514531
515−### `++rep`
532+## `++rep`
516533
517534Assemble single
518535
@@ -533,63 +550,69 @@ An atom.
533550#### Source
534551
535552```hoon
536− ++ rep
537− ~/ %rep
538− |= [a=bite b=(list @)]
539− =/ [=bloq =step] ?^(a a [a *step])
540− =| i=@ud
541− |- ^- @
542− ?~ b 0
543− %+ add $(i +(i), b t.b)
544− (lsh [bloq (mul step i)] (end [bloq step] i.b))
553+++ rep
554+ ~/ %rep
555+ |= [a=bite b=(list @)]
556+ =/ [=bloq =step] ?^(a a [a *step])
557+ =| i=@ud
558+ |- ^- @
559+ ?~ b 0
560+ %+ add $(i +(i), b t.b)
561+ (lsh [bloq (mul step i)] (end [bloq step] i.b))
545562```
546563
547564#### Examples
548565
549566```
550− > `@ub`(rep 2 [1 2 3 4 ~]) :: @ub is the binary aura
551− 0b100.0011.0010.0001
552−
553− > (rep 0 [0 0 1 ~])
554− 4
555−
556− > (rep 0 [0 0 0 1 ~])
557− 8
558−
559− > `@ub`(rep 0 [0 0 0 1 ~])
560− 0b1000
561−
562− > `@ub`8
563− 0b1000
564−
565− > `@ub`(rep 0 [1 0 1 0 ~])
566− 0b101
567−
568− > `@ub`(rep 0 [1 2 3 4 ~])
569− 0b101
567+> `@ub`(rep 2 [1 2 3 4 ~]) :: @ub is the binary aura
568+0b100.0011.0010.0001
569+```
570570
571− > (rep 0 [0 1 0 1 ~])
572− 10
571+```
572+> (rep 0 [0 0 1 ~])
573+4
574+> (rep 0 [0 0 0 1 ~])
575+8
576+```
573577
574− > (rep 0 [1 0 1 0 1 ~])
575− 21
578+```
579+> `@ub`(rep 0 [0 0 0 1 ~])
580+0b1000
581+> `@ub`8
582+0b1000
583+```
576584
577− > `@ub`21
578− 0b10.1010
585+```
586+> `@ub`(rep 0 [1 0 1 0 ~])
587+0b101
588+> `@ub`(rep 0 [1 2 3 4 ~])
589+0b101
590+```
579591
580− > `@ub`(rep 3 [12 166 8 34 ~])
581− 0b10.0010.0000.1000.1010.0110.0000.1100
592+```
593+> (rep 0 [0 1 0 1 ~])
594+10
595+> (rep 0 [1 0 1 0 1 ~])
596+21
597+> `@ub`21
598+0b10.1010
599+```
582600
583− > `*`"abcd"
584− [97 98 99 100 0]
601+```
602+> `@ub`(rep 3 [12 166 8 34 ~])
603+0b10.0010.0000.1000.1010.0110.0000.1100
604+```
585605
586− > `@t`(rep 3 "abcd") :: @t is the text aura
587− 'abcd'
606+```
607+> `*`"abcd"
608+[97 98 99 100 0]
609+> `@t`(rep 3 "abcd") :: @t is the text aura
610+'abcd'
588611```
589612
590613---
591614
592−### `++rev`
615+## `++rev`
593616
594617Reverses block order, accounting for leading zeroes.
595618
@@ -630,35 +653,30 @@ An atom.
630653
631654```
632655> =a 0b1111.0000.1111.1010.0011
633−
634656> `@ub`(rev 0 20 a)
6356570b1100.0101.1111.0000.1111
636−
637658> `@ub`(rev 0 12 a)
6386590b1100.0101.1111
639−
640660> `@ub`(rev 2 5 a)
6416610b11.1010.1111.0000.1111
642−
643662> `@ub`(rev 2 4 a)
6446630b11.1010.1111.0000
645−
646664> `@ub`(rev 2 6 a)
6476650b11.1010.1111.0000.1111.0000
666+```
648667
668+```
649669> (rev 1 10 1.000)
650670179.200
651−
652671> (rev 2 5 1.000)
653672582.400
654−
655673> (rev 1 5 1.000)
656674175
657675```
658676
659677---
660678
661−### `++rip`
679+## `++rip`
662680
663681Disassemble
664682
@@ -679,51 +697,51 @@ A list of atoms.
679697#### Source
680698
681699```hoon
682− ++ rip
683− ~/ %rip
684− |= [a=bite b=@]
685− ^- (list @)
686− ?: =(0 b) ~
687− [(end a b) $(b (rsh a b))]
700+++ rip
701+ ~/ %rip
702+ |= [a=bite b=@]
703+ ^- (list @)
704+ ?: =(0 b) ~
705+ [(end a b) $(b (rsh a b))]
688706```
689707
690708#### Examples
691709
692710```
693− > `@ub`155 :: @ub is the binary aura
694− 0b1001.1011
695−
696− > (rip 0 155)
697− ~[1 1 0 1 1 0 0 1]
698−
699− > (rip 2 155)
700− ~[11 9]
701−
702− > (rip 0 11)
703− ~[1 1 0 1]
704−
705− > (rip 1 155)
706− ~[3 2 1 2]
707−
708− > `@ub`256
709− 0b1.0000.0000
710−
711− > (rip 0 256)
712− ~[0 0 0 0 0 0 0 0 1]
711+> `@ub`155 :: @ub is the binary aura
712+0b1001.1011
713+> (rip 0 155)
714+~[1 1 0 1 1 0 0 1]
715+> (rip 2 155)
716+~[11 9]
717+```
713718
714− > (rip 2 256)
715− ~[0 0 1]
719+```
720+> (rip 0 11)
721+~[1 1 0 1]
722+> (rip 1 155)
723+~[3 2 1 2]
724+```
716725
717− > (rip 3 256)
718− ~[0 1]
726+```
727+> `@ub`256
728+0b1.0000.0000
729+> (rip 0 256)
730+~[0 0 0 0 0 0 0 0 1]
731+> (rip 2 256)
732+~[0 0 1]
733+> (rip 3 256)
734+~[0 1]
735+```
719736
720− > `tape`(rip 3 'abcd')
721− "abcd"
737+```
738+> `tape`(rip 3 'abcd')
739+"abcd"
722740```
723741
724742---
725743
726−### `++rsh`
744+## `++rsh`
727745
728746Right-shift
729747
@@ -744,56 +762,51 @@ An atom.
744762#### Source
745763
746764```hoon
747− ++ rsh
748− ~/ %rsh
749− |= [a=bite b=@]
750− =/ [=bloq =step] ?^(a a [a *step])
751− (div b (bex (mul (bex bloq) step)))
765+++ rsh
766+ ~/ %rsh
767+ |= [a=bite b=@]
768+ =/ [=bloq =step] ?^(a a [a *step])
769+ (div b (bex (mul (bex bloq) step)))
752770```
753771
754772#### Examples
755773
756774```
757− > `@ub`145 :: @ub is the binary aura
758− 0b1001.0001
759−
760− > `@ub`(rsh [1 1] 145)
761− 0b10.0100
762−
763− > (rsh [1 1] 145)
764− 36
765−
766− > (rsh 1 145)
767− 36
768−
769− > `@ub`(rsh [2 1] 145)
770− 0b1001
771−
772− > (rsh [2 1] 145)
773− 9
774−
775− > `@ub`10
776− 0b1010
777−
778− > `@ub`(rsh [0 1] 10)
779− 0b101
780−
781− > (rsh [0 1] 10)
782− 5
783−
784− > `@ux`'abc'
785− 0x63.6261
775+> `@ub`145 :: @ub is the binary aura
776+0b1001.0001
777+> `@ub`(rsh [1 1] 145)
778+0b10.0100
779+> (rsh [1 1] 145)
780+36
781+> (rsh 1 145)
782+36
783+> `@ub`(rsh [2 1] 145)
784+0b1001
785+> (rsh [2 1] 145)
786+9
787+```
786788
787− > `@t`(rsh [3 1] 'abc')
788− 'bc'
789+```
790+> `@ub`10
791+0b1010
792+> `@ub`(rsh [0 1] 10)
793+0b101
794+> (rsh [0 1] 10)
795+5
796+```
789797
790− > `@ux`(rsh [3 1] 'abc')
791− 0x6362
798+```
799+> `@ux`'abc'
800+0x63.6261
801+> `@t`(rsh [3 1] 'abc')
802+'bc'
803+> `@ux`(rsh [3 1] 'abc')
804+0x6362
792805```
793806
794807---
795808
796−### `++run`
809+## `++run`
797810
798811`++turn` into atom.
799812
@@ -817,25 +830,24 @@ An atom.
817830#### Source
818831
819832```hoon
820− ++ run
821− ~/ %run
822− |= [a=bite b=@ c=$-(@ @)]
823− (rep a (turn (rip a b) c))
833+++ run
834+ ~/ %run
835+ |= [a=bite b=@ c=$-(@ @)]
836+ (rep a (turn (rip a b) c))
824837```
825838
826839#### Examples
827840
828841```
829− > `@ux`65.535 :: @ux is the hexadecimal aura
842+ > `@ux`65.535 :: @ux is the hexadecimal aura
830843 0xffff
831−
832− > `@ux`(run 2 65.535 dec) :: dec is the decrement gate
844+ > `@ux`(run 2 65.535 dec) :: dec is the decrement gate
833845 0xeeee
834846```
835847
836848---
837849
838−### `++rut`
850+## `++rut`
839851
840852`++turn` into list.
841853
@@ -859,25 +871,80 @@ A list.
859871#### Source
860872
861873```hoon
862− ++ rut
863− ~/ %rut
864− |* [a=bite b=@ c=$-(@ *)]
865− (turn (rip a b) c)
874+++ rut
875+ ~/ %rut
876+ |* [a=bite b=@ c=$-(@ *)]
877+ (turn (rip a b) c)
866878```
867879
868880#### Examples
869881
870882```
871− > `@ux`65.535 :: @ux is the hexadecimal aura
872− 0xffff
883+> `@ux`65.535 :: @ux is the hexadecimal aura
884+0xffff
885+> `(list @ux)`(rut 2 65.535 dec) :: dec is the decrement gate
886+~[0xe 0xe 0xe 0xe]
887+```
888+
889+---
890+
891+## `++sew`
892+
893+Stitch one atom into another
894+
895+Replace `c` blocks of size `a` at offset `b` of atom `e` with `c` blocks of size `a` from atom `d`.
896+
897+That is, take `(end [a c] d)` from `d` and overwrite the `(cut a [b c] e)` part of `e`.
898+
899+Or in simpler terms, take from the start of `d` and replace some part of `e` with it.
900+
901+#### Accepts
873902
874− > `(list @ux)`(rut 2 65.535 dec) :: dec is the decrement gate
875− ~[0xe 0xe 0xe 0xe]
903+`a` is a [$bloq](/docs/hoon/reference/stdlib/1c#bite) (block size).
904+
905+`[b c d]` where:
906+
907+- `b` is a [step](/docs/hoon/reference/stdlib/1c#step) specifying the number of `bloq`s to offset.
908+- `b` is a [step](/docs/hoon/reference/stdlib/1c#step) specifying the number of `bloq`s to replace.
909+- `d` is the donor atom.
910+
911+`e` is the recipient atom.
912+
913+#### Produces
914+
915+An atom.
916+
917+#### Source
918+
919+```hoon
920+++ sew
921+ ~/ %sew
922+ |= [a=bloq [b=step c=step d=@] e=@]
923+ ^- @
924+ %+ add
925+ (can a b^e c^d ~)
926+ =/ f [a (add b c)]
927+ (lsh f (rsh f e))
928+```
929+
930+#### Examples
931+
932+```
933+> `@t`(sew 3 [0 0 'XXXX'] 'OOOO')
934+'OOOO'
935+> `@t`(sew 3 [0 1 'XXXX'] 'OOOO')
936+'XOOO'
937+> `@t`(sew 3 [2 1 'XXXX'] 'OOOO')
938+'OOXO'
939+> `@t`(sew 3 [2 2 'XXXX'] 'OOOO')
940+'OOXX'
941+> `@t`(sew 3 [0 4 'XXXX'] 'OOOO')
942+'XXXX'
876943```
877944
878945---
879946
880−### `++swp`
947+## `++swp`
881948
882949Reverse block order
883950
@@ -886,7 +953,7 @@ reversing the block order of `b` using block size `a`.
886953
887954#### Accepts
888955
889−`a` is a block size (see [`++bloq`](/docs/hoon/reference/stdlib/1c)).
956+`a` is a block size (see [`$bloq`](/docs/hoon/reference/stdlib/1c#bloq)).
890957
891958`b` is an atom.
892959
@@ -897,31 +964,33 @@ An atom
897964#### Source
898965
899966```hoon
900− ++ swp |=([a=bloq b=@] (rep a (flop (rip a b))))
967+++ swp
968+ ~/ %swp
969+ |= [a=bloq b=@]
970+ (rep a (flop (rip a b)))
901971```
902972
903973#### Examples
904974
905975```
906− > `@ub`24 :: @ub is the binary aura
907− 0b1.1000
908−
909− > (swp 0 24)
910− 3
911−
912− > `@ub`3
913− 0b11
914−
915− > (swp 0 0)
916− 0
976+> `@ub`24 :: @ub is the binary aura
977+0b1.1000
978+> (swp 0 24)
979+3
980+> `@ub`3
981+0b11
982+```
917983
918− > (swp 0 128)
919− 1
984+```
985+> (swp 0 0)
986+0
987+> (swp 0 128)
988+1
920989```
921990
922991---
923992
924−### `++xeb`
993+## `++xeb`
925994
926995Binary logarithm
927996
@@ -938,38 +1007,48 @@ An atom.
9381007#### Source
9391008
9401009```hoon
941− ++ xeb
942− ~/ %xeb
943− |= a=@
944− ^- @
945− (met 0 a)
1010+++ xeb
1011+ ~/ %xeb
1012+ |= a=@
1013+ ^- @
1014+ (met 0 a)
9461015```
9471016
9481017#### Examples
9491018
9501019```
951− > (xeb 31)
952− 5
1020+> (xeb 31)
1021+5
1022+```
9531023
954− > (xeb 32)
955− 6
1024+```
1025+> (xeb 32)
1026+6
1027+```
9561028
957− > (xeb 49)
958− 6
1029+```
1030+> (xeb 49)
1031+6
1032+```
9591033
960− > (xeb 0)
961− 0
1034+```
1035+> (xeb 0)
1036+0
1037+```
9621038
963− > (xeb 1)
964− 1
1039+```
1040+> (xeb 1)
1041+1
1042+```
9651043
966− > (xeb 2)
967− 2
1044+```
1045+> (xeb 2)
1046+2
9681047```
9691048
9701049---
9711050
972−### `++fe`
1051+## `++fe`
9731052
9741053Modulo bloq
9751054
@@ -994,7 +1073,7 @@ representation.
9941073
9951074#### Accepts
9961075
997−`a` is a `bloq`.
1076+`a` is a `bloq` (and is the sample of the parent core).
9981077
9991078`b` is an atom.
10001079
@@ -1002,40 +1081,40 @@ representation.
10021081
10031082#### Produces
10041083
1005−A `@s`
1084+A `@s`.
10061085
10071086#### Source
10081087
10091088```hoon
1010− ++ dif |=([b=@ c=@] (sit (sub (add out (sit b)) (sit c))))
1089+ ++ dif
1090+ |=([b=@ c=@] (sit (sub (add out (sit b)) (sit c))))
10111091```
10121092
10131093#### Examples
10141094
10151095```
1016− > (~(dif fe 3) 63 64)
1017− 255
1018−
1019− > (~(dif fe 3) 5 10)
1020− 251
1021−
1022− > (~(dif fe 3) 0 1)
1023− 255
1024−
1025− > (~(dif fe 0) 9 10)
1026− 1
1027−
1028− > (~(dif fe 0) 9 11)
1029− 0
1030−
1031− > (~(dif fe 0) 9 12)
1032− 1
1096+> (~(dif fe 3) 63 64)
1097+255
1098+> (~(dif fe 3) 5 10)
1099+251
1100+> (~(dif fe 3) 0 1)
1101+255
1102+```
10331103
1034− > (~(dif fe 2) 9 12)
1035− 13
1104+```
1105+> (~(dif fe 0) 9 10)
1106+1
1107+> (~(dif fe 0) 9 11)
1108+0
1109+> (~(dif fe 0) 9 12)
1110+1
1111+```
10361112
1037− > (~(dif fe 2) 63 64)
1038− 15
1113+```
1114+> (~(dif fe 2) 9 12)
1115+13
1116+> (~(dif fe 2) 63 64)
1117+15
10391118```
10401119
10411120---
@@ -1048,7 +1127,9 @@ Inverts the order of the modular field.
10481127
10491128#### Accepts
10501129
1051−`b` is a `bloq`. (see [`++bloq`](/docs/hoon/reference/stdlib/1c))
1130+`a` is a `bloq` (and is the sample of the parent core).
1131+
1132+`b` is a `bloq`. (see [`$bloq`](/docs/hoon/reference/stdlib/1c#bloq))
10521133
10531134#### Produces
10541135
@@ -1057,29 +1138,30 @@ An atom.
10571138#### Source
10581139
10591140```hoon
1060− ++ inv |=(b=@ (sub (dec out) (sit b)))
1141+++ inv |=(b=@ (sub (dec out) (sit b)))
10611142```
10621143
10631144#### Examples
10641145
10651146```
1066− > (~(inv fe 3) 255)
1067− 0
1068−
1069− > (~(inv fe 3) 256)
1070− 255
1071−
1072− > (~(inv fe 3) 0)
1073− 255
1074−
1075− > (~(inv fe 3) 1)
1076− 254
1147+> (~(inv fe 3) 255)
1148+0
1149+> (~(inv fe 3) 256)
1150+255
1151+```
10771152
1078− > (~(inv fe 3) 2)
1079− 253
1153+```
1154+> (~(inv fe 3) 0)
1155+255
1156+> (~(inv fe 3) 1)
1157+254
1158+> (~(inv fe 3) 2)
1159+253
1160+```
10801161
1081− > (~(inv fe 3) 55)
1082− 200
1162+```
1163+> (~(inv fe 3) 55)
1164+200
10831165```
10841166
10851167---
@@ -1092,7 +1174,9 @@ Reverses bytes within a block.
10921174
10931175#### Accepts
10941176
1095−`b` is a `bloq`. (see [`++bloq`](/docs/hoon/reference/stdlib/1c))
1177+`a` is a `bloq` (and the sample of the parent core).
1178+
1179+`b` is a `bloq`. (see [`$bloq`](/docs/hoon/reference/stdlib/1c#bloq))
10961180
10971181#### Produces
10981182
@@ -1101,75 +1185,66 @@ An atom.
11011185#### Source
11021186
11031187```hoon
1104− ++ net |= b=@ ^- @
1105− => .(b (sit b))
1106− ?: (lte a 3)
1107− b
1108− =+ c=(dec a)
1109− %+ con
1110− (lsh c 1 $(a c, b (cut c [0 1] b)))
1111− $(a c, b (cut c [1 1] b))
1188+++ net |= b=@ ^- @
1189+ => .(b (sit b))
1190+ ?: (lte a 3)
1191+ b
1192+ =+ c=(dec a)
1193+ %+ con
1194+ (lsh c $(a c, b (cut c [0 1] b)))
1195+ $(a c, b (cut c [1 1] b))
11121196```
11131197
11141198#### Examples
11151199
11161200```
1117− > (~(net fe 3) 64)
1118− 64
1119−
1120− > (~(net fe 3) 128)
1121− 128
1122−
1123− > (~(net fe 3) 255)
1124− 255
1125−
1126− > (~(net fe 3) 256)
1127− 0
1128−
1129− > (~(net fe 3) 257)
1130− 1
1131−
1132− > (~(net fe 3) 500)
1133− 244
1134−
1135− > (~(net fe 3) 511)
1136− 255
1137−
1138− > (~(net fe 3) 512)
1139− 0
1140−
1141− > (~(net fe 3) 513)
1142− 1
1143−
1144− > (~(net fe 3) 0)
1145− 0
1146−
1147− > (~(net fe 3) 1)
1148− 1
1149−
1150− > (~(net fe 0) 1)
1151− 1
1152−
1153− > (~(net fe 0) 2)
1154− 0
1155−
1156− > (~(net fe 0) 3)
1157− 1
1158−
1159− > (~(net fe 6) 1)
1160− 72.057.594.037.927.936
1161−
1162− > (~(net fe 6) 2)
1163− 144.115.188.075.855.872
1201+> (~(net fe 3) 64)
1202+64
1203+> (~(net fe 3) 128)
1204+128
1205+> (~(net fe 3) 255)
1206+255
1207+> (~(net fe 3) 256)
1208+0
1209+> (~(net fe 3) 257)
1210+1
1211+```
11641212
1165− > (~(net fe 6) 3)
1166− 216.172.782.113.783.808
1213+```
1214+> (~(net fe 3) 500)
1215+244
1216+> (~(net fe 3) 511)
1217+255
1218+> (~(net fe 3) 512)
1219+0
1220+> (~(net fe 3) 513)
1221+1
1222+```
11671223
1168− > (~(net fe 6) 4)
1169− 288.230.376.151.711.744
1224+```
1225+> (~(net fe 3) 0)
1226+0
1227+> (~(net fe 3) 1)
1228+1
1229+> (~(net fe 0) 1)
1230+1
1231+> (~(net fe 0) 2)
1232+0
1233+> (~(net fe 0) 3)
1234+1
1235+```
11701236
1171− > (~(net fe 6) 5)
1172− 360.287.970.189.639.680
1237+```
1238+> (~(net fe 6) 1)
1239+72.057.594.037.927.936
1240+> (~(net fe 6) 2)
1241+144.115.188.075.855.872
1242+> (~(net fe 6) 3)
1243+216.172.782.113.783.808
1244+> (~(net fe 6) 4)
1245+288.230.376.151.711.744
1246+> (~(net fe 6) 5)
1247+360.287.970.189.639.680
11731248```
11741249
11751250---
@@ -1182,7 +1257,7 @@ Produces the maximum integer value that the current block can store; `2^a^a`.
11821257
11831258#### Accepts
11841259
1185−`a` is a `bloq`.
1260+`a` is a `bloq` (and is the sample of the parent core).
11861261
11871262#### Produces
11881263
@@ -1191,35 +1266,33 @@ An atom.
11911266#### Source
11921267
11931268```hoon
1194− ++ out (bex (bex a))
1269+++ out (bex (bex a))
11951270```
11961271
11971272#### Examples
11981273
11991274```
1200− > ~(out fe 0)
1201− 2
1202−
1203− > ~(out fe 1)
1204− 4
1205−
1206− > ~(out fe 2)
1207− 16
1208−
1209− > ~(out fe 3)
1210− 256
1211−
1212− > ~(out fe 4)
1213− 65.536
1275+> ~(out fe 0)
1276+2
1277+> ~(out fe 1)
1278+4
1279+> ~(out fe 2)
1280+16
1281+> ~(out fe 3)
1282+256
1283+> ~(out fe 4)
1284+65.536
1285+```
12141286
1215− > ~(out fe 10)
1216− \/179.769.313.486.231.590.772.930.519.078.902.473.361.797.697.894.230.657.273\/
1217− .430.081.157.732.675.805.500.963.132.708.477.322.407.536.021.120.113.879.87
1218− 1.393.357.658.789.768.814.416.622.492.847.430.639.474.124.377.767.893.424.8
1219− 65.485.276.302.219.601.246.094.119.453.082.952.085.005.768.838.150.682.342.
1220− 462.881.473.913.110.540.827.237.163.350.510.684.586.298.239.947.245.938.479
1221− .716.304.835.356.329.624.224.137.216
1222− \/ \/
1287+```
1288+> ~(out fe 10)
1289+\/179.769.313.486.231.590.772.930.519.078.902.473.361.797.697.894.230.657.273\/
1290+ .430.081.157.732.675.805.500.963.132.708.477.322.407.536.021.120.113.879.87
1291+ 1.393.357.658.789.768.814.416.622.492.847.430.639.474.124.377.767.893.424.8
1292+ 65.485.276.302.219.601.246.094.119.453.082.952.085.005.768.838.150.682.342.
1293+ 462.881.473.913.110.540.827.237.163.350.510.684.586.298.239.947.245.938.479
1294+ .716.304.835.356.329.624.224.137.216
1295+\/ \/
12231296```
12241297
12251298---
@@ -1232,7 +1305,7 @@ Rolls `d` to the left by `c` `b`-sized blocks.
12321305
12331306#### Accepts
12341307
1235−`a` is a `bloq`.
1308+`a` is a `bloq` (and is the sample of the parent core).
12361309
12371310`b` is a `bloq`.
12381311
@@ -1247,30 +1320,32 @@ An atom.
12471320#### Source
12481321
12491322```hoon
1250− ++ rol |= [b=bloq c=@ d=@] ^- @
1251− =+ e=(sit d)
1252− =+ f=(bex (sub a b))
1253− =+ g=(mod c f)
1254− (sit (con (lsh b g e) (rsh b (sub f g) e)))
1323+++ rol |= [b=bloq c=@ d=@] ^- @
1324+ =+ e=(sit d)
1325+ =+ f=(bex (sub a b))
1326+ =+ g=(mod c f)
1327+ (sit (con (lsh [b g] e) (rsh [b (sub f g)] e)))
12551328```
12561329
12571330#### Examples
12581331
12591332```
1260− > `@ux`(~(rol fe 6) 4 3 0xabac.dedf.1213)
1261− 0x1213.0000.abac.dedf
1333+> `@ux`(~(rol fe 6) 4 3 0xabac.dedf.1213)
1334+0x1213.0000.abac.dedf
12621335
1263− > `@ux`(~(rol fe 6) 4 2 0xabac.dedf.1213)
1264− 0xdedf.1213.0000.abac
1336+> `@ux`(~(rol fe 6) 4 2 0xabac.dedf.1213)
1337+0xdedf.1213.0000.abac
1338+```
12651339
1266− > `@t`(~(rol fe 5) 3 1 'dfgh')
1267− 'hdfg'
1340+```
1341+> `@t`(~(rol fe 5) 3 1 'dfgh')
1342+'hdfg'
12681343
1269− > `@t`(~(rol fe 5) 3 2 'dfgh')
1270− 'ghdf'
1344+> `@t`(~(rol fe 5) 3 2 'dfgh')
1345+'ghdf'
12711346
1272− > `@t`(~(rol fe 5) 3 0 'dfgh')
1273− 'dfgh'
1347+> `@t`(~(rol fe 5) 3 0 'dfgh')
1348+'dfgh'
12741349```
12751350
12761351---
@@ -1283,7 +1358,7 @@ Rolls `d` to the right by `c` `b`-sized blocks.
12831358
12841359#### Accepts
12851360
1286−`a` is a `bloq`.
1361+`a` is a `bloq` (and is the sample of the parent core).
12871362
12881363`b` is a `bloq`.
12891364
@@ -1298,49 +1373,53 @@ An atom.
12981373#### Source
12991374
13001375```hoon
1301− ++ ror |= [b=bloq c=@ d=@] ^- @
1302− =+ e=(sit d)
1303− =+ f=(bex (sub a b))
1304− =+ g=(mod c f)
1305− (sit (con (rsh b g e) (lsh b (sub f g) e)))
1376+++ ror |= [b=bloq c=@ d=@] ^- @
1377+ =+ e=(sit d)
1378+ =+ f=(bex (sub a b))
1379+ =+ g=(mod c f)
1380+ (sit (con (rsh [b g] e) (lsh [b (sub f g)] e)))
13061381```
13071382
13081383#### Examples
13091384
13101385```
1311− > `@ux`(~(ror fe 6) 4 1 0xabac.dedf.1213)
1312− 0x1213.0000.abac.dedf
1386+> `@ux`(~(ror fe 6) 4 1 0xabac.dedf.1213)
1387+0x1213.0000.abac.dedf
13131388
1314− > `@ux`(~(ror fe 6) 3 5 0xabac.dedf.1213)
1315− 0xacde.df12.1300.00ab
1389+> `@ux`(~(ror fe 6) 3 5 0xabac.dedf.1213)
1390+0xacde.df12.1300.00ab
13161391
1317− > `@ux`(~(ror fe 6) 3 3 0xabac.dedf.1213)
1318− 0xdf12.1300.00ab.acde
1392+> `@ux`(~(ror fe 6) 3 3 0xabac.dedf.1213)
1393+0xdf12.1300.00ab.acde
1394+```
13191395
1320− > `@t`(~(rol fe 5) 3 0 'hijk')
1321− 'hijk'
1396+```
1397+> `@t`(~(rol fe 5) 3 0 'hijk')
1398+'hijk'
13221399
1323− > `@t`(~(rol fe 5) 3 1 'hijk')
1324− 'khij'
1400+> `@t`(~(rol fe 5) 3 1 'hijk')
1401+'khij'
13251402
1326− > `@t`(~(rol fe 5) 3 2 'hijk')
1327− 'jkhi'
1403+> `@t`(~(rol fe 5) 3 2 'hijk')
1404+'jkhi'
13281405```
13291406
13301407---
13311408
1332−### `++sit:fe`
1409+### `++sum:fe`
13331410
1334−Enforce modulo
1411+Sum
13351412
1336−Produces an atom in the current modular block representation.
1413+Sums two numbers in this modular field.
13371414
13381415#### Accepts
13391416
1340−`a` is a `bloq`.
1417+`a` is a `bloq` (and is the sample of the parent core).
13411418
13421419`b` is an atom.
13431420
1421+`c` is an atom.
1422+
13441423#### Produces
13451424
13461425An atom.
@@ -1348,62 +1427,51 @@ An atom.
13481427#### Source
13491428
13501429```hoon
1351− ++ sit |=(b=@ (end a 1 b))
1430+++ sum |=([b=@ c=@] (sit (add b c)))
13521431```
13531432
13541433#### Examples
13551434
13561435```
1357− > (~(sit fe 3) 255)
1358− 255
1359−
1360− > (~(sit fe 3) 256)
1361− 0
1362−
1363− > (~(sit fe 3) 257)
1364− 1
1365−
1366− > (~(sit fe 2) 257)
1367− 1
1368−
1369− > (~(sit fe 2) 10.000)
1370− 0
1371−
1372− > (~(sit fe 2) 100)
1373− 4
1374−
1375− > (~(sit fe 2) 19)
1376− 3
1377−
1378− > (~(sit fe 2) 17)
1379− 1
1436+> (~(sum fe 3) 10 250)
1437+4
1438+```
13801439
1381− > (~(sit fe 0) 17)
1382− 1
1440+```
1441+> (~(sum fe 0) 0 1)
1442+1
1443+> (~(sum fe 0) 0 2)
1444+0
1445+```
13831446
1384− > (~(sit fe 0) 0)
1385− 0
1447+```
1448+> (~(sum fe 2) 14 2)
1449+0
1450+> (~(sum fe 2) 14 3)
1451+1
1452+```
13861453
1387− > (~(sit fe 0) 1)
1388− 1
1454+```
1455+> (~(sum fe 4) 10.000 256)
1456+10.256
1457+> (~(sum fe 4) 10.000 100.000)
1458+44.464
13891459```
13901460
13911461---
13921462
1393−### `++sum:fe`
1463+### `++sit:fe`
13941464
1395−Sum
1465+Enforce modulo
13961466
1397−Sums two numbers in this modular field.
1467+Produces an atom in the current modular block representation.
13981468
13991469#### Accepts
14001470
1401−`a` is a `bloq`.
1471+`a` is a `bloq` (and is the sample of the parent core).
14021472
14031473`b` is an atom.
14041474
1405−`c` is an atom.
1406−
14071475#### Produces
14081476
14091477An atom.
@@ -1411,32 +1479,40 @@ An atom.
14111479#### Source
14121480
14131481```hoon
1414− ++ sum |=([b=@ c=@] (sit (add b c)))
1482+++ sit |=(b=@ (end a b))
14151483```
14161484
14171485#### Examples
14181486
14191487```
1420− > (~(sum fe 3) 10 250)
1421− 4
1422−
1423− > (~(sum fe 0) 0 1)
1424− 1
1425−
1426− > (~(sum fe 0) 0 2)
1427− 0
1428−
1429− > (~(sum fe 2) 14 2)
1430− 0
1431−
1432− > (~(sum fe 2) 14 3)
1433− 1
1488+> (~(sit fe 3) 255)
1489+255
1490+> (~(sit fe 3) 256)
1491+0
1492+> (~(sit fe 3) 257)
1493+1
1494+```
14341495
1435− > (~(sum fe 4) 10.000 256)
1436− 10.256
1496+```
1497+> (~(sit fe 2) 257)
1498+1
1499+> (~(sit fe 2) 10.000)
1500+0
1501+> (~(sit fe 2) 100)
1502+4
1503+> (~(sit fe 2) 19)
1504+3
1505+> (~(sit fe 2) 17)
1506+1
1507+```
14371508
1438− > (~(sum fe 4) 10.000 100.000)
1439− 44.464
1509+```
1510+> (~(sit fe 0) 17)
1511+1
1512+> (~(sit fe 0) 0)
1513+0
1514+> (~(sit fe 0) 1)
1515+1
14401516```
14411517
14421518---
content/docs/hoon/reference/stdlib/2d.md+55−54
@@ -4,7 +4,7 @@ weight = 7
44template = "doc.html"
55+++
66
7−### `++con`
7+## `++con`
88
99Binary OR
1010
@@ -23,22 +23,22 @@ An atom.
2323#### Source
2424
2525```hoon
26− ++ con
27− ~/ %con
28− |= [a=@ b=@]
29− =+ [c=0 d=0]
30− |- ^- @
31− ?: ?&(=(0 a) =(0 b)) d
32− %= $
33− a (rsh 0 1 a)
34− b (rsh 0 1 b)
35− c +(c)
36− d %+ add d
37− %^ lsh 0 c
38− ?& =(0 (end 0 1 a))
39− =(0 (end 0 1 b))
40− ==
41− ==
26+++ con
27+ ~/ %con
28+ |= [a=@ b=@]
29+ =+ [c=0 d=0]
30+ |- ^- @
31+ ?: ?&(=(0 a) =(0 b)) d
32+ %= $
33+ a (rsh 0 a)
34+ b (rsh 0 b)
35+ c +(c)
36+ d %+ add d
37+ %+ lsh [0 c]
38+ ?& =(0 (end 0 a))
39+ =(0 (end 0 b))
40+ ==
41+ ==
4242```
4343
4444#### Examples
@@ -97,9 +97,9 @@ contexts. That's because `0` is true in Hoon and `1` is false. Outside of Hoon,
9797where `0` is false and `1` is true, bitwise OR is the logical disjunction and
9898bitwise AND is the logical conjunction.
9999
100−
101100---
102−### `++dis`
101+
102+## `++dis`
103103
104104Binary AND
105105
@@ -118,22 +118,22 @@ An atom.
118118#### Source
119119
120120```hoon
121− ++ dis
122− ~/ %dis
123− |= [a=@ b=@]
124− =| [c=@ d=@]
125− |- ^- @
126− ?: ?|(=(0 a) =(0 b)) d
127− %= $
128− a (rsh 0 1 a)
129− b (rsh 0 1 b)
130− c +(c)
131− d %+ add d
132− %^ lsh 0 c
133− ?| =(0 (end 0 1 a))
134− =(0 (end 0 1 b))
135− ==
136− ==
121+++ dis
122+ ~/ %dis
123+ |= [a=@ b=@]
124+ =| [c=@ d=@]
125+ |- ^- @
126+ ?: ?|(=(0 a) =(0 b)) d
127+ %= $
128+ a (rsh 0 a)
129+ b (rsh 0 b)
130+ c +(c)
131+ d %+ add d
132+ %+ lsh [0 c]
133+ ?| =(0 (end 0 a))
134+ =(0 (end 0 b))
135+ ==
136+ ==
137137```
138138
139139#### Examples
@@ -187,7 +187,8 @@ where `0` is false and `1` is true, bitwise OR is the logical disjunction and
187187bitwise AND is the logical conjunction.
188188
189189---
190−### `++mix`
190+
191+## `++mix`
191192
192193Binary XOR
193194
@@ -206,19 +207,19 @@ An atom.
206207#### Source
207208
208209```hoon
209− ++ mix
210− ~/ %mix
211− |= [a=@ b=@]
212− ^- @
213− =+ [c=0 d=0]
214− |-
215− ?: ?&(=(0 a) =(0 b)) d
216− %= $
217− a (rsh 0 1 a)
218− b (rsh 0 1 b)
219− c +(c)
220− d (add d (lsh 0 c =((end 0 1 a) (end 0 1 b))))
221− ==
210+++ mix
211+ ~/ %mix
212+ |= [a=@ b=@]
213+ ^- @
214+ =+ [c=0 d=0]
215+ |-
216+ ?: ?&(=(0 a) =(0 b)) d
217+ %= $
218+ a (rsh 0 a)
219+ b (rsh 0 b)
220+ c +(c)
221+ d (add d (lsh [0 c] =((end 0 a) (end 0 b))))
222+ ==
222223```
223224
224225#### Examples
@@ -272,7 +273,8 @@ its samples and its product are stacked.
272273```
273274
274275---
275−### `++not`
276+
277+## `++not`
276278
277279Binary NOT
278280
@@ -294,8 +296,8 @@ An atom.
294296#### Source
295297
296298```hoon
297− ++ not |= [a=bloq b=@ c=@]
298− (mix c (dec (bex (mul b (bex a)))))
299+++ not |= [a=bloq b=@ c=@]
300+ (mix c (dec (bex (mul b (bex a)))))
299301```
300302
301303#### Examples
@@ -369,5 +371,4 @@ What's happening here may not be readily apparent. But we're only flipping the
369371last block of size `1` (bitwidth 2) of the binary `0b111`. That is, we leave
370372the "0b1" piece just the same and manipulate the "11" that the number ends with.
371373
372−
373−---
374+---
content/docs/hoon/reference/stdlib/2e.md+98−178
@@ -4,44 +4,7 @@ weight = 8
44template = "doc.html"
55+++
66
7−### `++fnv`
8−
9−FNV scrambler
10−
11−Hashes an atom with the 32-bit FNV non-cryptographic hash algorithm. Multiplies
12−`a` by the prime number 16,777,619 and then takes the [block](/docs/hoon/reference/stdlib/2c) of size
13−5 off the product's end, producing an atom.
14−
15−#### Accepts
16−
17−`a` is an atom.
18−
19−#### Produces
20−
21−An atom.
22−
23−#### Source
24−
25−```hoon
26− ++ fnv |=(a=@ (end 5 1 (mul 16.777.619 a)))
27−```
28−
29−#### Examples
30−
31−```
32− > (fnv 10.000)
33− 272.465.456
34−
35− > (fnv 10.001)
36− 289.243.075
37−
38− > (fnv 1)
39− 16.777.619
40−```
41−
42−
43−---
44−### `++mug` {#mug}
7+## `++mug` {#mug}
458
469murmur3 scrambler
4710
@@ -59,57 +22,70 @@ An atom.
5922#### Source
6023
6124```hoon
62−++ mug :: mug with murmur3
25+++ mug
6326 ~/ %mug
64− |= a/*
65− |^ (trim ?@(a a (mix $(a -.a) (mix 0x7fff.ffff $(a +.a)))))
66− ++ trim :: 31-bit nonzero
67− |= key/@
68− =+ syd=0xcafe.babe
69− |- ^- @
70− =+ haz=(muk syd (met 3 key) key)
71− =+ ham=(mix (rsh 0 31 haz) (end 0 31 haz))
72− ?.(=(0 ham) ham $(syd +(syd)))
27+ |= a=*
28+ |^ ?@ a (mum 0xcafe.babe 0x7fff a)
29+ =/ b (cat 5 $(a -.a) $(a +.a))
30+ (mum 0xdead.beef 0xfffe b)
31+ ::
32+ ++ mum
33+ |= [syd=@uxF fal=@F key=@]
34+ =/ wyd (met 3 key)
35+ =| i=@ud
36+ |- ^- @F
37+ ?: =(8 i) fal
38+ =/ haz=@F (muk syd wyd key)
39+ =/ ham=@F (mix (rsh [0 31] haz) (end [0 31] haz))
40+ ?.(=(0 ham) ham $(i +(i), syd +(syd)))
7341 --
7442```
7543
7644#### Examples
7745
7846```
79− > (mug 10.000)
80− 795.713.195
81−
82− > (mug 10.001)
83− 420.521.697
47+> (mug 10.000)
48+795.713.195
49+```
8450
85− > (mug 1)
86− 1.901.865.568
51+```
52+> (mug 10.001)
53+420.521.697
54+```
8755
88− > (mug (some 10))
89− 2.099.076.946
56+```
57+> (mug 1)
58+1.901.865.568
59+```
9060
91− > (mug [1 2 3 4 5 ~])
92− 1.719.833.228
61+```
62+> (mug (some 10))
63+750.200.080
9364```
9465
66+```
67+> (mug [1 2 3 4 5 ~])
68+1.565.443.491
69+```
9570
9671---
97−### `++muk`
72+
73+## `++muk`
9874
9975Standard MurmurHash3
10076
10177Implementation of the 32-bit
10278[MurmurHash3](https://en.wikipedia.org/wiki/MurmurHash#Algorithm)
103−non-cryptographic hash algorithm. Takes `a` as the seed, `b` as the key length
104−in [blocks](/docs/hoon/reference/stdlib/2c) of size 3, and `c` as the key, producing an atom.
79+non-cryptographic hash algorithm. Takes `syd` as the seed, `len` as the key length
80+in [blocks](/docs/hoon/reference/stdlib/2c) of size 3, and `key` as the key, producing an atom.
10581
10682#### Accepts
10783
108−`a` is an atom.
84+`syd` is an atom.
10985
110−`b` is an atom.
86+`len` is an atom.
11187
112−`c` is an atom.
88+`key` is an atom.
11389
11490#### Produces
11591
@@ -118,63 +94,63 @@ An atom.
11894#### Source
11995
12096```hoon
121− ++ muk
122− ~% %muk ..muk ~
123− =+ ~(. fe 5)
124− |= [syd=@ len=@ key=@]
125− ?> &((lte (met 5 syd) 1) (lte (met 0 len) 31))
126− =/ pad (sub len (met 3 key))
127− =/ data (weld (rip 3 key) (reap pad 0))
128− =/ nblocks (div len 4) :: intentionally off-by-one
129− =/ h1 syd
130− =+ [c1=0xcc9e.2d51 c2=0x1b87.3593]
131− =/ blocks (rip 5 key)
132− =/ i nblocks
133− =. h1 =/ hi h1 |-
134− ?: =(0 i) hi :: negative array index
135− =/ k1 (snag (sub nblocks i) blocks)
136− =. k1 (sit (mul k1 c1))
137− =. k1 (rol 0 15 k1)
138− =. k1 (sit (mul k1 c2))
139− =. hi (mix hi k1)
140− =. hi (rol 0 13 hi)
141− =. hi (sum (sit (mul hi 5)) 0xe654.6b64)
142− $(i (dec i))
143− =/ tail (slag (mul 4 nblocks) data)
144− =/ k1 0
145− =/ tlen (dis len 3)
146− =. h1
147− ?+ tlen h1 :: fallthrough switch
148− $3 =. k1 (mix k1 (lsh 0 16 (snag 2 tail)))
149− =. k1 (mix k1 (lsh 0 8 (snag 1 tail)))
150− =. k1 (mix k1 (snag 0 tail))
151− =. k1 (sit (mul k1 c1))
152− =. k1 (rol 0 15 k1)
153− =. k1 (sit (mul k1 c2))
154− (mix h1 k1)
155− $2 =. k1 (mix k1 (lsh 0 8 (snag 1 tail)))
156− =. k1 (mix k1 (snag 0 tail))
157− =. k1 (sit (mul k1 c1))
158− =. k1 (rol 0 15 k1)
159− =. k1 (sit (mul k1 c2))
160− (mix h1 k1)
161− $1 =. k1 (mix k1 (snag 0 tail))
162− =. k1 (sit (mul k1 c1))
163− =. k1 (rol 0 15 k1)
164− =. k1 (sit (mul k1 c2))
165− (mix h1 k1)
166− ==
167− =. h1 (mix h1 len)
168− |^ (fmix32 h1)
169− ++ fmix32
170− |= h=@
171− =. h (mix h (rsh 0 16 h))
172− =. h (sit (mul h 0x85eb.ca6b))
173− =. h (mix h (rsh 0 13 h))
174− =. h (sit (mul h 0xc2b2.ae35))
175− =. h (mix h (rsh 0 16 h))
176− h
177− --
97+++ muk :: standard murmur3
98+ ~% %muk ..muk ~
99+ =+ ~(. fe 5)
100+ |= [syd=@ len=@ key=@]
101+ =. syd (end 5 syd)
102+ =/ pad (sub len (met 3 key))
103+ =/ data (weld (rip 3 key) (reap pad 0))
104+ =/ nblocks (div len 4) :: intentionally off-by-one
105+ =/ h1 syd
106+ =+ [c1=0xcc9e.2d51 c2=0x1b87.3593]
107+ =/ blocks (rip 5 key)
108+ =/ i nblocks
109+ =. h1 =/ hi h1 |-
110+ ?: =(0 i) hi
111+ =/ k1 (snag (sub nblocks i) blocks) :: negative array index
112+ =. k1 (sit (mul k1 c1))
113+ =. k1 (rol 0 15 k1)
114+ =. k1 (sit (mul k1 c2))
115+ =. hi (mix hi k1)
116+ =. hi (rol 0 13 hi)
117+ =. hi (sum (sit (mul hi 5)) 0xe654.6b64)
118+ $(i (dec i))
119+ =/ tail (slag (mul 4 nblocks) data)
120+ =/ k1 0
121+ =/ tlen (dis len 3)
122+ =. h1
123+ ?+ tlen h1 :: fallthrough switch
124+ %3 =. k1 (mix k1 (lsh [0 16] (snag 2 tail)))
125+ =. k1 (mix k1 (lsh [0 8] (snag 1 tail)))
126+ =. k1 (mix k1 (snag 0 tail))
127+ =. k1 (sit (mul k1 c1))
128+ =. k1 (rol 0 15 k1)
129+ =. k1 (sit (mul k1 c2))
130+ (mix h1 k1)
131+ %2 =. k1 (mix k1 (lsh [0 8] (snag 1 tail)))
132+ =. k1 (mix k1 (snag 0 tail))
133+ =. k1 (sit (mul k1 c1))
134+ =. k1 (rol 0 15 k1)
135+ =. k1 (sit (mul k1 c2))
136+ (mix h1 k1)
137+ %1 =. k1 (mix k1 (snag 0 tail))
138+ =. k1 (sit (mul k1 c1))
139+ =. k1 (rol 0 15 k1)
140+ =. k1 (sit (mul k1 c2))
141+ (mix h1 k1)
142+ ==
143+ =. h1 (mix h1 len)
144+ |^ (fmix32 h1)
145+ ++ fmix32
146+ |= h=@
147+ =. h (mix h (rsh [0 16] h))
148+ =. h (sit (mul h 0x85eb.ca6b))
149+ =. h (mix h (rsh [0 13] h))
150+ =. h (sit (mul h 0xc2b2.ae35))
151+ =. h (mix h (rsh [0 16] h))
152+ h
153+ --
178154```
179155
180156#### Examples
@@ -209,60 +185,4 @@ An atom.
209185 246.077.549
210186```
211187
212−
213−---
214−### `++mum`
215−
216−31-bit MurmurHash3 scrambler
217−
218−Hashes `a` with the 31-bit MurmurHash3 non-cryptographic hash algorithm,
219−producing an atom.
220−
221−#### Accepts
222−
223−`a` is a noun.
224−
225−#### Produces
226−
227−An atom.
228−
229−#### Source
230−
231−```hoon
232− ++ mum
233− ~/ %mum
234− |= a=*
235− |^ (trim ?@(a a (mix $(a -.a) (mix 0x7fff.ffff $(a +.a)))))
236− ++ trim
237− |= key=@
238− =+ syd=0xcafe.babe
239− |- ^- @
240− =+ haz=(muk syd (met 3 key) key)
241− =+ ham=(mix (rsh 0 31 haz) (end 0 31 haz))
242− ?.(=(0 ham) ham $(syd +(syd)))
243−```
244−
245−#### Examples
246−
247−```
248− > (mum 10.000)
249− 795.713.195
250−
251− > (mum 10.001)
252− 420.521.697
253−
254− > (mum 'jerry')
255− 1.540.161.753
256−
257− > (mum 1)
258− 1.901.865.568
259−
260− > (mum (some 10))
261− 2.099.076.946
262−
263− > (mum [1 2 3 4 5 ~])
264− 1.719.833.228
265−```
266−
267−
268188---
content/docs/hoon/reference/stdlib/2f.md+163−285
@@ -4,11 +4,11 @@ weight = 9
44template = "doc.html"
55+++
66
7−### `++aor`
7+## `++aor`
88
99Alphabetical order
1010
11−Computes whether `a` and `b` are in alphabetical order, producing a flag.
11+Computes whether `a` and `b` are in alphabetical order, producing a flag. Orders atoms before cells, and atoms in ascending LSB order.
1212
1313#### Accepts
1414
@@ -23,62 +23,85 @@ A flag.
2323#### Source
2424
2525```hoon
26− ++ aor
27− ~/ %aor
28− |= [a=* b=*]
29− ^- ?
30− ?: =(a b) &
31− ?. ?=(@ a)
32− ?: ?=(@ b) |
33− ?: =(-.a -.b)
34− $(a +.a, b +.b)
35− $(a -.a, b -.b)
36− ?. ?=(@ b) &
37− |-
38− =+ [c=(end 3 1 a) d=(end 3 1 b)]
39− ?: =(c d)
40− $(a (rsh 3 1 a), b (rsh 3 1 b))
41− (lth c d)
26+++ aor
27+ ~/ %aor
28+ |= [a=* b=*]
29+ ^- ?
30+ ?: =(a b) &
31+ ?. ?=(@ a)
32+ ?: ?=(@ b) |
33+ ?: =(-.a -.b)
34+ $(a +.a, b +.b)
35+ $(a -.a, b -.b)
36+ ?. ?=(@ b) &
37+ |-
38+ =+ [c=(end 3 a) d=(end 3 b)]
39+ ?: =(c d)
40+ $(a (rsh 3 a), b (rsh 3 b))
41+ (lth c d)
4242```
4343
4444#### Examples
4545
4646```
47− > (aor 'a' 'b')
48− %.y
49−
50− > (aor 'b' 'a')
51− %.n
52−
53− > (aor 'a' 'a')
54− %.y
55−
56− > (aor "foo" "bar")
57− %.n
58−
59− > (aor "bar" "foo")
60− %.y
47+> (aor 'a' 'b')
48+%.y
49+> (aor 'b' 'a')
50+%.n
51+> (aor 'a' 'a')
52+%.y
53+
54+> (aor 1 2)
55+%.y
56+> (aor 2 1)
57+%.n
58+
59+> (aor ['a' ~] 'b')
60+%.n
61+> (aor 'b' ['a' ~])
62+%.y
63+
64+> (aor ['a' ~] ['b' ~])
65+%.y
66+> (aor ['b' ~] ['a' ~])
67+%.n
68+
69+> (aor "abca" "abcz")
70+%.y
71+> (aor "abcz" "abca")
72+%.n
73+
74+> (aor 0b1011 0b1010)
75+%.n
76+> (aor 0b1010 0b1011)
77+%.y
78+
79+> (aor [1 2] [2 1])
80+%.y
81+> (aor [2 1] [1 2])
82+%.n
83+```
6184
62− > (aor "abcdefz" "abcdefa")
63− %.n
85+Note the possible differences with `+dor` due to comparing one byte at a time:
6486
65− > (aor "abcdefa" "abcdefz")
66− %.y
67−
68− > (aor 10.000 17.000)
69− %.y
70−
71− > (aor 10 9)
72− %.n
7387```
88+> (aor 0b1001.0000.0000 0b1000.1000.0000)
89+%.y
90+> (dor 0b1001.0000.0000 0b1000.1000.0000)
91+%.n
92+```
93+
94+#### Discussion
7495
96+This is different than [+dor](#dor) in that it compares atoms one byte at a time, while `+dor` compares whole atoms at once. Note that because it simply compares bytes, it doesn't account for multi-byte UTF-8 characters and the like.
7597
7698---
77−### `++dor`
7899
79−Numeric order
100+## `++dor`
101+
102+Depth order
80103
81−Computes whether `a` and `b` are in ascending numeric order, producing a flag.
104+Computes whether `a` and `b` are in ascending tree depth order, producing a flag. Orders atoms before cells, and atoms in ascending numerical order.
82105
83106#### Accepts
84107
@@ -93,62 +116,71 @@ A flag.
93116#### Source
94117
95118```hoon
96− ++ dor
97− ~/ %dor
98− |= [a=* b=*]
99− ^- ?
100− ?: =(a b) &
101− ?. ?=(@ a)
102− ?: ?=(@ b) |
103− ?: =(-.a -.b)
104− $(a +.a, b +.b)
105− $(a -.a, b -.b)
106− ?. ?=(@ b) &
107− (lth a b)
119+++ dor
120+ ~/ %dor
121+ |= [a=* b=*]
122+ ^- ?
123+ ?: =(a b) &
124+ ?. ?=(@ a)
125+ ?: ?=(@ b) |
126+ ?: =(-.a -.b)
127+ $(a +.a, b +.b)
128+ $(a -.a, b -.b)
129+ ?. ?=(@ b) &
130+ (lth a b)
108131```
109132
110133#### Examples
111134
112135```
113− > (dor 1 2)
114− %.y
136+> (dor 1 2)
137+%.y
115138
116− > (dor 2 1)
117− %.n
139+> (dor 2 1)
140+%.n
118141
119− > (dor ~[1 2 3] ~[1 2 4])
120− %.y
142+> (dor ~[1 2 3] ~[1 2 4])
143+%.y
121144
122− > (dor ~[1 2 4] ~[1 2 3])
123− %.n
145+> (dor ~[1 2 4] ~[1 2 3])
146+%.n
124147
125− > (dor `(list @)`~[99 100 10.000] ~[99 101 10.000])
126− %.y
148+> (dor `(list @)`~[99 100 10.000] ~[99 101 10.000])
149+%.y
127150
128− > (dor ~[99 101 10.999] `(list @)`~[99 100 10.000])
129− %.n
151+> (dor ~[99 101 10.999] `(list @)`~[99 100 10.000])
152+%.n
153+```
154+
155+Note the possible difference with [+aor](#aor) due to comparing whole atoms rather than one byte at a time:
156+
157+```
158+> (aor 0b1001.0000.0000 0b1000.1000.0000)
159+%.y
160+> (dor 0b1001.0000.0000 0b1000.1000.0000)
161+%.n
130162```
131163
132164#### Discussion
133165
134−If `a` and `b` are both atoms, `dor` is equivalent to [`lte`](/docs/hoon/reference/stdlib/1a). If they're
166+If `a` and `b` are both atoms, `dor` is equivalent to [`lte`](/docs/hoon/reference/stdlib/1a#lte). If they're
135167cells, `dor` recurses on the heads, and then if the heads are the same it checks
136168the tails.
137169
138170If one sample is a cell and the other is an atom, the cell sample is treated as
139171"greater."
140172
141−
142173---
143−### `++gor`
144174
145−Hash order
175+## `++gor`
176+
177+Mug order
146178
147179Computes whether of `(mug a)` and `(mug b)` are in ascending numeric order,
148180producing a flag. If the `mug` hashes are equal, `a` and `b` are compared by
149181`dor` instead.
150182
151−[`mug`](/docs/hoon/reference/stdlib/2e) is the the 31-bit nonzero FNV-1a hash algorithm.
183+[`mug`](/docs/hoon/reference/stdlib/2e#mug) is the the 31-bit nonzero FNV-1a hash algorithm.
152184
153185#### Accepts
154186
@@ -163,223 +195,70 @@ A flag.
163195#### Source
164196
165197```hoon
166− ++ gor
167− ~/ %gor
168− |= [a=* b=*]
169− ^- ?
170− =+ [c=(mug a) d=(mug b)]
171− ?: =(c d)
172− (dor a b)
173− (lth c d)
198+++ gor
199+ ~/ %gor
200+ |= [a=* b=*]
201+ ^- ?
202+ =+ [c=(mug a) d=(mug b)]
203+ ?: =(c d)
204+ (dor a b)
205+ (lth c d)
174206```
175207
176208#### Examples
177209
178210```
179− > (gor 'd' 'c')
180− %.y
181−
182− > 'd'
183− 'd'
184−
185− > 'c'
186− 'c'
187−
188− > `@ud`'d'
189− 100
190−
191− > `@ud`'c'
192− 99
193−
194− > (mug 'd')
195− 1.628.185.714
196−
197− > (mug 'c')
198− 1.712.073.811
199−
200− > (gor 'd' 'c')
201− %.y
202−
203− > (gor 'c' 'd')
204− %.n
205−
206− > (gor "foo" "bar")
207− %.n
208−
209− > (gor (some 10) `(list @)`[1 2 3 ~])
210− %.n
211−```
212−
213−#### Discussion
214−
215−`map`s use `gor` on the key for horizontal ordering and `vor` for
216−vertical order. `map`s only look at the keys (the head of the key-value pair
217−elements) for ordering.
218−
219−---
220−### `++hor`
221−
222−Horizontal hash order
223−
224−If `a` and `b` are atoms, they are computed as samples of `gor`, producing a
225−flag.
226−
227−If `a` and `b` are cells, `hor` checks to see if their heads are equal. If their
228−heads are equal, `gor` is computed on their tails, producing a flag. If their
229−heads are not equal, `gor` is computed on their heads, producing a flag.
230−
231−If `a` is an atom and `b` is not, then `%.y` is produced. If `b` is an atom and
232−`a` is not, `%.n` is produced.
233−
234−#### Accepts
235−
236−`a` is a noun.
237−
238−`b` is a noun.
239−
240−#### Produces
241−
242−A flag.
243−
244−#### Source
245−
246−```hoon
247− ++ hor
248− ~/ %hor
249− |= [a=* b=*]
250− ^- ?
251− ?: ?=(@ a)
252− ?. ?=(@ b) &
253− (gor a b)
254− ?: ?=(@ b) |
255− ?: =(-.a -.b)
256− (gor +.a +.b)
257− (gor -.a -.b)
258−```
259−
260−#### Examples
261−
211+> (gor 'd' 'c')
212+%.y
213+
214+> 'd'
215+'d'
216+> 'c'
217+'c'
218+
219+> `@ud`'d'
220+100
221+> `@ud`'c'
222+99
223+
224+> (mug 'd')
225+1.628.185.714
226+> (mug 'c')
227+1.712.073.811
228+
229+> (gor 'd' 'c')
230+%.y
231+> (gor 'c' 'd')
232+%.n
262233```
263− > (hor . 1)
264− %.n
265−
266− > (hor 1 2)
267− %.y
268−
269− > (hor "abc" "cba")
270− %.y
271−
272− > (hor 'c' 'd')
273− %.n
274−
275− > (hor 100 [1 1])
276− %.y
277−
278− > (hor [1 1] 100)
279− %.n
280−
281− > (hor 500.000.000 "foo")
282− %.y
283−
284− > (hor "foo" 500.000.000)
285− %.n
286−
287− > (hor 0 "foo")
288− %.y
289234
290− > (gor `(list @)`[0 ~] 1)
291− %.n
292−
293− > (hor `(list @)`[50 500 5.000 ~] 1)
294− %.n
295235```
296−
297−#### Discussion
298−
299−Sets (+set, +in) use `hor` for their horizontal order and `vor` for their
300−vertical order. See [`apt:in`](/docs/hoon/reference/stdlib/2h) to see how a set verifies its correctness.
301−`vor` is used to verify.
302−
303−---
304−### `++lor`
305−
306−Leg order
307−
308−Computes whether the corresponding legs of `a` and `b` are in ascending
309−numeric order, producing a flag.
310−
311−#### Accepts
312−
313−`a` is a noun.
314−
315−`b` is a noun.
316−
317−#### Accepts
318−
319−A flag.
320−
321−#### Source
322−
323−```hoon
324− ++ lor
325− ~/ %lor
326− |= [a=* b=*]
327− ^- ?
328− ?: =(a b) &
329− ?@ a
330− ?^ b &
331− (lth a b)
332− ?: =(-.a -.b)
333− $(a +.a, b +.b)
334− $(a -.a, b -.b)
236+> (gor "foo" "bar")
237+%.n
335238```
336239
337−#### Examples
338−
339240```
340− > (lor 1 2)
341− %.y
342−
343− > (lor 2 1)
344− %.n
345−
346− > (lor 9 [1 2])
347− %.y
348−
349− > (lor `(list @)`[1 2 3 ~] `(list @)`[1 2 3 4 ~])
350− %.y
351−
352− > (lor `(list @)`[1 2 3 ~] `(list @)`[1 2 2 ~])
353− %.n
354−
355− > (lor `(list @)`[1 2 3 ~] `(list @)`[2 2 ~])
356− %.y
357−
358− > (lor [2 2 5] [1 5 9 8])
359− %.n
360−
361− > (lor [1 5 8] [1 5 9 8])
362− %.y
363−
364− > (lor [1 2 3] [1 2])
365− !! exit
241+> (gor (some 10) `(list @)`[1 2 3 ~])
242+%.n
366243```
367244
368245#### Discussion
369246
370−`lor` is no longer used internally.
247+`map`s use `gor` on the key for horizontal ordering and `mor` for
248+vertical order. `map`s only look at the keys (the head of the key-value pair
249+elements) for ordering.
371250
372251---
373−### `++vor`
374252
375−Vertical order
253+## `++mor`
254+
255+(more) mug order
376256
377257Computes whether the double-hashes `(mug (mug a))` and `(mug (mug b))` are in
378258ascending numeric order, producing a flag. If the double-`mug` hashes are
379259equal, `a` and `b` are compared by `dor` instead.
380260
381−[`mug`](/docs/hoon/reference/stdlib/2e) is the the 31-bit nonzero FNV-1a hash algorithm.
382−
261+[`mug`](/docs/hoon/reference/stdlib/2e#mug) is the the 31-bit nonzero FNV-1a hash algorithm.
383262
384263#### Accepts
385264
@@ -394,20 +273,20 @@ A flag.
394273#### Source
395274
396275```hoon
397− ++ vor
398− ~/ %vor
399− |= [a=* b=*]
400− ^- ?
401− =+ [c=(mug (mug a)) d=(mug (mug b))]
402− ?: =(c d)
403− (dor a b)
404− (lth c d)
276+++ mor
277+ ~/ %mor
278+ |= [a=* b=*]
279+ ^- ?
280+ =+ [c=(mug (mug a)) d=(mug (mug b))]
281+ ?: =(c d)
282+ (dor a b)
283+ (lth c d)
405284```
406285
407286#### Examples
408287
409288```
410− > (vor 'f' 'g')
289+ > (mor 'f' 'g')
411290 %.y
412291
413292 > [(mug 'f') (mug 'g')]
@@ -416,22 +295,21 @@ A flag.
416295 > [(mug (mug 'f')) (mug (mug 'g'))]
417296 [261.421.509 1.861.258.547]
418297
419− > (vor 'a' 'z')
298+ > (mor 'a' 'z')
420299 %.n
421300
422− > (vor 43.326 41.106)
301+ > (mor 43.326 41.106)
423302 %.n
424303```
425304
426305#### Discussion
427306
428−Maps, sets, and queues all use `vor` to check for vertical ordering. Maps and
429−sets also use `gor` and `hor` for horizontal order, respectively, but queues use
307+Maps, sets, and queues all use `mor` to check for vertical ordering. Maps and
308+sets also use `gor` for horizontal order, but queues use
430309vertical ordering alone.
431310
432−Since hashing removes correlation, double-`mug`ging with `vor` removes
433−correlation with single-`mug`ged `hor`. Vertical order becomes uncorrelated
311+Since hashing removes correlation, double-`mug`ging with `mor` removes
312+correlation with single-`mug`ged `gor`. Vertical order becomes uncorrelated
434313with horizontal order.
435314
436−
437−---
315+---
content/docs/hoon/reference/stdlib/2g.md+26−26
@@ -4,7 +4,7 @@ weight = 10
44template = "doc.html"
55+++
66
7−### `++pow`
7+## `++pow`
88
99Computes `a` raised to the power of `b`, producing an atom.
1010
@@ -21,14 +21,14 @@ An atom.
2121#### Source
2222
2323```hoon
24− ++ pow
25− ~/ %pow
26− |= [a=@ b=@]
27− ?: =(b 0) 1
28− |- ?: =(b 1) a
29− =+ c=$(b (div b 2))
30− =+ d=(mul c c)
31− ?~ (dis b 1) d (mul d a)
24+++ pow
25+ ~/ %pow
26+ |= [a=@ b=@]
27+ ?: =(b 0) 1
28+ |- ?: =(b 1) a
29+ =+ c=$(b (div b 2))
30+ =+ d=(mul c c)
31+ ?~ (dis b 1) d (mul d a)
3232```
3333
3434#### Examples
@@ -51,7 +51,8 @@ An atom.
5151```
5252
5353---
54−### `++sqt`
54+
55+## `++sqt`
5556
5657Computes the square root of `a` and its remainder.
5758
@@ -66,20 +67,20 @@ A cell of atoms.
6667#### Source
6768
6869```hoon
69− ++ sqt
70− ~/ %sqt
71− |= a=@ ^- [p=@ q=@]
72− ?~ a [0 0]
73− =+ [q=(div (dec (xeb a)) 2) r=0]
74− =- [-.b (sub a +.b)]
75− ^= b |-
76− =+ s=(add r (bex q))
77− =+ t=(mul s s)
78− ?: =(q 0)
79− ?:((lte t a) [s t] [r (mul r r)])
80− ?: (lte t a)
81− $(r s, q (dec q))
82− $(q (dec q))
70+++ sqt
71+ ~/ %sqt
72+ |= a=@ ^- [p=@ q=@]
73+ ?~ a [0 0]
74+ =+ [q=(div (dec (xeb a)) 2) r=0]
75+ =- [-.b (sub a +.b)]
76+ ^= b |-
77+ =+ s=(add r (bex q))
78+ =+ t=(mul s s)
79+ ?: =(q 0)
80+ ?:((lte t a) [s t] [r (mul r r)])
81+ ?: (lte t a)
82+ $(r s, q (dec q))
83+ $(q (dec q))
8384```
8485
8586#### Examples
@@ -101,5 +102,4 @@ A cell of atoms.
101102 ! exit
102103```
103104
104−
105−---
105+---
content/docs/hoon/reference/stdlib/2h.md+345−345
@@ -4,7 +4,7 @@ weight = 11
44template = "doc.html"
55+++
66
7−### `++in`
7+## `++in`
88
99Set operations
1010
@@ -18,16 +18,16 @@ A `set`.
1818#### Source
1919
2020```hoon
21− ++ in
22− ~/ %in
23− |_ a=(set)
21+ ~/ %in
22+ =| a=(tree)
23+ |@
2424```
2525
2626#### Examples
2727
2828```
29− > ~(. in (sy "asd"))
30− <13.evb [nlr(^$1{@tD $1}) <414.fvk 101.jzo 1.ypj %164>]>
29+> ~(. in (sy "asd"))
30+<16.ufw [a=?(%~ [?(n=@tD n=#1) l=nlr(?(@tD #1)) r=nlr(?(@tD ^#1.?(@tD #1)))]) <123.zao 46.hgz 1.pnw %140>]>
3131```
3232
3333### `++all:in`
@@ -39,9 +39,9 @@ flag.
3939
4040#### Accepts
4141
42−`a` is a `set`.
42+`a` is a `set`, and is the sample of `+in`.
4343
44−`b` is a wet gate that accepts a noun and produces a flag.
44+`b` is a gate that accepts a noun and produces a flag.
4545
4646#### Produces
4747
@@ -50,28 +50,27 @@ A flag.
5050#### Source
5151
5252```hoon
53− ++ all :: logical AND
54− ~/ %all
55− |* b=$-(* ?)
56− |- ^- ?
57− ?~ a
58− &
59− ?&((b n.a) $(a l.a) $(a r.a))
53+++ all
54+ ~/ %all
55+ |* b=$-(* ?)
56+ |- ^- ?
57+ ?~ a
58+ &
59+ ?&((b n.a) $(a l.a) $(a r.a))
6060```
6161
6262#### Examples
6363
6464```
65− > =b (sy `(list [@t *])`[['a' 1] ['b' [2 3]] ~])
66− > (~(all in b) |=(a=* ?@(+.a & |)))
67− %.n
65+> (~(all in (silt ~[1 2 3 4])) |=(a=@ (lth a 5)))
66+%.y
6867
69− > =b (sy `(list @t)`['john' 'bonita' 'daniel' 'madeleine' ~])
70− > (~(all in b) |=(a=@t (gte a 100)))
71− %.y
68+> (~(all in (silt ~[1 2 3 4 5])) |=(a=@ (lth a 5)))
69+%.n
7270```
7371
7472---
73+
7574### `++any:in`
7675
7776Logical OR
@@ -81,7 +80,7 @@ flag.
8180
8281#### Accepts
8382
84−`a` is a `set`.
83+`a` is a `set`, and is the sample of `+in`.
8584
8685`b` is a gate that accepts a noun and produces a flag.
8786
@@ -92,28 +91,27 @@ A flag.
9291#### Source
9392
9493```hoon
95− ++ any :: logical OR
96− ~/ %any
97− |* b=$-(* ?)
98− |- ^- ?
99− ?~ a
100− |
101− ?|((b n.a) $(a l.a) $(a r.a))
94+++ any
95+ ~/ %any
96+ |* b=$-(* ?)
97+ |- ^- ?
98+ ?~ a
99+ |
100+ ?|((b n.a) $(a l.a) $(a r.a))
102101```
103102
104103#### Examples
105104
106105```
107− > =b (sy `(list [@t *])`[['a' 1] ['b' [2 3]] ~])
108− > (~(any in b) |=(a/* ?@(+.a & |)))
109− %.y
106+> (~(any in (silt ~[2 3 4 5])) |=(a=@ (lth a 3)))
107+%.y
110108
111− > =b (sy `(list @t)`['john' 'bonita' 'daniel' 'madeleine' ~])
112− > (~(any in b) |=(a=@t (lte a 100)))
113− %.n
109+> (~(any in (silt ~[3 4 5])) |=(a=@ (lth a 3)))
110+%.n
114111```
115112
116113---
114+
117115### `++apt:in`
118116
119117Check correctness
@@ -132,36 +130,38 @@ A flag.
132130#### Source
133131
134132```hoon
135− ++ apt :: check correctness
136− =< $
137− ~/ %apt
138− =| [l=(unit) r=(unit)]
139− |. ^- ?
140− ?~ a &
141− ?& ?~(l & (gor n.a u.l))
142− ?~(r & (gor u.r n.a))
143− ?~(l.a & ?&((mor n.a n.l.a) $(a l.a, l `n.a)))
144− ?~(r.a & ?&((mor n.a n.r.a) $(a r.a, r `n.a)))
145− ==
133+++ apt
134+ =< $
135+ ~/ %apt
136+ =| [l=(unit) r=(unit)]
137+ |. ^- ?
138+ ?~ a &
139+ ?& ?~(l & (gor n.a u.l))
140+ ?~(r & (gor u.r n.a))
141+ ?~(l.a & ?&((mor n.a n.l.a) $(a l.a, l `n.a)))
142+ ?~(r.a & ?&((mor n.a n.r.a) $(a r.a, r `n.a)))
143+ ==
146144```
147145
148146#### Examples
149147
150148```
151− > ~(apt in ~)
152− %.y
149+> ~(apt in ~)
150+%.y
151+```
153152
154− > =a (sy [1 2 3 4 5 6 ~])
155− > a
156− [n=6 l={5 4} r={1 3 2}]
157− > ~(apt in a)
158− %.y
153+```
154+> =a (silt ~[1 2 3])
155+> a
156+[n=2 l={1} r={3}]
157+> ~(apt in a)
158+%.y
159159
160− > =z ?~ a ~ a(n 7)
161− > z
162− [n=7 l={5 4} r={1 3 2}]
163− > ~(apt in z)
164− %.n
160+> =z ?~(a ~ a(n 10))
161+> z
162+[n=10 l={1} r={3}]
163+> ~(apt in z)
164+%.n
165165```
166166
167167#### Discussion
@@ -169,15 +169,16 @@ A flag.
169169See section [`2f`](/docs/hoon/reference/stdlib/2f) for more information on noun ordering.
170170
171171---
172+
172173### `++bif:in`
173174
174175Bifurcate
175176
176−Splits set `a` into two sets `l` and `r`, with any noun `b` removed.
177+Splits set `a` into sets `l` and `r`, which contain the items either side of `b` but not including `b`.
177178
178179#### Accepts
179180
180−`a` is a set.
181+`a` is a set, and is the sample of `+in`.
181182
182183`b` is a noun.
183184
@@ -188,40 +189,45 @@ A cell of two sets.
188189#### Source
189190
190191```hoon
191− ++ bif :: splits a by b
192− ~/ %bif
193− |* b=*
194− ^+ [l=a r=a]
195− =< +
196− |- ^+ a
197− ?~ a
198− [b ~ ~]
199− ?: =(b n.a)
200− a
201− ?: (gor b n.a)
202− =+ c=$(a l.a)
203− ?> ?=(^ c)
204− c(r a(l r.c))
205− =+ c=$(a r.a)
192+++ bif
193+ ~/ %bif
194+ |* b=*
195+ ^+ [l=a r=a]
196+ =< +
197+ |- ^+ a
198+ ?~ a
199+ [b ~ ~]
200+ ?: =(b n.a)
201+ a
202+ ?: (gor b n.a)
203+ =+ c=$(a l.a)
206204 ?> ?=(^ c)
207− c(l a(r l.c))
205+ c(r a(l r.c))
206+ =+ c=$(a r.a)
207+ ?> ?=(^ c)
208+ c(l a(r l.c))
208209```
209210
210211#### Examples
211212
212213```
213− > =a (sy `(list @)`[1 2 3 4 5 6 ~])
214− > a
215− [n=6 l={5 4} r={1 3 2}]
214+> =a `(set @)`(silt (gulf 1 20))
215+> a
216+{17 8 20 13 11 5 19 7 15 10 18 14 6 12 9 1 2 3 16 4}
216217
217− > (~(bif in a) 6)
218− [l=[n=4 l=[n=5 l={} r={}] r=~] r=[n=2 l=[n=1 l={} r={3}] r=~]]
218+> (~(bif in a) 10)
219+[l=[n=11 l={17 8 20 13} r={5 19 7 15}] r=[n=12 l={18 14 6} r={9 1 2 3 16 4}]]
219220
220− > (~(bif in a) 100)
221− [l=[n=6 l=[n=4 l={5} r={}] r=[n=2 l={1 3} r={}]] r=~]
221+> `[(set @) (set @)]`(~(bif in a) 10)
222+[{17 8 20 13 11 5 19 7 15} {18 14 6 12 9 1 2 3 16 4}]
222223```
223224
225+#### Discussion
226+
227+Note that `set`s are horizontally ordered by the [mug](/docs/hoon/reference/stdlib/2e#mug) hash of their items and vertically ordered by the double-`mug` hash of their items. This means bifurcating the set of numbers `(silt ~[10 20 30 40 50])` at `30` will not produce `[{10 20} {40 50}]`, but rather `[{20} {10 40 50}]` due to the tree structure resulting from their `mug` hashes.
228+
224229---
230+
225231### `++del:in`
226232
227233Remove noun
@@ -230,7 +236,7 @@ Removes `b` from the `set` `a`.
230236
231237#### Accepts
232238
233−`a` is a set.
239+`a` is a set, and is the sample of `+in`.
234240
235241`b` is a noun.
236242
@@ -241,41 +247,48 @@ A set.
241247#### Source
242248
243249```hoon
244− ++ del :: b without any a
245− ~/ %del
246− |* b=*
247− |- ^+ a
248− ?~ a
249− ~
250− ?. =(b n.a)
251− ?: (gor b n.a)
252− a(l $(a l.a))
253− a(r $(a r.a))
254− |- ^- [$?(~ _a)]
255− ?~ l.a r.a
256− ?~ r.a l.a
257− ?: (mor n.l.a n.r.a)
258− l.a(r $(l.a r.l.a))
259− r.a(l $(r.a l.r.a))
250+++ del
251+ ~/ %del
252+ |* b=*
253+ |- ^+ a
254+ ?~ a
255+ ~
256+ ?. =(b n.a)
257+ ?: (gor b n.a)
258+ a(l $(a l.a))
259+ a(r $(a r.a))
260+ |- ^- [$?(~ _a)]
261+ ?~ l.a r.a
262+ ?~ r.a l.a
263+ ?: (mor n.l.a n.r.a)
264+ l.a(r $(l.a r.l.a))
265+ r.a(l $(r.a l.r.a))
260266```
261267
262−
263268#### Examples
264269
265270```
266− > =b (sy `(list @t)`['a' 'b' 'c' ~])
267− > (~(del in b) 'a')
268− [n='b' l=[n='c' l={} r={}] r=~]
271+> `(set @)`(~(del in (silt ~[1 2 3 4 5])) 3)
272+{5 1 2 4}
273+```
269274
270− > =b (sy `(list @t)`['john' 'bonita' 'daniel' 'madeleine' ~])
271− > (~(del in b) 'john')
272− [n='madeleine' l=[n='daniel' l={} r={'bonita'}] r=~]
275+```
276+> `(set @t)`(~(del in (silt ~['foo' 'bar' 'baz'])) 'bar')
277+{'baz' 'foo'}
278+```
273279
274− > (~(del in b) 'susan')
275− [n='madeleine' l=[n='daniel' l={} r={'bonita'}] r=[n='john' l={} r={}]]
280+```
281+> `(set @)`(~(del in (silt ~[1 2 3 4 5])) 10)
282+{5 1 2 3 4}
283+```
284+
285+```
286+> `(set @)`(~(del in ~) 10)
287+{}
276288```
277289
278290---
291+
279292### `++dif:in`
280293
281294Difference
@@ -285,7 +298,7 @@ that are not in `b`.
285298
286299#### Accepts
287300
288−`a` is a set.
301+`a` is a set, and is the sample of `+in`.
289302
290303`b` is a set.
291304
@@ -296,46 +309,39 @@ A set.
296309#### Source
297310
298311```hoon
299− ++ dif :: difference
300− ~/ %dif
301− =+ b=a
302− |@
303− ++ $
304− |- ^+ a
305− ?~ b
306− a
307− =+ c=(bif n.b)
308− ?> ?=(^ c)
309− =+ d=$(a l.c, b l.b)
310− =+ e=$(a r.c, b r.b)
311− |- ^- [$?(~ _a)]
312− ?~ d e
313− ?~ e d
314− ?: (mor n.d n.e)
315− d(r $(d r.d))
316− e(l $(e l.e))
317− --
312+++ dif
313+ ~/ %dif
314+ =+ b=a
315+ |@
316+ ++ $
317+ |- ^+ a
318+ ?~ b
319+ a
320+ =+ c=(bif n.b)
321+ ?> ?=(^ c)
322+ =+ d=$(a l.c, b l.b)
323+ =+ e=$(a r.c, b r.b)
324+ |- ^- [$?(~ _a)]
325+ ?~ d e
326+ ?~ e d
327+ ?: (mor n.d n.e)
328+ d(r $(d r.d))
329+ e(l $(e l.e))
330+ --
318331```
319332
320333#### Examples
321334
322335```
323− > =c (sy 1 2 3 ~)
324− > =d (sy 2 3 4 ~)
325− > (~(dif in c) d)
326− [n=1 l=~ r=~]
336+> =a (silt ~[1 2 3 4 5])
337+> =b (silt ~[3 4])
327338
328− > (~(dif in d) c)
329− [n=4 l=~ r=~]
330−
331− > `(set @ud)`(~(dif in c) d)
332− {1}
333−
334− > `(set @ud)`(~(dif in d) c)
335− {4}
339+> `(set @)`(~(dif in a) b)
340+{5 1 2}
336341```
337342
338343---
344+
339345### `++dig:in`
340346
341347Address b in a
@@ -344,7 +350,7 @@ Produce the tree address of `b` within `a`.
344350
345351#### Accepts
346352
347−`a` is a set.
353+`a` is a set, and is the sample of `+in`.
348354
349355`b` is a noun.
350356
@@ -355,36 +361,36 @@ The `unit` of an atom.
355361#### Source
356362
357363```hoon
358− ++ dig :: axis of a in b
359− |= b=*
360− =+ c=1
361− |- ^- (unit @)
362− ?~ a ~
363− ?: =(b n.a) [~ u=(peg c 2)]
364− ?: (gor b n.a)
365− $(a l.a, c (peg c 6))
366− $(a r.a, c (peg c 7))
364+++ dig
365+ |= b=*
366+ =+ c=1
367+ |- ^- (unit @)
368+ ?~ a ~
369+ ?: =(b n.a) [~ u=(peg c 2)]
370+ ?: (gor b n.a)
371+ $(a l.a, c (peg c 6))
372+ $(a r.a, c (peg c 7))
367373```
368374
369−
370375#### Examples
371376
372377```
373− > =a (sy `(list @)`[1 2 3 4 5 6 7 ~])
374− > `(set @)`a
375− {5 4 7 6 1 3 2}
378+> =a (silt ~[1 2 3 4 5 6 7])
376379
377− > -.a
378− n=6
380+> -.a
381+n=6
379382
380− > (~(dig in a) 7)
381− [~ u=12]
383+> (~(dig in a) 7)
384+[~ 12]
382385
383− > (~(dig in a) 2)
384− [~ u=14]
386+> (~(dig in a) 2)
387+[~ 60]
385388
386− > (~(dig in a) 6)
387− [~ u=2]
389+> (~(dig in a) 6)
390+[~ 2]
391+
392+> (~(dig in a) 10)
393+~
388394```
389395
390396#### Discussion
@@ -392,6 +398,7 @@ The `unit` of an atom.
392398For more on the tree addressing system, see section [1b](/docs/hoon/reference/stdlib/1b).
393399
394400---
401+
395402### `++gas:in`
396403
397404Concatenate
@@ -400,7 +407,7 @@ Insert the elements of a `list` `b` into a `set` `a`.
400407
401408#### Accepts
402409
403−`a` is a set.
410+`a` is a set, and is the sample of `+in`.
404411
405412`b` is a list.
406413
@@ -411,31 +418,31 @@ A `set`.
411418#### Source
412419
413420```hoon
414− ++ gas :: concatenate
415− ~/ %gas
416− |= b=(list _?>(?=(^ a) n.a))
417− |- ^+ a
418− ?~ b
419− a
420− $(b t.b, a (put i.b))
421+++ gas
422+ ~/ %gas
423+ |= b=(list _?>(?=(^ a) n.a))
424+ |- ^+ a
425+ ?~ b
426+ a
427+ $(b t.b, a (put i.b))
421428```
422429
423430#### Examples
424431
425432```
426− > =b `(set @t)`(sy `(list @t)`['bonita' 'madeleine' 'rudolf' 'john' ~])
427− > b
428− {'bonita' 'madeleine' 'rudolf' 'john'}
433+> =a (silt ~['foo' 'bar' 'baz'])
434+> `(set @t)`a
435+{'bar' 'baz' 'foo'}
429436
430− > (~(gas in b) `(list @t)`['14' 'things' 'number' '1.337' ~])
431− [n='number' l={'1.337' '14'} r={'things' 'bonita' 'madeleine' 'rudolf' 'john'}]
437+> `(set @t)`(~(gas in a) ~['foo' 'foo' 'foo' 'foo'])
438+{'bar' 'baz' 'foo'}
432439
433− > =s (sy `(list @t)`['a' 'b' 'c' 'd' 'e' ~])
434− > (~(gas in s) `(list @t)`['1' '2' '3' ~])
435− [n='e' l=[n='1' l={} r={'3' '2'}] r=[n='b' l={'d' 'a' 'c'} r={}]]
440+> `(set @t)`(~(gas in a) ~['abc' 'xyz' '123'])
441+{'xyz' 'bar' 'baz' 'foo' 'abc' '123'}
436442```
437443
438444---
445+
439446### `++has:in`
440447
441448b in a?
@@ -444,7 +451,7 @@ Checks if `b` is an element of `a`, producing a flag.
444451
445452#### Accepts
446453
447−`a` is a set.
454+`a` is a set, and is the sample of `+in`.
448455
449456`b` is a noun.
450457
@@ -455,46 +462,37 @@ A flag.
455462#### Source
456463
457464```hoon
458− ++ has
459− ~/ %has
460− |* b=*
461− ^- ?
462− :: wrap extracted item type in a unit because bunting fails
463− ::
464− :: If we used the real item type of _?^(a n.a !!) as the sample type,
465− :: then hoon would bunt it to create the default sample for the gate.
466− ::
467− :: However, bunting that expression fails if :a is ~. If we wrap it
468− :: in a unit, the bunted unit doesn't include the bunted item type.
469− ::
470− :: This way we can ensure type safety of :b without needing to perform
471− :: this failing bunt. It's a hack.
472− ::
473− %. [~ b]
474− |= b=(unit _?>(?=(^ a) n.a))
475− => .(b ?>(?=(^ b) u.b))
476− |- ^- ?
477− ?~ a
478− |
479− ?: =(b n.a)
480− &
481− ?: (gor b n.a)
482− $(a l.a)
483− $(a r.a)
465+++ has
466+ ~/ %has
467+ |* b=*
468+ ^- ?
469+ %. [~ b]
470+ |= b=(unit _?>(?=(^ a) n.a))
471+ => .(b ?>(?=(^ b) u.b))
472+ |- ^- ?
473+ ?~ a
474+ |
475+ ?: =(b n.a)
476+ &
477+ ?: (gor b n.a)
478+ $(a l.a)
479+ $(a r.a)
484480```
485481
486482#### Examples
487483
488484```
489− > =a (~(gas in `(set @t)`~) `(list @t)`['a' 'b' 'c' ~])
490− > (~(has in a) 'a')
491− %.y
485+> =a (silt ~[1 2 3 4 5])
492486
493− > (~(has in a) 'z')
494− %.n
487+> (~(has in a) 2)
488+%.y
489+
490+> (~(has in a) 6)
491+%.n
495492```
496493
497494---
495+
498496### `++int:in`
499497
500498Intersection
@@ -504,7 +502,7 @@ Produces a set of the intersection between two sets of the same type,
504502
505503#### Accepts
506504
507−`a` is a set.
505+`a` is a set, and is the sample of `+in`.
508506
509507`b` is a set.
510508
@@ -515,41 +513,41 @@ A `set`.
515513#### Source
516514
517515```hoon
518− ++ int :: intersection
519− ~/ %int
520− =+ b=a
521− |@
522− ++ $
523− |- ^+ a
524− ?~ b
525− ~
526− ?~ a
527− ~
528− ?. (mor n.a n.b)
529− $(a b, b a)
530− ?: =(n.b n.a)
531− a(l $(a l.a, b l.b), r $(a r.a, b r.b))
532− ?: (gor n.b n.a)
533− %- uni(a $(a l.a, r.b ~)) $(b r.b)
534− %- uni(a $(a r.a, l.b ~)) $(b l.b)
535− --
516+++ int
517+ ~/ %int
518+ =+ b=a
519+ |@
520+ ++ $
521+ |- ^+ a
522+ ?~ b
523+ ~
524+ ?~ a
525+ ~
526+ ?. (mor n.a n.b)
527+ $(a b, b a)
528+ ?: =(n.b n.a)
529+ a(l $(a l.a, b l.b), r $(a r.a, b r.b))
530+ ?: (gor n.b n.a)
531+ %- uni(a $(a l.a, r.b ~)) $(b r.b)
532+ %- uni(a $(a r.a, l.b ~)) $(b l.b)
533+ --
536534```
537535
538−
539536#### Examples
540537
541538```
542− > (~(int in `(set @t)`(sy "acmo")) `(set @t)`(sy "ham"))
543− [n='m' l={'a'} r={}]
539+> `(set @tD)`(~(int in (silt "foobar")) (silt "bar"))
540+{'r' 'b' 'a'}
544541
545− > (~(int in (sy "acmo")) ~)
546− ~
542+> `(set @tD)`(~(int in (silt "foobar")) ~)
543+{}
547544
548− > (~(int in `(set @t)`(sy "ac")) `(set @t)`(sy "ha"))
549− [n='a' l={} r={}]
545+> `(set @tD)`(~(int in (silt "foobar")) (silt "baz"))
546+{'b' 'a'}
550547```
551548
552549---
550+
553551### `++put:in`
554552
555553Put b in a
@@ -558,7 +556,7 @@ Add an element `b` to the set `a`, producing a set.
558556
559557#### Accepts
560558
561−`a` is a set.
559+`a` is a set, and is the sample of `+in`.
562560
563561`b` is a noun.
564562
@@ -569,49 +567,48 @@ A `set`.
569567#### Source
570568
571569```hoon
572− ++ put :: puts b in a, sorted
573− ~/ %put
574− |* b=*
575− |- ^+ a
576− ?~ a
577− [b ~ ~]
578− ?: =(b n.a)
579− a
580− ?: (gor b n.a)
581− =+ c=$(a l.a)
582− ?> ?=(^ c)
583− ?: (mor n.a n.c)
584− a(l c)
585− c(r a(l r.c))
586− =+ c=$(a r.a)
570+++ put
571+ ~/ %put
572+ |* b=*
573+ |- ^+ a
574+ ?~ a
575+ [b ~ ~]
576+ ?: =(b n.a)
577+ a
578+ ?: (gor b n.a)
579+ =+ c=$(a l.a)
587580 ?> ?=(^ c)
588581 ?: (mor n.a n.c)
589− a(r c)
590− c(l a(r l.c))
582+ a(l c)
583+ c(r a(l r.c))
584+ =+ c=$(a r.a)
585+ ?> ?=(^ c)
586+ ?: (mor n.a n.c)
587+ a(r c)
588+ c(l a(r l.c))
591589```
592590
593591#### Examples
594592
595593```
596− > =a (~(gas in `(set @t)`~) `(list @t)`['a' 'b' 'c' ~])
597− > =b (~(put in a) 'd')
598− > `(set @t)`b
599− {'d' 'a' 'c' 'b'}
594+> `(set @)`(~(put in (silt ~[1 2 3])) 4)
595+{1 2 3 4}
600596
601− > -.l.+.b
602− n='d'
597+> `(set @)`(~(put in `(set @)`~) 42)
598+{42}
603599```
604600
605601---
602+
606603### `++rep:in`
607604
608605Accumulate
609606
610−Accumulate the elements of `a` using a gate `b`.
607+Accumulate the elements of `a` using binary gate `b`.
611608
612609#### Accepts
613610
614−`a` is a `set`.
611+`a` is a `set`, and is the sample of `+in`.
615612
616613`b` is a gate.
617614
@@ -622,26 +619,28 @@ A noun.
622619#### Source
623620
624621```hoon
625− ++ rep :: reduce to product
626− ~/ %rep
627− |* b=_=>(~ |=([* *] +<+))
628− |-
629− ?~ a +<+.b
630− $(a r.a, +<+.b $(a l.a, +<+.b (b n.a +<+.b)))
622+++ rep
623+ ~/ %rep
624+ |* b=_=>(~ |=([* *] +<+))
625+ |-
626+ ?~ a +<+.b
627+ $(a r.a, +<+.b $(a l.a, +<+.b (b n.a +<+.b)))
631628```
632629
633630#### Examples
634631
635632```
636− > =a (~(gas in *(set @)) [1 2 3 ~])
637− > `(set @)`a
638− {1 3 2}
633+> (~(rep in (silt ~[1 2 3 4 5])) add)
634+b=15
635+```
639636
640− > (~(rep in a) |=([a=@ b=@] (add a b)))
641− b=6
637+```
638+> `@t`(~(rep in (silt ~['foo' 'bar' 'baz'])) |=(a=[@ @] (cat 3 a)))
639+'foobarbaz'
642640```
643641
644642---
643+
645644### `++run:in`
646645
647646Apply gate to set
@@ -662,28 +661,29 @@ A set.
662661#### Source
663662
664663```hoon
665− ++ run :: apply gate to values
666− ~/ %run
667− |* b=gate
668− =+ c=`(set _?>(?=(^ a) (b n.a)))`~
669− |- ?~ a c
670− =. c (~(put in c) (b n.a))
671− =. c $(a l.a, c c)
672− $(a r.a, c c)
664+++ run
665+ ~/ %run
666+ |* b=gate
667+ =+ c=`(set _?>(?=(^ a) (b n.a)))`~
668+ |- ?~ a c
669+ =. c (~(put in c) (b n.a))
670+ =. c $(a l.a, c c)
671+ $(a r.a, c c)
673672```
674673
675674#### Examples
676675
677676```
678− > =s (sy ~["a" "A" "b" "c"])
679− > `(set tape)`s
680− {"A" "a" "c" "b"}
677+> =s (silt ~["a" "A" "b" "c"])
678+> `(set tape)`s
679+{"A" "a" "c" "b"}
681680
682− > (~(run in s) cuss)
683− {"A" "C" "B"}
681+> (~(run in s) cuss)
682+{"A" "C" "B"}
684683```
685684
686685---
686+
687687### `++tap:in`
688688
689689Set to list
@@ -701,29 +701,30 @@ A list.
701701#### Source
702702
703703```hoon
704− ++ tap :: convert to list
705− =< $
706− ~/ %tap
707− =+ b=`(list _?>(?=(^ a) n.a))`~
708− |. ^+ b
709− ?~ a
710− b
711− $(a r.a, b [n.a $(a l.a)])
704+++ tap
705+ =< $
706+ ~/ %tap
707+ =+ b=`(list _?>(?=(^ a) n.a))`~
708+ |. ^+ b
709+ ?~ a
710+ b
711+ $(a r.a, b [n.a $(a l.a)])
712712```
713713
714−
715714#### Examples
716715
717716```
718− > =s (sy `(list @t)`['a' 'b' 'c' 'd' 'e' ~])
719− > s
720− [n='e' l={} r={'d' 'a' 'c' 'b'}]
717+> ~(tap in (silt "foobar"))
718+"oafbr"
719+```
721720
722− > ~(tap in s)
723− ~['b' 'c' 'a' 'd' 'e']
721+```
722+> ~(tap in (silt ~[1 2 3 4 5]))
723+~[4 3 2 1 5]
724724```
725725
726726---
727+
727728### `++uni:in`
728729
729730Union
@@ -733,7 +734,7 @@ Produces a set of the union between two sets of the same type, `a` and
733734
734735#### Accepts
735736
736−`a` is a set.
737+`a` is a set, and is the sample of `+in`.
737738
738739`b` is a set.
739740
@@ -744,47 +745,47 @@ A set.
744745#### Source
745746
746747```hoon
747− ++ uni :: union
748− ~/ %uni
749− =+ b=a
750− |@
751− ++ $
752− ?: =(a b) a
753− |- ^+ a
754− ?~ b
755− a
756− ?~ a
757− b
758− ?: =(n.b n.a)
759− b(l $(a l.a, b l.b), r $(a r.a, b r.b))
760− ?: (mor n.a n.b)
761− ?: (gor n.b n.a)
762− $(l.a $(a l.a, r.b ~), b r.b)
763− $(r.a $(a r.a, l.b ~), b l.b)
764− ?: (gor n.a n.b)
765− $(l.b $(b l.b, r.a ~), a r.a)
766− $(r.b $(b r.b, l.a ~), a l.a)
767− --
748+++ uni
749+ ~/ %uni
750+ =+ b=a
751+ |@
752+ ++ $
753+ ?: =(a b) a
754+ |- ^+ a
755+ ?~ b
756+ a
757+ ?~ a
758+ b
759+ ?: =(n.b n.a)
760+ b(l $(a l.a, b l.b), r $(a r.a, b r.b))
761+ ?: (mor n.a n.b)
762+ ?: (gor n.b n.a)
763+ $(l.a $(a l.a, r.b ~), b r.b)
764+ $(r.a $(a r.a, l.b ~), b l.b)
765+ ?: (gor n.a n.b)
766+ $(l.b $(b l.b, r.a ~), a r.a)
767+ $(r.b $(b r.b, l.a ~), a l.a)
768+ --
768769```
769770
770−
771771#### Examples
772772
773773```
774− > (~(uni in `(set @t)`(sy "ac")) `(set @)`(sy "ha"))
775− [n='c' l={'a'} r={'h'}]
774+> =a (silt ~[1 2 3 4 5])
775+> =b (silt ~[4 5 6 7 8])
776776
777− > (~(uni in `(set @t)`(sy "acmo")) ~)
778− [n='c' l={'a'} r={'m' 'o'}]
777+> `(set @)`(~(uni in a) b)
778+{8 5 7 6 1 2 3 4}
779779
780− > (~(uni in `(set @t)`(sy "acmo")) `(set @t)`(sy "ham"))
781− [n='c' l={'a'} r={'m' 'o' 'h'}]
780+> `(set @)`(~(uni in a) ~)
781+{5 1 2 3 4}
782782
783− > (~(uni in `(set @t)`(sy "acmo")) `(set @t)`(sy "lep"))
784− [n='e' l={} r={'a' 'c' 'm' 'l' 'o' 'p'}]
783+> `(set @)`(~(uni in `(set @)`~) b)
784+{8 5 7 6 4}
785785```
786786
787787---
788+
788789### `++wyt:in`
789790
790791Set size
@@ -802,25 +803,24 @@ An atom.
802803#### Source
803804
804805```hoon
805− ++ wyt :: size of set
806− =< $
807− ~% %wyt + ~
808− |. ^- @
809− ?~(a 0 +((add $(a l.a) $(a r.a))))
810− --
806+++ wyt
807+ =< $
808+ ~% %wyt + ~
809+ |. ^- @
810+ ?~(a 0 +((add $(a l.a) $(a r.a))))
811+--
811812```
812813
813−
814814#### Examples
815815
816816```
817− > =a (~(put in (~(put in (sy)) 'a')) 'b')
818− > ~(wyt in a)
819− 2
817+> ~(wyt in (silt ~[1 2 3 4]))
818+4
819+```
820820
821− > =b (sy `(list @t)`['john' 'bonita' 'daniel' 'madeleine' ~])
822− > ~(wyt in b)
823− 4
821+```
822+> ~(wyt in `(set @)`~)
823+0
824824```
825825
826826---
content/docs/hoon/reference/stdlib/2i.md+720−436

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2j.md+263−155

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2k.md+191−135

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2l.md+5−3

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2m.md+40−32

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2n.md+152−138

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2o.md+99−86

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2p.md+125−119

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2q.md+350−139

This diff is too big to show here.

content/docs/hoon/reference/stdlib/3a.md+259−237

This diff is too big to show here.

content/docs/hoon/reference/stdlib/3b.md+1583−1418

This diff is too big to show here.

content/docs/hoon/reference/stdlib/3c.md+260−245

This diff is too big to show here.

content/docs/hoon/reference/stdlib/3d.md+455−456

This diff is too big to show here.

content/docs/hoon/reference/stdlib/3f.md+463−317

This diff is too big to show here.

content/docs/hoon/reference/stdlib/3g.md+136−165

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4a.md+5−1

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4b.md+36−37

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4c.md+12−16

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4d.md+4−4

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4e.md+20−33

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4f.md+49−53

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4g.md+8−8

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4h.md+66−64

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4i.md+70−72

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4j.md+62−64

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4k.md+5−5

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4l.md+11−13

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4m.md+20−18

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4n.md+15−13

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4o.md+31−127

This diff is too big to show here.

content/docs/hoon/reference/stdlib/5c.md+77−1

This diff is too big to show here.

content/docs/hoon/reference/stdlib/5f.md+18−23

This diff is too big to show here.

content/docs/hoon/reference/stdlib/table-of-contents.md+134−97

This diff is too big to show here.

content/docs/hoon/reference/zuse/2d_1-5.mdnew file+587

This diff is too big to show here.

content/docs/hoon/reference/zuse/2d_6.mdnew file+1551

This diff is too big to show here.

content/docs/hoon/reference/zuse/2d_7.mdnew file+1307

This diff is too big to show here.

content/docs/hoon/reference/zuse/2e_2-3.mdnew file+67

This diff is too big to show here.

content/docs/hoon/reference/zuse/_index.mdnew file+31

This diff is too big to show here.

content/docs/hoon/reference/zuse/table-of-contents.mdnew file+247

This diff is too big to show here.

content/docs/system-overview/arvo.md+1−1

This diff is too big to show here.

content/docs/userspace/_index.md+5−2

This diff is too big to show here.

content/docs/userspace/dist/_index.mdnew file+29

This diff is too big to show here.

content/docs/userspace/dist/dist.mdnew file+105

This diff is too big to show here.

content/docs/userspace/dist/docket.mdnew file+296

This diff is too big to show here.

content/docs/userspace/dist/glob.mdnew file+102

This diff is too big to show here.

content/docs/userspace/dist/guide.mdnew file+269

This diff is too big to show here.

content/docs/userspace/dist/tools.mdnew file+342

This diff is too big to show here.

content/docs/userspace/gall/tutorial.md → content/docs/userspace/gall-guide.mdrenamed+1−1

This diff is too big to show here.

content/docs/userspace/gall/_index.mddeleted−21

This diff is too big to show here.

content/docs/userspace/graph-store/overview.md+15−21

This diff is too big to show here.

content/docs/userspace/graph-store/sample-application-overview.md+58−58

This diff is too big to show here.

content/docs/userspace/graph-store/validator-walkthrough.md+38−49

This diff is too big to show here.

content/docs/userspace/landscape/overview.md+5−14

This diff is too big to show here.

content/docs/userspace/overview.md+7−2

This diff is too big to show here.

content/docs/userspace/threads/basics/bind.md+1−1

This diff is too big to show here.

content/docs/userspace/threads/basics/fundamentals.md+16−17

This diff is too big to show here.

content/docs/userspace/threads/examples/child-thread.md+6−5

This diff is too big to show here.

content/docs/userspace/threads/examples/get-json.md+1−1

This diff is too big to show here.

content/docs/userspace/threads/examples/main-loop.md+2−2

This diff is too big to show here.

content/docs/userspace/threads/examples/poke-agent.md+1−1

This diff is too big to show here.

content/docs/userspace/threads/examples/scry.md+1−1

This diff is too big to show here.

content/docs/userspace/threads/examples/take-fact.md+1−1

This diff is too big to show here.

content/docs/userspace/threads/gall/poke-thread.md+1−1

This diff is too big to show here.

content/docs/userspace/threads/gall/start-thread.md+3−3

This diff is too big to show here.

content/docs/userspace/threads/gall/stop-thread.md+1−1

This diff is too big to show here.

content/docs/userspace/threads/gall/take-facts.md+1−1

This diff is too big to show here.

content/docs/userspace/threads/gall/take-result.md+1−1

This diff is too big to show here.

content/docs/userspace/threads/http-api.md+6−6

This diff is too big to show here.

content/docs/userspace/threads/overview.md+13−12

This diff is too big to show here.

content/docs/userspace/threads/reference.md+11−2

This diff is too big to show here.

content/events/2021-09-16-developer-call-azimuth-scaled.mdnew file+46

This diff is too big to show here.

content/events/2021-10-16-assembly-keynote.mdnew file+14

This diff is too big to show here.

content/events/2021-10-16-assembly-sw-dist-qa.mdnew file+14

This diff is too big to show here.

content/events/2021-11-26-meetup-brisbane.mdnew file+30

This diff is too big to show here.

content/events/20211007-developer-call-visor.mdnew file+38

This diff is too big to show here.

content/events/20211028-developer-call-hosting.mdnew file+33

This diff is too big to show here.

content/faq.md+10−155

This diff is too big to show here.

content/getting-started/_index.md+54−4

This diff is too big to show here.

content/getting-started/cli.md+15−24

This diff is too big to show here.

content/getting-started/planet.md+167−83

This diff is too big to show here.

content/grant-submission-guide.md+1−1

This diff is too big to show here.

content/grants/a-collaborative-web-mapping-system-for-urbit.md → content/grants/a-network-enabled-spatial-database-and-demonstration-app.mdrenamed+26−21

This diff is too big to show here.

content/grants/analytics-script.md+2−1

This diff is too big to show here.

content/grants/art-by-urbit.md+1

This diff is too big to show here.

content/grants/authenticate-with-urbit.mdnew file+36

This diff is too big to show here.

content/grants/azimuth-cli.mdnew file+164

This diff is too big to show here.

content/grants/bridge-l2-revamp.md+1

This diff is too big to show here.

content/grants/calendar-ui.md+1

This diff is too big to show here.

content/grants/clojure-urbit-client.mdnew file+111

This diff is too big to show here.

content/grants/comprehensive-local-server-and-mum-explanation-video.md+2−1

This diff is too big to show here.

content/grants/contacts.md+1

This diff is too big to show here.

content/grants/content-producer.md+1

This diff is too big to show here.

content/grants/cross-platform-desktop-urbit-app.md+2−1

This diff is too big to show here.

content/grants/cypherscope-bot.mdnew file+80

This diff is too big to show here.

content/grants/educational-guide-todomvc-urbit-edition.md+1

This diff is too big to show here.

content/grants/feed-aggregator.md+1

This diff is too big to show here.

content/grants/graph-store-documentation-guide.md+1

This diff is too big to show here.

content/grants/guide-to-s3.md+1

This diff is too big to show here.

content/grants/host-two-urbit-meetups-12.md+2−1

This diff is too big to show here.

content/grants/host-two-urbit-meetups-13.mdnew file+59

This diff is too big to show here.

content/grants/host-two-urbit-meetups-14.mdnew file+59

This diff is too big to show here.

content/grants/host-two-urbit-meetups-15.mdnew file+59

This diff is too big to show here.

content/grants/host-two-urbit-meetups-16.mdnew file+59

This diff is too big to show here.

content/grants/json-jet.md+1

This diff is too big to show here.

content/grants/links-in-urbit-reference-docs.md+2−1

This diff is too big to show here.

content/grants/login-with-urbit.md+3−8

This diff is too big to show here.

content/grants/machine-learning.md+1

This diff is too big to show here.

content/grants/market-interface.mdnew file+61

This diff is too big to show here.

content/grants/meetup-bom.mdnew file+118

This diff is too big to show here.

content/grants/minimal-urbit-os.md+1

This diff is too big to show here.

content/grants/native-urbit.mdnew file+30

This diff is too big to show here.

content/grants/network-explorer-data-pipeline-http-api.md+2−1

This diff is too big to show here.

content/grants/network-explorer.mddeleted−233

This diff is too big to show here.

content/grants/nuck-jet.md+1

This diff is too big to show here.

content/grants/overhaul-the-urbitorg-website.md+3−2

This diff is too big to show here.

content/grants/planet-sales.md+1

This diff is too big to show here.

content/grants/pokur.mdnew file+90

This diff is too big to show here.

content/grants/ra-page-tracking.md+2−2

This diff is too big to show here.

content/grants/search-in-groups.md+1−1

This diff is too big to show here.

content/grants/send-emails-to-a-mailing-list.mdnew file+78

This diff is too big to show here.

content/grants/slaw-scot-jets.md+1−1

This diff is too big to show here.

content/grants/-smol-future-sustained-knowledge-sharing-and-marketing.md → content/grants/smol-future-sustained-knowledge-sharing-and-marketing.mdrenamed

The content is the same.

content/grants/speech-recognition.md+1

This diff is too big to show here.

content/grants/static-site-generation.mdnew file+80

This diff is too big to show here.

content/grants/translate-key-parts-of-urbitorg-into-german.md+1

This diff is too big to show here.

content/grants/translate-key-parts-of-urbitorg-into-korean.md+1

This diff is too big to show here.

content/grants/translate-key-parts-of-urbitorg-into-spanish.md+1

This diff is too big to show here.

content/grants/try-urbit-website.md+2−1

This diff is too big to show here.

content/grants/twitter-uv-extension.mdnew file+67

This diff is too big to show here.

content/grants/ua-collaborative-text-editor.md+2−2

This diff is too big to show here.

content/grants/ua-filesharer.md+1−1

This diff is too big to show here.

content/grants/ua-heads-up-poker.md+1−1

This diff is too big to show here.

content/grants/ua-invoice-system.md+1−1

This diff is too big to show here.

content/grants/ua-marketplace.md+1−1

This diff is too big to show here.

content/grants/ucal-google-and-outlook-integration.md+1

This diff is too big to show here.

content/grants/urbian-a-customized-linux-distribution-for-urbit-appliances.md+1

This diff is too big to show here.

content/grants/urbit-community-concierge-east-coast-2q2021.md+2−1

This diff is too big to show here.

content/grants/urbit-community-concierge-east-coast.md+2−1

This diff is too big to show here.

content/grants/urbit-community-concierge-west-coast-2q2021.md+2−1

This diff is too big to show here.

content/grants/urbit-community-concierge-west-coast.md+2−1

This diff is too big to show here.

content/grants/urbit-event-series.md+2−1

This diff is too big to show here.

content/grants/urbit-explainer-video.md+1

This diff is too big to show here.

content/grants/urbit-http-api-for-emacs-elisp.md+1

This diff is too big to show here.

content/grants/urbit-http-api-for-kotlin.md+1

This diff is too big to show here.

content/grants/urbit-http-api-for-python.md+1

This diff is too big to show here.

content/grants/urbit-http-api-for-rust.md+1

This diff is too big to show here.

content/grants/urbit-http-interface-java-edition.md+1

This diff is too big to show here.

content/grants/urbit-http-library-for-ruby.md+1

This diff is too big to show here.

content/grants/urbit-irc-bridge.md+1

This diff is too big to show here.

content/grants/urbit-lfs-filehosting.md+1

This diff is too big to show here.

content/grants/urbit-react-cookbook.md+2−1

This diff is too big to show here.

content/grants/uturn.mdnew file+37

This diff is too big to show here.

content/grants/uv-extension-library.mdnew file+44

This diff is too big to show here.

content/grants/video-content-manager.md+1

This diff is too big to show here.

content/grants/volt-lightning-on-urbit.md+39−9

This diff is too big to show here.

content/grants/webrtc-gall-agent-and-external-app.md+16−18

This diff is too big to show here.

content/grants/webrtc.mddeleted−80

This diff is too big to show here.

content/grants/~home-urbit.mdnew file+120

This diff is too big to show here.

content/using/_index.md+3−3

This diff is too big to show here.

content/using/id/_index.md+26

This diff is too big to show here.

content/using/id/guide-to-breaches.md+1−3

This diff is too big to show here.

content/using/id/hd-wallet.mdnew file+164

This diff is too big to show here.

content/using/id/l2-star.mdnew file+41

This diff is too big to show here.

content/using/id/overview.md+187−55

This diff is too big to show here.

content/using/id/proxies.mdnew file+56

This diff is too big to show here.

content/using/id/using-bridge.md+1−1

This diff is too big to show here.

content/using/os/_index.md+1−1

This diff is too big to show here.

content/using/os/basics.mdnew file+236

This diff is too big to show here.

content/using/os/dist-faq.mdnew file+162

This diff is too big to show here.

content/using/os/filesystem.md+29−47

This diff is too big to show here.

content/using/os/getting-started.mddeleted−335

This diff is too big to show here.

content/using/os/shell.md+20−90

This diff is too big to show here.

content/using/os/ship-troubleshooting.md+2−2

This diff is too big to show here.

content/using/running/_index.md+4

This diff is too big to show here.

content/using/running/port.mdnew file+157

This diff is too big to show here.

lib/constants.js−1

This diff is too big to show here.

lib/glossary.js+1301−551

This diff is too big to show here.

next.config.js+46−10

This diff is too big to show here.

package-lock.json+2313−3335

This diff is too big to show here.

package.json+8−6

This diff is too big to show here.

pages/bitcoin-wallet.jsnew file+21

This diff is too big to show here.

pages/events.js+15−4

This diff is too big to show here.

pages/events/[slug].js+2−2

This diff is too big to show here.

pages/grants.js+1−1

This diff is too big to show here.

pages/index.js+75−23

This diff is too big to show here.

pages/using/[[...slug]].js+3−3

This diff is too big to show here.

patches/prismjs+1.24.1.patchdeleted−42

This diff is too big to show here.

public/images/developers-guide-logo.pngnew file

Binary file not shown.

public/images/network-explorer-logo.pngnew file

Binary file not shown.

public/images/operators-guide-logo.pngnew file

Binary file not shown.

public/images/star-market-logo.pngnew file

Binary file not shown.

public/rss.xmlnew file+17611

This diff is too big to show here.

styles/markdown.css+2−6

This diff is too big to show here.

vercel.json+5

This diff is too big to show here.

yarn.lockdeleted−1865

This diff is too big to show here.