on master help sign in
init
commit3a121b1a47d99b4e56b9de8c814bd6bd2e509bd4 authorGalen Wolfe-Pauly <root@office-for.com> dateWed 27 Jan 2016, 10:59 (11 years ago)
210 files changed+44467
docs.md+24 docs/dev.md+28 docs/dev/arvo.md+13 docs/dev/client.md+11 docs/dev/client/tree.md+59 docs/dev/contributing.md+213 docs/dev/hoon.md+24 docs/dev/hoon/leap-in.md+8 docs/dev/hoon/leap-in/1-basic.md+421 docs/dev/hoon/leap-in/2-network.md+335 docs/dev/hoon/leap-in/3-app.md+55 docs/dev/hoon/library.md+7 docs/dev/hoon/library/0.md+37 docs/dev/hoon/library/1.md+1786 docs/dev/hoon/library/2a.md+450 docs/dev/hoon/library/2b.md+907 docs/dev/hoon/library/2c.md+2134 docs/dev/hoon/library/2da.md+437 docs/dev/hoon/library/2db.md+813 docs/dev/hoon/library/2dc.md+221 docs/dev/hoon/library/2dd.md+69 docs/dev/hoon/library/2ea.md+162 docs/dev/hoon/library/2eb.md+63 docs/dev/hoon/library/2ec.md+652 docs/dev/hoon/library/2ed.md+289 docs/dev/hoon/library/2ee.md+195 docs/dev/hoon/library/2ef.md+648 docs/dev/hoon/library/2eg.md+160 docs/dev/hoon/library/2eh.md+531 docs/dev/hoon/library/2ei.md+107 docs/dev/hoon/library/2ej.md+561 docs/dev/hoon/library/2ek.md+162 docs/dev/hoon/library/2el.md+1871 docs/dev/hoon/library/2em.md+758 docs/dev/hoon/library/2en.md+378 docs/dev/hoon/library/2eo.md+453 docs/dev/hoon/library/2ep.md+586 docs/dev/hoon/library/2ew.md+439 docs/dev/hoon/library/2ex.md+717 docs/dev/hoon/library/2ey.md+399 docs/dev/hoon/library/2ez.md+250 docs/dev/hoon/library/3ba.md+67 docs/dev/hoon/library/3bb.md+600 docs/dev/hoon/library/3bc.md+382 docs/dev/hoon/library/3bd.md+1807 docs/dev/hoon/library/3be.md+1316 docs/dev/hoon/library/3bf.md+267 docs/dev/hoon/library/3bg.md+943 docs/dev/hoon/library/3bh.md+479 docs/dev/hoon/library/3bi.md+1483 docs/dev/hoon/principles.md+18 docs/dev/hoon/principles/0-nouns.md+286 docs/dev/hoon/principles/1-twigs.md+286 docs/dev/hoon/principles/2-syntax.md+475 docs/dev/hoon/principles/3-program.md+350 docs/dev/hoon/principles/4-functions.md+327 docs/dev/hoon/reference.md+7 docs/dev/hoon/reference/odors.md+686 docs/dev/hoon/reference/pronunciation.md+68 docs/dev/hoon/runes.md+132 docs/dev/hoon/runes/bc.md+49 docs/dev/hoon/runes/bc/bcbr.md+52 docs/dev/hoon/runes/bc/bccb.md+43 docs/dev/hoon/runes/bc/bccl.md+44 docs/dev/hoon/runes/bc/bccm.md+61 docs/dev/hoon/runes/bc/bccn.md+64 docs/dev/hoon/runes/bc/bckt.md+49 docs/dev/hoon/runes/bc/bcls.md+62 docs/dev/hoon/runes/bc/bcpm.md+39 docs/dev/hoon/runes/bc/bcpt.md+37 docs/dev/hoon/runes/bc/bctr.md+38 docs/dev/hoon/runes/bc/bcts.md+53 docs/dev/hoon/runes/bc/bcwt.md+48 docs/dev/hoon/runes/bc/bczp.md+40 docs/dev/hoon/runes/br.md+47 docs/dev/hoon/runes/br/brcb.md+118 docs/dev/hoon/runes/br/brcn.md+135 docs/dev/hoon/runes/br/brdt.md+114 docs/dev/hoon/runes/br/brfs.md+105 docs/dev/hoon/runes/br/brhp.md+78 docs/dev/hoon/runes/br/brkt.md+103 docs/dev/hoon/runes/br/brls.md+63 docs/dev/hoon/runes/br/brtr.md+73 docs/dev/hoon/runes/br/brts.md+71 docs/dev/hoon/runes/br/brwt.md+54 docs/dev/hoon/runes/cl.md+44 docs/dev/hoon/runes/cl/clcb.md+56 docs/dev/hoon/runes/cl/clfs.md+47 docs/dev/hoon/runes/cl/clhp.md+85 docs/dev/hoon/runes/cl/clkt.md+68 docs/dev/hoon/runes/cl/clls.md+61 docs/dev/hoon/runes/cl/clsg.md+69 docs/dev/hoon/runes/cl/cltr.md+57 docs/dev/hoon/runes/cn.md+41 docs/dev/hoon/runes/cn/cncb.md+74 docs/dev/hoon/runes/cn/cncl.md+55 docs/dev/hoon/runes/cn/cndt.md+62 docs/dev/hoon/runes/cn/cnhp.md+39 docs/dev/hoon/runes/cn/cnkt.md+46 docs/dev/hoon/runes/cn/cnls.md+59 docs/dev/hoon/runes/cn/cnsg.md+70 docs/dev/hoon/runes/cn/cntr.md+60 docs/dev/hoon/runes/cn/cnts.md+71 docs/dev/hoon/runes/cn/cnzy.md+40 docs/dev/hoon/runes/cn/cnzz.md+43 docs/dev/hoon/runes/dt.md+33 docs/dev/hoon/runes/dt/dtkt.md+56 docs/dev/hoon/runes/dt/dtls.md+66 docs/dev/hoon/runes/dt/dttr.md+57 docs/dev/hoon/runes/dt/dtts.md+77 docs/dev/hoon/runes/dt/dtwt.md+59 docs/dev/hoon/runes/dt/dtzy.md+47 docs/dev/hoon/runes/dt/dtzz.md+52 docs/dev/hoon/runes/hx.md+19 docs/dev/hoon/runes/hx/hxgl.md+62 docs/dev/hoon/runes/hx/hxgr.md+83 docs/dev/hoon/runes/index.hook+13 docs/dev/hoon/runes/kt.md+40 docs/dev/hoon/runes/kt/ktbr.md+61 docs/dev/hoon/runes/kt/ktdt.md+47 docs/dev/hoon/runes/kt/kthp.md+70 docs/dev/hoon/runes/kt/ktls.md+80 docs/dev/hoon/runes/kt/ktpm.md+46 docs/dev/hoon/runes/kt/ktsg.md+47 docs/dev/hoon/runes/kt/ktts.md+52 docs/dev/hoon/runes/kt/ktwt.md+45 docs/dev/hoon/runes/sg.md+32 docs/dev/hoon/runes/sg/sgbc.md+43 docs/dev/hoon/runes/sg/sgbr.md+36 docs/dev/hoon/runes/sg/sgcb.md+41 docs/dev/hoon/runes/sg/sgcn.md+64 docs/dev/hoon/runes/sg/sgfs.md+44 docs/dev/hoon/runes/sg/sggl.md+50 docs/dev/hoon/runes/sg/sggr.md+48 docs/dev/hoon/runes/sg/sgls.md+50 docs/dev/hoon/runes/sg/sgpm.md+64 docs/dev/hoon/runes/sg/sgts.md+49 docs/dev/hoon/runes/sg/sgwt.md+64 docs/dev/hoon/runes/sg/sgzp.md+59 docs/dev/hoon/runes/sm.md+42 docs/dev/hoon/runes/sm/smcl.md+63 docs/dev/hoon/runes/sm/smcn.md+93 docs/dev/hoon/runes/sm/smdq.md+56 docs/dev/hoon/runes/sm/smhp.md+55 docs/dev/hoon/runes/sm/smls.md+58 docs/dev/hoon/runes/sm/smsg.md+162 docs/dev/hoon/runes/sm/smsm.md+52 docs/dev/hoon/runes/sm/smtr.md+61 docs/dev/hoon/runes/sm/smzz.md+84 docs/dev/hoon/runes/ts.md+49 docs/dev/hoon/runes/ts/tsbr.md+55 docs/dev/hoon/runes/ts/tscl.md+57 docs/dev/hoon/runes/ts/tsdt.md+55 docs/dev/hoon/runes/ts/tsgl.md+63 docs/dev/hoon/runes/ts/tsgr.md+68 docs/dev/hoon/runes/ts/tshp.md+62 docs/dev/hoon/runes/ts/tskt.md+66 docs/dev/hoon/runes/ts/tsls.md+65 docs/dev/hoon/runes/ts/tssg.md+49 docs/dev/hoon/runes/ts/tstr.md+51 docs/dev/hoon/runes/wt.md+39 docs/dev/hoon/runes/wt/wtbr.md+55 docs/dev/hoon/runes/wt/wtcl.md+54 docs/dev/hoon/runes/wt/wtdt.md+58 docs/dev/hoon/runes/wt/wtgl.md+52 docs/dev/hoon/runes/wt/wtgr.md+52 docs/dev/hoon/runes/wt/wthp.md+99 docs/dev/hoon/runes/wt/wthz.md+52 docs/dev/hoon/runes/wt/wtkt.md+70 docs/dev/hoon/runes/wt/wtkz.md+34 docs/dev/hoon/runes/wt/wtls.md+115 docs/dev/hoon/runes/wt/wtlz.md+35 docs/dev/hoon/runes/wt/wtpm.md+49 docs/dev/hoon/runes/wt/wtpt.md+59 docs/dev/hoon/runes/wt/wtpz.md+34 docs/dev/hoon/runes/wt/wtsg.md+50 docs/dev/hoon/runes/wt/wtsz.md+37 docs/dev/hoon/runes/wt/wtts.md+45 docs/dev/hoon/runes/wt/wttz.md+35 docs/dev/hoon/runes/wt/wtzp.md+46 docs/dev/hoon/runes/zp.md+23 docs/dev/hoon/runes/zp/zpcb.md+57 docs/dev/hoon/runes/zp/zpcm.md+36 docs/dev/hoon/runes/zp/zpfs.md+64 docs/dev/hoon/runes/zp/zpgr.md+62 docs/dev/hoon/runes/zp/zpsm.md+43 docs/dev/hoon/runes/zp/zpts.md+55 docs/dev/hoon/runes/zp/zpwt.md+49 docs/dev/hoon/runes/zp/zpzp.md+48 docs/dev/interpreter.md+12 docs/dev/interpreter/u3.md+1570 docs/dev/nock.md+52 docs/dev/nock/reference.md+737 docs/dev/nock/tutorial.md+1044 docs/theory.md+26 docs/theory/network-goals.md+565 docs/theory/old.md+21 docs/theory/part-i.md+512 docs/theory/part-ii.md+462 docs/theory/whitepaper.md+2346 docs/user.md+25 docs/user/appliance.md+274 docs/user/basic.md+143 docs/user/clay.md+420 docs/user/dojo.md+547 docs/user/install.md+111 docs/user/intro.md+137 docs/user/launch.md+112 docs/user/talk.md+314 docs/user/tour.md+209
docs.mdnew file+24
@@ -0,0 +1,24 @@
1+---
2+anchor: none
3+layout: no-anchor
4+logo: black
5+---
6+
7+<div class="short lead">
8+
9+# Urbit documentation
10+
11+The Urbit doc is divided into three parts: [user doc](docs/user),
12+[developer doc](docs/dev), and [theory](docs/theory) (whitepaper, essays,
13+videos, etc).
14+
15+If you want to try Urbit, start with the user doc. If you want
16+to learn about Urbit, try the theory. Or just start with the
17+user doc; it doesn't assume any prior knowledge.
18+
19+The most fun thing to do with Urbit is code, but the developer
20+doc remains under construction. Sorry. We'll have more soon.
21+
22+<list dataSort="true" class="children"></list>
23+
24+</div>
docs/dev.mdnew file+28
@@ -0,0 +1,28 @@
1+---
2+logo: black
3+sort: 2
4+title: Developer doc
5+---
6+<div class="short">
7+
8+# Developer documentation
9+
10+Urbit has three programming layers: [Nock](dev/nock) (combinator nano-VM),
11+[Hoon](dev/hoon) (strict functional language), and [Arvo](dev/arvo) (functional
12+OS).
13+
14+To code in Urbit, the least you need to learn is Hoon, plus a
15+little bit of Arvo. Nock is a sort of functional assembly
16+language -- you don't need to know it, but it's useful to.
17+Nock is also the easiest thing in the world to learn.
18+
19+You can program for Arvo without knowing much about Arvo
20+internals, but again it helps. But you need to know Hoon.
21+Don't worry, it's easier than it looks.
22+
23+Alas, the developer doc is still under construction. We'll have
24+more soon.
25+
26+<list></list>
27+
28+</div>
docs/dev/arvo.mdnew file+13
@@ -0,0 +1,13 @@
1+---
2+logo: black
3+sort: 3
4+title: Arvo
5+---
6+<div class="short">
7+
8+# Arvo
9+
10+Arvo is a functional operating system. But hopefully you knew that! Sorry,
11+please watch this space for actual documentation.
12+
13+</div>
docs/dev/client.mdnew file+11
@@ -0,0 +1,11 @@
1+---
2+hide: true
3+logo: black
4+sort: 4
5+title: Frontend tools
6+---
7+
8+Frontend tools
9+==============
10+
11+<list></list>
docs/dev/client/tree.mdnew file+59
@@ -0,0 +1,59 @@
1+# `:tree`
2+
3+`:tree` is the web filesystem interface. Odds are this file has been rendered for you by `:tree`.
4+
5+`:tree` is a single-page app that uses a backend in `/home/tree` to load
6+contents from `%clay` as the user navigates around as `%json`. The frontend
7+lives in `/home/pub/tree` and is a fairly straightforward
8+[React](https://facebook.github.io/react/) /
9+[Flux](https://facebook.github.io/flux/) app.
10+
11+## Frontend
12+
13+The frontend code for `:tree` can be found in `/home/pub/tree/src/`.
14+
15+### CSS
16+
17+The CSS is written in [Stylus](https://learnboost.github.io/stylus/). The main entry point is `main.styl` and can be compiled with `stylus main.styl` which should output a `main.css`
18+
19+### JS
20+
21+The JS is written in [CoffeeScript](http://coffeescript.org/) and packaged with
22+[Browserify](http://browserify.org/). The main entry point is `main.coffee` and
23+is compiled with `browserify -t coffeeify main.coffee > main.js`. You'll need
24+to `npm install` first.
25+
26+Each page is loaded as JSON and then rendered using React on the page. This
27+allows us to write JSX in our markdown to implement simple components. Check
28+out `/home/pub/tree/src/js/components` to see the component library.
29+
30+You'll notice that some of these doc pages use things like `<list>` in the raw markdown files.
31+
32+## JSON API
33+Async provides loading by schema
34+
35+`{path name sein sibs next prev}` are all immediately accesible from the store
36+
37+a `getPath` method, if present (defaulting to current url), is used to determine the query root node.
38+
39+## JSON Internals
40+
41+### `/[desk]/tree/{path}.json`
42+`tree/json.hook` accepts a query string schema `q` in light noun encoding
43+
44+ ++ schema (dict ,[term $|(mark schema)])
45+ ++ dict |*(a=_,* $&([a (dict a)] a))
46+
47+which is normalized and type-checked to a `query` list of
48+- `[%kids query]`, the only recursive value, which executes for all subpaths
49+ XX descent is only currently supported to a single level as a performance optimization
50+- `[%name %t]`, the node name
51+- `[%path %t]`, the current path
52+- `[%snip %r]`, a snippet, extracted via `react-snip-json`
53+- `[%head %r]`, the first `<h1/>`, extracted via `react-head-json`
54+- `[%body %r]`, the `react-json` body
55+- `[%meta %j]`, json frontmatter per the `mdy` mark definition
56+
57+The request types above are `%t` text, `%r` html-derived tree, and `%j`
58+arbitrary json; an example query, used by the main content renderer, is
59+`"q=body.r__kids_name.t"` (`body:'r' kids:{name:'t'}` )
docs/dev/contributing.mdnew file+213
@@ -0,0 +1,213 @@
1+---
2+sort: 6
3+title: Contributing
4+---
5+
6+# Contributing to urbit
7+
8+Thank you for your interest in contributing to urbit.
9+
10+## Development practice
11+
12+You may have an identity on the live network, but doing all your
13+development on the live network would be cumbersome and unnecessary.
14+Standard practice in urbit development is to work on a fake `~zod`. A
15+fake `~zod` will get its initial files from the `urb/zod/` directory
16+rather than trying to sync them over the network, which is invaluable
17+for working in Hoon. Also, a fake `~zod` or any fake urbit instances you
18+start do not talk to the live network, but to a fake network that exists
19+only on your computer.
20+
21+To start a fake `~zod`, the command is:
22+
23+ bin/urbit -F -I zod -c [pier directory]
24+
25+To resume one that was already created, just as on the live network,
26+remove `-c` (but leave the rest of the options there). `-F` uses the
27+fake network, and `-I` starts an "imperial" instance - that is, an 8-bit
28+galaxy.
29+
30+## Kernel development
31+
32+Working on either C or non-kernel Hoon should not bring any surprises,
33+but the Hoon kernel (anything under `urb/zod/arvo/`) is bootstrapped
34+from `urbit.pill` in `urb/`, and must be manually recompiled if any
35+changes are made. The command to manually recompile the kernel and
36+install the new kernel is `|reset` in `dojo`. This rebuilds from the
37+`arvo` directory in the `home` desk in `%clay`. Currently, `|reset`
38+does not reload apps like `dojo` itself, which will still reference the
39+old kernel. To force them to reload, make a trivial edit to their main
40+source file (under the `ape` directory) in `%clay`.
41+
42+If you do any kernel development, be sure to read the section below about
43+pills.
44+
45+## Git practice
46+
47+Since we use the GitHub issue tracker, it is helpful to contribute via a
48+GitHub pull request. If you already know what you are doing, skip down
49+to the Style section.
50+
51+Start by cloning the repository on your work machine:
52+
53+ git clone https://github.com/urbit/urbit
54+
55+And, additionally, fork the repository on GitHub by clicking the "Fork"
56+button. Add your fork as a remote:
57+
58+ git remote add [username] https://github.com/[username]/urbit
59+
60+and set it as the default remote to push to:
61+
62+ git config --local remote.pushDefault [username]
63+
64+This is good practice for any project that uses git. You will pull
65+upstream branches from urbit/urbit and push to your personal urbit fork
66+by default.
67+
68+Next, check out `test`, which is the mainline development branch, and
69+base a new branch on it to do your work on:
70+
71+ git checkout test
72+ git checkout -b [branch name]
73+
74+Now you are free to do your work on this branch. When finished, you may
75+want to clean up your commits:
76+
77+ git rebase -i test
78+
79+Then you can push to your public fork with `git push` and make a pull
80+request via the GitHub UI. Make sure you request to merge your branch
81+into `test`, not `master`.
82+
83+After your changes are merged upstream, you can delete your branch (via
84+github UI or `git push :[branch]` remotely, and with `git branch -d`
85+locally).
86+
87+## Style
88+
89+The urbit project uses two-space indentation and avoids tab characters.
90+In C code, it should not be too difficult to mimic the style of the code
91+around you, which is just fairly standard K&R with braces on every
92+compound statement. One thing to watch out for is top-level sections in
93+source files that are denoted by comments and are actually indented one
94+level.
95+
96+Hoon will be a less familiar language to many contributors. Some of our
97+less obvious stylistic rules are:
98+
99+- Keep your source files 80 characters or less wide. Many urbit
100+ developers use 80 character terminals/tmux panes/&c.
101+- Tab characters are actually a syntax error, so be extra sure your
102+ editor is not inserting any. Trailing whitespace is *usually* not a
103+ syntax error, but avoiding it is encouraged.
104+- The kernel convention is that line comments start at column 57 with
105+ the `::` followed by 2 spaces. This leaves 20 characters for the
106+ comment. Outside the kernel, things are less strict.
107+- Tall arms within a core are conventionally separated by empty comments
108+ (just `::`) at the same indentation level as the initial `++` or `+-`.
109+ The last arm in a core is not followed by an empty comment, because it
110+ is visually closed by the `--` that closes the core. The empty comment
111+ is also sometimes omitted in data structure definitions.
112+
113+## The kernel and pills
114+
115+urbit bootstraps itself using a binary blob called `urbit.pill`, which
116+we do indeed keep in version control. This creates some special
117+requirements. If you are not changing anything in the kernel (everything
118+under `urb/zod/arvo/`) then you can skim this section (please do not
119+skip it entirely, though). If you *are* working there, then this
120+section is critically important!
121+
122+The procedure for creating `urbit.pill` is often called "soliding". It
123+is somewhat similar to `|reset`, but instead of replacing your running
124+kernel, it writes the compiled kernel to a file. The command to solid
125+is, on a fakezod:
126+
127+ .urbit/pill +solid
128+
129+When the compilation finishes, your `urbit.pill` will be found in the
130+`[pier]/.urb/put/` directory. Copy it into `urb/` and add it to your
131+commit.
132+
133+The requirement here is that every commit that changes the kernel must
134+come with an `urbit.pill` built from the same code in `urb/zod/arvo/`
135+for that commit. (Only changing the actual Hoon code counts, so a change
136+to a jet with no corresponding Hoon change does not require a new pill.)
137+This is so that checking out an arbitrary revision and starting up a
138+fakezod actually works as expected. However you do this is fine, but I
139+like to do it as part of my committing process - just before `git
140+commit`, I fire up a new fakezod. This will use the previous
141+`urbit.pill`, but the kernel code in `%clay` will be copied from
142+`urb/zod/arvo/`, so `+solid` will compile it. Then I copy `urbit.pill`
143+into `urb/` and make my commit.
144+
145+If you rebase or interactive rebase your commits, be sure to preserve
146+this property on all the commits you end up with. If multiple people
147+were collaborating on your branch, you may end up with conflicts in
148+`urbit.pill` and have to merge the branch into itself to resolve them.
149+Just do the same procedure to create a new, merged pill before
150+committing the merge. Otherwise, just make sure to use the correct
151+`urbit.pill` for each commit.
152+
153+## Debug urbit with `gdb`
154+
155+Follow the build instructions in README.md but run `make` with argument `DEBUG=yes`:
156+
157+(If you've already built urbit first run `make clean`.)
158+
159+ make DEBUG=yes
160+
161+Run `gdb`, while loading `bin/urbit` and its symbol table:
162+
163+ gdb bin/urbit
164+
165+Set a breakpoint on `main()` (optional):
166+
167+ break main
168+
169+Run your urbit comet `mycomet`:
170+
171+ run mycomet
172+
173+Continue from the breakpoint on `main()`:
174+
175+ continue
176+
177+## What to work on
178+
179+If you are not thinking of contributing with a specific goal in mind,
180+the GitHub issue tracker is the first place you should look for ideas.
181+Issues are tagged with a priority and a difficulty. A good place to
182+start is on either a low-difficulty issue or a low-priority issue.
183+Higher priority issues are likely to be assigned to someone - if this is
184+the case, then contacting that person to coordinate before starting to
185+work is probably a good idea.
186+
187+There is also a "help wanted" tag for things that we are especially
188+eager to have outside contributions on. Check here first!
189+
190+## Staying in touch
191+
192+The urbit developers communicate on urbit itself. Joining the
193+`~doznec/urbit-meta` channel on `talk` is highly recommended.
194+Subscribing to `urbit-dev` on Google Groups is also recommended, since
195+this is where continuity breach notifications are sent.
196+
197+You can also contact one of the following people:
198+
199+- Philip Monk
200+
201+ email: philip.monk@tlon.io
202+
203+ urbit: `~wictuc-folrex`
204+
205+ GitHub: [@philipcmonk](https://github.com/philipcmonk/)
206+
207+- Raymond Pasco
208+
209+ email: ray@the.ug
210+
211+ urbit: `~ramtev-wisbyt`
212+
213+ GitHub: [@juped](https://github.com/juped/)
docs/dev/hoon.mdnew file+24
@@ -0,0 +1,24 @@
1+---
2+logo: black
3+sort: 2
4+title: Hoon
5+---
6+
7+<div class="short">
8+
9+# Hoon
10+
11+Hoon is a strict, typed, pure functional language. This site is
12+served by an urbit written in Hoon.
13+
14+If you're interested in learning the fundamentals of Hoon from
15+the bottom up, start with [Principles of
16+Hoon](hoon/principles).
17+
18+If you want to jump into building things right away and prefer to
19+learn from the top down, check out [Leap into
20+Hoon](hoon/leap-in/1-basic).
21+
22+Both of these are under active development.
23+
24+</div>
docs/dev/hoon/leap-in.mdnew file+8
@@ -0,0 +1,8 @@
1+---
2+hide: false
3+next: false
4+sort: 1
5+title: Leap into Hoon
6+---
7+
8+<list></list>
docs/dev/hoon/leap-in/1-basic.mdnew file+421
@@ -0,0 +1,421 @@
1+---
2+logo: black
3+sort: 1
4+next: true
5+title: Basic Hoon
6+---
7+
8+# Basic Hoon
9+
10+Our goal is to get you programming interesting and useful things
11+as soon as possible. To get there we have to quickly cover some
12+of the fundamentals of hoon. To do this we'll walk through two
13+simple programs: the first [Project
14+Euler](https://projecteuler.net/) problem and
15+[fizzbuzz](https://en.wikipedia.org/wiki/Fizz_buzz).
16+
17+To run this code, you'll need an urbit, and you'll need the
18+`%examples` desk from `~wactex-ribmex`. If you haven't installed
19+urbit yet, check out the [installation
20+instructions](http://urbit.org/docs/user/install). Once urbit is
21+intalled, take a look at the [basic
22+operation](http://urbit.org/docs/user/basic) of your urbit.
23+
24+If you haven't pulled the examples desk from `~wactex-ribmex`, do
25+so now:
26+
27+ ~fintud-macrep:dojo> |merge %examples ~wactex-ribmex %examples
28+ >=
29+ ; ~wactex-ribmex is your neighbor
30+ ; ~wactex-ribmex is your neighbor
31+ [time passes...]
32+ merged with strategy %init
33+
34+The merge could take several minutes; you'll know it's done when
35+"merged with strategy %init" is printed. Mount the new files to
36+your Unix pier directory:
37+
38+ ~fintud-macrep:dojo> |mount /=examples=
39+
40+Switch desks to run commands from the `%examples` desk:
41+
42+ ~fintud-macrep:dojo> =dir /=examples=
43+ =% /~fintud-macrep/examples/~2015.11.13..02.25.00..41e9/
44+
45+Run an example:
46+
47+ ~fintud-macrep:dojo> +euler1
48+ 233.168
49+
50+## Euler 1
51+
52+Let's check out the code for Euler 1. First, the problem:
53+
54+```
55+If we list all the natural numbers below 10 that are multiples of
56+3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
57+
58+Find the sum of all the multiples of 3 or 5 below 1000.
59+```
60+
61+Here is the hoon solution (which should be in your pier directory
62+under `/examples/gen/euler1.hoon`):
63+
64+```
65+:: project euler 1
66+:: https://projecteuler.net/problem=1
67+:: run in dojo with +euler1
68+::
69+:::: /hoon/euler1/gen
70+ ::
71+:- %say |= *
72+:- %noun
73+=< (sum 1.000)
74+::
75+:::: ~fintud-macrep
76+ ::
77+|%
78+++ three
79+ |= a=@
80+ =| b=@
81+ |- ^- @u
82+ ?: (lth a b)
83+ 0
84+ (add b $(b (add 3 b)))
85+
86+++ five
87+ |= a=@
88+ =| b=@
89+ |- ^- @
90+ ?: (lte a b)
91+ 0
92+ ?: =((mod b 3) 0)
93+ $(b (add b 5))
94+ (add b $(b (add b 5)))
95+
96+++ sum
97+ |= a=@u
98+ (add (five a) (three a))
99+--
100+```
101+
102+> Hoon is not generally whitespace sensitive, but we do have two
103+> different kinds of whitespace: a single space and a gap, which
104+> is two or more spaces or a linebreak. Tabs are taboo. Do not
105+> use them. Really. For a more detailed explanation of when to
106+> use spaces vs. gaps, see the syntax section before the first
107+> excercises.
108+
109+### Lines 1-11:
110+
111+Any line that begins with `::` is a comment.
112+
113+ :- %say |= *
114+ :- %noun
115+ =< (sum 1.000)
116+
117+All you need to know about the lines above is that they call the
118+`++sum` function with an argument of `1.000`. We'll cover them in
119+more detail later.
120+
121+### How to form expressions
122+
123+Hoon does not use reserved words to form expressions. Instead,
124+expressions are formed with runes, which are diagraphs of two
125+ascii symbols. Each rune takes a specific number of
126+children--either expressions formed by other runes or literals
127+that produce their own value.
128+
129+For example, the rune `?:` from line 17 is the classic
130+'if-then-else' statement, and thus takes three children:
131+
132+ ?: (lth a b) :: if first child evals to true
133+ 0 :: then produce result of second
134+ (add b $(b (add 3 b))) :: else, produce result of third
135+
136+Since runes are such a fundamental structure in Hoon, we found
137+ourselves speaking them out loud frequently. It quickly grew
138+cumbersome to have to say "question mark, colon" to describe
139+`?:`. To alleviate this problem, we came up with our own naming
140+scheme: each ascii glyph has a single syllable pronunciation
141+phonetically designed to be both easily remembered and easily
142+pronounced in conjunction with the other glyphs (when forming a
143+rune).
144+
145+See the entire naming schema below/or link to it:
146+
147+```
148+ ace [1 space] gal < pel (
149+ bar | gap [>1 space, nl] per )
150+ bas \ gar > sel [
151+ buc $ hax # sem ;
152+ cab _ hep - ser ]
153+ cen % kel { soq '
154+ col : ker } tar *
155+ com , ket ^ tec `
156+ doq " lus + tis =
157+ dot . pam & wut ?
158+ fas / pat @ zap !
159+```
160+
161+Using our naming scheme `?:` is said 'wut col'.
162+
163+### Lines 12-34
164+
165+Now let's quickly walk through this code line-by-line. Lines
166+12-34 are wrapped in a `|%` (pronounced 'bar cen'), which
167+produces a core, a fundamental datatype in hoon similar to a
168+struct, class, or object. A core is just a map of names
169+to any kind of code, whether it be functions or data. Each
170+element in this map begins with a `++` followed by the name and
171+the corresponding code. Since `|%` takes an arbitrary number of
172+children, it needs to be closed with a `--`.
173+
174+> `++` is not technically a rune, since it is only used in core
175+> syntax as shown above
176+
177+Let's step into each of the three arms within our core.
178+
179+### `++ sum`
180+
181+ ++ sum
182+ |= a=@
183+ (add (five a) (three a))
184+ --
185+
186+`|=` produces a function, much like a lambda in lisp. It takes two children:
187+
188+- A set of argument(s). In this case our argument set only
189+ contains one: `a` which is required to be an atom or natural
190+ number, denoted by `@`.
191+
192+- The body of the function itself, which is executed when the
193+ function is called (in this case, with `(sum 1.000)`). This
194+ particular function adds the results of evaluating the gates `++
195+ five` and `++three` with each of their respective input
196+ parameters set to `a`.
197+
198+### ++ three
199+
200+ ++ three
201+ |= a=@
202+ =| b=@
203+ |- ^- @u
204+ ?: (lth a b)
205+ 0
206+ (add b $(b (add 3 b)))
207+
208+As above, `++three` takes an integer argument, `a`, and then
209+executes the remainder of the code with `a` set to the actual
210+arguments.
211+
212+Similarly, `=|` pushes its first child, `b` into our context (in
213+other words, it declares a variable `b`) and executes the
214+remainder of the code. However, `b` is not an argument; `=|`
215+sets `b` to the default value of whatever type it is declared as.
216+Since the default value of an atom is `0`, b is set to `0`.
217+
218+So now we have two variables: `a` is set to our input, and `b` is
219+initialized to `0`.
220+
221+The easiest way to think about `|-` that it lays down a recursion
222+point. More on this later.
223+
224+`^-` is just a cast that sets the result of the remainder of the
225+code to an unsigned integer, `@u`.
226+
227+In pseudocode, the last three lines read like this: if `a` is
228+less than `b`, produce zero. Else, add `b` to the result of
229+rerunning the segment of the function following the `|-` with the
230+value of `b` changed to `b` plus three.
231+
232+The only thing that should look completely unfamiliar to you here
233+is the `$(b (add 3 b))`, which causes us to recurse back to our
234+last recursion point with the value of `b` set to `(add 3 b)`.
235+Note that we only specify what changes (`b` in this case). If
236+you recurse by an actual function call, then you have to specify
237+every argument.
238+
239+> If you're familiar with Clojure, `|-` is `loop` and `$()` is
240+> recur.
241+
242+
243+## Excercises
244+
245+Please tweak your code to complete the following excercises.
246+
247+There are a few runes and some syntax that we have yet to cover that
248+you will need to complete the excercises below. For these, please
249+refer to our cheatsheat at the bottom.
250+
251+1. Read and understand `++five` line by line.
252+
253+2. Change `++sum` to accept two variables, `a` and `b`. Pass `a`
254+ to three and `b` to five. Then run the code with `a` set to
255+ `1.000` and b set to `2.000`.
256+
257+3. Check if this new result is under one thousand. If it is,
258+ return the string 'result is less than one thousand'. If not,
259+ return 'result is greater than or equal to one thousand'.
260+
261+```
262+Review
263+
264+|% start core (collection of named ++ arms)
265+|= define function
266+=| define variable from type with default value
267+|- drop a recursion point
268+^- cast
269+?: if-then-else
270+=(a b) test equality
271+(function args ...) call function
272+
273+New material
274+
275+- :- make a cell of values. The irregular wide form of this is
276+ [a b] with two expressions separated by a single space.
277+
278+- Cords are one datatype for text in hoon. They're just a big
279+ atom formed from adjacent unicode bytes -- a "c string". To
280+ produce a cord enclose text within single quotes. To set the type
281+ of an argument to a cord, use @t.
282+
283+- There are two syntaxes for writing Hoon: tall form and wide
284+ form.
285+
286+ In tall form, expressions are formed with either two spaces or
287+ a line break separating both a rune from its children and each
288+ of its children from one another. We use tall form when writing
289+ multiline expressions.
290+
291+ For more concise expressions, we use wideform, which is always
292+ a single line. Wideform can be used inside tall form
293+ expressions, but not vice versa.
294+
295+ Wideform expressions are formed with a rune followed by ()
296+ containing its children, all of which are separated by a
297+ single space. For example to make a cell of two elements:
298+
299+ :-(a b)
300+
301+ We've already seen wideform in action, for example with
302+ =((mod b 3) 0). In this case = is actually an irregular form
303+ of .=, which tests its two children for equality.
304+
305+ Another irregular form is [a b] for :-(a b)
306+
307+ Surrounding a function with () is an irregular wide form
308+ syntax for calling a function with n arguments.
309+```
310+
311+
312+## The subject
313+
314+Now we're going to cover the boiler plate that we skimmed over
315+earlier.
316+
317+ :- %say |= *
318+ :- %noun
319+ =< (sum [1.000 2.000])
320+
321+This program is a cell of two elements: the first, `%say`, tells
322+the interpreter what to produce--in this case a value.
323+
324+The second element is `|=`, which we know produces a function.
325+`|=`'s first child is its argument(s), which in this case is any
326+noun (`*`). Its second child is the remainder of the program.
327+
328+Similarly, the rest of the program is a cell of the literal
329+`%noun`, which tells the shell that we're producing a value of
330+type `noun`, and the second child contains the code that we run
331+to actually produce our value of the type `noun`.
332+
333+`=<` is a rune that takes two children. The second child is the
334+context against which we run the first child. So in this case, we
335+are running the expression `(sum 1.000)` against everything
336+contained within the `|%`. In Hoon, we call the code executed the
337+"formula" and its context the "subject".
338+
339+```
340+::::::::::::::::::::::::::::::
341+=< (sum 1.000) :: formula
342+::::::::::::::::::::::::::::::
343+|% ::
344+++ three ::
345+ |= a=@ ::
346+ =| b=@ ::
347+ |- ^- @u ::
348+ ?: (lth a b) ::
349+ 0 ::
350+ (add b $(b (add 3 b))) ::
351+ ::
352+++ five ::
353+ |= a=@ :: subject
354+ =| b=@ ::
355+ |- ^- @ ::
356+ ?: (lte a b) ::
357+ 0 ::
358+ ?: =((mod b 3) 0) ::
359+ $(b (add b 5)) ::
360+ (add b $(b (add b 5))) ::
361+ ::
362+++ sum ::
363+ |= a=@u ::
364+ (add (five a) (three a)) ::
365+-- ::
366+::::::::::::::::::::::::::::::
367+```
368+
369+In nearly every language there is a similar concept of a
370+"context" in which expressions are executed. For example, in C
371+this includes things like the call stack, stack variables, and so
372+on.
373+
374+Hoon is unique in that this context is a first-class value.
375+Scheme allows a sort of reification of the context through
376+continutations, and some may see a parallel to Forth's stack, but
377+Hoon takes takes the concept one step further.
378+
379+Our starting subject is the standard library, which is defined in
380+`/arvo/hoon.hoon` and `/arvo/zuse.hoon`. This is where functions
381+like `add` are defined. When we define a core with `|%`, we
382+don't throw away the subject (i.e. the standard library); rather,
383+we stack the new core on top of the old subject so that both are
384+accessible.
385+
386+## Exercises:
387+
388+4. Pass `++sum` its arguments (`2000` and `3000`) from the
389+ commandline.
390+
391+5. Comment out all of the arms of the `|%`. Now add another arm
392+ and call it `++add`, have it accept two arguments and procduce
393+ 42 (regardless of input). Change the `=<` line to `[(add 5 7)
394+ (^add 5 7)]`. Can you recognize what's happening?
395+
396+6. Write fizbuzz:
397+
398+ Write a program that prints the numbers from 1 to 100
399+ (entered from the command line). But for multiples of three
400+ print 'Fizz' instead of the number and for the multiples of
401+ five print 'Buzz'. For numbers which are multiples of both
402+ three and five print 'FizzBuzz'.
403+
404+Cheatsheet:
405+
406+- To pass arguments from the command line to a program, you
407+ replace the `*` in the first line of the boiler plate to
408+ `[^ [[arg=TYPE ~] ~]]` where `TYPE` is replaced with the
409+ type of argument you're expecting. Then `+euler1 a` from
410+ the dojo sets `arg` to `a`.
411+- A list of strings is of type `(list ,@t)`, so the result of
412+ the fizzbuzz function is of this type (hint: you'll need to
413+ use `^-`)
414+- The empty list is `~`
415+- Lisp-style cons (construct a cell/prepend an element) is
416+ `[new-element list]`
417+- For example, the first three positive integers are `[1 2 3
418+ ~]`
419+- `gte` tests whether `a` is greater than or equal to `b`.
420+- `mod` runs the modulo operation on two atoms.
421+- See the [basic math section]() for more info.
docs/dev/hoon/leap-in/2-network.mdnew file+335
@@ -0,0 +1,335 @@
1+---
2+next: false
3+sort: 2
4+title: Network Messages
5+---
6+
7+Enough of pure hoonery. Let's get to the good stuff. Let's get
8+our planets to talk to each other.
9+
10+Of course, for talking to be of any use, we need someone
11+listening. What we've written up until now are just shell
12+commands that produce a value and then disappear. We need an
13+actual app to listen for messages from another planet. Let's
14+take a look at a very basic one.
15+
16+```
17+:: There is no love that is not an echo
18+::
19+:::: /hoon/echo/ape
20+ ::
21+/? 314
22+!:
23+|_ [bowl state=~]
24+++ poke-noun
25+ |= arg=*
26+ ^- [(list) _+>.$]
27+ ~& [%argument arg]
28+ [~ +>.$]
29+--
30+```
31+
32+This is a very simple app that does only one thing. If you poke
33+it with a value it prints that out. You have to start the app,
34+then you can poke it from the command line with the following
35+commands:
36+
37+```
38+~fintud-macrep:dojo> |start %echo
39+>=
40+~fintud-macrep:dojo> :echo 5
41+[%argument 5]
42+>=
43+~fintud-macrep:dojo> :echo [1 2]
44+[%argument [1 2]]
45+>=
46+```
47+
48+> There is currently a bug where the `%argument` lines are
49+> printed *above* the line you entered, so your output may not
50+> look exactly like this.
51+
52+Most of the app code should be simple enough to guess its
53+function. The important part of this code is the definition of
54+`++poke-noun`.
55+
56+Once an app starts, it's always on in the background, and you
57+interact with it by sending it messages. The most
58+straightforward way to do that is to poke it from the command
59+line. When you do that, `++poke-noun` is called from your app.
60+
61+In our case, `++poke-noun` takes an argument `arg` and prints it
62+out with `~&`. This is an unusual rune that formally "does
63+nothing", but the interpreter detects it and printfs the first
64+child. This is a slightly hacky way of printing to the console,
65+and we'll get to the correct way later on.
66+
67+But what does `++poke-noun` produce? Recall that `^-` casts to a
68+type. In this case, it's declaring that end result of the
69+function will be of type `[(list) _+>.$]`. But what does this
70+mean?
71+
72+The phrase to remember is "a list of moves and our state". Urbit
73+is a message passing system, so whenver we want to do something
74+that interacts with the rest of the system we send a message.
75+Thus, a move is arvo's equivalent of a syscall. The first
76+thing that `++poke-noun` produces is a list of messages, called
77+"moves". In this case, we don't actually want the system to do
78+anything, so we produce the empty list, `~` (in the `[~ +>.$]`
79+line).
80+
81+The second thing `++poke-noun` produces is our state. `+>.$`
82+refers to a particular address in our subject where our formal
83+app state is stored. It'll become clear why this is later on,
84+but for now pretend that `+>.$` is a magic invocation that means
85+"app state".
86+
87+Let's look at another example. Say we want to only accept a
88+number, and then print out the square of that number.
89+
90+```
91+/? 314
92+!:
93+|_ [bowl state=~]
94+::
95+++ poke-atom
96+ |= arg=@
97+ ^- [(list) _+>.$]
98+ ~& [%square (mul arg arg)]
99+ [~ +>.$]
100+--
101+```
102+
103+A few things have changed. Firstly, we no longer accept
104+arbitrary nouns because we can only square atoms. Thus, our
105+argument is now `arg=@`. Secondly, it's `++poke-atom` rather
106+than `++poke-noun`.
107+
108+Are there other `++poke`s? Definitely. In fact, `noun` and
109+`atom` are just two of arbitrarily many "marks". A mark is
110+fundamentally a type definition, but accessible at the arvo
111+level. Each mark is defined in the `/mar` directory. Some marks
112+have conversion routines to other marks, and some have diff,
113+patch, and merge algorithms. None of these are required for a
114+mark to exist, though.
115+
116+`noun` and `atom` are two of dozens of predefined marks, and the
117+user may add more at will. The type associated with `noun` is
118+`*`, and the type associated with `atom` is `@`.
119+
120+Data constructed on the command line is by default marked with
121+`noun`. In this case, the app is expecting an atom, so we have
122+to explicitly mark the data with `atom`. Try the following
123+commands:
124+
125+```
126+~fintud-macrep:dojo> |start %square
127+>=
128+~fintud-macrep:dojo> :square 6
129+gall: %square: no poke arm for noun
130+~fintud-macrep:dojo> :square &atom 6
131+[%square 36]
132+>=
133+```
134+
135+> Recall the bug where `%square` may get printed above the input
136+> line.
137+
138+Marks are powerful, and they're the backbone of urbit's data
139+pipeline, so we'll be getting quite used to them.
140+
141+**Exercises**:
142+
143+- Write an app that computes fizzbuzz on its input (as in the
144+ previous section).
145+
146+- One way of representing strings is with double quoted strings
147+ called "tapes". The hoon type is `tape`, and there is a
148+ corresponding mark with the same name. Write an app that
149+ accepts a tape and prints out `(flop argument)`, where
150+ `argument` is the input. What does this do?
151+
152+
153+Let's write our first network message! Here's `/ape/pong.hoon`:
154+
155+```
156+/? 314
157+|%
158+ ++ move ,[bone term path *]
159+--
160+!:
161+|_ [bowl state=~]
162+::
163+++ poke-urbit
164+ |= to=@p
165+ ^- [(list move) _+>.$]
166+ [[[ost %poke /sending [to %pong] %atom 'howdy'] ~] +>.$]
167+::
168+++ poke-atom
169+ |= arg=@
170+ ^- [(list move) _+>.$]
171+ ~& [%receiving (,@t arg)]
172+ [~ +>.$]
173+::
174+++ coup |=(* [~ +>.$])
175+--
176+```
177+
178+Run it with these commands:
179+
180+```
181+~fintud-macrep:dojo> |start %pong
182+>=
183+~fintud-macrep:dojo> :pong &urbit ~sampel-sipnym
184+>=
185+```
186+
187+Replace `~sampel-sipnym` with another urbit. Don't forget to
188+start the `%pong` app on that urbit too. You should see, on the
189+foreign urbit, this output:
190+
191+```
192+[%receiving 'howdy']
193+```
194+
195+Most of the code should be straightforward. In `++poke-atom`,
196+the only new thing is the expression `(,@t arg)`. As we already
197+know, `@t` is the type of "cord" text strings. `,` is an
198+operator that turns a type into a validator function -- that is,
199+a function whose domain is all nouns and range is the given type,
200+and which is identity when the domain is restricted to the given
201+type. In simpler terms, it's a function that coerces any value
202+to the given type. We call this `,@t` function on the argument.
203+This coerces the argument to text, so that we can print it out
204+prettily.
205+
206+The more interesting part is in `++poke-urbit`. The `urbit` mark
207+is an urbit identity, and the hoon type associated with it is
208+`@p` (the "p" stands for "phonetic base").
209+
210+Recall that in a `++poke` arm we produce "a list of moves and our
211+state". Until now, we've left the list of moves empty, since we
212+haven't wanted to tell arvo to do anything in particular. Now we
213+want to send a message to another urbit. Thus, we produce a list
214+with one element:
215+
216+```
217+[ost %poke /sending [to %pong] %atom 'howdy']
218+```
219+
220+The general form of a move is
221+
222+`[bone term path *]`
223+
224+If you look up `++bone` in `hoon.hoon`, you'll see that it's a
225+number (`@ud`), and that it's an opaque reference to a duct.
226+`++duct` in hoon.hoon is a list of `wire`s, where `wire` is an
227+alias for `path`. `++path` is a list of `span`s, which are ASCII
228+text. Thus, a duct is a list of paths, and a bone is an opaque
229+reference to that duct (in the same way that a Unix file
230+descriptor is an opaque reference to a file structure). Thus,
231+the center of all this is the concept of a "duct".
232+
233+A duct is stack of causes, represented as paths. At the bottom
234+of every duct is a unix event, such as a keystroke, network
235+packet, file change, or timer event. When arvo is given this
236+event, it routes the event to appropriate kernel module for
237+handling.
238+
239+Sometimes, the module can immediately handle the event and
240+produce any necessary results. Otherwise, it asks other kernel
241+modules or applications to do certain things, and produces the
242+result from that. When it sends a message to another kernel
243+module or application, it sends it "along" the duct it was given,
244+plus with a new path. Arvo pushes the new path onto the duct.
245+Now the duct has two entries, with the unix even on the bottom
246+and the kernel module that handled it next. This process can
247+continue indefinitely, adding more and more layers onto the duct.
248+When an entity produces a result, a layer is popped off the duct.
249+
250+In effect, a duct is an arvo-level call stack. The duct system
251+creates a structured message-passing system. It's worth noting
252+that while in traditional call stacks a function call happens
253+synchronously and returns exactly once, in arvo multiple moves
254+can be sent at once, they are evaluated asynchronously, and each
255+one may be responded to zero or more times.
256+
257+Anyhow, the point is that whatever caused `++poke-urbit` to be
258+called is also the root cause for the network message we're
259+trying to send. Thus, we say to send the network message along
260+the given bone `ost`. Of course, we have to push a layer to the
261+duct. This layer can have any data we want in it, but we don't
262+need anything specific here, so we just use `/sending`. If we
263+were expecting a response (which we're not), it would come back
264+along the `/sending` path. It's a good idea for debugging
265+purposes to make the path human-readable, but it's not necessary.
266+
267+Looking back at the general form of a move, there is a `term`,
268+which in this case is `%poke`. This is the name of the
269+particular kind of move we're sending. If you think of a move as
270+a syscall (which you should), then this `term` is the name of the
271+syscall. Common ones include: `%poke`, to message an app;
272+`%warp`, to read from the filesystem; `%wait`, to set a timer;
273+and `%them`, to send an http request.
274+
275+The general form ends with `*` since each type of move takes
276+different data. In our case, a `%poke` move takes a target
277+(urbit and app) and marked data and pokes that app on that urbit
278+with that data. `[to %pong]` is the target urbit and app,
279+`%atom` is the mark`, and `'howdy'` is the data.
280+
281+When arvo receives a `%poke` move, it calls the appropriate
282+`++poke`. The same mechanism is used for sending messages
283+between apps on the same urbit as for sending messages between
284+apps on different urbits.
285+
286+> We said earlier that we're not expecting a response. This is
287+> not entirely true: the `++coup` is called when we receive
288+> acknowledgment that the `++poke` was called. We don't do
289+> anything with this information right now, but we could.
290+
291+**Exercises**:
292+
293+- Extend either of the apps in the first two exercises to accept
294+ input over the network in the same way as `pong`.
295+
296+- Modify `pong` to print out a message when it receives an ack.
297+
298+- Write two apps, `even` and `odd`. When you pass an atom to
299+ `even`, check whether it's even. If so, divide it by two and
300+ recurse; otherwise, poke `odd` with it. When `odd` recieves
301+ an atom, check whether it's equal to one. If so, terminate,
302+ printing "%success". Otherwise, check whether it's odd. If
303+ so, multiply it by three, add one, and recurse; otherwise, poke
304+ `even` with it. multiply it by three and add one. When either
305+ app receives a number, print it out along with the name of the
306+ app. In the end, you should be able to watch Collatz's
307+ conjecture play out between the two apps. Sample output:
308+
309+```
310+~fintud-macrep:dojo> :even &atom 18
311+[%even 18]
312+[%odd 9]
313+[%even 28]
314+[%even 14]
315+[%odd 7]
316+[%even 22]
317+[%odd 11]
318+[%even 34]
319+[%odd 17]
320+[%even 52]
321+[%even 26]
322+[%odd 13]
323+[%even 40]
324+[%even 20]
325+[%even 10]
326+[%odd 5]
327+[%even 16]
328+[%even 8]
329+[%even 4]
330+[%even 2]
331+%success
332+```
333+
334+- Put `even` and `odd` on two separate ships and pass the
335+ messages over the network.
docs/dev/hoon/leap-in/3-app.mdnew file+55
@@ -0,0 +1,55 @@
1+---
2+hide: true
3+next: false
4+sort: 3
5+title: Advanced Applications
6+---
7+
8+XXX PLACEHOLDER
9+
10+But what is our app state, exactly? In Unix systems, application
11+state is just a block of memory, which you need to serialize to
12+disk if you want to keep it around for very long.
13+
14+In urbit, app state is a single (usually complex) value. In our
15+example, we don't have any special state, so we defined
16+`state=~`, meaning that our state is null. Of course, `state` is
17+just a name we're assigning to it, and you're free to use
18+whatever name you want.
19+
20+Since urbit is purely functional, we can't just implicitly "have"
21+and "change" our state. Rather, it's explicitly passed to us, in
22+the `|_ [bowl state=~]` line, and we produce the new state with
23+`+>.$` in the `[~ +>.$]` line.
24+
25+Two points you may be wondering about. Firstly, `bowl` is a set
26+of general global state that is managed by the system. It
27+includes things like `now` (current time), `our` (our urbit
28+identity), and `eny` (256 bits of guaranteed-fresh entropy). For
29+the full list of things in `++bowl`, search for `++ bowl` (note
30+the double space) in `/arvo/zuse.hoon`.
31+
32+> This is a very common technique in learning hoon. While some
33+> documentation exists, often the easiest way to learn about an
34+> identifier you see in code is to search in `/arvo/zuse.hoon`
35+> and `/arvo/hoon.hoon` for it. These are our two "standard
36+> libraries", and they're usually not hard to read. Since
37+> urbit's codebase is relatively small (those two files are less
38+> than 15000 lines of code combined, and besides the standard
39+> library they include the hoon parser and compiler, plus the
40+> /arvo microkernel), you can usually use the code and the
41+> comments as reference doc.
42+
43+Second point is that urbit needs no "serialize to disk" step.
44+Everything you produce in the app state is persistent across
45+calls to the app, restarts of the urbit, and even power failure.
46+If you want to write to the filesystem, you can, but it's not
47+needed for persistence. Urbit has transactional events, which
48+makes it an ACID operating system. Persistence is just another
49+one of those things you don't have to worry about when
50+programming in urbit.
51+
52+As fascinating as state is, we don't actually need any state to
53+accomplish our immediate goal, which is to get apps on two urbits
54+talking to each other. We'll discuss state more in a later
55+chapter.
docs/dev/hoon/library.mdnew file+7
@@ -0,0 +1,7 @@
1+Library
2+========
3+
4+<list dataPreview="true" titlesOnly="true"></list>
5+
6+
7+<search/>
docs/dev/hoon/library/0.mdnew file+37
@@ -0,0 +1,37 @@
1+volume 0, Kelvin Versioning.
2+===========================
3+
4+### `++hoon`
5+
6+ ++ hoon %164 :: version stub
7+
8+Declares the current Hoon version number in degrees Kelvin.
9+
10+When normal people release normal software, they count by fractions, and
11+they count up. Thus, they can keep extending and revising their systems
12+incrementally. This is generally considered a good thing. It generally
13+is.
14+
15+In some cases, however, specifications needs to be permanently frozen.
16+This requirement is generally found in the context of standards. Some
17+standards are extensible or versionable, but some are not. ASCII, for
18+instance, is perma-frozen. So is IPv4 (its relationship to IPv6 is
19+little more than nominal - if they were really the same protocol, they'd
20+have the same ethertype). Moreover, many standards render themselves
21+incompatible in practice through excessive enthusiasm for extensibility.
22+They may not be perma-frozen, but they probably should be.
23+
24+The true, Martian way to perma-freeze a system is what I call Kelvin
25+versioning. In Kelvin versioning, releases count down by integer degrees
26+Kelvin. At absolute zero, the system can no longer be changed. At 1K,
27+one more modification is possible. And so on. For instance, Nock is at
28+5K. It might change, though it probably won't. Nouns themselves are at
29+0K - it is impossible to imagine changing anything about their three
30+sentence definition.
31+
32+------------------------------------------------------------------------
33+
34+ ~zod/try=> stub
35+ 164
36+
37+------------------------------------------------------------------------
docs/dev/hoon/library/1.mdnew file+1786
@@ -0,0 +1,1786 @@
1+volume 1, Hoon Structures
2+=========================
3+
4+------------------------------------------------------------------------
5+
6+### `++abel`
7+
8+ ++ abel typo :: original sin: type
9+
10+Biblical names in hoon are primarily aliases for the compiler.
11+
12+See also: `++typo`
13+
14+ ~zod/try=> *abel
15+ %void
16+
17+------------------------------------------------------------------------
18+
19+### `++axis`
20+
21+ ++ axis ,@ :: tree address
22+
23+A Nock axis inside a noun. After the leading 1, in binary, a 1 signfies
24+right and 0 left.
25+
26+See also: `++clue`, `++limb`, `++slot`, `++peg`, and Section 2fC
27+
28+ ~zod/try=> *axis
29+ 0
30+
31+ ~zod/try=> :: 0 is not actually a valid axis
32+ ~zod/try=> [[4 5] 6 7]
33+ [[4 5] 6 7]
34+ ~zod/try=> `axis`0b110
35+ 6
36+
37+------------------------------------------------------------------------
38+
39+### `++also`
40+
41+ ++ also ,[p=term q=wing r=type] :: alias
42+
43+XX unused?
44+
45+------------------------------------------------------------------------
46+
47+### `++base`
48+
49+ ++ base ?([%atom p=odor] %noun %cell %bean %null) :: axils, @ * ^ ? ~
50+
51+A base type that nouns are built from. Either a noun, a cell, loobean or
52+null labelled with an odor.
53+
54+See also: `++tile`, `++twig`
55+
56+ ~zod/try=> *base
57+ %null
58+
59+ ~zod/try=> (ream '=|(^ !!)')
60+ [%tsbr p=[%axil p=%cell] q=[%zpzp ~]]
61+ ~zod/try=> :: p.p is a ++base
62+ ~zod/try=> (ream '=|(@t !!)')
63+ [%tsbr p=[%axil p=[%atom p=~.t]] q=[%zpzp ~]]
64+ ~zod/try=> (ream '=|(? !!)')
65+ [%tsbr p=[%axil p=%bean] q=[%zpzp ~]]
66+
67+------------------------------------------------------------------------
68+
69+### `++bean`
70+
71+ ++ bean ,? :: 0=&=yes, 1=|=no
72+
73+The Urbit version of a boolean, which we call a loobean. 0 or & is
74+"yes", 1 or | is "no".
75+
76+ ~zod/try=> *bean
77+ %.y
78+
79+ ~zod/try=> `bean`&
80+ %.y
81+ ~zod/try=> `bean`|
82+ %.n
83+
84+------------------------------------------------------------------------
85+
86+### `++beer`
87+
88+ ++ beer $|(@ [~ p=twig]) :: simple embed
89+
90+Used to build tapes internally.
91+
92+See also: `++phax`, `++scat`, section 2fD
93+
94+ ~zod/try=> `beer`'as'
95+ 29.537
96+ ~zod/try=> `beer`[~ (ream 'lan')]
97+ [~ p=[%cnzz p=~[%lan]]]
98+
99+------------------------------------------------------------------------
100+
101+### `++beet`
102+
103+ ++ beet $| @ :: advanced embed
104+ $% [%a p=twig] :: take tape
105+ [%b p=twig] :: take manx
106+ [%c p=twig] :: take marl
107+ [%d p=twig] :: take $+(marl marl)
108+ [%e p=twig q=(list tuna)] :: element literal
109+ == ::
110+
111+Cases for XML interpolation. Used internally.
112+
113+See also: `++sail`, section 2fD
114+
115+------------------------------------------------------------------------
116+
117+### `++bloq`
118+
119+ ++ bloq ,@ :: blockclass
120+
121+Atom representing a blocksize, by convention expressed as a power of 2.
122+
123+See also: section 2cA
124+
125+ ~zod/try=> :: ++met measures how many bloqs long an atom is
126+ ~zod/try=> (met 3 256)
127+ 2
128+ ~zod/try=> :: 256 is 2 bloqs of 2^3
129+
130+------------------------------------------------------------------------
131+
132+### `++calf`
133+
134+ ++ calf ,[p=(map ,@ud wine) q=wine] ::
135+
136+Encodes cyclical backreferences in types. Used in pretty printing.
137+
138+See also: `++wine`, `++dole`, `++doge`, `++dish`, section 2fC
139+
140+ ~zod/try=> `calf`[~ %atom %ta]
141+ [p={} q=[%atom p=%ta]]
142+
143+ ~zod/try=> `calf`~(dole ut p:!>(*^))
144+ [p={} q=[%plot p=~[%noun %noun]]]
145+
146+ ~zod/try=> `calf`~(dole ut p:!>($:|-(?(~ [* $]))))
147+ [ p={[p=1 q=[%pick p=~[[%pear p=%n q=0] [%plot p=~[%noun [%stop p=1]]]]]]}
148+ q=[%stop p=1]
149+ ]
150+
151+------------------------------------------------------------------------
152+
153+### `++char`
154+
155+ ++ char ,@tD :: UTF-8 byte
156+
157+A single character. Odor `@tD` designates a single Unicode byte. All
158+parsers consume `++tape` (a list of `++char`).
159+
160+See also: `++tape`, `++lust`, `++just`, `++mask`, chapter 2f
161+
162+ ~zod/try=> *char
163+ ~~
164+
165+ ~zod/try=> (char 97)
166+ ~~a
167+
168+------------------------------------------------------------------------
169+
170+### `++chub`
171+
172+ ++ chub :: registered battery
173+ $: p=(pair chum tyre) :: definition
174+ q=* :: battery
175+ r=(unit (pair axis chub)) :: parent
176+ == ::
177+
178+Used by the compiler (implicitly by `%sgcn`) to attach jets.
179+
180+See also: Section 2fB.
181+
182+------------------------------------------------------------------------
183+
184+### `++chum`
185+
186+ ++ chum $? lef=term :: jet name
187+ [std=term kel=@] :: kelvin version
188+ [ven=term pro=term kel=@] :: vendor and product
189+ [ven=term pro=term ver=@ kel=@] :: all of the above
190+ == ::
191+
192+Jet hint information that must be present in the body of a \~/ or \~%
193+rune. A `++chum` can optionally contain a kelvin version, jet vendor,
194+and major.minor version number.
195+
196+XX there's a ++chum in zuse that's politely causing this not to work
197+
198+See also: `++twig`, `++clue`
199+
200+ ~zod/try=> `chum`'hi'
201+ lef=%hi
202+
203+ ~zod/try=> (ream '~/(%lob.314 !!)')
204+ [%sgfs p=[std=%lob kel=314] q=[%zpzp ~]]
205+
206+------------------------------------------------------------------------
207+
208+### `++clue`
209+
210+ ++ clue ,[p=axis q=chum r=tyre] :: battery definition
211+
212+Used by compiler to attach jets.
213+
214+XX implementation does not currenlty match docs
215+
216+See also: section 2fB
217+
218+------------------------------------------------------------------------
219+
220+### `++coil`
221+
222+ ++ coil $: p=?(%gold %iron %lead %zinc) :: core type
223+ q=type ::
224+ r=[p=?(~ ^) q=(map term foot)] ::
225+ == ::
226+
227+Core information tuple: variance, subject type, optional compiled nock,
228+and arms. Used as an intermediate step within Section 2fB. Converted by
229+`++core` to %core type.
230+
231+See also: `++core`, Section 2fB
232+
233+------------------------------------------------------------------------
234+
235+### `++coin`
236+
237+ ++ coin $% [%$ p=dime] ::
238+ [%blob p=*] ::
239+ [%many p=(list coin)] ::
240+ == ::
241+
242+Noun literal syntax cases: atoms, jammed nouns, and nestable tuples.
243+Parsed and printed using `++so` and `++co` cores in Section 2eL
244+respectively.
245+
246+See also: `++so`, `++co`, Section 2eL, `++dime`
247+
248+ ~zod/try=> `coin`(need (slay '~s1'))
249+ [%$ p=[p=~.dr q=18.446.744.073.709.551.616]]
250+ ~zod/try=> `coin`(need (slay '0x2b59'))
251+ [%$ p=[p=~.ux q=11.097]]
252+
253+ ~zod/try=> ~(rend co [%many ~[[%$ %ud 1] [%$ %tas 'a'] [%$ %s -2]]])
254+ "._1_a_-2__"
255+ ~zod/try=> ._1_a_-2__
256+ [1 %a -2]
257+
258+ ~zod/try=> `@uv`(jam [3 4])
259+ 0v2cd1
260+ ~zod/try=> (slay '~02cd1')
261+ [~ [%blob p=[3 4]]]
262+ ~zod/try=> ~02cd1
263+ [3 4]
264+
265+------------------------------------------------------------------------
266+
267+### `++cord`
268+
269+ ++ cord ,@t :: text atom (UTF-8)
270+
271+One of Hoon's two string types (the other being `++tape`). A cord is an
272+atom of UTF-8 text. `++trip` and `++crip` convert between cord and
273+`++tape`
274+
275+Odor `@t` designates a Unicode atom, little-endian: the first character
276+in the text is the low byte.
277+
278+See also: `++trip`, `++crip`, Section 2eJ
279+
280+ ~zod/try=> `@ux`'foobar'
281+ 0x7261.626f.6f66
282+
283+ ~zod/try=> `@`'urbit'
284+ 499.984.265.845
285+ ~zod/try=> (cord 499.984.265.845)
286+ 'urbit'
287+
288+------------------------------------------------------------------------
289+
290+### `++date`
291+
292+ ++ date ,[[a=? y=@ud] m=@ud t=tarp] :: parsed date
293+
294+A point in time. A loobean designating AD or BC, a year atom, a month
295+atom, and a `++tarp`, which is a day atom and a time.
296+
297+See also: `++year`, `++yore`, Section 2cH, `++stud`, `++dust`, Section
298+3bc
299+
300+ ~zod/try=> `date`(yore ~2014.6.6..21.09.15..0a16)
301+ [[a=%.y y=2.014] m=6 t=[d=6 h=21 m=9 s=15 f=~[0xa16]]]
302+
303+------------------------------------------------------------------------
304+
305+### `++dime`
306+
307+ ++ dime ,[p=@ta q=@] ::
308+
309+Odor-atom pair, used in `++coin`.
310+
311+Convenience methods `++scot` and `++scow` (in Section 2eL) print dimes
312+as cords/tapes, `++slat`, `++slav`, and `++slaw` are used to parse atoms
313+of specific odor.
314+
315+See also: `++so`, `++co`, Section 2eL, `++coin`
316+
317+ ~zod/try=> +>:(slay '0x123')
318+ p=[p=~.ux q=291]
319+
320+------------------------------------------------------------------------
321+
322+### `++dram`
323+
324+ ++ dram $% [| p=(map ,@tas dram)] :: simple unix dir
325+ [& p=@ud q=@] ::
326+ == ::
327+
328+The structure of a unix filesystem tree. A `++dram` is one of two cases:
329+`|` a directory - a map of names to deeper tree structures, `&` a file -
330+a numbered atom of data.
331+
332+XX Unused
333+
334+------------------------------------------------------------------------
335+
336+### `++each`
337+
338+ ++ each |*([a=$+(* *) b=$+(* *)] $%([& p=a] [| p=b])) :: either a or b
339+
340+Tile generator: produces a discriminated fork between two types.
341+
342+ ~zod/try=> :type; *(each cord time)
343+ [%.y p='']
344+ {[%.y p=@t] [%.n p=@da]}
345+
346+------------------------------------------------------------------------
347+
348+### `++edge`
349+
350+ ++ edge ,[p=hair q=(unit ,[p=* q=nail])] :: parsing output
351+
352+Parsing location metadata: optional result and parsing continuation.
353+
354+See also: Section 2eD, `++rule`
355+
356+ ~zod/try=> *edge
357+ [p=[p=0 q=0] q=~]
358+ ~zod/try=> (tall:vast [1 1] "a b")
359+ [p=[p=1 q=2] q=[~ [p=[%cnzz p=~[%a]] q=[p=[p=1 q=2] q=" b"]]]]
360+
361+------------------------------------------------------------------------
362+
363+### `++foot`
364+
365+ ++ foot $% [%ash p=twig] :: dry arm, geometric
366+ [%elm p=twig] :: wet arm, generic
367+ [%oak ~] :: XX not used
368+ [%yew p=(map term foot)] :: XX not used
369+ == ::
370+
371+Cases of arms by variance model.
372+
373+See also: `++ap`, `++ut`, Section 2fB, Section 2fC
374+
375+ ~zod/try=> *foot
376+ [%yew p={}]
377+
378+ ~zod/try=> (ream '|% ++ $ foo --')
379+ [%brcn p={[p=%$ q=[%ash p=[%cnzz p=~[%foo]]]]}]
380+ ~zod/try=> +<+:(ream '|% ++ $ foo --')
381+ t=~[%ash %cnzz %foo]
382+ ~zod/try=> (foot +<+:(ream '|% ++ $ foo --'))
383+ [%ash p=[%cnzz p=~[%foo]]]
384+ ~zod/try=> (foot +<+:(ream '|% +- $ foo --'))
385+ [%elm p=[%cnzz p=~[%foo]]]
386+
387+------------------------------------------------------------------------
388+
389+### `++gate`
390+
391+ ++ gate $+(* *) :: general gate
392+
393+An core with one arm, `$`, which transforms a sample noun into a product
394+noun. If used dryly as a type, subject must have a sample type of `*`.
395+
396+See also: `++lift`, `++cork`, Core Language Doc
397+
398+ ~zod/try=> *gate
399+ <1|mws [* <101.jzo 1.ypj %164>]>
400+ ~zod/try=> `gate`|=(* 0)
401+ <1|mws [* <101.jzo 1.ypj %164>]>
402+
403+ ~zod/try=> (|=(a=* [a 'b']) 'c')
404+ [99 'b']
405+ ~zod/try=> (`gate`|=(a=* [a 'b']) 'c')
406+ [99 98]
407+
408+------------------------------------------------------------------------
409+
410+### `++hair`
411+
412+ ++ hair ,[p=@ud q=@ud] :: parsing trace
413+
414+A pair of two `@ud` used in parsing indicating line and column number.
415+
416+See also: `++last`, Section 2eB
417+
418+ ~zod/try=> *hair
419+ [p=0 q=0]
420+
421+ ~zod/try=> `hair`[1 1] :: parsing starts at [1 1] as a convention.
422+ [p=1 q=1]
423+ ~zod/try=> ((plus ace) [1 1] " --")
424+ [p=[p=1 q=4] q=[~ u=[p=[~~. " "] q=[p=[p=1 q=4] q="--"]]]]
425+ ~zod/try=> `hair`p:((plus ace) [1 1] " --")
426+ [p=1 q=4]
427+
428+------------------------------------------------------------------------
429+
430+### `++like`
431+
432+ ++ like |* a=_,* :: generic edge
433+ |= b=_`*`[(hair) ~] ::
434+ :- p=(hair -.b) ::
435+ ^= q ::
436+ ?@ +.b ~ ::
437+ :- ~ ::
438+ u=[p=(a +>-.b) q=[p=(hair -.b) q=(tape +.b)]] ::
439+
440+Tile generator for an `++edge`. `++like` generates an `++edge` with a
441+parsed result set to a specific type.
442+
443+See also: `++easy`, `++just`/`++jest`, `++knee`, `++mask`, `++shim`,
444+`++stir`, `++stun`, Section 2eC
445+
446+ ~zod/try=> *(like char)
447+ [p=[p=0 q=0] q=~]
448+
449+ ~zod/try=> (ace [1 1] " a")
450+ [p=[p=1 q=2] q=[~ [p=~~. q=[p=[p=1 q=2] q="a"]]]]
451+ ~zod/try=> `(like char)`(ace [1 1] " a")
452+ [p=[p=1 q=2] q=[~ [p=~~. q=[p=[p=1 q=2] q="a"]]]]
453+ ~zod/try=> `(like ,@)`(ace [1 1] " a")
454+ [p=[p=1 q=2] q=[~ [p=32 q=[p=[p=1 q=2] q="a"]]]]
455+
456+------------------------------------------------------------------------
457+
458+### `++limb`
459+
460+ ++ limb $|(term $%([%& p=axis] [%| p=@ud q=term])) ::
461+
462+XX move to `++ut`
463+
464+Reference into subject by name/axis
465+
466+See also: section 2fC-2fD
467+
468+ ~zod/try=> (ream '^^$')
469+ [%cnzz p=~[[%.n p=2 q=%$]]]
470+ ~zod/try=> (limb &2:(ream '^^$'))
471+ [%.n p=2 q=%$]
472+ ~zod/try=> (limb &2:(ream '^^^$'))
473+ [%.n p=3 q=%$]
474+
475+------------------------------------------------------------------------
476+
477+### `++line`
478+
479+ ++ line ,[p=[%leaf p=odor q=@] q=tile] :: %kelp case
480+
481+XX move to `++ut`
482+
483+Dicriminated union unionee XX
484+
485+Used in compilation and grammar, section 2fC-2fD
486+
487+ ~zod/try=> (ream '$%([1 a] [%2 b])')
488+ [ %bccm
489+ p
490+ [ %kelp
491+ p
492+ [ i=[p=[%leaf p=~.ud q=1] q=[%herb p=[%cnzz p=~[%a]]]]
493+ t=~[[p=[%leaf p=~.ud q=2] q=[%herb p=[%cnzz p=~[%b]]]]]
494+ ]
495+ ]
496+ ]
497+ ~zod/try=> &3:(ream '$%([1 a] [%2 b])')
498+ p=[p=[%leaf p=%ud q=1] q=[%herb p=[%cnzz p=~[%a]]]]
499+ ~zod/try=> (line &3:(ream '$%([1 a] [%2 b])'))
500+ [p=[%leaf p=~.ud q=1] q=[%herb p=[%cnzz p=~[%a]]]]
501+
502+------------------------------------------------------------------------
503+
504+### `++list`
505+
506+ ++ list |* a=_,* :: null-term list
507+ $|(~ [i=a t=(list a)]) ::
508+
509+Tile generator. `++list` generates a tile of a null-terminated list of
510+homogenous type.
511+
512+See also: `++turn`, `++snag`, section 2bB.
513+
514+ ~zod/try=> *(list)
515+ ~
516+ ~zod/try=> `(list ,@)`"abc"
517+ ~[97 98 99]
518+ ~zod/try=> (snag 0 "abc")
519+ ~~a
520+
521+------------------------------------------------------------------------
522+
523+### `++lone`
524+
525+ ++ lone |*(a=$+(* *) ,p=a) :: just one thing
526+
527+XX unused
528+
529+Tile generator. `++lone` puts face of `p` on something.
530+
531+------------------------------------------------------------------------
532+
533+### `++mane`
534+
535+ ++ mane $|(@tas [@tas @tas]) :: XML name/space
536+
537+An XML name (tag name or attribute name) with an optional namespace.
538+Parsed by `++name`:poxa, rendered by `++name`:poxo.
539+
540+See also: `++sail` doc, Section 3bD
541+
542+ ~zod/try=> *mane
543+ %$
544+
545+ ~zod/try=> `mane`n.g:`manx`;div:namespace;
546+ %div
547+ ~zod/try=> `mane`n.g:`manx`;div_namespace;
548+ [%div %namespace]
549+
550+------------------------------------------------------------------------
551+
552+### `++manx`
553+
554+ ++ manx ,[g=marx c=marl] :: XML node
555+
556+XML node.
557+
558+Parsed by `++apex`:poxa, rendered by `++poxo`, section 3bD
559+
560+See also: `++sail` doc, Section 3bD
561+
562+------------------------------------------------------------------------
563+
564+### `++marl`
565+
566+ ++ marl (list manx) :: XML node list
567+
568+List of XML nodes.
569+
570+Parsed within `++apex`:poxa, rendered by `++many`:poxo, section 3bD
571+
572+See also: `++sail` doc
573+
574+------------------------------------------------------------------------
575+
576+### `++mars`
577+
578+ ++ mars ,[t=[n=%$ a=[i=[n=%$ v=tape] t=~]] c=~] :: XML cdata
579+
580+XML CDATA. Implicitly produced by `++chrd`:poxa
581+
582+See also: `++sail` doc
583+
584+------------------------------------------------------------------------
585+
586+### `++mart`
587+
588+ ++ mart (list ,[n=mane v=tape]) :: XML attributes
589+
590+List of XML attributes. Each `++mart` is a list of pairs of `++mane` and
591+`++tape`.
592+
593+Parsed by `++attr`:poxa, rendered by `++attr`:poxo, section 3bD
594+
595+See also: `++sail` doc
596+
597+------------------------------------------------------------------------
598+
599+### `++marx`
600+
601+ ++ marx ,[n=mane a=mart] :: XML tag
602+
603+XML tag. A `++marx` is a pair of a tag name, `++mane` and a list of
604+attributes, `++mart`.
605+
606+Parsed by `++head`:poxa, rendered within `++poxo`, section 3bD
607+
608+See also: `++sail` doc
609+
610+------------------------------------------------------------------------
611+
612+### `++metl`
613+
614+ ++ metl ?(%gold %iron %zinc %lead) :: core variance
615+
616+XX move to `++ut`
617+
618+See also: `++coil`
619+
620+------------------------------------------------------------------------
621+
622+### `++noun`
623+
624+ ++ noun ,* :: any noun
625+
626+Used nowhere XX
627+
628+ ~zod/try=> `noun`~[1 2 3]
629+ [1 2 3 0]
630+
631+------------------------------------------------------------------------
632+
633+### `++null`
634+
635+ ++ null ,~ :: null, nil, etc
636+
637+Used nowhere XX
638+
639+ ~zod/try=> :type; *null
640+ ~
641+ %~
642+
643+------------------------------------------------------------------------
644+
645+### `++odor`
646+
647+ ++ odor ,@ta :: atom format
648+
649+By convetion, a short name for a category of atom. `++odor` is
650+circularly defined, `@ta` being the `++odor` of the ASCII subset
651+commonly used in urbit.
652+
653+See also: `++base`, odor reference
654+
655+ ~zod/try=> `odor`%ux
656+ ~.ux
657+
658+------------------------------------------------------------------------
659+
660+### `++tarp`
661+
662+ ++ tarp ,[d=@ud h=@ud m=@ud s=@ud f=(list ,@ux)] :: parsed time
663+
664+The remaining part of a `++date`: day, hour, minute, second and a list
665+of `@ux` for precision.
666+
667+See also: `++date`, `++yell`/`++yule`, Section 2cH
668+
669+ ~zod/try=> -<-
670+ ~2014.9.20..00.43.33..b52a
671+ ~zod/try=> :: the time is always in your context at -<-
672+ ~zod/try=> (yell -<-)
673+ [d=106.751.991.820.278 h=0 m=43 s=39 f=~[0x54d1]]
674+
675+ ~zod/try=> (yell ~d20)
676+ [d=20 h=0 m=0 s=0 f=~]
677+
678+------------------------------------------------------------------------
679+
680+### `++time`
681+
682+ ++ time ,@da :: galactic time
683+
684+The `@da` odor designates an absolute date atom.
685+
686+See also: `++date`, odor reference
687+
688+ ~zod/try=> `time`-<-
689+ ~2014.9.25..20.01.47..eeac
690+ ~zod/try=> :: the time is always in your context at -<-
691+ ~zod/try=> `time`~2014.1.1
692+ ~2014.1.1
693+
694+------------------------------------------------------------------------
695+
696+### `++tree`
697+
698+ ++ tree |* a=_,* :: binary tree
699+ $|(~ [n=a l=(tree a) r=(tree a)]) ::
700+
701+Tile generator. A `++tree` can be empty, or contain a node of a type and
702+left/right sub `++tree`s of the same type. Pretty-printed with `{}`.
703+
704+ ~zod/try=> `(tree ,[@ tape])`[[1 "hi"] [[2 "bye"] ~ ~] ~]
705+ {[2 "bye"] [1 "hi"]}
706+
707+------------------------------------------------------------------------
708+
709+### `++nail`
710+
711+ ++ nail ,[p=hair q=tape] :: parsing input
712+
713+Location in parsed text, and remainder of it. Indicates parsing position
714+and remaining text to be parsed.
715+
716+See also: `++roll`
717+
718+ ~zod/try=> +<:;~(plug cab cab)
719+ c=tub=[p=[p=0 q=0] q=""]
720+ ~zod/try=> :: tub is a ++nail
721+
722+------------------------------------------------------------------------
723+
724+### `++numb`
725+
726+ ++ numb ,@ :: just a number
727+
728+Used nowhere XX
729+
730+------------------------------------------------------------------------
731+
732+### `++pair`
733+
734+ ++ pair |*([a=$+(* *) b=$+(* *)] ,[p=a q=b]) :: just a pair
735+
736+Tile generator. Produces a tuple of two of the types passed in.
737+
738+ ~zod/try=> *(pair bean cord)
739+ [p=%.y q='']
740+
741+------------------------------------------------------------------------
742+
743+### `++pass`
744+
745+ ++ pass ,@ :: public key
746+
747+Atom alias. Used primarily in crypto.
748+
749+See also: `++acru`, `++crua`, `++crub`
750+
751+------------------------------------------------------------------------
752+
753+### `++path`
754+
755+ ++ path (list span) :: filesys location
756+
757+A filesystem path. A `++path` is a list of `++span`, `@ta`. Used in
758+`%clay` and `%eyre` extensively.
759+
760+ ~zod/try=> `path`"abc"
761+ /a/b/c
762+
763+------------------------------------------------------------------------
764+
765+### `++pint`
766+
767+ ++ pint ,[p=[p=@ q=@] q=[p=@ q=@]] :: line/column range
768+
769+A parsing range, mostly used for stacktraces. A `++pint` is a pair of
770+hairs indicating from - to.
771+
772+ ~zod/try=> !:(!!)
773+ ! /~zod/try/~2014.9.20..01.22.04..52e3/:<[1 4].[1 6]>
774+ ~zod/try=> :: !! always produces a crash
775+ ~zod/try=> `pint`[[1 4] [1 6]]
776+ [p=[p=1 q=4] q=[p=1 q=6]]
777+
778+------------------------------------------------------------------------
779+
780+### `++pole`
781+
782+ ++ pole |* a=_,* :: nameless list
783+ $|(~ [a (pole a)]) ::
784+
785+A `++list` without the faces. A `++pole` is a null-terminated tuple
786+without the `i=` and `t=`.
787+
788+ ~zod/try=> `(pole char)`"asdf"
789+ [~~a [~~s [~~d [~~f ~]]]]
790+
791+------------------------------------------------------------------------
792+
793+### `++port`
794+
795+ ++ port $: p=axis ::
796+ $= q ::
797+ $% [%& p=type] ::
798+ [%| p=axis q=(list ,[p=type q=foot])] ::
799+ == ::
800+ == ::
801+
802+XX move to `++ut`
803+
804+Type and location of core-shaped thing? XX Compiler Internals
805+
806+ ~zod/try=> *port
807+ [p=0 q=[%.y p=%void]]
808+
809+------------------------------------------------------------------------
810+
811+### `++post`
812+
813+ ++ post $: p=axis ::
814+ $= q ::
815+ $% [0 p=type] ::
816+ [1 p=axis q=(list ,[p=type q=foot])] ::
817+ [2 p=twin q=type] ::
818+ == ::
819+ == ::
820+
821+XX move to `++ut`
822+
823+Type and location of possibly core-shaped thing? XX Compiler Internals
824+
825+ ~zod/try=> *post
826+ [p=0 q=[%0 p=%void]]
827+
828+------------------------------------------------------------------------
829+
830+### `++prop`
831+
832+ ++ prop $: p=axis ::
833+ $= q ::
834+ [p=?(~ axis) q=(list ,[p=type q=foot])] ::
835+ == ::
836+
837+XX move to `++ut`
838+
839+Verified core-shaped thing? XX Compiler Internals
840+
841+ ~zod/try=> *prop
842+ [p=0 q=[p=~ q=~]]
843+
844+------------------------------------------------------------------------
845+
846+### `++qual`
847+
848+ ++ qual |* [a=$+(* *) b=$+(* *) c=$+(* *) d=$+(* *)] :: just a quadruple
849+ ,[p=a q=b r=c s=d] ::
850+
851+Tile generator. A `++qual` is a tuple of four of the types passed in..
852+
853+ ~zod/try=> *(qual date time tape cord)
854+ [p=[[a=%.y y=0] m=0 t=[d=0 h=0 m=0 s=0 f=~]] q=~292277024401-.1.1 r="" s='']
855+
856+------------------------------------------------------------------------
857+
858+### `++rege`
859+
860+ ++ rege $| ?(%dote %ende %sart %empt %boun %bout) :: parsed regex
861+ $% [%lite p=char] :: literal
862+ [%pair p=rege q=rege] :: ordering
863+ [%capt p=rege q=@u] :: capture group
864+ [%brac p=@] :: p is 256 bitmask
865+ [%eith p=rege q=rege] :: either
866+ [%mant p=rege] :: greedy 0 or more
867+ [%plls p=rege] :: greedy 1 or more
868+ [%betw p=rege q=@u r=@u] :: between q and r
869+ [%bint p=rege q=@u] :: min q
870+ [%bant p=rege q=@u] :: exactly q
871+ [%manl p=rege] :: lazy 0 or more
872+ [%plll p=rege] :: lazy 1 or more
873+ [%betl p=rege q=@u r=@u] :: between q and r lazy
874+ [%binl p=rege q=@u] :: min q lazy
875+ == ::
876+
877+Regular expressions. `++rege` defines the cases of a regex.
878+
879+See also: `++rexp`, `++repg`, `++pars`
880+
881+ ~zod/try=> (pars "[a-z]")
882+ [~ [%brac p=10.633.823.807.823.001.954.701.781.295.154.855.936]]
883+ ~zod/try=> (rexp "[a-z]" "abc1")
884+ [~ [~ {[p=0 q="a"]}]]
885+
886+------------------------------------------------------------------------
887+
888+### `++ring`
889+
890+ ++ ring ,@ :: private key
891+
892+Atom alias, used primarily in crypto.
893+
894+See also: `++acru`, `++crua`, `++crub`.
895+
896+------------------------------------------------------------------------
897+
898+### `++rule`
899+
900+ ++ rule |=(tub=nail `edge`[p.tub ~ ~ tub]) :: parsing rule
901+
902+Parsing rule. `++rule` is an empty parsing rule, but it is used to check
903+that parsing rules match this with `_`.
904+
905+See also: `++cold`, Section 2eC
906+
907+ ~zod/try=> *rule
908+ [p=[p=0 q=0] q=[~ [p=0 q=[p=[p=0 q=0] q=""]]]]
909+
910+ ~zod/try=> ^+(rule [|=(a=nail [p.a ~])]:|6)
911+ <1.dww [tub=[p=[p=@ud q=@ud] q=""] <101.jzo 1.ypj %164>]>
912+ ~zod/try=> (^+(rule [|=(a=nail [p.a ~ u=['a' a]])]:|6) [1 1] "hi")
913+ [p=[p=1 q=1] q=[~ [p=97 q=[p=[p=1 q=1] q="hi"]]]]
914+ ~zod/try=> ([|=(a=nail [p.a ~ u=['a' a]])]:|6 [1 1] "hi")
915+ [[p=1 q=1] ~ u=['a' p=[p=1 q=1] q="hi"]]
916+
917+------------------------------------------------------------------------
918+
919+### `++span`
920+
921+ ++ span ,@ta :: text-atom (ASCII)
922+
923+A restricted text atom for canonical atom syntaxes. The prefix is `~.`.
924+There are no escape sequences except `~~`, which means `~`, and `~-`,
925+which means `_`. `-` and `.` encode themselves. No other characters
926+besides numbers and lowercase letters are permitted.
927+
928+ ~zod/try=> *span
929+ ~.
930+
931+ ~zod/try=> `@t`~.foo
932+ 'foo'
933+ ~zod/try=> `@t`~.foo.bar
934+ 'foo.bar'
935+ ~zod/try=> `@t`~.foo~~bar
936+ 'foo~bar'
937+ ~zod/try=> `@t`~.foo~-bar
938+ 'foo_bar'
939+ ~zod/try=> `@t`~.foo-bar
940+ 'foo-bar'
941+
942+------------------------------------------------------------------------
943+
944+### `++spot`
945+
946+ ++ spot ,[p=path q=pint] :: range in file
947+
948+Stack trace line. A `++spot` is what we print after crashing.
949+
950+See also: `++pint`
951+
952+ ~zod/try=> :into /=main=/bin/fail/hoon '!: !!'
953+ + /~zod/main/359/bin/fail/hoon
954+ ~zod/try=> :fail
955+ ! /~zod/main/~2014.9.22..18.40.56..ef04/bin/fail/:<[1 5].[1 7]>
956+ ! exit
957+
958+------------------------------------------------------------------------
959+
960+### `++tang`
961+
962+ ++ tang (list tank) :: general error
963+
964+Unused XX
965+
966+------------------------------------------------------------------------
967+
968+### `++tank`
969+
970+ ++ tank $% [%leaf p=tape] :: printing formats
971+ $: %palm ::
972+ p=[p=tape q=tape r=tape s=tape] ::
973+ q=(list tank) ::
974+ == ::
975+ $: %rose :: delimeted list
976+ p=[p=tape q=tape r=tape] :: mid open close
977+ q=(list tank) ::
978+ == ::
979+ ==
980+
981+Pretty-printing structure. A `++tank` is one of three cases. A `%leaf`
982+is just a string. A `%palm` is XX need more information. A `%rose` is a
983+list of `++tank` delimted by the strings in `p`.
984+
985+ ~zod/try=> >(bex 20) (bex 19)<
986+ [%rose p=[p=" " q="[" r="]"] q=~[[%leaf p="1.048.576"] [%leaf p="524.288"]]]
987+ ~zod/try=> (wash [0 80] >(bex 20) (bex 19)<) :: at 80 cols
988+ <<"[1.048.576 524.288]">>
989+ ~zod/try=> (wash [0 15] >(bex 20) (bex 19)<) :: at 15 cols (two lines)
990+ <<"[ 1.048.576" " 524.288" "]">>
991+
992+ ~zod/try=> [(bex 150) (bex 151)] :: at 80 cols
993+ [ 1.427.247.692.705.959.881.058.285.969.449.495.136.382.746.624
994+ 2.854.495.385.411.919.762.116.571.938.898.990.272.765.493.248
995+ ]
996+
997+------------------------------------------------------------------------
998+
999+### `++tape`
1000+
1001+ ++ tape (list char) :: like a string
1002+
1003+One of Hoon's two string types, the other being `++cord`. A tape is a
1004+list of chars.
1005+
1006+ ~zod/try=> `(list ,char)`"foobar"
1007+ "foobar"
1008+ ~zod/try=> `(list ,@)`"foobar"
1009+ ~[102 111 111 98 97 114]
1010+
1011+------------------------------------------------------------------------
1012+
1013+### `++term`
1014+
1015+ ++ term ,@tas :: Hoon ASCII subset
1016+
1017+A restricted text atom for Hoon constants. The only characters permitted
1018+are lowercase ASCII, - except as the first or last character, and 0-9
1019+except as the first character. The syntax for `@tas` is the text itself,
1020+always preceded by `%`. This means a term is always cubical. The empty
1021+`@tas` has a special syntax, `$`:
1022+
1023+ ~zod/try=> *term
1024+ %$
1025+
1026+ ~zod/try=> %dead-fish9
1027+ %dead-fish9
1028+ ~zod/try=> -:!>(%dead-fish9)
1029+ [%cube p=271.101.667.197.767.630.546.276 q=[%atom p=%tas]]
1030+
1031+------------------------------------------------------------------------
1032+
1033+### `++tiki`
1034+
1035+ ++ tiki :: test case
1036+ $% [& p=(unit term) q=wing] :: simple wing
1037+ [| p=(unit term) q=twig] :: named wing
1038+ == ::
1039+
1040+XX move to `++ut`
1041+
1042+A `++wing` or `++twig`.
1043+
1044+ ~zod/try=> (ream '=+ a=4 ?-(a @ ~)')
1045+ [ %tsls
1046+ p=[%ktts p=p=%a q=[%dtzy p=%ud q=4]]
1047+ q
1048+ [ %wthz
1049+ p=[%.y p=~ q=~[%a]]
1050+ q=~[[p=[%axil p=[%atom p=~.]] q=[%bczp p=%null]]]
1051+ ]
1052+ ]
1053+ ~zod/try=> (ream '=+ a=4 ?-(4 @ ~)')
1054+ [ %tsls
1055+ p=[%ktts p=p=%a q=[%dtzy p=%ud q=4]]
1056+ q
1057+ [ %wthz
1058+ p=[%.n p=~ q=[%dtzy p=%ud q=4]]
1059+ q=~[[p=[%axil p=[%atom p=~.]] q=[%bczp p=%null]]]
1060+ ]
1061+ ]
1062+
1063+------------------------------------------------------------------------
1064+
1065+### `++tile`
1066+
1067+See the Tile section of the Hoon Reference.
1068+
1069+------------------------------------------------------------------------
1070+
1071+### `++toga`
1072+
1073+ ++ toga :: face control
1074+ $| p=term :: two togas
1075+ $% [0 ~] :: no toga
1076+ [1 p=term q=toga] :: deep toga
1077+ [2 p=toga q=toga] :: cell toga
1078+ == ::
1079+
1080+XX move to `++ut` and rune doc (for \^= examples)
1081+
1082+A face, or tree of faces. A `++toga` is applied to anything assigned
1083+using `^=`.
1084+
1085+ ~zod/try=> a=1
1086+ a=1
1087+ ~zod/try=> (ream 'a=1')
1088+ [%ktts p=p=%a q=[%dtzy p=%ud q=1]]
1089+ ~zod/try=> [a b]=[1 2 3]
1090+ [a=1 b=[2 3]]
1091+ ~zod/try=> (ream '[a b]=[1 2 3]')
1092+ [ %ktts
1093+ p=[%2 p=p=%a q=p=%b]
1094+ q=[%cltr p=~[[%dtzy p=%ud q=1] [%dtzy p=%ud q=2] [%dtzy p=%ud q=3]]]
1095+ ]
1096+
1097+ ~zod/try=> [a ~]=[1 2 3]
1098+ [a=1 2 3]
1099+ ~zod/try=> (ream '[a ~]=[1 2 3]')
1100+ [ %ktts
1101+ p=[%2 p=p=%a q=[%0 ~]]
1102+ q=[%cltr p=~[[%dtzy p=%ud q=1] [%dtzy p=%ud q=2] [%dtzy p=%ud q=3]]]
1103+ ]
1104+
1105+------------------------------------------------------------------------
1106+
1107+### `++trap`
1108+
1109+ ++ trap ,_|.(_*) :: makes perfect sense
1110+
1111+A trap is a core with one arm `++$`.
1112+
1113+See also: `|.`
1114+
1115+ ~zod/try=> *trap
1116+ <1.mws 101.jzo 1.ypj %164>
1117+ ~zod/try=> (*trap)
1118+ 0
1119+ ~zod/try=> (|.(42))
1120+ 42
1121+
1122+------------------------------------------------------------------------
1123+
1124+### `++trel`
1125+
1126+ ++ trel |* [a=$+(* *) b=$+(* *) c=$+(* *)] :: just a triple
1127+ ,[p=a q=b r=c] ::
1128+
1129+Tile generator. `++trel` is a tuple of three of the types passed in.
1130+
1131+ ~zod/try=> *(trel ,@ud ,@t ,@s)
1132+ [p=0 q='' r=--0]
1133+
1134+------------------------------------------------------------------------
1135+
1136+### `++tuna`
1137+
1138+ ++ tuna :: tagflow
1139+ $% [%a p=twig] :: plain text
1140+ [%b p=twig] :: single tag
1141+ [%c p=twig] :: simple list
1142+ [%d p=twig] :: dynamic list
1143+ [%e p=twig q=(list tuna)] :: element
1144+ [%f p=(list tuna)] :: subflow
1145+ == ::
1146+
1147+An XML template tree.
1148+
1149+Leaf %a contains plain-text, %b an empty tag, %c a static list, %d a
1150+dynamic list, %e a full node element containing a twig and a list of
1151+tuna, and %f is a empty node.
1152+
1153+See also: `++sail`
1154+
1155+------------------------------------------------------------------------
1156+
1157+### `++twig`
1158+
1159+See Twig section of Hoon reference
1160+
1161+------------------------------------------------------------------------
1162+
1163+### `++tine`
1164+
1165+ ++ tine (list ,[p=tile q=twig]) ::
1166+
1167+Switch statement cases. In `?-`, for example, your list of cases is a
1168+`++tine`.
1169+
1170+See also: `++twig`
1171+
1172+ ~zod/try=> (ream '?-(!! @ |, ^ &)')
1173+ [ %wthz
1174+ p=[%.n p=~ q=[%zpzp ~]]
1175+ q
1176+ ~[
1177+ [p=[%axil p=[%atom p=~.]] q=[%dtzy p=%f q=1]]
1178+ [p=[%axil p=%cell] q=[%dtzy p=%f q=0]]
1179+ ]
1180+ ]
1181+ ~zod/try=> (tine |2:(ream '?-(!! @ |, ^ &)'))
1182+ ~[
1183+ [p=[%axil p=[%atom p=~.]] q=[%dtzy p=%f q=1]]
1184+ [p=[%axil p=%cell] q=[%dtzy p=%f q=0]]
1185+ ]
1186+
1187+------------------------------------------------------------------------
1188+
1189+### `++tusk`
1190+
1191+ ++ tusk (list twig) ::
1192+
1193+Variable-arity expression list. In `:*`, for example, your contents are
1194+a `++tusk`.
1195+
1196+See also: `++twig`
1197+
1198+ ~zod/try=> (ream '[1 2 3]')
1199+ [%cltr p=~[[%dtzy p=%ud q=1] [%dtzy p=%ud q=2] [%dtzy p=%ud q=3]]]
1200+ ~zod/try=> (tusk +:(ream '[1 2 3]'))
1201+ ~[[%dtzy p=%ud q=1] [%dtzy p=%ud q=2] [%dtzy p=%ud q=3]]
1202+
1203+------------------------------------------------------------------------
1204+
1205+### `++tyre`
1206+
1207+ ++ tyre (list ,[p=term q=twig]) ::
1208+
1209+Associative list of term to twig, used in jet hint processing.
1210+
1211+See also: `++twig`
1212+
1213+------------------------------------------------------------------------
1214+
1215+### `++tyke`
1216+
1217+ ++ tyke (list (unit twig)) ::
1218+
1219+List of twigs, or gaps left to be inferred, in path parsing. When you
1220+use a path such as `/=main=/pub/src/doc` the path is in fact a `++tyke`,
1221+where the `=` are inferred from your current path.
1222+
1223+ ~zod/try=> (scan "/==as=" porc:vast)
1224+ [0 ~[~ ~ [~ [%dtzy p=%tas q=29.537]] ~]]
1225+ ~zod/try=> `tyke`+:(scan "/==as=" porc:vast)
1226+ ~[~ ~ [~ [%dtzy p=%tas q=29.537]] ~]
1227+
1228+------------------------------------------------------------------------
1229+
1230+### `++tram`
1231+
1232+ ++ tram (list ,[p=wing q=twig]) ::
1233+
1234+List of changes by location in context. When using `%=`, for example,
1235+the list of changes is a `++tram`.
1236+
1237+See also: `++twig`
1238+
1239+ ~zod/try=> (ream '$(a 1, b 2)')
1240+ [ %cnts
1241+ p=~[%$]
1242+ q=~[[p=~[%a] q=[%dtzy p=%ud q=1]] [p=~[%b] q=[%dtzy p=%ud q=2]]]
1243+ ]
1244+ ~zod/try=> (tram +:(ream '$(a 1, b 2)'))
1245+ ~[[p=~ q=[% p=0]] [p=~[%a] q=[%dtzy p=%ud q=1]] [p=~[%b] q=[%dtzy p=%ud q=2]]]
1246+
1247+------------------------------------------------------------------------
1248+
1249+### `++nock`
1250+
1251+ ++ nock $& [p=nock q=nock] :: autocons
1252+ $% [%0 p=@] :: axis select
1253+ [%1 p=*] :: constant
1254+ [%2 p=nock q=nock] :: compose
1255+ [%3 p=nock] :: cell test
1256+ [%4 p=nock] :: increment
1257+ [%5 p=nock q=nock] :: equality test
1258+ [%6 p=nock q=nock r=nock] :: if, then, else
1259+ [%7 p=nock q=nock] :: serial compose
1260+ [%8 p=nock q=nock] :: push onto subject
1261+ [%9 p=@ q=nock] :: select arm and fire
1262+ [%10 p=?(@ [p=@ q=nock]) q=nock] :: hint
1263+ [%11 p=nock] :: grab data from sky
1264+ == ::
1265+
1266+See Nock doc
1267+
1268+ ~zod/try=> !=([+(.) 20 -<])
1269+ [[4 0 1] [1 20] 0 4]
1270+ ~zod/try=> (nock !=([+(.) 20]))
1271+ [p=[%4 p=[%0 p=1]] q=[%1 p=20]]
1272+
1273+------------------------------------------------------------------------
1274+
1275+### `++tone`
1276+
1277+ ++ tone $% [%0 p=*] :: success
1278+ [%1 p=(list)] :: blocks
1279+ [%2 p=(list ,[@ta *])] :: error ~_s
1280+ == ::
1281+
1282+Intermediate Nock computation result. Similar to `++toon`, but stack
1283+trace is not yet rendered.
1284+
1285+ ~zod/try=> (mink [[20 21] 0 3] ,~)
1286+ [%0 p=21]
1287+
1288+ ~zod/try=> (mink [[0] !=(.^(cy//=main/1))] ,~)
1289+ [%1 p=~[[31.075 1.685.027.454 1.852.399.981 49 0]]]
1290+ ~zod/try=> (path [31.075 1.685.027.454 1.852.399.981 49 0])
1291+ /cy/~zod/main/1
1292+
1293+ ~zod/try=> (mink [[1 2] !=(~|(%hi +(.)))] ,~)
1294+ [%2 p=~[[~.yelp 26.984]]]
1295+ ~zod/try=> (mink [[1 2] !=(!:(+(.)))] ,~)
1296+ [ %2
1297+ p
1298+ ~[
1299+ [ ~.spot
1300+ [ [ 1.685.027.454
1301+ 7.959.156
1302+ \/159.445.990.350.374.058.574.398.238.344.143.957.205.628.479.572.65\/
1303+ 8.112.403.878.526
1304+ \/ \/
1305+ 0
1306+ ]
1307+ [1 20]
1308+ 1
1309+ 24
1310+ ]
1311+ ]
1312+ ]
1313+ ]
1314+
1315+------------------------------------------------------------------------
1316+
1317+### `++toon`
1318+
1319+ ++ toon $% [%0 p=*] :: success
1320+ [%1 p=(list)] :: blocks
1321+ [%2 p=(list tank)] :: stack trace
1322+ == ::
1323+
1324+Nock computation result. Either success (`%0`), a block with list of
1325+requests blocked on (`%1`), or failure with stack trace (`%2`).
1326+
1327+ ~zod/try=> (mock [[20 21] 0 3] ,~)
1328+ [%0 p=21]
1329+
1330+ ~zod/try=> (mock [[0] !=(.^(cy//=main/1))] ,~)
1331+ [%1 p=~[[31.075 1.685.027.454 1.852.399.981 49 0]]]
1332+ ~zod/try=> (path [31.075 1.685.027.454 1.852.399.981 49 0])
1333+ /cy/~zod/main/1
1334+
1335+ ~zod/try=> (mock [[1 2] !=(!:(+(.)))] ,~)
1336+ [%2 p=~[[%leaf p="/~zod/try/~2014.9.23..18.34.32..d3c5/:<[1 20].[1 24]>"]]]
1337+
1338+------------------------------------------------------------------------
1339+
1340+### `++tune`
1341+
1342+ ++ tune $% [%0 p=vase] ::
1343+ [%1 p=(list)] ::
1344+ [%2 p=(list ,[@ta *])] ::
1345+ == ::
1346+
1347+XX Unused
1348+
1349+Probably typed `tone`?
1350+
1351+------------------------------------------------------------------------
1352+
1353+### `++twin`
1354+
1355+ ++ twin ,[p=term q=wing r=axis s=type] :: alias info
1356+
1357+Aliasing. Used in `%bull` `++type` to typecheck aliased faces.
1358+
1359+ ~zod/try=> (~(busk ut %cell %noun [%atom %ud]) %fal [%& 3]~)
1360+ [ %bull
1361+ p=[p=%fal q=~[[%.y p=3]] r=3 s=[%atom p=%ud]]
1362+ q=[%cell p=%noun q=[%atom p=%ud]]
1363+ ]
1364+ ~zod/try=> &2:(~(busk ut %cell %noun [%atom %ud]) %fal [%& 3]~)
1365+ p=[p=%fal q=~[[%.y p=3]] r=3 s=[%atom p=%ud]]
1366+ ~zod/try=> (twin &2:(~(busk ut %cell %noun [%atom %ud]) %fal [%& 3]~))
1367+ [p=%fal q=~[[%.y p=3]] r=3 s=[%atom p=%ud]]
1368+
1369+------------------------------------------------------------------------
1370+
1371+### `++type`
1372+
1373+See Type section of Hoon reference
1374+
1375+------------------------------------------------------------------------
1376+
1377+### `++typo`
1378+
1379+ ++ typo type :: old type
1380+
1381+Pointer for `++type`. `++typo` preserves the previous `++type` in your
1382+context when upating.
1383+
1384+See also: `++seem`, `++vise`, `++type`
1385+
1386+------------------------------------------------------------------------
1387+
1388+### `++udal`
1389+
1390+ ++ udal :: atomic change (%b)
1391+ $: p=@ud :: blockwidth
1392+ q=(list ,[p=@ud q=(unit ,[p=@ q=@])]) :: indels
1393+ == ::
1394+
1395+XX Unused
1396+
1397+------------------------------------------------------------------------
1398+
1399+### `++udon`
1400+
1401+ ++ udon :: abstract delta
1402+ $: p=umph :: preprocessor
1403+ $= q :: patch
1404+ $% [%a p=* q=*] :: trivial replace
1405+ [%b p=udal] :: atomic indel
1406+ [%c p=(urge)] :: list indel
1407+ [%d p=upas q=upas] :: tree edit
1408+ == ::
1409+ == ::
1410+
1411+See `%clay` doc
1412+
1413+------------------------------------------------------------------------
1414+
1415+### `++umph`
1416+
1417+ ++ umph :: change filter
1418+ $| $? %a :: no filter
1419+ %b :: jamfile
1420+ %c :: LF text
1421+ == ::
1422+ $% [%d p=@ud] :: blocklist
1423+ == ::
1424+
1425+See `%clay` doc
1426+
1427+------------------------------------------------------------------------
1428+
1429+### `++unce`
1430+
1431+ ++ unce |* a=_,* :: change part
1432+ $% [%& p=@ud] :: skip[copy]
1433+ [%| p=(list a) q=(list a)] :: p -> q[chunk]
1434+ == ::
1435+
1436+See `%clay` doc
1437+
1438+------------------------------------------------------------------------
1439+
1440+### `++unit`
1441+
1442+ ++ unit |* a=_,* :: maybe
1443+ $|(~ [~ u=a]) ::
1444+
1445+Tile generator. A `++unit` is either `~` or `[~ u=a]` where `a` is the
1446+type that was passed in.
1447+
1448+See also: `++bind`, Section 2bA
1449+
1450+ ~zod/try=> :type; *(unit time)
1451+ ~
1452+ u(@da)
1453+ ~zod/try=> `(unit time)`[~ -<-]
1454+ [~ ~2014.9.24..19.25.10..7dd5]
1455+
1456+------------------------------------------------------------------------
1457+
1458+### `++upas`
1459+
1460+ ++ upas :: tree change (%d)
1461+ $& [p=upas q=upas] :: cell
1462+ $% [%0 p=axis] :: copy old
1463+ [%1 p=*] :: insert new
1464+ [%2 p=axis q=udon] :: mutate!
1465+ == ::
1466+
1467+See `%clay` doc
1468+
1469+------------------------------------------------------------------------
1470+
1471+### `++urge`
1472+
1473+ ++ urge |*(a=_,* (list (unce a))) :: list change
1474+
1475+See `%clay` doc
1476+
1477+------------------------------------------------------------------------
1478+
1479+### `++vase`
1480+
1481+ ++ vase ,[p=type q=*] :: type-value pair
1482+
1483+Typed data. A `++vase` is used wherever typed data is explicitly worked
1484+with.
1485+
1486+See `%arvo` doc
1487+
1488+ ~zod/try=> `vase`!>(~)
1489+ [p=[%cube p=0 q=[%atom p=%n]] q=0]
1490+
1491+------------------------------------------------------------------------
1492+
1493+### `++vise`
1494+
1495+ ++ vise ,[p=typo q=*] :: old vase
1496+
1497+Used to convert from previously-typed data during reboot.
1498+
1499+See `++typo`, `++seer`
1500+
1501+------------------------------------------------------------------------
1502+
1503+### `++wall`
1504+
1505+ ++ wall (list tape) :: text lines (no \n)
1506+
1507+A list of lines. A `++wall` is used instead of a single `++tape` with
1508+`\n`.
1509+
1510+See also: `++wash`
1511+
1512+ ~zod/try=> `wall`(wash [0 20] leaf/<(bex 256)>)
1513+ <<
1514+ "\/115.792.089.237.\/"
1515+ " 316.195.423.570."
1516+ " 985.008.687.907."
1517+ " 853.269.984.665."
1518+ " 640.564.039.457."
1519+ " 584.007.913.129."
1520+ " 639.936"
1521+ "\/ \/"
1522+ >>
1523+
1524+------------------------------------------------------------------------
1525+
1526+### `++wain`
1527+
1528+ ++ wain (list cord) :: text lines (no \n)
1529+
1530+A list of lines. A `++wain` is used instead of a single `++cord` with
1531+`\n`.
1532+
1533+See also: `++lore`, `++role`
1534+
1535+ ~zod/try=> `wain`/som/del/rok
1536+ <|som del rok|>
1537+ ~zod/try=> `wain`(lore ^:@t/=main=/bin/tree/hoon)
1538+ <|
1539+ !:
1540+ :: /===/bin/tree/hoon
1541+ |= ^
1542+ |= [pax=path fla=$|(~ [%full ~])]
1543+ =- ~[te/-]~
1544+ =+ len=(lent pax)
1545+ =+ rend=?~(fla |=(a=path +:(spud (slag len a))) spud)
1546+ |- ^- wain
1547+ =+ ark=;;(arch .^(cy/pax))
1548+ =- ?~ q.ark -
1549+ [(crip (rend pax)) -]
1550+ %- zing
1551+ %- turn :_ |=(a=@t ^$(pax (weld pax `path`/[a])))
1552+ %- sort :_ aor
1553+ %- turn :_ |=([a=@t ~] a)
1554+ (~(tap by r.ark))
1555+ |>
1556+
1557+------------------------------------------------------------------------
1558+
1559+### `++wing`
1560+
1561+ ++ wing (list limb) ::
1562+
1563+Address in subject. A `++wing` is a path to a value in the subject. A
1564+term alone is the trivial case of a `++wing`.
1565+
1566+See also: `++twig`
1567+
1568+ ~zod/try=> (ream 'a.+.c')
1569+ [%cnzz p=~[%a [%.y p=3] %c]]
1570+ ~zod/try=> (wing +:(ream 'a.+.c'))
1571+ ~[%a [%.y p=3] %c]
1572+
1573+------------------------------------------------------------------------
1574+
1575+### `++wine`
1576+
1577+ ++ wine $| ?(%noun %path %tank %void %wall %wool %yarn)
1578+ $% [%atom p=term] ::
1579+ [%core p=(list ,@ta) q=wine] ::
1580+ [%face p=term q=wine] ::
1581+ [%list p=term q=wine] ::
1582+ [%pear p=term q=@] ::
1583+ [%pick p=(list wine)] ::
1584+ [%plot p=(list wine)] ::
1585+ [%stop p=@ud] ::
1586+ [%tree p=term q=wine] ::
1587+ [%unit p=term q=wine] ::
1588+ == ::
1589+
1590+Printable type. `++wine` is used for pretty printing.
1591+
1592+See also: `++calf`
1593+
1594+ ~zod/try=> ~(dole ut p:!>(*@tas))
1595+ [p={} q=[%atom p=%tas]]
1596+ ~zod/try=> `wine`q:~(dole ut p:!>(*@tas))
1597+ [%atom p=%tas]
1598+
1599+ ~zod/try=> ~(dole ut p:!>(*path))
1600+ [ p
1601+ { [ p=1
1602+ q
1603+ [ %pick
1604+ p
1605+ ~[
1606+ [%pear p=%n q=0]
1607+ [%plot p=~[[%face p=%i q=[%atom p=%ta]] [%face p=%t q=[%stop p=1]]]]
1608+ ]
1609+ ]
1610+ ]
1611+ }
1612+ q=%path
1613+ ]
1614+ ~zod/try=> `wine`q:~(dole ut p:!>(*path))
1615+ %path
1616+
1617+ ~zod/try=> ~(dole ut p:!>(*(map time cord)))
1618+ [ p
1619+ { [ p=1
1620+ q
1621+ [ %pick
1622+ p
1623+ ~[
1624+ [%pear p=%n q=0]
1625+ [ %plot
1626+ p
1627+ ~[
1628+ [ %face
1629+ p=%n
1630+ q
1631+ [ %plot
1632+ p=~[[%face p=%p q=[%atom p=%da]] [%face p=%q q=[%atom p=%t]]]
1633+ ]
1634+ ]
1635+ [%face p=%l q=[%stop p=1]]
1636+ [%face p=%r q=[%stop p=1]]
1637+ ]
1638+ ]
1639+ ]
1640+ ]
1641+ ]
1642+ }
1643+ q
1644+ [ %tree
1645+ p=%nlr
1646+ q=[%plot p=~[[%face p=%p q=[%atom p=%da]] [%face p=%q q=[%atom p=%t]]]]
1647+ ]
1648+ ]
1649+ ~zod/try=> `wine`q:~(dole ut p:!>(*(map time cord)))
1650+ [ %tree
1651+ p=%nlr
1652+ q=[%plot p=~[[%face p=%p q=[%atom p=%da]] [%face p=%q q=[%atom p=%t]]]]
1653+ ]
1654+
1655+------------------------------------------------------------------------
1656+
1657+### `++wonk`
1658+
1659+ ++ wonk |*(veq=edge ?~(q.veq !! p.u.q.veq)) ::
1660+ :: ::
1661+ :: ::
1662+
1663+XX Not a model?
1664+
1665+ ++ wonk |*(veq=edge ?~(q.veq !! p.u.q.veq)) ::
1666+
1667+Pull result out of a `++edge`, or crash if there's no result.
1668+
1669+See also: `++edge`, Section 2eC
1670+
1671+ ~zod/try=> (wide:vast [1 1] "(add 2 2)")
1672+ [ p=[p=1 q=10]
1673+ q
1674+ [ ~
1675+ [ p=[%cnhp p=[%cnzz p=~[%add]] q=~[[%dtzy p=%ud q=2] [%dtzy p=%ud q=2]]]
1676+ q=[p=[p=1 q=10] q=""]
1677+ ]
1678+ ]
1679+ ]
1680+ ~zod/try=> (wonk (wide:vast [1 1] "(add 2 2)"))
1681+ [%cnhp p=[%cnzz p=~[%add]] q=~[[%dtzy p=%ud q=2] [%dtzy p=%ud q=2]]]
1682+
1683+------------------------------------------------------------------------
1684+
1685+### `++map`
1686+
1687+ ++ map |* [a=_,* b=_,*] :: associative tree
1688+ $|(~ [n=[p=a q=b] l=(map a b) r=(map a b)]) ::
1689+
1690+Tile generator. A `++map` is a
1691+[treap](http://en.wikipedia.org/wiki/Treap) of key, value pairs.
1692+
1693+See also: `++by`
1694+
1695+ ~zod/try=> :type; *(map ,@t ,@u)
1696+ {}
1697+ nlr([p=@t q=@u])
1698+ ~zod/try=> `(map ,@ta ,@ud)`(mo (limo a/1 b/2 ~))
1699+ {[p=~.a q=1] [p=~.b q=2]}
1700+
1701+------------------------------------------------------------------------
1702+
1703+### `++qeu`
1704+
1705+ ++ qeu |* a=_,* :: queue
1706+ $|(~ [n=a l=(qeu a) r=(qeu a)]) ::
1707+
1708+Tile generator. A `++qeu` is an ordered
1709+[treap](http://en.wikipedia.org/wiki/Treap) of items.
1710+
1711+See also: `++to`
1712+
1713+ ~zod/try=> (qeu time)
1714+ <1.qyo [* <1.sxx [a=<1.ebd [* <101.jzo 1.ypj %164>]> <101.jzo 1.ypj %164>]>]>
1715+ ~zod/try=> (~(gas to *(qeu time)) [~2014.1.1 ~2014.1.2 ~])
1716+ {~2014.1.2 ~2014.1.1}
1717+
1718+------------------------------------------------------------------------
1719+
1720+### `++set`
1721+
1722+ ++ set |* a=_,* :: set
1723+ $|(~ [n=a l=(set a) r=(set a)]) ::
1724+
1725+Tile generator. A `++set` is a
1726+[treap](http://en.wikipedia.org/wiki/Treap) with unique values.
1727+
1728+See also: `++in`
1729+
1730+ ~zod/try=> (sa "abc")
1731+ {~~a ~~c ~~b}
1732+ ~zod/try=> (~(put in (sa "abc")) %d)
1733+ {~~d ~~a ~~c ~~b}
1734+ ~zod/try=> (~(put in (sa "abc")) %a)
1735+ {~~a ~~c ~~b}
1736+
1737+------------------------------------------------------------------------
1738+
1739+### `++jar`
1740+
1741+ ++ jar |*([a=_,* b=_,*] (map a (list b))) :: map of lists
1742+
1743+Tile generator. A `++jar` is a `++map` of `++list`.
1744+
1745+See also: `++ja`, `++by`, `++map`, `++list`
1746+
1747+ ~zod/try=> =a (limo [1 2 ~])
1748+ ~zod/try=> a
1749+ [i=1 t=[i=2 t=~]]
1750+ ~zod/try=> =b (limo [3 4 ~])
1751+ ~zod/try=> b
1752+ [i=3 t=[i=4 t=~]]
1753+ ~zod/try=> =c (mo (limo [[%a a] [%b b] ~]))
1754+ ~zod/try=> c
1755+ {[p=%a q=[i=1 t=[i=2 t=~]]] [p=%b q=[i=3 t=[i=4 t=~]]]}
1756+ ~zod/try=> (~(get ja c) %a)
1757+ [i=1 t=[i=2 t=~]]
1758+ ~zod/try=> (~(get ja c) %c)
1759+ ~
1760+
1761+------------------------------------------------------------------------
1762+
1763+### `++jug`
1764+
1765+ ++ jug |*([a=_,* b=_,*] (map a (set b))) :: map of sets
1766+
1767+Tile generator. Similar to `++jar`, but with `++set`. A `++jug` is a
1768+`++map` of `++set`.
1769+
1770+See also: `++ju`, `++by`, `++map`, `++set`
1771+
1772+ ~zod/try=> =a (sa (limo [1 2 ~]))
1773+ ~zod/try=> a
1774+ {1 2}
1775+ ~zod/try=> =b (sa (limo [3 4 ~]))
1776+ ~zod/try=> b
1777+ {4 3}
1778+ ~zod/try=> =c (mo (limo [[%a a] [%b b] ~]))
1779+ ~zod/try=> c
1780+ {[p=%a q={1 2}] [p=%b q={4 3}]}
1781+ ~zod/try=> (~(get ju c) %b)
1782+ {4 3}
1783+ ~zod/try=> (~(put ju c) [%b 5])
1784+ {[p=%a q={1 2}] [p=%b q={5 4 3}]}
1785+
1786+------------------------------------------------------------------------
docs/dev/hoon/library/2a.mdnew file+450
@@ -0,0 +1,450 @@
1+chapter 2a, basic unsigned math
2+===============================
3+
4+### `++add`
5+
6+Add
7+
8+ ++ add :: add
9+ ~/ %add
10+ |= [a=@ b=@]
11+ ^- @
12+ ?: =(0 a) b
13+ $(a (dec a), b +(b))
14+ ::
15+
16+Produces the sum of `a` and `b` as an atom.
17+
18+`a` is an [atom]().
19+
20+`b` is an [atom]().
21+
22+ ~zod/try=> (add 2 2)
23+ 4
24+ ~zod/try=> (add 1 1.000.000)
25+ 1.000.001
26+ ~zod/try=> (add 1.333 (mul 2 2))
27+ 1.337
28+
29+------------------------------------------------------------------------
30+
31+### `++cap`
32+
33+Tree head
34+
35+ ++ cap :: tree head
36+ ~/ %cap
37+ |= a=@
38+ ^- ?(%2 %3)
39+ ?- a
40+ %2 %2
41+ %3 %3
42+ ?(%0 %1) !!
43+ * $(a (div a 2))
44+ ==
45+ ::
46+
47+Tests whether an `a` is in the head or tail of a noun. Produces the
48+[cube]() `%2` if it is within the head, or the [cube]() `%3` if is is
49+within the tail.
50+
51+`a` is an [atom]().
52+
53+ ~zod/try=> (cap 4)
54+ %2
55+ ~zod/try=> (cap 6)
56+ %3
57+ ~zod/try=> (cap (add 10 9))
58+ %2
59+
60+------------------------------------------------------------------------
61+
62+### `++dec`
63+
64+Decrement
65+
66+ ++ dec :: decrement
67+ ~/ %dec
68+ |= a=@
69+ ~| %decrement-underflow
70+ ?< =(0 a)
71+ =+ b=0
72+ |- ^- @
73+ ?: =(a +(b)) b
74+ $(b +(b))
75+ ::
76+
77+Produces `a-1` as an atom.
78+
79+`a` is an [atom]().
80+
81+ ~zod/try=> (dec 7)
82+ 6
83+ ~zod/try=> (dec 0)
84+ ! decrement-underflow
85+ ! exit
86+
87+------------------------------------------------------------------------
88+
89+### `++div`
90+
91+Divide
92+
93+ ++ div :: divide
94+ ~/ %div
95+ |= [a=@ b=@]
96+ ^- @
97+ ~| 'div'
98+ ?< =(0 b)
99+ =+ c=0
100+ |-
101+ ?: (lth a b) c
102+ $(a (sub a b), c +(c))
103+ ::
104+
105+Computes `a` divided by `b`, producing an atom.
106+
107+`a` is an [atom]().
108+
109+`b` is an [atom]().
110+
111+ ~zod/try=> (div 4 2)
112+ 2
113+ ~zod/try=> (div 17 8)
114+ 2
115+ ~zod/try=> (div 20 30)
116+ 0
117+
118+------------------------------------------------------------------------
119+
120+### `++fac`
121+
122+Factorial
123+
124+ ++ fac :: factorial
125+ ~/ %fac
126+ |= a=@
127+ ^- @
128+ ?: =(0 a) 1
129+ (mul a $(a (dec a)))
130+ ::
131+
132+Computes the factorial of `a`, producing an atom.
133+
134+`a` is an [atom]().
135+
136+ ~zod/try=> (fac 3)
137+ 6
138+ ~zod/try=> (fac 0)
139+ 1
140+ ~zod/try=> (fac 11)
141+ 39.916.800
142+
143+------------------------------------------------------------------------
144+
145+### `++gte`
146+
147+Greater-than/equal
148+
149+ ++ gte :: greater-equal
150+ ~/ %gte
151+ |= [a=@ b=@]
152+ ^- ?
153+ !(lth a b)
154+ ::
155+
156+Tests whether `a` is greater than a number `b`, producing a loobean.
157+
158+`a` is an [atom]().
159+
160+`b` is an [atom]().
161+
162+ ~zod/try=> (gte 100 10)
163+ %.y
164+ ~zod/try=> (gte 4 4)
165+ %.y
166+ ~zod/try=> (gte 3 4)
167+ %.n
168+
169+------------------------------------------------------------------------
170+
171+### `++gth`
172+
173+Greater-than
174+
175+ ++ gth :: greater-than
176+ ~/ %gth
177+ |= [a=@ b=@]
178+ ^- ?
179+ !(lte a b)
180+ ::
181+
182+Tests whether `a` is greater than `b`, producing a loobean.
183+
184+`a` is an [atom]().
185+
186+`b` is an [atom]().
187+
188+ ~zod/try=> (gth 'd' 'c')
189+ %.y
190+ ~zod/try=> (gth ~h1 ~m61)
191+ %.n
192+
193+------------------------------------------------------------------------
194+
195+### `++lte`
196+
197+Less-than/equal
198+
199+ ++ lte :: less-equal
200+ ~/ %lte
201+ |= [a=@ b=@]
202+ |(=(a b) (lth a b))
203+ ::
204+
205+Tests whether `a` is less than or equal to `b`, producing a loobean.
206+
207+`a` is an [atom]().
208+
209+`b` is an [atom]().
210+
211+ ~zod/try=> (lte 4 5)
212+ %.y
213+ ~zod/try=> (lte 5 4)
214+ %.n
215+ ~zod/try=> (lte 5 5)
216+ %.y
217+ ~zod/try=> (lte 0 0)
218+ %.y
219+
220+------------------------------------------------------------------------
221+
222+### `++lth`
223+
224+Less-than
225+
226+ ++ lth :: less-than
227+ ~/ %lth
228+ |= [a=@ b=@]
229+ ^- ?
230+ ?& !=(a b)
231+ |-
232+ ?| =(0 a)
233+ ?& !=(0 b)
234+ $(a (dec a), b (dec b))
235+ == == ==
236+ ::
237+
238+Tests whether `a` is less than `b`, producing a loobean.
239+
240+`a` is an [atom]().
241+
242+`b` is an [atom]().
243+
244+ ~zod/try=> (lth 4 5)
245+ %.y
246+ ~zod/try=> (lth 5 4)
247+ %.n
248+ ~zod/try=> (lth 5 5)
249+ %.n
250+ ~zod/try=> (lth 5 0)
251+ %.n
252+
253+------------------------------------------------------------------------
254+
255+### `++mas`
256+
257+Axis within head/tail
258+
259+ ++ mas :: tree body
260+ ~/ %mas
261+ |= a=@
262+ ^- @
263+ ?- a
264+ 1 !!
265+ 2 1
266+ 3 1
267+ * (add (mod a 2) (mul $(a (div a 2)) 2))
268+ ==
269+ ::
270+
271+Computes the axis of `a` within the head or the tail, producing an atom.
272+
273+`a` is an [atom]().
274+
275+ ~zod/try=> (mas 3)
276+ 1
277+ ~zod/try=> (mas 4)
278+ 2
279+ ~zod/try=> (mas 5)
280+ 3
281+ ~zod/try=> (mas 6)
282+ 2
283+ ~zod/try=> (mas 0)
284+ ! exit
285+ ~zod/try=> (mas 1)
286+ ! exit
287+
288+------------------------------------------------------------------------
289+
290+### `++max`
291+
292+Maximum
293+
294+ ++ max :: maximum
295+ ~/ %max
296+ |= [a=@ b=@]
297+ ^- @
298+ ?: (gth a b) a
299+ b
300+ ::
301+
302+Computes the maximum of `a` and `b`, producing an atom.
303+
304+`a` is an [atom]().
305+
306+`b` is an [atom]().
307+
308+ ~zod/try=> (max 10 100)
309+ 100
310+ ~zod/try=> (max 10.443 9)
311+ 10.443
312+ ~zod/try=> (max 0 1)
313+ 1
314+
315+------------------------------------------------------------------------
316+
317+### `++min`
318+
319+Minimum
320+
321+ ++ min :: minimum
322+ ~/ %min
323+ |= [a=@ b=@]
324+ ^- @
325+ ?: (lth a b) a
326+ b
327+ ::
328+
329+Computes the minimum of `a` and `b`, producing an atom.
330+
331+`a` is an [atom]().
332+
333+`b` is an [atom]().
334+
335+ ~zod/try=> (min 10 100)
336+ 10
337+ ~zod/try=> (min 10.443 9)
338+ 9
339+ ~zod/try=> (min 0 1)
340+ 0
341+
342+------------------------------------------------------------------------
343+
344+### `++mod`
345+
346+Modulus
347+
348+ ++ mod :: remainder
349+ ~/ %mod
350+ |= [a=@ b=@]
351+ ^- @
352+ ?< =(0 b)
353+ (sub a (mul b (div a b)))
354+ ::
355+
356+Computes the remainder of dividing `a` by `b`, producing an atom.
357+
358+`a` is an [atom]().
359+
360+`b` is an [atom]().
361+
362+------------------------------------------------------------------------
363+
364+### `++mul`
365+
366+Multiply
367+
368+ ++ mul :: multiply
369+ ~/ %mul
370+ |= [a=@ b=@]
371+ ^- @
372+ =+ c=0
373+ |-
374+ ?: =(0 a) c
375+ $(a (dec a), c (add b c))
376+ ::
377+
378+Multiplies `a` by `b`, producing an atom.
379+
380+`a` is an [atom]().
381+
382+`b` is an [atom]().
383+
384+ ~zod/try=> (mul 3 4)
385+ 12
386+ ~zod/try=> (mul 0 1)
387+ 0
388+
389+------------------------------------------------------------------------
390+
391+### `++peg`
392+
393+Axis within axis
394+
395+ ++ peg :: tree connect
396+ ~/ %peg
397+ |= [a=@ b=@]
398+ ^- @
399+ ?- b
400+ 1 a
401+ 2 (mul a 2)
402+ 3 +((mul a 2))
403+ * (add (mod b 2) (mul $(b (div b 2)) 2))
404+ ==
405+ ::
406+
407+Computes the axis of `b` within axis `a`, producing an atom.
408+
409+`a` is an [atom]().
410+
411+`b` is an [atom]().
412+
413+ ~zod/try=> (peg 4 1)
414+ 4
415+ ~zod/try=> (peg 4 2)
416+ 8
417+ ~zod/try=> (peg 8 45)
418+ 269
419+
420+------------------------------------------------------------------------
421+
422+### `++sub`
423+
424+Subtract
425+
426+ ++ sub :: subtract
427+ ~/ %sub
428+ |= [a=@ b=@]
429+ ~| %subtract-underflow
430+ ^- @
431+ ?: =(0 b) a
432+ $(a (dec a), b (dec b))
433+
434+Subtracts `b` from `a`, producing an atom.
435+
436+`a` is an [atom]().
437+
438+`b` is an [atom]().
439+
440+ ~zod/try=> (sub 10 5)
441+ 5
442+ ~zod/try=> (sub 243 44)
443+ 199
444+ ~zod/try=> (sub 5 0)
445+ 5
446+ ~zod/try=> (sub 0 5)
447+ ! subtract-underflow
448+ ! exit
449+
450+------------------------------------------------------------------------
docs/dev/hoon/library/2b.mdnew file+907
@@ -0,0 +1,907 @@
1+chapter 2b, basic containers
2+============================
3+
4+Section 2bA, units
5+------------------
6+
7+### `++biff`
8+
9+Unit as argument
10+
11+ ++ biff :: apply
12+ |* [a=(unit) b=$+(* (unit))]
13+ ?~ a ~
14+ (b u.a)
15+
16+Applies a gate that produces a unit, `b`, to the value (`u.a`) of a unit
17+`a`. If `a` is empty, `~` is produced.
18+
19+`a` is a [unit]().
20+
21+`b` is a [gate]() that accepts a noun and produces a unit.
22+
23+ ~zod/try=> (biff (some 5) |=(a=@ (some (add a 2))))
24+ [~ u=7]
25+ ~zod/try=> (biff ~ |=(a=@ (some (add a 2))))
26+ ~
27+
28+------------------------------------------------------------------------
29+
30+### `++bind`
31+
32+Bind
33+
34+ ++ bind :: argue
35+ |* [a=(unit) b=gate]
36+ ?~ a ~
37+ [~ u=(b u.a)]
38+
39+Applies a function `b` to the value (`u.a`) of a unit `a`, producing a
40+unit.
41+
42+`a` is a [unit]()
43+
44+`b` is a [gate]().
45+
46+ ~zod/try=> (bind ((unit ,@) [~ 97]) ,@t)
47+ [~ `a`]
48+ ~zod/try=> =a |=(a=@ (add a 1))
49+ ~zod/try=> (bind ((unit ,@) [~ 2]) a)
50+ [~ 3]
51+
52+------------------------------------------------------------------------
53+
54+### `++bond`
55+
56+Replace null
57+
58+ ++ bond :: replace
59+ |* a=trap
60+ |* b=(unit)
61+ ?~ b $:a
62+ u.b
63+
64+Replaces an empty unit `b` with the product of a kicked trap `a`. If the
65+unit is not empty, then the original unit is produced.
66+
67+`a` is a [trap]().
68+
69+`b` is a [unit]().
70+
71+ ~zod/try=> (bex 10)
72+ 1.024
73+ ~zod/try=> ((bond |.((bex 10))) ~)
74+ 1.024
75+ ~zod/try=> ((bond |.((bex 10))) (slaw %ud '123'))
76+ 123
77+
78+------------------------------------------------------------------------
79+
80+### `++both`
81+
82+Group unit values
83+
84+ ++ both :: all the above
85+ |* [a=(unit) b=(unit)]
86+ ?~ a ~
87+ ?~ b ~
88+ [~ u=[u.a u.b]]
89+
90+Produces a unit whose value is a cell of the values of two input units
91+`a` and `b`. If either of the two units are empty, `~` is produced.
92+
93+`a` is a [unit]().
94+
95+`b` is a [unit]().
96+
97+ ~zod/try=> (both (some 1) (some %b))
98+ [~ u=[1 %b]]
99+ ~zod/try=> (both ~ (some %b))
100+ ~
101+
102+------------------------------------------------------------------------
103+
104+### `++clap`
105+
106+Apply gate to two units
107+
108+ ++ clap :: combine
109+ |* [a=(unit) b=(unit) c=_|=(^ +<-)]
110+ ?~ a b
111+ ?~ b a
112+ [~ u=(c u.a u.b)]
113+
114+Applies a binary operation `c` which produces a unit to the values of
115+two units `a` and `b`.
116+
117+`a` is a [unit]().
118+
119+`b` is a [unit]().
120+
121+`c` is a [gate]() that performs a binary operation.
122+
123+ ~zod/try=> =u ((unit ,@t) [~ 'a'])
124+ ~zod/try=> =v ((unit ,@t) [~ 'b'])
125+ ~zod/try=> (clap u v |=([a=@t b=@t] (welp (trip a) (trip b))))
126+ [~ u="ab"]
127+ ~zod/try=> =a ((unit ,@u) [~ 1])
128+ ~zod/try=> =b ((unit ,@u) [~ 2])
129+ ~zod/try=> =c |=([a=@ b=@] (add a b))
130+ ~zod/try=> (clap a b c)
131+ [~ 3]
132+
133+
134+------------------------------------------------------------------------
135+
136+### `++drop`
137+
138+Unit list
139+
140+ ++ drop :: enlist
141+ |* a=(unit)
142+ ?~ a ~
143+ [i=u.a t=~]
144+
145+Produces a [list]() of the value from a unit `a`.
146+
147+`a` is a [unit]().
148+
149+ ~zod/try=> =a ((unit ,@) [~ 97])
150+ ~zod/try=> (drop a)
151+ [i=97 t=~]
152+ ~zod/try=> =a ((unit ,@) [~])
153+ ~zod/try=> (drop a)
154+ ~
155+
156+------------------------------------------------------------------------
157+
158+### `++fall`
159+
160+Default unit
161+
162+ ++ fall :: default
163+ |* [a=(unit) b=*]
164+ ?~(a b u.a)
165+
166+Produces a default value `b` for a unit `a` in cases where the unit is
167+null.
168+
169+`a` is a [unit]().
170+
171+`b` is a [noun]() used as the default value.
172+
173+ ~zod/try=> (fall ~ `a`)
174+ `a`
175+ ~zod/try=> (fall [~ u=0] `a`)
176+ 0
177+
178+------------------------------------------------------------------------
179+
180+### `++lift`
181+
182+Fmap
183+
184+ ++ lift :: lift gate (fmap)
185+ |* a=gate :: flipped
186+ |* b=(unit) :: curried
187+ (bind b a) :: bind
188+
189+Similar to `fmap` in Haskell: accepts a gate `a` that accepts and
190+produces an unwrapped value, passes it the value of a unit `b`, and then
191+produces a unit value.
192+
193+`a` is a [gate]().
194+
195+`b` is a [unit]().
196+
197+ ~zod/try=> ((lift dec) `(unit ,@)`~)
198+ ~
199+ ~zod/try=> ((lift dec) `(unit ,@)`[~ 20])
200+ [~ 19]
201+
202+------------------------------------------------------------------------
203+
204+### `++mate`
205+
206+Choose
207+
208+ ++ mate :: choose
209+ |* [a=(unit) b=(unit)]
210+ ?~ b a
211+ ?~ a b
212+ ?.(=(u.a u.b) ~|('mate' !!) a)
213+
214+Accepts two units `a` and `b` whose values are expected to be
215+equivalent. If either is empty, then the value of the other is produced.
216+If neither are empty, it asserts that both values are the same and
217+produces that value. If the assertion fails, `++mate` crashes with
218+`'mate'` in the stack trace.
219+
220+`a` is a [unit]().
221+
222+`b` is a [unit]().
223+
224+ ~zod/try=> =a ((unit ,@) [~ 97])
225+ ~zod/try=> =b ((unit ,@) [~ 97])
226+ ~zod/try=> (mate a b)
227+ [~ 97]
228+ ~zod/try=> =a ((unit ,@) [~ 97])
229+ ~zod/try=> =b ((unit ,@) [~])
230+ ~zod/try=> (mate a b)
231+ [~ 97]
232+ ~zod/try=> =a ((unit ,@) [~ 97])
233+ ~zod/try=> =b ((unit ,@) [~ 98])
234+ ~zod/try=> (mate a b)
235+ ! 'mate'
236+ ! exit
237+
238+------------------------------------------------------------------------
239+
240+### `++need`
241+
242+Unwrap
243+
244+ ++ need :: demand
245+ |* a=(unit)
246+ ?~ a !!
247+ u.a
248+
249+Retrieve the value from a unit and crash if the unit is null.
250+
251+`a` is a [unit]().
252+
253+ ~zod/try=> =a ((unit ,[@t @t]) [~ ['a' 'b']])
254+ ~zod/try=> (need a)
255+ ['a' 'b']
256+ ~zod/try=> =a ((unit ,@ud) [~ 17])
257+ ~zod/try=> (need a)
258+ 17
259+ ~zod/try=> =a ((unit ,@) [~])
260+ ~zod/try=> (need a)
261+ ! exit
262+
263+------------------------------------------------------------------------
264+
265+### `++some`
266+
267+Unify
268+
269+ ++ some :: lift (pure)
270+ |* a=*
271+ [~ u=a]
272+
273+Takes any atom `a` and produces a unit with the value set to `a`.
274+
275+`a` is a [noun]().
276+
277+ ~zod/try=> (some [`a` `b`])
278+ [~ u=[`a` `b`]]
279+ ~zod/try=> (some &)
280+ [~ u=%.y]
281+
282+------------------------------------------------------------------------
283+
284+section 2bB, lists
285+------------------
286+
287+### `++flop`
288+
289+Reverse
290+
291+ ++ flop :: reverse
292+ ~/ %flop
293+ |* a=(list)
294+ => .(a (homo a))
295+ ^+ a
296+ =+ b=`_a`~
297+ |-
298+ ?~ a b
299+ $(a t.a, b [i.a b])
300+
301+Produces the list `a` in reverse order.
302+
303+`a` is a [list]().
304+
305+ ~zod/try=> =a (limo [1 2 3 ~])
306+ ~zod/try=> (flop a)
307+ ~[3 2 1]
308+
309+------------------------------------------------------------------------
310+
311+### `++homo`
312+
313+Homogenize
314+
315+ ++ homo :: homogenize
316+ |* a=(list)
317+ ^+ =< $
318+ |% +- $ ?:(_? ~ [i=(snag 0 a) t=$])
319+ --
320+ a
321+
322+Produces a list whose type is a fork of all the contained types in the
323+list `a`.
324+
325+`a` is a [list]().
326+
327+ ~zod/try=> lyst
328+ [i=1 t=[i=97 t=[i=2 t=[i=98 t=[i=[~ u=10] t=~]]]]]
329+ ~zod/try=> (homo lyst)
330+ ~[1 97 2 98 [~ u=10]]
331+ ~zod/try=> =a (limo [1 2 3 ~])
332+ ~zod/try=> a
333+ [i=1 t=[i=2 t=[i=3 t=~]]]
334+ ~zod/try=> (homo a)
335+ ~[1 2 3]
336+
337+------------------------------------------------------------------------
338+
339+### `++limo`
340+
341+List Constructor
342+
343+ ++ limo :: listify
344+ |* a=*
345+ ^+ =< $
346+ |% +- $ ?~(a ~ ?:(_? i=-.a t=$ $(a +.a)))
347+ --
348+ a
349+
350+Turns a null-terminated tuple into a list.
351+
352+`a` is a null-terminated tuple.
353+
354+ ~zod/try=> (limo [1 2 3 ~])
355+ [i=1 t=[i=2 t=[i=3 t=~]]]
356+
357+------------------------------------------------------------------------
358+
359+### `++lent`
360+
361+List length
362+
363+ ++ lent :: length
364+ ~/ %lent
365+ |= a=(list)
366+ ^- @
367+ =+ b=0
368+ |-
369+ ?~ a b
370+ $(a t.a, b +(b))
371+
372+Produces the length of any list `a` as an atom.
373+
374+`a` is a [list]().
375+
376+ ~zod/try=> (lent (limo [1 2 3 4 ~]))
377+ 4
378+ ~zod/try=> (lent (limo [1 'a' 2 'b' (some 10) ~]))
379+ 5
380+
381+------------------------------------------------------------------------
382+
383+### `++levy`
384+
385+"and" to list
386+
387+ ++ levy
388+ ~/ %levy :: all of
389+ |* [a=(list) b=_|=(p=* .?(p))]
390+ |- ^- ?
391+ ?~ a &
392+ ?. (b i.a) |
393+ $(a t.a)
394+
395+Produces the Boolean "and" of the result of every element in list `a`
396+passed to gate `b`.
397+
398+`a` is a [list]().
399+
400+`b` is a [gate]().
401+
402+ ~zod/try=> =a |=(a=@ (lte a 1))
403+ ~zod/try=> (levy (limo [0 1 2 1 ~]) a)
404+ %.n
405+ ~zod/try=> =a |=(a=@ (lte a 3))
406+ ~zod/try=> (levy (limo [0 1 2 1 ~]) a)
407+ %.y
408+
409+------------------------------------------------------------------------
410+
411+### `++lien`
412+
413+"or" to list
414+
415+ ++ lien :: some of
416+ ~/ %lien
417+ |* [a=(list) b=$+(* ?)]
418+ |- ^- ?
419+ ?~ a |
420+ ?: (b i.a) &
421+ $(a t.a)
422+
423+Produces the Boolean "or" of the result of every element in list `a`
424+passed to gate `b`.
425+
426+`a` is a [list]().
427+
428+`b` is a [gate]().
429+
430+ ~zod/try=> =a |=(a=@ (gte a 1))
431+ ~zod/try=> (lien (limo [0 1 2 1 ~]) a)
432+ %.y
433+ ~zod/try=> =a |=(a=@ (gte a 3))
434+ ~zod/try=> (lien (limo [0 1 2 1 ~]) a)
435+ %.n
436+
437+------------------------------------------------------------------------
438+
439+### `++murn`
440+
441+Maybe transform
442+
443+ ++ murn :: maybe transform
444+ |* [a=(list) b=$+(* (unit))]
445+ |-
446+ ?~ a ~
447+ =+ c=(b i.a)
448+ ?~ c
449+ $(a t.a)
450+ [i=u.c t=$(a t.a)]
451+
452+Passes each member of list `a` to gate `b`, which must produce a unit.
453+Produces a new list with all the results that do not produce `~`.
454+
455+`a` is a [list]().
456+
457+`b` is a [gate]() that produces a [unit]().
458+
459+ ~zod/try=> =a |=(a=@ ?.((gte a 2) ~ (some (add a 10))))
460+ ~zod/try=> (murn (limo [0 1 2 3 ~]) a)
461+ [i=12 t=[i=13 t=~]]
462+
463+------------------------------------------------------------------------
464+
465+### `++reap`
466+
467+Replicate
468+
469+ ++ reap :: replicate
470+ |* [a=@ b=*]
471+ |- ^- (list ,_b)
472+ ?~ a ~
473+ [b $(a (dec a))]
474+
475+Replicate: produces a list containing `a` copies of `b`.
476+
477+`a` is an [atom]()
478+
479+`b` is a [noun]()
480+
481+ ~zod/try=> (reap 20 %a)
482+ ~[%a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a]
483+ ~zod/try=> (reap 5 ~s1)
484+ ~[~s1 ~s1 ~s1 ~s1 ~s1]
485+ ~zod/try=> `@dr`(roll (reap 5 ~s1) add)
486+ ~s5
487+
488+------------------------------------------------------------------------
489+
490+### `++reel`
491+
492+Right fold
493+
494+ ++ reel :: right fold
495+ ~/ %reel
496+ |* [a=(list) b=_|=([* *] +<+)]
497+ |- ^+ +<+.b
498+ ?~ a
499+ +<+.b
500+ (b i.a $(a t.a))
501+
502+Right fold: moves right to left across a list `a`, recursively slamming
503+a binary gate `b` with an element from `a` and an accumulator, producing
504+the final value of the accumulator.
505+
506+`a` is a [list]().
507+
508+`b` is a binary [gate]().
509+
510+ ~zod/try=> =sum =|([p=@ q=@] |.((add p q)))
511+ ~zod/try=> (reel (limo [1 2 3 4 5 ~]) sum)
512+ 15
513+ ~zod/try=> =a =|([p=@ q=@] |.((sub p q)))
514+ ~zod/try=> (reel (limo [6 3 1 ~]) a)
515+ 4
516+ ~zod/try=> (reel (limo [3 6 1 ~]) a)
517+ ! subtract-underflow
518+ ! exit
519+
520+------------------------------------------------------------------------
521+
522+### `++roll`
523+
524+Left fold
525+
526+ ++ roll :: left fold
527+ ~/ %roll
528+ |* [a=(list) b=_|=([* *] +<+)]
529+ |- ^+ +<+.b
530+ ?~ a
531+ +<+.b
532+ $(a t.a, b b(+<+ (b i.a +<+.b)))
533+
534+Left fold: moves left to right across a list `a`, recursively slamming a
535+binary gate `b` with an element from the list and an accumulator,
536+producing the final value of the accumulator.
537+
538+`a` is a [list]().
539+
540+`b` is a binary [gate]().
541+
542+ ~zod/try=> =sum =|([p=@ q=@] |.((add p q)))
543+ ~zod/try=> (roll (limo [1 2 3 4 5 ~]) sum)
544+ q=15
545+ ~zod/try=> =a =|([p=@ q=@] |.((sub p q)))
546+ ~zod/try=> (roll (limo [6 3 1 ~]) a)
547+ ! subtract-underflow
548+ ! exit
549+ ~zod/try=> (roll (limo [1 3 6 ~]) a)
550+ q=4
551+
552+------------------------------------------------------------------------
553+
554+### `++skid`
555+
556+Separate
557+
558+ ++ skid :: separate
559+ |* [a=(list) b=$+(* ?)]
560+ |- ^+ [p=a q=a]
561+ ?~ a [~ ~]
562+ =+ c=$(a t.a)
563+ ?:((b i.a) [[i.a p.c] q.c] [p.c [i.a q.c]])
564+
565+Seperates a list `a` into two lists - Those elements of `a` who produce
566+true when slammed to gate `b` and those who produce `%.n`.
567+
568+`a` is a [list]().
569+
570+`b` is a [gate]() that accepts one argument and produces a loobean.
571+
572+ ~zod/try=> =a |=(a=@ (gth a 1))
573+ ~zod/try=> (skid (limo [0 1 2 3 ~]) a)
574+ [p=[i=2 t=[i=3 t=~]] q=[i=0 t=[i=1 t=~]]]
575+
576+------------------------------------------------------------------------
577+
578+### `++skim`
579+
580+Suffix
581+
582+ ++ skim :: only
583+ ~/ %skim
584+ |* [a=(list) b=_|=(p=* .?(p))]
585+ |-
586+ ^+ a
587+ ?~ a ~
588+ ?:((b i.a) [i.a $(a t.a)] $(a t.a))
589+
590+Cycles through the members of a list `a`, passing them to a gate `b` and
591+producing a list of all of the members that produce `%.y`. Inverse of
592+`++skip`.
593+
594+`a` is a [list]().
595+
596+`b` is a [gate]() that accepts one argument and produces a loobean.
597+
598+ ~zod/try=> =a |=(a=@ (gth a 1))
599+ ~zod/try=> (skim (limo [0 1 2 3 ~]) a)
600+ [i=2 t=[i=3 t=~]]
601+
602+------------------------------------------------------------------------
603+
604+### `++skip`
605+
606+Except
607+
608+ ++ skip :: except
609+ ~/ %skip
610+ |* [a=(list) b=_|=(p=* .?(p))]
611+ |-
612+ ^+ a
613+ ?~ a ~
614+ ?:((b i.a) $(a t.a) [i.a $(a t.a)])
615+
616+Cycles through the members of a list `a`, passing them to a gate `b` and
617+producing a list of all of the members that produce `%.n`. Inverse of
618+`++skim`.
619+
620+`a` is a [list]().
621+
622+`b` is a [gate]() that accepts one argument and produces a loobean.
623+
624+ ~zod/try=> =a |=(a=@ (gth a 1))
625+ ~zod/try=> (skip (limo [0 1 2 3 ~]) a)
626+ [i=0 t=[i=1 t=~]]
627+
628+------------------------------------------------------------------------
629+
630+### `++scag`
631+
632+Prefix
633+
634+ ++ scag :: prefix
635+ ~/ %scag
636+ |* [a=@ b=(list)]
637+ |- ^+ b
638+ ?: |(?=(~ b) =(0 a)) ~
639+ [i.b $(b t.b, a (dec a))]
640+
641+Accepts an atom `a` and list `b`, producing the first `a` elements of
642+the front of the list.
643+
644+`a` is an [atom]().
645+
646+`b` is a [list]().
647+
648+ ~zod/try=> (scag 2 (limo [0 1 2 3 ~]))
649+ [i=0 t=[i=1 t=~]]
650+ ~zod/try=> (scag 10 (limo [1 2 3 4 ~]))
651+ [i=1 t=[i=2 t=[i=3 t=[i=4 t=~]]]]
652+
653+------------------------------------------------------------------------
654+
655+### `++slag`
656+
657+Suffix
658+
659+ ++ slag :: suffix
660+ ~/ %slag
661+ |* [a=@ b=(list)]
662+ |- ^+ b
663+ ?: =(0 a) b
664+ ?~ b ~
665+ $(b t.b, a (dec a))
666+
667+Accepts an atom `a` and list `b`, producing the remaining elements from
668+`b` starting at `a`.
669+
670+`a` is an [atom]().
671+
672+`b` is a [list]().
673+
674+ ~zod/try=> (slag 2 (limo [1 2 3 4 ~]))
675+ [i=3 t=[i=4 t=~]]
676+ ~zod/try=> (slag 1 (limo [1 2 3 4 ~]))
677+ [i=2 t=[i=3 t=[i=4 t=~]]]
678+
679+------------------------------------------------------------------------
680+
681+### `++snag`
682+
683+Index
684+
685+ ++ snag :: index
686+ ~/ %snag
687+ |* [a=@ b=(list)]
688+ |-
689+ ?~ b
690+ ~|('snag-fail' !!)
691+ ?: =(0 a) i.b
692+ $(b t.b, a (dec a))
693+
694+Accepts an atom `a` and a list `b`, producing the element at the index
695+of `a`and failing if the list is null. Lists are 0-indexed.
696+
697+`a` is an [atom]().
698+
699+`b` is a [list]().
700+
701+ ~zod/try=> (snag 2 "asdf")
702+ ~~d
703+ ~zod/try=> (snag 0 `(list ,@ud)`~[1 2 3 4])
704+ 1
705+
706+------------------------------------------------------------------------
707+
708+### `++sort`
709+
710+Quicksort
711+
712+ ++ sort :: quicksort
713+ ~/ %sort
714+ |* [a=(list) b=$+([* *] ?)]
715+ => .(a ^.(homo a))
716+ |- ^+ a
717+ ?~ a ~
718+ %+ weld
719+ $(a (skim t.a |=(c=_i.a (b c i.a))))
720+ ^+ t.a
721+ [i.a $(a (skim t.a |=(c=_i.a !(b c i.a))))]
722+
723+Quicksort: accepts a list `a` and a gate `b` which accepts two nouns and
724+produces a loobean. `++sort` then produces a list of the elements of `a`
725+sorted according to `b`.
726+
727+`a` is an [atom]().
728+
729+`b` is a [gate]() which accepts two nouns and produces a loobean.
730+
731+ ~zod/try=> =a =|([p=@ q=@] |.((gth p q)))
732+ ~zod/try=> (sort (limo [0 1 2 3 ~]) a)
733+ ~[3 2 1 0]
734+
735+------------------------------------------------------------------------
736+
737+### `++swag`
738+
739+Infix
740+
741+ ++ swag :: infix
742+ |* [[a=@ b=@] c=(list)]
743+ (scag b (slag a c))
744+
745+Similar to `substr` in JavaScript: extracts a string infix, beginning at
746+inclusive index `a`, producing `b` number of characters.
747+
748+`a` and `b` are [atom]()s.
749+
750+`c` is a [list]().
751+
752+ ~zod/try=> (swag [2 5] "roly poly")
753+ "ly po"
754+ ~zod/try=> (swag [2 2] (limo [1 2 3 4 ~]))
755+ [i=3 t=[i=4 t=~]]
756+
757+------------------------------------------------------------------------
758+
759+### `++turn`
760+
761+Gate to list
762+
763+ ++ turn :: transform
764+ ~/ %turn
765+ |* [a=(list) b=_,*]
766+ |-
767+ ?~ a ~
768+ [i=(b i.a) t=$(a t.a)]
769+
770+Accepts a list `a` and a gate `b`. Produces a list with the gate applied
771+to each element of the original list.
772+
773+`a` is a [list]().
774+
775+`b` is a [gate]().
776+
777+ ~zod/try=> (turn (limo [104 111 111 110 ~]) ,@t)
778+ <|h o o n|>
779+ ~zod/try=> =a |=(a=@ (add a 4))
780+ ~zod/try=> (turn (limo [1 2 3 4 ~]) a)
781+ ~[5 6 7 8]
782+
783+------------------------------------------------------------------------
784+
785+### `++weld`
786+
787+Concatenate
788+
789+ ++ weld :: concatenate
790+ ~/ %weld
791+ |* [a=(list) b=(list)]
792+ => .(a ^.(homo a), b ^.(homo b))
793+ |- ^+ b
794+ ?~ a b
795+ [i.a $(a t.a)]
796+
797+Concatenate two lists `a` and `b`.
798+
799+`a` and `b` are [list]()s.
800+
801+ ~zod/try=> (weld "urb" "it")
802+ ~[~~u ~~r ~~b ~~i ~~t]
803+ ~zod/try=> (weld (limo [1 2 ~]) (limo [3 4 ~]))
804+ ~[1 2 3 4]
805+
806+------------------------------------------------------------------------
807+
808+### `++welp`
809+
810+Perfect weld
811+
812+ ++ welp :: perfect weld
813+ =| [* *]
814+ |%
815+ +- $
816+ ?~ +<-
817+ +<-(. +<+)
818+ +<-(+ $(+<- +<->))
819+ --
820+
821+Concatenate two lists `a` and `b` without losing their type information
822+to homogenization.
823+
824+`a` and `b` are [list]()s.
825+
826+ ~zod/try=> (welp "foo" "bar")
827+ "foobar"
828+ ~zod/arvo=/hoon/hoon> (welp ~[60 61 62] ~[%a %b %c])
829+ [60 61 62 %a %b %c ~]
830+ ~zod/arvo=/hoon/hoon> :type; (welp ~[60 61 62] ~[%a %b %c])
831+ [60 61 62 %a %b %c ~]
832+ [@ud @ud @ud %a %b %c %~]
833+ ~zod/arvo=/hoon/hoon> (welp [sa/1 so/2 ~] si/3)
834+ [[%sa 1] [%so 2] %si 3]
835+
836+------------------------------------------------------------------------
837+
838+### `++wild`
839+
840+XXDELETE
841+
842+ ++ wild :: concatenate
843+ |* [a=(list) b=(list)]
844+ => .(a ^.(homo a), b ^.(homo b))
845+ |-
846+ ?~ a b
847+ [i=i.a $(a t.a)]
848+
849+Concatenates two lists `a` and `b`, homogenizing their types
850+individually.
851+
852+`a` and `b` are [list]()s.
853+
854+ ~zod/try=> (wild (limo ~[1 2 3]) (limo [4]~))
855+ ~[1 2 3 4]
856+ ~zod/try=> (wild (limo 60 61 62 ~) (limo %a %b %c ~))
857+ [i=60 [i=61 [i=62 ~[%a %b %c]]]]
858+ ~zod/try=> (weld (limo 60 61 62 ~) (limo %a %b %c ~))
859+ ! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.000 15].[10.016 57]>
860+ ! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.001 15].[10.016 57]>
861+ ! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.002 15].[10.016 57]>
862+ ! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.004 15].[10.016 57]>
863+ ! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.006 15].[10.016 57]>
864+ ! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.006 29].[10.006 44]>
865+ ! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.056 3].[10.061 13]>
866+ ! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.058 3].[10.061 13]>
867+ ! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.059 3].[10.061 13]>
868+ ! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.060 5].[10.060 47]>
869+ ! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.826 7].[9.844 35]>
870+ ! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.827 7].[9.844 35]>
871+ ! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.827 11].[9.838 13]>
872+ ! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.828 11].[9.838 13]>
873+ ! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.829 13].[9.831 47]>
874+ ! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.830 13].[9.831 47]>
875+ ! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.706 7].[9.712 25]>
876+ ! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.707 7].[9.712 25]>
877+ ! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.708 7].[9.712 25]>
878+ ! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.712 7].[9.712 25]>
879+ ! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.712 8].[9.712 25]>
880+ ! exit
881+
882+------------------------------------------------------------------------
883+
884+### `++zing`
885+
886+Cons
887+
888+ ++ zing :: promote
889+ =| *
890+ |%
891+ +- $
892+ ?~ +<
893+ +<
894+ (welp +<- $(+< +<+))
895+ --
896+
897+Turns a list of lists into a single list by promoting the elements of
898+each sublist into the higher.
899+
900+Accepts a [list]() of lists.
901+
902+ ~zod/try=> (zing (limo [(limo ['a' 'b' 'c' ~]) (limo ['e' 'f' 'g' ~]) (limo ['h' 'i' 'j' ~]) ~]))
903+ ~['a' 'b' 'c' 'e' 'f' 'g' 'h' 'i' 'j']
904+ ~zod/try=> (zing (limo [(limo [1 'a' 2 'b' ~]) (limo [3 'c' 4 'd' ~]) ~]))
905+ ~[1 97 2 98 3 99 4 100]
906+
907+------------------------------------------------------------------------
docs/dev/hoon/library/2c.mdnew file+2134
@@ -0,0 +1,2134 @@
1+chapter 2c, simple noun surgery
2+===============================
3+
4+section 2cA, bit surgery
5+------------------------
6+
7+### `++bex`
8+
9+Binary exponent
10+
11+ ++ bex :: binary exponent
12+ ~/ %bex
13+ |= a=@
14+ ^- @
15+ ?: =(0 a) 1
16+ (mul 2 $(a (dec a)))
17+
18+Computes the result of `2^a`, producing an atom.
19+
20+`a` is an [atom](atom).
21+
22+ ~zod/try=> (bex 4)
23+ 16
24+ ~zod/try=> (bex (add 19 1))
25+ 1.048.576
26+ ~zod/try=> (bex 0)
27+ 1
28+
29+------------------------------------------------------------------------
30+
31+### `++xeb`
32+
33+Binary logarithm
34+
35+ ++ xeb :: binary logarithm
36+ :: ~/ %xeb
37+ |= a=@
38+ ^- @
39+ (met 0 a)
40+
41+Computes the base-2 logarithm of `a`, producing an atom.
42+
43+`a` is an [atom](atom).
44+
45+ ~zod/try=> (xeb 31)
46+ 5
47+ ~zod/try=> (xeb 32)
48+ 6
49+ ~zod/try=> (xeb 49)
50+ 6
51+ ~zod/try=> (xeb 0)
52+ 0
53+ ~zod/try=> (xeb 1)
54+ 1
55+ ~zod/try=> (xeb 2)
56+ 2
57+
58+------------------------------------------------------------------------
59+
60+### `++can`
61+
62+Assemble
63+
64+ ++ can :: assemble
65+ ~/ %can
66+ |= [a=bloq b=(list ,[p=@ q=@])]
67+ ^- @
68+ ?~ b 0
69+ (mix (end a p.i.b q.i.b) (lsh a p.i.b $(b t.b)))
70+
71+Produces an atom from a list `b` of length-value pairs `p` and `q`,
72+where `p` is the length in bloqs of size `a`, and `q` is an atomic
73+value.
74+
75+`a` is a block size (see [++bloq]()).
76+
77+`b` is a [list](list) of length value pairs, `p` and `q`.
78+
79+ ~zod/try=> `@ub`(can 3 ~[[1 1]])
80+ 0b1
81+ ~zod/try=> `@ub`(can 0 ~[[1 255]])
82+ 0b1
83+ ~zod/try=> `@ux`(can 3 [3 0xc1] [1 0xa] ~)
84+ 0xa00.00c1
85+ ~zod/try=> `@ux`(can 3 [3 0xc1] [1 0xa] [1 0x23] ~)
86+ 0x23.0a00.00c1
87+ ~zod/try=> `@ux`(can 4 [3 0xc1] [1 0xa] [1 0x23] ~)
88+ 0x23.000a.0000.0000.00c1
89+ ~zod/try=> `@ux`(can 3 ~[[1 'a'] [2 'bc']])
90+ 0x63.6261
91+
92+------------------------------------------------------------------------
93+
94+### `++cat`
95+
96+Concatenate
97+
98+ ++ cat :: concatenate
99+ ~/ %cat
100+ |= [a=bloq b=@ c=@]
101+ (add (lsh a (met a b) c) b)
102+
103+Concatenates two atoms, `b` and `c`, using bloq size `a`, producing an
104+atom.
105+
106+`a` is a block size (see [++bloq]()).
107+
108+`b` is an [atom]().
109+
110+`c` is an [atom]().
111+
112+ ~zod/try=> `@ub`(cat 3 1 0)
113+ 0b1
114+ ~zod/try=> `@ub`(cat 0 1 1)
115+ 0b11
116+ ~zod/try=> `@ub`(cat 0 2 1)
117+ 0b110
118+ ~zod/try=> `@ub`(cat 2 1 1)
119+ 0b1.0001
120+ ~zod/try=> `@ub`256
121+ 0b1.0000.0000
122+ ~zod/try=> `@ub`255
123+ 0b1111.1111
124+ ~zod/try=> `@ub`(cat 3 256 255)
125+ 0b1111.1111.0000.0001.0000.0000
126+ ~zod/try=> `@ub`(cat 2 256 255)
127+ 0b1111.1111.0001.0000.0000
128+ ~zod/try=> (cat 3 256 255)
129+ 16.711.936
130+
131+------------------------------------------------------------------------
132+
133+### `++cut`
134+
135+Slice
136+
137+ ++ cut :: slice
138+ ~/ %cut
139+ |= [a=bloq [b=@ c=@] d=@]
140+ (end a c (rsh a b d))
141+
142+Slices `c` blocks of size `a` that are `b` blocks from the end of `d`.
143+Produces an atom.
144+
145+`a` is a block size (see [++bloq]()).
146+
147+`b` is an [atom]().
148+
149+`c` is an [atom]().
150+
151+ ~zod/try=> (cut 0 [1 1] 2)
152+ 1
153+ ~zod/try=> (cut 0 [2 1] 4)
154+ 1
155+ ~zod/try=> `@t`(cut 3 [0 3] 'abcdefgh')
156+ 'abc'
157+ ~zod/try=> `@t`(cut 3 [1 3] 'abcdefgh')
158+ 'bcd'
159+ ~zod/try=> `@ub`(cut 0 [0 3] 0b1111.0000.1101)
160+ 0b101
161+ ~zod/try=> `@ub`(cut 0 [0 6] 0b1111.0000.1101)
162+ 0b1101
163+ ~zod/try=> `@ub`(cut 0 [4 6] 0b1111.0000.1101)
164+ 0b11.0000
165+ ~zod/try=> `@ub`(cut 0 [3 6] 0b1111.0000.1101)
166+ 0b10.0001
167+
168+------------------------------------------------------------------------
169+
170+### `++end`
171+
172+Tail
173+
174+ ++ end :: tail
175+ ~/ %end
176+ |= [a=bloq b=@ c=@]
177+ (mod c (bex (mul (bex a) b)))
178+
179+Produces an atom by taking the last `b` blocks of size `a` from `c`.
180+
181+`a` is a block size (see [++bloq]()).
182+
183+`b` is an [atom]().
184+
185+`c` is an [atom]().
186+
187+ ~zod/try=> `@ub`12
188+ 0b1100
189+ ~zod/try=> `@ub`(end 0 3 12)
190+ 0b100
191+ ~zod/try=> (end 0 3 12)
192+ 4
193+ ~zod/try=> `@ub`(end 1 3 12)
194+ 0b1100
195+ ~zod/try=> (end 1 3 12)
196+ 12
197+ ~zod/try=> `@ux`'abc'
198+ 0x63.6261
199+ ~zod/try=> `@ux`(end 3 2 'abc')
200+ 0x6261
201+ ~zod/try=> `@t`(end 3 2 'abc')
202+ 'ab'
203+
204+------------------------------------------------------------------------
205+
206+### `++fil`
207+
208+Fill bloqstream
209+
210+ ++ fil :: fill bloqstream
211+ |= [a=bloq b=@ c=@]
212+ =+ n=0
213+ =+ d=c
214+ |- ^- @
215+ ?: =(n b)
216+ (rsh a 1 d)
217+ $(d (add c (lsh a 1 d)), n +(n))
218+
219+Produces an atom by repeating `c` for `b` blocks of size `a`.
220+
221+`a` is a block size (see [++bloq]()).
222+
223+`b` is an [atom]().
224+
225+`c` is an [atom]().
226+
227+ ~zod/try=> `@t`(fil 3 5 %a)
228+ 'aaaaa'
229+ ~zod/try=> `@t`(fil 5 10 %ceeb)
230+ 'ceebceebceebceebceebceebceebceebceebceeb'
231+ ~zod/try=> `@t`(fil 4 10 %eced)
232+ 'ʇʇʇʇʇʇʇʇʇʇed'
233+ ~zod/try=> `@tas`(fil 4 10 %bf)
234+ %bfbfbfbfbfbfbfbfbfbf
235+
236+------------------------------------------------------------------------
237+
238+### `++lsh`
239+
240+Left-shift
241+
242+ ++ lsh :: left-shift
243+ ~/ %lsh
244+ |= [a=bloq b=@ c=@]
245+ (mul (bex (mul (bex a) b)) c)
246+
247+Produces an atom by left-shifting `c` by `b` blocks of size `a`.
248+
249+`a` is a block size (see [++bloq]()).
250+
251+`b` is an [atom]().
252+
253+`c` is an [atom]().
254+
255+ ~zod/try=> `@ub`1
256+ 0b1
257+ ~zod/try=> `@ub`(lsh 0 1 1)
258+ 0b10
259+ ~zod/try=> (lsh 0 1 1)
260+ 2
261+ ~zod/try=> `@ub`255
262+ 0b1111.1111
263+ ~zod/try=> `@ub`(lsh 3 1 255)
264+ 0b1111.1111.0000.0000
265+ ~zod/try=> (lsh 3 1 255)
266+ 65.280
267+
268+------------------------------------------------------------------------
269+
270+### `++met`
271+
272+Measure
273+
274+ ++ met :: measure
275+ ~/ %met
276+ |= [a=bloq b=@]
277+ ^- @
278+ =+ c=0
279+ |-
280+ ?: =(0 b) c
281+ $(b (rsh a 1 b), c +(c))
282+
283+Computes the number of blocks of size `a` in `b`, producing an atom.
284+
285+`a` is a block size (see [++bloq]()).
286+
287+`b` is an [atom]().
288+
289+ ~zod/try=> (met 0 1)
290+ 1
291+ ~zod/try=> (met 0 2)
292+ 2
293+ ~zod/try=> (met 3 255)
294+ 1
295+ ~zod/try=> (met 3 256)
296+ 2
297+ ~zod/try=> (met 3 'abcde')
298+ 5
299+
300+------------------------------------------------------------------------
301+
302+### `++rap`
303+
304+Assemble non-zero
305+
306+ ++ rap :: assemble nonzero
307+ ~/ %rap
308+ |= [a=bloq b=(list ,@)]
309+ ^- @
310+ ?~ b 0
311+ (cat a i.b $(b t.b))
312+
313+Concatenate a list of atoms `b` using blocksize `a`, producing an atom.
314+
315+`a` is a block size (see [++bloq]()).
316+
317+`b` is a [list]() of [atoms]().
318+
319+ ~zod/try=> `@ub`(rap 2 (limo [1 2 3 4 ~]))
320+ 0b100.0011.0010.0001
321+ ~zod/try=> `@ub`(rap 1 (limo [1 2 3 4 ~]))
322+ 0b1.0011.1001
323+ ~zod/try=> (rap 0 (limo [0 0 0 ~]))
324+ 0
325+ ~zod/try=> (rap 0 (limo [1 0 1 ~]))
326+ 3
327+
328+------------------------------------------------------------------------
329+
330+### `++rep`
331+
332+Assemble single
333+
334+ ++ rep :: assemble single
335+ ~/ %rep
336+ |= [a=bloq b=(list ,@)]
337+ ^- @
338+ =+ c=0
339+ |-
340+ ?~ b 0
341+ (con (lsh a c (end a 1 i.b)) $(c +(c), b t.b))
342+
343+Produces an atom by assembling a list of atoms `b` using block size `a`.
344+
345+`a` is a block size (see [++bloq]()).
346+
347+`b` is a list of [atoms]().
348+
349+ ~zod/try=> `@ub`(rep 2 (limo [1 2 3 4 ~]))
350+ 0b100.0011.0010.0001
351+ ~zod/try=> (rep 0 (limo [0 0 1 ~]))
352+ 4
353+ ~zod/try=> (rep 0 (limo [0 0 0 1 ~]))
354+ 8
355+ ~zod/try=> (rep 0 (limo [0 1 0 0 ~]))
356+ 2
357+ ~zod/try=> (rep 0 (limo [0 1 0 1 ~]))
358+ 10
359+ ~zod/try=> (rep 0 (limo [0 1 0 1 0 1 ~]))
360+ 42
361+ ~zod/try=> `@ub`42
362+ 0b10.1010
363+
364+------------------------------------------------------------------------
365+
366+### `++rip`
367+
368+Disassemble
369+
370+ ++ rip :: disassemble
371+ ~/ %rip
372+ |= [a=bloq b=@]
373+ ^- (list ,@)
374+ ?: =(0 b) ~
375+ [(end a 1 b) $(b (rsh a 1 b))]
376+
377+Produces a list of atoms from the bits of `b` using block size `a`.
378+
379+`a` is a block size (see [++bloq]()).
380+
381+`b` is an [atom]().
382+
383+ ~zod/try=> `@ub`155
384+ 0b1001.1011
385+ ~zod/try=> (rip 0 155)
386+ ~[1 1 0 1 1 0 0 1]
387+ ~zod/try=> (rip 2 155)
388+ ~[11 9]
389+ ~zod/try=> (rip 1 155)
390+ ~[3 2 1 2]
391+ ~zod/try=> `@ub`256
392+ 0b1.0000.0000
393+ ~zod/try=> (rip 0 256)
394+ ~[0 0 0 0 0 0 0 0 1]
395+ ~zod/try=> (rip 2 256)
396+ ~[0 0 1]
397+ ~zod/try=> (rip 3 256)
398+ ~[0 1]
399+
400+------------------------------------------------------------------------
401+
402+### `++rsh`
403+
404+Right-shift
405+
406+ ++ rsh :: right-shift
407+ ~/ %rsh
408+ |= [a=bloq b=@ c=@]
409+ (div c (bex (mul (bex a) b)))
410+
411+Right-shifts `c` by `b` blocks of size `a`, producing an atom.
412+
413+`a` is a block size (see [++bloq]()).
414+
415+`b` is an [atom]().
416+
417+`c` is an [atom]().
418+
419+ ~zod/try=> `@ub`145
420+ 0b1001.0001
421+ ~zod/try=> `@ub`(rsh 1 1 145)
422+ 0b10.0100
423+ ~zod/try=> (rsh 1 1 145)
424+ 36
425+ ~zod/try=> `@ub`(rsh 2 1 145)
426+ 0b1001
427+ ~zod/try=> (rsh 2 1 145)
428+ 9
429+ ~zod/try=> `@ub`10
430+ 0b1010
431+ ~zod/try=> `@ub`(rsh 0 1 10)
432+ 0b101
433+ ~zod/try=> (rsh 0 1 10)
434+ 5
435+ ~zod/try=> `@ux`'abc'
436+ 0x63.6261
437+ ~zod/try=> `@t`(rsh 3 1 'abc')
438+ 'bc'
439+ ~zod/try=> `@ux`(rsh 3 1 'abc')
440+ 0x6362
441+
442+------------------------------------------------------------------------
443+
444+### `++swap`
445+
446+Reverse block order
447+
448+ ++ swap |=([a=bloq b=@] (rep a (flop (rip a b)))) :: reverse bloq order
449+
450+Switches little ending to big and vice versa: produces an atom by
451+reversing the block order of `b` using block size `a`.
452+
453+`a` is a block size (see [++bloq]()).
454+
455+`b` is an [atom]()
456+
457+ ~zod/try=> `@ub`24
458+ 0b1.1000
459+ ~zod/try=> (swap 0 24)
460+ 3
461+ ~zod/try=> `@ub`3
462+ 0b11
463+ ~zod/try=> (swap 0 0)
464+ 0
465+ ~zod/try=> (swap 0 128)
466+ 1
467+
468+------------------------------------------------------------------------
469+
470+section 2cB, bit logic
471+----------------------
472+
473+### `++con`
474+
475+Binary OR
476+
477+ ++ con :: binary or
478+ ~/ %con
479+ |= [a=@ b=@]
480+ =+ [c=0 d=0]
481+ |- ^- @
482+ ?: ?&(=(0 a) =(0 b)) d
483+ %= $
484+ a (rsh 0 1 a)
485+ b (rsh 0 1 b)
486+ c +(c)
487+ d %+ add d
488+ %^ lsh 0 c
489+ ?& =(0 (end 0 1 a))
490+ =(0 (end 0 1 b))
491+ ==
492+ ==
493+
494+Computes the bit-wise logical OR of two atoms, `a` and `b`, producing an
495+atom.
496+
497+`a` is an [atom]()
498+
499+`b` is an [atom]()
500+
501+ ~zod/try=> (con 0b0 0b1)
502+ 1
503+ ~zod/try=> (con 0 1)
504+ 1
505+ ~zod/try=> (con 0 0)
506+ 0
507+ ~zod/try=> `@ub`(con 0b1111.0000 0b1.0011)
508+ 0b1111.0011
509+ ~zod/try=> (con 4 4)
510+ 4
511+ ~zod/try=> (con 10.000 234)
512+ 10.234
513+
514+------------------------------------------------------------------------
515+
516+### `++dis`
517+
518+Binary AND
519+
520+ ++ dis :: binary and
521+ ~/ %dis
522+ |= [a=@ b=@]
523+ =| [c=@ d=@]
524+ |- ^- @
525+ ?: ?|(=(0 a) =(0 b)) d
526+ %= $
527+ a (rsh 0 1 a)
528+ b (rsh 0 1 b)
529+ c +(c)
530+ d %+ add d
531+ %^ lsh 0 c
532+ ?| =(0 (end 0 1 a))
533+ =(0 (end 0 1 b))
534+ ==
535+ ==
536+
537+Computes the bit-wise logical AND of two atoms `a` and `b`, producing an
538+atom.
539+
540+`a` is an [atom]()
541+
542+`b` is an [atom]()
543+
544+ ~zod/try=> `@ub`9
545+ 0b1001
546+ ~zod/try=> `@ub`5
547+ 0b101
548+ ~zod/try=> `@ub`(dis 9 5)
549+ 0b1
550+ ~zod/try=> (dis 9 5)
551+ 1
552+ ~zod/try=> `@ub`534
553+ 0b10.0001.0110
554+ ~zod/try=> `@ub`987
555+ 0b11.1101.1011
556+ ~zod/try=> `@ub`(dis 534 987)
557+ 0b10.0001.0010
558+ ~zod/try=> (dis 534 987)
559+ 530
560+
561+------------------------------------------------------------------------
562+
563+### `++mix`
564+
565+Binary XOR
566+
567+ ++ mix :: binary xor
568+ ~/ %mix
569+ |= [a=@ b=@]
570+ ^- @
571+ =+ [c=0 d=0]
572+ |-
573+ ?: ?&(=(0 a) =(0 b)) d
574+ %= $
575+ a (rsh 0 1 a)
576+ b (rsh 0 1 b)
577+ c +(c)
578+ d (add d (lsh 0 c =((end 0 1 a) (end 0 1 b))))
579+ ==
580+
581+Produces the bit-wise logical XOR of `a` and `b`, producing an atom.
582+
583+`a` is an [atom]()
584+
585+`b` is an [atom]()
586+
587+ ~zod/try=> `@ub`2
588+ 0b10
589+ ~zod/try=> `@ub`3
590+ 0b11
591+ ~zod/try=> `@ub`(mix 2 3)
592+ 0b1
593+ ~zod/try=> (mix 2 3)
594+ 1
595+ ~zod/try=> `@ub`(mix 2 2)
596+ 0b0
597+ ~zod/try=> (mix 2 2)
598+ 0
599+
600+------------------------------------------------------------------------
601+
602+### `++not`
603+
604+Binary NOT
605+
606+ ++ not |= [a=bloq b=@ c=@] :: binary not (sized)
607+ (mix c (dec (bex (mul b (bex a)))))
608+
609+Computes the bit-wise logical NOT of the bottom `b` blocks of size `a`
610+of `c`.
611+
612+`a` is a block size (see [++bloq]()).
613+
614+`b` is an [atom]().
615+
616+`c` is an [atom]().
617+
618+ ~zod/try=> `@ub`24
619+ 0b1.1000
620+ ~zod/try=> (not 0 5 24)
621+ 7
622+ ~zod/try=> `@ub`7
623+ 0b111
624+ ~zod/try=> (not 2 5 24)
625+ 1.048.551
626+ ~zod/try=> (not 2 5 1.048.551)
627+ 24
628+ ~zod/try=> (not 1 1 (not 1 1 10))
629+ 10
630+
631+------------------------------------------------------------------------
632+
633+section 2cC, noun orders
634+------------------------
635+
636+### `++aor`
637+
638+Alphabetic order
639+
640+ ++ aor :: alphabetic-order
641+ ~/ %aor
642+ |= [a=* b=*]
643+ ^- ?
644+ ?: =(a b) &
645+ ?. ?=(@ a)
646+ ?: ?=(@ b) |
647+ ?: =(-.a -.b)
648+ $(a +.a, b +.b)
649+ $(a -.a, b -.b)
650+ ?. ?=(@ b) &
651+ |-
652+ =+ [c=(end 3 1 a) d=(end 3 1 b)]
653+ ?: =(c d)
654+ $(a (rsh 3 1 a), b (rsh 3 1 b))
655+ (lth c d)
656+
657+Computes whether `a` and `b` are in alphabetical order, producing a
658+loobean.
659+
660+`a` is a [noun]().
661+
662+`b` is a [noun]().
663+
664+ ~zod/try=> (aor 'a' 'b')
665+ %.y
666+ ~zod/try=> (aor 'b' 'a')
667+ %.n
668+ ~zod/try=> (aor "foo" "bar")
669+ %.n
670+ ~zod/try=> (aor "bar" "foo")
671+ %.y
672+ ~zod/try=> (aor "abcdefz" "abcdefa")
673+ %.n
674+ ~zod/try=> (aor "abcdefa" "abcdefz")
675+ %.y
676+ ~zod/try=> (aor 10.000 17.000)
677+ %.y
678+ ~zod/try=> (aor 10 9)
679+ %.n
680+
681+------------------------------------------------------------------------
682+
683+### `++dor`
684+
685+Numeric order
686+
687+ ++ dor :: d-order
688+ ~/ %dor
689+ |= [a=* b=*]
690+ ^- ?
691+ ?: =(a b) &
692+ ?. ?=(@ a)
693+ ?: ?=(@ b) |
694+ ?: =(-.a -.b)
695+ $(a +.a, b +.b)
696+ $(a -.a, b -.b)
697+ ?. ?=(@ b) &
698+ (lth a b)
699+
700+Computes whether `a` and `b` are in ascending numeric order, producing a
701+loobean.
702+
703+`a` is a [noun]().
704+
705+`b` is a [noun]().
706+
707+ ~zod/try=> (dor 1 2)
708+ %.y
709+ ~zod/try=> (dor 2 1)
710+ %.n
711+ ~zod/try=> (dor ~[1 2 3] ~[1 2 4])
712+ %.y
713+ ~zod/try=> (dor ~[1 2 4] ~[1 2 3])
714+ %.n
715+ ~zod/try=> (dor (limo ~[99 100 10.000]) ~[99 101 10.000])
716+ %.y
717+ ~zod/try=> (dor ~[99 101 10.999] (limo ~[99 100 10.000]))
718+ %.n
719+
720+------------------------------------------------------------------------
721+
722+### `++gor`
723+
724+Hash order
725+
726+ ++ gor :: g-order
727+ ~/ %gor
728+ |= [a=* b=*]
729+ ^- ?
730+ =+ [c=(mug a) d=(mug b)]
731+ ?: =(c d)
732+ (dor a b)
733+ (lth c d)
734+
735+XX revisit
736+
737+ ~zod/try=> (gor 'd' 'c')
738+ %.y
739+ ~zod/try=> 'd'
740+ 'd'
741+ ~zod/try=> 'c'
742+ ~zod/try=> `@ud`'d'
743+ 100
744+ ~zod/try=> `@ud`'c'
745+ 99
746+ ~zod/try=> (mug 'd')
747+ 1.628.185.714
748+ ~zod/try=> (mug 'c')
749+ 1.712.073.811
750+ ~zod/try=> (gor 'd' 'c')
751+ %.y
752+ ~zod/try=> (gor 'c' 'd')
753+ %.n
754+ ~zod/try=> (gor "foo" "bar")
755+ %.n
756+ ~zod/try=> (gor (some 10) (limo [1 2 3 ~]))
757+ %.n
758+
759+------------------------------------------------------------------------
760+
761+### `++hor`
762+
763+Hash order
764+
765+ ++ hor :: h-order
766+ ~/ %hor
767+ |= [a=* b=*]
768+ ^- ?
769+ ?: ?=(@ a)
770+ ?. ?=(@ b) &
771+ (gor a b)
772+ ?: ?=(@ b) |
773+ ?: =(-.a -.b)
774+ (gor +.a +.b)
775+ (gor -.a -.b)
776+
777+XX revisit
778+
779+Recursive hash comparator gate.
780+
781+ ~zod/try=> (hor . 1)
782+ %.n
783+ ~zod/try=> (hor 1 2)
784+ %.y
785+ ~zod/try=> (hor "abc" "cba")
786+ %.y
787+ ~zod/try=> (hor 'c' 'd')
788+ %.n
789+
790+------------------------------------------------------------------------
791+
792+### `++vor`
793+
794+ ++ vor :: v-order
795+ ~/ %vor
796+ |= [a=* b=*]
797+ ^- ?
798+ =+ [c=(mug (mug a)) d=(mug (mug b))]
799+ ?: =(c d)
800+ (dor a b)
801+ (lth c d)
802+
803+XX revisit
804+
805+Double hash comparator gate.
806+
807+ ~zod/try=> (vor 'f' 'g')
808+ %.y
809+ ~zod/try=> (vor 'a' 'z')
810+ %.n
811+ ~zod/try=> (vor 43.326 41.106)
812+ %.n
813+
814+section 2cD, insecure hashing
815+-----------------------------
816+
817+### `++fnv`
818+
819+ ++ fnv |=(a=@ (end 5 1 (mul 16.777.619 a))) :: FNV scrambler
820+
821+Hashes an atom with the 32-bit FNV non-cryptographic hash algorithm.
822+Multiplies `a` by the prime number 16,777,619 and then takes the block
823+of size 5 off the product's end, producing atom.
824+
825+`a` is an [atom]().
826+
827+ ~zod/try=> (fnv 10.000)
828+ 272.465.456
829+ ~zod/try=> (fnv 10.001)
830+ 289.243.075
831+ ~zod/try=> (fnv 1)
832+ 16.777.619
833+
834+------------------------------------------------------------------------
835+
836+### `++mum`
837+
838+ ++ mum :: mug with murmur3
839+ ~/ %mum
840+ |= a=*
841+ |^ (trim ?@(a a (mix $(a -.a) (mix 0x7fff.ffff $(a +.a)))))
842+ ++ spec :: standard murmur3
843+ |= [syd=@ key=@]
844+ ?> (lte (met 5 syd) 1)
845+ =+ ^= row
846+ |= [a=@ b=@]
847+ (con (end 5 1 (lsh 0 a b)) (rsh 0 (sub 32 a) b))
848+ =+ mow=|=([a=@ b=@] (end 5 1 (mul a b)))
849+ =+ len=(met 5 key)
850+ =- =. goc (mix goc len)
851+ =. goc (mix goc (rsh 4 1 goc))
852+ =. goc (mow goc 0x85eb.ca6b)
853+ =. goc (mix goc (rsh 0 13 goc))
854+ =. goc (mow goc 0xc2b2.ae35)
855+ (mix goc (rsh 4 1 goc))
856+ ^= goc
857+ =+ [inx=0 goc=syd]
858+ |- ^- @
859+ ?: =(inx len) goc
860+ =+ kop=(cut 5 [inx 1] key)
861+ =. kop (mow kop 0xcc9e.2d51)
862+ =. kop (row 15 kop)
863+ =. kop (mow kop 0x1b87.3593)
864+ =. goc (mix kop goc)
865+ =. goc (row 13 goc)
866+ =. goc (end 5 1 (add 0xe654.6b64 (mul 5 goc)))
867+ $(inx +(inx))
868+ ::
869+ ++ trim :: 31-bit nonzero
870+ |= key=@
871+ =+ syd=0xcafe.babe
872+ |- ^- @
873+ =+ haz=(spec syd key)
874+ =+ ham=(mix (rsh 0 31 haz) (end 0 31 haz))
875+ ?.(=(0 ham) ham $(syd +(syd)))
876+ --
877+ ::
878+
879+XX document
880+
881+ ~zod/try=> (mum 10.000)
882+ 1.232.632.901
883+ ~zod/try=> (mum 10.001)
884+ 658.093.079
885+ ~zod/try=> (mum 1)
886+ 818.387.364
887+ ~zod/try=> (mum (some 10))
888+ 1.177.215.703
889+ ~zod/try=> (mum ~[1 2 3 4 5])
890+ 1.517.902.092
891+
892+### `++mug`
893+
894+ ++ mug :: 31bit nonzero FNV1a
895+ ~/ %mug
896+ |= a=*
897+ ?^ a
898+ =+ b=[p=$(a -.a) q=$(a +.a)]
899+ |- ^- @
900+ =+ c=(fnv (mix p.b (fnv q.b)))
901+ =+ d=(mix (rsh 0 31 c) (end 0 31 c))
902+ ?. =(0 c) c
903+ $(q.b +(q.b))
904+ =+ b=2.166.136.261
905+ |- ^- @
906+ =+ c=b
907+ =+ [d=0 e=(met 3 a)]
908+ |- ^- @
909+ ?: =(d e)
910+ =+ f=(mix (rsh 0 31 c) (end 0 31 c))
911+ ?. =(0 f) f
912+ ^$(b +(b))
913+ $(c (fnv (mix c (cut 3 [d 1] a))), d +(d))
914+
915+Hashes `a` with the 31-bit nonzero FNV-1a non-cryptographic hash
916+algorithm, producing an atom.
917+
918+ ~zod/try=> (mug 10.000)
919+ 178.152.889
920+ ~zod/try=> (mug 10.001)
921+ 714.838.017
922+ ~zod/try=> (mug 1)
923+ 67.918.732
924+ ~zod/try=> (mug (some 10))
925+ 1.872.403.737
926+ ~zod/try=> (mug (limo [1 2 3 4 5 ~]))
927+ 1.067.931.605
928+
929+section 2cE, phonetic base
930+--------------------------
931+
932+### `++po`
933+
934+ ++ po
935+ ~/ %po
936+ =+ :- ^= sis :: prefix syllables
937+ 'dozmarbinwansamlitsighidfidlissogdirwacsabwissib\
938+ /rigsoldopmodfoglidhopdardorlorhodfolrintogsilmir\
939+ /holpaslacrovlivdalsatlibtabhanticpidtorbolfosdot\
940+ /losdilforpilramtirwintadbicdifrocwidbisdasmidlop\
941+ /rilnardapmolsanlocnovsitnidtipsicropwitnatpanmin\
942+ /ritpodmottamtolsavposnapnopsomfinfonbanporworsip\
943+ /ronnorbotwicsocwatdolmagpicdavbidbaltimtasmallig\
944+ /sivtagpadsaldivdactansidfabtarmonranniswolmispal\
945+ /lasdismaprabtobrollatlonnodnavfignomnibpagsopral\
946+ /bilhaddocridmocpacravripfaltodtiltinhapmicfanpat\
947+ /taclabmogsimsonpinlomrictapfirhasbosbatpochactid\
948+ /havsaplindibhosdabbitbarracparloddosbortochilmac\
949+ /tomdigfilfasmithobharmighinradmashalraglagfadtop\
950+ /mophabnilnosmilfopfamdatnoldinhatnacrisfotribhoc\
951+ /nimlarfitwalrapsarnalmoslandondanladdovrivbacpol\
952+ /laptalpitnambonrostonfodponsovnocsorlavmatmipfap'
953+ ^= dex :: suffix syllables
954+ 'zodnecbudwessevpersutletfulpensytdurwepserwylsun\
955+ /rypsyxdyrnuphebpeglupdepdysputlughecryttyvsydnex\
956+ /lunmeplutseppesdelsulpedtemledtulmetwenbynhexfeb\
957+ /pyldulhetmevruttylwydtepbesdexsefwycburderneppur\
958+ /rysrebdennutsubpetrulsynregtydsupsemwynrecmegnet\
959+ /secmulnymtevwebsummutnyxrextebfushepbenmuswyxsym\
960+ /selrucdecwexsyrwetdylmynmesdetbetbeltuxtugmyrpel\
961+ /syptermebsetdutdegtexsurfeltudnuxruxrenwytnubmed\
962+ /lytdusnebrumtynseglyxpunresredfunrevrefmectedrus\
963+ /bexlebduxrynnumpyxrygryxfeptyrtustyclegnemfermer\
964+ /tenlusnussyltecmexpubrymtucfyllepdebbermughuttun\
965+ /bylsudpemdevlurdefbusbeprunmelpexdytbyttyplevmyl\
966+ /wedducfurfexnulluclennerlexrupnedlecrydlydfenwel\
967+ /nydhusrelrudneshesfetdesretdunlernyrsebhulryllud\
968+ /remlysfynwerrycsugnysnyllyndyndemluxfedsedbecmun\
969+ /lyrtesmudnytbyrsenwegfyrmurtelreptegpecnelnevfes'
970+ |%
971+
972+Provides the phonetic syllables and name generators for the Urbit naming
973+system. The two faces, `sis` and `dex` are available to the arms
974+contained in this section.
975+
976+------------------------------------------------------------------------
977+
978+### `++ind`
979+
980+Parse prefix
981+
982+ ++ ind ~/ %ind :: parse prefix
983+ |= a=@
984+ =+ b=0
985+ |- ^- (unit ,@)
986+ ?:(=(256 b) ~ ?:(=(a (tod b)) [~ b] $(b +(b))))
987+
988+Produces the byte of the right-hand syllable `a`.
989+
990+`a` is an [atom]().
991+
992+ ~zod/try=> (ind:po 'zod')
993+ [~ 0]
994+ ~zod/try=> (ind:po 'zam')
995+ ~
996+ ~zod/try=> (ind:po 'del')
997+ [~ 37]
998+
999+------------------------------------------------------------------------
1000+
1001+### `++ins`
1002+
1003+Parse suffix
1004+
1005+ ++ ins ~/ %ins :: parse suffix
1006+ |= a=@
1007+ =+ b=0
1008+ |- ^- (unit ,@)
1009+ ?:(=(256 b) ~ ?:(=(a (tos b)) [~ b] $(b +(b))))
1010+
1011+Produces the byte of the left-hand phonetic syllable `b`.
1012+
1013+`a` is an [atom]().
1014+
1015+ ~zod/try=> (ins:po 'mar')
1016+ [~ 1]
1017+ ~zod/try=> (ins:po 'son')
1018+ [~ 164]
1019+ ~zod/try=> (ins:po 'pit')
1020+ [~ 242]
1021+ ~zod/try=> (ins:po 'pok')
1022+ ~
1023+
1024+------------------------------------------------------------------------
1025+
1026+### `++tod`
1027+
1028+Fetch prefix
1029+
1030+ ++ tod ~/ %tod :: fetch prefix
1031+ |=(a=@ ?>((lth a 256) (cut 3 [(mul 3 a) 3] dex)))
1032+
1033+Produces the phonetic prefix syllable from index `a` within `dex` as an
1034+atom.
1035+
1036+`a` is an [atom]()
1037+
1038+ ~zod/try=> `@t`(tod:po 1)
1039+ 'nec'
1040+ ~zod/try=> `@t`(tod:po 98)
1041+ 'dec'
1042+ ~zod/try=> `@t`(tod:po 0)
1043+ 'zod'
1044+ ~zod/try=> `@t`(tod:po 150)
1045+ 'ryg'
1046+ ~zod/try=> `@t`(tod:po 255)
1047+ 'fes'
1048+ ~zod/try=> `@t`(tod:po 256)
1049+ ! exit
1050+
1051+------------------------------------------------------------------------
1052+
1053+### `++tos`
1054+
1055+Fetch suffix
1056+
1057+ ++ tos ~/ %tos :: fetch suffix
1058+ |=(a=@ ?>((lth a 256) (cut 3 [(mul 3 a) 3] sis)))
1059+
1060+Produces the phonetic prefix syllable from index `a` within `sis` as an
1061+atom.
1062+
1063+ ~zod/try=> `@t`(tos:po 0)
1064+ 'doz'
1065+ ~zod/try=> `@t`(tos:po 120)
1066+ 'fab'
1067+ ~zod/try=> `@t`(tos:po 43)
1068+ 'pid'
1069+ ~zod/try=> `@t`(tos:po 253)
1070+ 'mat'
1071+
1072+------------------------------------------------------------------------
1073+
1074+section 2cF, signed and modular ints
1075+------------------------------------
1076+
1077+### `++si`
1078+
1079+ ++ si !: :: signed integer
1080+ |%
1081+
1082+Container for the signed integer functions.
1083+
1084+------------------------------------------------------------------------
1085+
1086+### `++abs`
1087+
1088+ ++ abs |=(a=@s (add (end 0 1 a) (rsh 0 1 a))) :: absolute value
1089+
1090+Produces the absolute value of a signed integer.
1091+
1092+`a` is a signed integer, `@s`.
1093+
1094+ ~zod/try=> (abs:si -2)
1095+ 2
1096+ ~zod/try=> (abs:si -10.000)
1097+ 10.000
1098+ ~zod/try=> (abs:si --2)
1099+ 2
1100+
1101+------------------------------------------------------------------------
1102+
1103+### `++dif`
1104+
1105+ ++ dif |= [a=@s b=@s] :: subtraction
1106+ (sum a (new !(syn b) (abs b)))
1107+
1108+Produces the difference between two signed integers `b` and `c`.
1109+
1110+`a` is a signed integer, `@s`.
1111+
1112+`b` is a signed integer, `@s`.
1113+
1114+ ~zod/try=> (dif:si --10 -7)
1115+ --17
1116+ ~zod/try=> (dif:si --10 --7)
1117+ --3
1118+ ~zod/try=> (dif:si `@s`0 --7)
1119+ -7
1120+ ~zod/try=> (dif:si `@s`0 `@s`7)
1121+ --4
1122+
1123+------------------------------------------------------------------------
1124+
1125+### `++dul`
1126+
1127+ ++ dul |= [a=@s b=@] :: modulus
1128+ =+(c=(old a) ?:(-.c (mod +.c b) (sub b +.c)))
1129+
1130+Produces the modulus of two signed integers.
1131+
1132+`a` is a signed integer, `@s`.
1133+
1134+`b` is an [atom]().
1135+
1136+ ~zod/try=> (dul:si --9 3)
1137+ 0
1138+ ~zod/try=> (dul:si --9 4)
1139+ 1
1140+ ~zod/try=> (dul:si --9 5)
1141+ 4
1142+ ~zod/try=> (dul:si --9 6)
1143+ 3
1144+ ~zod/try=> (dul:si --90 --10)
1145+ 10
1146+
1147+------------------------------------------------------------------------
1148+
1149+### `++fra`
1150+
1151+ ++ fra |= [a=@s b=@s] :: divide
1152+ (new =(0 (mix (syn a) (syn b))) (div (abs a) (abs b)))
1153+
1154+Produces the quotient of two signed integers.
1155+
1156+`a` is a signed integer, `@s`.
1157+
1158+`b` is a signed integer, `@s`.
1159+
1160+ ~zod/try=> (fra:si --10 -2)
1161+ -5
1162+ ~zod/try=> (fra:si -20 -5)
1163+ --4
1164+
1165+------------------------------------------------------------------------
1166+
1167+### `++new`
1168+
1169+ ++ new |= [a=? b=@] :: [sign value] to @s
1170+ `@s`?:(a (mul 2 b) ?:(=(0 b) 0 +((mul 2 (dec b)))))
1171+
1172+Produces a signed integer from a loobean sign value `a` and an atom `b`.
1173+
1174+`a` is a loobean.
1175+
1176+`b` is an [atom]().
1177+
1178+ ~zod/try=> (new:si [& 10])
1179+ --10
1180+ ~zod/try=> (new:si [| 10])
1181+ -10
1182+ ~zod/try=> (new:si [%.y 7])
1183+ --7
1184+
1185+------------------------------------------------------------------------
1186+
1187+### `++old`
1188+
1189+ ++ old |=(a=@s [(syn a) (abs a)]) :: [sign value]
1190+
1191+Produces the cell `[sign value]` representations of a signed integer.
1192+
1193+`a` is a signed integer, `@s`.
1194+
1195+ ~zod/try=> (old:si 7)
1196+ ! type-fail
1197+ ! exit
1198+ ~zod/try=> (old:si -7)
1199+ [%.n 7]
1200+ ~zod/try=> (old:si --7)
1201+ [%.y 7]
1202+ ~zod/try=> (old:si `@s`7)
1203+ [%.n 4]
1204+ ~zod/try=> (old:si -0)
1205+ [%.y 0]
1206+
1207+------------------------------------------------------------------------
1208+
1209+### `++pro`
1210+
1211+ ++ pro |= [a=@s b=@s] :: multiplication
1212+ (new =(0 (mix (syn a) (syn b))) (mul (abs a) (abs b)))
1213+
1214+Produces the product of two signed integers.
1215+
1216+`a` is a signed integer, `@s`.
1217+
1218+`b` is a signed integer, `@s`.
1219+
1220+ ~zod/try=> (pro:si -4 --2)
1221+ -8
1222+ ~zod/try=> (pro:si -4 -2)
1223+ --8
1224+ ~zod/try=> (pro:si --10.000.000 -10)
1225+ -100.000.000
1226+ ~zod/try=> (pro:si -1.337 --0)
1227+ --0
1228+
1229+------------------------------------------------------------------------
1230+
1231+### `++rem`
1232+
1233+ ++ rem |=([a=@s b=@s] (dif a (pro b (fra a b)))) :: remainder
1234+
1235+Produces the remainder from a division of two signed integers.
1236+
1237+`a` is a signed integer, `@s`.
1238+
1239+`b` is a signed integer, `@s`.
1240+
1241+ ~zod/try=> (rem:si -10 -4)
1242+ -2
1243+ ~zod/try=> (rem:si --10 --4)
1244+ --2
1245+ ~zod/try=> (rem:si --10 -4)
1246+ --2
1247+ ~zod/try=> (rem:si --7 --3)
1248+ --1
1249+ ~zod/try=> (rem:si --0 --10.000)
1250+ --0
1251+
1252+------------------------------------------------------------------------
1253+
1254+### `++sum`
1255+
1256+ ++ sum |= [a=@s b=@s] :: addition
1257+ ~| %si-sum
1258+ =+ [c=(old a) d=(old b)]
1259+ ?: -.c
1260+ ?: -.d
1261+ (new & (add +.c +.d))
1262+ ?: (gte +.c +.d)
1263+ (new & (sub +.c +.d))
1264+ (new | (sub +.d +.c))
1265+ ?: -.d
1266+ ?: (gte +.c +.d)
1267+ (new | (sub +.c +.d))
1268+ (new & (sub +.d +.c))
1269+ (new | (add +.c +.d))
1270+
1271+Sum two signed integers.
1272+
1273+`b` is a signed integer, `@s`.
1274+
1275+`c` is a signed integer, `@s`.
1276+
1277+ ~zod/try=> (sum:si --10 --10)
1278+ --20
1279+ ~zod/try=> (sum:si --10 -0)
1280+ --10
1281+ ~zod/try=> (sum:si -10 -7)
1282+ -17
1283+ ~zod/try=> (sum:si -10 --7)
1284+ -3
1285+
1286+------------------------------------------------------------------------
1287+
1288+### `++sun`
1289+
1290+ ++ sun |=(a=@u (mul 2 a)) :: @u to @s
1291+
1292+Produces a signed integer from an unsigned integer.
1293+
1294+Note that the result must be manually cast to some @s odor to be
1295+inferred as an unsigned integer in the type system.
1296+
1297+`a` is an unsigned integer, `@u`.
1298+
1299+ ~zod/try=> `@s`10
1300+ --5
1301+ ~zod/try=> (sun:si 10)
1302+ 20
1303+ ~zod/try=> `@s`(sun:si 10)
1304+ --10
1305+ ~zod/try=> `@sd`(sun:si 10)
1306+ --10
1307+ ~zod/try=> `@sd`(sun:si 12.345)
1308+ --12.345
1309+
1310+------------------------------------------------------------------------
1311+
1312+### `++syn`
1313+
1314+ ++ syn |=(a=@s =(0 (end 0 1 a))) :: sign test
1315+
1316+Produce the sign of a signed integer, `&` being posiitve, `|` negative.
1317+
1318+`a` is a signed integer, `@s`.
1319+
1320+ ~zod/try=> (syn:si -2)
1321+ %.n
1322+ ~zod/try=> (syn:si --2)
1323+ %.y
1324+ ~zod/try=> (syn:si -0)
1325+ %.y
1326+
1327+------------------------------------------------------------------------
1328+
1329+### `++cmp`
1330+
1331+ ++ cmp |= [a=@s b=@s] :: compare
1332+ ^- @s
1333+ ?: =(a b)
1334+ --0
1335+ ?: (syn a)
1336+ ?: (syn b)
1337+ ?: (gth a b)
1338+ --1
1339+ -1
1340+ --1
1341+ ?: (syn b)
1342+ -1
1343+ ?: (gth a b)
1344+ -1
1345+ --1
1346+
1347+Compare two signed integers.
1348+
1349+`b` is a signed integer, `@s`.
1350+
1351+`c` is a signed integer, `@s`.
1352+
1353+ ~zod/try=> (cmp:si --10 --10)
1354+ --0
1355+ ~zod/try=> (cmp:si --10 -0)
1356+ --1
1357+ ~zod/try=> (cmp:si -10 -7)
1358+ -1
1359+ ~zod/try=> (cmp:si -10 --7)
1360+ -1
1361+
1362+------------------------------------------------------------------------
1363+
1364+### `++dif`
1365+
1366+ ++ dif |=([b=@ c=@] (sit (sub (add out (sit b)) (sit c))))
1367+
1368+Produces the difference between two atoms in the modular basis
1369+representation.
1370+
1371+`b` is an [atom]().
1372+
1373+`c` is an [atom]().
1374+
1375+ ~zod/try=> (~(dif fe 3) 63 64)
1376+ 255
1377+ ~zod/try=> (~(dif fe 3) 5 10)
1378+ 251
1379+ ~zod/try=> (~(dif fe 3) 0 1)
1380+ 255
1381+ ~zod/try=> (~(dif fe 0) 9 10)
1382+ 1
1383+ ~zod/try=> (~(dif fe 0) 9 11)
1384+ 0
1385+ ~zod/try=> (~(dif fe 0) 9 12)
1386+ 1
1387+ ~zod/try=> (~(dif fe 2) 9 12)
1388+ 13
1389+ ~zod/try=> (~(dif fe 2) 63 64)
1390+ 15
1391+
1392+------------------------------------------------------------------------
1393+
1394+### `++inv`
1395+
1396+ ++ inv |=(b=@ (sub (dec out) (sit b)))
1397+
1398+Inverts the order of the modular field.
1399+
1400+`b` is an [atom]().
1401+
1402+ ~zod/try=> (~(inv fe 3) 255)
1403+ 0
1404+ ~zod/try=> (~(inv fe 3) 256)
1405+ 255
1406+ ~zod/try=> (~(inv fe 3) 0)
1407+ 255
1408+ ~zod/try=> (~(inv fe 3) 1)
1409+ 254
1410+ ~zod/try=> (~(inv fe 3) 2)
1411+ 253
1412+ ~zod/try=> (~(inv fe 3) 55)
1413+ 200
1414+
1415+------------------------------------------------------------------------
1416+
1417+### `++net`
1418+
1419+ ++ net |= b=@ ^- @
1420+ => .(b (sit b))
1421+ ?: (lte a 3)
1422+ b
1423+ =+ c=(dec a)
1424+ %+ con
1425+ (lsh c 1 $(a c, b (cut c [0 1] b)))
1426+ $(a c, b (cut c [1 1] b))
1427+
1428+Reverse bytes within block.
1429+
1430+`b` is an [atom]().
1431+
1432+ ~zod/try=> (~(net fe 3) 64)
1433+ 64
1434+ ~zod/try=> (~(net fe 3) 128)
1435+ 128
1436+ ~zod/try=> (~(net fe 3) 255)
1437+ 255
1438+ ~zod/try=> (~(net fe 3) 256)
1439+ 0
1440+ ~zod/try=> (~(net fe 3) 257)
1441+ 1
1442+ ~zod/try=> (~(net fe 3) 500)
1443+ 244
1444+ ~zod/try=> (~(net fe 3) 511)
1445+ 255
1446+ ~zod/try=> (~(net fe 3) 512)
1447+ 0
1448+ ~zod/try=> (~(net fe 3) 513)
1449+ 1
1450+ ~zod/try=> (~(net fe 3) 0)
1451+ 0
1452+ ~zod/try=> (~(net fe 3) 1)
1453+ 1
1454+ ~zod/try=> (~(net fe 0) 1)
1455+ 1
1456+ ~zod/try=> (~(net fe 0) 2)
1457+ 0
1458+ ~zod/try=> (~(net fe 0) 3)
1459+ 1
1460+ ~zod/try=> (~(net fe 6) 1)
1461+ 72.057.594.037.927.936
1462+ ~zod/try=> (~(net fe 6) 2)
1463+ 144.115.188.075.855.872
1464+ ~zod/try=> (~(net fe 6) 3)
1465+ 216.172.782.113.783.808
1466+ ~zod/try=> (~(net fe 6) 4)
1467+ 288.230.376.151.711.744
1468+ ~zod/try=> (~(net fe 6) 5)
1469+ 360.287.970.189.639.680
1470+ ~zod/try=> (~(net fe 6) 6)
1471+ 432.345.564.227.567.616
1472+ ~zod/try=> (~(net fe 6) 7)
1473+ 504.403.158.265.495.552
1474+ ~zod/try=> (~(net fe 6) 512)
1475+ 562.949.953.421.312
1476+ ~zod/try=> (~(net fe 6) 513)
1477+ 72.620.543.991.349.248
1478+
1479+------------------------------------------------------------------------
1480+
1481+### `++out`
1482+
1483+ ++ out (bex (bex a))
1484+
1485+The maximum integer value that the current block can store.
1486+
1487+ ~zod/try=> ~(out fe 0)
1488+ 2
1489+ ~zod/try=> ~(out fe 1)
1490+ 4
1491+ ~zod/try=> ~(out fe 2)
1492+ 16
1493+ ~zod/try=> ~(out fe 3)
1494+ 256
1495+ ~zod/try=> ~(out fe 4)
1496+ 65.536
1497+ ~zod/try=> ~(out fe 10)
1498+ \/179.769.313.486.231.590.772.930.519.078.902.473.361.797.697.894.230.657.\/
1499+ 273.430.081.157.732.675.805.500.963.132.708.477.322.407.536.021.120.113.
1500+ 879.871.393.357.658.789.768.814.416.622.492.847.430.639.474.124.377.767.
1501+ 893.424.865.485.276.302.219.601.246.094.119.453.082.952.085.005.768.838.
1502+ 150.682.342.462.881.473.913.110.540.827.237.163.350.510.684.586.298.239.
1503+ 947.245.938.479.716.304.835.356.329.624.224.137.216
1504+ \/ \/
1505+
1506+------------------------------------------------------------------------
1507+
1508+### `++rol`
1509+
1510+ ++ rol |= [b=bloq c=@ d=@] ^- @ :: roll left
1511+ =+ e=(sit d)
1512+ =+ f=(bex (sub a b))
1513+ =+ g=(mod c f)
1514+ (sit (con (lsh b g e) (rsh b (sub f g) e)))
1515+
1516+Roll `d` to the left by `c` `b`-sized blocks.
1517+
1518+`b` is a block size (see [++bloq]()).
1519+
1520+`c` is an [atom]().
1521+
1522+`d` is an [atom]().
1523+
1524+ ~zod/try=> `@ux`(~(rol fe 6) 4 3 0xabac.dedf.1213)
1525+ 0x1213.0000.abac.dedf
1526+ ~zod/try=> `@ux`(~(rol fe 6) 4 2 0xabac.dedf.1213)
1527+ 0xdedf.1213.0000.abac
1528+ ~zod/try=> `@t`(~(rol fe 5) 3 1 'dfgh')
1529+ 'hdfg'
1530+ ~zod/try=> `@t`(~(rol fe 5) 3 2 'dfgh')
1531+ 'ghdf'
1532+ ~zod/try=> `@t`(~(rol fe 5) 3 0 'dfgh')
1533+ 'dfgh'
1534+
1535+------------------------------------------------------------------------
1536+
1537+### `++ror`
1538+
1539+ ++ ror |= [b=bloq c=@ d=@] ^- @ :: roll right
1540+ =+ e=(sit d)
1541+ =+ f=(bex (sub a b))
1542+ =+ g=(mod c f)
1543+ (sit (con (rsh b g e) (lsh b (sub f g) e)))
1544+
1545+Roll `d` to the right by `c` `b`-sized blocks.
1546+
1547+`b` is a block size (see [++bloq]()).
1548+
1549+`c` is an [atom]().
1550+
1551+`d` is an [atom]().
1552+
1553+ ~zod/try=> `@ux`(~(ror fe 6) 4 1 0xabac.dedf.1213)
1554+ 0x1213.0000.abac.dedf
1555+ ~zod/try=> `@ux`(~(ror fe 6) 3 5 0xabac.dedf.1213)
1556+ 0xacde.df12.1300.00ab
1557+ ~zod/try=> `@ux`(~(ror fe 6) 3 3 0xabac.dedf.1213)
1558+ 0xdf12.1300.00ab.acde
1559+ ~zod/try=> `@t`(~(rol fe 5) 3 0 'hijk')
1560+ 'hijk'
1561+ ~zod/try=> `@t`(~(rol fe 5) 3 1 'hijk')
1562+ 'khij'
1563+ ~zod/try=> `@t`(~(rol fe 5) 3 2 'hijk')
1564+ 'jkhi'
1565+
1566+------------------------------------------------------------------------
1567+
1568+### `++sum`
1569+
1570+ ++ sum |=([b=@ c=@] (sit (add b c))) :: wrapping add
1571+
1572+Sum two numbers in this modular field.
1573+
1574+`b` is an [atom]().
1575+
1576+`c` is an [atom]().
1577+
1578+ ~zod/try=> (~(sum fe 3) 10 250)
1579+ 4
1580+ ~zod/try=> (~(sum fe 0) 0 1)
1581+ 1
1582+ ~zod/try=> (~(sum fe 0) 0 2)
1583+ 0
1584+ ~zod/try=> (~(sum fe 2) 14 2)
1585+ 0
1586+ ~zod/try=> (~(sum fe 2) 14 3)
1587+ 1
1588+ ~zod/try=> (~(sum fe 4) 10.000 256)
1589+ 10.256
1590+ ~zod/try=> (~(sum fe 4) 10.000 100.000)
1591+ 44.464
1592+
1593+------------------------------------------------------------------------
1594+
1595+### `++sit`
1596+
1597+ ++ sit |=(b=@ (end a 1 b)) :: enforce modulo
1598+
1599+Produce an atom in the current modular block representation.
1600+
1601+`b` is an [atom]().
1602+
1603+ ~zod/try=> (~(sit fe 3) 255)
1604+ 255
1605+ ~zod/try=> (~(sit fe 3) 256)
1606+ 0
1607+ ~zod/try=> (~(sit fe 3) 257)
1608+ 1
1609+ ~zod/try=> (~(sit fe 2) 257)
1610+ 1
1611+ ~zod/try=> (~(sit fe 2) 10.000)
1612+ 0
1613+ ~zod/try=> (~(sit fe 2) 100)
1614+ 4
1615+ ~zod/try=> (~(sit fe 2) 19)
1616+ 3
1617+ ~zod/try=> (~(sit fe 2) 17)
1618+ 1
1619+ ~zod/try=> (~(sit fe 0) 17)
1620+ 1
1621+ ~zod/try=> (~(sit fe 0) 0)
1622+ 0
1623+ ~zod/try=> (~(sit fe 0) 1)
1624+ 1
1625+
1626+------------------------------------------------------------------------
1627+
1628+section 2cG, floating point
1629+---------------------------
1630+
1631+XX awaiting interface rewrite
1632+
1633+section 2cH, urbit time
1634+-----------------------
1635+
1636+Note that entering '-\<-' in the shell produces the current time in @da
1637+format. We use this for many of our examples.
1638+
1639+ ~zod/try=> -<-
1640+ ~2014.8.4..19.39.59..9288
1641+
1642+### `++year`
1643+
1644+ ++ year :: date to @d
1645+ |= det=date
1646+ ^- @d
1647+ =+ ^= yer
1648+ ?: a.det
1649+ (add 292.277.024.400 y.det)
1650+ (sub 292.277.024.400 (dec y.det))
1651+ =+ day=(yawn yer m.det d.t.det)
1652+ (yule day h.t.det m.t.det s.t.det f.t.det)
1653+
1654+Accept a parsed date of form `[[a=? y=@ud] m=@ud t=tarp]` and produce
1655+its `@d`representation.
1656+
1657+`det` is a [`++date`]()
1658+
1659+ ~zod/try=> (year [[a=%.y y=2.014] m=8 t=[d=4 h=20 m=4 s=57 f=~[0xd940]]])
1660+ 0x8000000d227df4e9d940000000000000
1661+
1662+------------------------------------------------------------------------
1663+
1664+### `++yore`
1665+
1666+ ++ yore :: @d to date
1667+ |= now=@d
1668+ ^- date
1669+ =+ rip=(yell now)
1670+ =+ ger=(yall d.rip)
1671+ :- ?: (gth y.ger 292.277.024.400)
1672+ [a=& y=(sub y.ger 292.277.024.400)]
1673+ [a=| y=+((sub 292.277.024.400 y.ger))]
1674+ [m.ger d.ger h.rip m.rip s.rip f.rip]
1675+
1676+Produces a `++date` from a `@d`
1677+
1678+`now` is a `@d`.
1679+
1680+ ~zod/try=> (yore -<-)
1681+ [[a=%.y y=2.014] m=8 t=[d=4 h=20 m=17 s=1 f=~[0x700d]]]
1682+ ~zod/try=> (yore -<-)
1683+ [[a=%.y y=2.014] m=8 t=[d=4 h=20 m=28 s=53 f=~[0x7b82]]]
1684+
1685+------------------------------------------------------------------------
1686+
1687+### `++yell`
1688+
1689+ ++ yell :: tarp from @d
1690+ |= now=@d
1691+ ^- tarp
1692+ =+ sec=(rsh 6 1 now)
1693+ =+ ^= fan
1694+ =+ [muc=4 raw=(end 6 1 now)]
1695+ |- ^- (list ,@ux)
1696+ ?: |(=(0 raw) =(0 muc))
1697+ ~
1698+ => .(muc (dec muc))
1699+ [(cut 4 [muc 1] raw) $(raw (end 4 muc raw))]
1700+ =+ day=(div sec day:yo)
1701+ => .(sec (mod sec day:yo))
1702+ =+ hor=(div sec hor:yo)
1703+ => .(sec (mod sec hor:yo))
1704+ =+ mit=(div sec mit:yo)
1705+ => .(sec (mod sec mit:yo))
1706+ [day hor mit sec fan]
1707+
1708+Produce a parsed daily time format from an atomic date.
1709+
1710+`now` is a `@d`.
1711+
1712+ ~zod/try=> (yell ~2014.3.20..05.42.53..7456)
1713+ [d=106.751.991.820.094 h=5 m=42 s=53 f=~[0x7456]]
1714+ ~zod/try=> (yell ~2014.6.9..19.09.40..8b66)
1715+ [d=106.751.991.820.175 h=19 m=9 s=40 f=~[0x8b66]]
1716+ ~zod/try=> (yell ~1776.7.4)
1717+ [d=106.751.991.733.273 h=0 m=0 s=0 f=~]
1718+
1719+------------------------------------------------------------------------
1720+
1721+### `++yule`
1722+
1723+ ++ yule :: time atom
1724+ |= rip=tarp
1725+ ^- @d
1726+ =+ ^= sec ;: add
1727+ (mul d.rip day:yo)
1728+ (mul h.rip hor:yo)
1729+ (mul m.rip mit:yo)
1730+ s.rip
1731+ ==
1732+ =+ ^= fac =+ muc=4
1733+ |- ^- @
1734+ ?~ f.rip
1735+ 0
1736+ => .(muc (dec muc))
1737+ (add (lsh 4 muc i.f.rip) $(f.rip t.f.rip))
1738+ (con (lsh 6 1 sec) fac)
1739+
1740+Accept a [`++tarp`](/doc/hoon/library/1#++tarp), a parsed daily time, and produces a time atom,
1741+`@d`.
1742+
1743+`rip` is a [`++tarp`](/doc/hoon/library/1#++tarp).
1744+
1745+ ~zod/try=> =murica (yell ~1776.7.4)
1746+ ~zod/try=> murica
1747+ [d=106.751.991.733.273 h=0 m=0 s=0 f=~]
1748+ ~zod/try=> (yule murica)
1749+ 0x8000000b62aaf5800000000000000000
1750+ ~zod/try=> `@da`(yule murica)
1751+ ~1776.7.4
1752+ ~zod/try=> `@da`(yule (yell ~2014.3.20..05.42.53..7456))
1753+ ~2014.3.20..05.42.53..7456
1754+ ~zod/try=> `tarp`[31 12 30 0 ~]
1755+ [d=31 h=12 m=30 s=0 f=~]
1756+ ~zod/try=> `@dr`(yule `tarp`[31 12 30 0 ~])
1757+ ~d31.h12.m30
1758+
1759+------------------------------------------------------------------------
1760+
1761+### `++yall`
1762+
1763+ ++ yall :: day # to day of year
1764+ |= day=@ud
1765+ ^- [y=@ud m=@ud d=@ud]
1766+ =+ [era=0 cet=0 lep=_?]
1767+ => .(era (div day era:yo), day (mod day era:yo))
1768+ => ^+ .
1769+ ?: (lth day +(cet:yo))
1770+ .(lep &, cet 0)
1771+ => .(lep |, cet 1, day (sub day +(cet:yo)))
1772+ .(cet (add cet (div day cet:yo)), day (mod day cet:yo))
1773+ =+ yer=(add (mul 400 era) (mul 100 cet))
1774+ |- ^- [y=@ud m=@ud d=@ud]
1775+ =+ dis=?:(lep 366 365)
1776+ ?. (lth day dis)
1777+ =+ ner=+(yer)
1778+ $(yer ner, day (sub day dis), lep =(0 (end 0 2 ner)))
1779+ |- ^- [y=@ud m=@ud d=@ud]
1780+ =+ [mot=0 cah=?:(lep moy:yo moh:yo)]
1781+ |- ^- [y=@ud m=@ud d=@ud]
1782+ =+ zis=(snag mot cah)
1783+ ?: (lth day zis)
1784+ [yer +(mot) +(day)]
1785+ $(mot +(mot), day (sub day zis))
1786+
1787+Produce the date tuple of `[y=@ud m=@ud d=@ud]` of the year, month, and
1788+day from a number of days from the beginning of time.
1789+
1790+`day` is an unsigned decimal, `@ud`.
1791+
1792+ ~zod/try=> (yall 198)
1793+ [y=0 m=7 d=17]
1794+ ~zod/try=> (yall 90.398)
1795+ [y=247 m=7 d=3]
1796+ ~zod/try=> (yall 0)
1797+ [y=0 m=1 d=1]
1798+
1799+------------------------------------------------------------------------
1800+
1801+### `++yawn`
1802+
1803+ ++ yawn :: days since Jesus
1804+ |= [yer=@ud mot=@ud day=@ud]
1805+ ^- @ud
1806+ => .(mot (dec mot), day (dec day))
1807+ => ^+ .
1808+ %= .
1809+ day
1810+ =+ cah=?:((yelp yer) moy:yo moh:yo)
1811+ |- ^- @ud
1812+ ?: =(0 mot)
1813+ day
1814+ $(mot (dec mot), cah (slag 1 cah), day (add day (snag 0 cah)))
1815+ ==
1816+ |- ^- @ud
1817+ ?. =(0 (mod yer 4))
1818+ =+ ney=(dec yer)
1819+ $(yer ney, day (add day ?:((yelp ney) 366 365)))
1820+ ?. =(0 (mod yer 100))
1821+ =+ nef=(sub yer 4)
1822+ $(yer nef, day (add day ?:((yelp nef) 1.461 1.460)))
1823+ ?. =(0 (mod yer 400))
1824+ =+ nec=(sub yer 100)
1825+ $(yer nec, day (add day ?:((yelp nec) 36.525 36.524)))
1826+ (add day (mul (div yer 400) (add 1 (mul 4 36.524))))
1827+
1828+Inverse of `yall`, computes number of days A.D. from y/m/d date as the
1829+tuple `[yer=@ud mot=@ud day=@ud]`.
1830+
1831+`yer` is an unsigned decimal, `@ud`.
1832+
1833+`mon` is an unsigned decimal, `@ud`.
1834+
1835+`day` is an unsigned decimal, `@ud`.
1836+
1837+ ~zod/try=> (yawn 2.014 8 4)
1838+ 735.814
1839+ ~zod/try=> (yawn 1.776 7 4)
1840+ 648.856
1841+ ~zod/try=> (yawn 1.990 10 11)
1842+ 727.116
1843+
1844+------------------------------------------------------------------------
1845+
1846+### `++yelp`
1847+
1848+ ++ yelp :: leap year
1849+ |= yer=@ud ^- ?
1850+ &(=(0 (mod yer 4)) |(!=(0 (mod yer 100)) =(0 (mod yer 400))))
1851+
1852+Determines whether a year contains an ISO 8601 leap week. Produces a
1853+loobean.
1854+
1855+`yer` is an unsigned decimal, `@ud`.
1856+
1857+ ~zod/try=> (yelp 2.014)
1858+ %.n
1859+ ~zod/try=> (yelp 2.008)
1860+ %.y
1861+ ~zod/try=> (yelp 0)
1862+ %.y
1863+ ~zod/try=> (yelp 14.011)
1864+ %.n
1865+
1866+------------------------------------------------------------------------
1867+
1868+### `++yo`
1869+
1870+ ++ yo :: time constants
1871+
1872+
1873+Useful constants for interacting with earth time.
1874+
1875+### `++cet`
1876+
1877+ |% ++ cet 36.524 :: (add 24 (mul 100 365))
1878+
1879+Days in a century. Derived by multiplying the number of days in a year
1880+(365) by the number of years in a century (100), then adding the number
1881+days from leap years in a century (24).
1882+
1883+ ~zod/try=> cet:yo
1884+ 36.524
1885+ ~zod/try=> (add 365 cet:yo)
1886+ 36.889
1887+ ~zod/try=> (sub (add 24 (mul 100 365)) cet:yo)
1888+ 0
1889+
1890+------------------------------------------------------------------------
1891+
1892+### `++day`
1893+
1894+ ++ day 86.400 :: (mul 24 hor)
1895+
1896+Number of seconds in a day.
1897+
1898+ ~zod/try=> day:yo
1899+ 86.400
1900+ ~zod/try=> (add 60 day:yo)
1901+ 86.460
1902+
1903+------------------------------------------------------------------------
1904+
1905+### `++era`
1906+
1907+ ++ era 146.097 :: (add 1 (mul 4 cet))
1908+
1909+XX Revisit
1910+
1911+------------------------------------------------------------------------
1912+
1913+### `++hor`
1914+
1915+ ++ hor 3.600 :: (mul 60 mit)
1916+
1917+The number of seconds in an hour. Derived by multiplying the number of
1918+seconds in a minute by the minutes in an hour.
1919+
1920+ ~zod/try=> hor:yo
1921+ 3.600
1922+ ~zod/try=> (div hor:yo 60)
1923+ 60
1924+
1925+------------------------------------------------------------------------
1926+
1927+### `++jes`
1928+
1929+ ++ jes 106.751.991.084.417 :: (mul 730.692.561 era)
1930+
1931+XX Revisit
1932+
1933+ ~zod/try=> jes:yo
1934+ 106.751.991.084.417
1935+
1936+------------------------------------------------------------------------
1937+
1938+### `++mit`
1939+
1940+ ++ mit 60
1941+
1942+The number of seconds in a minute.
1943+
1944+ ~zod/try=> mit:yo
1945+ 60
1946+
1947+------------------------------------------------------------------------
1948+
1949+### `++moh`
1950+
1951+ ++ moh `(list ,@ud)`[31 28 31 30 31 30 31 31 30 31 30 31 ~]
1952+
1953+The days in each month of the Gregorian common year. A list of unsigned
1954+decimal atoms (Either 28, 30, or 31) denoting the number of days in the
1955+month at the year at that index.
1956+
1957+ ~zod/try=> moh:yo
1958+ ~[31 28 31 30 31 30 31 31 30 31 30 31]
1959+ ~zod/try=> (snag 4 moh:yo)
1960+ 31
1961+
1962+------------------------------------------------------------------------
1963+
1964+### `++moy`
1965+
1966+ ++ moy `(list ,@ud)`[31 29 31 30 31 30 31 31 30 31 30 31 ~]
1967+
1968+The days in each month of the Gregorian leap-year. A list of unsigned
1969+decimal atoms (Either 29,30, or 31) denoting the number of days in the
1970+month at the leap-year at that index.
1971+
1972+ ~zod/try=> moy:yo
1973+ ~[31 29 31 30 31 30 31 31 30 31 30 31]
1974+ ~zod/try=> (snag 1 moy:yo)
1975+ 29
1976+
1977+------------------------------------------------------------------------
1978+
1979+### `++qad`
1980+
1981+ ++ qad 126.144.001 :: (add 1 (mul 4 yer))
1982+
1983+The number of seconds in four years. Derived by adding one second to the
1984+number of seconds in four years.
1985+
1986+ ~zod/try=> qad:yo
1987+ 126.144.001
1988+
1989+------------------------------------------------------------------------
1990+
1991+### `++yer`
1992+
1993+ ++ yer 31.536.000 :: (mul 365 day)
1994+
1995+The number of seconds in a year. Derived by multiplying the number of
1996+seconds in a day by 365.
1997+
1998+ ~zod/try=> yer:yo
1999+ 31.536.000
2000+
2001+------------------------------------------------------------------------
2002+
2003+section 2cI, almost macros
2004+--------------------------
2005+
2006+### `++cury`
2007+
2008+ ++ cury
2009+ |* [a=_|=(^ _*) b=*]
2010+ |* c=_+<+.a
2011+ (a b c)
2012+
2013+Curry a gate, binding the head of its sample
2014+
2015+`a` is a [gate]().
2016+
2017+`b` is a noun.
2018+
2019+ ~zod/try=> =mol (cury add 2)
2020+ ~zod/try=> (mol 4)
2021+ 6
2022+ ~zod/try=> (mol 7)
2023+ 9
2024+
2025+------------------------------------------------------------------------
2026+
2027+### `++curr`
2028+
2029+ ++ curr
2030+ |* [a=_|=(^ _*) c=*]
2031+ |* b=_+<+.a
2032+ (a b c)
2033+
2034+Right curry a gate, binding the tail of its sample
2035+
2036+`a` is a gate.
2037+
2038+`c` is a noun.
2039+
2040+ ~zod/try=> =tep (curr scan sym)
2041+ ~zod/try=> `@t`(tep "asd")
2042+ 'asd'
2043+ ~zod/try=> `@t`(tep "lek-om")
2044+ 'lek-om'
2045+
2046+------------------------------------------------------------------------
2047+
2048+### `++cork`
2049+
2050+ ++ cork |*([a=_,* b=gate] (corl b a)) :: compose forward
2051+
2052+Build `f` such that `(f x) .= (b (a x))`.
2053+
2054+`a` is a noun.
2055+
2056+`b` is a gate.
2057+
2058+ ~zod/try=> (:(cork dec dec dec) 20)
2059+ 17
2060+ ~zod/try=> =mal (mo (limo a/15 b/23 ~))
2061+ ~zod/try=> ((cork ~(got by mal) dec) %a)
2062+ 14
2063+ ~zod/try=> ((cork ~(got by mal) dec) %b)
2064+ 22
2065+
2066+------------------------------------------------------------------------
2067+
2068+### `++corl`
2069+
2070+ ++ corl :: compose backwards
2071+ |* [a=gate b=_,*]
2072+ |= c=_+<.b
2073+ (a (b c))
2074+
2075+Gate compose
2076+
2077+XX Revisit
2078+
2079+`a` is a gate.
2080+
2081+`b` is a noun.
2082+
2083+ ~zod/try=> ((corl (lift bex) (slat %ud)) '2')
2084+ [~ 4]
2085+
2086+------------------------------------------------------------------------
2087+
2088+### `++hard`
2089+
2090+ ++ hard
2091+ |* han=$+(* *)
2092+ |= fud=* ^- han
2093+ ~| %hard
2094+ =+ gol=(han fud)
2095+ ?>(=(gol fud) gol)
2096+
2097+Demands that a specific type be produced, crashing the program is it is
2098+not.
2099+
2100+ ~zod/try=> ((hard (list)) (limo [1 2 3 ~]))
2101+ ~[1 2 3]
2102+ ~zod/try=> ((hard ,@) (add 2 2))
2103+ 4
2104+ ~zod/try=> ((hard ,@t) (crip "Tape to cord, bro!"))
2105+ 'Tape to cord, bro'
2106+ ~zod/try=> ((hard tape) (crip "...Tape to cord, bro?..."))
2107+ ! hard
2108+ ! exit
2109+
2110+------------------------------------------------------------------------
2111+
2112+### `++soft`
2113+
2114+ ++ soft
2115+ |* han=$+(* *)
2116+ |= fud=* ^- (unit han)
2117+ =+ gol=(han fud)
2118+ ?.(=(gol fud) ~ [~ gol])
2119+
2120+Politely requests a specific type to be produced, producing null if it
2121+is not.
2122+
2123+ ~zod/try=> ((soft ,%4) (add 2 2))
2124+ [~ %4]
2125+ ~zod/try=> ((soft ,@) (add 2 2))
2126+ [~ 4]
2127+ ~zod/try=> ((soft ,%5) (add 2 2))
2128+ ~
2129+ ~zod/try=> ((soft ,@t) (crip "Tape to cord, Woohoo!"))
2130+ [~ 'Tape to cord, Woohoo!']
2131+ ~zod/try=> ((soft ,@t) (trip 'Cmon man... Tape to cord? Please?!'))
2132+ ~
2133+
2134+------------------------------------------------------------------------
docs/dev/hoon/library/2da.mdnew file+437
@@ -0,0 +1,437 @@
1+section 2dA, sets
2+=================
3+
4+### `++apt`
5+
6+Set verification
7+
8+ ++ apt :: set invariant
9+ |= a=(tree)
10+ ?~ a
11+ &
12+ ?& ?~(l.a & ?&((vor n.a n.l.a) (hor n.l.a n.a)))
13+ ?~(r.a & ?&((vor n.a n.r.a) (hor n.a n.r.a)))
14+ ==
15+ ::
16+
17+Produces a loobean indicating whether `a` is a set or not.
18+
19+`a` is a [tree]().
20+
21+ ~zod/try=> =b (sa `(list ,@t)`['john' 'bonita' 'daniel' 'madeleine' ~])
22+ ~zod/try=> (apt b)
23+ %.y
24+ ~zod/try=> =m (mo `(list ,[@t *])`[['a' 1] ['b' [2 3]] ['c' 4] ['d' 5] ~])
25+ ~zod/try=> m
26+ {[p='d' q=5] [p='a' q=1] [p='c' q=4] [p='b' q=[2 3]]}
27+ ~zod/try=> (apt m)
28+ %.y
29+
30+------------------------------------------------------------------------
31+
32+### `++in`
33+
34+Set operations
35+
36+ ++ in :: set engine
37+ ~/ %in
38+ |/ a=(set)
39+
40+Input arm.
41+
42+ ~zod/try=> ~(. in (sa "asd"))
43+ <13.evb [nlr(^$1{@tD $1}) <414.fvk 101.jzo 1.ypj %164>]>
44+
45+`a` is a [set]()
46+
47+### `+-all:in`
48+
49+Logical AND
50+
51+ +- all :: logical AND
52+ ~/ %all
53+ |* b=$+(* ?)
54+ |- ^- ?
55+ ?~ a
56+ &
57+ ?&((b n.a) $(a l.a) $(a r.a))
58+ ::
59+
60+Computes the logical AND on every element in `a` slammed with `b`,
61+producing a loobean.
62+
63+`a` is a [set]().
64+
65+`b` is a [wet gate]() that accepts a noun and produces a loobean.
66+
67+ ~zod/try=> =b (sa `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
68+ ~zod/try=> (~(all in b) |=(a=* ?@(+.a & |)))
69+ %.n
70+ ~zod/try=> =b (sa `(list ,@t)`['john' 'bonita' 'daniel' 'madeleine' ~])
71+ ~zod/try=> (~(all in b) |=(a=@t (gte a 100)))
72+ %.y
73+
74+------------------------------------------------------------------------
75+
76+### `+-any:in`
77+
78+Logical OR
79+
80+ +- any :: logical OR
81+ ~/ %any
82+ |* b=$+(* ?)
83+ |- ^- ?
84+ ?~ a
85+ |
86+ ?|((b n.a) $(a l.a) $(a r.a))
87+ ::
88+
89+Computes the logical OR on every element of `a` slammed with `b`.
90+
91+`a` is a [set]().
92+
93+`b` is a [gate]() that accepts a noun and produces a loobean.
94+
95+ ~zod/try=> =b (sa `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
96+ ~zod/try=> (~(any in b) |=(a=* ?@(+.a & |)))
97+ %.y
98+ ~zod/try=> =b (sa `(list ,@t)`['john' 'bonita' 'daniel' 'madeleine' ~])
99+ ~zod/try=> (~(any in b) |=(a=@t (lte a 100)))
100+ %.n
101+
102+------------------------------------------------------------------------
103+
104+### `+-del:in`
105+
106+Remove noun
107+
108+ +- del :: b without any a
109+ ~/ %del
110+ |* b=*
111+ |- ^+ a
112+ ?~ a
113+ ~
114+ ?. =(b n.a)
115+ ?: (hor b n.a)
116+ [n.a $(a l.a) r.a]
117+ [n.a l.a $(a r.a)]
118+ |- ^- ?(~ _a)
119+ ?~ l.a r.a
120+ ?~ r.a l.a
121+ ?: (vor n.l.a n.r.a)
122+ [n.l.a l.l.a $(l.a r.l.a)]
123+ [n.r.a $(r.a l.r.a) r.r.a]
124+ ::
125+
126+Removes `b` from the set `a`.
127+
128+`a` is a [set]().
129+
130+`b` is a [noun]().
131+
132+ ~zod/try=> =b (sa `(list ,@t)`['a' 'b' 'c' ~])
133+ ~zod/try=> (~(del in b) 'a')
134+ {'c' 'b'}
135+ ~zod/try=> =b (sa `(list ,@t)`['john' 'bonita' 'daniel' 'madeleine' ~])
136+ ~zod/try=> (~(del in b) 'john')
137+ {'bonita' 'madeleine' 'daniel'}
138+ ~zod/try=> (~(del in b) 'susan')
139+ {'bonita' 'madeleine' 'daniel' 'john'}
140+
141+------------------------------------------------------------------------
142+
143+### `+-dig:in`
144+
145+Axis a in b
146+
147+ +- dig :: axis of a in b
148+ |= b=*
149+ =+ c=1
150+ |- ^- (unit ,@)
151+ ?~ a ~
152+ ?: =(b n.a) [~ u=(peg c 2)]
153+ ?: (gor b n.a)
154+ $(a l.a, c (peg c 6))
155+ $(a r.a, c (peg c 7))
156+ ::
157+
158+Produce the axis of `b` within `a`.
159+
160+`a` is a [set]().
161+
162+`b` is a [noun]().
163+
164+ ~zod/try=> =a (sa `(list ,@)`[1 2 3 4 5 6 7 ~])
165+ ~zod/try=> a
166+ {5 4 7 6 1 3 2}
167+ ~zod/try=> -.a
168+ n=6
169+ ~zod/try=> (~(dig in a) 7)
170+ [~ 12]
171+ ~zod/try=> (~(dig in a) 2)
172+ [~ 14]
173+ ~zod/try=> (~(dig in a) 6)
174+ [~ 2]
175+
176+------------------------------------------------------------------------
177+
178+### `+-gas:in`
179+
180+Concatenate
181+
182+ +- gas :: concatenate
183+ ~/ %gas
184+ |= b=(list ,_?>(?=(^ a) n.a))
185+ |- ^+ a
186+ ?~ b
187+ a
188+ $(b t.b, a (put(+< a) i.b))
189+ ::
190+
191+Insert the elements of a list `b` into a set `a`.
192+
193+`a` is a [set]().
194+
195+`b` is a [list]().
196+
197+ ~zod/try=> b
198+ {'bonita' 'madeleine' 'rudolf' 'john'}
199+ ~zod/try=> (~(gas in b) `(list ,@t)`['14' 'things' 'number' '1.337' ~])
200+ {'1.337' '14' 'number' 'things' 'bonita' 'madeleine' 'rudolf' 'john'}
201+ ~zod/try=> (~(gas in s) `(list ,@t)`['1' '2' '3' ~])
202+ {'1' '3' '2' 'e' 'd' 'a' 'c' 'b'}
203+
204+------------------------------------------------------------------------
205+
206+### `+-has:in`
207+
208+b in a?
209+
210+ +- has :: b exists in a check
211+ ~/ %has
212+ |* b=*
213+ |- ^- ?
214+ ?~ a
215+ |
216+ ?: =(b n.a)
217+ &
218+ ?: (hor b n.a)
219+ $(a l.a)
220+ $(a r.a)
221+ ::
222+
223+Checks if `b` is an element of `a`, producing a loobean.
224+
225+`a` is a [set]().
226+
227+`b` is a [noun]().
228+
229+ ~zod/try=> =a (~(gas in `(set ,@t)`~) `(list ,@t)`[`a` `b` `c` ~])
230+ ~zod/try=> (~(has in a) `a`)
231+ %.y
232+ ~zod/try=> (~(has in a) 'z')
233+ %.n
234+
235+------------------------------------------------------------------------
236+
237+### `+-int:in`
238+
239+Intersection
240+
241+ +- int :: intersection
242+ ~/ %int
243+ |* b=_a
244+ |- ^+ a
245+ ?~ b
246+ ~
247+ ?~ a
248+ ~
249+ ?. (vor n.a n.b)
250+ $(a b, b a)
251+ ?: =(n.b n.a)
252+ [n.a $(a l.a, b l.b) $(a r.a, b r.b)]
253+ ?: (hor n.b n.a)
254+ %- uni(+< $(a l.a, b [n.b l.b ~])) $(b r.b)
255+ %- uni(+< $(a r.a, b [n.b ~ r.b])) $(b l.b)
256+
257+Produces a set of the intersection between two sets of the same type,
258+`a` and `b`.
259+
260+`a` is a [set]().
261+
262+`b` is a [set]().
263+
264+ ~zod/try=> (~(int in (sa "ac")) (sa "ha"))
265+ {~~a}
266+ ~zod/try=> (~(int in (sa "acmo")) ~)
267+ {}
268+ ~zod/try=> (~(int in (sa "acmo")) (sa "ham"))
269+ {~~a ~~m}
270+ ~zod/try=> (~(int in (sa "acmo")) (sa "lep"))
271+ {}
272+
273+------------------------------------------------------------------------
274+
275+### `+-put:in`
276+
277+Put b in a
278+
279+ +- put :: puts b in a
280+ ~/ %put
281+ |* b=*
282+ |- ^+ a
283+ ?~ a
284+ [b ~ ~]
285+ ?: =(b n.a)
286+ a
287+ ?: (hor b n.a)
288+ =+ c=$(a l.a)
289+ ?> ?=(^ c)
290+ ?: (vor n.a n.c)
291+ [n.a c r.a]
292+ [n.c l.c [n.a r.c r.a]]
293+ =+ c=$(a r.a)
294+ ?> ?=(^ c)
295+ ?: (vor n.a n.c)
296+ [n.a l.a c]
297+ [n.c [n.a l.a l.c] r.c]
298+ ::
299+
300+Add an element `b` to the set `a`.
301+
302+`a` is a [set]().
303+
304+`b` is a [noun]().
305+
306+ ~zod/try=> =a (~(gas in `(set ,@t)`~) `(list ,@t)`[`a` `b` `c` ~])
307+ ~zod/try=> =b (~(put in a) `d`)
308+ ~zod/try=> b
309+ {`d` `a` `c` `b`}
310+ ~zod/try=> -.l.+.b
311+ n=`d`
312+
313+------------------------------------------------------------------------
314+
315+### `+-rep:in`
316+
317+Accumulate
318+
319+ +- rep :: replace by tile
320+ |* [b=* c=_,*]
321+ |-
322+ ?~ a b
323+ $(a r.a, b $(a l.a, b (c n.a b)))
324+ ::
325+
326+Accumulate the elements of `a` using a gate `c` and an accumulator `b`.
327+
328+`a` is a [set]().
329+
330+`b` is a [noun]() that accepts a noun and produces a loobean.
331+
332+`c` is a [gate]().
333+
334+ ~zod/try=> =a (~(gas in *(set ,@)) [1 2 3 ~])
335+ ~zod/try=> a
336+ {1 3 2}
337+ ~zod/try=> (~(rep in a) 0 |=([a=@ b=@] (add a b)))
338+ 6
339+
340+------------------------------------------------------------------------
341+
342+### `+-tap:in`
343+
344+Set to list
345+
346+ +- tap :: list tiles a set
347+ ~/ %tap
348+ |= b=(list ,_?>(?=(^ a) n.a))
349+ ^+ b
350+ ?~ a
351+ b
352+ $(a r.a, b [n.a $(a l.a)])
353+ ::
354+
355+Flatten the set `a` into a list.
356+
357+`a` is an [set]().
358+
359+`a` is a [set]().
360+
361+`b` is a [list]().
362+
363+ ~zod/try=> =s (sa `(list ,@t)`['a' 'b' 'c' 'd' 'e' ~])
364+ ~zod/try=> s
365+ {'e' 'd' 'a' 'c' 'b'}
366+ ~zod/try=> (~(tap in s) `(list ,@t)`['1' '2' '3' ~])
367+ ~['b' 'c' 'a' 'd' 'e' '1' '2' '3']
368+ ~zod/try=> b
369+ {'bonita' 'madeleine' 'daniel' 'john'}
370+ ~zod/try=> (~(tap in b) `(list ,@t)`['david' 'people' ~])
371+ ~['john' 'daniel' 'madeleine' 'bonita' 'david' 'people']
372+
373+------------------------------------------------------------------------
374+
375+### `+-uni:in`
376+
377+Union
378+
379+ +- uni :: union
380+ ~/ %uni
381+ |* b=_a
382+ |- ^+ a
383+ ?~ b
384+ a
385+ ?~ a
386+ b
387+ ?: (vor n.a n.b)
388+ ?: =(n.b n.a)
389+ [n.b $(a l.a, b l.b) $(a r.a, b r.b)]
390+ ?: (hor n.b n.a)
391+ $(a [n.a $(a l.a, b [n.b l.b ~]) r.a], b r.b)
392+ $(a [n.a l.a $(a r.a, b [n.b ~ r.b])], b l.b)
393+ ?: =(n.a n.b)
394+ [n.b $(b l.b, a l.a) $(b r.b, a r.a)]
395+ ?: (hor n.a n.b)
396+ $(b [n.b $(b l.b, a [n.a l.a ~]) r.b], a r.a)
397+ $(b [n.b l.b $(b r.b, a [n.a ~ r.a])], a l.a)
398+
399+Produces a set of the union between two sets of the same type, `a` and
400+`b`.
401+
402+`a` is a [set]().
403+
404+`b` is a [set]().
405+
406+ ~zod/try=> (~(uni in (sa "ac")) (sa "ha"))
407+ {~~a ~~c ~~h}
408+ ~zod/try=> (~(uni in (sa "acmo")) ~)
409+ {~~a ~~c ~~m ~~o}
410+ ~zod/try=> (~(uni in (sa "acmo")) (sa "ham"))
411+ {~~a ~~c ~~m ~~o ~~h}
412+ ~zod/try=> (~(uni in (sa "acmo")) (sa "lep"))
413+ {~~e ~~a ~~c ~~m ~~l ~~o ~~p}
414+
415+------------------------------------------------------------------------
416+
417+### `+-wyt:in`
418+
419+Set size
420+
421+ +- wyt :: size of set
422+ |- ^- @
423+ ?~(a 0 +((add $(a l.a) $(a r.a))))
424+
425+Produce the number of elements in set `a` as an atom.
426+
427+`a` is an [set]().
428+
429+ ~zod/try=> =a (~(put in (~(put in (sa)) 'a')) 'b')
430+ ~zod/try=> ~(wyt in a)
431+ 2
432+ ~zod/try=> b
433+ {'bonita' 'madeleine' 'daniel' 'john'}
434+ ~zod/try=> ~(wyt in b)
435+ 4
436+
437+------------------------------------------------------------------------
docs/dev/hoon/library/2db.mdnew file+813
@@ -0,0 +1,813 @@
1+section 2dB, maps
2+=================
3+
4+### `++ept`
5+
6+Map invariant.
7+
8+ ++ ept :: map invariant
9+ |= a=(tree ,[p=* q=*])
10+ ?~ a
11+ &
12+ ?& ?~(l.a & ?&((vor p.n.a p.n.l.a) (hor p.n.l.a p.n.a)))
13+ ?~(r.a & ?&((vor p.n.a p.n.r.a) (hor p.n.a p.n.r.a)))
14+ ==
15+
16+Computes whether `a` is a [map](), producing a loobean.
17+
18+`a` is a [tree]().
19+
20+ ~zod/try=> m
21+ {[p='d' q=5] [p='a' q=1] [p='c' q=4] [p='b' q=[2 3]]}
22+ ~zod/try=> (ept m)
23+ %.y
24+ ~zod/try=> b
25+ {'bonita' 'madeleine' 'daniel' 'john'}
26+ ~zod/try=> (ept b)
27+ ! type-fail
28+ ! exit
29+
30+------------------------------------------------------------------------
31+
32+### `++ja`
33+
34+Jar engine
35+
36+ ++ ja :: jar engine
37+ |/ a=(jar)
38+
39+A container arm for `++jar` operation arms. A `++jar` is a `++map` of
40+`++list`s. The contained arms inherit the [sample]() jar.
41+
42+`a` is a [jar]().
43+
44+ ~zod/try=> ~(. ja (mo (limo a/"ho" b/"he" ~)))
45+ <2.dgz [nlr([p={%a %b} q=""]) <414.fvk 101.jzo 1.ypj %164>]>
46+
47+------------------------------------------------------------------------
48+
49+### `+-get:ja`
50+
51+Grab value by key
52+
53+ +- get :: grab value by key
54+ |* b=*
55+ =+ c=(~(get by a) b)
56+ ?~(c ~ u.c)
57+
58+Produces a list retrieved from jar `a` using the key `b`.
59+
60+`a` is a [`++jar`](/doc/hoon/library/1#++jar).
61+
62+`b` is a key of the same type as the keys in `a`.
63+
64+ ~zod/try=> =l (mo `(list ,[@t (list ,@)])`[['a' `(list ,@)`[1 2 3 ~]] ['b' `(list ,@)`[4 5 6 ~]] ~])
65+ ~zod/try=> l
66+ {[p='a' q=~[1 2 3]] [p='b' q=~[4 5 6]]}
67+ ~zod/try=> (~(get ja l) 'a')
68+ ~[1 2 3]
69+ ~zod/try=> (~(get ja l) 'b')
70+ ~[4 5 6]
71+ ~zod/try=> (~(get ja l) 'c')
72+ ~
73+
74+------------------------------------------------------------------------
75+
76+### `+-add:ja`
77+
78+Prepend to list
79+
80+ +- add :: adds key-list pair
81+ |* [b=* c=*]
82+ =+ d=(get(+< a) b)
83+ (~(put by a) b [c d])
84+
85+Produces jar `a` with value `c` prepended to the list located at key
86+`b`.
87+
88+`a` is a [jar]().
89+
90+`b` is a key of the same type as the keys in `a`.
91+
92+`c` is a value of the same type as the values in `a`.
93+
94+ ~zod/try=> =l (mo `(list ,[@t (list ,@)])`[['a' `(list ,@)`[1 2 3 ~]] ['b' `(list ,@)`[4 5 6 ~]] ~])
95+ ~zod/try=> l
96+ {[p='a' q=~[1 2 3]] [p='b' q=~[4 5 6]]}
97+ ~zod/try=> (~(add ja l) 'b' 7)
98+ {[p='a' q=~[1 2 3]] [p='b' q=~[7 4 5 6]]}
99+ ~zod/try=> (~(add ja l) 'a' 100)
100+ {[p='a' q=~[100 1 2 3]] [p='b' q=~[4 5 6]]}
101+ ~zod/try=> (~(add ja l) 'c' 7)
102+ {[p='a' q=~[1 2 3]] [p='c' q=~[7]] [p='b' q=~[4 5 6]]}
103+ ~zod/try=> (~(add ja l) 'c' `(list ,@)`[7 8 9 ~])
104+ ! type-fail
105+ ! exit
106+
107+------------------------------------------------------------------------
108+
109+### `++ju`
110+
111+Jug operations
112+
113+ ++ ju :: jug engine
114+ |/ a=(jug)
115+
116+Container arm for jug operation arms. A `++jug` is a `++map` of
117+`++sets`. The contained arms inherit its [sample]() jug, `a`.
118+
119+`a` is a [jug]().
120+
121+ ~zod/try=> ~(. ju (mo (limo a/(sa "ho") b/(sa "he") ~)))
122+ <2.dgz [nlr([p={%a %b} q={nlr(^$1{@tD $1}) nlr(^$3{@tD $3})}]) <414.fvk 101.jzo 1.ypj %164>]>
123+
124+### `+-del:ju`
125+
126+Remove
127+
128+ +- del :: delete at key b
129+ |* [b=* c=*]
130+ ^+ a
131+ =+ d=(get(+< a) b)
132+ =+ e=(~(del in d) c)
133+ ?~ e
134+ (~(del by a) b)
135+ (~(put by a) b e)
136+
137+Produces jug `a` with value `c` removed from set located at key `b`.
138+
139+`a` is a [jug]().
140+
141+`b` is a key of the same type as the keys in `a`.
142+
143+`c` is the value of the same type of the keys in `a` that is to be
144+removed.
145+
146+ ~zod/try=> s
147+ {[p='a' q={1 3 2}] [p='b' q={5 4 6}]}
148+ ~zod/try=> (~(del ju s) 'a' 1)
149+ {[p='a' q={3 2}] [p='b' q={5 4 6}]}
150+ ~zod/try=> (~(del ju s) 'c' 7)
151+ {[p='a' q={1 3 2}] [p='b' q={5 4 6}]}
152+
153+------------------------------------------------------------------------
154+
155+### `+-get:ju`
156+
157+Retrieve set
158+
159+ +- get :: gets set by key
160+ |* b=*
161+ =+ c=(~(get by a) b)
162+ ?~(c ~ u.c)
163+
164+Produces a set retrieved from jar `a` using key `b`.
165+
166+`a` is a [jar]().
167+
168+`b` is a key of the same type as the keys in `a`.
169+
170+ ~zod/try=> s
171+ {[p='a' q={1 3 2}] [p='b' q={5 4 6}]}
172+ ~zod/try=> (~(get ju s) 'a')
173+ {1 3 2}
174+ ~zod/try=> (~(get ju s) 'b')
175+ {5 4 6}
176+ ~zod/try=> (~(get ju s) 'c')
177+ ~
178+
179+------------------------------------------------------------------------
180+
181+### `+-has:ju`
182+
183+Check contents
184+
185+ +- has :: existence check
186+ |* [b=* c=*]
187+ ^- ?
188+ (~(has in (get(+< a) b)) c)
189+
190+Computes whether a value `c` exists within the set located at key `b`
191+with jar `a`. Produces a loobean.
192+
193+`a` is a [set]().
194+
195+`b` is a key as a [noun]().
196+
197+`c` is a value as a [noun]().
198+
199+ ~zod/try=> s
200+ {[p='a' q={1 3 2}] [p='b' q={5 4 6}]}
201+ ~zod/try=> (~(has ju s) 'a' 3)
202+ %.y
203+ ~zod/try=> (~(has ju s) 'b' 6)
204+ %.y
205+ ~zod/try=> (~(has ju s) 'a' 7)
206+ %.n
207+ ~zod/try=> (~(has jus s) 'c' 7)
208+ ! -find-limb.jus
209+ ! find-none
210+ ! exit
211+ ~zod/try=> (~(has ju s) 'c' 7)
212+ %.n
213+
214+------------------------------------------------------------------------
215+
216+### `+-put:ju`
217+
218+Add key-set pair
219+
220+ +- put :: adds key-element pair
221+ |* [b=* c=*]
222+ ^+ a
223+ =+ d=(get(+< a) b)
224+ (~(put by a) b (~(put in d) c))
225+
226+Produces jar `a` with `c` added to the set value located at key `b`.
227+
228+`a` is a [set]().
229+
230+`b` is a key as a [noun]().
231+
232+`c` is a [value]().
233+
234+ ~zod/try=> s
235+ {[p='a' q={1 3 2}] [p='b' q={5 4 6}]}
236+ ~zod/try=> (~(put ju s) 'a' 7)
237+ {[p='a' q={7 1 3 2}] [p='b' q={5 4 6}]}
238+ ~zod/try=> (~(put ju s) 'a' 1)
239+ {[p='a' q={1 3 2}] [p='b' q={5 4 6}]}
240+ ~zod/try=> (~(put ju s) 'c' 7)
241+ {[p='a' q={1 3 2}] [p='c' q={7}] [p='b' q={5 4 6}]}
242+
243+------------------------------------------------------------------------
244+
245+### `++by`
246+
247+Map operations
248+
249+ ++ by :: map engine
250+ ~/ %by
251+ |/ a=(map)
252+
253+Container arm for map operation arms. A map is a set of key, value
254+pairs. The contained arms inherit it's [sample]() [map](), `a`.
255+
256+`a` is a [map]().
257+
258+ ~zod/try=> ~(. by (mo (limo [%a 1] [%b 2] ~)))
259+ <19.irb [nlr([p={%a %b} q=@ud]) <414.rvm 101.jzo 1.ypj %164>]>
260+
261+------------------------------------------------------------------------
262+
263+### `+-all:by`
264+
265+Logical AND
266+
267+ +- all :: logical AND
268+ ~/ %all
269+ |* b=$+(* ?)
270+ |- ^- ?
271+ ?~ a
272+ &
273+ ?&((b q.n.a) $(a l.a) $(a r.a))
274+
275+Computes the logical AND on the results of slamming every element in map
276+`a` with gate `b`. Produces a loobean.
277+
278+`a` is a [map]().
279+
280+`b` is a [wet gate]().
281+
282+ ~zod/try=> =b (mo `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
283+ ~zod/try=> (~(all by b) |=(a=* ?@(a & |)))
284+ %.n
285+ ~zod/try=> =a (mo `(list ,[@t @u])`[['a' 1] ['b' 2] ['c' 3] ['d' 4] ['e' 5] ~])
286+ ~zod/try=> (~(all by a) |=(a=@ (lte a 6)))
287+ %.y
288+ ~zod/try=> (~(all by a) |=(a=@ (lte a 4)))
289+ %.n
290+
291+------------------------------------------------------------------------
292+
293+### `+-any:by`
294+
295+Logical OR
296+
297+ +- any :: logical OR
298+ ~/ %any
299+ |* b=$+(* ?)
300+ |- ^- ?
301+ ?~ a
302+ |
303+ ?|((b q.n.a) $(a l.a) $(a r.a))
304+
305+Computes the logical OR on the results of slamming every element with
306+gate `b`. Produces a loobean.
307+
308+`a` is a [map]().
309+
310+`b` is a [wet gate]().
311+
312+ ~zod/try=> =b (mo `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
313+ ~zod/try=> (~(all by b) |=(a=* ?@(a & |)))
314+ %.y
315+ ~zod/try=> =a (mo `(list ,[@t @u])`[['a' 1] ['b' 2] ['c' 3] ['d' 4] ['e' 5] ~])
316+ ~zod/try=> (~(any by a) |=(a=@ (lte a 4)))
317+ %.y
318+
319+------------------------------------------------------------------------
320+
321+### `+-del:by`
322+
323+Delete
324+
325+ +- del :: delete at key b
326+ ~/ %del
327+ |* b=*
328+ |- ^+ a
329+ ?~ a
330+ ~
331+ ?. =(b p.n.a)
332+ ?: (gor b p.n.a)
333+ [n.a $(a l.a) r.a]
334+ [n.a l.a $(a r.a)]
335+ |- ^- ?(~ _a)
336+ ?~ l.a r.a
337+ ?~ r.a l.a
338+ ?: (vor p.n.l.a p.n.r.a)
339+ [n.l.a l.l.a $(l.a r.l.a)]
340+ [n.r.a $(r.a l.r.a) r.r.a]
341+
342+Produces map `a` with the element located at key `b` removed.
343+
344+`a` is a [map]().
345+
346+`b` is a key as a [noun]().
347+
348+ ~zod/try=> =b (mo `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
349+ ~zod/try=> (~(del by b) `a`)
350+ {[p=`b` q=[2 3]]}
351+
352+------------------------------------------------------------------------
353+
354+### `+-dig:by`
355+
356+Axis of key
357+
358+ +- dig :: axis of key
359+ |= b=*
360+ =+ c=1
361+ |- ^- (unit ,@)
362+ ?~ a ~
363+ ?: =(b p.n.a) [~ u=(peg c 2)]
364+ ?: (gor b p.n.a)
365+ $(a l.a, c (peg c 6))
366+ $(a r.a, c (peg c 7))
367+
368+Produce the axis of key `b` within map `a`.
369+
370+`a` is a [map]().
371+
372+`b` is a key as a [noun]().
373+
374+ ~zod/try=> =b (mo `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
375+ ~zod/try=> (~(dig by b) `b`)
376+ [~ 2]
377+
378+------------------------------------------------------------------------
379+
380+### `+-gas:by`
381+
382+Concatenate
383+
384+ +- gas :: concatenate
385+ ~/ %gas
386+ |* b=(list ,[p=* q=*])
387+ => .(b `(list ,_?>(?=(^ a) n.a))`b)
388+ |- ^+ a
389+ ?~ b
390+ a
391+ $(b t.b, a (put(+< a) p.i.b q.i.b))
392+
393+Insert a list of key-value pairs `b` into map `a`.
394+
395+`a` is a [map]().
396+
397+`b` is a [list]() of [cells]() of key-value nouns `p` and `q`.
398+
399+ ~zod/try=> =a (mo `(list ,[@t *])`[[`a` 1] [`b` 2] ~])
400+ ~zod/try=> =b `(list ,[@t *])`[[`c` 3] [`d` 4] ~]
401+ ~zod/try=> (~(gas by a) b)
402+ {[p=`d` q=4] [p=`a` q=1] [p=`c` q=3] [p=`b` q=2]}
403+
404+------------------------------------------------------------------------
405+
406+### `+-get:by`
407+
408+Grab unit value
409+
410+ +- get :: unit value by key
411+ ~/ %get
412+ |* b=*
413+ |- ^- ?(~ [~ u=_?>(?=(^ a) q.n.a)])
414+ ?~ a
415+ ~
416+ ?: =(b p.n.a)
417+ [~ u=q.n.a]
418+ ?: (gor b p.n.a)
419+ $(a l.a)
420+ $(a r.a)
421+
422+Produce the unit value of the value located at key `b` within map `a`.
423+
424+`a` is a [map]()
425+
426+`b` is a [key]() as a [noun]()
427+
428+ ~zod/try=> =b (mo `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
429+ ~zod/try=> (~(get by b) `b`)
430+ [~ [2 3]]
431+
432+------------------------------------------------------------------------
433+
434+### `+-got:by`
435+
436+Assert
437+
438+ +- got
439+ |* b=*
440+ %- need
441+ %- get(+< a) b
442+
443+Produce the value located at key `b` within map `a`. Crash if key `b`
444+does not exist.
445+
446+`a` is a [map]().
447+
448+`b` is a [key]().
449+
450+ ~zod/try=> =m (mo `(list ,[@t *])`[['a' 1] ['b' 2] ~])
451+ ~zod/try=> m
452+ {[p='a' q=1] [p='b' q=2]}
453+ ~zod/try=> (~(get by m) 'a')
454+ [~ 1]
455+ ~zod/try=> (~(got by m) 'a')
456+ 1
457+ ~zod/try=> (~(got by m) 'c')
458+ ! exit
459+
460+------------------------------------------------------------------------
461+
462+### `+-has:by`
463+
464+Key existence check
465+
466+ +- has :: key existence check
467+ ~/ %has
468+ |* b=*
469+ !=(~ (get(+< a) b))
470+
471+Checks whether map `a` contains an element with key `b`, producing a
472+loobean.
473+
474+`a` is a [map]().
475+
476+`b` is a key as a [noun]().
477+
478+ ~zod/try=> =b (mo `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
479+ ~zod/try=> (~(has by b) `b`)
480+ %.y
481+ ~zod/try=> (~(has by b) `c`)
482+ %.n
483+
484+------------------------------------------------------------------------
485+
486+### `+-int:by`
487+
488+Intersection
489+
490+ +- int :: intersection
491+ ~/ %int
492+ |* b=_a
493+ |- ^+ a
494+ ?~ b
495+ ~
496+ ?~ a
497+ ~
498+ ?: (vor p.n.a p.n.b)
499+ ?: =(p.n.b p.n.a)
500+ [n.b $(a l.a, b l.b) $(a r.a, b r.b)]
501+ ?: (hor p.n.b p.n.a)
502+ %- uni(+< $(a l.a, b [n.b l.b ~])) $(b r.b)
503+ %- uni(+< $(a r.a, b [n.b ~ r.b])) $(b l.b)
504+ ?: =(p.n.a p.n.b)
505+ [n.b $(b l.b, a l.a) $(b r.b, a r.a)]
506+ ?: (hor p.n.a p.n.b)
507+ %- uni(+< $(b l.b, a [n.a l.a ~])) $(a r.a)
508+ %- uni(+< $(b r.b, a [n.a ~ r.a])) $(a l.a)
509+
510+Produces a map of the (key) intersection between two maps of the same
511+type, `a` and `b`. If both maps have an identical key that point to
512+different values, the element from map `b` is used.
513+
514+`a` is a [map]().
515+
516+`b` is a [map]().
517+
518+ ~zod/try=> =n (mo `(list ,[@t *])`[['a' 1] ['c' 3] ~])
519+ ~zod/try=> n
520+ {[p='a' q=1] [p='c' q=3]}
521+ ~zod/try=> m
522+ {[p='a' q=1] [p='b' q=2]}
523+ ~zod/try=> (~(int by m) n)
524+ {[p='a' q=1]}
525+ ~ravpel-holber/try=> =p (mo `(list ,[@t *])`[['a' 2] ['b' 2] ~])
526+ ~zod/try=> p
527+ {[p='a' q=2] [p='b' q=2]}
528+ ~zod/try=> (~(int by p) n)
529+ {[p='a' q=2]}
530+ ~zod/try=> =q (mo `(list ,[@t *])`[['a' 2] ['c' 2] ~])
531+ ~zod/try=> q
532+ {[p='a' q=2] [p='b' q=2]}
533+ ~zod/try=> (~(int by p) q)
534+ {[p='a' q=2] [p='b' q=2]}
535+ ~zod/try=> =o (mo `(list ,[@t *])`[['c' 3] ['d' 4] ~])
536+ ~zod/try=> (~(int by m) o)
537+ {}
538+
539+
540+------------------------------------------------------------------------
541+
542+### `+-mar:by`
543+
544+Assert and Add
545+
546+ +- mar :: add with validation
547+ |* [b=_?>(?=(^ a) p.n.a) c=(unit ,_?>(?=(^ a) q.n.a))]
548+ ?~ c
549+ (del b)
550+ (put b u.c)
551+
552+Produces map `a` with the addition of a key-value pair, where the value
553+is a nonempty unit.
554+
555+Accept a noun and a unit of a noun of the type of the map's keys and
556+values, respectively. Validate that the value is not null and put the
557+pair in the map. If the value is null, delete the key.
558+
559+XX This arm is broken, asana task 15186618346453
560+
561+ ~zod/try=> m
562+ {[p='a' q=1] [p='b' q=2]}
563+ ~zod/try=> (~(mar by m) 'c' (some 3))
564+ ! -find-limb.n
565+ ! find-none
566+ ! exit
567+ ~zod/try=> (~(mar by m) 'c' ~)
568+ ! -find-limb.n
569+ ! find-none
570+ ! exit
571+ ~zod/try=> (~(mar by m) 'b' ~)
572+ ! -find-limb.n
573+ ! find-none
574+ ! exit
575+
576+------------------------------------------------------------------------
577+
578+### `+-put:by`
579+
580+Add key-value pair
581+
582+ +- put :: adds key-value pair
583+ ~/ %put
584+ |* [b=* c=*]
585+ |- ^+ a
586+ ?~ a
587+ [[b c] ~ ~]
588+ ?: =(b p.n.a)
589+ ?: =(c q.n.a)
590+ a
591+ [[b c] l.a r.a]
592+ ?: (gor b p.n.a)
593+ =+ d=$(a l.a)
594+ ?> ?=(^ d)
595+ ?: (vor p.n.a p.n.d)
596+ [n.a d r.a]
597+ [n.d l.d [n.a r.d r.a]]
598+ =+ d=$(a r.a)
599+ ?> ?=(^ d)
600+ ?: (vor p.n.a p.n.d)
601+ [n.a l.a d]
602+ [n.d [n.a l.a l.d] r.d]
603+
604+Produces `a` with the addition of the key-value pair of `b` and `c`.
605+
606+`a` is a [map]().
607+
608+`b` is a key of the same type as the keys in `a`.
609+
610+`c` is a value of the same type of the values in `a`.
611+
612+ ~zod/try=> m
613+ {[p='a' q=1] [p='b' q=2]}
614+ ~zod/try=> (~(put by m) 'c' 3)
615+ {[p='a' q=1] [p='c' q=3] [p='b' q=2]}
616+ ~zod/try=> (~(put by m) "zod" 26)
617+ ! type-fail
618+ ! exit
619+ ~zod/try=> (~(put by m) 'a' 2)
620+ {[p='a' q=2] [p='b' q=2]}
621+
622+------------------------------------------------------------------------
623+
624+### `+-rep:by`
625+
626+ +- rep :: replace by product
627+ |* [b=* c=_,*]
628+ |-
629+ ?~ a b
630+ $(a r.a, b $(a l.a, b (c q.n.a b)))
631+
632+Accumulate using gate from values in map
633+
634+XX interface changing.
635+
636+------------------------------------------------------------------------
637+
638+### `+-rib:by`
639+
640+ +- rib :: transform + product
641+ |* [b=* c=_,*]
642+ |- ^+ [b a]
643+ ?~ a [b ~]
644+ =+ d=(c n.a b)
645+ =. n.a +.d
646+ =+ e=$(a l.a, b -.d)
647+ =+ f=$(a r.a, b -.e)
648+ [-.f [n.a +.e +.f]]
649+
650+Replace values with accumulator
651+
652+XX interface changing, possibly disappearing
653+
654+------------------------------------------------------------------------
655+
656+### `+-run:by`
657+
658+Transform values
659+
660+ +- run :: turns to tuples
661+ |* b=_,*
662+ |-
663+ ?~ a a
664+ a(n (b q.n.a), l $(a l.a), r $(a r.a))
665+
666+Iterates over every value in set `a` using gate `b`. Produces a map.
667+
668+`a` is a [map]().
669+
670+`b` is a [wet gate]().
671+
672+ ~zod/try=> m
673+ {[p='a' q=1] [p='b' q=2]}
674+ ~zod/try=> ^+(m (~(run by m) dec))
675+ {[p='a' q=0] [p='b' q=1]}
676+ ~zod/try=> `(map ,@tas ,@t)`(~(run by m) (cury scot %ux))
677+ {[p=%a q='0x1'] [p=%b q='0x2']}
678+
679+------------------------------------------------------------------------
680+
681+### `+-tap:by`
682+
683+Listify pairs
684+
685+ +- tap :: listify pairs
686+ ~/ %tap
687+ |= b=(list ,_?>(?=(^ a) n.a))
688+ ^+ b
689+ ?~ a
690+ b
691+ $(a r.a, b [n.a $(a l.a)])
692+
693+Produces the list of all elements in map `a` that is prepended to list
694+`b`, which is empty by default.
695+
696+`a` is a [map]().
697+
698+`b` is a [list]().
699+
700+ {[p='a' q=1] [p='b' q=2]}
701+ ~zod/try=> `*`m
702+ [[98 2] [[97 1] 0 0] 0]
703+ ~zod/try=> (~(tap by m))
704+ ~[[p='b' q=2] [p='a' q=1]]
705+ ~zod/try=> `*`(~(tap by m))
706+ [[98 2] [97 1] 0]
707+
708+------------------------------------------------------------------------
709+
710+### `+-uni:by`
711+
712+Union
713+
714+ +- uni :: union, merge
715+ ~/ %uni
716+ |* b=_a
717+ |- ^+ a
718+ ?~ b
719+ a
720+ ?~ a
721+ b
722+ ?: (vor p.n.a p.n.b)
723+ ?: =(p.n.b p.n.a)
724+ [n.b $(a l.a, b l.b) $(a r.a, b r.b)]
725+ ?: (hor p.n.b p.n.a)
726+ $(a [n.a $(a l.a, b [n.b l.b ~]) r.a], b r.b)
727+ $(a [n.a l.a $(a r.a, b [n.b ~ r.b])], b l.b)
728+ ?: =(p.n.a p.n.b)
729+ [n.b $(b l.b, a l.a) $(b r.b, a r.a)]
730+ ?: (hor p.n.a p.n.b)
731+ $(b [n.b $(b l.b, a [n.a l.a ~]) r.b], a r.a)
732+ $(b [n.b l.b $(b r.b, a [n.a ~ r.a])], a l.a)
733+
734+Produces a map of the union between the keys of `a` and `b`. If `b`
735+shares a key with `a`, the tuple from `a` is preserved.
736+
737+`a` is a [map]().
738+
739+`b` is a [map]().
740+
741+ ~zod/try=> m
742+ {[p='a' q=1] [p='b' q=2]}
743+ ~zod/try=> o
744+ {[p='d' q=4] [p='c' q=3]}
745+ ~zod/try=> (~(uni by m) o)
746+ {[p='d' q=4] [p='a' q=1] [p='c' q=3] [p='b' q=2]}
747+ ~zod/try=> (~(uni by m) ~)
748+ {[p='a' q=1] [p='b' q=2]}
749+ ~zod/try=> n
750+ {[p='a' q=1] [p='c' q=9]}
751+ ~zod/try=> (~(uni by o) n)
752+ {[p='d' q=4] [p='a' q=1] [p='c' q=3]}
753+ ~zod/try=> =n (mo `(list ,[@t *])`[['a' 1] ['c' 9] ~])
754+ ~zod/try=> n
755+ {[p='a' q=1] [p='c' q=9]}
756+ ~zod/try=> (~(uni by o) n)
757+ {[p='d' q=4] [p='a' q=1] [p='c' q=9]}
758+
759+------------------------------------------------------------------------
760+
761+### `+-urn:by`
762+
763+Turn (with key)
764+
765+ +- urn :: turn
766+ |* b=$+([* *] *)
767+ |-
768+ ?~ a ~
769+ [n=[p=p.n.a q=(b p.n.a q.n.a)] l=$(a l.a) r=$(a r.a)]
770+
771+Iterates over every value in map `a` using gate `b`, which accepts both
772+the key and the value of each element as its sample.
773+
774+`a` is a [map]().
775+
776+`b` is a [wet gate]() that accepts two nouns (a key and a value) and
777+produces a noun (the new value).
778+
779+ ~zod/try=> m
780+ {[p='a' q=1] [p='b' q=2]}
781+ ~zod/try=> (~(urn by m) |=(a=[p=* q=*] q.a))
782+ {[p='a' q=1] [p='b' q=2]}
783+ ~zod/try=> (~(urn by m) |=(a=[p=* q=*] 7))
784+ {[p='a' q=7] [p='b' q=7]}
785+ ~zod/try=> (~(urn by m) |=(a=[p=* q=*] p.a))
786+ {[p='a' q=97] [p='b' q=98]}
787+
788+------------------------------------------------------------------------
789+
790+### `+-wyt:by`
791+
792+Depth
793+
794+ +- wyt :: depth of map
795+ |- ^- @
796+ ?~(a 0 +((add $(a l.a) $(a r.a))))
797+
798+Produce the depth of the tree map `a`.
799+
800+`a` is a [map]().
801+
802+ ~zod/try=> m
803+ {[p='a' q=1] [p='b' q=2]}
804+ ~zod/try=> o
805+ {[p='d' q=4] [p='c' q=3]}
806+ ~zod/try=> ~(wyt by m)
807+ 2
808+ ~zod/try=> ~(wyt by o)
809+ 2
810+ ~zod/try=> ~(wyt by (~(uni by m) o))
811+ 4
812+
813+------------------------------------------------------------------------
docs/dev/hoon/library/2dc.mdnew file+221
@@ -0,0 +1,221 @@
1+section 2dC, queues
2+===================
3+
4+### `++to`
5+
6+Queue engine
7+
8+ ++ to :: queue engine
9+ |/ a=(qeu)
10+
11+Container arm for queue operation arms. The contained arms inherit its
12+[sample]() `++qeu` `a`.
13+
14+`a` is a queue, [++qeu]().
15+
16+### `+-bal:to`
17+
18+Balance
19+
20+ +- bal
21+ |- ^+ a
22+ ?~ a ~
23+ ?. |(?=(~ l.a) (vor n.a n.l.a))
24+ $(a [n.l.a l.l.a $(a [n.a r.l.a r.a])])
25+ ?. |(?=(~ r.a) (vor n.a n.r.a))
26+ $(a [n.r.a $(a [n.a l.a l.r.a]) r.r.a])
27+ a
28+ ::
29+
30+Vertically rebalances queue `a`.
31+
32+`a` is a [queue]().
33+
34+ ~zod/try=> `(qeu tape)`["a" ~ "b" ~ "c" ~ "d" ~ "e" ~ "f" ~ "g" ~ ~]
35+ {"a" "b" "c" "d" "e" "f" "g"}
36+ ~zod/try=> `*`["a" ~ "b" ~ "c" ~ "d" ~ "e" ~ "f" ~ "g" ~ ~]
37+ [[97 0] 0 [98 0] 0 [99 0] 0 [100 0] 0 [101 0] 0 [102 0] 0 [103 0] 0 0]
38+ ~zod/try=> ~(bal to `(qeu tape)`["a" ~ "b" ~ "c" ~ "d" ~ "e" ~ "f" ~ "g" ~ ~])
39+ {"a" "b" "c" "d" "e" "f" "g"}
40+ ~zod/try=> `*`~(bal to `(qeu tape)`["a" ~ "b" ~ "c" ~ "d" ~ "e" ~ "f" ~ "g" ~ ~])
41+ [[100 0] [[99 0] [[98 0] [[97 0] 0 0] 0] 0] [101 0] 0 [102 0] 0 [103 0] 0 0]
42+
43+------------------------------------------------------------------------
44+
45+### `+-dep:to`
46+
47+Maximum Depth
48+
49+ +- dep :: max depth of queue
50+ |- ^- @
51+ ?~ a 0
52+ +((max $(a l.a) $(a r.a)))
53+ ::
54+
55+Produces the maximum depth of leaves (r.a and l.a) in queue `a`.
56+
57+`a` is a [queue]().
58+
59+ ~zod/try=> =a (~(gas to `(qeu ,@)`~) `(list ,@)`[1 2 3 4 5 6 7 ~])
60+ ~zod/try=> ~(dep to a)
61+ 4
62+ ~zod/try=> =a (~(gas to `(qeu ,@)`~) `(list ,@)`[1 2 3 4 ~])
63+ ~zod/try=> ~(dep to a)
64+ 3
65+ ~zod/try=> =a (~(gas to `(qeu ,@)`~) `(list ,@)`[1 2 ~])
66+ ~zod/try=> ~(dep to a)
67+ 2
68+ ~zod/try=> ~(dep to `(qeu tape)`["a" ~ "b" ~ "c" ~ "d" ~ "e" ~ "f" ~ "g" ~ ~])
69+ 7
70+ ~zod/try=> ~(dep to ~(bal to `(qeu tape)`["a" ~ "b" ~ "c" ~ "d" ~ "e" ~ "f" ~ "g" ~ ~]))
71+ 4
72+
73+------------------------------------------------------------------------
74+
75+### `+-gas`
76+
77+Push list
78+
79+ +- gas :: insert list to queue
80+ |= b=(list ,_?>(?=(^ a) n.a))
81+ |- ^+ a
82+ ?~(b a $(b t.b, a (put(+< a) i.b)))
83+ ::
84+
85+Push all elements of list `b` into the queue.
86+
87+`a` is a [queue]().
88+
89+`b` is a list.
90+
91+ ~zod/try=> (~(gas to `(qeu ,@)`~) `(list ,@)`[1 2 3 ~])
92+ {3 2 1}
93+ ~zod/try=> =a (~(gas to `(qeu ,@)`~) `(list ,@)`[1 2 3 ~])
94+ ~zod/try=> =b `(list ,@)`[4 5 6 ~]
95+ ~zod/try=> (~(gas to a) b)
96+ {6 5 4 3 2 1}
97+
98+------------------------------------------------------------------------
99+
100+### `+-get:to`
101+
102+Pop
103+
104+ +- get :: head-tail pair
105+ |- ^+ [p=?>(?=(^ a) n.a) q=a]
106+ ?~ a
107+ !!
108+ ?~ r.a
109+ [n.a l.a]
110+ =+ b=$(a r.a)
111+ :- p.b
112+ ?: |(?=(~ q.b) (vor n.a n.q.b))
113+ [n.a l.a q.b]
114+ [n.q.b [n.a l.a l.q.b] r.q.b]
115+ ::
116+
117+Produces the head and tail queue of `a`.
118+
119+`a` is a [queue]().
120+
121+ ~zod/try=> =s (~(gas to *(qeu ,@)) `(list ,@)`~[1 2 3])
122+ ~zod/try=> ~(get to s)
123+ [p=1 q={3 2}]
124+ ~zod/try=> ~(get to ~)
125+ ! exit
126+
127+------------------------------------------------------------------------
128+
129+### `+-nap:to`
130+
131+Remove last in
132+
133+ +- nap :: removes head
134+ ?> ?=(^ a)
135+ ?: =(~ l.a) r.a
136+ =+ b=get(+< l.a)
137+ bal(+< ^+(a [p.b q.b r.a]))
138+ ::
139+
140+Removes the head of queue `a`, producing the resulting queue.
141+
142+`a` is a [queue]().
143+
144+ ~zod/try=> =a (~(gas to `(qeu ,@)`~) `(list ,@)`[1 2 3 4 5 6 ~])
145+ ~zod/try=> -.a
146+ n=6
147+ ~zod/try=> =b ~(nap to a)
148+ ~zod/try=> -.b
149+ n=2
150+ ~zod/try=> b
151+ {5 4 3 2 1}
152+ ~zod/try=> a
153+ {6 5 4 3 2 1}
154+
155+------------------------------------------------------------------------
156+
157+### `+-put:to`
158+
159+Insert
160+
161+ +- put :: insert new tail
162+ |* b=*
163+ |- ^+ a
164+ ?~ a
165+ [b ~ ~]
166+ bal(+< a(l $(a l.a)))
167+ ::
168+
169+Accept any noun `b` and adds to queue `a` as the head, producing the
170+resulting queue.
171+
172+`a` is a [queue]().
173+
174+`b` is any noun.
175+
176+ ~zod/try=> (~(gas to `(qeu ,@)`~) `(list ,@)`[3 1 2 4 5 6 ~])
177+ ~zod/try=> (~(put to a) 7)
178+ {7 6 5 4 2 1 3}
179+
180+------------------------------------------------------------------------
181+
182+### `+-tap:to`
183+
184+Queue to list
185+
186+ +- tap :: queue to list
187+ |= b=(list ,_?>(?=(^ a) n.a))
188+ ^+ b
189+ ?~ a
190+ b
191+ $(a r.a, b [n.a $(a l.a)])
192+ ::
193+
194+Produces queue `a` as a list from front to back.
195+
196+`a` is a [queue]().
197+
198+ ~zod/try=> =a (~(gas to `(qeu ,@)`~) `(list ,@)`[3 1 2 4 5 6 ~])
199+ ~zod/try=> `*`a
200+ [6 0 2 [4 [5 0 0] 0] 1 0 3 0 0]
201+ ~zod/try=> (~(tap to a) `(list ,@)`[99 100 101 ~])
202+ ~[3 1 2 4 5 6 99 100 101]
203+
204+------------------------------------------------------------------------
205+
206+### `+-top:to`
207+
208+ +- top :: produces head
209+ |- ^- (unit ,_?>(?=(^ a) n.a))
210+ ?~ a ~
211+ ?~(r.a [~ n.a] $(a r.a))
212+
213+Produces the head of queue `a` as a unit (an empty queue has no head).
214+
215+`a` is a [queue]().
216+
217+ ~zod/try=> =a (~(gas to `(qeu ,@)`~) `(list ,@)`[1 2 3 4 5 6 ~])
218+ ~zod/try=> ~(top to a)
219+ [~ 1]
220+
221+------------------------------------------------------------------------
docs/dev/hoon/library/2dd.mdnew file+69
@@ -0,0 +1,69 @@
1+section 2dD, casual containers
2+==============================
3+
4+### `++mo`
5+
6+Map from list
7+
8+ ++ mo :: map from list
9+ |* a=(list)
10+ => .(a `_(homo a)`a)
11+ => .(a `(list ,[p=_-<.a q=_->.a])`a)
12+ =+ b=*(map ,_?>(?=(^ a) p.i.a) ,_?>(?=(^ a) q.i.a))
13+ (~(gas by b) a)
14+ ::
15+
16+Produces a map of key-value pairs from the left-right cell pairs of list
17+`a`.
18+
19+`a` is a [list]().
20+
21+ ~zod/try=> (mo `(list ,[@t *])`[[`a` 1] [`b` 2] ~])
22+ {[p=`a` q=1] [p=`b` q=2]}
23+
24+------------------------------------------------------------------------
25+
26+### `++sa`
27+
28+Set from list
29+
30+ ++ sa :: set from list
31+ |* a=(list)
32+ => .(a `_(homo a)`a)
33+ =+ b=*(set ,_?>(?=(^ a) i.a))
34+ (~(gas in b) a)
35+ ::
36+
37+Produces a set of the elements in list `a`.
38+
39+`a` is a [list]().
40+
41+ ~zod/try=> (sa `(list ,@)`[1 2 3 4 5 ~])
42+ {5 4 1 3 2}
43+ ~zod/try=> (sa `(list ,[@t *])`[[`a` 1] [`b` 2] ~])
44+ {[`a` 1] [`b` 2]}
45+
46+------------------------------------------------------------------------
47+
48+### `++qu`
49+
50+Queue from list
51+
52+ ++ qu :: queue from list
53+ |* a=(list)
54+ => .(a `_(homo a)`a)
55+ =+ b=*(qeu ,_?>(?=(^ a) i.a))
56+ (~(gas to b) a)
57+
58+Produces a queue from list `a`.
59+
60+`a` is a [list]().
61+
62+ ~zod/try=> (qu `(list ,@ud)`~[1 2 3 5])
63+ {5 3 2 1}
64+ ~zod/try=> (qu "sada")
65+ {'a' 'd' 'a' 's'}
66+ ~zod/try=> ~(top to (qu "sada"))
67+ [~ 's']
68+
69+------------------------------------------------------------------------
docs/dev/hoon/library/2ea.mdnew file+162
@@ -0,0 +1,162 @@
1+section 2eA, packing
2+====================
3+
4+### `++cue`
5+
6+Unpack atom to noun
7+
8+ ++ cue :: unpack atom to noun
9+ ~/ %cue
10+ |= a=@
11+ ^- *
12+ =+ b=0
13+ =+ m=`(map ,@ ,*)`~
14+ =< q
15+ |- ^- [p=@ q=* r=_m]
16+ ?: =(0 (cut 0 [b 1] a))
17+ =+ c=(rub +(b) a)
18+ [+(p.c) q.c (~(put by m) b q.c)]
19+ =+ c=(add 2 b)
20+ ?: =(0 (cut 0 [+(b) 1] a))
21+ =+ u=$(b c)
22+ =+ v=$(b (add p.u c), m r.u)
23+ =+ w=[q.u q.v]
24+ [(add 2 (add p.u p.v)) w (~(put by r.v) b w)]
25+ =+ d=(rub c a)
26+ [(add 2 p.d) (need (~(get by m) q.d)) m]
27+ ::
28+
29+Produces a noun unpacked from atom `a`. The inverse of jam.
30+
31+`a` is an [atom]().
32+
33+ ~zod/try=> (cue 12)
34+ 1
35+ ~zod/try=> (cue 817)
36+ [1 1]
37+ ~zod/try=> (cue 4.657)
38+ [1 2]
39+ ~zod/try=> (cue 39.689)
40+ [0 19]
41+
42+------------------------------------------------------------------------
43+
44+### `++jam`
45+
46+ ++ jam :: pack
47+ ~/ %jam
48+ |= a=*
49+ ^- @
50+ =+ b=0
51+ =+ m=`(map ,* ,@)`~
52+ =< q
53+ |- ^- [p=@ q=@ r=_m]
54+ =+ c=(~(get by m) a)
55+ ?~ c
56+ => .(m (~(put by m) a b))
57+ ?: ?=(@ a)
58+ =+ d=(mat a)
59+ [(add 1 p.d) (lsh 0 1 q.d) m]
60+ => .(b (add 2 b))
61+ =+ d=$(a -.a)
62+ =+ e=$(a +.a, b (add b p.d), m r.d)
63+ [(add 2 (add p.d p.e)) (mix 1 (lsh 0 2 (cat 0 q.d q.e))) r.e]
64+ ?: ?&(?=(@ a) (lte (met 0 a) (met 0 u.c)))
65+ =+ d=(mat a)
66+ [(add 1 p.d) (lsh 0 1 q.d) m]
67+ =+ d=(mat u.c)
68+ [(add 2 p.d) (mix 3 (lsh 0 2 q.d)) m]
69+ ::
70+
71+Produces an atom unpacked from noun `a`. The inverse of cue.
72+
73+`a` is a [noun]().
74+
75+ ~zod/try=> (jam 1)
76+ 12
77+ ~zod/try=> (jam [1 1])
78+ 817
79+ ~zod/try=> (jam [1 2])
80+ 4.657
81+ ~zod/try=> (jam [~ u=19])
82+ 39.689
83+
84+------------------------------------------------------------------------
85+
86+### `++mat`
87+
88+Length-encode
89+
90+ ++ mat :: length-encode
91+ ~/ %mat
92+ |= a=@
93+ ^- [p=@ q=@]
94+ ?: =(0 a)
95+ [1 1]
96+ =+ b=(met 0 a)
97+ =+ c=(met 0 b)
98+ :- (add (add c c) b)
99+ (cat 0 (bex c) (mix (end 0 (dec c) b) (lsh 0 (dec c) a)))
100+
101+Produces a cell whose tail `q` is atom `a` with a bit representation of
102+its length prepended to it (as the least significant bits). The head `p`
103+is the length of `q` in bits.
104+
105+`a` is an atom.
106+
107+ ~zod/try=> (mat 0xaaa)
108+ [p=20 q=699.024]
109+ ~zod/try=> (met 0 q:(mat 0xaaa))
110+ 20
111+ ~zod/try=> `@ub`q:(mat 0xaaa)
112+ 0b1010.1010.1010.1001.0000
113+ ~zod/try=> =a =-(~&(- -) `@ub`0xaaa)
114+ 0b1010.1010.1010
115+ ~zod/try=> =b =-(~&(- -) `@ub`(xeb a))
116+ 0b1100
117+ ~zod/try=> =b =-(~&(- -) `@ub`(met 0 a))
118+ 0b1100
119+ ~zod/try=> =c =-(~&(- -) (xeb b))
120+ 4
121+ ~zod/try=> [`@ub`a `@ub`(end 0 (dec c) b) `@ub`(bex c)]
122+ [0b1010.1010.1010 0b100 0b1.0000]
123+
124+------------------------------------------------------------------------
125+
126+### `++rub`
127+
128+Length-decode
129+
130+ ++ rub :: length-decode
131+ ~/ %rub
132+ |= [a=@ b=@]
133+ ^- [p=@ q=@]
134+ =+ ^= c
135+ =+ [c=0 m=(met 0 b)]
136+ |- ?< (gth c m)
137+ ?. =(0 (cut 0 [(add a c) 1] b))
138+ c
139+ $(c +(c))
140+ ?: =(0 c)
141+ [1 0]
142+ =+ d=(add a +(c))
143+ =+ e=(add (bex (dec c)) (cut 0 [d (dec c)] b))
144+ [(add (add c c) e) (cut 0 [(add d (dec c)) e] b)]
145+
146+The inverse of `++mat`. Accepts a cell of index `a` and a bitstring `b`
147+and produces the cell whose tail `q` is the decoded atom at index `a`
148+and whose head is the length of the encoded atom `q`, by which the
149+offset `a` is advanced. Only used internally as a helper cue.
150+
151+`a` is an atom.
152+
153+`b` is a bitstring as an atom.
154+
155+ ~zod/try=> `@ub`(jam 0xaaa)
156+ 0b1.0101.0101.0101.0010.0000
157+ ~zod/try=> (rub 1 0b1.0101.0101.0101.0010.0000)
158+ [p=20 q=2.730]
159+ ~zod/try=> `@ux`q:(rub 1 0b1.0101.0101.0101.0010.0000)
160+ 0xaaa
161+
162+------------------------------------------------------------------------
docs/dev/hoon/library/2eb.mdnew file+63
@@ -0,0 +1,63 @@
1+section 2eB, parsing (tracing)
2+==============================
3+
4+### `++last`
5+
6+Farther trace
7+
8+ ++ last |= [zyc=hair naz=hair] :: farther trace
9+ ^- hair
10+ ?: =(p.zyc p.naz)
11+ ?:((gth q.zyc q.naz) zyc naz)
12+ ?:((gth p.zyc p.naz) zyc naz)
13+ ::
14+
15+Compares two line-column pairs, `zyc` and `naz`, and produces whichever
16+[hair]() is farther along.
17+
18+`zyc` is a [hair]().
19+
20+`naz` is a [hair]().
21+
22+ ~zod/try=> (last [1 1] [1 2])
23+ [p=1 q=2]
24+ ~zod/try=> (last [2 1] [1 2])
25+ [p=2 q=1]
26+ ~zod/try=> (last [0 0] [99 0])
27+ [p=99 q=0]
28+ ~zod/try=> (last [7 7] [7 7])
29+ [p=7 q=7]
30+
31+------------------------------------------------------------------------
32+
33+### `++lust`
34+
35+Detect newline
36+
37+ ++ lust |= [weq=char naz=hair] :: detect newline
38+ ^- hair
39+ ?:(=(10 weq) [+(p.naz) 1] [p.naz +(q.naz)])
40+
41+Advances the hair `naz` by a row if the char `weq` is a newline, or by a
42+column if `weq` is any other character.
43+
44+`weq` is a [char]().
45+
46+`naz` is a [hair]().
47+
48+ ~zod/try=> (lust `a` [1 1])
49+ [p=1 q=2]
50+ ~zod/try=> (lust `@t`10 [1 1])
51+ [p=2 q=1]
52+ ~zod/try=> (lust '9' [10 10])
53+ [p=10 q=11]
54+ /~zod/try=> (roll "maze" [.(+<+ [1 1])]:lust)
55+ [1 5]
56+ /~zod/try=> %- roll :_ [.(+<+ [1 1])]:lust
57+ """
58+ Sam
59+ lokes
60+ """
61+ [2 6]
62+
63+------------------------------------------------------------------------
docs/dev/hoon/library/2ec.mdnew file+652
@@ -0,0 +1,652 @@
1+section 2eC, parsing (custom rules)
2+===================================
3+
4+### `++cold`
5+
6+Replace with constant
7+
8+ ++ cold :: replace w/ constant
9+ ~/ %cold
10+ |* [cus=* sef=_rule]
11+ ~/ %fun
12+ |= tub=nail
13+ =+ vex=(sef tub)
14+ ?~ q.vex
15+ vex
16+ [p=p.vex q=[~ u=[p=cus q=q.u.q.vex]]]
17+ ::
18+
19+Parser modifier. Accepts a rule `sef` and produces a parser that
20+produces a constant `cus`, if `sef` is successful.
21+
22+`cus` is a constant [noun]().
23+
24+`sef` is a [`++rule`]().
25+
26+ ~zod/try=> ((cold %foo (just 'a')) [[1 1] "abc"])
27+ [p=[p=1 q=2] q=[~ u=[p=%foo q=[p=[p=1 q=2] q="bc"]]]]
28+ ~zod/try=> ((cold %foo (just 'a')) [[1 1] "bc"])
29+ [p=[p=1 q=1] q=~]
30+
31+------------------------------------------------------------------------
32+
33+### `++cook`
34+
35+Apply gate
36+
37+ ++ cook :: apply gate
38+ ~/ %cook
39+ |* [poq=_,* sef=_rule]
40+ ~/ %fun
41+ |= tub=nail
42+ =+ vex=(sef tub)
43+ ?~ q.vex
44+ vex
45+ [p=p.vex q=[~ u=[p=(poq p.u.q.vex) q=q.u.q.vex]]]
46+ ::
47+
48+Parser modifier. Produces a parser that takes a (successful) result of a
49+rule `sef` and slams it through `poq`.
50+
51+`poq` is a [gate]().
52+
53+`sef` is a [`++rule`]().
54+
55+ ~zod/try=> ((cook ,@ud (just 'a')) [[1 1] "abc"])
56+ [p=[p=1 q=2] q=[~ u=[p=97 q=[p=[p=1 q=2] q="bc"]]]]
57+ ~zod/try=> ((cook ,@tas (just 'a')) [[1 1] "abc"])
58+ [p=[p=1 q=2] q=[~ u=[p=%a q=[p=[p=1 q=2] q="bc"]]]]
59+ ~zod/try=> ((cook |=(a=@ +(a)) (just 'a')) [[1 1] "abc"])
60+ [p=[p=1 q=2] q=[~ u=[p=98 q=[p=[p=1 q=2] q="bc"]]]]
61+ ~zod/try=> ((cook |=(a=@ `@t`+(a)) (just 'a')) [[1 1] "abc"])
62+ [p=[p=1 q=2] q=[~ u=[p='b' q=[p=[p=1 q=2] q="bc"]]]]
63+
64+------------------------------------------------------------------------
65+
66+### `++easy`
67+
68+Always parse
69+
70+ ++ easy :: always parse
71+ ~/ %easy
72+ |* huf=*
73+ ~/ %fun
74+ |= tub=nail
75+ ^- (like ,_huf)
76+ [p=p.tub q=[~ u=[p=huf q=tub]]]
77+ ::
78+
79+Parser generator. Produces a parser that succeeds with given noun `huf`
80+without consuming any text.
81+
82+ ~zod/try=> ((easy %foo) [[1 1] "abc"])
83+ [p=[p=1 q=1] q=[~ [p=%foo q=[p=[p=1 q=1] q="abc"]]]]
84+ ~zod/try=> ((easy %foo) [[1 1] "bc"])
85+ [p=[p=1 q=1] q=[~ [p=%foo q=[p=[p=1 q=1] q="bc"]]]]
86+ ~zod/try=> ((easy 'a') [[1 1] "bc"])
87+ [p=[p=1 q=1] q=[~ [p='a' q=[p=[p=1 q=1] q="bc"]]]]
88+
89+------------------------------------------------------------------------
90+
91+### `++fail`
92+
93+Never parse
94+
95+ ++ fail |=(tub=nail [p=p.tub q=~]) :: never parse
96+
97+Produces an [edge]() at the same text position ([hair]()) with a failing
98+result (`q=~`).
99+
100+`tub` is a [`++nail`]().
101+
102+ ~zod/try=> (fail [[1 1] "abc"])
103+ [p=[p=1 q=1] q=~]
104+ ~zod/try=> (fail [[p=1.337 q=70] "Parse me, please?"])
105+ [p=[p=1.337 q=70] q=~]
106+
107+------------------------------------------------------------------------
108+
109+### `++full`
110+
111+Parse to end
112+
113+ ++ full :: parse to end
114+ |* sef=_rule
115+ |= tub=nail
116+ =+ vex=(sef tub)
117+ ?~(q.vex vex ?:(=(~ q.q.u.q.vex) vex [p=p.vex q=~]))
118+ ::
119+
120+Accepts a [`++nail`](), `tub`, and produces a parser that succeeds only
121+when a `tub` success consumes the remainder of the [tape]().
122+
123+`sef` is a [`++rule`]().
124+
125+ ~zod/try=> ((full (just 'a')) [[1 1] "ab"])
126+ [p=[p=1 q=2] q=~]
127+ ~zod/try=> ((full (jest 'ab')) [[1 1] "ab"])
128+ [p=[p=1 q=3] q=[~ u=[p='ab' q=[p=[p=1 q=3] q=""]]]]
129+ ~zod/try=> ((full ;~(plug (just 'a') (just 'b'))) [[1 1] "ab"])
130+ [p=[p=1 q=3] q=[~ u=[p=[~~a ~~b] q=[p=[p=1 q=3] q=""]]]]
131+
132+------------------------------------------------------------------------
133+
134+### `++funk`
135+
136+Add to tape
137+
138+ ++ funk :: add to tape first
139+ |* [pre=tape sef=_rule]
140+ |= tub=nail
141+ (sef p.tub (weld pre q.tub))
142+ ::
143+
144+Parser modifier: prepend text to tape before applying parser.
145+
146+`pre` is a [`++tape`]()
147+
148+`sef` is a [`++rule`]()
149+
150+ ~zod/try=> ((funk "abc prefix-" (jest 'abc')) [[1 1] "to be parsed"])
151+ [p=[p=1 q=4] q=[~ [p='abc' q=[p=[p=1 q=4] q=" prefix-to be parsed"]]]]
152+ ~zod/try=> ((funk "parse" (just 'a')) [[1 4] " me"])
153+ [p=[p=1 q=4] q=~]
154+
155+------------------------------------------------------------------------
156+
157+### `++here`
158+
159+Place-based apply
160+
161+ ++ here :: place-based apply
162+ ~/ %here
163+ |* [hez=_|=([a=pint b=*] [a b]) sef=_rule]
164+ ~/ %fun
165+ |= tub=nail
166+ =+ vex=(sef tub)
167+ ?~ q.vex
168+ vex
169+ [p=p.vex q=[~ u=[p=(hez [p.tub p.q.u.q.vex] p.u.q.vex) q=q.u.q.vex]]]
170+ ::
171+
172+Parser modifier. Similar to [`++cook`](), produces a parser that takes a
173+(successful) result of `sef` and slams it through `hez`. `hez` accepts a
174+[`++pint`]() `a` and a noun `b`, which is what the parser parsed.
175+
176+`hez` is a [gate]().
177+
178+`sef` is a [`++rule`]()
179+
180+ ~zod/try=> (scan "abc" (star alf))
181+ "abc"
182+ ~zod/try=> (scan "abc" (here |*(^ +<) (star alf)))
183+ [[[p=1 q=1] p=1 q=4] "abc"]
184+ ~zod/try=> (scan "abc" (star (here |*(^ +<) alf)))
185+ ~[[[[p=1 q=1] p=1 q=2] ~~a] [[[p=1 q=2] p=1 q=3] ~~b] [[[p=1 q=3] p=1 q=4] ~~c]]
186+
187+------------------------------------------------------------------------
188+
189+### `++inde`
190+
191+Indentation block
192+
193+ ++ inde |* sef=_rule :: indentation block
194+ |= nail ^+ (sef)
195+ =+ [har tap]=[p q]:+<
196+ =+ lev=(fil 3 (dec q.har) ' ')
197+ =+ eol=(just `@t`10)
198+ =+ =- roq=((star ;~(pose prn ;~(sfix eol (jest lev)) -)) har tap)
199+ ;~(simu ;~(plug eol eol) eol)
200+ ?~ q.roq roq
201+ =+ vex=(sef har(q 1) p.u.q.roq)
202+ =+ fur=p.vex(q (add (dec q.har) q.p.vex))
203+ ?~ q.vex vex(p fur)
204+ =- vex(p fur, u.q -)
205+ :+ &3.vex
206+ &4.vex(q.p (add (dec q.har) q.p.&4.vex))
207+ =+ res=|4.vex
208+ |- ?~ res |4.roq
209+ ?. =(10 -.res) [-.res $(res +.res)]
210+ (welp [`@t`10 (trip lev)] $(res +.res))
211+ ::
212+
213+Apply rule to indented block starting at current column number, omitting
214+the leading whitespace.
215+
216+`sef` is a [`++rule`]()
217+
218+ ~zod/try=> (scan "abc" (inde (star ;~(pose prn (just `@`10)))))
219+ "abc"
220+ ~zod/try=> (scan "abc" (star ;~(pose prn (just `@`10))))
221+ "abc"
222+ ~zod/try=> (scan " abc\0ade" ;~(pfix ace ace (star ;~(pose prn (just `@`10)))))
223+ "abc
224+ de"
225+ ~zod/try=> (scan " abc\0ade" ;~(pfix ace ace (inde (star ;~(pose prn (just `@`10))))))
226+ ! {1 6}
227+ ! exit
228+ ~zod/try=> (scan " abc\0a de" ;~(pfix ace ace (inde (star ;~(pose prn (just `@`10))))))
229+ "abc
230+ de"
231+
232+------------------------------------------------------------------------
233+
234+### `++jest`
235+
236+Match a cord
237+
238+ ++ jest :: match a cord
239+ |= daf=@t
240+ |= tub=nail
241+ =+ fad=daf
242+ |- ^- (like ,@t)
243+ ?: =(0 daf)
244+ [p=p.tub q=[~ u=[p=fad q=tub]]]
245+ ?: |(?=(~ q.tub) !=((end 3 1 daf) i.q.tub))
246+ (fail tub)
247+ $(p.tub (lust i.q.tub p.tub), q.tub t.q.tub, daf (rsh 3 1 daf))
248+ ::
249+
250+Match and consume a cord.
251+
252+`daf` is a `@t`
253+
254+ ~zod/try=> ((jest 'abc') [[1 1] "abc"])
255+ [p=[p=1 q=4] q=[~ [p='abc' q=[p=[p=1 q=4] q=""]]]]
256+ ~zod/try=> (scan "abc" (jest 'abc'))
257+ 'abc'
258+ ~zod/try=> (scan "abc" (jest 'acb'))
259+ ! {1 2}
260+ ! 'syntax-error'
261+ ! exit
262+ ~zod/try=> ((jest 'john doe') [[1 1] "john smith"])
263+ [p=[p=1 q=6] q=~]
264+ ~zod/try=> ((jest 'john doe') [[1 1] "john doe"])
265+ [p=[p=1 q=9] q=[~ [p='john doe' q=[p=[p=1 q=9] q=""]]]]
266+
267+------------------------------------------------------------------------
268+
269+### `++just`
270+
271+Match a char
272+
273+ ++ just :: XX redundant, jest
274+ ~/ %just :: match a char
275+ |= daf=char
276+ ~/ %fun
277+ |= tub=nail
278+ ^- (like char)
279+ ?~ q.tub
280+ (fail tub)
281+ ?. =(daf i.q.tub)
282+ (fail tub)
283+ (next tub)
284+ ::
285+
286+Match and consume a single character.
287+
288+`daf` is a [`++char`]()
289+
290+ ~zod/try=> ((just 'a') [[1 1] "abc"])
291+ [p=[p=1 q=2] q=[~ [p=~~a q=[p=[p=1 q=2] q="bc"]]]]
292+ ~zod/try=> (scan "abc" (just 'a'))
293+ ! {1 2}
294+ ! 'syntax-error'
295+ ! exit
296+ ~zod/try=> (scan "a" (just 'a'))
297+ ~~a
298+ ~zod/try=> (scan "%" (just '%'))
299+ ~~~25.
300+
301+------------------------------------------------------------------------
302+
303+### `++knee`
304+
305+Recursive parsers
306+
307+ ++ knee :: callbacks
308+ |* [gar=* sef=_|.(rule)]
309+ |= tub=nail
310+ ^- (like ,_gar)
311+ ((sef) tub)
312+ ::
313+
314+Used for recursive parsers, which would otherwise be infinite when
315+compiled.
316+
317+`gar` is a noun.
318+
319+`sef` is a [gate]() that accepts a [`++rule`]()
320+
321+ ~zod/try=> |-(;~(plug prn ;~(pose $ (easy ~))))
322+ ! rest-loop
323+ ! exit
324+ ~zod/try=> |-(;~(plug prn ;~(pose (knee *tape |.(^$)) (easy ~))))
325+ < 1.obo
326+ [ c=c=tub=[p=[p=@ud q=@ud] q=""]
327+ b
328+ < 1.bes
329+ [ c=tub=[p=[p=@ud q=@ud] q=""]
330+ b=<1.tnv [tub=[p=[p=@ud q=@ud] q=""] <1.ktu [daf=@tD <414.fvk 101.jzo 1.ypj %164>]>]>
331+ a=<1.fvg [tub=[p=[p=@ud q=@ud] q=""] <1.khu [[les=@ mos=@] <414.fvk 101.jzo 1.ypj %164>]>]>
332+ v=<414.fvk 101.jzo 1.ypj %164>
333+ ]
334+ >
335+ a
336+ ... 450 lines omitted ...
337+ ]
338+ >
339+ ~zod/try=> (scan "abcd" |-(;~(plug prn ;~(pose (knee *tape |.(^$)) (easy ~)))))
340+ [~~a "bcd"]
341+
342+------------------------------------------------------------------------
343+
344+### `++mask`
345+
346+Match char
347+
348+ ++ mask :: match char in set
349+ ~/ %mask
350+ |= bud=(list char)
351+ ~/ %fun
352+ |= tub=nail
353+ ^- (like char)
354+ ?~ q.tub
355+ (fail tub)
356+ ?. (lien bud |=(a=char =(i.q.tub a)))
357+ (fail tub)
358+ (next tub)
359+ ::
360+
361+Parser generator. Matches the next character if it is in a list of
362+characters.
363+
364+`bud` is a list of [`++char`]()
365+
366+ ~zod/try=> (scan "a" (mask "cba"))
367+ ~~a
368+ ~zod/try=> ((mask "abc") [[1 1] "abc"])
369+ [p=[p=1 q=2] q=[~ [p=~~a q=[p=[p=1 q=2] q="bc"]]]]
370+ ~zod/try=> ((mask "abc") [[1 1] "bbc"])
371+ [p=[p=1 q=2] q=[~ [p=~~b q=[p=[p=1 q=2] q="bc"]]]]
372+ ~zod/try=> ((mask "abc") [[1 1] "dbc"])
373+ [p=[p=1 q=1] q=~]
374+
375+------------------------------------------------------------------------
376+
377+### `++next`
378+
379+Consume char
380+
381+ ++ next :: consume a char
382+ |= tub=nail
383+ ^- (like char)
384+ ?~ q.tub
385+ (fail tub)
386+ =+ zac=(lust i.q.tub p.tub)
387+ [zac [~ i.q.tub [zac t.q.tub]]]
388+ ::
389+
390+Consume any character, producing it as a result.
391+
392+`tub` is a [`++nail`]()
393+
394+ ~zod/try=> (next [[1 1] "ebc"])
395+ [p=[p=1 q=2] q=[~ [p=~~e q=[p=[p=1 q=2] q="bc"]]]]
396+ ~zod/try=> (next [[1 1] "john jumps jones"])
397+ [p=[p=1 q=2] q=[~ [p=~~j q=[p=[p=1 q=2] q="ohn jumps jones"]]]]
398+
399+------------------------------------------------------------------------
400+
401+### `++sear`
402+
403+Conditional `++cook`
404+
405+ ++ sear :: conditional cook
406+ |* [pyq=_|=(* *(unit)) sef=_rule]
407+ |= tub=nail
408+ =+ vex=(sef tub)
409+ ?~ q.vex
410+ vex
411+ =+ gey=(pyq p.u.q.vex)
412+ ?~ gey
413+ [p=p.vex q=~]
414+ [p=p.vex q=[~ u=[p=u.gey q=q.u.q.vex]]]
415+ ::
416+
417+Conditional [`++cook`](). Slams the result through a gate that produces
418+a unit; if that unit is empty, fail.
419+
420+`tub` is a [`++nail`](/doc/hoon/library/1#++nail)
421+
422+ ~zod/try=> ((sear |=(a=* ?@(a (some a) ~)) (just `a`)) [[1 1] "abc"])
423+ [p=[p=1 q=2] q=[~ u=[p=97 q=[p=[p=1 q=2] q="bc"]]]]
424+ ~zod/try=> ((sear |=(* ~) (just 'a')) [[1 1] "abc"])
425+ [p=[p=1 q=2] q=~]
426+
427+------------------------------------------------------------------------
428+
429+### `++shim`
430+
431+Char in range
432+
433+ ++ shim :: match char in range
434+ ~/ %shim
435+ |= [les=@ mos=@]
436+ ~/ %fun
437+ |= tub=nail
438+ ^- (like char)
439+ ?~ q.tub
440+ (fail tub)
441+ ?. ?&((gte i.q.tub les) (lte i.q.tub mos))
442+ (fail tub)
443+ (next tub)
444+ ::
445+
446+Match characters within a range.
447+
448+`les` and `mos` are atoms, `@`.
449+
450+ ~zod/try=> ((shim 'a' 'z') [[1 1] "abc"])
451+ [p=[p=1 q=2] q=[~ [p=~~a q=[p=[p=1 q=2] q="bc"]]]]
452+ ~zod/try=> ((shim 'a' 'Z') [[1 1] "abc"])
453+ [p=[p=1 q=1] q=~]
454+ ~zod/try=> ((shim 'a' 'Z') [[1 1] "Abc"])
455+ [p=[p=1 q=2] q=[~ [p=~~~41. q=[p=[p=1 q=2] q="bc"]]]]
456+
457+------------------------------------------------------------------------
458+
459+### `++stag`
460+
461+Add label
462+
463+ ++ stag :: add a label
464+ ~/ %stag
465+ |* [gob=* sef=_rule]
466+ ~/ %fun
467+ |= tub=nail
468+ =+ vex=(sef tub)
469+ ?~ q.vex
470+ vex
471+ [p=p.vex q=[~ u=[p=[gob p.u.q.vex] q=q.u.q.vex]]]
472+ ::
473+
474+Add a label to an edge parsed by a rule.
475+
476+`gob` is a noun.
477+
478+`sef` is a rule.
479+
480+ ~zod/try=> ((stag %foo (just 'a')) [[1 1] "abc"])
481+ [p=[p=1 q=2] q=[~ u=[p=[%foo ~~a] q=[p=[p=1 q=2] q="bc"]]]]
482+ ~zod/try=> ((stag "xyz" (jest 'abc')) [[1 1] "abc"])
483+ [p=[p=1 q=4] q=[~ u=[p=["xyz" 'abc'] q=[p=[p=1 q=4] q=""]]]]
484+ ~zod/try=> ((stag 10.000 (shim 0 100)) [[1 1] "abc"])
485+ [p=[p=1 q=2] q=[~ u=[p=[10.000 ~~a] q=[p=[p=1 q=2] q="bc"]]]]
486+
487+------------------------------------------------------------------------
488+
489+### `++stet`
490+
491+Add faces
492+
493+ ++ stet
494+ |* leh=(list ,[?(@ [@ @]) _rule])
495+ |-
496+ ?~ leh
497+ ~
498+ [i=[p=-.i.leh q=+.i.leh] t=$(leh t.leh)]
499+ ::
500+
501+Add `[p q]` faces to range-parser pairs in a list.
502+
503+`leh` is a list of range-parsers.
504+
505+ ~zod/try=> (stet (limo [[5 (just 'a')] [1 (jest 'abc')] [[1 1] (shim 0 200)]
506+ [[1 10] (cold %foo (just 'a'))]~]))
507+ ~[
508+ [p=5 q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
509+ [p=1 q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
510+ [p=[1 1] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
511+ [p=[1 10] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
512+ ]
513+ ~zod/try=> [[[1 1] (just 'a')] [[2 1] (shim 0 200)] ~]
514+ [ [[1 1] <1.tnv [tub=[p=[p=@ud q=@ud] q=""] <1.ktu [daf=@tD <414.fvk 101.jzo 1.ypj %164>]>]>]
515+ [[2 1] <1.fvg [tub=[p=[p=@ud q=@ud] q=""] <1.khu [[les=@ mos=@] <414.fvk 101.jzo 1.ypj %164>]>]>]
516+ ~
517+ ]
518+ ~zod/try=> (stet (limo [[[1 1] (just 'a')] [[2 1] (shim 0 200)] ~]))
519+ ~[
520+ [p=[1 1] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
521+ [p=[2 1] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
522+ ]
523+
524+------------------------------------------------------------------------
525+
526+### `++stew`
527+
528+Switch by first
529+
530+ ++ stew :: switch by first char
531+ ~/ %stew
532+ |* leh=(list ,[p=?(@ [@ @]) q=_rule]) :: char/range keys
533+ =+ ^= wor :: range complete lth
534+ |= [ort=?(@ [@ @]) wan=?(@ [@ @])]
535+ ?@ ort
536+ ?@(wan (lth ort wan) (lth ort -.wan))
537+ ?@(wan (lth +.ort wan) (lth +.ort -.wan))
538+ =+ ^= hel :: build parser map
539+ =+ hel=`(tree $_(?>(?=(^ leh) i.leh)))`~
540+ |- ^+ hel
541+ ?~ leh
542+ ~
543+ =+ yal=$(leh t.leh)
544+ |- ^+ hel
545+ ?~ yal
546+ [i.leh ~ ~]
547+ ?: (wor p.i.leh p.n.yal)
548+ =+ nuc=$(yal l.yal)
549+ ?> ?=(^ nuc)
550+ ?: (vor p.n.yal p.n.nuc)
551+ [n.yal nuc r.yal]
552+ [n.nuc l.nuc [n.yal r.nuc r.yal]]
553+ =+ nuc=$(yal r.yal)
554+ ?> ?=(^ nuc)
555+ ?: (vor p.n.yal p.n.nuc)
556+ [n.yal l.yal nuc]
557+ [n.nuc [n.yal l.yal l.nuc] r.nuc]
558+ ~% %fun ..^$ ~
559+ |= tub=nail
560+ ?~ q.tub
561+ (fail tub)
562+ |-
563+ ?~ hel
564+ (fail tub)
565+ ?: ?@ p.n.hel
566+ =(p.n.hel i.q.tub)
567+ ?&((gte i.q.tub -.p.n.hel) (lte i.q.tub +.p.n.hel))
568+ :: (q.n.hel [(lust i.q.tub p.tub) t.q.tub])
569+ (q.n.hel tub)
570+ ?: (wor i.q.tub p.n.hel)
571+ $(hel l.hel)
572+ $(hel r.hel)
573+ ::
574+
575+Parser generator. From an associative list of characters or character
576+ranges to rules, construct a map, and parse tapes only with rules
577+associated with a range the tape's first character falls in.
578+
579+------------------------------------------------------------------------
580+
581+### `++stir`
582+
583+Parse repeatedly
584+
585+ ++ stir :: parse repeatedly
586+ ~/ %stir
587+ |* [rud=* raq=_|*([a=* b=*] [a b]) fel=_rule]
588+ ~/ %fun
589+ |= tub=nail
590+ ^- (like ,_rud)
591+ =+ vex=(fel tub)
592+ ?~ q.vex
593+ [p.vex [~ rud tub]]
594+ =+ wag=$(tub q.u.q.vex)
595+ ?> ?=(^ q.wag)
596+ [(last p.vex p.wag) [~ (raq p.u.q.vex p.u.q.wag) q.u.q.wag]]
597+ ::
598+
599+Parse with rule as many times as possible, and fold over results with a
600+binary gate.
601+
602+`rud` is a noun.
603+
604+`raq` is a gate that takes two nouns and produces a cell.
605+
606+`fel` is a rule.
607+
608+ ~zod/try=> (scan "abc" (stir *@ add prn))
609+ 294
610+ ~zod/try=> (roll "abc" add)
611+ b=294
612+
613+------------------------------------------------------------------------
614+
615+### `++stun`
616+
617+Parse several times
618+
619+ ++ stun :: parse several times
620+ |* [[les=@ mos=@] fel=_rule]
621+ |= tub=nail
622+ ^- (like (list ,_(wonk (fel))))
623+ ?: =(0 mos)
624+ [p.tub [~ ~ tub]]
625+ =+ vex=(fel tub)
626+ ?~ q.vex
627+ ?: =(0 les)
628+ [p.vex [~ ~ tub]]
629+ vex
630+ =+ ^= wag %= $
631+ les ?:(=(0 les) 0 (dec les))
632+ mos ?:(=(0 mos) 0 (dec mos))
633+ tub q.u.q.vex
634+ ==
635+ ?~ q.wag
636+ wag
637+ [p.wag [~ [p.u.q.vex p.u.q.wag] q.u.q.wag]]
638+
639+Parse bounded number of times.
640+
641+`[les=@ mos=@]` is a cell of atoms indicating the bounds.
642+
643+`fel` is a rule.
644+
645+ ~zod/try=> ((stun [5 10] prn) [1 1] "aquickbrownfoxran")
646+ [p=[p=1 q=11] q=[~ [p="aquickbrow" q=[p=[p=1 q=11] q="nfoxran"]]]]
647+ ~zod/try=> ((stun [5 10] prn) [1 1] "aquickbro")
648+ [p=[p=1 q=10] q=[~ [p="aquickbro" q=[p=[p=1 q=10] q=""]]]]
649+ ~zod/try=> ((stun [5 10] prn) [1 1] "aqui")
650+ [p=[p=1 q=5] q=~]
651+
652+------------------------------------------------------------------------
docs/dev/hoon/library/2ed.mdnew file+289
@@ -0,0 +1,289 @@
1+section 2eD
2+===========
3+
4+### `++bend`
5+
6+Conditional composer
7+
8+ ++ bend :: conditional comp
9+ ~/ %bend
10+ |* raq=_|*([a=* b=*] [~ u=[a b]])
11+ ~/ %fun
12+ |* [vex=edge sab=_rule]
13+ ?~ q.vex
14+ vex
15+ =+ yit=(sab q.u.q.vex)
16+ =+ yur=(last p.vex p.yit)
17+ ?~ q.yit
18+ [p=yur q=q.vex]
19+ =+ vux=(raq p.u.q.vex p.u.q.yit)
20+ ?~ vux
21+ [p=yur q=q.vex]
22+ [p=yur q=[~ u=[p=u.vux q=q.u.q.yit]]]
23+ ::
24+
25+Parsing composer: connects the edge `vex` with the subsequent rule `sab`
26+as an optional suffix, using the gate `raq` to compose or reject its
27+result. If there is no suffix, or if the suffix fails to be composed
28+with the current result, the current result is produced. Used to map a
29+group of rules to a specified output.
30+
31+`raq` is a [gate]().
32+
33+`sab` is a [rule]().
34+
35+`vex` is an [edge]().
36+
37+ ~zod/try=> (;~((bend |=([a=char b=char] ?.(=(a b) ~ (some +(a))))) prn prn) [1 1] "qs")
38+ [p=[p=1 q=3] q=[~ u=[p=~~q q=[p=[p=1 q=2] q="s"]]]]
39+ ~zod/try=> (;~((bend |=([a=char b=char] ?.(=(a b) ~ (some +(a))))) prn prn) [1 1] "qqq")
40+ [p=[p=1 q=3] q=[~ u=[p=~~r q=[p=[p=1 q=3] q="q"]]]]
41+ ~zod/try=> (scan "aa" ;~((bend |=([a=char b=char] ?.(=(a b) ~ (some +(a))))) prn prn))
42+ ~~b
43+ ~zod/try=> (scan "ba" ;~((bend |=([a=char b=char] ?.(=(a b) ~ (some +(a))))) prn prn))
44+ ! {1 3}
45+ ! exit
46+ ~zod/try=> `(unit ,@tas)`(scan "" ;~((bend) (easy ~) sym))
47+ ~
48+ ~zod/try=> `(unit ,@tas)`(scan "sep" ;~((bend) (easy ~) sym))
49+ [~ %sep]
50+
51+------------------------------------------------------------------------
52+
53+### `++comp`
54+
55+Arbitrary compose
56+
57+ ++ comp
58+ ~/ %comp
59+ |* raq=_|*([a=* b=*] [a b]) :: arbitrary compose
60+ ~/ %fun
61+ |* [vex=edge sab=_rule]
62+ ?~ q.vex
63+ vex
64+ =+ yit=(sab q.u.q.vex)
65+ =+ yur=(last p.vex p.yit)
66+ ?~ q.yit
67+ [p=yur q=q.yit]
68+ [p=yur q=[~ u=[p=(raq p.u.q.vex p.u.q.yit) q=q.u.q.yit]]]
69+ ::
70+
71+Parsing composer: connects the edge `vex` with a following rule `sab`,
72+combining the contents of `vex` with the result of `sab` using a binary
73+gate `raq`. Used to fold over the results of several rules.
74+
75+`raq` is a [gate]() that accepts a cell of two nouns, `a` and `b`, and
76+produces a cell of two nouns.
77+
78+`sab` is a [rule]().
79+
80+`vex` is an [edge]().
81+
82+ ~zod/try=> (scan "123" ;~((comp |=([a=@u b=@u] (add a b))) dit dit dit))
83+ 6
84+ ~zod/try=> (scan "12" ;~((comp |=([a=@u b=@u] (add a b))) dit dit dit))
85+ ! {1 3}
86+ ! exit
87+
88+------------------------------------------------------------------------
89+
90+### `++glue`
91+
92+Skip delimiter
93+
94+ ++ glue :: add rule
95+ ~/ %glue
96+ |* bus=_rule
97+ ~/ %fun
98+ |* [vex=edge sab=_rule]
99+ (plug vex ;~(pfix bus sab))
100+ ::
101+
102+Parsing composer: connects an edge `vex` with a following rule `sab` by
103+parsing the rule `bus` (the delimiting symbol) and throwing out the
104+result.
105+
106+`bus` is a [rule]().
107+
108+`sab` is a [rule]().
109+
110+`vex` is an [edge]().
111+
112+ ~zod/try=> (scan "200|mal|bon" ;~((glue bar) dem sym sym))
113+ [q=200 7.102.829 7.237.474]
114+ ~zod/try=> `[@u @tas @tas]`(scan "200|mal|bon" ;~((glue bar) dem sym sym))
115+ [200 %mal %bon]
116+ ~zod/try=> (scan "200|;|bon" ;~((glue bar) dem sem sym))
117+ [q=200 ~~~3b. 7.237.474]
118+ ~zod/try=> (scan "200.;.bon" ;~((glue dot) dem sem sym))
119+ [q=200 ~~~3b. 7.237.474]
120+
121+------------------------------------------------------------------------
122+
123+### `++less`
124+
125+Parse unless
126+
127+ ++ less :: no first and second
128+ |* [vex=edge sab=_rule]
129+ ?~ q.vex
130+ =+ roq=(sab)
131+ [p=(last p.vex p.roq) q=q.roq]
132+ vex(q ~)
133+ ::
134+
135+Parsing composer: if an edge `vex` reflects a success, fail. Otherwise,
136+connect `vex` with the following rule.
137+
138+`sab` is a [rule]().
139+
140+`vex` is an [edge]().
141+
142+ ~zod/try=> (scan "sas-/lo" (star ;~(less lus bar prn)))
143+ "sas-/lo"
144+ ~zod/try=> (scan "sas-/l+o" (star ;~(less lus bar prn)))
145+ ! {1 8}
146+ ! exit
147+ ~zod/try=> (scan "sas|-/lo" (star ;~(less lus bar prn)))
148+ ! {1 5}
149+ ! exit
150+
151+------------------------------------------------------------------------
152+
153+### `++pfix`
154+
155+Discard first rule
156+
157+ ++ pfix :: discard first rule
158+ ~/ %pfix
159+ (comp |*([a=* b=*] b))
160+ ::
161+
162+Parsing composer: connects an [edge]() `vex` with two subsequent rules,
163+ignoring the result of the first and producing the result of the second.
164+
165+`vex` is an [edge]().
166+
167+ ~zod/try=> `@t`(scan "%him" ;~(pfix cen sym))
168+ 'him'
169+ ~zod/try=> (scan "+++10" ;~(pfix (star lus) dem))
170+ q=10
171+
172+------------------------------------------------------------------------
173+
174+### `++plug`
175+
176+Parse to tuple
177+
178+ ++ plug :: first then second
179+ ~/ %plug
180+ |* [vex=edge sab=_rule]
181+ ?~ q.vex
182+ vex
183+ =+ yit=(sab q.u.q.vex)
184+ =+ yur=(last p.vex p.yit)
185+ ?~ q.yit
186+ [p=yur q=q.yit]
187+ [p=yur q=[~ u=[p=[p.u.q.vex p.u.q.yit] q=q.u.q.yit]]]
188+ ::
189+
190+Parsing composer: connects `vex` with a following rule `sab`, producing
191+a cell of both the results. See also: the monad applicator [;\~]() for a
192+more detailed explanation.
193+
194+`sab` is a [rule]().
195+
196+`vex` is an [edge]().
197+
198+ ~zod/try=> (scan "1..20" ;~(plug dem dot dot dem))
199+ [q=1 ~~~. ~~~. q=20]
200+ ~zod/try=> (scan "moke/~2014.1.1" ;~(plug sym fas nuck:so))
201+ [1.701.539.693 ~~~2f. [% p=[p=~.da q=170.141.184.500.766.106.671.844.917.172.921.958.400]]]
202+ ~zod/try=> ;;(,[@tas @t ~ %da @da] (scan "moke/~2014.1.1" ;~(plug sym fas nuck:so)))
203+ [%moke '/' ~ %da ~2014.1.1]
204+
205+------------------------------------------------------------------------
206+
207+### `++pose`
208+
209+Parse options
210+
211+ ++ pose :: first or second
212+ ~/ %pose
213+ |* [vex=edge sab=_rule]
214+ ?~ q.vex
215+ =+ roq=(sab)
216+ [p=(last p.vex p.roq) q=q.roq]
217+ vex
218+
219+Parsing composer: if `vex` reflects a failure, connect it with the
220+following rule `sab`. See also: the monad applicator [;\~]()
221+
222+`sab` is a [rule]().
223+
224+`vex` is an [edge]().
225+
226+ ~zod/try=> `@t`(scan "+" ;~(pose lus tar cen))
227+ '+'
228+ ~zod/try=> `@t`(scan "*" ;~(pose lus tar cen))
229+ '*'
230+ ~zod/try=> `@t`(scan "%" ;~(pose lus tar cen))
231+ '%'
232+ ~zod/try=> `@t`(scan "-" ;~(pose lus tar cen))
233+ ! {1 1}
234+ ! exit
235+
236+------------------------------------------------------------------------
237+
238+### `++simu`
239+
240+First and second
241+
242+ ++ simu :: first and second
243+ |* [vex=edge sab=_rule]
244+ ?~ q.vex
245+ vex
246+ =+ roq=(sab)
247+ roq
248+ ::
249+
250+Parsing composer: if an edge `vex` reflects a failure, fail. Otherwise,
251+connect `vex` with the following rule.
252+
253+`sab` is a [rule]().
254+
255+`vex` is an [edge]().
256+
257+ ~zod/try=> (scan "~zod" scat:vast)
258+ [%dtzy p=%p q=0]
259+ ~zod/try=> (scan "%zod" scat:vast)
260+ [%dtzz p=%tas q=6.582.138]
261+ ~zod/try=> (scan "%zod" ;~(simu cen scat:vast))
262+ [%dtzz p=%tas q=6.582.138]
263+ ~zod/try=> (scan "~zod" ;~(simu cen scat:vast))
264+ ! {1 1}
265+ ! exit
266+
267+------------------------------------------------------------------------
268+
269+### `++sfix`
270+
271+Discard second rule
272+
273+ ++ sfix :: discard second rule
274+ ~/ %sfix
275+ (comp |*([a=* b=*] a))
276+
277+Parsing composer: connects `vex` with two subsequent rules returning the
278+result of the first and discarding the result of the second.
279+
280+`a` is the result of parsing the first [rule]().
281+
282+`b` is the result of of parsing the second [rule]().
283+
284+ ~zod/try=> `@t`(scan "him%" ;~(sfix sym cen))
285+ 'him'
286+ ~zod/try=> (scan "10+++" ;~(sfix dem (star lus)))
287+ q=10
288+
289+------------------------------------------------------------------------
docs/dev/hoon/library/2ee.mdnew file+195
@@ -0,0 +1,195 @@
1+section 2eE, parsing (composers)
2+================================
3+
4+### `++bass`
5+
6+ ++ bass
7+ |* [wuc=@ tyd=_rule]
8+ %+ cook
9+ |= waq=(list ,@)
10+ %+ roll
11+ waq
12+ =|([p=@ q=@] |.((add p (mul wuc q))))
13+ tyd
14+ ::
15+
16+Parser modifier:
17+[LSB](http://en.wikipedia.org/wiki/Least_significant_bit) ordered list
18+as atom of a base.
19+
20+`wuc` is an [atom]().
21+
22+`tyd` is a [rule]().
23+
24+ ~zod/try=> (scan "123" (bass 10 (star dit)))
25+ q=123
26+ ~zod/try=> (scan "123" (bass 8 (star dit)))
27+ q=83
28+ ~zod/try=> `@ub`(scan "123" (bass 8 (star dit)))
29+ 0b101.0011
30+
31+------------------------------------------------------------------------
32+
33+### `++boss`
34+
35+ ++ boss
36+ |* [wuc=@ tyd=_rule]
37+ %+ cook
38+ |= waq=(list ,@)
39+ %+ reel
40+ waq
41+ =|([p=@ q=@] |.((add p (mul wuc q))))
42+ tyd
43+ ::
44+
45+Parser modifier:
46+[LSB](http://en.wikipedia.org/wiki/Least_significant_bit) ordered list
47+as atom of a base.
48+
49+`wuc` is an [atom]().
50+
51+`tyd` is a [rule]().
52+
53+ ~zod/try=> (scan "123" (boss 10 (star dit)))
54+ q=321
55+ ~zod/try=> `@t`(scan "bam" (boss 256 (star alp)))
56+ 'bam'
57+ ~zod/try=> `@ux`(scan "bam" (boss 256 (star alp)))
58+ 0x6d.6162
59+
60+------------------------------------------------------------------------
61+
62+### `++ifix`
63+
64+ ++ ifix
65+ |* [fel=[p=_rule q=_rule] hof=_rule]
66+ ;~(pfix p.fel ;~(sfix hof q.fel))
67+ ::
68+
69+Parser modifier: surround with pair of rules, output of which is
70+discarded.
71+
72+`fel` is a pair of [rule]()s.
73+
74+`hof` is a [rule]().
75+
76+ ~zod/try=> (scan "-40-" (ifix [hep hep] dem))
77+ q=40
78+ ~zod/try=> (scan "4my4" (ifix [dit dit] (star alf)))
79+ "my"
80+
81+------------------------------------------------------------------------
82+
83+### `++more`
84+
85+ ++ more
86+ |* [bus=_rule fel=_rule]
87+ ;~(pose (most bus fel) (easy ~))
88+ ::
89+
90+Parser modifier: using a delimiter rule, parse a list of matches.
91+
92+`bus` is a [rule]().
93+
94+`fel` is a [rule]().
95+
96+ ~zod/try=> (scan "" (more ace dem))
97+ ~
98+ ~zod/try=> (scan "40 20" (more ace dem))
99+ [q=40 ~[q=20]]
100+ ~zod/try=> (scan "40 20 60 1 5" (more ace dem))
101+ [q=40 ~[q=20 q=60 q=1 q=5]]
102+
103+------------------------------------------------------------------------
104+
105+### `++most`
106+
107+ ++ most
108+ |* [bus=_rule fel=_rule]
109+ ;~(plug fel (star ;~(pfix bus fel)))
110+ ::
111+
112+Parser modifier: using a delimiter rule, parse a list of at least one
113+match.
114+
115+`bus` is a [rule]().
116+
117+`fel` is a [rule]().
118+
119+ ~zod/try=> (scan "40 20" (most ace dem))
120+ [q=40 ~[q=20]]
121+ ~zod/try=> (scan "40 20 60 1 5" (most ace dem))
122+ [q=40 ~[q=20 q=60 q=1 q=5]]
123+ ~zod/try=> (scan "" (most ace dem))
124+ ! {1 1}
125+ ! exit
126+
127+------------------------------------------------------------------------
128+
129+### `++plus`
130+
131+ ++ plus |*(fel=_rule ;~(plug fel (star fel)))
132+
133+Parser modifier: parse list of at least one match
134+
135+`fel` is a [rule]().
136+
137+ ~zod/try=> (scan ">>>>" (cook lent (plus gar)))
138+ 4
139+ ~zod/try=> (scan "- - " (plus ;~(pose ace hep)))
140+ [~~- " - "]
141+ ~zod/try=> `tape`(scan "- - " (plus ;~(pose ace hep)))
142+ "- - "
143+ ~zod/try=> `(pole ,@t)`(scan "- - " (plus ;~(pose ace hep)))
144+ ['-' [' ' [' ' ['-' [' ' ~]]]]]
145+
146+------------------------------------------------------------------------
147+
148+### `++slug`
149+
150+ ++ slug
151+ |* raq=_|*([a=* b=*] [a b])
152+ |* [bus=_rule fel=_rule]
153+ ;~((comp raq) fel (stir rud raq ;~(pfix bus fel)))
154+ ::
155+
156+Parser modifier: By composing with a gate, parse a delimited list of
157+matches.
158+
159+`bus` is a [rule]().
160+
161+`fel` is a [rule]().
162+
163+ ~zod/try=> (scan "20+5+110" ((slug add) lus dem))
164+ 135
165+ ~zod/try=> `@t`(scan "a b c" ((slug |=(a=[@ @t] (cat 3 a))) ace alp))
166+ 'abc'
167+
168+------------------------------------------------------------------------
169+
170+### `++star`
171+
172+ ++ star :: 0 or more times
173+ |* fel=_rule
174+ (stir `(list ,_(wonk *fel))`~ |*([a=* b=*] [a b]) fel)
175+
176+Parser modifier: parse list of matches.
177+
178+`fel` is a [rule]().
179+
180+ ~zod/try=> (scan "aaaaa" (just 'a'))
181+ ! {1 2}
182+ ! 'syntax-error'
183+ ! exit
184+ ~zod/try=> (scan "aaaaa" (star (just 'a')))
185+ "aaaaa"
186+ ~zod/try=> (scan "abcdef" (star (just 'a')))
187+ ! {1 2}
188+ ! 'syntax-error'
189+ ! exit
190+ ~zod/try=> (scan "abcabc" (star (jest 'abc')))
191+ <|abc abc|>
192+ ~zod/try=> (scan "john smith" (star (shim 0 200)))
193+ "john smith"
194+
195+------------------------------------------------------------------------
docs/dev/hoon/library/2ef.mdnew file+648
@@ -0,0 +1,648 @@
1+section 2eF, parsing (ascii)
2+============================
3+
4+### `++ace`
5+
6+Parse space
7+
8+ ++ ace (just ' ')
9+
10+Parses ASCII character 32, space.
11+
12+ ~zod/try=> (scan " " ace)
13+ ~~.
14+ ~zod/try=> `cord`(scan " " ace)
15+ ' '
16+ ~zod/try=> (ace [[1 1] " "])
17+ [p=[p=1 q=2] q=[~ [p=~~. q=[p=[p=1 q=2] q=""]]]]
18+ ~zod/try=> (ace [[1 1] " abc "])
19+ [p=[p=1 q=2] q=[~ [p=~~. q=[p=[p=1 q=2] q="abc "]]]]
20+
21+------------------------------------------------------------------------
22+
23+### `++bar`
24+
25+Parse vertical bar
26+
27+ ++ bar (just '|')
28+
29+Parses ASCII character 124, the vertical bar.
30+
31+ ~zod/try=> (scan "|" bar)
32+ ~~~7c.
33+ ~zod/try=> `cord`(scan "|" bar)
34+ '|'
35+ ~zod/try=> (bar [[1 1] "|"])
36+ [p=[p=1 q=2] q=[~ [p=~~~7c. q=[p=[p=1 q=2] q=""]]]]
37+ ~zod/try=> (bar [[1 1] "|="])
38+ [p=[p=1 q=2] q=[~ [p=~~~7c. q=[p=[p=1 q=2] q="="]]]]
39+
40+------------------------------------------------------------------------
41+
42+### `++bas`
43+
44+Parse backslash
45+
46+ ++ bas (just '\\')
47+
48+Parses ASCII character 92, the backslash. Note the extra `\` in the slam
49+of `bas` with [`++just`](/doc/hoon/library/2ec#++just) is to escape the escape character, `\`.
50+
51+ ~zod/try=> (scan "\\" bas)
52+ ~~~5c.
53+ ~zod/try=> `cord`(scan "\\" bas)
54+ '\'
55+ ~zod/try=> (bas [[1 1] "\"])
56+ ~ <syntax error at [1 18]>
57+ ~zod/try=> (bas [[1 1] "\\"])
58+ [p=[p=1 q=2] q=[~ [p=~~~5c. q=[p=[p=1 q=2] q=""]]]]
59+ ~zod/try=> (bas [[1 1] "\""])
60+ [p=[p=1 q=1] q=~]
61+
62+------------------------------------------------------------------------
63+
64+### `++buc`
65+
66+Parse dollar sign
67+
68+ ++ buc (just '$')
69+
70+Parses ASCII character 36, the dollar sign.
71+
72+ ~zod/try=> (scan "$" buc)
73+ ~~~24.
74+ ~zod/try=> `cord`(scan "$" buc)
75+ '$'
76+ ~zod/try=> (buc [[1 1] "$"])
77+ [p=[p=1 q=2] q=[~ [p=~~~24. q=[p=[p=1 q=2] q=""]]]]
78+ ~zod/try=> (buc [[1 1] "$%"])
79+ [p=[p=1 q=2] q=[~ [p=~~~24. q=[p=[p=1 q=2] q="%"]]]]
80+
81+------------------------------------------------------------------------
82+
83+### `++cab`
84+
85+Parse underscore
86+
87+ ++ cab (just '_')
88+
89+Parses ASCII character 95, the underscore.
90+
91+ ~zod/try=> (scan "_" cab)
92+ ~~~5f.
93+ ~zod/try=> `cord`(scan "_" cab)
94+ '_'
95+ ~zod/try=> (cab [[1 1] "_"])
96+ [p=[p=1 q=2] q=[~ [p=~~~5f. q=[p=[p=1 q=2] q=""]]]]
97+ ~zod/try=> (cab [[1 1] "|_"])
98+ [p=[p=1 q=1] q=~]
99+
100+------------------------------------------------------------------------
101+
102+### `++cen`
103+
104+Parses percent sign
105+
106+ ++ cen (just '%')
107+
108+Parses ASCII character 37, the percent sign.
109+
110+ ~zod/try=> (scan "%" cen)
111+ ~~~25.
112+ ~zod/try=> `cord`(scan "%" cen)
113+ '%'
114+ ~zod/try=> (cen [[1 1] "%"])
115+ [p=[p=1 q=2] q=[~ [p=~~~25. q=[p=[p=1 q=2] q=""]]]]
116+ ~zod/try=> (cen [[1 1] "%^"])
117+ [p=[p=1 q=2] q=[~ [p=~~~25. q=[p=[p=1 q=2] q="^"]]]]
118+
119+------------------------------------------------------------------------
120+
121+### `++col`
122+
123+Parse colon
124+
125+ ++ col (just ':')
126+
127+Parses ASCII character 58, the colon
128+
129+ ~zod/try=> (scan ":" col)
130+ ~~~3a.
131+ ~zod/try=> `cord`(scan ":" col)
132+ ':'
133+ ~zod/try=> (col [[1 1] ":"])
134+ [p=[p=1 q=2] q=[~ [p=~~~3a. q=[p=[p=1 q=2] q=""]]]]
135+ ~zod/try=> (col [[1 1] ":-"])
136+ [p=[p=1 q=2] q=[~ [p=~~~3a. q=[p=[p=1 q=2] q="-"]]]]
137+
138+------------------------------------------------------------------------
139+
140+### `++com`
141+
142+Parse comma
143+
144+ ++ com (just ',')
145+
146+Parses ASCII character 44, the comma.
147+
148+ ~zod/try=> (scan "," com)
149+ ~~~2c.
150+ ~zod/try=> `cord`(scan "," com)
151+ ','
152+ ~zod/try=> (com [[1 1] ","])
153+ [p=[p=1 q=2] q=[~ [p=~~~2c. q=[p=[p=1 q=2] q=""]]]]
154+ ~zod/try=> (com [[1 1] "not com"])
155+ [p=[p=1 q=1] q=~]
156+
157+------------------------------------------------------------------------
158+
159+### `++doq`
160+
161+Parse double quote
162+
163+ ++ doq (just '"')
164+
165+Parses ASCII character 34, the double quote.
166+
167+ ~tadbyl-hilbel/try=> (scan "\"" doq)
168+ ~~~22.
169+ ~tadbyl-hilbel/try=> `cord`(scan "\"" doq)
170+ '"'
171+ ~tadbyl-hilbel/try=> (doq [[1 1] "\""])
172+ [p=[p=1 q=2] q=[~ [p=~~~22. q=[p=[p=1 q=2] q=""]]]]
173+ ~tadbyl-hilbel/try=> (doq [[1 1] "not successfully parsed"])
174+ [p=[p=1 q=1] q=~]
175+ ~tadbyl-hilbel/try=> (scan "see?" doq)
176+ ! {1 1}
177+ ! 'syntax-error'
178+ ! exit
179+
180+------------------------------------------------------------------------
181+
182+### `++dot`
183+
184+Parse period
185+
186+ ++ dot (just '.')
187+
188+Parses ASCII character 46, the period.
189+
190+ ~zod/try=> (scan "." dot)
191+ ~~~.
192+ ~zod/try=> `cord`(scan "." dot)
193+ '.'
194+ ~zod/try=> (dot [[1 1] "."])
195+ [p=[p=1 q=2] q=[~ [p=~~~. q=[p=[p=1 q=2] q=""]]]]
196+ ~zod/try=> (dot [[1 1] ".^"])
197+ [p=[p=1 q=2] q=[~ [p=~~~. q=[p=[p=1 q=2] q="^"]]]]
198+
199+------------------------------------------------------------------------
200+
201+### `++fas`
202+
203+Parse forward slash
204+
205+ ++ fas (just '/')
206+
207+Parses ASCII character 47, the forward slash.
208+
209+ ~zod/try=> (scan "/" fas)
210+ ~~~2f.
211+ ~zod/try=> `cord`(scan "/" fas)
212+ '/'
213+ ~zod/try=> (fas [[1 1] "/"])
214+ [p=[p=1 q=2] q=[~ [p=~~~2f. q=[p=[p=1 q=2] q=""]]]]
215+ ~zod/try=> (fas [[1 1] "|/"])
216+ [p=[p=1 q=1] q=~]
217+
218+------------------------------------------------------------------------
219+
220+### `++gal`
221+
222+Parse less-than sign
223+
224+ ++ gal (just '<')
225+
226+Parses ASCII character 60, the less-than sign.
227+
228+ ~zod/try=> (scan "<" gal)
229+ ~~~3c.
230+ ~zod/try=> `cord`(scan "<" gal)
231+ '<'
232+ ~zod/try=> (gal [[1 1] "<"])
233+ [p=[p=1 q=2] q=[~ [p=~~~3c. q=[p=[p=1 q=2] q=""]]]]
234+ ~zod/try=> (gal [[1 1] "<+"])
235+ [p=[p=1 q=2] q=[~ [p=~~~3c. q=[p=[p=1 q=2] q="+"]]]]
236+ ~zod/try=> (gal [[1 1] "+<"])
237+ [p=[p=1 q=1] q=~]
238+
239+------------------------------------------------------------------------
240+
241+### `++gar`
242+
243+Parse greater-than sign
244+
245+ ++ gar (just '>')
246+
247+Parses ASCII character 62, the greater-than sign.
248+
249+ ~zod/try=> (scan ">" gar)
250+ ~~~3e.
251+ ~zod/try=> `cord`(scan ">" gar)
252+ '>'
253+ ~zod/try=> (gar [[1 1] ">"])
254+ [p=[p=1 q=2] q=[~ [p=~~~3e. q=[p=[p=1 q=2] q=""]]]]
255+ ~zod/try=> (gar [[1 1] "=>"])
256+ [p=[p=1 q=1] q=~]
257+
258+------------------------------------------------------------------------
259+
260+### `++hax`
261+
262+Parse number sign
263+
264+ ++ hax (just '#')
265+
266+Parses ASCII character 35, the number sign.
267+
268+ ~zod/try=> (scan "#" hax)
269+ ~~~23.
270+ ~zod/try=> `cord`(scan "#" hax)
271+ '#'
272+ ~zod/try=> (hax [[1 1] "#"])
273+ [p=[p=1 q=2] q=[~ [p=~~~23. q=[p=[p=1 q=2] q=""]]]]
274+ ~zod/try=> (hax [[1 1] "#!"])
275+ [p=[p=1 q=2] q=[~ [p=~~~23. q=[p=[p=1 q=2] q="!"]]]]
276+
277+------------------------------------------------------------------------
278+
279+### `++kel`
280+
281+Parse left curley bracket
282+
283+ ++ kel (just '{')
284+
285+Parses ASCII character 123, the left curly bracket. Note that `{`
286+(`kel`) and `}` (`ker`) open and close a Hoon expression for Hoon string
287+interpolation. To parse either of them, they must be escaped.
288+
289+ ~zod/try=> (scan "\{" kel)
290+ ~~~7b.
291+ ~zod/try=> `cord`(scan "\{" kel)
292+ '{'
293+ ~zod/try=> (kel [[1 1] "\{"])
294+ [p=[p=1 q=2] q=[~ [p=~~~7b. q=[p=[p=1 q=2] q=""]]]]
295+ ~zod/try=> (kel [[1 1] " \{"])
296+ [p=[p=1 q=1] q=~]
297+
298+------------------------------------------------------------------------
299+
300+### `++ker`
301+
302+Parse right curley bracket
303+
304+ ++ ker (just '}')
305+
306+Parses ASCII character 125, the right curly bracket. Note that `{`
307+(`kel`) and `}` (`ker`) open and close a Hoon expression for Hoon string
308+interpolation. To parse either of them, they must be escaped.
309+
310+ ~zod/try=> (scan "}" ker)
311+ ~~~7d.
312+ ~zod/try=> `cord`(scan "}" ker)
313+ '}'
314+ ~zod/try=> (ker [[1 1] "}"])
315+ [p=[p=1 q=2] q=[~ [p=~~~7d. q=[p=[p=1 q=2] q=""]]]]
316+ ~zod/try=> (ker [[1 1] "\{}"])
317+ [p=[p=1 q=1] q=~]
318+
319+------------------------------------------------------------------------
320+
321+### `++ket`
322+
323+Parse caret
324+
325+ ++ ket (just '^')
326+
327+Parses ASCII character 94, the caret.
328+
329+ ~zod/try=> (scan "^" ket)
330+ ~~~5e.
331+ ~zod/try=> `cord`(scan "^" ket)
332+ '^'
333+ ~zod/try=> (ket [[1 1] "^"])
334+ [p=[p=1 q=2] q=[~ [p=~~~5e. q=[p=[p=1 q=2] q=""]]]]
335+ ~zod/try=> (ket [[1 1] ".^"])
336+ [p=[p=1 q=1] q=~]
337+
338+------------------------------------------------------------------------
339+
340+### `++lus`
341+
342+Parse plus sign
343+
344+ ++ lus (just '+')
345+
346+Parses ASCII character 43, the plus sign.
347+
348+ ~zod/try=> (scan "+" lus)
349+ ~~~2b.
350+ ~zod/try=> `cord`(scan "+" lus)
351+ '+'
352+ ~zod/try=> (lus [[1 1] "+"])
353+ [p=[p=1 q=2] q=[~ [p=~~~2b. q=[p=[p=1 q=2] q=""]]]]
354+ ~zod/try=> (lus [[1 1] ".+"])
355+ [p=[p=1 q=1] q=~]
356+
357+------------------------------------------------------------------------
358+
359+### `++hep`
360+
361+Parse hyphen
362+
363+ ++ hep (just '-')
364+
365+Parses ASCII character 45, the hyphen.
366+
367+ ~zod/try=> (scan "-" hep)
368+ ~~-
369+ ~zod/try=> `cord`(scan "-" hep)
370+ '-'
371+ ~zod/try=> (hep [[1 1] "-"])
372+ [p=[p=1 q=2] q=[~ [p=~~- q=[p=[p=1 q=2] q=""]]]]
373+ ~zod/try=> (hep [[1 1] ":-"])
374+ [p=[p=1 q=1] q=~]
375+
376+------------------------------------------------------------------------
377+
378+### `++pel`
379+
380+Parse left parenthesis
381+
382+ ++ pel (just '(')
383+
384+Parses ASCII character 40, the left parenthesis.
385+
386+ ~zod/try=> (scan "(" pel)
387+ ~~~28.
388+ ~zod/try=> `cord`(scan "(" pel)
389+ '('
390+ ~zod/try=> (pel [[1 1] "("])
391+ [p=[p=1 q=2] q=[~ [p=~~~28. q=[p=[p=1 q=2] q=""]]]]
392+ ~zod/try=> (pel [[1 1] ";("])
393+ [p=[p=1 q=1] q=~]
394+
395+------------------------------------------------------------------------
396+
397+### `++pam`
398+
399+Parse ampersand
400+
401+ ++ pam (just '&')
402+
403+Parses ASCII character 38, the ampersand.
404+
405+ ~zod/try=> (scan "&" pam)
406+ ~~~26.
407+ ~zod/try=> `cord`(scan "&" pam)
408+ '&'
409+ ~zod/try=> (pam [[1 1] "&"])
410+ [p=[p=1 q=2] q=[~ [p=~~~26. q=[p=[p=1 q=2] q=""]]]]
411+ ~zod/try=> (pam [[1 1] "?&"])
412+ [p=[p=1 q=1] q=~]
413+
414+------------------------------------------------------------------------
415+
416+### `++per`
417+
418+Parse right parenthesis
419+
420+ ++ per (just ')')
421+
422+Parses ASCII character 41, the right parenthesis.
423+
424+ ~zod/try=> (scan ")" per)
425+ ~~~29.
426+ ~zod/try=> `cord`(scan ")" per)
427+ ')'
428+ ~zod/try=> (per [[1 1] ")"])
429+ [p=[p=1 q=2] q=[~ [p=~~~29. q=[p=[p=1 q=2] q=""]]]]
430+ ~zod/try=> (per [[1 1] " )"])
431+ [p=[p=1 q=1] q=~]
432+
433+------------------------------------------------------------------------
434+
435+### `++pat`
436+
437+Parse "at" sign
438+
439+ ++ pat (just '@')
440+
441+Parses ASCII character 64, the "at" sign.
442+
443+ ~zod/try=> (scan "@" pat)
444+ ~~~4.
445+ ~zod/try=> `cord`(scan "@" pat)
446+ '@'
447+ ~zod/try=> (pat [[1 1] "@"])
448+ [p=[p=1 q=2] q=[~ [p=~~~4. q=[p=[p=1 q=2] q=""]]]]
449+ ~zod/try=> (pat [[1 1] "?@"])
450+ [p=[p=1 q=1] q=~]
451+
452+------------------------------------------------------------------------
453+
454+### `++sel`
455+
456+Parse left square bracket
457+
458+Left square bracket
459+
460+ ++ sel (just '[')
461+
462+Parses ASCII character 91, the left square bracket.
463+
464+ ~zod/try=> (scan "[" sel)
465+ ~~~5b.
466+ ~zod/try=> `cord`(scan "[" sel)
467+ '['
468+ ~zod/try=> (sel [[1 1] "["])
469+ [p=[p=1 q=2] q=[~ [p=~~~5b. q=[p=[p=1 q=2] q=""]]]]
470+ ~zod/try=> (sel [[1 1] "-["])
471+ [p=[p=1 q=1] q=~]
472+
473+------------------------------------------------------------------------
474+
475+### `++sem`
476+
477+Parse semicolon
478+
479+ ++ sem (just ';')
480+
481+Parses ASCII character 59, the semicolon.
482+
483+### `Examples`
484+
485+ ~zod/try=> (scan ";" sem)
486+ ~~~3b.
487+ ~zod/try=> `cord`(scan ";" sem)
488+ ';'
489+ ~zod/try=> (sem [[1 1] ";"])
490+ [p=[p=1 q=2] q=[~ [p=~~~3b. q=[p=[p=1 q=2] q=""]]]]
491+ ~zod/try=> (sem [[1 1] " ;"])
492+ [p=[p=1 q=1] q=~]
493+
494+------------------------------------------------------------------------
495+
496+### `++ser`
497+
498+Parse right square bracket
499+
500+ ++ ser (just ']')
501+
502+Parses ASCII character 93, the right square bracket.
503+
504+ ~zod/try=> (scan "]" ser)
505+ ~~~5d.
506+ ~zod/try=> `cord`(scan "]" ser)
507+ ']'
508+ ~zod/try=> (ser [[1 1] "]"])
509+ [p=[p=1 q=2] q=[~ [p=~~~5d. q=[p=[p=1 q=2] q=""]]]]
510+ ~zod/try=> (ser [[1 1] "[ ]"])
511+ [p=[p=1 q=1] q=~]
512+
513+------------------------------------------------------------------------
514+
515+### `++sig`
516+
517+Parse tilde
518+
519+ ++ sig (just '~')
520+
521+Parses ASCII character 126, the tilde.
522+
523+ ~zod/try=> (scan "~" sig)
524+ ~~~~
525+ ~zod/try=> `cord`(scan "~" sig)
526+ '~'
527+ ~zod/try=> (sig [[1 1] "~"])
528+ [p=[p=1 q=2] q=[~ [p=~~~~ q=[p=[p=1 q=2] q=""]]]]
529+ ~zod/try=> (sig [[1 1] "?~"])
530+ [p=[p=1 q=1] q=~]
531+
532+------------------------------------------------------------------------
533+
534+### `++soq`
535+
536+Parse single quote
537+
538+ ++ soq (just '\'')
539+
540+Parses ASCII character 39, soq. Note the extra '' is to escape the first
541+`soq` because soq delimits a cord.
542+
543+ ~zod/try=> (scan "'" soq)
544+ ~~~27.
545+ ~zod/try=> `cord`(scan "'" soq)
546+ '''
547+ ~zod/try=> (soq [[1 1] "'"])
548+ [p=[p=1 q=2] q=[~ [p=~~~27. q=[p=[p=1 q=2] q=""]]]]
549+ ~zod/try=> (soq [[1 1] ">'"])
550+ [p=[p=1 q=1] q=~]
551+
552+------------------------------------------------------------------------
553+
554+### `++tar`
555+
556+Parse asterisk
557+
558+ ++ tar (just '*')
559+
560+Parses ASCII character 42, the asterisk.
561+
562+ ~zod/try=> (scan "*" tar)
563+ ~~~2a.
564+ ~zod/try=> `cord`(scan "*" tar)
565+ '*'
566+ ~zod/try=> (tar [[1 1] "*"])
567+ [p=[p=1 q=2] q=[~ [p=~~~2a. q=[p=[p=1 q=2] q=""]]]]
568+ ~zod/try=> (tar [[1 1] ".*"])
569+ [p=[p=1 q=1] q=~]
570+
571+------------------------------------------------------------------------
572+
573+### `++tec`
574+
575+Parse backtick
576+
577+ ++ tec (just '`') :: backTiCk
578+
579+Parses ASCII character 96, the backtick (also known as the "grave
580+accent".
581+
582+ ~zod/try=> (scan "`" tec)
583+ ~~~6.
584+ ~zod/try=> `cord`(scan "`" tec)
585+ '`'
586+ ~zod/try=> (tec [[1 1] "`"])
587+ [p=[p=1 q=2] q=[~ [p=~~~6. q=[p=[p=1 q=2] q=""]]]]
588+ ~zod/try=> (tec [[1 1] " `"])
589+ [p=[p=1 q=1] q=~]
590+
591+------------------------------------------------------------------------
592+
593+### `++tis`
594+
595+Parse equals sign
596+
597+ ++ tis (just '=')
598+
599+Parses ASCII character 61, the equals sign.
600+
601+ ~zod/try=> (scan "=" tis)
602+ ~~~3d.
603+ ~zod/try=> `cord`(scan "=" tis)
604+ '='
605+ ~zod/try=> (tis [[1 1] "="])
606+ [p=[p=1 q=2] q=[~ [p=~~~3d. q=[p=[p=1 q=2] q=""]]]]
607+ ~zod/try=> (tis [[1 1] "|="])
608+ [p=[p=1 q=1] q=~]
609+
610+------------------------------------------------------------------------
611+
612+### `++wut`
613+
614+Parses question mark
615+
616+ ++ wut (just '?')
617+
618+Parses ASCII character 63, wut.
619+
620+ ~zod/try=> (scan "?" wut)
621+ ~~~3f.
622+ ~zod/try=> `cord`(scan "?" wut)
623+ '?'
624+ ~zod/try=> (wut [[1 1] "?"])
625+ [p=[p=1 q=2] q=[~ [p=~~~3f. q=[p=[p=1 q=2] q=""]]]]
626+ ~zod/try=> (wut [[1 1] ".?"])
627+ [p=[p=1 q=1] q=~]
628+
629+------------------------------------------------------------------------
630+
631+### `++zap`
632+
633+Exclamation point
634+
635+ ++ zap (just '!')
636+
637+Parses ASCII character 33, the exclamation point zap.
638+
639+ ~zod/try=> (scan "!" zap)
640+ ~~~21.
641+ ~zod/try=> `cord`(scan "!" zap)
642+ '!'
643+ ~zod/try=> (zap [[1 1] "!"])
644+ [p=[p=1 q=2] q=[~ [p=~~~21. q=[p=[p=1 q=2] q=""]]]]
645+ ~zod/try=> (zap [[1 1] "?!"])
646+ [p=[p=1 q=1] q=~]
647+
648+------------------------------------------------------------------------
docs/dev/hoon/library/2eg.mdnew file+160
@@ -0,0 +1,160 @@
1+section 2eG, parsing (whitespace)
2+=================================
3+
4+### `++dog`
5+
6+`.` optional gap
7+
8+ ++ dog ;~(plug dot gay) ::
9+
10+Dot followed by an optional gap, used in numbers.
11+
12+ /~zod/try=> 1.234.
13+ 703
14+ 1.234.703
15+ ~zod/try=> (scan "a. " ;~(pfix alf dog))
16+ [~~~. ~]
17+
18+------------------------------------------------------------------------
19+
20+### `++doh`
21+
22+`@p` separator
23+
24+ ++ doh ;~(plug ;~(plug hep hep) gay) ::
25+
26+Phonetic base phrase separator
27+
28+ /~zod/try=> ~nopfel-botduc-nilnev-dolfyn--haspub-natlun-lodmur-holtyd
29+ ~nopfel-botduc-nilnev-dolfyn--haspub-natlun-lodmur-holtyd
30+ /~zod/try=> ~nopfel-botduc-nilnev-dolfyn--
31+ haspub-natlun-lodmur-holtyd
32+ ~nopfel-botduc-nilnev-dolfyn--haspub-natlun-lodmur-holtyd
33+ ~zod/try=> (scan "--" doh)
34+ [[~~- ~~-] ~]
35+ ~zod/try=> (scan "-- " doh)
36+ [[~~- ~~-] ~]
37+
38+------------------------------------------------------------------------
39+
40+### `++dun`
41+
42+`--` to `~`
43+
44+ ++ dun (cold ~ ;~(plug hep hep)) :: -- (phep) to ~
45+
46+Parse phep, `--`, to null, `~`.
47+
48+ ~zod/try=> (scan "--" dun)
49+ ~
50+ ~zod/try=> (dun [[1 1] "--"])
51+ [p=[p=1 q=3] q=[~ u=[p=~ q=[p=[p=1 q=3] q=""]]]]
52+
53+------------------------------------------------------------------------
54+
55+### `++duz`
56+
57+`==` to `~`
58+
59+ ++ duz (cold ~ ;~(plug tis tis)) :: == (stet) to ~
60+
61+Parse stet, `==`, to null `~`.
62+
63+ ~zod/try=> (scan "==" duz)
64+ ~
65+ ~zod/try=> (duz [[1 1] "== |=..."])
66+ [p=[p=1 q=3] q=[~ u=[p=~ q=[p=[p=1 q=3] q=" |=..."]]]]
67+
68+------------------------------------------------------------------------
69+
70+### `++gah`
71+
72+Newline or ' '
73+
74+ ++ gah (mask [`@`10 ' ' ~]) :: newline or ace
75+
76+Whitespace component, either newline or space.
77+
78+ /~zod/try=> ^- * :: show spaces
79+ """
80+ -
81+ -
82+ -
83+ """
84+ [32 32 32 45 10 32 45 10 32 32 45 0]
85+ /~zod/try=> ^- *
86+ """
87+
88+ """
89+ [32 32 32 10 32 10 32 32 0]
90+ /~zod/try=> ^- (list ,@)
91+ %- scan :_ (star gah)
92+ """
93+
94+ """
95+ ~[32 32 32 10 32 10 32 32]
96+
97+------------------------------------------------------------------------
98+
99+### `++gap`
100+
101+Plural whitespace
102+
103+ ++ gap (cold ~ ;~(plug gaq (star ;~(pose vul gah)))) :: plural whitespace
104+
105+Separates tall runes
106+
107+------------------------------------------------------------------------
108+
109+### `++gaq`
110+
111+End of line
112+
113+ ++ gaq ;~ pose :: end of line
114+ (just `@`10)
115+ ;~(plug gah ;~(pose gah vul))
116+ vul
117+ ==
118+
119+Two spaces, a newline, or comment.
120+
121+------------------------------------------------------------------------
122+
123+### `++gaw`
124+
125+Classic whitespace
126+
127+ ++ gaw (cold ~ (star ;~(pose vul gah))) :: classic white
128+
129+Terran whitespace
130+
131+------------------------------------------------------------------------
132+
133+### `++gay`
134+
135+Optional gap.
136+
137+ ++ gay ;~(pose gap (easy ~)) ::
138+
139+Optional gap.
140+
141+------------------------------------------------------------------------
142+
143+### `++vul`
144+
145+ ++ vul %- cold :- ~ :: comments
146+ ;~ plug col col
147+ (star prn)
148+ (just `@`10)
149+ ==
150+
151+Parse comments and produce a null. Note that a comment must be ended
152+with a newline character.
153+
154+ ~zod/try=> (scan "::this is a comment \0a" vul)
155+ ~
156+ ~zod/try=> (scan "::this is a comment " vul)
157+ ! {1 21}
158+ ! exit
159+
160+------------------------------------------------------------------------
docs/dev/hoon/library/2eh.mdnew file+531
@@ -0,0 +1,531 @@
1+section 2eH, parsing (idioms)
2+=============================
3+
4+### `++alf`
5+
6+Alphabetic characters
7+
8+ ++ alf ;~(pose low hig) :: alphabetic
9+
10+Parse alphabetic characters, both upper and lowercase.
11+
12+ ~zod/try=> (scan "a" alf)
13+ ~~a
14+ ~zod/try=> (scan "A" alf)
15+ ~~~41.
16+ ~zod/try=> (scan "AaBbCc" (star alf))
17+ "AaBbCc"
18+
19+------------------------------------------------------------------------
20+
21+### `++aln`
22+
23+Alphanumeric characters
24+
25+ ++ aln ;~(pose low hig nud) :: alphanumeric
26+
27+Parse alphanumeric characters - both alphabetic characters and numbers.
28+
29+ ~zod/try=> (scan "0" aln)
30+ ~~0
31+ ~zod/try=> (scan "alf42" (star aln))
32+ "alf42"
33+ ~zod/try=> (scan "0123456789abcdef" (star aln))
34+ "0123456789abcdef"
35+
36+------------------------------------------------------------------------
37+
38+### `++alp`
39+
40+Alphanumeric and `-`
41+
42+ ++ alp ;~(pose low hig nud hep) :: alphanumeric and -
43+
44+Parse alphanumeric strings and hep, "-".
45+
46+ ~zod/try=> (scan "7" alp)
47+ ~~7
48+ ~zod/try=> (scan "s" alp)
49+ ~~s
50+ ~zod/try=> (scan "123abc-" (star alp))
51+ "123abc-"
52+
53+------------------------------------------------------------------------
54+
55+### `++bet`
56+
57+Axis syntax `-`, `+`
58+
59+ ++ bet ;~(pose (cold 2 hep) (cold 3 lus)) :: axis syntax - +
60+
61+Parse the hep and lus axis syntax.
62+
63+ ~zod/try=> (scan "-" bet)
64+ 2
65+ ~zod/try=> (scan "+" bet)
66+ 3
67+
68+------------------------------------------------------------------------
69+
70+### `++bin`
71+
72+Binary to atom
73+
74+ ++ bin (bass 2 (most gon but)) :: binary to atom
75+
76+Parse a tape of binary (0s and 1s) and produce its atomic
77+representation.
78+
79+ ~zod/try=> (scan "0000" bin)
80+ 0
81+ ~zod/try=> (scan "0001" bin)
82+ 1
83+ ~zod/try=> (scan "0010" bin)
84+ 2
85+ ~zod/try=> (scan "100000001111" bin)
86+ 2.063
87+
88+------------------------------------------------------------------------
89+
90+### `++but`
91+
92+Binary digit
93+
94+ ++ but (cook |=(a=@ (sub a '0')) (shim '0' '1')) :: binary digit
95+
96+Parse a single binary digit.
97+
98+ ~zod/try=> (scan "0" but)
99+ 0
100+ ~zod/try=> (scan "1" but)
101+ 1
102+ ~zod/try=> (scan "01" but)
103+ ! {1 2}
104+ ! 'syntax-error'
105+ ! exit
106+ ~zod/try=> (scan "01" (star but))
107+ ~[0 1]
108+
109+------------------------------------------------------------------------
110+
111+### `++cit`
112+
113+Octal digit
114+
115+ ++ cit (cook |=(a=@ (sub a '0')) (shim '0' '7')) :: octal digit
116+
117+Parse a single octal digit.
118+
119+ ~zod/try=> (scan "1" cit)
120+ 1
121+ ~zod/try=> (scan "7" cit)
122+ 7
123+ ~zod/try=> (scan "8" cit)
124+ ! {1 1}
125+ ! 'syntax-error'
126+ ! exit
127+ ~zod/try=> (scan "60" (star cit))
128+ ~[6 0]
129+
130+------------------------------------------------------------------------
131+
132+### `++dem`
133+
134+Decimal to atom
135+
136+ ++ dem (bass 10 (most gon dit)) :: decimal to atom
137+
138+Parse a decimal number to an atom.
139+
140+ ~zod/try=> (scan "7" dem)
141+ 7
142+ ~zod/try=> (scan "42" dem)
143+ 42
144+ ~zod/try=> (scan "150000000" dem)
145+ 150.000.000
146+ ~zod/try=> (scan "12456" dem)
147+ 12.456
148+
149+------------------------------------------------------------------------
150+
151+### `++dit`
152+
153+Decimal digit
154+
155+ ++ dit (cook |=(a=@ (sub a '0')) (shim '0' '9')) :: decimal digit
156+
157+Parse a single decimal digit.
158+
159+ ~zod/try=> (scan "7" dit)
160+ 7
161+ ~zod/try=> (scan "42" (star dit))
162+ ~[4 2]
163+ ~zod/try=> (scan "26000" (star dit))
164+ ~[2 6 0 0 0]
165+
166+------------------------------------------------------------------------
167+
168+### `++gul`
169+
170+Axis syntax `<` or `>`
171+
172+ ++ gul ;~(pose (cold 2 gal) (cold 3 gar)) :: axis syntax < >
173+
174+Parse the axis gal and gar axis syntax.
175+
176+ ~zod/try=> (scan "<" gul)
177+ 2
178+ ~zod/try=> (scan ">" gul)
179+ 3
180+
181+------------------------------------------------------------------------
182+
183+### `++gon`
184+
185+Long numbers
186+
187+ ++ gon ;~(pose ;~(plug bas gay fas) (easy ~)) :: long numbers \ /
188+
189+Parse long numbers - Numbers which wrap around the shell with the line
190+break characters bas and fas.
191+
192+ ~zod/try=> (scan "\\/" gon)
193+ [~~~5c. ~ ~~~2f.]
194+ ~zod/try=> (gon [[1 1] "\\/"])
195+ [p=[p=1 q=3] q=[~ u=[p=[~~~5c. ~ ~~~2f.] q=[p=[p=1 q=3] q=""]]]]
196+
197+------------------------------------------------------------------------
198+
199+### `++hex`
200+
201+Hex to atom
202+
203+ ++ hex (bass 16 (most gon hit)) :: hex to atom
204+
205+Parse any hexadecimal number to an atom.
206+
207+ ~zod/try=> (scan "a" hex)
208+ 10
209+ ~zod/try=> (scan "A" hex)
210+ 10
211+ ~zod/try=> (scan "2A" hex)
212+ 42
213+ ~zod/try=> (scan "1ee7" hex)
214+ 7.911
215+ ~zod/try=> (scan "1EE7" hex)
216+ 7.911
217+ ~zod/try=> (scan "1EE7F7" hex)
218+ 2.025.463
219+ ~zod/try=> `@ux`(scan "1EE7F7" hex)
220+ 0x1e.e7f7
221+
222+------------------------------------------------------------------------
223+
224+### `++hig`
225+
226+Uppercase
227+
228+ ++ hig (shim 'A' 'Z') :: uppercase
229+
230+Parse a single uppercase letter.
231+
232+ ~zod/try=> (scan "G" hig)
233+ ~~~47.
234+ ~zod/try=> `cord`(scan "G" hig)
235+ 'G'
236+ ~zod/try=> (scan "ABCDEFGHIJKLMNOPQRSTUVWXYZ" (star hig))
237+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
238+ ~zod/try=> (hig [[1 1] "G"])
239+ [p=[p=1 q=2] q=[~ [p=~~~47. q=[p=[p=1 q=2] q=""]]]]
240+
241+------------------------------------------------------------------------
242+
243+### `++hit`
244+
245+Hex digits
246+
247+ ++ hit ;~ pose :: hex digits
248+ dit
249+ (cook |=(a=char (sub a 87)) (shim 'a' 'f'))
250+ (cook |=(a=char (sub a 55)) (shim 'A' 'F'))
251+ ==
252+
253+Parse a single hexadecimal digit.
254+
255+ ~zod/try=> (scan "a" hit)
256+ 10
257+ ~zod/try=> (scan "A" hit)
258+ 10
259+ ~zod/try=> (hit [[1 1] "a"])
260+ [p=[p=1 q=2] q=[~ [p=10 q=[p=[p=1 q=2] q=""]]]]
261+ ~zod/try=> (scan "2A" (star hit))
262+ ~[2 10]
263+
264+------------------------------------------------------------------------
265+
266+### `++low`
267+
268+Lowercase
269+
270+ ++ low (shim 'a' 'z') :: lowercase
271+
272+Parse a single lowercase letter.
273+
274+ ~zod/try=> (scan "g" low)
275+ ~~g
276+ ~zod/try=> `cord`(scan "g" low)
277+ 'g'
278+ ~zod/try=> (scan "abcdefghijklmnopqrstuvwxyz" (star low))
279+ "abcdefghijklmnopqrstuvwxyz"
280+ ~zod/try=> (low [[1 1] "g"])
281+ [p=[p=1 q=2] q=[~ [p=~~g q=[p=[p=1 q=2] q=""]]]]
282+
283+------------------------------------------------------------------------
284+
285+### `++mes`
286+
287+Hexbyte
288+
289+ ++ mes %+ cook :: hexbyte
290+ |=([a=@ b=@] (add (mul 16 a) b))
291+ ;~(plug hit hit)
292+
293+Parse a hexbyte.
294+
295+ ~zod/try=> (scan "2A" mes)
296+ 42
297+ ~zod/try=> (mes [[1 1] "2A"])
298+ [p=[p=1 q=3] q=[~ u=[p=42 q=[p=[p=1 q=3] q=""]]]]
299+ ~zod/try=> (scan "42" mes)
300+ 66
301+
302+------------------------------------------------------------------------
303+
304+### `++nix`
305+
306+Letters, `-`, and `_`
307+
308+ ++ nix (boss 256 (star ;~(pose aln cab))) ::
309+
310+Letters, `-`, and `_`
311+
312+ ~zod/try=> (scan "as_me" nix)
313+ q=435.626.668.897
314+ ~zod/try=> `@t`(scan "as_me" nix)
315+ 'as_me'
316+
317+------------------------------------------------------------------------
318+
319+### `++nud`
320+
321+Numeric
322+
323+ ++ nud (shim '0' '9') :: numeric
324+
325+Parse a numeric character - A number.
326+
327+ ~zod/try=> (scan "0" nud)
328+ ~~0
329+ ~zod/try=> (scan "7" nud)
330+ ~~7
331+ ~zod/try=> (nud [[1 1] "1"])
332+ [p=[p=1 q=2] q=[~ [p=~~1 q=[p=[p=1 q=2] q=""]]]]
333+ ~zod/try=> (scan "0123456789" (star nud))
334+ "0123456789"
335+
336+------------------------------------------------------------------------
337+
338+### `++prn`
339+
340+Printable character
341+
342+ ++ prn ;~(less (just `@`127) (shim 32 256))
343+
344+Parse any printable character
345+
346+ ~zod/try=> (scan "h" prn)
347+ ~~h
348+ ~zod/try=> (scan "!" prn)
349+ ~~~21.
350+ ~zod/try=> (scan "\01" prn)
351+ ! {1 1}
352+ ! exit
353+
354+------------------------------------------------------------------------
355+
356+### `++qat`
357+
358+Chars in blockcord
359+
360+ ++ qat ;~ pose :: chars in blockcord
361+ prn
362+ ;~(less ;~(plug (just `@`10) soqs) (just `@`10))
363+ ==
364+
365+Parse character in cord block.
366+
367+ ~zod/try=> (scan "h" qat)
368+ ~~h
369+ ~zod/try=> (scan "!" qat)
370+ ~~~21.
371+ ~zod/try=> (scan "\0a" qat)
372+ ~~~a.
373+ ~zod/try=> (scan "\00" qat)
374+ ! {1 1}
375+ ! exit
376+
377+------------------------------------------------------------------------
378+
379+### `++qit`
380+
381+Chars in cord
382+
383+ ++ qit ;~ pose :: chars in a cord
384+ ;~(less bas soq prn)
385+ ;~(pfix bas ;~(pose bas soq mes)) :: escape chars
386+ ==
387+
388+Parse an individual character to its cord atom representation.
389+
390+ ~zod/try=> (scan "%" qit)
391+ 37
392+ ~zod/try=> `@t`(scan "%" qit)
393+ '%'
394+ ~zod/try=> (scan "0" qit)
395+ 48
396+ ~zod/try=> (scan "E" qit)
397+ 69
398+ ~zod/try=> (scan "a" qit)
399+ 97
400+ ~zod/try=> (scan "\\0a" qit)
401+ 10
402+ ~zod/try=> `@ux`(scan "\\0a" qit)
403+ 0xa
404+ ~zod/try=> (scan "cord" (star qit))
405+ ~[99 111 114 100]
406+
407+------------------------------------------------------------------------
408+
409+### `++qut`
410+
411+Cord
412+
413+ ++ qut ;~ pose :: cord
414+ ;~ less soqs
415+ (ifix [soq soq] (boss 256 (more gon qit)))
416+ ==
417+ %- inde %+ ifix
418+ :- ;~ plug soqs
419+ ;~(pose ;~(plug (plus ace) vul) (just '\0a'))
420+ ==
421+ ;~(plug (just '\0a') soqs)
422+ (boss 256 (star qat))
423+ ==
424+ ::
425+
426+Parse single-soq cord with `\{gap}/` anywhere in the middle, or
427+triple-soq cord which must be in an indented block.
428+
429+ ~zod/try=> (scan "'cord'" qut)
430+ q=1.685.221.219
431+ ~zod/try=> 'cord'
432+ 'cord'
433+ ~zod/try=> `@ud`'cord'
434+ 1.685.221.219
435+ /~zod/try=> '''
436+ Heredoc isn't prohibited from containing quotes
437+ '''
438+ 'Heredoc isn't prohibited from containing quotes'
439+
440+------------------------------------------------------------------------
441+
442+### `++soqs`
443+
444+Delimiting `'''`
445+
446+ ++ soqs ;~(plug soq soq soq) :: delimiting '''
447+
448+Triple single quote
449+
450+ ~zod/try=> (scan "'''" soqs)
451+ [~~~27. ~~~27. ~~~27.]
452+ ~zod/try=> (rash '"""' soqs)
453+ ! {1 1}
454+ ! exit
455+
456+------------------------------------------------------------------------
457+
458+### `++sym`
459+
460+Term
461+
462+ ++ sym
463+ %+ cook
464+ |=(a=tape (rap 3 ^-((list ,@) a)))
465+ ;~(plug low (star ;~(pose nud low hep)))
466+ ::
467+
468+A term: a letter(lowercase), followed by letters, numbers, or `-`.
469+
470+ ~zod/try=> (scan "sam-2" sym)
471+ 215.510.507.891
472+ ~zod/try=> `@t`(scan "sam-2" sym)
473+ 'sam-2'
474+ ~zod/try=> (scan "sym" sym)
475+ 7.174.515
476+
477+------------------------------------------------------------------------
478+
479+### `++ven`
480+
481+`+>-` axis syntax
482+
483+ ++ ven ;~ (comp |=([a=@ b=@] (peg a b))) :: +>- axis syntax
484+ bet
485+ =+ hom=`?`|
486+ |= tub=nail
487+ ^- (like axis)
488+ =+ vex=?:(hom (bet tub) (gul tub))
489+ ?~ q.vex
490+ [p.tub [~ 1 tub]]
491+ =+ wag=$(p.tub p.vex, hom !hom, tub q.u.q.vex)
492+ ?> ?=(^ q.wag)
493+ [p.wag [~ (peg p.u.q.vex p.u.q.wag) q.u.q.wag]]
494+ ==
495+
496+Axis syntax parser
497+
498+ ~zod/arvo=/hoon/hoon> (scan "->+" ven)
499+ 11
500+ ~zod/arvo=/hoon/hoon> `@ub`(scan "->+" ven)
501+ 0b1011
502+ ~zod/arvo=/hoon/hoon> (peg (scan "->" ven) (scan "+" ven))
503+ 11
504+ ~zod/arvo=/hoon/hoon> ->+:[[1 2 [3 4]] 5]
505+ [3 4]
506+
507+------------------------------------------------------------------------
508+
509+### `++vit`
510+
511+Base64 digit
512+
513+ ++ vit :: base64 digit
514+ ;~ pose
515+ (cook |=(a=@ (sub a 65)) (shim 'A' 'Z'))
516+ (cook |=(a=@ (sub a 71)) (shim 'a' 'z'))
517+ (cook |=(a=@ (add a 4)) (shim '0' '9'))
518+ (cold 62 (just '-'))
519+ (cold 63 (just '+'))
520+ ==
521+
522+Terran base64
523+
524+ ~zod/arvo=/hoon/hoon> (scan "C" vit)
525+ 2
526+ ~zod/arvo=/hoon/hoon> (scan "c" vit)
527+ 28
528+ ~zod/arvo=/hoon/hoon> (scan "2" vit)
529+ 54
530+ ~zod/arvo=/hoon/hoon> (scan "-" vit)
531+ 62
docs/dev/hoon/library/2ei.mdnew file+107
@@ -0,0 +1,107 @@
1+section 2eI, parsing (external)
2+===============================
3+
4+### `++rash`
5+
6+Parse or crash
7+
8+ ++ rash |*([naf=@ sab=_rule] (scan (trip naf) sab)) ::
9+
10+Parse a cord with a given rule and crash if the cord isn't entirely
11+parsed.
12+
13+`naf` is an [atom]().
14+
15+`sab` is a [rule]().
16+
17+ ~zod/try=> (rash 'I was the world in which I walked, and what I saw' (star (shim 0 200)))
18+ "I was the world in which I walked, and what I saw"
19+ ~zod/try=> (rash 'abc' (just 'a'))
20+ ! {1 2}
21+ ! 'syntax-error'
22+ ! exit
23+ ~zod/try=> (rash 'abc' (jest 'abc'))
24+ 'abc'
25+ `~zod/try=> (rash 'abc' (jest 'ab'))
26+ ! {1 3}
27+ ! 'syntax-error'
28+ ! exit
29+
30+------------------------------------------------------------------------
31+
32+### `++rush`
33+
34+Parse or null
35+
36+ ++ rush |*([naf=@ sab=_rule] (rust (trip naf) sab))
37+
38+Parse a given with a given rule and produce null if the cord isn't
39+entirely parsed.
40+
41+`naf` is an [atom]().
42+
43+`sab` is a [rule]().
44+
45+ ~zod/try=> (rush 'I was the world in which I walked, and what I saw' (star (shim 0 200)))
46+ [~ "I was the world in which I walked, and what I saw"]
47+ ~zod/try=> (rush 'abc' (just 'a'))
48+ ~
49+ ~zod/try=> (rush 'abc' (jest 'abc'))
50+ [~ 'abc']
51+ ~zod/try=> (rush 'abc' (jest 'ac'))
52+ ~
53+ ~zod/try=> (rush 'abc' (jest 'ab'))
54+ ~
55+
56+------------------------------------------------------------------------
57+
58+### `++rust`
59+
60+Parse tape or null
61+
62+ ++ rust |* [los=tape sab=_rule]
63+ =+ vex=((full sab) [[1 1] los])
64+ ?~(q.vex ~ [~ u=p.u.q.vex])
65+
66+Parse a tape with a given rule and produce null if the tape isn't
67+entirely parsed.
68+
69+`los` is a [tape]().
70+
71+`sab` is a [rule]().
72+
73+ ~zod/try=> (rust "I was the world in which I walked, and what I saw" (star (shim 0 200)))
74+ [~ "I was the world in which I walked, and what I saw"]
75+ ~zod/try=> (rust "Or heard or felt came not but from myself;" (star (shim 0 200)))
76+ [~ "Or heard or felt came not but from myself;"]
77+ ~zod/try=> (rust "And there I found myself more truly and more strange." (jest 'And there I'))
78+ ~
79+
80+------------------------------------------------------------------------
81+
82+### `++scan`
83+
84+Parse tape or crash
85+
86+ ++ scan |* [los=tape sab=_rule]
87+ =+ vex=((full sab) [[1 1] los])
88+ ?~ q.vex
89+ ~_ (show [%m '{%d %d}'] p.p.vex q.p.vex ~)
90+ ~|('syntax-error' !!)
91+ p.u.q.vex
92+
93+Parse a tape with a given rule and crash if the tape isn't entirely
94+parsed.
95+
96+`los` is a [tape]().
97+
98+`sab` is a [rule]().
99+
100+ ~zod/try=> (scan "I was the world in which I walked, and what I saw" (star (shim 0 200)))
101+ "I was the world in which I walked, and what I saw"
102+ ~zod/try=> (scan "Or heard or felt came not but from myself;" (star (shim 0 200)))
103+ "Or heard or felt came not but from myself;"
104+ ~zod/try=> (scan "And there I found myself more truly and more strange." (jest 'And there I'))
105+ ! {1 12}
106+ ! 'syntax-error'
107+ ! exit
docs/dev/hoon/library/2ej.mdnew file+561
@@ -0,0 +1,561 @@
1+section 2eJ, formatting (basic text)
2+====================================
3+
4+### `++cass`
5+
6+To lowercase
7+
8+ ++ cass :: lowercase
9+ |= vib=tape
10+ %+ rap 3
11+ (turn vib |=(a=@ ?.(&((gte a 'A') (lte a 'Z')) a (add 32 a))))
12+ ::
13+
14+Produce the case insensitive (all lowercase) cord of a tape.
15+
16+`vib` is a [tape]().
17+
18+ ~zod/try=> (cass "john doe")
19+ 7.309.170.810.699.673.450
20+ ~zod/try=> `cord`(cass "john doe")
21+ 'john doe'
22+ ~zod/try=> (cass "abc, 123, !@#")
23+ 2.792.832.775.110.938.439.066.079.945.313
24+ ~zod/try=> `cord`(cass "abc, 123, !@#")
25+ 'abc, 123, !@#'
26+
27+------------------------------------------------------------------------
28+
29+### `++cuss`
30+
31+To uppercase
32+
33+ ++ cuss :: uppercase
34+ |= vib=tape
35+ ^- @t
36+ %+ rap 3
37+ (turn vib |=(a=@ ?.(&((gte a 'a') (lte a 'z')) a (sub a 32))))
38+ ::
39+
40+Turn all occurances of lowercase letters in any tape into uppercase
41+letters, as a cord.
42+
43+`vib` is a [tape]().
44+
45+ ~zod/try=> (cuss "john doe")
46+ 'JOHN DOE'
47+ ~zod/try=> (cuss "abc ABC 123 !@#")
48+ 'ABC ABC 123 !@#'
49+ ~zod/try=> `@ud`(cuss "abc")
50+ 4.407.873
51+ ~zod/try=> (cuss "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsQqRrVvWwXxYyZz")
52+ 'AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSQQRRVVWWXXYYZZ'
53+
54+------------------------------------------------------------------------
55+
56+### `++crip`
57+
58+Tape to cord
59+
60+ ++ crip |=(a=tape `@t`(rap 3 a)) :: tape to cord
61+
62+Produce cord from a tape.
63+
64+`a` is a [tape]().
65+
66+ ~zod/try=> (crip "john doe")
67+ 'john doe'
68+ ~zod/try=> (crip "abc 123 !@#")
69+ 'abc 123 !@#'
70+ ~zod/try=> `@ud`(crip "abc")
71+ 6.513.249
72+
73+------------------------------------------------------------------------
74+
75+### `++mesc`
76+
77+Escape special chars
78+
79+ ++ mesc :: ctrl code escape
80+ |= vib=tape
81+ ^- tape
82+ ?~ vib
83+ ~
84+ ?: =('\\' i.vib)
85+ ['\\' '\\' $(vib t.vib)]
86+ ?: ?|((gth i.vib 126) (lth i.vib 32) =(39 i.vib))
87+ ['\\' (welp ~(rux at i.vib) '/' $(vib t.vib))]
88+ [i.vib $(vib t.vib)]
89+ ::
90+
91+Escape special characters, used in [`++show`](/doc/hoon/library/2ez#++show)
92+
93+`vib` is a [tape]().
94+
95+ /~zod/try=> (mesc "ham lus")
96+ "ham lus"
97+ /~zod/try=> (mesc "bas\\hur")
98+ "bas\\\\hur"
99+ /~zod/try=> (mesc "as'saß")
100+ "as\0x27/sa\0xc3/\0x9f/"
101+
102+------------------------------------------------------------------------
103+
104+### `++runt`
105+
106+Prepend `n` times
107+
108+ ++ runt :: prepend repeatedly
109+ |= [[a=@ b=@] c=tape]
110+ ^- tape
111+ ?: =(0 a)
112+ c
113+ [b $(a (dec a))]
114+ ::
115+
116+Add `a` repetitions of character `b` to the head of `c`
117+
118+`a` and `b` are [atom]()s.
119+
120+`c` is a [tape]().
121+
122+ /~zod/try=> (runt [2 '/'] "ham")
123+ "//ham"
124+ /~zod/try=> (runt [10 'a'] "")
125+ "aaaaaaaaaa"
126+
127+------------------------------------------------------------------------
128+
129+### `++sand`
130+
131+Soft-cast by odor
132+
133+ ++ sand :: atom sanity
134+ |= a=@ta
135+ |= b=@ ^- (unit ,@)
136+ ?.(((sane a) b) ~ [~ b])
137+ ::
138+
139+Soft-cast validity by odor.
140+
141+`a` is a [`@ta`]().
142+
143+`b` is an [atom]().
144+
145+ /~zod/try=> `(unit ,@ta)`((sand %ta) 'sym-som')
146+ [~ ~.sym-som]
147+ /~zod/try=> `(unit ,@ta)`((sand %ta) 'err!')
148+ ~
149+
150+------------------------------------------------------------------------
151+
152+### `++sane`
153+
154+Check odor validity
155+
156+ ++ sane :: atom sanity
157+ |= a=@ta
158+ |= b=@ ^- ?
159+ ?. =(%t (end 3 1 a))
160+ ~|(%sane-stub !!)
161+ =+ [inx=0 len=(met 3 b)]
162+ ?: =(%tas a)
163+ |- ^- ?
164+ ?: =(inx len) &
165+ =+ cur=(cut 3 [inx 1] b)
166+ ?& ?| &((gte cur 'a') (lte cur 'z'))
167+ &(=('-' cur) !=(0 inx) !=(len inx))
168+ &(&((gte cur '0') (lte cur '9')) !=(0 inx))
169+ ==
170+ $(inx +(inx))
171+ ==
172+ ?: =(%ta a)
173+ |- ^- ?
174+ ?: =(inx len) &
175+ =+ cur=(cut 3 [inx 1] b)
176+ ?& ?| &((gte cur 'a') (lte cur 'z'))
177+ &((gte cur '0') (lte cur '9'))
178+ |(=('-' cur) =('~' cur) =('_' cur) =('.' cur))
179+ ==
180+ $(inx +(inx))
181+ ==
182+ |- ^- ?
183+ ?: =(0 b) &
184+ =+ cur=(end 3 1 b)
185+ ?: &((lth cur 32) !=(10 cur)) |
186+ =+ len=(teff cur)
187+ ?& |(=(1 len) =+(i=1 |-(|(=(i len) &((gte (cut 3 [i 1] b) 128) $(i +(i)))))))
188+ $(b (rsh 3 len b))
189+ ==
190+ ::
191+
192+Check validity by odor. Produces a gate.
193+
194+`a` is a [`@ta`]().
195+
196+`b` is an [atom]().
197+
198+ /~zod/try=> ((sane %tas) %mol)
199+ %.y
200+ /~zod/try=> ((sane %tas) 'lam')
201+ %.y
202+ /~zod/try=> ((sane %tas) 'more ace')
203+ %.n
204+
205+------------------------------------------------------------------------
206+
207+### `++trim`
208+
209+Tape split
210+
211+ ++ trim :: tape split
212+ |= [a=@ b=tape]
213+ ^- [p=tape q=tape]
214+ ?~ b
215+ [~ ~]
216+ ?: =(0 a)
217+ [~ b]
218+ =+ c=$(a (dec a), b t.b)
219+ [[i.b p.c] q.c]
220+ ::
221+
222+Split first `a` characters off tape.
223+
224+`a` is an [atom]().
225+
226+`b` is a [tape]().
227+
228+ /~zod/try=> (trim 5 "lasok termun")
229+ [p="lasok" q=" termun"]
230+ /~zod/try=> (trim 5 "zam")
231+ [p="zam" q=""]
232+
233+------------------------------------------------------------------------
234+
235+### `++trip`
236+
237+Cord to tape
238+
239+ ++ trip :: cord to tape
240+ ~/ %trip
241+ |= a=@ ^- tape
242+ ?: =(0 (met 3 a))
243+ ~
244+ [^-(@ta (end 3 1 a)) $(a (rsh 3 1 a))]
245+ ::
246+
247+Produce tape from cord.
248+
249+`a` is an [atom]().
250+
251+ /~zod/try=> (trip 'john doe')
252+ "john doe"
253+ /~zod/try=> (trip 'abc 123 !@#')
254+ "abc 123 !@#"
255+ /~zod/try=> (trip 'abc')
256+ "abc"
257+
258+------------------------------------------------------------------------
259+
260+### `++teff`
261+
262+UTF8 Length
263+
264+ ++ teff :: length utf8
265+ |= a=@t ^- @
266+ =+ b=(end 3 1 a)
267+ ?: =(0 b)
268+ ?>(=(0 a) 0)
269+ ?> |((gte b 32) =(10 b))
270+ ?:((lte b 127) 1 ?:((lte b 223) 2 ?:((lte b 239) 3 4)))
271+ ::
272+
273+Number of utf8 bytes.
274+
275+`a` is a [`@t`]().
276+
277+ /~zod/try=> (teff 'a')
278+ 1
279+ /~zod/try=> (teff 'ß')
280+ 2
281+
282+------------------------------------------------------------------------
283+
284+### `++turf`
285+
286+UTF8 to UTF32 cord
287+
288+ ++ turf :: utf8 to utf32
289+ |= a=@t
290+ ^- @c
291+ %+ rap 5
292+ |- ^- (list ,@c)
293+ =+ b=(teff a)
294+ ?: =(0 b) ~
295+ :- %+ can 0
296+ %+ turn
297+ ^- (list ,[p=@ q=@])
298+ ?+ b !!
299+ 1 [[0 7] ~]
300+ 2 [[8 6] [0 5] ~]
301+ 3 [[16 6] [8 6] [0 4] ~]
302+ 4 [[24 6] [16 6] [8 6] [0 3] ~]
303+ ==
304+ |=([p=@ q=@] [q (cut 0 [p q] a)])
305+ $(a (rsh 3 b a))
306+ ::
307+
308+Convert utf8 ([cord]()) to utf32 codepoints.
309+
310+`a` is a [`@t`]().
311+
312+ /~zod/try=> (turf 'my ßam')
313+ ~-my.~df.am
314+ /~zod/try=> 'я тут'
315+ 'я тут'
316+ /~zod/try=> (turf 'я тут')
317+ ~-~44f..~442.~443.~442.
318+ /~zod/try=> `@ux`'я тут'
319+ 0x82.d183.d182.d120.8fd1
320+ /~zod/try=> `@ux`(turf 'я тут')
321+ 0x442.0000.0443.0000.0442.0000.0020.0000.044f
322+
323+------------------------------------------------------------------------
324+
325+### `++tuba`
326+
327+UTF8 to UTF32 tape
328+
329+ ++ tuba :: utf8 to utf32 tape
330+ |= a=tape
331+ ^- (list ,@c)
332+ (rip 5 (turf (rap 3 a))) :: XX horrible
333+ ::
334+
335+Convert tape to list of codepoints.
336+
337+`a` is a [tape]()
338+
339+ /~zod/try=> (tuba "я тут")
340+ ~[~-~44f. ~-. ~-~442. ~-~443. ~-~442.]
341+ /~zod/try=> (tuba "chars")
342+ ~[~-c ~-h ~-a ~-r ~-s]
343+
344+------------------------------------------------------------------------
345+
346+### `++tufa`
347+
348+UTF32 to UTF8 tape
349+
350+ ++ tufa :: utf32 to utf8 tape
351+ |= a=(list ,@c)
352+ ^- tape
353+ ?~ a ""
354+ (weld (rip 3 (tuft i.a)) $(a t.a))
355+ ::
356+
357+Wrap list of utf32 codepoints to utf8 [tape]().
358+
359+`a` is a [list]() of [`@c`]().
360+
361+ /~zod/try=> (tufa ~[~-~44f. ~-. ~-~442. ~-~443. ~-~442.])
362+ "я тут"
363+ /~zod/try=> (tufa ((list ,@c) ~[%a %b 0xb1 %c]))
364+ "ab±c"
365+
366+------------------------------------------------------------------------
367+
368+### `++tuft`
369+
370+UTF32 to UTF8 text
371+
372+ ++ tuft :: utf32 to utf8 text
373+ |= a=@c
374+ ^- @t
375+ %+ rap 3
376+ |- ^- (list ,@)
377+ ?: =(0 a)
378+ ~
379+ =+ b=(end 5 1 a)
380+ =+ c=$(a (rsh 5 1 a))
381+ ?: (lth b 0x7f)
382+ [b c]
383+ ?: (lth b 0x7ff)
384+ :* (mix 0b1100.0000 (cut 0 [6 5] b))
385+ (mix 0b1000.0000 (end 0 6 b))
386+ c
387+ ==
388+ ?: (lth b 0xffff)
389+ :* (mix 0b1110.0000 (cut 0 [12 4] b))
390+ (mix 0b1000.0000 (cut 0 [6 6] b))
391+ (mix 0b1000.0000 (end 0 6 b))
392+ c
393+ ==
394+ :* (mix 0b1111.0000 (cut 0 [18 3] b))
395+ (mix 0b1000.0000 (cut 0 [12 6] b))
396+ (mix 0b1000.0000 (cut 0 [6 6] b))
397+ (mix 0b1000.0000 (end 0 6 b))
398+ c
399+ ==
400+ ::
401+
402+Convert utf32 glyph to
403+[LSB](http://en.wikipedia.org/wiki/Least_significant_bit) utf8 cord.
404+
405+`a` is a [`@c`]().
406+
407+ /~zod/try=> (tuft `@c`%a)
408+ 'a'
409+ /~zod/try=> (tuft `@c`0xb6)
410+ '¶'
411+
412+------------------------------------------------------------------------
413+
414+### `++wack`
415+
416+Coin format encode
417+
418+ ++ wack :: coin format
419+ |= a=@ta
420+ ^- @ta
421+ =+ b=(rip 3 a)
422+ %+ rap 3
423+ |- ^- tape
424+ ?~ b
425+ ~
426+ ?: =('~' i.b) ['~' '~' $(b t.b)]
427+ ?: =('_' i.b) ['~' '-' $(b t.b)]
428+ [i.b $(b t.b)]
429+ ::
430+
431+Escape span `~` as `~~` and `_` as `~-`. Used for printing.
432+
433+`a` is a [`@ta`]().
434+
435+ /~zod/try=> (wack '~20_sam~')
436+ ~.~~20~-sam~~
437+ /~zod/try=> `@t`(wack '~20_sam~')
438+ '~~20~-sam~~'
439+ ~zod/try=> ~(rend co %many ~[`ud/5 `ta/'~20_sam'])
440+ "._5_~~.~~20~-sam__"
441+ ~zod/try=> ._5_~~.~~20~-sam__
442+ [5 ~.~20_sam]
443+
444+------------------------------------------------------------------------
445+
446+### `++wick`
447+
448+Coin format decode
449+
450+ ++ wick :: coin format
451+ |= a=@
452+ ^- @ta
453+ =+ b=(rip 3 a)
454+ %+ rap 3
455+ |- ^- tape
456+ ?~ b
457+ ~
458+ ?: =('~' i.b)
459+ ?~ t.b !!
460+ [?:(=('~' i.t.b) '~' ?>(=('-' i.t.b) '_')) $(b t.t.b)]
461+ [i.b $(b t.b)]
462+ ::
463+
464+Unescape span `~~` as `~` and `~-` as `_`.
465+
466+`a` is a an [atom]().
467+
468+ /~zod/try=> `@t`(wick '~-ams~~lop')
469+ '_ams~lop'
470+ /~zod/try=> `@t`(wick (wack '~20_sam~'))
471+ '~20_sam~'
472+
473+------------------------------------------------------------------------
474+
475+### `++woad`
476+
477+Unescape cord
478+
479+ ++ woad :: cord format
480+ |= a=@ta
481+ ^- @t
482+ %+ rap 3
483+ |- ^- (list ,@)
484+ ?: =(0 a)
485+ ~
486+ =+ b=(end 3 1 a)
487+ =+ c=(rsh 3 1 a)
488+ ?: =('.' b)
489+ [' ' $(a c)]
490+ ?. =('~' b)
491+ [b $(a c)]
492+ => .(b (end 3 1 c), c (rsh 3 1 c))
493+ ?+ b =- (weld (rip 3 (tuft p.d)) $(a q.d))
494+ ^= d
495+ =+ d=0
496+ |- ^- [p=@ q=@]
497+ ?: =('.' b)
498+ [d c]
499+ ?< =(0 c)
500+ %= $
501+ b (end 3 1 c)
502+ c (rsh 3 1 c)
503+ d %+ add (mul 16 d)
504+ %+ sub b
505+ ?: &((gte b '0') (lte b '9')) 48
506+ ?>(&((gte b 'a') (lte b 'z')) 87)
507+ ==
508+ %'.' ['.' $(a c)]
509+ %'~' ['~' $(a c)]
510+ ==
511+ ::
512+
513+Unescape cord codepoints.
514+
515+`a` is a [`@ta`]().
516+
517+ /~zod/try=> (woad ~.~b6.20.as)
518+ '¶20 as'
519+
520+------------------------------------------------------------------------
521+
522+### `++wood`
523+
524+Escape cord
525+
526+ ++ wood :: cord format
527+ |= a=@t
528+ ^- @ta
529+ %+ rap 3
530+ |- ^- (list ,@)
531+ ?: =(0 a)
532+ ~
533+ =+ b=(teff a)
534+ =+ c=(turf (end 3 b a))
535+ =+ d=$(a (rsh 3 b a))
536+ ?: ?| &((gte c 'a') (lte c 'z'))
537+ &((gte c '0') (lte c '9'))
538+ =('-' c)
539+ ==
540+ [c d]
541+ ?+ c
542+ :- '~'
543+ =+ e=(met 2 c)
544+ |- ^- tape
545+ ?: =(0 c)
546+ ['.' d]
547+ =. e (dec e)
548+ =+ f=(rsh 2 e c)
549+ [(add ?:((lte f 9) 48 87) f) $(c (end 2 e c))]
550+ ::
551+ %' ' ['.' d]
552+ %'.' ['~' '.' d]
553+ %'~' ['~' '~' d]
554+ ==
555+
556+Escape cord codepoints.
557+
558+`a` is a [`@ta`]().
559+
560+ /~zod/try=> (wood 'my ßam')
561+ ~.my.~df.am
docs/dev/hoon/library/2ek.mdnew file+162
@@ -0,0 +1,162 @@
1+section 2eK, formatting (layout)
2+================================
3+
4+### `++re`
5+
6+Pretty-printing engine
7+
8+ ++ re
9+ |_ tac=tank
10+
11+Pretty-printing engine.
12+
13+`tac` is a [`++tank`](/doc/hoon/library/1#++tank).
14+
15+ /~zod/try=> ~(. re leaf/"ham")
16+ <2.ghl [[%leaf ""] <414.gly 100.xkc 1.ypj %164>]>
17+
18+### `++ram`
19+
20+Flatten to tape
21+
22+ ++ ram
23+ ^- tape
24+ ?- -.tac
25+ %leaf p.tac
26+ %palm ram(tac [%rose [p.p.tac (weld q.p.tac r.p.tac) s.p.tac] q.tac])
27+ %rose
28+ %+ weld
29+ q.p.tac
30+ |- ^- tape
31+ ?~ q.tac
32+ r.p.tac
33+ =+ voz=$(q.tac t.q.tac)
34+ (weld ram(tac i.q.tac) ?~(t.q.tac voz (weld p.p.tac voz)))
35+ ==
36+ ::
37+
38+Flatten tank out into a tape.
39+
40+ /~zod/try=> ~(ram re leaf/"foo")
41+ "foo"
42+ /~zod/try=> ~(ram re rose/["." "(" ")"]^~[leaf/"bar" leaf/"baz" leaf/"bam"])
43+ "(bar.baz.bam)"
44+
45+### `++win`
46+
47+Render at indent
48+
49+ ++ win
50+ |= [tab=@ edg=@]
51+ =+ lug=`wall`~
52+ |^ |- ^- wall
53+ ?- -.tac
54+ %leaf (rig p.tac)
55+ %palm
56+ ?: fit
57+ (rig ram)
58+ ?~ q.tac
59+ (rig q.p.tac)
60+ ?~ t.q.tac
61+ (rig(tab (add 2 tab), lug $(tac i.q.tac)) q.p.tac)
62+ => .(q.tac `(list tank)`q.tac)
63+ =+ lyn=(mul 2 (lent q.tac))
64+ =+ ^= qyr
65+ |- ^- wall
66+ ?~ q.tac
67+ lug
68+ %= ^$
69+ tac i.q.tac
70+ tab (add tab (sub lyn 2))
71+ lug $(q.tac t.q.tac, lyn (sub lyn 2))
72+ ==
73+ (wig(lug qyr) q.p.tac)
74+ ::
75+ %rose
76+ ?: fit
77+ (rig ram)
78+ =+ ^= gyl
79+ |- ^- wall
80+ ?~ q.tac
81+ ?:(=(%$ r.p.tac) lug (rig r.p.tac))
82+ ^$(tac i.q.tac, lug $(q.tac t.q.tac), tab din)
83+ ?: =(%$ q.p.tac)
84+ gyl
85+ (wig(lug gyl) q.p.tac)
86+ ==
87+ ::
88+
89+Render at indent level `tab` and width `edg`.
90+
91+`tab` and `edg` are [atom]()s.
92+
93+ /~zod/try=> (~(win re leaf/"samoltekon-lapdok") 0 20)
94+ <<"samoltekon-lapdok">>
95+ /~zod/try=> (~(win re leaf/"samoltekon-lapdok") 0 10)
96+ <<"\/samolt\/" " ekon-l" " apdok" "\/ \/">>
97+ /~zod/try=> (~(win re rose/["--" "[" "]"]^~[leaf/"1423" leaf/"2316"]) 0 20)
98+ <<"[1423--2316]">>
99+ /~zod/try=> (~(win re rose/["--" "[" "]"]^~[leaf/"1423" leaf/"2316"]) 0 10)
100+ <<"[ 1423" " 2316" "]">>
101+
102+### `++din`
103+
104+ ++ din (mod (add 2 tab) (mul 2 (div edg 3)))
105+
106+XX document
107+
108+### `++fit`
109+
110+Fit on one line test
111+
112+ ++ fit (lte (lent ram) (sub edg tab))
113+
114+Determine whether `tac` fits on one line. Internal to `++win`
115+
116+### `++rig`
117+
118+Wrap in `\/`
119+
120+ ++ rig
121+ |= hom=tape
122+ ^- wall
123+ ?: (lte (lent hom) (sub edg tab))
124+ [(runt [tab ' '] hom) lug]
125+ => .(tab (add tab 2), edg (sub edg 2))
126+ =+ mut=(trim (sub edg tab) hom)
127+ :- (runt [(sub tab 2) ' '] ['\\' '/' (weld p.mut `_hom`['\\' '/' ~])])
128+ => .(hom q.mut)
129+ |-
130+ ?~ hom
131+ :- %+ runt
132+ [(sub tab 2) ' ']
133+ ['\\' '/' (runt [(sub edg tab) ' '] ['\\' '/' ~])]
134+ lug
135+ => .(mut (trim (sub edg tab) hom))
136+ [(runt [tab ' '] p.mut) $(hom q.mut)]
137+ ::
138+
139+Wrap tape in `\/` if it doesn't fit at current indentation. Internal to
140+`++win`
141+
142+### `++wig`
143+
144+`++win` render tape
145+
146+ ++ wig
147+ |= hom=tape
148+ ^- wall
149+ ?~ lug
150+ (rig hom)
151+ =+ lin=(lent hom)
152+ =+ wug=:(add 1 tab lin)
153+ ?. =+ mir=i.lug
154+ |- ?~ mir
155+ |
156+ ?|(=(0 wug) ?&(=(' ' i.mir) $(mir t.mir, wug (dec wug))))
157+ (rig hom) :: ^ XX regular form?
158+ [(runt [tab ' '] (weld hom `tape`[' ' (slag wug i.lug)])) t.lug]
159+ --
160+ --
161+
162+Render tape. Internal to `++win`.
docs/dev/hoon/library/2el.mdnew file+1871
@@ -0,0 +1,1871 @@
1+section 2eL, formatting (path)
2+==============================
3+
4+### `++ab`
5+
6+Primitive parser engine
7+
8+ ++ ab
9+ |%
10+
11+A core containing numeric parser primitives.
12+
13+ ~zod/try=> ab
14+ <36.ecc 414.gly 100.xkc 1.ypj %164>
15+
16+------------------------------------------------------------------------
17+
18+### `++bix`
19+
20+Parse hex pair
21+
22+ ++ bix (bass 16 (stun [2 2] six))
23+
24+Parsing rule. Parses a pair of base-16 digits. Used in escapes.
25+
26+ ~zod/try=> (scan "07" bix:ab)
27+ q=7
28+ ~zod/try=> (scan "51" bix:ab)
29+ q=81
30+ ~zod/try=> (scan "a3" bix:ab)
31+ q=163
32+
33+------------------------------------------------------------------------
34+
35+### `++hif`
36+
37+Parse phonetic pair
38+
39+ ++ hif (boss 256 ;~(plug tip tiq (easy ~)))
40+
41+Parsing rule. Parses an atom of odor [`@pE`](), a phrase of two bytes
42+encoded phonetically.
43+
44+ ~zod/try=> (scan "doznec" hif:ab)
45+ q=256
46+ ~zod/try=> (scan "pittyp" hif:ab)
47+ q=48.626
48+
49+------------------------------------------------------------------------
50+
51+### `++huf`
52+
53+Parse two phonetic pairs
54+
55+ ++ huf %+ cook
56+ |=([a=@ b=@] (wred:un ~(zug mu ~(zag mu [a b]))))
57+ ;~(plug hif ;~(pfix hep hif))
58+
59+Parsing rule. Parses and unscrambles an atom of odor [@pF](), a phrase
60+of two two-byte pairs that are encoded (and scrambled) phonetically.
61+
62+ ~zod/try=> (scan "pittyp-pittyp" huf:ab)
63+ 328.203.557
64+ ~zod/try=> (scan "tasfyn-partyv" huf:ab)
65+ 65.792
66+ ~zod/try=> `@ux`(scan "tasfyn-partyv" huf:ab)
67+ 0x1.0100
68+
69+------------------------------------------------------------------------
70+
71+### `++hyf`
72+
73+Parse 8 phonetic bytes
74+
75+ ++ hyf (bass 0x1.0000.0000 ;~(plug huf ;~(pfix hep huf) (easy ~)))
76+
77+Parsing rule. Parses an atom of odor [@pG](), a phrase of eight of
78+phonetic bytes.
79+
80+ ~zod/try=> (scan "sondel-forsut-tillyn-nillyt" hyf:ab)
81+ q=365.637.097.828.335.095
82+ ~zod/try=> `@u`~sondel-forsut-tillyn-nillyt
83+ 365.637.097.828.335.095
84+
85+------------------------------------------------------------------------
86+
87+### `++pev`
88+
89+Parse \<= 5 base-32
90+
91+ ++ pev (bass 32 ;~(plug sev (stun [0 4] siv)))
92+
93+Parsing rule. Parses up to five base-32 digits without a leading zero.
94+
95+ ~zod/try=> (scan "a" pev:ab)
96+ q=10
97+ ~zod/try=> (scan "290j" pev:ab)
98+ q=74.771
99+ ~zod/try=> (scan "123456" pev:ab)
100+ ! {1 6}
101+ ! exit
102+ ~zod/try=> (scan "090j" pev:ab)
103+ ~ <syntax error at [1 11]>
104+
105+------------------------------------------------------------------------
106+
107+### `++pew`
108+
109+Parse \<= 5 base-64
110+
111+ ++ pew (bass 64 ;~(plug sew (stun [0 4] siw)))
112+
113+Parsing rule. Parses up to five base-64 digits without a leading zero.
114+
115+ ~zod/try=> (scan "Q" pew:ab)
116+ q=52
117+ ~zod/try=> (scan "aQ~9" pew:ab)
118+ q=2.838.473
119+ ~zod/try=> `@`0waQ~9
120+ 2.838.473
121+ ~zod/try=> (scan "123456" pew:ab)
122+ ! {1 6}
123+ ! exit
124+ ~zod/try=> (scan "012345" pew:ab)
125+ ! {1 1}
126+ ! exit
127+
128+------------------------------------------------------------------------
129+
130+### `++piv`
131+
132+Parse 5 base-32
133+
134+ ++ piv (bass 32 (stun [5 5] siv))
135+
136+Parsing rule. Parses exactly five base-32 digits.
137+
138+ ~zod/try=> (scan "10b3l" piv:ab)
139+ q=1.059.957
140+ ~zod/try=> (scan "1" piv:ab)
141+ ! {1 2}
142+ ! exit
143+
144+------------------------------------------------------------------------
145+
146+### `++piw`
147+
148+Parse 5 base-64
149+
150+ ++ piw (bass 64 (stun [5 5] siw))
151+
152+Parsing rule. Parses exactly five base-64 digits.
153+
154+ ~zod/try=> (scan "2C-pZ" piw:ab)
155+ q=43.771.517
156+ ~zod/try=> (scan "2" piv:ab)
157+ ! {1 2}
158+ ! exit
159+
160+------------------------------------------------------------------------
161+
162+### `++qeb`
163+
164+Parse \<= 4 binary
165+
166+ ++ qeb (bass 2 ;~(plug seb (stun [0 3] sib)))
167+
168+Parsing rule. Parses a binary number of up to 4 digits in length without
169+a leading zero.
170+
171+ ~zod/try=> (scan "1" qeb:ab)
172+ q=1
173+ ~zod/try=> (scan "101" qeb:ab)
174+ q=5
175+ ~zod/try=> (scan "1111" qeb:ab)
176+ q=15
177+ ~zod/try=> (scan "11111" qeb:ab)
178+ ! {1 5}
179+ ! exit
180+ ~zod/try=> (scan "01" qeb:ab)
181+ ! {1 1}
182+ ! exit
183+
184+------------------------------------------------------------------------
185+
186+### `++qex`
187+
188+Parse \<= 4 hex
189+
190+ ++ qex (bass 16 ;~(plug sex (stun [0 3] hit)))
191+
192+Parsing rule. Parses a hexadecimal number of up to 4 digits in length
193+without a leading zero.
194+
195+ ~zod/try=> (scan "ca" qex:ab)
196+ q=202
197+ ~zod/try=> (scan "18ac" qex:ab)
198+ q=6.316
199+ ~zod/try=> (scan "18acc" qex:ab)
200+ ! {1 5}
201+ ! exit
202+ ~zod/try=> (scan "08ac" qex:ab)
203+ ! {1 1}
204+ ! exit
205+
206+------------------------------------------------------------------------
207+
208+### `++qib`
209+
210+Parse 4 binary
211+
212+ ++ qib (bass 2 (stun [4 4] sib))
213+
214+Parsing rule. Parses exactly four binary digits.
215+
216+ ~zod/try=> (scan "0001" qib:ab)
217+ q=1
218+ ~zod/try=> (scan "0100" qib:ab)
219+ q=4
220+ ~zod/try=> (scan "110" qib:ab)
221+ ! {1 4}
222+ ! exit
223+
224+------------------------------------------------------------------------
225+
226+### `++qix`
227+
228+Parse 4 hex
229+
230+ ++ qix (bass 16 (stun [4 4] six))
231+
232+Parsing rule. Parses exactly four hexadecimal digits.
233+
234+ ~zod/try=> (scan "0100" qix:ab)
235+ q=256
236+ ~zod/try=> (scan "10ff" qix:ab)
237+ q=4.351
238+ ~zod/try=> (scan "0" qix:ab)
239+ ! {1 2}
240+ ! exit
241+
242+------------------------------------------------------------------------
243+
244+### `++seb`
245+
246+Parse 1
247+
248+ ++ seb (cold 1 (just '1'))
249+
250+Parsing rule. Parses the number 1.
251+
252+ ~zod/try=> (scan "1" seb:ab)
253+ 1
254+ ~zod/try=> (scan "0" seb:ab)
255+ ! ~zod/try/~2014.10.23..22.34.21..bfdd/:<[1 1].[1 18]>
256+ ! {1 1}
257+ ~zod/try=> (scan "2" seb:ab)
258+ ! ~zod/try/~2014.10.23..22.34.29..d399/:<[1 1].[1 18]>
259+ ! {1 1}
260+
261+------------------------------------------------------------------------
262+
263+### `++sed`
264+
265+Parse decimal
266+
267+ ++ sed (cook |=(a=@ (sub a '0')) (shim '1' '9'))
268+
269+Parsing rule. Parses a nonzero decimal digit.
270+
271+ ~zod/try=> (scan "5" sed:ab)
272+ 5
273+ ~zod/try=> (scan "0" sed:ab)
274+ ! {1 1}
275+ ! exit
276+
277+------------------------------------------------------------------------
278+
279+### `++sev`
280+
281+Parse base-32
282+
283+ ++ sev ;~(pose sed sov)
284+
285+Parsing rule. Parses a nonzero base-32 digit
286+
287+ ~zod/try=> (scan "c" sev:ab)
288+ 12
289+ ~zod/socialnet=> (scan "0" sev:ab)
290+ ! {1 1}
291+ ! exit
292+
293+------------------------------------------------------------------------
294+
295+### `++sew`
296+
297+Parse base-64
298+
299+ ++ sew ;~(pose sed sow)
300+
301+Parsing rule. Parses a nonzero base-64 digit
302+
303+ ~zod/try=> (scan "M" sew:ab)
304+ 48
305+ ~zod/try=> (scan "0" sew:ab)
306+ ! {1 1}
307+ ! exit
308+
309+------------------------------------------------------------------------
310+
311+### `++sex`
312+
313+Parse hex
314+
315+ ++ sex ;~(pose sed sox)
316+
317+Parsing rule. Parses a nonzero hexadecimal digit.
318+
319+ ~zod/try=> (scan "e" sex:ab)
320+ 14
321+ ~zod/try=> (scan "0" sex:ab)
322+ ! {1 1}
323+ ! exit
324+
325+------------------------------------------------------------------------
326+
327+### `++sib`
328+
329+Parse binary
330+
331+ ++ sib (cook |=(a=@ (sub a '0')) (shim '0' '1'))
332+
333+Parsing rule. Parses a binary digit.
334+
335+ ~zod/try=> (scan "1" sib:ab)
336+ 1
337+ ~zod/socialnet=> (scan "0" sib:ab)
338+ 0
339+
340+------------------------------------------------------------------------
341+
342+### `++sid`
343+
344+Parse decimal
345+
346+ ++ sid (cook |=(a=@ (sub a '0')) (shim '0' '9'))
347+
348+Parsing rule. Parses a decimal digit.
349+
350+ ~zod/try=> (scan "5" sid:ab)
351+ 5
352+
353+------------------------------------------------------------------------
354+
355+### `++siv`
356+
357+Parse base-32
358+
359+ ++ siv ;~(pose sid sov)
360+
361+Parsing rule. Parses a base-32 digit.
362+
363+ ~zod/try=> (scan "c" siv:ab)
364+ 12
365+
366+------------------------------------------------------------------------
367+
368+### `++siw`
369+
370+Parse base-64
371+
372+ ++ siw ;~(pose sid sow)
373+
374+Parsing rule. Parses a base-64 digit.
375+
376+ ~zod/try=> (scan "M" siw:ab)
377+ 48
378+
379+------------------------------------------------------------------------
380+
381+### `++six`
382+
383+Parse hex
384+
385+ ++ six ;~(pose sid sox)
386+
387+Parsing rule. Parses a hexadecimal digit.
388+
389+ ~zod/try=> (scan "e" six:ab)
390+ 14
391+
392+------------------------------------------------------------------------
393+
394+### `++sov`
395+
396+Parse base-32
397+
398+ ++ sov (cook |=(a=@ (sub a 87)) (shim 'a' 'v'))
399+
400+Parsing rule. Parses a base-32 letter.
401+
402+ ~zod/try=> (scan "c" sov:ab)
403+ 12
404+
405+------------------------------------------------------------------------
406+
407+### `++sow`
408+
409+Parse base-64
410+
411+ ++ sow ;~ pose
412+ (cook |=(a=@ (sub a 87)) (shim 'a' 'z'))
413+ (cook |=(a=@ (sub a 29)) (shim 'A' 'Z'))
414+ (cold 62 (just '-'))
415+ (cold 63 (just '~'))
416+ ==
417+
418+Parsing rule. Parses a base-64 letter/symbol.
419+
420+ ~zod/try=> (scan "M" sow:ab)
421+ 48
422+
423+------------------------------------------------------------------------
424+
425+### `++sox`
426+
427+Parse hex letter
428+
429+ ++ sox (cook |=(a=@ (sub a 87)) (shim 'a' 'f'))
430+
431+Parsing rule. Parses a hexadecimal letter.
432+
433+ ~zod/try=> (scan "e" sox:ab)
434+ 14
435+
436+------------------------------------------------------------------------
437+
438+### `++ted`
439+
440+Parse \<= 3 decimal
441+
442+ ++ ted (bass 10 ;~(plug sed (stun [0 2] sid)))
443+
444+Parsing rule. Parses a decimal number of up to 3 digits without a
445+leading zero.
446+
447+ ~zod/try=> (scan "21" ted:ab)
448+ q=21
449+ ~zod/try=> (scan "214" ted:ab)
450+ q=214
451+ ~zod/try=> (scan "2140" ted:ab)
452+ {1 4}
453+ ~zod/try=> (scan "0" ted:ab)
454+ ! {1 1}
455+ ! exit
456+
457+------------------------------------------------------------------------
458+
459+### `++tip`
460+
461+Leading phonetic byte
462+
463+ ++ tip (sear |=(a=@ (ins:po a)) til)
464+
465+Parsing rule. Parses the leading phonetic byte, which represents a
466+syllable.
467+
468+ ~zod/try=> (scan "doz" tip:ab)
469+ 0
470+ ~zod/try=> (scan "pit" tip:ab)
471+ 242
472+
473+------------------------------------------------------------------------
474+
475+### `++tiq`
476+
477+Trailing phonetic syllable
478+
479+ ++ tiq (sear |=(a=@ (ind:po a)) til)
480+
481+Parsing rule. Parses the trailing phonetic byte, which represents a
482+syllable.
483+
484+ ~zod/try=> (scan "zod" tiq:ab)
485+ 0
486+ ~zod/try=> (scan "nec" tiq:ab)
487+ 1
488+
489+------------------------------------------------------------------------
490+
491+### `++tid`
492+
493+Parse 3 decimal digits
494+
495+ ++ tid (bass 10 (stun [3 3] sid))
496+
497+Parsing rule. Parses exactly three decimal digits.
498+
499+ ~zod/try=> (scan "013" tid:ab)
500+ q=13
501+ ~zod/try=> (scan "01" tid:ab)
502+ ! {1 3}
503+ ! exit
504+
505+------------------------------------------------------------------------
506+
507+### `++til`
508+
509+Parse 3 lowercase
510+
511+ ++ til (boss 256 (stun [3 3] low))
512+
513+Parsing rule. Parses exactly three lowercase letters.
514+
515+ ~zod/try=> (scan "mer" til:ab)
516+ q=7.497.069
517+ ~zod/try=> `@t`(scan "mer" til:ab)
518+ 'mer'
519+ ~zod/try=> (scan "me" til:ab)
520+ ! {1 3}
521+ ! exit
522+
523+------------------------------------------------------------------------
524+
525+### `++urs`
526+
527+Parse span characters
528+
529+ ++ urs %+ cook
530+ |=(a=tape (rap 3 ^-((list ,@) a)))
531+ (star ;~(pose nud low hep dot sig cab))
532+
533+Parsing rule. Parses characters from an atom of the span odor [`@ta`]().
534+
535+ ~zod/try=> `@ta`(scan "asa-lom_tak" urs:ab)
536+ ~.asa-lom_tak
537+ ~zod/try=> `@t`(scan "asa-lom_tak" urs:ab)
538+ 'asa-lom_tak'
539+
540+------------------------------------------------------------------------
541+
542+### `++urt`
543+
544+Parse non-`_` span
545+
546+ ++ urt %+ cook
547+ |=(a=tape (rap 3 ^-((list ,@) a)))
548+ (star ;~(pose nud low hep dot sig))
549+
550+Parsing rule. Parses all characters of the span odor [`@ta`]() except
551+for cab, `_`.
552+
553+ ~zod/try=> `@t`(scan "asa-lom.t0k" urt:ab)
554+ 'asa-lom.t0k'
555+
556+------------------------------------------------------------------------
557+
558+### `++voy`
559+
560+Parse bas, soq, or bix
561+
562+ ++ voy ;~(pfix bas ;~(pose bas soq bix))
563+
564+Parsing rule. Parses an escaped backslash, single quote, or hex pair
565+byte.
566+
567+ ~zod/try=> (scan "\\0a" voy:ab)
568+ q=10
569+ ~zod/try=> (scan "\\'" voy:ab)
570+ q=39
571+
572+------------------------------------------------------------------------
573+
574+### `++ag`
575+
576+Top-level atom parser engine
577+
578+ ++ ag
579+ |%
580+
581+A core containing top-level atom parsers.
582+
583+ ~zod/try=> ag
584+ <14.vpu 414.mof 100.xkc 1.ypj %164>
585+
586+------------------------------------------------------------------------
587+
588+### `++ape`
589+
590+Parse 0 or rule
591+
592+ ++ ape |*(fel=_rule ;~(pose (cold 0 (just '0')) fel))
593+
594+Parser modifier. Parses 0 or the sample rule `fel`.
595+
596+`fel` is a [`rule`]().
597+
598+ ~zod/try=> (scan "202" (star (ape:ag (cold 2 (just '2')))))
599+ ~[2 0 2]
600+
601+------------------------------------------------------------------------
602+
603+### `++bay`
604+
605+Parses binary number
606+
607+ ++ bay (ape (bass 16 ;~(plug qeb:ab (star ;~(pfix dog qib:ab)))))
608+
609+Parsing rule. Parses a binary number without a leading zero.
610+
611+ ~zod/try=> (scan "10.0110" bay:ag)
612+ q=38
613+
614+------------------------------------------------------------------------
615+
616+### `++bip`
617+
618+Parse IPv6
619+
620+ ++ bip =+ tod=(ape qex:ab)
621+ (bass 0x1.0000 ;~(plug tod (stun [7 7] ;~(pfix dog tod))))
622+
623+Parsing rule. Parses a [`@is`](), an IPv6 address.
624+
625+ ~zod/try=> (scan "0.0.ea.3e6c.0.0.0.0" bip:ag)
626+ q=283.183.420.760.121.105.516.068.864
627+ ~zod/try=> `@is`(scan "0.0.ea.3e6c.0.0.0.0" bip:ag)
628+ .0.0.ea.3e6c.0.0.0.0
629+
630+------------------------------------------------------------------------
631+
632+### `++dem`
633+
634+Parse decimal with dots
635+
636+ ++ dem (ape (bass 1.000 ;~(plug ted:ab (star ;~(pfix dog tid:ab)))))
637+
638+Parsing rule. Parses a decimal number that includes dot separators.
639+
640+ ~zod/try=> (scan "52" dem:ag)
641+ q=52
642+ ~zod/try=> (scan "13.507" dem:ag)
643+ q=13.507
644+
645+------------------------------------------------------------------------
646+
647+### `++dim`
648+
649+Parse decimal number
650+
651+ ++ dim (ape (bass 10 ;~(plug sed:ab (star sid:ab))))
652+
653+Parsing rule. Parses a decimal number without a leading zero.
654+
655+ ~zod/try=> (scan "52" dim:ag)
656+ q=52
657+ ~zod/try=> (scan "013507" dim:ag)
658+ ! {1 2}
659+ ! exit
660+
661+------------------------------------------------------------------------
662+
663+### `++dum`
664+
665+Parse decimal with leading `0`
666+
667+ ++ dum (bass 10 (plus sid:ab))
668+
669+Parsing rule. Parses a decmial number with leading zeroes.
670+
671+ ~zod/try=> (scan "52" dum:ag)
672+ q=52
673+ ~zod/try=> (scan "0000052" dum:ag)
674+ q=52
675+ ~zod/try=> (scan "13507" dim:ag)
676+ q=13.507
677+
678+------------------------------------------------------------------------
679+
680+### `++fed`
681+
682+Parse phonetic base
683+
684+ ++ fed ;~ pose
685+ (bass 0x1.0000.0000.0000.0000 (most doh hyf:ab))
686+ huf:ab
687+ hif:ab
688+ tiq:ab
689+ ==
690+
691+Parsing rule. Parses an atom of odor [`@p`](), the phonetic base.
692+
693+ ~zod/try=> (scan "zod" fed:ag)
694+ 0
695+ ~zod/try=> (scan "nec" fed:ag)
696+ 1
697+ ~zod/try=> (scan "sondel" fed:ag)
698+ 9.636
699+ ~zod/try=> ~tillyn-nillyt
700+ ~tillyn-nillyt
701+ ~zod/try=> (scan "tillyn-nillyt" fed:ag)
702+ 3.569.565.175
703+ ~zod/try=> (scan "tillyn-nillyt-tasfyn-partyv" fed:ag)
704+ 15.331.165.687.565.582.592
705+ ~zod/try=> (scan "tillyn-nillyt-tasfyn-partyv--novweb-talrud-talmud-sonfyr" fed:ag)
706+ 282.810.089.790.159.633.869.501.053.313.363.681.181
707+
708+------------------------------------------------------------------------
709+
710+### `++hex`
711+
712+Parse hex
713+
714+ ++ hex (ape (bass 0x1.0000 ;~(plug qex:ab (star ;~(pfix dog qix:ab)))))
715+
716+Parsing rule. Parses a hexadecimal number
717+
718+ ~zod/try=> (scan "4" hex:ag)
719+ q=4
720+ ~zod/try=> (scan "1a" hex:ag)
721+ q=26
722+ ~zod/try=> (scan "3.ac8d" hex:ag)
723+ q=240.781
724+ ~zod/try=> `@ux`(scan "3.ac8d" hex:ag)
725+ 0x3.ac8d
726+
727+------------------------------------------------------------------------
728+
729+### `++lip`
730+
731+Parse IPv4 address
732+
733+ ++ lip =+ tod=(ape ted:ab)
734+ (bass 256 ;~(plug tod (stun [3 3] ;~(pfix dog tod))))
735+
736+Parsing rule. Parses an IPv4 address.
737+
738+ ~zod/try=> (scan "127.0.0.1" lip:ag)
739+ q=2.130.706.433
740+ ~zod/try=> `@if`(scan "127.0.0.1" lip:ag)
741+ .127.0.0.1
742+ ~zod/try=> `@if`(scan "8.8.8.8" lip:ag)
743+ .8.8.8.8
744+
745+------------------------------------------------------------------------
746+
747+### `++viz`
748+
749+Parse Base-32 with dots
750+
751+ ++ viz (ape (bass 0x200.0000 ;~(plug pev:ab (star ;~(pfix dog piv:ab)))))
752+
753+Parsing rule. Parses a Base-32 number with dot separators.
754+
755+ ~zod/try=> (scan "e2.ol4pm" viz:ag)
756+ q=15.125.353.270
757+
758+------------------------------------------------------------------------
759+
760+### `++vum`
761+
762+Parse base-32 string
763+
764+ ++ vum (bass 32 (plus siv:ab))
765+
766+Parsing rule. Parses a raw base-32 string.
767+
768+ ~zod/try=> (scan "e2ol4pm" vum:ag)
769+ q=15.125.353.270
770+
771+------------------------------------------------------------------------
772+
773+### `++wiz`
774+
775+Parse base-64
776+
777+ ++ wiz (ape (bass 0x4000.0000 ;~(plug pew:ab (star ;~(pfix dog piw:ab)))))
778+ --
779+ ::
780+
781+Parsing rule. Parses a base-64 number.
782+
783+ ~zod/try=> (scan "e2O.l4Xpm" wiz:ag)
784+ q=61.764.130.813.526
785+
786+------------------------------------------------------------------------
787+
788+### `++co`
789+
790+Literal rendering engine
791+
792+ ++ co
793+ =< |_ lot=coin
794+
795+A [door]() that contains arms that operate on the sample coin `lot`.
796+
797+`lot` is a [`++coin`]().
798+
799+ ~zod/try=> ~(. co many/~[`ta/'mo' `ud/5])
800+ < 3.dhd
801+ [ [ %many
802+ [%~ %ta @t]
803+ [%~ %ud @ud]
804+ %~
805+ ]
806+ <10.utz 3.zid [rex="" <414.hmb 100.xkc 1.ypj %164>]>
807+ ]
808+ >
809+
810+------------------------------------------------------------------------
811+
812+### `++rear`
813+
814+Prepend & render as tape
815+
816+ ++ rear |=(rom=tape =>(.(rex rom) rend))
817+
818+Renders a coin `lot` as a [tape]() prepended to the sample tape `rom`.
819+
820+`rom` is a [`pe`]()
821+
822+`lot` is a [`++coin`]().
823+
824+ ~zod/try=> (~(rear co %$ %ux 200) "--ha")
825+ "0xc8--ha"
826+
827+------------------------------------------------------------------------
828+
829+### `++rent`
830+
831+Render as span
832+
833+ ++ rent `@ta`(rap 3 rend)
834+
835+Renders a coin `lot` as a span.
836+
837+`lot` is a [`++coin`]().
838+
839+ ~zod/try=> ~(rent co %$ %ux 200)
840+ ~.0xc8
841+ ~zod/try=> `@t`~(rent co %$ %ux 200)
842+ '0xc8'
843+
844+------------------------------------------------------------------------
845+
846+### `++rend`
847+
848+Render as tape
849+
850+ ++ rend
851+ ^- tape
852+ ?: ?=(%blob -.lot)
853+ ['~' '0' ((v-co 1) (jam p.lot))]
854+ ?: ?=(%many -.lot)
855+ :- '.'
856+ |- ^- tape
857+ ?~ p.lot
858+ ['_' '_' rex]
859+ ['_' (weld (trip (wack rent(lot i.p.lot))) $(p.lot t.p.lot))]
860+ =+ [yed=(end 3 1 p.p.lot) hay=(cut 3 [1 1] p.p.lot)]
861+ |- ^- tape
862+ ?+ yed (z-co q.p.lot)
863+ %c ['~' '-' (weld (rip 3 (wood (tuft q.p.lot))) rex)]
864+ %d
865+ ?+ hay (z-co q.p.lot)
866+ %a
867+ =+ yod=(yore q.p.lot)
868+ => ^+(. .(rex ?~(f.t.yod rex ['.' (s-co f.t.yod)])))
869+ => ^+ .
870+ %= .
871+ rex
872+ ?: &(=(~ f.t.yod) =(0 h.t.yod) =(0 m.t.yod) =(0 s.t.yod))
873+ rex
874+ => .(rex ['.' (y-co s.t.yod)])
875+ => .(rex ['.' (y-co m.t.yod)])
876+ ['.' '.' (y-co h.t.yod)]
877+ ==
878+ => .(rex ['.' (a-co d.t.yod)])
879+ => .(rex ['.' (a-co m.yod)])
880+ => .(rex ?:(a.yod rex ['-' rex]))
881+ ['~' (a-co y.yod)]
882+ ::
883+ %r
884+ =+ yug=(yell q.p.lot)
885+ => ^+(. .(rex ?~(f.yug rex ['.' (s-co f.yug)])))
886+ :- '~'
887+ ?: &(=(0 d.yug) =(0 m.yug) =(0 h.yug) =(0 s.yug))
888+ ['.' 's' '0' rex]
889+ => ^+(. ?:(=(0 s.yug) . .(rex ['.' 's' (a-co s.yug)])))
890+ => ^+(. ?:(=(0 m.yug) . .(rex ['.' 'm' (a-co m.yug)])))
891+ => ^+(. ?:(=(0 h.yug) . .(rex ['.' 'h' (a-co h.yug)])))
892+ => ^+(. ?:(=(0 d.yug) . .(rex ['.' 'd' (a-co d.yug)])))
893+ +.rex
894+ ==
895+ ::
896+ %f
897+ ?: =(& q.p.lot)
898+ ['.' 'y' rex]
899+ ?:(=(| q.p.lot) ['.' 'n' rex] (z-co q.p.lot))
900+ ::
901+ %n ['~' rex]
902+ %i
903+ ?+ hay (z-co q.p.lot)
904+ %f ((ro-co [3 10 4] |=(a=@ ~(d ne a))) q.p.lot)
905+ %s ((ro-co [4 16 8] |=(a=@ ~(x ne a))) q.p.lot)
906+ ==
907+ ::
908+ %p
909+ =+ dyx=(met 3 q.p.lot)
910+ :- '~'
911+ ?: (lte dyx 1)
912+ (weld (trip (tod:po q.p.lot)) rex)
913+ ?: =(2 dyx)
914+ ;: weld
915+ (trip (tos:po (end 3 1 q.p.lot)))
916+ (trip (tod:po (rsh 3 1 q.p.lot)))
917+ rex
918+ ==
919+ =+ [dyz=(met 5 q.p.lot) fin=|]
920+ |- ^- tape
921+ ?: =(0 dyz)
922+ rex
923+ %= $
924+ fin &
925+ dyz (dec dyz)
926+ q.p.lot (rsh 5 1 q.p.lot)
927+ rex
928+ =+ syb=(wren:un (end 5 1 q.p.lot))
929+ =+ cog=~(zig mu [(rsh 4 1 syb) (end 4 1 syb)])
930+ ;: weld
931+ (trip (tos:po (end 3 1 p.cog)))
932+ (trip (tod:po (rsh 3 1 p.cog)))
933+ `tape`['-' ~]
934+ (trip (tos:po (end 3 1 q.cog)))
935+ (trip (tod:po (rsh 3 1 q.cog)))
936+ `tape`?:(fin ['-' ?:(=(1 (end 0 1 dyz)) ~ ['-' ~])] ~)
937+ rex
938+ ==
939+ ==
940+ ::
941+ %r
942+ ?+ hay (z-co q.p.lot)
943+ %d
944+ =+ r=(rlyd q.p.lot)
945+ ?~ e.r
946+ ['.' '~' (r-co r)]
947+ ['.' '~' u.e.r]
948+ %h ['.' '~' '~' (r-co (rlyh q.p.lot))]
949+ %q ['.' '~' '~' '~' (r-co (rlyq q.p.lot))]
950+ %s ['.' (r-co (rlys q.p.lot))]
951+ ==
952+ ::
953+ %u
954+ =- (weld p.gam ?:(=(0 q.p.lot) `tape`['0' ~] q.gam))
955+ ^= gam ^- [p=tape q=tape]
956+ ?+ hay [~ ((ox-co [10 3] |=(a=@ ~(d ne a))) q.p.lot)]
957+ %b [['0' 'b' ~] ((ox-co [2 4] |=(a=@ ~(d ne a))) q.p.lot)]
958+ %i [['0' 'i' ~] ((d-co 1) q.p.lot)]
959+ %x [['0' 'x' ~] ((ox-co [16 4] |=(a=@ ~(x ne a))) q.p.lot)]
960+ %v [['0' 'v' ~] ((ox-co [32 5] |=(a=@ ~(x ne a))) q.p.lot)]
961+ %w [['0' 'w' ~] ((ox-co [64 5] |=(a=@ ~(w ne a))) q.p.lot)]
962+ ==
963+ ::
964+ %s
965+ %+ weld
966+ ?:((syn:si q.p.lot) "--" "-")
967+ $(yed 'u', q.p.lot (abs:si q.p.lot))
968+ ::
969+ %t
970+ ?: =('a' hay)
971+ ?: =('s' (cut 3 [2 1] p.p.lot))
972+
973+ (weld (rip 3 q.p.lot) rex)
974+ ['~' '.' (weld (rip 3 q.p.lot) rex)]
975+ ['~' '~' (weld (rip 3 (wood q.p.lot)) rex)]
976+ ==
977+ --
978+ =+ rex=*tape
979+ =< |%
980+ ++ a-co |=(dat=@ ((d-co 1) dat))
981+ ++ d-co |=(min=@ (em-co [10 min] |=([? b=@ c=tape] [~(d ne b) c])))
982+ ++ r-co
983+ |= [syn=? nub=@ der=@ ign=(unit tape) ne=?]
984+ => .(rex ['.' (t-co ((d-co 1) der) ne)])
985+ => .(rex ((d-co 1) nub))
986+ ?:(syn rex ['-' rex])
987+ ++ t-co |= [a=tape n=?] ^- tape
988+ ?: n a
989+ ?~ a ~|(%empty-frac !!) t.a
990+ ::
991+ ++ s-co
992+ |= esc=(list ,@) ^- tape
993+ ~| [%so-co esc]
994+ ?~ esc
995+ rex
996+ :- '.'
997+ =>(.(rex $(esc t.esc)) ((x-co 4) i.esc))
998+
999+ ::
1000+ ++ v-co |=(min=@ (em-co [32 min] |=([? b=@ c=tape] [~(v ne b) c])))
1001+ ++ w-co |=(min=@ (em-co [64 min] |=([? b=@ c=tape] [~(w ne b) c])))
1002+ ++ x-co |=(min=@ (em-co [16 min] |=([? b=@ c=tape] [~(x ne b) c])))
1003+ ++ y-co |=(dat=@ ((d-co 2) dat))
1004+ ++ z-co |=(dat=@ `tape`['0' 'x' ((x-co 1) dat)])
1005+ --
1006+ ~% %co +> ~
1007+ |%
1008+ ++ em-co
1009+ ~/ %emco
1010+ |= [[bas=@ min=@] [par=$+([? @ tape] tape)]]
1011+ |= hol=@
1012+ ^- tape
1013+ ?: &(=(0 hol) =(0 min))
1014+ rex
1015+ =+ [rad=(mod hol bas) dar=(div hol bas)]
1016+ %= $
1017+ min ?:(=(0 min) 0 (dec min))
1018+ hol dar
1019+ rex (par =(0 dar) rad rex)
1020+ ==
1021+ ::
1022+ ++ ox-co
1023+ ~/ %oxco
1024+ |= [[bas=@ gop=@] dug=$+(@ @)]
1025+ %+ em-co
1026+ [|-(?:(=(0 gop) 1 (mul bas $(gop (dec gop))))) 0]
1027+ |= [top=? seg=@ res=tape]
1028+ %+ weld
1029+ ?:(top ~ `tape`['.' ~])
1030+ %. seg
1031+ %+ em-co(rex res)
1032+ [bas ?:(top 0 gop)]
1033+ |=([? b=@ c=tape] [(dug b) c])
1034+ ::
1035+ ++ ro-co
1036+ ~/ %roco
1037+ |= [[buz=@ bas=@ dop=@] dug=$+(@ @)]
1038+ |= hol=@
1039+ ^- tape
1040+ ?: =(0 dop)
1041+ rex
1042+ => .(rex $(dop (dec dop)))
1043+ :- '.'
1044+ %- (em-co [bas 1] |=([? b=@ c=tape] [(dug b) c]))
1045+ [(cut buz [(dec dop) 1] hol)]
1046+ --
1047+ ::
1048+
1049+Renders a coin `lot` as a tape.
1050+
1051+`lot` is a [`++coin`]().
1052+
1053+ ~zod/try=> ~(rend co ~ %ux 200)
1054+ "0xc8"
1055+ ~zod/try=> ~(rend co %many ~[[%$ ux/200] [%$ p/40]])
1056+ "._0xc8_~~tem__"
1057+ ~zod/try=> ~(rend co ~ %p 32.819)
1058+ "~pillyt"
1059+ ~zod/try=> ~(rend co ~ %ux 18)
1060+ "0x12"
1061+ ~zod/try=> ~(rend co [~ p=[p=%if q=0x7f00.0001]])
1062+ ".127.0.0.1"
1063+ ~zod/try=> `@ux`.127.0.0.1
1064+ 2.130.706.433
1065+ ~zod/try=> ~(rend co %many ~[[~ %ud 20] [~ %uw 133] [~ %tas 'sam']])
1066+ "._20_0w25_sam__"
1067+ ~zod/try=> ~(rend co %blob [1 1])
1068+ "~0ph"
1069+ ~zod/try=> ~0ph
1070+ [1 1]
1071+ ~zod/try=> `@uv`(jam [1 1])
1072+ 0vph
1073+
1074+------------------------------------------------------------------------
1075+
1076+### `++ne`
1077+
1078+Digit rendering engine
1079+
1080+ ++ ne
1081+ |_ tig=@
1082+
1083+A [door]() containing arms that render digits at bases 10, 16, 32, and
1084+64.
1085+
1086+`tig` is an [`atom`]().
1087+
1088+ ~zod/try=> ~(. ne 20)
1089+ <4.gut [@ud <414.hhh 100.xkc 1.ypj %164>]>
1090+
1091+------------------------------------------------------------------------
1092+
1093+### `++d`
1094+
1095+Render decimal
1096+
1097+ ++ d (add tig '0')
1098+
1099+Renders a decimal digit as an atom of an ACII byte value.
1100+
1101+`tig` is an [`atom`]().
1102+
1103+ ~zod/try=> `@t`~(d ne 7)
1104+ '7'
1105+
1106+------------------------------------------------------------------------
1107+
1108+### `++x`
1109+
1110+Render hex
1111+
1112+ ++ x ?:((gte tig 10) (add tig 87) d)
1113+
1114+Renders a hexadecimal digit as an atom of an ASCII byte value.
1115+
1116+`tig` is an [`atom`]().
1117+
1118+ ~zod/try=> `@t`~(x ne 7)
1119+ '7'
1120+ ~zod/try=> `@t`~(x ne 14)
1121+ 'e'
1122+
1123+------------------------------------------------------------------------
1124+
1125+### `++v`
1126+
1127+Render base-32
1128+
1129+ ++ v ?:((gte tig 10) (add tig 87) d)
1130+
1131+Renders a base-32 digit as an atom of an ASCII byte value.
1132+
1133+ ~zod/try=> `@t`~(v ne 7)
1134+ '7'
1135+ ~zod/try=> `@t`~(v ne 14)
1136+ 'e'
1137+ ~zod/try=> `@t`~(v ne 25)
1138+ 'p'
1139+
1140+------------------------------------------------------------------------
1141+
1142+### `++w`
1143+
1144+Render base-64
1145+
1146+ ++ w ?:(=(tig 63) '~' ?:(=(tig 62) '-' ?:((gte tig 36) (add tig 29) x)))
1147+ --
1148+ ::
1149+
1150+Renders a base-64 digit as an atom of an ASCII byte value.
1151+
1152+`tig` is an [`atom`]().
1153+
1154+ ~zod/try=> `@t`~(w ne 7)
1155+ '7'
1156+ ~zod/try=> `@t`~(w ne 14)
1157+ 'e'
1158+ ~zod/try=> `@t`~(w ne 25)
1159+ 'p'
1160+ ~zod/try=> `@t`~(w ne 52)
1161+ 'Q'
1162+ ~zod/try=> `@t`~(w ne 61)
1163+ 'Z'
1164+ ~zod/try=> `@t`~(w ne 63)
1165+ '~'
1166+ ~zod/try=> `@t`~(w ne 62)
1167+ '-'
1168+
1169+------------------------------------------------------------------------
1170+
1171+### `++mu`
1172+
1173+Core used to scramble 16-bit atoms
1174+
1175+ ++ mu
1176+ |_ [top=@ bot=@]
1177+
1178+A [door]() that contains arms that are used to scramble two atoms, `top`
1179+and `bot`. Used especially in the phonetic base to disguise the
1180+relationship between a destroyer and its cruiser.
1181+
1182+`bot` is an [atom]().
1183+
1184+`top` is an [atom]().
1185+
1186+ ~zod/try=> ~(. mu 0x20e5 0x5901)
1187+ <3.sjm [[@ux @ux] <414.hhh 100.xkc 1.ypj %164>]>
1188+
1189+------------------------------------------------------------------------
1190+
1191+### `++zag`
1192+
1193+Add bottom into top
1194+
1195+ ++ zag [p=(end 4 1 (add top bot)) q=bot]
1196+
1197+Produces the cell of `top` and `bot` with `top` scrambled to the result
1198+of adding `bot` to `top` modulo 16. Used to scramble the name of a
1199+destroyer.
1200+
1201+`bot` is an [atom]().
1202+
1203+`top` is an [atom]().
1204+
1205+ ~zod/try=> `[@ux @ux]`~(zag mu 0x20e0 0x201)
1206+ [0x22e1 0x201]
1207+
1208+------------------------------------------------------------------------
1209+
1210+### `++zig`
1211+
1212+Subtract bottom from top
1213+
1214+ ++ zig [p=(end 4 1 (add top (sub 0x1.0000 bot))) q=bot]
1215+
1216+The inverse of [`++zag`](). Produces the cell of `top` and `bot` with
1217+`top` unscrambled. The unscrambled `top` is the sum of the sample `top`
1218+and the 16-bit complement of `bot`. Used to unscramble the name of the
1219+destroyer.
1220+
1221+`bot` is an [atom]().
1222+
1223+`top` is an [atom]().
1224+
1225+ ~zod/try=> `[@ux @ux]`~(zig mu 0x2f46 0x1042)
1226+ [0x1f04 0x1042]
1227+
1228+------------------------------------------------------------------------
1229+
1230+### `++zug`
1231+
1232+Concatenate into atom
1233+
1234+ ++ zug (mix (lsh 4 1 top) bot)
1235+
1236+Produces the concatenation of `top` and `bot`. Used to assemble a
1237+destroyer name.
1238+
1239+`bot` is an [atom]().
1240+
1241+`top` is an [atom]().
1242+
1243+ ~zod/try=> `@ux`~(zug mu 0x10e1 0xfa)
1244+ 0x10e1.00fa
1245+
1246+------------------------------------------------------------------------
1247+
1248+### `++so`
1249+
1250+Coin parser engine
1251+
1252+ ++ so
1253+ |%
1254+
1255+Core containing arms that parse [`++coin`]s.
1256+
1257+ ~zod/try=> so
1258+ <10.mkn 414.hhh 100.xkc 1.ypj %164>
1259+
1260+------------------------------------------------------------------------
1261+
1262+### `++bisk`
1263+
1264+Parse odor-atom pair
1265+
1266+ ++ bisk
1267+ ;~ pose
1268+ ;~ pfix (just '0')
1269+ ;~ pose
1270+ (stag %ub ;~(pfix (just 'b') bay:ag))
1271+ (stag %ui ;~(pfix (just 'i') dim:ag))
1272+ (stag %ux ;~(pfix (just 'x') hex:ag))
1273+ (stag %uv ;~(pfix (just 'v') viz:ag))
1274+ (stag %uw ;~(pfix (just 'w') wiz:ag))
1275+ ==
1276+ ==
1277+ (stag %ud dem:ag)
1278+ ==
1279+
1280+Parsing rule. Parses an unsigned integer of any permitted base,
1281+producing a [`++dime`]().
1282+
1283+ ~zod/try=> (scan "25" bisk:so)
1284+ [%ud q=25]
1285+ ~zod/try=> (scan "0x12.6401" bisk:so)
1286+ [%ux q=1.205.249]
1287+
1288+------------------------------------------------------------------------
1289+
1290+### `++crub`
1291+
1292+Parse `@da`, `@dr`, `@p`, `@t`
1293+
1294+ ++ crub
1295+ ;~ pose
1296+ %+ cook
1297+ |=(det=date `dime`[%da (year det)])
1298+ ;~ plug
1299+ %+ cook
1300+ |=([a=@ b=?] [b a])
1301+ ;~(plug dim:ag ;~(pose (cold | hep) (easy &)))
1302+ ;~(pfix dot dim:ag) :: month
1303+ ;~(pfix dot dim:ag) :: day
1304+ ;~ pose
1305+ ;~ pfix
1306+ ;~(plug dot dot)
1307+ ;~ plug
1308+ dum:ag
1309+ ;~(pfix dot dum:ag)
1310+ ;~(pfix dot dum:ag)
1311+ ;~(pose ;~(pfix ;~(plug dot dot) (most dot qix:ab)) (easy ~))
1312+ ==
1313+ ==
1314+ (easy [0 0 0 ~])
1315+ ==
1316+ ==
1317+ ::
1318+ %+ cook
1319+ |= [a=(list ,[p=?(%d %h %m %s) q=@]) b=(list ,@)]
1320+ =+ rop=`tarp`[0 0 0 0 b]
1321+ |- ^- dime
1322+ ?~ a
1323+ [%dr (yule rop)]
1324+ ?- p.i.a
1325+ %d $(a t.a, d.rop (add q.i.a d.rop))
1326+ %h $(a t.a, h.rop (add q.i.a h.rop))
1327+ %m $(a t.a, m.rop (add q.i.a m.rop))
1328+ %s $(a t.a, s.rop (add q.i.a s.rop))
1329+ ==
1330+ ;~ plug
1331+ %+ most
1332+ dot
1333+ ;~ pose
1334+ ;~(pfix (just 'd') (stag %d dim:ag))
1335+ ;~(pfix (just 'h') (stag %h dim:ag))
1336+ ;~(pfix (just 'm') (stag %m dim:ag))
1337+ ;~(pfix (just 's') (stag %s dim:ag))
1338+ ==
1339+ ;~(pose ;~(pfix ;~(plug dot dot) (most dot qix:ab)) (easy ~))
1340+ ==
1341+ ::
1342+ (stag %p fed:ag)
1343+ ;~(pfix dot (stag %ta urs:ab))
1344+ ;~(pfix sig (stag %t (cook woad urs:ab)))
1345+ ;~(pfix hep (stag %c (cook turf (cook woad urs:ab))))
1346+ ==
1347+
1348+Parsing rule. Parses any atom of any of the following odors after a
1349+leading sig, `~` into a [`++dime`](): [`@da`](), [`@dr`](), [`@p`](),
1350+and [`@t`](), producing a [`++dime`]().
1351+
1352+ ~zod/try=> (scan "1926.5.12" crub:so)
1353+ [p=~.da q=170.141.184.449.747.016.871.285.095.307.149.312.000]
1354+ ~zod/try=> (,[%da @da] (scan "1926.5.12" crub:so))
1355+ [%da ~1926.5.12]
1356+ ~zod/try=> (scan "s10" crub:so)
1357+ [p=~.dr q=184.467.440.737.095.516.160]
1358+ ~zod/try=> (,[%dr @dr] (scan "s10" crub:so))
1359+ [%dr ~s10]
1360+ ~zod/try=> (scan "doznec" crub:so)
1361+ [%p 256]
1362+ ~zod/try=> (scan ".mas" crub:so)
1363+ [%ta 7.561.581]
1364+
1365+------------------------------------------------------------------------
1366+
1367+### `++nuck`
1368+
1369+Top-level coin parser
1370+
1371+ ++ nuck
1372+ %+ knee *coin |. ~+
1373+ %- stew
1374+ ^. stet ^. limo
1375+ :~ :- ['a' 'z'] (cook |=(a=@ta [~ %tas a]) sym)
1376+ :- ['0' '9'] (stag ~ bisk)
1377+ :- '-' (stag ~ tash)
1378+ :- '.' ;~(pfix dot perd)
1379+ :- '~' ;~(pfix sig ;~(pose twid (easy [~ %n 0])))
1380+ ==
1381+
1382+Parsing rule. Switches on the first character and applies the
1383+corresponding [`++coin`]() parser.
1384+
1385+ ~zod/try=> (scan "~pillyt" nuck:so)
1386+ [% p=[p=~.p q=32.819]]
1387+ ~zod/try=> (scan "0x12" nuck:so)
1388+ [% p=[p=~.ux q=18]]
1389+ ~zod/try=> (scan ".127.0.0.1" nuck:so)
1390+ [% p=[p=~.if q=2.130.706.433]]
1391+ ~zod/try=> `@ud`.127.0.0.1
1392+ 2.130.706.433
1393+ ~zod/try=> (scan "._20_0w25_sam__" nuck:so)
1394+ [ %many
1395+ p
1396+ ~[[% p=[p=~.ud q=20]] [% p=[p=~.uw q=133]] [% p=[p=~.tas q=7.168.371]]]
1397+ ]
1398+ ~zod/try=> `@`%sam
1399+ 7.168.371
1400+ ~zod/try=> (scan "~0ph" nuck:so)
1401+ [%blob p=[1 1]]
1402+ ~zod/try=> ~0ph
1403+ [1 1]
1404+ ~zod/try=> `@uv`(jam [1 1])
1405+ 0vph
1406+
1407+------------------------------------------------------------------------
1408+
1409+### `++nusk`
1410+
1411+Parse coin literal with escapes
1412+
1413+ ++ nusk
1414+ (sear |=(a=@ta (rush (wick a) nuck)) urt:ab)
1415+
1416+Parsing rule. Parses a coin literal with escapes. (See also: xx tuple
1417+formatting).
1418+
1419+ ~zod/try=> ~.asd_a
1420+ ~.asd_a
1421+ ~zod/try=> ._1_~~.asd~-a__
1422+ [1 ~.asd_a]
1423+ ~zod/try=> (scan "~~.asd~-a" nusk:so)
1424+ [% p=[p=~.ta q=418.212.246.369]]
1425+ ~zod/try=> (,[~ %ta @ta] (scan "~~.asd~-a" nusk:so))
1426+ [~ %ta ~.asd_a]
1427+
1428+------------------------------------------------------------------------
1429+
1430+### `++perd`
1431+
1432+Parsing rule.
1433+
1434+ ++ perd
1435+ ;~ pose
1436+ (stag ~ zust)
1437+ (stag %many (ifix [cab ;~(plug cab cab)] (more cab nusk)))
1438+ ==
1439+
1440+Parsing rule. Parses a dime or tuple without their respective standard
1441+prefixes.
1442+
1443+ ~zod/try=> (scan "y" perd:so)
1444+ [~ [%f %.y]]
1445+ ~zod/try=> (scan "n" perd:so)
1446+ [~ [%f %.n]]
1447+ ~zod/try=> |
1448+ %.n
1449+ ~zod/try=> (scan "_20_x__" perd:so)
1450+ [%many [[% p=[p=~.ud q=20]] ~[[% p=[p=~.tas q=120]]]]]
1451+
1452+------------------------------------------------------------------------
1453+
1454+### `++royl`
1455+
1456+Parse dime float
1457+
1458+ ++ royl
1459+ =+ ^= zer
1460+ (cook lent (star (just '0')))
1461+ =+ ^= voy
1462+ %+ cook royl-cell
1463+ ;~ plug
1464+ ;~(pose (cold | hep) (easy &))
1465+ ;~(plug dim:ag ;~(pose ;~(pfix dot ;~(plug zer dim:ag)) (easy [0 0])))
1466+ ;~ pose
1467+ ;~ pfix
1468+ (just 'e')
1469+ (cook some ;~(plug ;~(pose (cold | hep) (easy &)) dim:ag))
1470+ ==
1471+ (easy ~)
1472+ ==
1473+ ==
1474+ ;~ pose
1475+ (stag %rh (cook rylh ;~(pfix ;~(plug sig sig) voy)))
1476+ (stag %rq (cook rylq ;~(pfix ;~(plug sig sig sig) voy)))
1477+ (stag %rd (cook ryld ;~(pfix sig voy)))
1478+ (stag %rs (cook ryls voy)
1479+ ==
1480+
1481+Parsing rule. Parses a number into a [`++dime`]() float.
1482+
1483+ ~zod/try=> (scan "~3.14" royl:so)
1484+ [%rd .~3.13999999999999]
1485+ ~zod/try=> .~3.14
1486+ .~3.13999999999999
1487+
1488+------------------------------------------------------------------------
1489+
1490+### `++royl-cell`
1491+
1492+XX still not fully functional
1493+
1494+ ++ royl-cell
1495+ |= [a=? b=[c=@ d=@ e=@] f=(unit ,[h=? i=@])]
1496+ ^- [? @ @ @ (unit ,@s)]
1497+ ?~ f
1498+ [a c.b d.b e.b ~]
1499+ ?: h.u.f
1500+ [a c.b d.b e.b [~ (mul i.u.f 2)]]
1501+ [a c.b d.b e.b [~ (dec (mul i.u.f 2))]]
1502+
1503+Intermediate parsed float convereter
1504+
1505+------------------------------------------------------------------------
1506+
1507+### `++tash`
1508+
1509+Parse signed dime
1510+
1511+ ++ tash
1512+ =+ ^= neg
1513+ |= [syn=? mol=dime] ^- dime
1514+ ?> =('u' (end 3 1 p.mol))
1515+ [(cat 3 's' (rsh 3 1 p.mol)) (new:si syn q.mol)]
1516+ ;~ pfix hep
1517+ ;~ pose
1518+ (cook |=(a=dime (neg | a)) bisk)
1519+ ;~(pfix hep (cook |=(a=dime (neg & a)) bisk))
1520+ ==
1521+ ==
1522+
1523+Parsing rule. Parses a signed number into a [`++dime`]().
1524+
1525+ ~zod/try=> (scan "-20" tash:so)
1526+ [p=~.sd q=39]
1527+ ~zod/try=> (,[%sd @sd] (scan "-20" tash:so))
1528+ [%sd -20]
1529+ ~zod/try=> (,[%sd @sd] (scan "--20" tash:so))
1530+ [%sd --20]
1531+ ~zod/try=> (,[%sx @sx] (scan "--0x2e" tash:so))
1532+ [%sx --0x2e]
1533+
1534+------------------------------------------------------------------------
1535+
1536+### `++twid`
1537+
1538+Parse coins without `~` prefix
1539+
1540+ ++ twid
1541+ ;~ pose
1542+ (cook |=(a=@ [%blob (cue a)]) ;~(pfix (just '0') vum:ag))
1543+ (stag ~ crub)
1544+ ==
1545+ ::
1546+
1547+Parsing rule. Parses coins after a leading sig, `~`.
1548+
1549+ ~zod/try=> (scan "zod" twid:so)
1550+ [~ [%p 0]]
1551+ ~zod/try=> (scan ".sam" twid:so)
1552+ [~ [%ta 7.168.371]]
1553+ ~zod/try=> `@ud`~.sam
1554+ 7.168.371
1555+ ~zod/try=> `@t`~.sam
1556+ 'sam'
1557+ ~zod/try=> (scan "0ph" twid:so)
1558+ [%blob [1 1]]
1559+
1560+------------------------------------------------------------------------
1561+
1562+### `++zust`
1563+
1564+Parse prefixed dimes from `@if`, `@f`, `@rd`
1565+
1566+ ++ zust
1567+ ;~ pose
1568+ (stag %is bip:ag)
1569+ (stag %if lip:ag)
1570+ (stag %f ;~(pose (cold & (just 'y')) (cold | (just 'n'))))
1571+ royl
1572+ ==
1573+ --
1574+
1575+Parsing rule. Parses an atom of either [`@if`]() (IP address), [`@f`]()
1576+(loobean), or [`rf`]()(floating point) into a [`++dime`]().
1577+
1578+ ~zod/try=> (scan "127.0.0.1" zust:so)
1579+ [%if q=2.130.706.433]
1580+ ~zod/try=> (scan "af.0.0.0.0.e7a5.30d2.7" zust:so)
1581+ [%is q=908.651.950.243.594.834.993.091.554.288.205.831]
1582+ ~zod/try=> (,[%is @is] (scan "af.0.0.0.0.e7a5.30d2.7" zust:so))
1583+ [%is .af.0.0.0.0.e7a5.30d2.7]
1584+ ~zod/try=> (,[%is @ux] (scan "af.0.0.0.0.e7a5.30d2.7" zust:so))
1585+ [%is 0xaf.0000.0000.0000.0000.e7a5.30d2.0007]
1586+ ~zod/try=> (scan "y" zust:so)
1587+ [%f %.y]
1588+ ~zod/try=> (scan "12.09" zust:so)
1589+ [%rd .~12.00999999999999]
1590+
1591+------------------------------------------------------------------------
1592+
1593+### `++scot`
1594+
1595+Render dime as cord
1596+
1597+ ++ scot |=(mol=dime ~(rent co %$ mol))
1598+
1599+Renders a dime `mol` as a cord.
1600+
1601+`mol` is a [`++dime`]().
1602+
1603+ ~zod/try=> (scot %p ~pillyt)
1604+ ~.~pillyt
1605+ ~zod/try=> `@t`(scot %p ~pillyt)
1606+ '~pillyt'
1607+ ~zod/try=> (scot %ux 0x12)
1608+ ~.0x12
1609+ ~zod/try=> `@t`(scot %ux 0x12)
1610+ '0x12'
1611+ ~zod/try=> (scot %if .127.0.0.1)
1612+ ~..127.0.0.1
1613+ ~zod/try=> `@t`(scot %if .127.0.0.1)
1614+ '.127.0.0.1'
1615+ ~zod/try=> (scot %ta ~.asd_a)
1616+ ~.~.asd_a
1617+ ~zod/try=> `@t`(scot %ta ~.asd_a)
1618+ '~.asd_a'
1619+
1620+------------------------------------------------------------------------
1621+
1622+### `++scow`
1623+
1624+Render dime as tape
1625+
1626+ ++ scow |=(mol=dime ~(rend co %$ mol))
1627+
1628+Renders `mol` as a tape.
1629+
1630+`mol` is a [`++dime`]().
1631+
1632+ ~zod/try=> (scow %p ~pillyt)
1633+ "~pillyt"
1634+ ~zod/try=> (scow %ux 0x12)
1635+ "0x12"
1636+ ~zod/try=> (scow %if .127.0.0.1)
1637+ ".127.0.0.1"
1638+ ~zod/try=> (scow %ta ~.asd_a)
1639+ "~.asd_a"
1640+
1641+------------------------------------------------------------------------
1642+
1643+### `++slat`
1644+
1645+Curried slaw
1646+
1647+ ++ slat |=(mod=@tas |=(txt=@ta (slaw mod txt)))
1648+
1649+Produces a [`gate`]() that parses a [`term`]() `txt` to an atom of the
1650+odor specified by `mod`.
1651+
1652+`mod` is a term, an atom of odor [`@tas`]().
1653+
1654+`txt` is a span, an atom of odor [`@ta`]().
1655+
1656+ ~zod/try=> `(unit ,@p)`((slat %p) '~pillyt')
1657+ [~ ~pillyt]
1658+ ~zod/try=> `(unit ,@ux)`((slat %ux) '0x12')
1659+ [~ 0x12]
1660+ ~zod/try=> `(unit ,@if)`((slat %if) '.127.0.0.1')
1661+ [~ .127.0.0.1]
1662+ ~zod/try=> `(unit ,@ta)`((slat %ta) '~.asd_a')
1663+ [~ ~.asd_a
1664+
1665+------------------------------------------------------------------------
1666+
1667+### `++slav`
1668+
1669+Demand: parse span with input odor
1670+
1671+ ++ slav |=([mod=@tas txt=@ta] (need (slaw mod txt)))
1672+
1673+Parses a span `txt` to an atom of the odor specificed by `mod`. Crashes
1674+if it failes to parse.
1675+
1676+`mod` is a term, an atom of odor [`@tas`]().
1677+
1678+`txt` is a span, an atom of odor [`@ta`]().
1679+
1680+ ~zod/try=> `@p`(slav %p '~pillyt')
1681+ ~pillyt
1682+ ~zod/try=> `@p`(slav %p '~pillam')
1683+ ! exit
1684+ ~zod/try=> `@ux`(slav %ux '0x12')
1685+ 0x12
1686+ ~zod/try=> `@ux`(slav %ux '0b10')
1687+ ! exit
1688+ ~zod/try=> `@if`(slav %if '.127.0.0.1')
1689+ .127.0.0.1
1690+ ~zod/try=> `@if`(slav %if '.fe80.0.0.202')
1691+ ! exit
1692+ ~zod/try=> `@ta`(slav %ta '~.asd_a')
1693+ ~.asd_a
1694+ ~zod/try=> `@ta`(slav %ta '~~asd-a')
1695+ ! exit
1696+
1697+------------------------------------------------------------------------
1698+
1699+### `++slaw`
1700+
1701+Parse span to input odor
1702+
1703+ ++ slaw
1704+ |= [mod=@tas txt=@ta]
1705+ ^- (unit ,@)
1706+ =+ con=(slay txt)
1707+ ?.(&(?=([~ %$ @ @] con) =(p.p.u.con mod)) ~ [~ q.p.u.con])
1708+ ::
1709+
1710+Parses a span `txt` to an atom of the odor specified by `mod`.
1711+
1712+`mod` is a term, an atom of odor [`@tas`]().
1713+
1714+`txt` is a span, an atom of odor [`@ta`]().
1715+
1716+ ~zod/try=> `(unit ,@p)`(slaw %p '~pillyt')
1717+ [~ ~pillyt]
1718+ ~zod/try=> `(unit ,@p)`(slaw %p '~pillam')
1719+ ~
1720+ ~zod/try=> `(unit ,@ux)`(slaw %ux '0x12')
1721+ [~ 0x12]
1722+ ~zod/try=> `(unit ,@ux)`(slaw %ux '0b10')
1723+ ~
1724+ ~zod/try=> `(unit ,@if)`(slaw %if '.127.0.0.1')
1725+ [~ .127.0.0.1]
1726+ ~zod/try=> `(unit ,@if)`(slaw %if '.fe80.0.0.202')
1727+ ~
1728+ ~zod/try=> `(unit ,@ta)`(slaw %ta '~.asd_a')
1729+ [~ ~.asd_a]
1730+ ~zod/try=> `(unit ,@ta)`(slaw %ta '~~asd-a')
1731+ ~
1732+
1733+------------------------------------------------------------------------
1734+
1735+### `++slay`
1736+
1737+Parse span to coin
1738+
1739+ ++ slay
1740+ |= txt=@ta ^- (unit coin)
1741+ =+ vex=((full nuck:so) [[1 1] (trip txt)])
1742+ ?~ q.vex
1743+ ~
1744+ [~ p.u.q.vex]
1745+ ::
1746+
1747+Parses a span `txt` to the unit of a [`++coin`]().
1748+
1749+`txt` is a [`@ta`]().
1750+
1751+ ~zod/try=> (slay '~pillyt')
1752+ [~ [% p=[p=~.p q=32.819]]]
1753+ ~zod/try=> (slay '0x12')
1754+ [~ [% p=[p=~.ux q=18]]]
1755+ ~zod/try=> (slay '.127.0.0.1')
1756+ [~ [% p=[p=~.if q=2.130.706.433]]]
1757+ ~zod/try=> `@ud`.127.0.0.1
1758+ 2.130.706.433
1759+ ~zod/try=> (slay '._20_0w25_sam__')
1760+ [ ~
1761+ [ %many
1762+ p=~[[% p=[p=~.ud q=20]] [% p=[p=~.uw q=133]] [% p=[p=~.tas q=7.168.371]]]
1763+ ]
1764+ ]
1765+ ~zod/try=> `@`%sam
1766+ 7.168.371
1767+ ~zod/try=> (slay '~0ph')
1768+ [~ [%blob p=[1 1]]]
1769+ ~zod/try=> 0ph
1770+ ~ <syntax error at [1 2]>
1771+ ~zod/try=> ~0ph
1772+ [1 1]
1773+ ~zod/try=> `@uv`(jam [1 1])
1774+ 0vph
1775+
1776+------------------------------------------------------------------------
1777+
1778+------------------------------------------------------------------------
1779+
1780+### `++smyt`
1781+
1782+Render path as tank
1783+
1784+ ++ smyt
1785+ |= bon=path ^- tank
1786+ :+ %rose [['/' ~] ['/' ~] ['/' ~]]
1787+ |- ^- (list tank)
1788+ (turn bon |=(a=@ [%leaf (rip 3 a)]))
1789+
1790+Renders the path `bon` as a [`tank`](), which is used for
1791+pretty-printing.
1792+
1793+`bon` is a [`++path`]().
1794+
1795+ ~zod/try=> (smyt %)
1796+ [ %rose
1797+ p=[p="/" q="/" r="/"]
1798+ q
1799+ ~[ [%leaf p="~zod"]
1800+ [%leaf p="try"]
1801+ [%leaf p="~2014.10.28..18.36.58..a280"]
1802+ ]
1803+ ]
1804+ ~zod/try=> (smyt /as/les/top)
1805+ [ %rose
1806+ p=[p="/" q="/" r="/"]
1807+ q=~[[%leaf p="as"] [%leaf p="les"] [%leaf p="top"]]
1808+ ]
1809+
1810+------------------------------------------------------------------------
1811+
1812+### `++spat`
1813+
1814+Render path as cord
1815+
1816+ ++ spat |=(pax=path (crip (spud pax))) :: path to cord
1817+
1818+Renders a path `pax` as cord.
1819+
1820+`pax` is a [`path`]().
1821+
1822+ ~zod/try=> (spat %)
1823+ '~zod/try/~2014.10.28..18.40.20..4287'
1824+ ~zod/try=> (spat %/bin)
1825+ '~zod/try/~2014.10.28..18.41.12..3bcd/bin'
1826+ ~zod/try=> (spat /as/les/top)
1827+ '/as/les/top'
1828+
1829+------------------------------------------------------------------------
1830+
1831+### `++spud`
1832+
1833+Render path as tape
1834+
1835+ ++ spud |=(pax=path ~(ram re (smyt pax))) :: path to tape
1836+
1837+Renders a path `pax` as [tape]().
1838+
1839+`pax` is a [`path`]().
1840+
1841+ ~zod/try=> (spud %)
1842+ "~zod/try/~2014.10.28..18.40.46..e951"
1843+ ~zod/try=> (spud %/bin)
1844+ "~zod/try/~2014.10.28..18.41.05..16f2/bin"
1845+ ~zod/try=> (spud /as/les/top)
1846+ "/as/les/top"
1847+
1848+------------------------------------------------------------------------
1849+
1850+### `++stab`
1851+
1852+Parse span to path
1853+
1854+ ++ stab :: parse span to path
1855+ |= zep=@ta ^- path
1856+ (rash zep ;~(pfix fas ;~(sfix (more fas urs:ab) fas)))
1857+
1858+Parsing rule. Parses a span `zep` to a static [`++path`](/doc/hoon/library/1#++path).
1859+
1860+ ~zod/try=> (stab '/as/lek/tor')
1861+ /as/lek/tor
1862+ ~zod/try=> `(pole ,@ta)`(stab '/as/lek/tor')
1863+ [~.as [~.lek [~.tor ~]]]
1864+ ~zod/try=> (stab '~zod/arvo/~2014.10.28..18.48.41..335f/zuse')
1865+ ~zod/arvo/~2014.10.28..18.48.41..335f/zuse
1866+ ~zod/try=> `(pole ,@ta)`(stab '~zod/arvo/~2014.10.28..18.48.41..335f/zuse')
1867+ [~.~zod [~.arvo [~.~2014.10.28..18.48.41..335f [~.zuse ~]]]]
1868+ ~zod/try=> (stab '/a/~pillyt/pals/1')
1869+ /a/~pillyt/pals/1
1870+ ~zod/try=> `(pole ,@ta)`(stab '/a/~pillyt/pals/1')
1871+ [~.a [~.~pillyt [~.pals [~.1 ~]]]]
docs/dev/hoon/library/2em.mdnew file+758
@@ -0,0 +1,758 @@
1+section 2eM, regular-expressions
2+================================
3+
4+### `++pars`
5+
6+ ++ pars
7+ |= [a=tape] :: parse tape to rege
8+ ^- (unit rege)
9+ =+ foo=((full apex:rags) [[1 1] a])
10+ ?~ q.foo
11+ ~
12+ [~ p.u.q.foo]
13+ ::
14+
15+Parse regular expression
16+
17+ ~zod/try=> (pars "samo")
18+ [ ~
19+ [ %pair
20+ p=[%lite p=~~s]
21+ q=[%pair p=[%lite p=~~a] q=[%pair p=[%lite p=~~m] q=[%lite p=~~o]]]
22+ ]
23+ ]
24+ ~zod/try=> (pars "so[,.0-9]")
25+ [ ~
26+ [ %pair
27+ p=[%lite p=~~s]
28+ q=[%pair p=[%lite p=~~o] q=[%brac p=288.036.862.105.223.168]]
29+ ]
30+ ]
31+ ~zod/try=> `@ub`288.036.862.105.223.168
32+ 0b11.1111.1111.0101.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000
33+ ~zod/try=> `@ub`(lsh 0 `@`'9' 1)
34+ 0b10.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000
35+ ~zod/try=> `@ub`(roll (turn ",.0123456789" |=(a=@ (lsh 0 a 1))) con)
36+ 0b11.1111.1111.0101.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000
37+ ~zod/try=> (pars "sop.*")
38+ [ ~
39+ [ %pair
40+ p=[%lite p=~~s]
41+ q=[%pair p=[%lite p=~~o] q=[%pair p=[%lite p=~~p] q=[%mant p=%dote]]]
42+ ]
43+ ]
44+ ~zod/try=> (pars "(hel)?")
45+ [ ~
46+ [ %eith
47+ p
48+ [ %capt
49+ p=[%pair p=[%lite p=~~h] q=[%pair p=[%lite p=~~e] q=[%lite p=~~l]]]
50+ q=0
51+ ]
52+ q=%empt
53+ ]
54+ ]
55+ ~zod/try=> (pars "(hel)??")
56+ [ ~
57+ [ %eith
58+ p=%empt
59+ q
60+ [ %capt
61+ p=[%pair p=[%lite p=~~h] q=[%pair p=[%lite p=~~e] q=[%lite p=~~l]]]
62+ q=0
63+ ]
64+ ]
65+ ]
66+ ~zod/try=> (pars "a\{1,20}")
67+ [~ [%betw p=[%lite p=~~a] q=1 r=20]]
68+
69+### `++rags`
70+
71+ ++ rags :: rege parsers
72+ => |%
73+
74+Regex parser arms
75+
76+### `++nor`
77+
78+ ++ nor ;~(less (mask "^$()|*?+.[\\") (shim 1 127)) :: non-control char
79+
80+XX document
81+
82+### `++les`
83+
84+ ++ les ;~(less bas asp) :: not backslash
85+
86+XX document
87+
88+### `++lep`
89+
90+ ++ lep ;~(less (mask "^[]\\") asp) :: charset non-control
91+
92+XX document
93+
94+### `++asp`
95+
96+ ++ asp (shim 32 126) :: printable ascii
97+
98+XX document
99+
100+### `++alb`
101+
102+ ++ alb ;~(less ser asp) :: charset literal char
103+
104+XX document
105+
106+### `++mis`
107+
108+ ++ mis ;~(less aln asp) :: non alphanumeric
109+ --
110+ |%
111+
112+XX document
113+
114+### `++apex`
115+
116+ ++ apex :: top level
117+ %+ knee *rege |. ~+
118+ ;~ pose
119+ ;~((bend |=(a=[rege rege] (some [%eith a]))) mall ;~(pfix bar apex))
120+ (stag %eith ;~(plug (easy %empt) ;~(pfix bar apex)))
121+ (easy %empt)
122+ ==
123+ ::
124+
125+XX document
126+
127+### `++mall`
128+
129+ ++ mall
130+ %+ knee *rege |. ~+
131+ ;~((bend |=(a=[rege rege] (some [%pair a]))) bets mall)
132+ ::
133+
134+XX document
135+
136+### `++bets`
137+
138+ ++ bets
139+ %+ knee *rege |. ~+
140+ |= tub=nail
141+ =+ vex=(chun tub)
142+ ?~ q.vex
143+ vex
144+ =+ a=p.u.q.vex
145+ %- ;~ pose
146+ (cold [%eith %empt a] (jest '??'))
147+ (cold [%manl a] (jest '*?'))
148+ (cold [%plll a] (jest '+?'))
149+ (cold [%eith a %empt] wut)
150+ (cold [%mant a] tar)
151+ (cold [%plls a] lus)
152+ (stag %betl ;~(plug (easy a) ;~(sfix rang wut)))
153+ (stag %betw ;~(plug (easy a) rang))
154+ (stag %binl ;~(plug (easy a) (ifix [kel (jest ',}?')] dim:ag)))
155+ (stag %bant ;~(plug (easy a) (ifix [kel (jest '}?')] dim:ag)))
156+ (stag %bant ;~(plug (easy a) (ifix [kel ker] dim:ag)))
157+ (stag %bint ;~(plug (easy a) (ifix [kel (jest ',}')] dim:ag)))
158+ (easy a)
159+ ==
160+ q.u.q.vex
161+ ::
162+
163+XX document
164+
165+### `++ranc`
166+
167+ ++ ranc
168+ |= [a=@ b=@]
169+ ^- @
170+ ?:((gth a b) 0 (con (bex a) $(a +(a))))
171+ ::
172+
173+XX document
174+
175+### `++flap`
176+
177+ ++ flap |=(a=@ (mix a (dec (bex 256))))
178+ ::
179+
180+XX document
181+
182+### `++rang`
183+
184+ ++ rang
185+ %+ sear |=([a=@ b=@] ?:((lte a b) (some [a b]) ~))
186+ (ifix [kel ker] ;~(plug dim:ag ;~(pfix com dim:ag)))
187+ ::
188+
189+XX document
190+
191+### `++chun`
192+
193+ ++ chun
194+ %+ knee *rege |. ~+
195+ ;~ pose
196+ (cold %ende buc)
197+ (cold %sart ket)
198+ (cold %dote dot)
199+ %+ cook |=(a=(list char) (reel a |=([p=char q=rege] [%pair [%lite p] q])))
200+ ;~(pfix (jest '\\Q') cape)
201+ |= tub=nail
202+ =+ foo=;~(plug kel dim:ag ;~(pose ker (jest ',}') ;~(plug com dim:ag ker)))
203+ =+ bar=(foo tub)
204+ ?~(q.bar (chad tub) (fail tub))
205+ (cook |=([a=rege] [%capt a 0]) (ifix [pel per] apex))
206+ %+ cook |=([a=rege] [%capt a 0])
207+ (ifix [;~(plug (jest '(?P<') (plus aln) gar) per] apex)
208+ (ifix [(jest '(?:') per] apex)
209+ (stag %brac ;~(pfix sel seac))
210+ ==
211+ ::
212+
213+XX document
214+
215+### `++seac`
216+
217+ ++ seac
218+ |= tub=nail
219+ ?~ q.tub
220+ (fail tub)
221+ ?: =(i.q.tub '^')
222+ (;~(pfix ket (cook flap sead)) tub)
223+ (sead tub)
224+ ::
225+
226+XX document
227+
228+### `++sead`
229+
230+ ++ sead
231+ %+ knee *@ |. ~+
232+ ;~ pose
233+ |= tub=nail
234+ ?~ q.tub
235+ (fail tub)
236+ ?. =(i.q.tub ']')
237+ (fail tub)
238+ ?~ t.q.tub
239+ (fail tub)
240+ ?: =(i.t.q.tub '-')
241+ ?~ t.t.q.tub
242+ (fail tub)
243+ ?: =(i.t.t.q.tub ']')
244+ (;~(pfix ser (cook |=(a=@ (con (bex ']') a)) sade)) tub)
245+ (fail tub)
246+ (;~(pfix ser (cook |=(a=@ (con (bex ']') a)) sade)) tub)
247+ |= tub=nail
248+ ?~ q.tub
249+ (fail tub)
250+ ?. =(i.q.tub '-')
251+ (fail tub)
252+ ?~ t.q.tub
253+ (fail tub)
254+ ?: =(i.t.q.tub '-')
255+ ?~ t.t.q.tub
256+ (fail tub)
257+ ?: =(i.t.t.q.tub ']')
258+ (;~(pfix hep (cook |=(a=@ (con (bex '-') a)) sade)) tub)
259+ (fail tub)
260+ (;~(pfix hep (cook |=(a=@ (con (bex '-') a)) sade)) tub)
261+ (cook |=(a=[@ @] (con a)) ;~(plug seap sade))
262+ ==
263+ ::
264+
265+XX document
266+
267+### `++sade`
268+
269+ ++ sade
270+ %+ knee *@ |. ~+
271+ ;~ pose
272+ (cold (bex '-') (jest '-]'))
273+ (cold 0 ser)
274+ (cook |=([p=@ q=@] `@`(con p q)) ;~(plug seap sade))
275+ ==
276+ ::
277+
278+XX document
279+
280+### `++seap`
281+
282+ ++ seap
283+ %+ knee *@ |. ~+
284+ ;~ pose
285+ unid
286+ %+ ifix (jest '[:')^(jest ':]')
287+ ;~(pose ;~(pfix ket (cook flap chas)) chas)
288+ %+ sear |=([a=@ b=@] ?:((gth a b) ~ (some (ranc a b))))
289+ ;~(plug asp ;~(pfix hep alb))
290+ |= tub=nail
291+ ?~ q.tub
292+ (fail tub)
293+ ?~ t.q.tub
294+ ((cook bex les) tub)
295+ ?: =(i.t.q.tub '-')
296+ ?~ t.t.q.tub
297+ ((cook bex les) tub)
298+ ?: =(i.t.t.q.tub ']')
299+ ((cook bex les) tub)
300+ (fail tub)
301+ ((cook bex les) tub)
302+ ;~(pfix bas escd)
303+ ==
304+ ::
305+
306+XX document
307+
308+### `++cape`
309+
310+ ++ cape
311+ %+ knee *tape |. ~+
312+ ;~ pose
313+ (cold ~ (jest '\\E'))
314+ ;~(plug next cape)
315+ (cook |=(a=char (tape [a ~])) next)
316+ (full (easy ~))
317+ ==
318+
319+XX document
320+
321+### `++chas`
322+
323+ ++ chas :: ascii character set
324+ =- (sear ~(get by -) sym)
325+ %- mo ^- (list ,[@tas @I])
326+ :~ alnum/alnum alpha/alpha ascii/ascii blank/blank cntrl/cntrl
327+ digit/digit graph/graph lower/lower print/print punct/punct
328+ space/space upper/upper word/wordc xdigit/xdigit
329+ ==
330+ :: Character sets
331+
332+++ alnum :(con lower upper digit)
333+
334+
335+ XX document
336+
337+ ###++alpha
338+
339+++ alpha :(con lower upper)
340+
341+
342+ XX document
343+
344+ ###++ascii
345+
346+++ ascii (ranc 0 127)
347+
348+
349+ ++ blank (con (bex 32) (bex 9))
350+
351+XX document
352+
353+### `++cntrl`
354+
355+ ++ cntrl :(con (ranc 0 31) (bex 127))
356+
357+XX document
358+
359+### `++digit`
360+
361+ ++ digit (ranc '0' '9')
362+
363+XX document
364+
365+### `++graph`
366+
367+ ++ graph (ranc 33 126)
368+
369+XX document
370+
371+### `++lower`
372+
373+ ++ lower (ranc 'a' 'z')
374+
375+XX document
376+
377+### `++print`
378+
379+ ++ print (ranc 32 126)
380+
381+XX document
382+
383+### `++punct`
384+
385+ ++ punct ;: con
386+ (ranc '!' '/')
387+ (ranc ':' '@')
388+ (ranc '[' '`')
389+ (ranc '{' '~')
390+ ==
391+
392+XX document
393+
394+### `++space`
395+
396+ ++ space :(con (ranc 9 13) (bex ' '))
397+
398+XX document
399+
400+### `++upper`
401+
402+ ++ upper (ranc 'A' 'Z')
403+
404+XX document
405+
406+### `++white`
407+
408+ ++ white :(con (bex ' ') (ranc 9 10) (ranc 12 13))
409+
410+XX document
411+
412+### `++wordc`
413+
414+ ++ wordc :(con digit lower upper (bex '_'))
415+
416+XX document
417+
418+### `++xdigit`
419+
420+ ++ xdigit :(con (ranc 'a' 'f') (ranc 'A' 'F') digit)
421+ ::
422+
423+XX document
424+
425+### `++chad`
426+
427+ ++ chad
428+ %+ knee *rege |. ~+
429+ ;~(pose (stag %lite nor) (stag %brac unid) ;~(pfix bas escp))
430+ ::
431+
432+XX document
433+
434+### `++escd`
435+
436+ ++ escd
437+ %+ knee *@ |. ~+
438+ ;~ pose
439+ (cold (bex 7) (just 'a'))
440+ (cold (bex 9) (just 't'))
441+ (cold (bex 10) (just 'n'))
442+ (cold (bex 11) (just 'v'))
443+ (cold (bex 12) (just 'f'))
444+ (cold (bex 13) (just 'r'))
445+ (cold (bex 0) (just '0'))
446+ (sear |=(a=@ ?:((lth a 256) (some (bex a)) ~)) (bass 8 (stun [2 3] cit)))
447+ (cook bex ;~(pfix (just 'x') (bass 16 (stun [2 2] hit))))
448+ (cook bex (ifix [(jest 'x{') ker] (bass 16 (stun [2 2] hit))))
449+ (cook bex mis)
450+ ==
451+ ::
452+
453+XX document
454+
455+### `++escp`
456+
457+ ++ escp
458+ %+ knee *rege |. ~+
459+ ;~ pose
460+ (cold %empt (just 'Q'))
461+ (cold [%lite `@tD`0] (just '0'))
462+ (cold [%lite `@tD`7] (just 'a'))
463+ (cold [%lite `@tD`9] (just 't'))
464+ (cold [%lite `@tD`10] (just 'n'))
465+ (cold [%lite `@tD`11] (just 'v'))
466+ (cold [%lite `@tD`12] (just 'f'))
467+ (cold [%lite `@tD`13] (just 'r'))
468+ (sear |=(a=@ ?:((lth a 256) (some [%lite a]) ~)) (bass 8 (stun [2 3] cit)))
469+ (stag %lite ;~(pfix (just 'x') (bass 16 (stun [2 2] hit))))
470+ (stag %lite (ifix [(jest 'x{') ker] (bass 16 (stun [2 2] hit))))
471+ (cold %dote (just 'C'))
472+ (cold %sart (just 'A'))
473+ (cold %ende (just 'z'))
474+ (cold %boun (just 'b'))
475+ (cold %bout (just 'B'))
476+ (stag %brac (cold wordc (just 'w')))
477+ (stag %brac (cold (flap wordc) (just 'W')))
478+ (stag %lite mis)
479+ ==
480+ ::
481+
482+XX document
483+
484+### `++unid`
485+
486+ ++ unid
487+ %+ knee *@ |. ~+
488+ ;~ pose
489+ (cold digit (jest '\\d'))
490+ (cold (flap digit) (jest '\\D'))
491+ (cold white (jest '\\s'))
492+ (cold (flap white) (jest '\\S'))
493+ (cold wordc (jest '\\w'))
494+ (cold (flap wordc) (jest '\\W'))
495+ ==
496+ --
497+ ::
498+
499+XX document
500+
501+### `++ra`
502+
503+ ++ ra :: regex engine
504+ |_ a=rege
505+
506+XX document
507+
508+### `++proc`
509+
510+ ++ proc :: capture numbering
511+ |= b=@
512+ =- -(+ +>.$(a a))
513+ ^- [p=@ a=rege]
514+ ?- a
515+ [%capt *] =+ foo=$(a p.a, b +(b))
516+ [p.foo [%capt a.foo b]]
517+ [%eith *] =+ foo=$(a p.a)
518+ =+ bar=$(a q.a, b p.foo)
519+ [p.bar [%eith a.foo a.bar]]
520+ [%pair *] =+ foo=$(a p.a)
521+ =+ bar=$(a q.a, b p.foo)
522+ [p.bar [%pair a.foo a.bar]]
523+ [%manl *] =+ foo=$(a p.a)
524+ [p.foo [%manl a.foo]]
525+ [%plll *] =+ foo=$(a p.a)
526+ [p.foo [%plll a.foo]]
527+ [%binl *] =+ foo=$(a p.a)
528+ [p.foo [%binl a.foo q.a]]
529+ [%betl *] =+ foo=$(a p.a)
530+ [p.foo [%betl a.foo q.a r.a]]
531+ [%mant *] =+ foo=$(a p.a)
532+ [p.foo [%mant a.foo]]
533+ [%plls *] =+ foo=$(a p.a)
534+ [p.foo [%plls a.foo]]
535+ [%bant *] =+ foo=$(a p.a)
536+ [p.foo [%bant a.foo q.a]]
537+ [%bint *] =+ foo=$(a p.a)
538+ [p.foo [%bint a.foo q.a]]
539+ [%betw *] =+ foo=$(a p.a)
540+ [p.foo [%betw a.foo q.a r.a]]
541+ * [b a]
542+ ==
543+ ::
544+
545+XX document
546+
547+### `++cont`
548+
549+ ++ cont
550+ |= [a=(map ,@u tape) b=(map ,@u tape)]
551+ (~(gas by _(map ,@u tape)) (weld (~(tap by a)) (~(tap by b))))
552+ ::
553+
554+XX document
555+
556+### `++abor`
557+
558+ ++ abor
559+ |= [a=char b=(unit ,[tape (map ,@u tape)])]
560+ ^- (unit ,[tape (map ,@u tape)])
561+ ?~ b
562+ b
563+ [~ [[a -.u.b] +.u.b]]
564+ ::
565+
566+XX document
567+
568+### `++matc`
569+
570+ ++ matc
571+ |= [b=tape c=tape]
572+ ^- (unit (map ,@u tape))
573+ =+ foo=`(unit ,[tape (map ,@u tape)])`(deep b %empt c)
574+ (bind foo |*(a=^ (~(put by +.a) 0 -.a)))
575+ ::
576+
577+XX document
578+
579+### `++chet`
580+
581+ ++ chet
582+ |= [b=(unit ,[tape (map ,@u tape)]) c=tape d=tape]
583+ ^- (unit ,[tape (map ,@u tape)])
584+ ?~ b
585+ b
586+ ?~ -.u.b
587+ b
588+ =+ bar=(deep (slag (lent -.u.b) c) %empt d)
589+ ?~ bar
590+ bar
591+ b
592+
593+XX document
594+
595+### `++blak`
596+
597+ ++ blak (some ["" _(map ,@u tape)])
598+
599+XX document
600+
601+### `++word`
602+
603+ ++ word |=(a=char =((dis wordc:rags (bex a)) 0))
604+
605+XX document
606+
607+### `++deep`
608+
609+ ++ deep
610+ |= [b=tape c=rege d=tape]
611+ ^- (unit ,[tape (map ,@u tape)])
612+ ?- a
613+ %dote ?~(b ~ (some [[i.b ~] _(map ,@u tape)]))
614+ %ende ?~(b blak ~)
615+ %sart ?:(=(b d) blak ~)
616+ %empt blak
617+ %boun =+ ^= luc
618+ ?: =(b d)
619+ &
620+ =+ foo=(slag (dec (sub (lent d) (lent b))) d)
621+ (word -.foo)
622+ =+ cuc=?~(b & (word -.b))
623+ ?:(!=(luc cuc) blak ~)
624+ %bout =+ ^= luc
625+ ?: =(b d)
626+ &
627+ =+ foo=(slag (dec (sub (lent d) (lent b))) d)
628+ (word -.foo)
629+ =+ cuc=?~(b & (word -.b))
630+ ?:(=(luc cuc) blak ~)
631+ [%capt *] =+ foo=$(a p.a)
632+ ?~ foo
633+ foo
634+ =+ ft=u.foo
635+ =+ bar=$(a c, b (slag (lent -.ft) b), c %empt)
636+ ?~ bar
637+ bar
638+ [~ [-.ft (~(put by +.ft) q.a -.ft)]]
639+ [%lite *] ?~(b ~ ?:(=(i.b p.a) (some [[i.b ~] _(map ,@u tape)]) ~))
640+ [%brac *] ?~ b
641+ ~
642+ ?. =((dis (bex `@`i.b) p.a) 0)
643+ (some [[i.b ~] _(map ,@u tape)])
644+ ~
645+ [%eith *] =+ foo=(chet(a c) $(a p.a) b d)
646+ =+ bar=(chet(a c) $(a q.a) b d)
647+ ?~ foo
648+ bar
649+ ?~ bar
650+ foo
651+ =+ ft=u.foo
652+ =+ bt=u.bar
653+ ?: (gte (lent -.ft) (lent -.bt))
654+ foo
655+ bar
656+ [%pair *] =+ foo=$(a p.a, c [%pair q.a c])
657+ ?~ foo
658+ foo
659+ =+ ft=u.foo
660+ =+ bar=$(a q.a, b (slag (lent -.ft) b))
661+ ?~ bar
662+ bar
663+ =+ bt=u.bar
664+ [~ [(weld -.ft -.bt) (cont +.ft +.bt)]]
665+ [%manl *] =+ foo=$(a p.a)
666+ ?~ foo
667+ blak
668+ ?~ -.u.foo
669+ blak
670+ $(a [%eith %empt [%pair p.a [%eith %empt a]]])
671+ [%mant *] =+ foo=$(a p.a)
672+ ?~ foo
673+ blak
674+ =+ ft=u.foo
675+ ?~ -.ft
676+ blak
677+ $(a [%eith [%pair p.a [%eith a %empt]] %empt])
678+ [%plls *] $(a [%pair p.a [%mant p.a]])
679+ [%plll *] $(a [%pair p.a [%manl p.a]])
680+ [%binl *] =+ min=?:(=(q.a 0) 0 (dec q.a))
681+ ?: =(q.a 0)
682+ $(a [%manl p.a])
683+ $(a [%pair p.a [%binl p.a min]])
684+ [%bant *] ?: =(0 q.a)
685+ blak
686+ $(a [%pair p.a [%bant p.a (dec q.a)]])
687+ [%bint *] =+ min=?:(=(q.a 0) 0 (dec q.a))
688+ ?: =(q.a 0)
689+ $(a [%mant p.a])
690+ $(a [%pair p.a [%bint p.a min]])
691+ [%betw *] ?: =(0 r.a)
692+ blak
693+ ?: =(q.a 0)
694+ $(a [%eith [%pair p.a [%betw p.a 0 (dec r.a)]] %empt])
695+ $(a [%pair p.a [%betw p.a (dec q.a) (dec r.a)]])
696+ [%betl *] ?: =(0 r.a)
697+ blak
698+ ?: =(q.a 0)
699+ $(a [%eith %empt [%pair p.a [%betl p.a 0 (dec r.a)]]])
700+ $(a [%pair p.a [%betl p.a (dec q.a) (dec r.a)]])
701+ ==
702+ --
703+ ::
704+
705+XX document
706+
707+### `++rexp`
708+
709+ ++ rexp :: Regex match
710+ ~/ %rexp
711+ |= [a=tape b=tape]
712+ ^- (unit (unit (map ,@u tape)))
713+ =+ ^= bar
714+ |= [a=@ b=(map ,@u tape)]
715+ ?: =(a 0)
716+ b
717+ =+ c=(~(get by b) a)
718+ ?~ c
719+ $(a (dec a), b (~(put by b) a ""))
720+ $(a (dec a))
721+ =+ par=(pars a)
722+ ?~ par ~
723+ =+ poc=(~(proc ra u.par) 1)
724+ =+ c=b
725+ |-
726+ =+ foo=(matc:poc c b)
727+ ?~ foo
728+ ?~ c
729+ [~ ~]
730+ $(c t.c)
731+ [~ [~ (bar (dec p.poc) u.foo)]]
732+ ::
733+
734+XX document
735+
736+### `++repg`
737+
738+ ++ repg :: Global regex replace
739+ ~/ %repg
740+ |= [a=tape b=tape c=tape]
741+ ^- (unit tape)
742+ =+ par=(pars a)
743+ ?~ par ~
744+ =+ poc=(~(proc ra u.par) 1)
745+ =+ d=b
746+ :- ~
747+ |-
748+ ^- tape
749+ =+ foo=(matc:poc d b)
750+ ?~ foo
751+ ?~ d
752+ ~
753+ [i.d $(d t.d)]
754+ =+ ft=(need (~(get by u.foo) 0))
755+ ?~ d
756+ c
757+ (weld c $(d `tape`(slag (lent ft) `tape`d)))
758+ ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
docs/dev/hoon/library/2en.mdnew file+378
@@ -0,0 +1,378 @@
1+section 2eN, pseudo-cryptography
2+================================
3+
4+### `++un`
5+
6+Reversible scrambling core
7+
8+ ++ un :: =(x (wred (wren x)))
9+ |%
10+
11+A core that contains arms that perform reversible scrambling operations.
12+Used in the `@p` phonetic base.
13+
14+------------------------------------------------------------------------
15+
16+### `++wren`
17+
18+Conceal structure
19+
20+ ++ wren :: conceal structure
21+ |= pyn=@ ^- @
22+ =+ len=(met 3 pyn)
23+ ?: =(0 len)
24+ 0
25+ => .(len (dec len))
26+ =+ mig=(zaft (xafo len (cut 3 [len 1] pyn)))
27+ %+ can 3
28+ %- flop ^- (list ,[@ @])
29+ :- [1 mig]
30+ |- ^- (list ,[@ @])
31+ ?: =(0 len)
32+ ~
33+ => .(len (dec len))
34+ =+ mog=(zyft :(mix mig (end 3 1 len) (cut 3 [len 1] pyn)))
35+ [[1 mog] $(mig mog)]
36+ ::
37+
38+Scrambles a bytestring `pyn` by adding the current position to each
39+byte, looking it up in an s-box, and then performing the XOR operation
40+on the result, pushing it forward. Produces an atom.
41+
42+`pyn` is an [atom]().
43+
44+ ~zod/try=> `@ux`(wren:un 'testing')
45+ 0x30.bf6a.b9fe.7d8f
46+ ~zod/try=> `@ux`'testing'
47+ 0x67.6e69.7473.6574
48+ ~zod/try=> `@da`(wred:un (wren:un ~2001.2.5))
49+ ~2001.2.5
50+
51+------------------------------------------------------------------------
52+
53+### `++wred`
54+
55+Restore structure
56+
57+ ++ wred :: restore structure
58+ |= cry=@ ^- @
59+ =+ len=(met 3 cry)
60+ ?: =(0 len)
61+ 0
62+ => .(len (dec len))
63+ =+ mig=(cut 3 [len 1] cry)
64+ %+ can 3
65+ %- flop ^- (list ,[@ @])
66+ :- [1 (xaro len (zart mig))]
67+ |- ^- (list ,[@ @])
68+ ?: =(0 len)
69+ ~
70+ => .(len (dec len))
71+ =+ mog=(cut 3 [len 1] cry)
72+ [[1 :(mix mig (end 3 1 len) (zyrt mog))] $(mig mog)]
73+ ::
74+
75+Unscrambles a bytestring `cry` by subtracting the current position from
76+each byte, looking it up in an s-box, and performing the XOR operation
77+on the result, pushing it forward. Produces an atom.
78+
79+`cry` is an [atom]().
80+
81+ ~zod/try=> (wred:un 0x30.bf6a.b9fe.7d8f)
82+ 29.113.321.805.538.676
83+ ~zod/try=> `@t`(wred:un 0x30.bf6a.b9fe.7d8f)
84+ 'testing'
85+ ~zod/try=> (wred:un (wren:un 200.038.426))
86+ 200.038.426
87+
88+------------------------------------------------------------------------
89+
90+### `++xafo`
91+
92+Add modulo 255
93+
94+ ++ xafo |=([a=@ b=@] +((mod (add (dec b) a) 255)))
95+
96+Produces the sum of two atoms modulo 255, encoded as a nonzero byte.
97+
98+ ~zod/try=> (xafo:un 5 6)
99+ 11
100+ ~zod/try=> (xafo:un 256 20)
101+ 21
102+
103+------------------------------------------------------------------------
104+
105+### `++xaro`
106+
107+Subtract modulo 255
108+
109+ ++ xaro |=([a=@ b=@] +((mod (add (dec b) (sub 255 (mod a 255))) 255)))
110+
111+Produces the difference between two atoms modulo 255, encoded as a
112+nonzero byte.
113+
114+ ~zod/try=> (xaro:un 17 57)
115+ 40
116+ ~zod/try=> (xaro:un 265 12)
117+ 2
118+
119+------------------------------------------------------------------------
120+
121+### `++zaft`
122+
123+Look up in 255 sub box
124+
125+ ++ zaft :: forward 255-sbox
126+ |= a=@D
127+ =+ ^= b
128+ 0xcc.75bc.86c8.2fb1.9a42.f0b3.79a0.92ca.21f6.1e41.cde5.fcc0.
129+ 7e85.51ae.1005.c72d.1246.07e8.7c64.a914.8d69.d9f4.59c2.8038.
130+ 1f4a.dca2.6fdf.66f9.f561.a12e.5a16.f7b0.a39f.364e.cb70.7318.
131+ 1de1.ad31.63d1.abd4.db68.6a33.134d.a760.edee.5434.493a.e323.
132+ 930d.8f3d.3562.bb81.0b24.43cf.bea5.a6eb.52b4.0229.06b2.6704.
133+ 78c9.45ec.d75e.58af.c577.b7b9.c40e.017d.90c3.87f8.96fa.1153.
134+ 0372.7f30.1c32.ac83.ff17.c6e4.d36d.6b55.e2ce.8c71.8a5b.b6f3.
135+ 9d4b.eab5.8b3c.e7f2.a8fe.9574.5de0.bf20.3f15.9784.9939.5f9c.
136+ e609.564f.d8a4.b825.9819.94aa.2c08.8e4c.9b22.477a.2840.3ed6.
137+ 3750.6ef1.44dd.89ef.6576.d00a.fbda.9ed2.3b6c.7b0c.bde9.2ade.
138+ 5c88.c182.481a.1b0f.2bfd.d591.2726.57ba
139+ (cut 3 [(dec a) 1] b)
140+ ::
141+
142+The inverse of [`++zart`](). Looks up a nonzero byte`a\` in a substiution
143+box with 255 values, producing a unique nonzero byte.
144+
145+`a` is an [atom]() of one byte in length.
146+
147+ ~zod/try=> (zaft:un 0x12)
148+ 42
149+ ~zod/try=> (zaft:un 0xff)
150+ 204
151+ ~zod/try=> (zaft:un 0x0)
152+ ! decrement-underflow
153+ ! exit
154+
155+------------------------------------------------------------------------
156+
157+### `++zart`
158+
159+Reverse look up in 255 sub box
160+
161+ ++ zart :: reverse 255-sbox
162+ |= a=@D
163+ =+ ^= b
164+ 0x68.4f07.ea1c.73c9.75c2.efc8.d559.5125.f621.a7a8.8591.5613.
165+ dd52.40eb.65a2.60b7.4bcb.1123.ceb0.1bd6.3c84.2906.b164.19b3.
166+ 1e95.5fec.ffbc.f187.fbe2.6680.7c77.d30e.e94a.9414.fd9a.017d.
167+ 3a7e.5a55.8ff5.8bf9.c181.e5b6.6ab2.35da.50aa.9293.3bc0.cdc6.
168+ f3bf.1a58.4130.f844.3846.744e.36a0.f205.789e.32d8.5e54.5c22.
169+ 0f76.fce7.4569.0d99.d26e.e879.dc16.2df4.887f.1ffe.4dba.6f5d.
170+ bbcc.2663.1762.aed7.af8a.ca20.dbb4.9bc7.a942.834c.105b.c4d4.
171+ 8202.3e61.a671.90e6.273d.bdab.3157.cfa4.0c2e.df86.2496.f7ed.
172+ 2b48.2a9d.5318.a343.d128.be9c.a5ad.6bb5.6dfa.c5e1.3408.128d.
173+ 2c04.0339.97a1.2ff0.49d0.eeb8.6c0a.0b37.b967.c347.d9ac.e072.
174+ e409.7b9f.1598.1d3f.33de.8ce3.8970.8e7a
175+ (cut 3 [(dec a) 1] b)
176+ ::
177+
178+The inverse of [`++zaft`](). Looks up the index of a nonzero byte `a` in
179+the substitution box with 255 values, producing a unique nonzero byte.
180+
181+`a` is an [atom]() of one byte in length.
182+
183+ ~zod/try=> `@ux`(zart:un 204)
184+ 0xff
185+ ~zod/try=> `@ux`(zart:un 42)
186+ 0x12
187+
188+------------------------------------------------------------------------
189+
190+### `++zyft`
191+
192+Lookup byte in 256 sub box
193+
194+ ++ zyft :: forward 256-sbox
195+ |= a=@D
196+ =+ ^= b
197+ 0xbb49.b71f.b881.b402.17e4.6b86.69b5.1647.115f.dddb.7ca5.
198+ 8371.4bd5.19a9.b092.605d.0d9b.e030.a0cc.78ba.5706.4d2d.
199+ 986a.768c.f8e8.c4c7.2f1c.effe.3cae.01c0.253e.65d3.3872.
200+ ce0e.7a74.8ac6.daac.7e5c.6479.44ec.4143.3d20.4af0.ee6c.
201+ c828.deca.0377.249f.ffcd.7b4f.eb7d.66f2.8951.042e.595a.
202+ 8e13.f9c3.a79a.f788.6199.9391.7fab.6200.4ce5.0758.e2f1.
203+ 7594.c945.d218.4248.afa1.e61a.54fb.1482.bea4.96a2.3473.
204+ 63c2.e7cb.155b.120a.4ed7.bfd8.b31b.4008.f329.fca3.5380.
205+ 9556.0cb2.8722.2bea.e96e.3ac5.d1bc.10e3.2c52.a62a.b1d6.
206+ 35aa.d05e.f6a8.0f3b.31ed.559d.09ad.f585.6d21.fd1d.8d67.
207+ 370b.26f4.70c1.b923.4684.6fbd.cf8b.5036.0539.9cdc.d93f.
208+ 9068.1edf.8f33.b632.d427.97fa.9ee1
209+ (cut 3 [a 1] b)
210+ ::
211+
212+The inverse of [`++zyrt`](). Looks up a byte `a` in a substituion box
213+with 256 values, producing a byte.
214+
215+`a` is an [atom]() of one byte in length.
216+
217+ ~zod/try=> (zyft:un 0x12)
218+ 57
219+ ~zod/try=> (zyft:un 0x0)
220+ 225
221+ ~zod/try=> (zyft:un 0xff)
222+ 187
223+
224+------------------------------------------------------------------------
225+
226+### `++zyrt`
227+
228+Reverse lookup byte in 256 sub box
229+
230+ ++ zyrt :: reverse 256-sbox
231+ |= a=@D
232+ =+ ^= b
233+ 0x9fc8.2753.6e02.8fcf.8b35.2b20.5598.7caa.c9a9.30b0.9b48.
234+ 47ce.6371.80f6.407d.00dd.0aa5.ed10.ecb7.0f5a.5c3a.e605.
235+ c077.4337.17bd.9eda.62a4.79a7.ccb8.44cd.8e64.1ec4.5b6b.
236+ 1842.ffd8.1dfb.fd07.f2f9.594c.3be3.73c6.2cb6.8438.e434.
237+ 8d3d.ea6a.5268.72db.a001.2e11.de8c.88d3.0369.4f7a.87e2.
238+ 860d.0991.25d0.16b9.978a.4bf4.2a1a.e96c.fa50.85b5.9aeb.
239+ 9dbb.b2d9.a2d1.7bba.66be.e81f.1946.29a8.f5d2.f30c.2499.
240+ c1b3.6583.89e1.ee36.e0b4.6092.937e.d74e.2f6f.513e.9615.
241+ 9c5d.d581.e7ab.fe74.f01b.78b1.ae75.af57.0ec2.adc7.3245.
242+ 12bf.2314.3967.0806.31dc.cb94.d43f.493c.54a6.0421.c3a1.
243+ 1c4a.28ac.fc0b.26ca.5870.e576.f7f1.616d.905f.ef41.33bc.
244+ df4d.225e.2d56.7fd6.1395.a3f8.c582
245+ (cut 3 [a 1] b)
246+
247+The inverse of [`++zyft`](/doc/hoon/library/2en#++zyft). Looks up a byte `a` in a substituion box
248+with 256 values, producing a byte.
249+
250+`a` is an [atom]() of one byte in length.
251+
252+ ~zod/try=> `@ux`(zyrt:un 57)
253+ 0x12
254+ ~zod/try=> `@ux`(zyrt:un 225)
255+ 0x0
256+ ~zod/try=> `@ux`(zyrt:un 187)
257+ 0xff
258+
259+### `++ob`
260+
261+Reversible scrambling core, v2
262+
263+ ++ ob
264+ |%
265+
266+A core for performing reversible scrambling operations for the `@p` phonetic base.
267+
268+------------------------------------------------------------------------
269+
270+### `++feen`
271+
272+Conceal structure, v2
273+
274+ ++ feen :: conceal structure v2
275+ |= pyn=@ ^- @
276+ ?: &((gte pyn 0x1.0000) (lte pyn 0xffff.ffff))
277+ (add 0x1.0000 (fice (sub pyn 0x1.0000)))
278+ ?: &((gte pyn 0x1.0000.0000) (lte pyn 0xffff.ffff.ffff.ffff))
279+ =+ lo=(dis pyn 0xffff.ffff)
280+ =+ hi=(dis pyn 0xffff.ffff.0000.0000)
281+ %+ con hi
282+ (add 0x1.0000 (fice (sub lo 0x1.0000)))
283+ pyn
284+
285+Randomly permutes atoms that fit into 17 to 32 bits into one another. If the atom fits into 33 to 64 bits, does the same permutation on the low 32 bits only. Otherwise, passes the atom through unchanged.
286+
287+------------------------------------------------------------------------
288+
289+### `++fend`
290+
291+ ++ fend :: restore structure v2
292+ |= cry=@ ^- @
293+ ?: &((gte cry 0x1.0000) (lte cry 0xffff.ffff))
294+ (add 0x1.0000 (teil (sub cry 0x1.0000)))
295+ ?: &((gte cry 0x1.0000.0000) (lte cry 0xffff.ffff.ffff.ffff))
296+ =+ lo=(dis cry 0xffff.ffff)
297+ =+ hi=(dis cry 0xffff.ffff.0000.0000)
298+ %+ con hi
299+ (add 0x1.0000 (teil (sub lo 0x1.0000)))
300+ cry
301+
302+Randomly permutes atoms that fit into 17 to 32 bits into one another, and randomly permutes the low 32 bits of atoms that fit into 33 to 64 bits; otherwise, passes the atom through unchanged. The permutation is the inverse of the one applied by [`++feen`]().
303+
304+------------------------------------------------------------------------
305+
306+### `++fice`
307+
308+ ++ fice :: adapted from
309+ |= nor=@ :: black and rogaway
310+ ^- @ :: "ciphers with
311+ =+ ^= sel :: arbitrary finite
312+ %+ rynd 2 :: domains", 2002
313+ %+ rynd 1
314+ %+ rynd 0
315+ [(mod nor 65.535) (div nor 65.535)]
316+ (add (mul 65.535 -.sel) +.sel)
317+
318+Applies a 3-round Feistel-like cipher to randomly permute atoms in the range `0` to `2^32 - 2^16`. The construction given in Black and Rogaway is ideal for a domain with a size of that form, and as with a conventionel Feistel cipher, three rounds suffice to make the permutation pseudorandom.
319+
320+------------------------------------------------------------------------
321+
322+### `++teil`
323+
324+ ++ teil :: reverse ++fice
325+ |= vip=@
326+ ^- @
327+ =+ ^= sel
328+ %+ rund 0
329+ %+ rund 1
330+ %+ rund 2
331+ [(mod vip 65.535) (div vip 65.535)]
332+ (add (mul 65.535 -.sel) +.sel)
333+
334+Applies the reverse of the Feistel-like cipher applied by [`++fice`](). Unlike a conventional Feistel cipher that is its own inverse if keys are used in reverse order, this Feistel-like cipher uses two moduli that must be swapped when applying the reverse transformation.
335+
336+------------------------------------------------------------------------
337+
338+### `++rynd`
339+
340+ ++ rynd :: feistel round
341+ |= [n=@ l=@ r=@]
342+ ^- [@ @]
343+ :- r
344+ ?~ (mod n 2)
345+ (~(sum fo 65.535) l (en:aesc (snag n raku) r))
346+ (~(sum fo 65.536) l (en:aesc (snag n raku) r))
347+
348+A single round of the Feistel-like cipher [`++fice`](). AES ([`++aesc`]()) is used as the round function.
349+
350+------------------------------------------------------------------------
351+
352+### `++rund`
353+
354+ ++ rund :: reverse round
355+ |= [n=@ l=@ r=@]
356+ ^- [@ @]
357+ :- r
358+ ?~ (mod n 2)
359+ (~(dif fo 65.535) l (en:aesc (snag n raku) r))
360+ (~(dif fo 65.536) l (en:aesc (snag n raku) r))
361+
362+A single round of the Feistel-like reverse cipher [`++teil`]().
363+
364+------------------------------------------------------------------------
365+
366+### `++raku`
367+
368+ ++ raku
369+ ^- (list ,@ux)
370+ :~ 0x15f6.25e3.083a.eb3e.7a55.d4db.fb99.32a3.
371+ 43af.2750.219e.8a24.e5f8.fac3.6c36.f968
372+ 0xf2ff.24fe.54d0.1abd.4b2a.d8aa.4402.8e88.
373+ e82f.19ec.948d.b1bb.ed2e.f791.83a3.8133
374+ 0xa3d8.6a7b.400e.9e91.187d.91a7.6942.f34a.
375+ 6f5f.ab8e.88b9.c089.b2dc.95a6.aed5.e3a4
376+ ==
377+
378+Arbitrary keys for use with [`++aesc`]().
docs/dev/hoon/library/2eo.mdnew file+453
@@ -0,0 +1,453 @@
1+section 2eO, virtualization
2+===========================
3+
4+### `++mack`
5+
6+Nock subject to unit
7+
8+ ++ mack
9+ |= [sub=* fol=*]
10+ ^- (unit)
11+ =+ ton=(mink [sub fol] |=(* ~))
12+ ?.(?=([0 *] ton) ~ [~ p.ton])
13+ ::
14+
15+Accepts a nock subject-formula cell and wraps it into a [`++unit`]().
16+`fol` is pure nock, meaning that nock `11` operations result in a block,
17+producing a `~`.
18+
19+`sub` is a subject [noun]().
20+
21+`fol` is a formula [noun](), which is generally a `++nock`.
22+
23+ ~zod/try=> (mack [[1 2 3] [0 1]])
24+ [~ [1 2 3]]
25+ ~zod/try=> (mack [41 4 0 1])
26+ [~ 42]
27+ ~zod/try=> (mack [4 0 4])
28+ ~
29+ ~zod/try=> (mack [[[0 2] [1 3]] 4 4 4 4 0 5])
30+ [~ 6]
31+ ~zod/try=> ;;((unit ,@tas) (mack [[1 %yes %no] 6 [0 2] [0 6] 0 7]))
32+ [~ %no]
33+
34+------------------------------------------------------------------------
35+
36+### `++mink`
37+
38+Mock interpreter
39+
40+ ++ mink
41+ ~/ %mink
42+ |= [[sub=* fol=*] sky=$+(* (unit))]
43+ =+ tax=*(list ,[@ta *])
44+ |- ^- tone
45+ ?@ fol
46+ [%2 tax]
47+ ?: ?=(^ -.fol)
48+ =+ hed=$(fol -.fol)
49+ ?: ?=(%2 -.hed)
50+ hed
51+ =+ tal=$(fol +.fol)
52+ ?- -.tal
53+ %0 ?-(-.hed %0 [%0 p.hed p.tal], %1 hed)
54+ %1 ?-(-.hed %0 tal, %1 [%1 (weld p.hed p.tal)])
55+ %2 tal
56+ ==
57+ ?+ fol
58+ [%2 tax]
59+ ::
60+ [0 b=@]
61+ ?: =(0 b.fol) [%2 tax]
62+ ?: =(1 b.fol) [%0 sub]
63+ ?: ?=(@ sub) [%2 tax]
64+ =+ [now=(cap b.fol) lat=(mas b.fol)]
65+ $(b.fol lat, sub ?:(=(2 now) -.sub +.sub))
66+ ::
67+ [1 b=*]
68+ [%0 b.fol]
69+ ::
70+ [2 b=[^ *]]
71+ =+ ben=$(fol b.fol)
72+ ?. ?=(%0 -.ben) ben
73+ ?>(?=(^ p.ben) $(sub -.p.ben, fol +.p.ben))
74+ ::?>(?=(^ p.ben) $([sub fol] p.ben)
75+ ::
76+ [3 b=*]
77+ =+ ben=$(fol b.fol)
78+ ?. ?=(%0 -.ben) ben
79+ [%0 .?(p.ben)]
80+ ::
81+ [4 b=*]
82+ =+ ben=$(fol b.fol)
83+ ?. ?=(%0 -.ben) ben
84+ ?. ?=(@ p.ben) [%2 tax]
85+ [%0 .+(p.ben)]
86+ ::
87+ [5 b=*]
88+ =+ ben=$(fol b.fol)
89+ ?. ?=(%0 -.ben) ben
90+ ?. ?=(^ p.ben) [%2 tax]
91+ [%0 =(-.p.ben +.p.ben)]
92+ ::
93+ [6 b=* c=* d=*]
94+ $(fol =>(fol [2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]))
95+ ::
96+ [7 b=* c=*] $(fol =>(fol [2 b 1 c]))
97+ [8 b=* c=*] $(fol =>(fol [7 [[0 1] b] c]))
98+ [9 b=* c=*] $(fol =>(fol [7 c 0 b]))
99+ [10 @ c=*] $(fol c.fol)
100+ [10 [b=* c=*] d=*]
101+ =+ ben=$(fol c.fol)
102+ ?. ?=(%0 -.ben) ben
103+ ?: ?=(?(%hunk %lose %mean %spot) b.fol)
104+ $(fol d.fol, tax [[b.fol p.ben] tax])
105+ $(fol d.fol)
106+ ::
107+ [11 b=*]
108+ =+ ben=$(fol b.fol)
109+ ?. ?=(%0 -.ben) ben
110+ =+ val=(sky p.ben)
111+ ?~(val [%1 p.ben ~] [%0 u.val])
112+ ::
113+ ==
114+ ::
115+
116+Bottom-level [mock]() (virtual nock) interpreter. Produces a
117+[`++tone`](), a nock computation result. If nock 11 is invoked, `sky`
118+computes on the subject and produces a [`++unit`]() result. An empty
119+result becomes a `%1` `++tone`, indicating a block.
120+
121+`sub` is the subject as a [noun]().
122+
123+`fol` is the formula as a [noun]().
124+
125+`sky` is an [`%iron`]() gate invoked with [nock operator 11]().
126+
127+ ~zod/try=> (mink [20 [4 0 1]] ,~)
128+ [%0 p=21]
129+ ~zod/try=> (mink [[90 5 3] [0 3]] ,~)
130+ [%0 p=[5 3]]
131+ ~zod/try=> (mink 20^[4 0 1] ,~)
132+ [%0 p=21]
133+ ~zod/try=> (mink [90 5 3]^[0 3] ,~)
134+ [%0 p=[5 3]]
135+ ~zod/try=> (mink [0]^[11 1 20] ,~)
136+ [%1 p=~[20]]
137+ ~zod/try=> (mink [0]^[11 1 20] |=(a=* `[40 a]))
138+ [%0 p=[40 20]]
139+ ~zod/try=> (mink [5]^[0 2] ,~)
140+ [%2 p=~]
141+ ~zod/try=> (mink [5]^[10 yelp/[0 1] 0 0] ,~)
142+ [%2 p=~[[~.yelp 5]]]
143+
144+------------------------------------------------------------------------
145+
146+### `++mock`
147+
148+Compute formula on subject with hint
149+
150+ ++ mock
151+ |= [[sub=* fol=*] sky=$+(* (unit))]
152+ (mook (mink [sub fol] sky))
153+ ::
154+
155+Produces a [`++toon`](), which is either a sucessful, blocked, or
156+crashed result. If nock 11 is invoked, `sky` computes on the subject and
157+produces a [`++unit`]() result. An empty result becomes a `%1` `++tune`,
158+indicating a block.
159+
160+`sub` is the subject as a [noun]().
161+
162+`fol` is the formula as a [noun]().
163+
164+`sky` is an [%iron]() gate invoked with [nock operator 11]().
165+
166+ ~zod/try=> (mock [5 4 0 1] ,~)
167+ [%0 p=6]
168+ ~zod/try=> (mock [~ 11 1 0] |=(* `999))
169+ [%0 p=999]
170+ ~zod/try=> (mock [~ 0 1.337] ,~)
171+ [%2 p=~]
172+ ~zod/try=> (mock [~ 11 1 1.337] ,~)
173+ [%1 p=~[1.337]]
174+ ~zod/try=> (mock [[[4 4 4 4 0 3] 10] 11 9 2 0 1] |=(* `[+<]))
175+ [%0 p=14]
176+ ~zod/try=> (mock [[[4 4 4 4 0 3] 10] 11 9 2 0 1] |=(* `[<+<>]))
177+ [%0 p=[49 52 0]]
178+ ~zod/try=> ;;(tape +:(mock [[[4 4 4 4 0 3] 10] 11 9 2 0 1] |=(* `[<+<>])))
179+ "14"
180+
181+------------------------------------------------------------------------
182+
183+### `++mook`
184+
185+Intelligently render crash annotation
186+
187+ ++ mook
188+ |= ton=tone
189+ ^- toon
190+ ?. ?=([2 *] ton) ton
191+ :- %2
192+ =+ yel=(lent p.ton)
193+ =. p.ton
194+ ?. (gth yel 256) p.ton
195+ %+ weld
196+ (scag 128 p.ton)
197+ ^- (list ,[@ta *])
198+ :_ (slag (sub yel 128) p.ton)
199+ :- %lose
200+ %+ rap 3
201+ ;: weld
202+ "[skipped "
203+ ~(rend co %$ %ud (sub yel 256))
204+ " frames]"
205+ ==
206+ |- ^- (list tank)
207+ ?~ p.ton ~
208+ =+ rex=$(p.ton t.p.ton)
209+ ?+ -.i.p.ton rex
210+ %hunk [(tank +.i.p.ton) rex]
211+ %lose [[%leaf (rip 3 (,@ +.i.p.ton))] rex]
212+ %mean :_ rex
213+ ?@ +.i.p.ton [%leaf (rip 3 (,@ +.i.p.ton))]
214+ =+ mac=(mack +.i.p.ton +<.i.p.ton)
215+ ?~(mac [%leaf "####"] (tank u.mac))
216+ %spot :_ rex
217+ =+ sot=(spot +.i.p.ton)
218+ :- %leaf
219+ ;: weld
220+ ~(ram re (smyt p.sot))
221+ ":<["
222+ ~(rend co ~ %ud p.p.q.sot)
223+ " "
224+ ~(rend co ~ %ud q.p.q.sot)
225+ "].["
226+ ~(rend co ~ %ud p.q.q.sot)
227+ " "
228+ ~(rend co ~ %ud q.q.q.sot)
229+ "]>"
230+ ==
231+ ==
232+ ::
233+
234+Converts a `%2` `++tone` nock stack trace to a list of [`++tank`]().
235+Each may be a tank, cord, [`++spot`](), or trapped tank. Produces a
236+[`++toon`]().
237+
238+`ton` is a [`++tone`]().
239+
240+ ~zod/try=> (mook [%0 5 4 5 1])
241+ [%0 p=[5 4 5 1]]
242+ ~zod/try=> (mook [%2 ~[[%hunk %rose ["<" "," ">"] ~[[%leaf "err"]]]]])
243+ [%2 p=~[[%rose p=[p="<" q="," r=">"] q=[i=[%leaf p="err"] t=~]]]]
244+ ~zod/try=> (mook [%2 ~[[%malformed %elem] [%lose 'do print']]])
245+ [%2 p=~[[%leaf p="do print"]]]
246+ ~zod/try=> (mook [%2 ~[[%mean |.(>(add 5 6)<)]]])
247+ [%2 p=~[[%leaf p="11"]]]
248+ ~zod/try=> (mook [%2 ~[[%spot /b/repl [1 1]^[1 2]] [%mean |.(!!)]]])
249+ [%2 p=~[[%leaf p="/b/repl/:<[1 1].[1 2]>"] [%leaf p="####"]]]
250+
251+------------------------------------------------------------------------
252+
253+### `++mang`
254+
255+Unit: Slam gate with sample
256+
257+ ++ mang
258+ |= [[gat=* sam=*] sky=$+(* (unit))]
259+ ^- (unit)
260+ =+ ton=(mong [[gat sam] sky])
261+ ?.(?=([0 *] ton) ~ [~ p.ton])
262+ ::
263+
264+Produces a [`++unit`]() computation result from slamming `gat` with
265+`sam`, using `sky` to compute or block on nock 11 when applicable.
266+Similar to [`++mong`]().
267+
268+`gat` is a [noun]() that is generally a [`gate`]().
269+
270+`sam` is a [`sample`]() noun.
271+
272+`sky` is an [%iron]() gate invoked with [nock operator 11]().
273+
274+ ~zod/try=> (mang [|=(@ 20) ~] ,~)
275+ [~ 20]
276+ ~zod/try=> (mang [|=(@ !!) ~] ,~)
277+ ~
278+ ~zod/try=> (mang [|=(a=@ (add 20 a)) ~] ,~)
279+ [~ 20]
280+ ~zod/try=> (mang [|=(a=[@ @] (add 20 -.a)) ~] ,~)
281+ ~
282+ ~zod/try=> (mang [|=(a=[@ @] (add 20 -.a)) [4 6]] ,~)
283+ [~ 24]
284+ ~zod/try=> (mang [|=(a=@ .^(a)) ~] ,~)
285+ ~
286+ ~zod/try=> (mang [|=(a=@ .^(a)) ~] ,[~ %42])
287+ [~ 42]
288+ ~zod/try=> (mang [|=(a=@ .^(a)) ~] |=(a=* [~ a 6]))
289+ [~ [0 6]]
290+ ~zod/try=> (mang [|=(a=@ .^(a)) 8] |=(a=* [~ a 6]))
291+ [~ [8 6]]
292+
293+------------------------------------------------------------------------
294+
295+### `++mong`
296+
297+Slam gate with sample
298+
299+ ++ mong
300+ |= [[gat=* sam=*] sky=$+(* (unit))]
301+ ^- toon
302+ ?. &(?=(^ gat) ?=(^ +.gat))
303+ [%2 ~]
304+ (mock [[-.gat [sam +>.gat]] -.gat] sky)
305+ ::
306+
307+Produces a [`++toon`]() computation result from slamming `gat` with
308+`sam`, using `sky` to compute or block on nock 11 when applicable.
309+
310+`gat` is a [noun]() that is generally a [`gate`]().
311+
312+`sam` is a [`sample`]() noun.
313+
314+`sky` is an [%iron]() gate invoked with [nock operator 11]().
315+
316+ ~zod/try=> (mong [|=(@ 20) ~] ,~)
317+ [%0 p=20]
318+ ~zod/try=> (mong [|=(@ !!) ~] ,~)
319+ [%2 p=~]
320+ ~zod/try=> (mong [|=(a=@ (add 20 a)) ~] ,~)
321+ [%0 p=20]
322+ ~zod/try=> (mong [|=(a=[@ @] (add 20 -.a)) ~] ,~)
323+ [%2 p=~]
324+ ~zod/try=> (mong [|=(a=[@ @] (add 20 -.a)) [4 6]] ,~)
325+ [%0 p=24]
326+ ~zod/try=> (mong [|=(a=@ .^(a)) ~] ,~)
327+ [%1 p=~[0]]
328+ ~zod/try=> (mong [|=(a=@ .^(a)) ~] ,[~ %42])
329+ [%0 p=42]
330+ ~zod/try=> (mong [|=(a=@ .^(a)) ~] |=(a=* [~ a 6]))
331+ [%0 p=[0 6]]
332+ ~zod/try=> (mong [|=(a=@ .^(a)) 8] |=(a=* [~ a 6]))
333+ [%0 p=[8 6]]
334+
335+------------------------------------------------------------------------
336+
337+### `++mung`
338+
339+Virtualize slamming gate
340+
341+ ++ mung
342+ |= [[gat=* sam=*] sky=$+(* (unit))]
343+ ^- tone
344+ ?. &(?=(^ gat) ?=(^ +.gat))
345+ [%2 ~]
346+ (mink [[-.gat [sam +>.gat]] -.gat] sky)
347+ ::
348+
349+Produces a [`++tone`]() computation result from slamming `gat` with
350+`sam`, using `sky` to compute or block on nock 11 when applicable.
351+
352+`gat` is a [noun]() that is generally a [`gate`]().
353+
354+`sam` is a [`sample`]() noun.
355+
356+`sky` is an [%iron]() gate invoked with [nock operator 11]().
357+
358+ ~zod/try=> (mung [|=(@ 20) ~] ,~)
359+ [%0 p=20]
360+ ~zod/try=> (mung [|=(@ !!) ~] ,~)
361+ [%2 p=~]
362+ ~zod/try=> (mung [|=(a=@ (add 20 a)) ~] ,~)
363+ [%0 p=20]
364+ ~zod/try=> (mung [|=(a=[@ @] (add 20 -.a)) ~] ,~)
365+ [%2 p=~]
366+ ~zod/try=> (mung [|=(a=[@ @] (add 20 -.a)) [4 6]] ,~)
367+ [%0 p=24]
368+ ~zod/try=> (mung [|=(a=@ .^(a)) ~] ,~)
369+ [%1 p=~[0]]
370+ ~zod/try=> (mung [|=(a=@ .^(a)) ~] ,[~ %42])
371+ [%0 p=42]
372+ ~zod/try=> (mung [|=(a=@ .^(a)) ~] |=(a=* [~ a 6]))
373+ [%0 p=[0 6]]
374+ ~zod/try=> (mung [|=(a=@ .^(a)) 8] |=(a=* [~ a 6]))
375+ [%0 p=[8 6]]
376+
377+------------------------------------------------------------------------
378+
379+### `++mule`
380+
381+Typed virtual
382+
383+ ++ mule :: typed virtual
384+ ~/ %mule
385+ |* taq=_|.(_*)
386+ =+ mud=(mute taq)
387+ ?- -.mud
388+ & [%& p=$:taq]
389+ | [%| p=p.mud]
390+ ==
391+ ::
392+
393+Kicks a `++trap`, producing its results or any errors that occur along
394+the way. Used to lazily compute stack traces.
395+
396+`taq` is a [`++trap`](), generally producing a list of [`++tank`]()s.
397+
398+ ~zod/try=> (mule |.(leaf/"hello"))
399+ [%.y p=[%leaf "hello"]]
400+ ~zod/try=> (mule |.(!!))
401+ [%.n p=~]
402+ ~zod/try=> (mule |.(.^(a//=pals/1)))
403+ [ %.n
404+ p
405+ ~[
406+ [ %rose
407+ p=[p="/" q="/" r="/"]
408+ q
409+ [ i=[%leaf p="a"]
410+ t=[i=[%leaf p="~zod"] t=[i=[%leaf p="pals"] t=[i=[%leaf p="1"] t=~]]]
411+ ]
412+ ]
413+ ]
414+ ]
415+
416+------------------------------------------------------------------------
417+
418+### `++mute`
419+
420+Untyped virtual
421+
422+ ++ mute :: untyped virtual
423+ |= taq=_^?(|.(_*))
424+ ^- (each ,* (list tank))
425+ =+ ton=(mock [taq 9 2 0 1] |=(* ~))
426+ ?- -.ton
427+ %0 [%& p.ton]
428+ %1 [%| (turn p.ton |=(a=* (smyt (path a))))]
429+ %2 [%| p.ton]
430+ ==
431+
432+Kicks a `++trap`, producing its result as a noun or the tanks of any
433+error that occurs. Similar to [`++mule`](), but preserves no type
434+information.
435+
436+`taq` is a [`++trap`](/doc/hoon/library/1#++trap).
437+
438+ ~zod/try=> (mute |.(leaf/"hello"))
439+ [%.y p=[1.717.658.988 104 101 108 108 111 0]]
440+ ~zod/try=> (mute |.(!!))
441+ [%.n p=~]
442+ ~zod/try=> (mute |.(.^(a//=pals/1)))
443+ [ %.n
444+ p
445+ ~[
446+ [ %rose
447+ p=[p="/" q="/" r="/"]
448+ q=[i=[%leaf p="a"] t=[i=[%leaf p="~zod"] t=[i=[%leaf p="pals"] t=[i=[%leaf p="1"] t=~]]]]
449+ ]
450+ ]
451+ ]
452+
453+------------------------------------------------------------------------
docs/dev/hoon/library/2ep.mdnew file+586
@@ -0,0 +1,586 @@
1+section 2eP, diff
2+=================
3+
4+A- more or less low priority and/or currently in the wrong section
5+anyway.
6+
7+------------------------------------------------------------------------
8+
9+------------------------------------------------------------------------
10+
11+### `++berk`
12+
13+Invert diff patches
14+
15+ ++ berk :: invert diff patch
16+ |* bur=(urge)
17+ |- ^+ bur
18+ ?~ bur ~
19+ :_ $(bur t.bur)
20+ ?- -.i.bur
21+ & i.bur
22+ | [%| q.i.bur p.i.bur]
23+ ==
24+ ::
25+
26+Inverts a list of changes `bur`. Skips stay constant and replaces are
27+swapped. Produces a `bur`.
28+
29+`bur` is a [`++urge`]().
30+
31+ ~zod/try=> (berk `(urge)`~[`10 %|^[~[2] ~[3 4]] `5])
32+ ~[[%.y p=10] [%.n p=~[3 4] q=~[2]] [%.y p=5]]
33+ ~zod/try=> (lurk "somes" `(urge char)`~[`1 [%| "o" "a"] `3])
34+ "sames"
35+ ~zod/try=> (berk `(urge char)`~[`1 [%| "o" "a"] `3])
36+ ~[[%.y p=1] [%.n p="a" q="o"] [%.y p=3]]
37+ ~zod/try=> (lurk "sames" (berk `(urge char)`~[`1 [%| "o" "a"] `3]))
38+ "somes"
39+
40+------------------------------------------------------------------------
41+
42+### `++diff`
43+
44+Generate patch
45+
46+ ++ diff :: generate patch
47+ |= pum=umph
48+ |= [old=* new=*] ^- udon
49+ :- pum
50+ ?+ pum ~|(%unsupported !!)
51+ %a [%d (nude old new)]
52+ %b =+ [hel=(cue ((hard ,@) old)) hev=(cue ((hard ,@) new))]
53+ [%d (nude hel hev)]
54+ %c =+ [hel=(lore ((hard ,@) old)) hev=(lore ((hard ,@) new))]
55+ [%c (lusk hel hev (loss hel hev))]
56+ ==
57+ ::
58+
59+Produces a patch between two nouns, by change type
60+
61+`pum` is an [`++umph`]().
62+
63+ ~zod/try=> ((diff %a) 20 21)
64+ [p=%a q=[%d p=[%1 p=21] q=[%1 p=20]]]
65+ ~zod/try=> ((diff %a) [1 2 3] [1 2 4])
66+ [ p=%a
67+ q
68+ [ %d
69+ p=[p=[%0 p=2] q=[p=[%0 p=6] q=[%1 p=4]]]
70+ q=[p=[%0 p=2] q=[p=[%0 p=6] q=[%1 p=3]]]
71+ ]
72+ ]
73+ ~zod/try=> ~04hh
74+ [1 2]
75+ ~zod/try=> ~0ph
76+ [1 1]
77+ ~zod/try=> ((diff %b) 0v4hh 0vph)
78+ [p=%b q=[%d p=[p=[%0 p=2] q=[%0 p=2]] q=[p=[%0 p=3] q=[%1 p=2]]]]
79+ ~zod/try=> ((diff %c) (role 'sam' 'les' 'les' 'kor' ~) (role 'sam' 'mor' 'kor' ~))
80+ [p=%c q=[%c p=~[[%.y p=1] [%.n p=~[7.562.604 7.562.604] q=~[7.499.629]] [%.y p=1]]]]
81+ ~[[%.y p=0] [%.y p=0] [%.y p=1] [%.n p=<|les les|> q=<|mor|>] [%.y p=1]]
82+ ~zod/try=> (,[%c %c (urge cord)] ((diff %c) (role 'sam' 'les' 'les' 'kor' ~) (role 'sam' 'mor' 'kor' ~)))
83+ [%c %c ~[[%.y p=1] [%.n p=<|les les|> q=<|mor|>] [%.y p=1]]]
84+
85+------------------------------------------------------------------------
86+
87+### `++loss`
88+
89+Longest subsequence
90+
91+ ++ loss :: longest subsequence
92+ ~/ %loss
93+ |* [hel=(list) hev=(list)]
94+ |- ^+ hev
95+ =+ ^= sev
96+ =+ [inx=0 sev=*(map ,@t (list ,@ud))]
97+ |- ^+ sev
98+ ?~ hev sev
99+ =+ guy=(~(get by sev) i.hev)
100+ $(hev t.hev, inx +(inx), sev (~(put by sev) i.hev [inx ?~(guy ~ u.guy)]))
101+ =| gox=[p=@ud q=(map ,@ud ,[p=@ud q=_hev])]
102+ =< abet
103+ =< main
104+ |%
105+ ++ abet =.(q.rag ?:(=([& 0] p.rag) q.rag [p.rag q.rag]) (flop q.rag))
106+ ++ hink :: extend fits top
107+ |= [inx=@ud goy=@ud] ^- ?
108+ |(=(p.gox inx) (lth goy p:(need (~(get by q.gox) inx))))
109+ ::
110+ ++ lonk :: extend fits bottom
111+ |= [inx=@ud goy=@ud] ^- ?
112+ |(=(0 inx) (gth goy p:(need (~(get by q.gox) (dec inx)))))
113+ ::
114+ ++ lune :: extend
115+ |= [inx=@ud goy=@ud]
116+ ^+ +>
117+ %_ +>.$
118+ gox
119+ :- ?:(=(inx p.gox) +(p.gox) p.gox)
120+ %+ ~(put by q.gox) inx
121+ [goy (snag goy hev) ?:(=(0 inx) ~ q:(need (~(get by q.gox) (dec inx))))]
122+ ==
123+ ::
124+ ++ merg :: merge all matches
125+ |= gay=(list ,@ud)
126+ ^+ +>
127+ =+ ^= zes
128+ =+ [inx=0 zes=*(list ,[p=@ud q=@ud])]
129+ |- ^+ zes
130+ ?: |(?=(~ gay) (gth inx p.gox)) zes
131+ ?. (lonk inx i.gay) $(gay t.gay)
132+ ?. (hink inx i.gay) $(inx +(inx))
133+ $(inx +(inx), gay t.gay, zes [[inx i.gay] zes])
134+ |- ^+ +>.^$
135+ ?~(zes +>.^$ $(zes t.zes, +>.^$ (lune i.zes)))
136+ ::
137+ ++ main
138+ |- ^+ +
139+ ?~ hel
140+ ?~ hev
141+ ?>(?=(~ lcs) +)
142+ $(hev t.hev, rag (done %| ~ [i.hev ~]))
143+ ?~ hev
144+ $(hel t.hel, rag (done %| [i.hel ~] ~))
145+ ?~ lcs
146+ +(rag (done %| (flop hel) (flop hev)))
147+ ?: =(i.hel i.lcs)
148+ ?: =(i.hev i.lcs)
149+ $(lcs t.lcs, hel t.hel, hev t.hev, rag (done %& 1))
150+ $(hev t.hev, rag (done %| ~ [i.hev ~]))
151+ ?: =(i.hev i.lcs)
152+ $(hel t.hel, rag (done %| [i.hel ~] ~))
153+ $(hel t.hel, hev t.hev, rag (done %| [i.hel ~] [i.hev ~]))
154+ --
155+
156+Finds a subsequence of repeated elements within two [`++list`]()s, using
157+several internal helper arms. Produces a [`++tape`]().
158+
159+`hel` is a [`++list`]() of characters.
160+
161+`hev` is a [++list\`]() of characters.
162+
163+ ~zod/try=> (loss "sam" "sem")
164+ "sm"
165+ ~zod/try=> (loss "samo" "semo")
166+ "smo"
167+ ~zod/try=> (loss "sakmo" "semo")
168+ "smo"
169+ ~zod/try=> (loss "ferdinham" "ferdilapos
170+ ~ <syntax error at [1 30]>
171+ ~zod/try=> (loss "ferdinham" "ferdilapos")
172+ "ferdia"
173+
174+------------------------------------------------------------------------
175+
176+### `++locz`
177+
178+Find common
179+
180+ ++ locz :: trivial algorithm
181+ |= [hel=tape hev=tape]
182+ ^- tape
183+ =+ [leh=(lent hel) veh=(lent hev)]
184+ =- (flop q.yun)
185+ ^= yun
186+ |- ^- [p=@ud q=tape]
187+ ~+
188+ ?: |(=(0 leh) =(0 veh)) [0 ~]
189+ =+ [dis=(snag (dec leh) hel) dat=(snag (dec veh) hev)]
190+ ?: =(dis dat)
191+ =+ say=$(leh (dec leh), veh (dec veh))
192+ [+(p.say) [dis q.say]]
193+ =+ [lef=$(leh (dec leh)) rig=$(veh (dec veh))]
194+ ?:((gth p.lef p.rig) lef rig)
195+ ::
196+
197+Finds a subsequence of repeated elements within two [`++list`](/doc/hoon/library/1#++list)s,
198+producing a [\`++tape]().
199+
200+ ~zod/try=> (locz "samukot" "semelkot")
201+ "smkot"
202+ ~zod/try=> (locz "samukot" "samelkot")
203+ "samkot"
204+
205+------------------------------------------------------------------------
206+
207+### `++lore`
208+
209+Split on `\n`
210+
211+ ++ lore :: atom to line list
212+ ~/ %lore
213+ |= lub=@
214+ =| tez=(list ,@t)
215+ |- ^+ tez
216+ ?: =(0 lub) (flop tez)
217+ =+ ^= meg
218+ =+ meg=0
219+ |- ^- @ud
220+ =+ gam=(cut 3 [meg 1] lub)
221+ ?:(|(=(10 gam) =(0 gam)) meg $(meg +(meg)))
222+ =+ res=(rsh 3 +(meg) lub)
223+ ?: &(=(0 (cut 3 [meg 1] lub)) !=(0 res))
224+ !!
225+ $(lub res, tez [(end 3 meg lub) tez])
226+ ::
227+
228+Split on newlines, ascii `10`
229+
230+ ~zod/try=> (lore 'soke\0alas\0amep')
231+ <|soke las mep|>
232+ ~zod/try=> (lore '|= a=@\0a=+ b=(add a 5)\0a(mix b a)')
233+ <||= a=@ =+ b=(add a 5) (mix b a)|>
234+ ~zod/try=> `wain`[(fil 3 80 ' ') (lore '|= a=@\0a=+ b=(add a 5)\0a(mix b a)')]
235+ <|
236+ |= a=@
237+ =+ b=(add a 5)
238+ (mix b a)
239+ |>
240+
241+------------------------------------------------------------------------
242+
243+### `++role`
244+
245+Join with `\n`
246+
247+ ++ role :: line list to atom
248+ |= tez=(list ,@t)
249+ (rap 3 (turn tez |=(a=@t (cat 3 a 10))))
250+ ::
251+
252+Join line list with newlines.
253+
254+ ~zod/try=> (role 'sep' 'tek' 'lap' ~)
255+ 3.230.709.852.558.292.782.985.274.739
256+ ~zod/try=> `@t`(role 'sep' 'tek' 'lap' ~)
257+ '''
258+ sep
259+ tek
260+ lap
261+ '''
262+
263+------------------------------------------------------------------------
264+
265+### `++lump`
266+
267+Change with `++udon`
268+
269+ ++ lump :: apply patch
270+ |= [don=udon src=*]
271+ ^- *
272+ ?+ p.don ~|(%unsupported !!)
273+ %a
274+ ?+ -.q.don ~|(%unsupported !!)
275+ %a q.q.don
276+ %c (lurk ((hard (list)) src) p.q.don)
277+ %d (lure src p.q.don)
278+ ==
279+ ::
280+ %c
281+ =+ dst=(lore ((hard ,@) src))
282+ %- role
283+ ?+ -.q.don ~|(%unsupported !!)
284+ %a ((hard (list ,@t)) q.q.don)
285+ %c (lurk dst p.q.don)
286+ ==
287+ ==
288+ ::
289+
290+Use udon to change noun
291+
292+ ~zod/try=> (lump [%a %a 20 25] 20)
293+ 25
294+ ~zod/try=> (lump [%a %d [[%0 1] [%0 1]] [%0 2]] 20)
295+ [20 20]
296+ ~zod/try=> (lump [%c %a ~['sa' 'le'] ~['sa' 'lo']] 'sa\0ale')
297+ 11.473.670.267.251
298+ ~zod/try=> (,@t (lump [%c %a ~['sa' 'le'] ~['sa' 'lo']] 'sa\0ale'))
299+ '''
300+ sa
301+ lo
302+ '''
303+ ~zod/try=> (,@t (lump [%c %c `1 [%| ~['le'] ~['lo' 'ma']] ~] 'sa\0ale'))
304+ '''
305+ sa
306+ ma
307+ lo
308+ '''
309+
310+------------------------------------------------------------------------
311+
312+### `++lure`
313+
314+Patch `a`
315+
316+ ++ lure :: apply tree diff
317+ |= [a=* b=upas]
318+ ^- *
319+ ?^ -.b
320+ [$(b -.b) $(b +.b)]
321+ ?+ -.b ~|(%unsupported !!)
322+ %0 .*(a [0 p.b])
323+ %1 .*(a [1 p.b])
324+ ==
325+
326+Patch a by references to axis and literal.
327+
328+ ~zod/try=> (lure ~[1 2] [[%0 2] [%1 3] [%0 7]])
329+ [1 3 0]
330+ ~zod/try=> (lure ~[1 2 4] [[%0 2] [%1 3] [%0 7]])
331+ [1 3 4 0]
332+
333+------------------------------------------------------------------------
334+
335+### `++limp`
336+
337+Reverse patch
338+
339+ ++ limp :: invert patch
340+ |= don=udon ^- udon
341+ :- p.don
342+ ?+ -.q.don ~|(%unsupported !!)
343+ %a [%a q.q.don p.q.don]
344+ %c [%c (berk p.q.don)]
345+ %d [%d q.q.don p.q.don]
346+ ==
347+ ::
348+
349+Reverse a patch (preprocessor unchanged)
350+
351+ ~zod/try=> (limp [%a %a 20 40])
352+ [p=%a q=[%a p=40 q=20]]
353+ ~zod/try=> (limp [%c %c ~[`20 [%| ~[52 53] ~[51]] `6]])
354+ [p=%c q=[%c p=~[[%.y p=20] [%.n p=~[51] q=~[52 53]] [%.y p=6]]]]
355+ ~zod/try=> (limp [%a %d [[%0 1] [%0 1]] [%0 2]])
356+ [p=%a q=[%d p=[%0 p=2] q=[p=[%0 p=1] q=[%0 p=1]]]]
357+
358+------------------------------------------------------------------------
359+
360+### `++hump`
361+
362+Prep for diff
363+
364+ ++ hump :: general prepatch
365+ |= [pum=umph src=*] ^- *
366+ ?+ pum ~|(%unsupported !!)
367+ %a src
368+ %b (cue ((hard ,@) src))
369+ %c (lore ((hard ,@) src))
370+ ==
371+ ::
372+
373+Prep atom for diff: leave alone, cue, or split by newlines.
374+
375+ ~zod/try=> (hump %a ~)
376+ 0
377+ ~zod/try=> (hump %a 40)
378+ 40
379+ ~zod/try=> (hump %c 40)
380+ [40 0]
381+ ~zod/try=> (hump %c 'as')
382+ [29.537 0]
383+ ~zod/try=> (hump %c 'as\0alok')
384+ [29.537 7.040.876 0]
385+ ~zod/try=> (hump %b 0vph)
386+ [1 1]
387+
388+------------------------------------------------------------------------
389+
390+### `++husk`
391+
392+Atomize post diff
393+
394+ ++ husk :: unprepatch
395+ |= [pum=umph dst=*] ^- *
396+ ?+ pum ~|(%unsupported !!)
397+ %a dst
398+ %b (jam dst)
399+ %c (role ((hard (list ,@)) dst))
400+ ==
401+ ::
402+
403+Re-atomize after diff: leave alone, jam, or join with newlines.
404+
405+ ~zod/try=> (husk %a 0)
406+ 0
407+ ~zod/try=> (husk %a 40)
408+ 40
409+ ~zod/try=> (husk %c [40 0])
410+ 2.600
411+ ~zod/try=> (rip 3 (,@ (husk %c [40 0])))
412+ ~[40 10]
413+ ~zod/try=> (husk %c [%as 0])
414+ 684.897
415+ ~zod/try=> (husk %c [%as 0])
416+ 684.897
417+ ~zod/try=> (,@t (husk %c [%as 0]))
418+ '''
419+ as
420+ '''
421+ ~zod/try=> (husk %c [%as %lok 0])
422+ 2.932.876.065.272.673
423+ ~zod/try=> (,@t (husk %c [%as %lok 0]))
424+ '''
425+ as
426+ lok
427+ '''
428+ ~zod/try=> (husk %b [1 1])
429+ 817
430+ ~zod/try=> (,@uv (husk %b [1 1]))
431+ 0vph
432+ ~zod/try=> ~0ph
433+ [1 1]
434+
435+------------------------------------------------------------------------
436+
437+### `++lurk`
438+
439+Apply list patch
440+
441+ ++ lurk :: apply list patch
442+ |* [hel=(list) rug=(urge)]
443+ ^+ hel
444+ =+ war=`_hel`~
445+ |- ^+ hel
446+ ?~ rug (flop war)
447+ ?- -.i.rug
448+ &
449+ %= $
450+ rug t.rug
451+ hel (slag p.i.rug hel)
452+ war (weld (flop (scag p.i.rug hel)) war)
453+ ==
454+ ::
455+ |
456+ %= $
457+ rug t.rug
458+ hel =+ gur=(flop p.i.rug)
459+ |- ^+ hel
460+ ?~ gur hel
461+ ?>(&(?=(^ hel) =(i.gur i.hel)) $(hel t.hel, gur t.gur))
462+ war (weld q.i.rug war)
463+ ==
464+ ==
465+ ::
466+
467+Amend list using an urge: list of `[%& {number skipped}]` and
468+`[%| old new]`
469+
470+ ~zod/try=> (lurk "hema" `(urge char)`~[`1 [%| "e" "ru"] `2])
471+ "hurma"
472+ ~zod/try=> (lurk "koltep" `(urge char)`~[`3 [%| "et" ""] `1])
473+ "kolp"
474+
475+------------------------------------------------------------------------
476+
477+### `++lusk`
478+
479+`lcs` to list patch
480+
481+ ++ lusk :: lcs to list patch
482+ |* [hel=(list) hev=(list) lcs=(list)]
483+ =+ ^= rag
484+ ^- $% [& p=@ud]
485+ [| p=_lcs q=_lcs]
486+ ==
487+ [%& 0]
488+ => .(rag [p=rag q=*(list ,_rag)])
489+ =< abet =< main
490+ |%
491+ ++ abet =.(q.rag ?:(=([& 0] p.rag) q.rag [p.rag q.rag]) (flop q.rag))
492+ ++ done
493+ |= new=_p.rag
494+ ^+ rag
495+ ?- -.p.rag
496+ | ?- -.new
497+ | [[%| (weld p.new p.p.rag) (weld q.new q.p.rag)] q.rag]
498+ & [new [p.rag q.rag]]
499+ ==
500+ & ?- -.new
501+ | [new ?:(=(0 p.p.rag) q.rag [p.rag q.rag])]
502+ & [[%& (add p.p.rag p.new)] q.rag]
503+ ==
504+ ==
505+ ::
506+ ++ main
507+ |- ^+ +
508+ ?~ hel
509+ ?~ hev
510+ ?>(?=(~ lcs) +)
511+ $(hev t.hev, rag (done %| ~ [i.hev ~]))
512+ ?~ hev
513+ $(hel t.hel, rag (done %| [i.hel ~] ~))
514+ ?~ lcs
515+ +(rag (done %| (flop hel) (flop hev)))
516+ ?: =(i.hel i.lcs)
517+ ?: =(i.hev i.lcs)
518+ $(lcs t.lcs, hel t.hel, hev t.hev, rag (done %& 1))
519+ $(hev t.hev, rag (done %| ~ [i.hev ~]))
520+ ?: =(i.hev i.lcs)
521+ $(hel t.hel, rag (done %| [i.hel ~] ~))
522+ $(hel t.hel, hev t.hev, rag (done %| [i.hel ~] [i.hev ~]))
523+ --
524+
525+Using a common sequence, generate urge from two lists
526+
527+ ~zod/try=> (lusk "hamok" "hasok" "haok")
528+ ~[[%.y p=2] [%.n p="m" q="s"] [%.y p=2]]
529+ ~zod/try=> (lusk "hamok" "hasok" "hak")
530+ ~[[%.y p=2] [%.n p="om" q="os"] [%.y p=1]]
531+ ~zod/try=> (lusk "telroga" "tesomga" "teoga")
532+ ~[[%.y p=2] [%.n p="rl" q="s"] [%.y p=1] [%.n p="" q="m"] [%.y p=2]]
533+ ~zod/try=> (lurk "telroga" `(urge char)`~[[%.y p=2] [%.n p="rl" q="s"] [%.y p=1] [%.n p="" q="m"] [%.y p=2]])
534+ "tesomga"
535+
536+------------------------------------------------------------------------
537+
538+### `++nude`
539+
540+Tree change
541+
542+ ++ nude :: tree change
543+ |= [a=* b=*]
544+ ^- [p=upas q=upas]
545+ =< [p=(tred a b) q=(tred b a)]
546+ |%
547+ ++ axes :: locs of nouns
548+ |= [a=@ b=*] ^- (map ,* axis)
549+ =+ c=*(map ,* axis)
550+ |- ^- (map ,* axis)
551+ => .(c (~(put by c) b a))
552+ ?@ b
553+ c
554+ %- ~(uni by c)
555+ %- ~(uni by $(a (mul 2 a), b -.b))
556+ $(a +((mul 2 a)), b +.b)
557+ ::
558+ ++ tred :: diff a->b
559+ |= [a=* b=*] ^- upas
560+ =| c=(unit ,*)
561+ =+ d=(axes 1 a)
562+ |- ^- upas
563+ => .(c (~(get by d) b))
564+ ?~ c
565+ ?@ b
566+ [%1 b]
567+ =+ e=^-(upas [$(b -.b) $(b +.b)])
568+ ?- e
569+ [[%1 *] [%1 *]] [%1 [p.p.e p.q.e]]
570+ * e
571+ ==
572+ [%0 u.c]
573+ --
574+
575+Generate tree diff from two nouns.
576+
577+ ~zod/try=> (nude 40 20)
578+ [p=[%1 p=20] q=[%1 p=40]]
579+ ~zod/try=> (nude [5 5] 5)
580+ [p=[%0 p=3] q=[p=[%0 p=1] q=[%0 p=1]]]
581+ ~zod/try=> (nude "sam" "sal")
582+ [ p=[p=[%1 p=115] q=[p=[%1 p=97] q=[p=[%1 p=108] q=[%0 p=15]]]]
583+ q=[p=[%1 p=115] q=[p=[%1 p=97] q=[p=[%1 p=109] q=[%0 p=15]]]]
584+ ]
585+
586+------------------------------------------------------------------------
docs/dev/hoon/library/2ew.mdnew file+439
@@ -0,0 +1,439 @@
1+section 2eW, lite number theory
2+===============================
3+
4+### `++egcd`
5+
6+GCD
7+
8+ ++ egcd :: schneier's egcd
9+ |= [a=@ b=@]
10+ =+ si
11+ =+ [c=(sun a) d=(sun b)]
12+ =+ [u=[c=(sun 1) d=--0] v=[c=--0 d=(sun 1)]]
13+ |- ^- [d=@ u=@ v=@]
14+ ?: =(--0 c)
15+ [(abs d) d.u d.v]
16+ :: ?> ?& =(c (sum (pro (sun a) c.u) (pro (sun b) c.v)))
17+ :: =(d (sum (pro (sun a) d.u) (pro (sun b) d.v)))
18+ :: ==
19+ =+ q=(fra d c)
20+ %= $
21+ c (dif d (pro q c))
22+ d c
23+ u [(dif d.u (pro q c.u)) c.u]
24+ v [(dif d.v (pro q c.v)) c.v]
25+ ==
26+ ::
27+
28+Greatest common denominator
29+
30+ ~zod/try=> (egcd 20 15)
31+ [d=5 u=2 v=1]
32+ ~zod/try=> (egcd 24 16)
33+ [d=8 u=2 v=1]
34+ ~zod/try=> (egcd 7 5)
35+ [d=1 u=3 v=6]
36+ ~zod/try=> (egcd (shaf ~ %ham) (shaf ~ %sam))
37+ [ d=1
38+ u=59.983.396.314.566.203.239.184.568.129.921.874.787
39+ v=38.716.650.351.034.402.960.165.718.823.532.275.722
40+ ]
41+
42+------------------------------------------------------------------------
43+
44+### `++pram`
45+
46+Probable prime
47+
48+ ++ pram :: rabin-miller
49+ |= a=@ ^- ?
50+ ?: ?| =(0 (end 0 1 a))
51+ =(1 a)
52+ =+ b=1
53+ |- ^- ?
54+ ?: =(512 b)
55+ |
56+ ?|(=+(c=+((mul 2 b)) &(!=(a c) =(a (mul c (div a c))))) $(b +(b)))
57+ ==
58+ |
59+ =+ ^= b
60+ =+ [s=(dec a) t=0]
61+ |- ^- [s=@ t=@]
62+ ?: =(0 (end 0 1 s))
63+ $(s (rsh 0 1 s), t +(t))
64+ [s t]
65+ ?> =((mul s.b (bex t.b)) (dec a))
66+ =+ c=0
67+ |- ^- ?
68+ ?: =(c 64)
69+ &
70+ =+ d=(~(raw og (add c a)) (met 0 a))
71+ =+ e=(~(exp fo a) s.b d)
72+ ?& ?| =(1 e)
73+ =+ f=0
74+ |- ^- ?
75+ ?: =(e (dec a))
76+ &
77+ ?: =(f (dec t.b))
78+ |
79+ $(e (~(pro fo a) e e), f +(f))
80+ ==
81+ $(c +(c))
82+ ==
83+ ::
84+
85+Probable prime test
86+
87+ ~zod/try=> (pram 31)
88+ %.y
89+ ~zod/try=> =+(a=2 |-(?:(=(a 31) ~ [i=(mod 31 a) t=$(a +(a))])))
90+ ~[1 1 3 1 1 3 7 4 1 9 7 5 3 1 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1]
91+ ~zod/try=> =+(a=2 |-(?:(=(a 31) ~ [i=(mod 30 a) t=$(a +(a))])))
92+ ~[0 0 2 0 0 2 6 3 0 8 6 4 2 0 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0]
93+ ~zod/try=> (pram 256)
94+ %.n
95+ ~zod/try=> (pram (dec (bex 127)))
96+ %.y
97+
98+------------------------------------------------------------------------
99+
100+### `++ramp`
101+
102+`r-m` prime
103+
104+ ++ ramp :: make r-m prime
105+ |= [a=@ b=(list ,@) c=@] ^- @ux :: [bits snags seed]
106+ => .(c (shas %ramp c))
107+ =+ d=_@
108+ |-
109+ ?: =((mul 100 a) d)
110+ ~|(%ar-ramp !!)
111+ =+ e=(~(raw og c) a)
112+ ?: &((levy b |=(f=@ !=(1 (mod e f)))) (pram e))
113+ e
114+ $(c +(c), d (shax d))
115+ ::
116+
117+Random `a` bit prime, which isn't 1 modulo a list of other numbers,
118+using salt `c`.
119+
120+ ~zod/try=> (ramp 20 ~ %hamelok)
121+ 0xf.1f0d
122+ ~zod/try=> (ramp 20 ~ %hameloe)
123+ 0x2.d341
124+ ~zod/try=> (ramp 5 ~ %kole)
125+ 0x1f
126+ ~zod/try=> (ramp 7 ~ %kole)
127+ 0x4f
128+ ~zod/try=> (ramp 7 ~[0x4e] %kole)
129+ 0x43
130+ ~zod/try=> `@uw`(ramp 128 ~ %late)
131+ 0w3y.irKIL.l-pp1.2CkG4.3lsTF
132+
133+------------------------------------------------------------------------
134+
135+### `++fo`
136+
137+Prime engine
138+
139+ ++ fo :: modulo prime
140+ |_ a=@
141+
142+XX DO NOT RERUN GET.LS, THERE EXIST ARM COLLISIONS
143+
144+Core for performing arithmetic modulo a prime number
145+
146+ ~zod/try=> ~(. fo 79)
147+ <7.get [@ud <373.jdd 100.kzl 1.ypj %164>]>
148+
149+------------------------------------------------------------------------
150+
151+### `++dif`
152+
153+Difference
154+
155+ ++ dif
156+ |= [b=@ c=@]
157+ (sit (sub (add a b) (sit c)))
158+ ::
159+
160+Subtract
161+
162+ ~zod/try=> (~(dif fo 79) 10 5)
163+ 5
164+ ~zod/try=> (~(dif fo 79) 5 10)
165+ 74
166+
167+------------------------------------------------------------------------
168+
169+### `++exp`
170+
171+Exponent
172+
173+ ++ exp
174+ |= [b=@ c=@]
175+ ?: =(0 b)
176+ 1
177+ =+ d=$(b (rsh 0 1 b))
178+ =+ e=(pro d d)
179+ ?:(=(0 (end 0 1 b)) e (pro c e))
180+ ::
181+
182+Exponent
183+
184+ ~zod/try=> (~(exp fo 79) 3 5)
185+ 46
186+
187+------------------------------------------------------------------------
188+
189+### `++fra`
190+
191+Divide
192+
193+ ++ fra
194+ |= [b=@ c=@]
195+ (pro b (inv c))
196+ ::
197+
198+Divide
199+
200+ ~zod/try=> (~(fra fo 79) 20 4)
201+ 5
202+ ~zod/try=> (~(fra fo 79) 7 11)
203+ 15
204+
205+------------------------------------------------------------------------
206+
207+### `++inv`
208+
209+Inverse
210+
211+ ++ inv
212+ |= b=@
213+ =+ c=(dul:si u:(egcd b a) a)
214+ c
215+ ::
216+
217+Multiplicative inverse
218+
219+ ~zod/try=> (~(inv fo 79) 12)
220+ 33
221+ ~zod/try=> (~(pro fo 79) 12 33)
222+ 1
223+ ~zod/try=> (~(inv fo 79) 0)
224+ 0
225+
226+------------------------------------------------------------------------
227+
228+### `++pro`
229+
230+Product
231+
232+ ++ pro
233+ |= [b=@ c=@]
234+ (sit (mul b c))
235+ ::
236+
237+Product
238+
239+ ~zod/try=> (~(pro fo 79) 5 10)
240+ 50
241+ ~zod/try=> (~(pro fo 79) 5 20)
242+ 21
243+
244+------------------------------------------------------------------------
245+
246+### `++sit`
247+
248+Bounds
249+
250+ ++ sit
251+ |= b=@
252+ (mod b a)
253+ ::
254+
255+Bounds check
256+
257+ ~zod/try=> (~(sit fo 79) 9)
258+ 9
259+ ~zod/try=> (~(sit fo 79) 99)
260+ 20
261+
262+------------------------------------------------------------------------
263+
264+### `++sum`
265+
266+Sum
267+
268+ ++ sum
269+ |= [b=@ c=@]
270+ (sit (add b c))
271+ --
272+
273+Add
274+
275+ ~zod/try=> (~(sum fo 79) 9 9)
276+ 18
277+ ~zod/try=> (~(sum fo 79) 70 9)
278+ 0
279+
280+------------------------------------------------------------------------
281+
282+### `++ga`
283+
284+ ++ ga :: GF (bex p.a)
285+ |= a=[p=@ q=@ r=@] :: dim poly gen
286+ =+ si=(bex p.a)
287+ =+ ma=(dec si)
288+ => |%
289+
290+RSA internals
291+
292+XX document
293+
294+------------------------------------------------------------------------
295+
296+### `++dif`
297+
298+ ++ dif :: add and sub
299+ |= [b=@ c=@]
300+ ~| [%dif-ga a]
301+ ?> &((lth b si) (lth c si))
302+ (mix b c)
303+ ::
304+
305+XX document
306+
307+------------------------------------------------------------------------
308+
309+### `++dub`
310+
311+ ++ dub :: mul by x
312+ |= b=@
313+ ~| [%dub-ga a]
314+ ?> (lth b si)
315+ ?: =(1 (cut 0 [(dec p.a) 1] b))
316+ (dif (sit q.a) (sit (lsh 0 1 b)))
317+ (lsh 0 1 b)
318+ ::
319+
320+XX document
321+
322+------------------------------------------------------------------------
323+
324+### `++pro`
325+
326+ ++ pro :: slow multiply
327+ |= [b=@ c=@]
328+ ?: =(0 b)
329+ 0
330+ ?: =(1 (dis 1 b))
331+ (dif c $(b (rsh 0 1 b), c (dub c)))
332+ $(b (rsh 0 1 b), c (dub c))
333+ ::
334+
335+XX document
336+
337+------------------------------------------------------------------------
338+
339+### `++toe`
340+
341+ ++ toe :: exp/log tables
342+ =+ ^= nu
343+ |= [b=@ c=@]
344+ ^- (map ,@ ,@)
345+ =+ d=*(map ,@ ,@)
346+ |-
347+ ?: =(0 c)
348+ d
349+ %= $
350+ c (dec c)
351+ d (~(put by d) c b)
352+ ==
353+ =+ [p=(nu 0 (bex p.a)) q=(nu ma ma)]
354+ =+ [b=1 c=0]
355+ |- ^- [p=(map ,@ ,@) q=(map ,@ ,@)]
356+ ?: =(ma c)
357+ [(~(put by p) c b) q]
358+ %= $
359+ b (pro r.a b)
360+ c +(c)
361+ p (~(put by p) c b)
362+ q (~(put by q) b c)
363+ ==
364+ ::
365+
366+XX document
367+
368+------------------------------------------------------------------------
369+
370+### `++sit`
371+
372+ ++ sit :: reduce
373+ |= b=@
374+ (mod b (bex p.a))
375+ --
376+
377+XX document
378+
379+------------------------------------------------------------------------
380+
381+### `++fra`
382+
383+ ++ fra :: divide
384+ |= [b=@ c=@]
385+ (pro b (inv c))
386+ ::
387+
388+XX document
389+
390+------------------------------------------------------------------------
391+
392+### `++inv`
393+
394+ ++ inv :: invert
395+ |= b=@
396+ ~| [%inv-ga a]
397+ =+ c=(~(get by q) b)
398+ ?~ c !!
399+ =+ d=(~(get by p) (sub ma u.c))
400+ (need d)
401+ ::
402+
403+XX document
404+
405+------------------------------------------------------------------------
406+
407+### `++pow`
408+
409+ ++ pow :: exponent
410+ |= [b=@ c=@]
411+ =+ [d=1 e=c f=0]
412+ |-
413+ ?: =(p.a f)
414+ d
415+ ?: =(1 (cut 0 [f 1] b))
416+ $(d (pro d e), e (pro e e), f +(f))
417+ $(e (pro e e), f +(f))
418+ ::
419+
420+XX document
421+
422+------------------------------------------------------------------------
423+
424+### `++pro`
425+
426+ ++ pro :: multiply
427+ |= [b=@ c=@]
428+ ~| [%pro-ga a]
429+ =+ d=(~(get by q) b)
430+ ?~ d 0
431+ =+ e=(~(get by q) c)
432+ ?~ e 0
433+ =+ f=(~(get by p) (mod (add u.d u.e) ma))
434+ (need f)
435+ --
436+
437+XX document
438+
439+------------------------------------------------------------------------
docs/dev/hoon/library/2ex.mdnew file+717
@@ -0,0 +1,717 @@
1+section 2eX, jetted crypto
2+==========================
3+
4+------------------------------------------------------------------------
5+
6+### `++aesc`
7+
8+ ++ aesc :: AES-256
9+ ~% %aesc + ~
10+ |%
11+
12+XX document
13+
14+### `++en`
15+
16+ ++ en :: ECB enc
17+ ~/ %en
18+ |= [a=@I b=@H] ^- @uxH
19+ =+ ahem
20+ (be & (ex a) b)
21+
22+XX document
23+
24+### `++de`
25+
26+ ++ de :: ECB dec
27+ ~/ %de
28+ |= [a=@I b=@H] ^- @uxH
29+ =+ ahem
30+ (be | (ix (ex a)) b)
31+ --
32+
33+XX document
34+
35+### `++ahem`
36+
37+ ++ ahem :: AES helpers
38+ :: XX should be in aesc, isn't for performance reasons
39+ =>
40+ =+ =+ [gr=(ga 8 0x11b 3) few==>(fe .(a 5))]
41+ =+ [pro=pro.gr dif=dif.gr pow=pow.gr ror=ror.few]
42+ [pro=pro dif=dif pow=pow ror=ror nnk=8 nnb=4 nnr=14]
43+ => |%
44+
45+XX document
46+
47+### `++cipa`
48+
49+ ++ cipa :: AES params
50+ $_ ^? |%
51+
52+XX document
53+
54+### `++co`
55+
56+ ++ co [0xe 0xb 0xd 0x9]
57+
58+XX document
59+
60+### `++ix`
61+
62+ ++ ix :: key expand, inv
63+ |= a=@ ^- @
64+ =+ [i=1 j=_@ b=_@ c=co:pin]
65+ |-
66+ ?: =(nnr i)
67+ a
68+ => .(b (cut 7 [i 1] a))
69+ => .(b (rep 5 (mcol (pode 5 4 b) c)))
70+ => .(j (sub nnr i))
71+ %= $
72+ i +(i)
73+ a
74+ %+ can 7
75+ :~ [i (cut 7 [0 i] a)]
76+ [1 b]
77+ [j (cut 7 [+(i) j] a)]
78+ ==
79+ ==
80+ --
81+ ::
82+
83+XX document
84+
85+### `++ro`
86+
87+ ++ ro [0 3 2 1]
88+
89+XX document
90+
91+### `++su`
92+
93+ ++ su 0x7d0c.2155.6314.69e1.26d6.77ba.7e04.2b17.
94+ 6199.5383.3cbb.ebc8.b0f5.2aae.4d3b.e0a0.
95+ ef9c.c993.9f7a.e52d.0d4a.b519.a97f.5160.
96+ 5fec.8027.5910.12b1.31c7.0788.33a8.dd1f.
97+ f45a.cd78.fec0.db9a.2079.d2c6.4b3e.56fc.
98+ 1bbe.18aa.0e62.b76f.89c5.291d.711a.f147.
99+ 6edf.751c.e837.f9e2.8535.ade7.2274.ac96.
100+ 73e6.b4f0.cecf.f297.eadc.674f.4111.913a.
101+ 6b8a.1301.03bd.afc1.020f.3fca.8f1e.2cd0.
102+ 0645.b3b8.0558.e4f7.0ad3.bc8c.00ab.d890.
103+ 849d.8da7.5746.155e.dab9.edfd.5048.706c.
104+ 92b6.655d.cc5c.a4d4.1698.6886.64f6.f872.
105+ 25d1.8b6d.49a2.5b76.b224.d928.66a1.2e08.
106+ 4ec3.fa42.0b95.4cee.3d23.c2a6.3294.7b54.
107+ cbe9.dec4.4443.8e34.87ff.2f9b.8239.e37c.
108+ fbd7.f381.9ea3.40bf.38a5.3630.d56a.0952
109+ --
110+ ::
111+
112+XX document
113+
114+### `++pen`
115+
116+ ++ pen :: encrypt
117+ ^- cipa
118+ |%
119+
120+XX document
121+
122+### `++co`
123+
124+ ++ co [0xe 0xb 0xd 0x9]
125+
126+XX document
127+
128+### `++ix`
129+
130+ ++ ix :: key expand, inv
131+ |= a=@ ^- @
132+ =+ [i=1 j=_@ b=_@ c=co:pin]
133+ |-
134+ ?: =(nnr i)
135+ a
136+ => .(b (cut 7 [i 1] a))
137+ => .(b (rep 5 (mcol (pode 5 4 b) c)))
138+ => .(j (sub nnr i))
139+ %= $
140+ i +(i)
141+ a
142+ %+ can 7
143+ :~ [i (cut 7 [0 i] a)]
144+ [1 b]
145+ [j (cut 7 [+(i) j] a)]
146+ ==
147+ ==
148+ --
149+ ::
150+
151+XX document
152+
153+### `++ro`
154+
155+ ++ ro [0 3 2 1]
156+
157+XX document
158+
159+### `++su`
160+
161+ ++ su 0x7d0c.2155.6314.69e1.26d6.77ba.7e04.2b17.
162+ 6199.5383.3cbb.ebc8.b0f5.2aae.4d3b.e0a0.
163+ ef9c.c993.9f7a.e52d.0d4a.b519.a97f.5160.
164+ 5fec.8027.5910.12b1.31c7.0788.33a8.dd1f.
165+ f45a.cd78.fec0.db9a.2079.d2c6.4b3e.56fc.
166+ 1bbe.18aa.0e62.b76f.89c5.291d.711a.f147.
167+ 6edf.751c.e837.f9e2.8535.ade7.2274.ac96.
168+ 73e6.b4f0.cecf.f297.eadc.674f.4111.913a.
169+ 6b8a.1301.03bd.afc1.020f.3fca.8f1e.2cd0.
170+ 0645.b3b8.0558.e4f7.0ad3.bc8c.00ab.d890.
171+ 849d.8da7.5746.155e.dab9.edfd.5048.706c.
172+ 92b6.655d.cc5c.a4d4.1698.6886.64f6.f872.
173+ 25d1.8b6d.49a2.5b76.b224.d928.66a1.2e08.
174+ 4ec3.fa42.0b95.4cee.3d23.c2a6.3294.7b54.
175+ cbe9.dec4.4443.8e34.87ff.2f9b.8239.e37c.
176+ fbd7.f381.9ea3.40bf.38a5.3630.d56a.0952
177+ --
178+ ::
179+
180+XX document
181+
182+### `++pin`
183+
184+ ++ pin :: decrypt
185+ ^- cipa
186+ |%
187+
188+XX document
189+
190+### `++co`
191+
192+ ++ co [0xe 0xb 0xd 0x9]
193+
194+XX document
195+
196+### `++ix`
197+
198+ ++ ix :: key expand, inv
199+ |= a=@ ^- @
200+ =+ [i=1 j=_@ b=_@ c=co:pin]
201+ |-
202+ ?: =(nnr i)
203+ a
204+ => .(b (cut 7 [i 1] a))
205+ => .(b (rep 5 (mcol (pode 5 4 b) c)))
206+ => .(j (sub nnr i))
207+ %= $
208+ i +(i)
209+ a
210+ %+ can 7
211+ :~ [i (cut 7 [0 i] a)]
212+ [1 b]
213+ [j (cut 7 [+(i) j] a)]
214+ ==
215+ ==
216+ --
217+ ::
218+
219+XX document
220+
221+### `++ro`
222+
223+ ++ ro [0 3 2 1]
224+
225+XX document
226+
227+### `++su`
228+
229+ ++ su 0x7d0c.2155.6314.69e1.26d6.77ba.7e04.2b17.
230+ 6199.5383.3cbb.ebc8.b0f5.2aae.4d3b.e0a0.
231+ ef9c.c993.9f7a.e52d.0d4a.b519.a97f.5160.
232+ 5fec.8027.5910.12b1.31c7.0788.33a8.dd1f.
233+ f45a.cd78.fec0.db9a.2079.d2c6.4b3e.56fc.
234+ 1bbe.18aa.0e62.b76f.89c5.291d.711a.f147.
235+ 6edf.751c.e837.f9e2.8535.ade7.2274.ac96.
236+ 73e6.b4f0.cecf.f297.eadc.674f.4111.913a.
237+ 6b8a.1301.03bd.afc1.020f.3fca.8f1e.2cd0.
238+ 0645.b3b8.0558.e4f7.0ad3.bc8c.00ab.d890.
239+ 849d.8da7.5746.155e.dab9.edfd.5048.706c.
240+ 92b6.655d.cc5c.a4d4.1698.6886.64f6.f872.
241+ 25d1.8b6d.49a2.5b76.b224.d928.66a1.2e08.
242+ 4ec3.fa42.0b95.4cee.3d23.c2a6.3294.7b54.
243+ cbe9.dec4.4443.8e34.87ff.2f9b.8239.e37c.
244+ fbd7.f381.9ea3.40bf.38a5.3630.d56a.0952
245+ --
246+ ::
247+
248+XX document
249+
250+### `++mcol`
251+
252+ ++ mcol
253+ |= [a=(list ,@) b=[p=@ q=@ r=@ s=@]] ^- (list ,@)
254+ =+ c=[p=_@ q=_@ r=_@ s=_@]
255+ |- ^- (list ,@)
256+ ?~ a ~
257+ => .(p.c (cut 3 [0 1] i.a))
258+ => .(q.c (cut 3 [1 1] i.a))
259+ => .(r.c (cut 3 [2 1] i.a))
260+ => .(s.c (cut 3 [3 1] i.a))
261+ :_ $(a t.a)
262+ %+ rep 3
263+ %+ turn
264+ %- limo
265+ :~ [[p.c p.b] [q.c q.b] [r.c r.b] [s.c s.b]]
266+ [[p.c s.b] [q.c p.b] [r.c q.b] [s.c r.b]]
267+ [[p.c r.b] [q.c s.b] [r.c p.b] [s.c q.b]]
268+ [[p.c q.b] [q.c r.b] [r.c s.b] [s.c p.b]]
269+ ==
270+ |= [a=[@ @] b=[@ @] c=[@ @] d=[@ @]]
271+ :(dif (pro a) (pro b) (pro c) (pro d))
272+ ::
273+
274+XX document
275+
276+### `++pode`
277+
278+ ++ pode :: explode to block
279+ |= [a=bloq b=@ c=@] ^- (list ,@)
280+ =+ d=(rip a c)
281+ =+ m=(met a c)
282+ |-
283+ ?: =(m b)
284+ d
285+ $(m +(m), d (weld d (limo [0 ~])))
286+
287+XX document
288+
289+### `++sube`
290+
291+ ++ sube :: s-box word
292+ |= [a=@ b=@] ^- @
293+ (rep 3 (turn (pode 3 4 a) |=(c=@ (cut 3 [c 1] b))))
294+ --
295+ |%
296+
297+XX document
298+
299+### `++be`
300+
301+ ++ be :: block cipher
302+ |= [a=? b=@ c=@H] ^- @uxH
303+ ~| %be-aesc
304+ => %= .
305+ +
306+ => +
307+ |%
308+
309+XX document
310+
311+### `++ankh`
312+
313+ ++ ankh
314+ |= [a=cipa b=@ c=@]
315+ (pode 5 nnb (cut 5 [(mul (ix.a b) nnb) nnb] c))
316+
317+XX document
318+
319+### `++sark`
320+
321+ ++ sark
322+ |= [c=(list ,@) d=(list ,@)] ^- (list ,@)
323+ ?~ c ~
324+ ?~ d !!
325+ [(mix i.c i.d) $(c t.c, d t.d)]
326+
327+XX document
328+
329+### `++srow`
330+
331+ ++ srow
332+ |= [a=cipa b=(list ,@)] ^- (list ,@)
333+ =+ [c=0 d=~ e=ro.a]
334+ |-
335+ ?: =(c nnb)
336+ d
337+ :_ $(c +(c))
338+ %+ rep 3
339+ %+ turn
340+ (limo [0 p.e] [1 q.e] [2 r.e] [3 s.e] ~)
341+ |= [f=@ g=@]
342+ (cut 3 [f 1] (snag (mod (add g c) nnb) b))
343+
344+XX document
345+
346+### `++subs`
347+
348+ ++ subs
349+ |= [a=cipa b=(list ,@)] ^- (list ,@)
350+ ?~ b ~
351+ [(sube i.b su.a) $(b t.b)]
352+ --
353+ ==
354+ =+ [d=?:(a pen pin) e=(pode 5 nnb c) f=1]
355+ => .(e (sark e (ankh d 0 b)))
356+ |-
357+ ?. =(nnr f)
358+ => .(e (subs d e))
359+ => .(e (srow d e))
360+ => .(e (mcol e co.d))
361+ => .(e (sark e (ankh d f b)))
362+ $(f +(f))
363+ => .(e (subs d e))
364+ => .(e (srow d e))
365+ => .(e (sark e (ankh d nnr b)))
366+ (rep 5 e)
367+
368+XX document
369+
370+### `++ex`
371+
372+ ++ ex :: key expand
373+ |= a=@I ^- @
374+ =+ [b=a c=0 d=su:pen i=nnk]
375+ |-
376+ ?: =(i (mul nnb +(nnr)))
377+ b
378+ => .(c (cut 5 [(dec i) 1] b))
379+ => ?: =(0 (mod i nnk))
380+ => .(c (ror 3 1 c))
381+ => .(c (sube c d))
382+ .(c (mix c (pow (dec (div i nnk)) 2)))
383+ ?: &((gth nnk 6) =(4 (mod i nnk)))
384+ .(c (sube c d))
385+ .
386+ => .(c (mix c (cut 5 [(sub i nnk) 1] b)))
387+ => .(b (can 5 [i b] [1 c] ~))
388+ $(i +(i))
389+
390+XX document
391+
392+### `++ix`
393+
394+ ++ ix :: key expand, inv
395+ |= a=@ ^- @
396+ =+ [i=1 j=_@ b=_@ c=co:pin]
397+ |-
398+ ?: =(nnr i)
399+ a
400+ => .(b (cut 7 [i 1] a))
401+ => .(b (rep 5 (mcol (pode 5 4 b) c)))
402+ => .(j (sub nnr i))
403+ %= $
404+ i +(i)
405+ a
406+ %+ can 7
407+ :~ [i (cut 7 [0 i] a)]
408+ [1 b]
409+ [j (cut 7 [+(i) j] a)]
410+ ==
411+ ==
412+ --
413+ ::
414+
415+XX document
416+
417+### `++curt`
418+
419+ ++ curt :: curve25519
420+ |= [a=@ b=@]
421+ => %= .
422+ +
423+ => +
424+ =+ =+ [p=486.662 q=(sub (bex 255) 19)]
425+ =+ fq=~(. fo q)
426+ [p=p q=q fq=fq]
427+ |%
428+
429+XX document
430+
431+### `++cla`
432+
433+ ++ cla
434+ |= raw=@
435+ =+ low=(dis 248 (cut 3 [0 1] raw))
436+ =+ hih=(con 64 (dis 127 (cut 3 [31 1] raw)))
437+ =+ mid=(cut 3 [1 30] raw)
438+ (can 3 [[1 low] [30 mid] [1 hih] ~])
439+
440+XX document
441+
442+### `++sqr`
443+
444+ ++ sqr |=(a=@ (mul a a))
445+
446+XX document
447+
448+### `++inv`
449+
450+ ++ inv |=(a=@ (~(exp fo q) (sub q 2) a))
451+
452+XX document
453+
454+### `++cad`
455+
456+ ++ cad
457+ |= [n=[x=@ z=@] m=[x=@ z=@] d=[x=@ z=@]]
458+ =+ ^= xx
459+ ;: mul 4 z.d
460+ %- sqr %- abs:si
461+ %+ dif:si
462+ (sun:si (mul x.m x.n))
463+ (sun:si (mul z.m z.n))
464+ ==
465+ =+ ^= zz
466+ ;: mul 4 x.d
467+ %- sqr %- abs:si
468+ %+ dif:si
469+ (sun:si (mul x.m z.n))
470+ (sun:si (mul z.m x.n))
471+ ==
472+ [(sit.fq xx) (sit.fq zz)]
473+
474+XX document
475+
476+### `++cub`
477+
478+ ++ cub
479+ |= [x=@ z=@]
480+ =+ ^= xx
481+ %+ mul
482+ %- sqr %- abs:si
483+ (dif:si (sun:si x) (sun:si z))
484+ (sqr (add x z))
485+ =+ ^= zz
486+ ;: mul 4 x z
487+ :(add (sqr x) :(mul p x z) (sqr z))
488+ ==
489+ [(sit.fq xx) (sit.fq zz)]
490+ --
491+ ==
492+ =+ one=[b 1]
493+ =+ i=253
494+ =+ r=one
495+ =+ s=(cub one)
496+ |-
497+ ?: =(i 0)
498+ =+ x=(cub r)
499+ (sit.fq (mul -.x (inv +.x)))
500+ =+ m=(rsh 0 i a)
501+ ?: =(0 (mod m 2))
502+ $(i (dec i), s (cad r s one), r (cub r))
503+ $(i (dec i), r (cad r s one), s (cub s))
504+ ::
505+
506+XX document
507+
508+### `++ed`
509+
510+ ++ ed :: ed25519
511+ =>
512+ =+ =+ [b=256 q=(sub (bex 255) 19)]
513+ =+ fq=~(. fo q)
514+ =+ ^= l
515+ %+ add
516+ (bex 252)
517+ 27.742.317.777.372.353.535.851.937.790.883.648.493
518+ =+ d=(dif.fq 0 (fra.fq 121.665 121.666))
519+ =+ ii=(exp.fq (div (dec q) 4) 2)
520+ [b=b q=q fq=fq l=l d=d ii=ii]
521+ ~% %coed +> ~
522+ |%
523+
524+### `++norm`
525+
526+ ++ norm |=(x=@ ?:(=(0 (mod x 2)) x (sub q x)))
527+ ::
528+
529+XX document
530+
531+### `++xrec`
532+
533+ ++ xrec :: recover x-coord
534+ |= y=@ ^- @
535+ =+ ^= xx
536+ %+ mul (dif.fq (mul y y) 1)
537+ (inv.fq +(:(mul d y y)))
538+ =+ x=(exp.fq (div (add 3 q) 8) xx)
539+ ?: !=(0 (dif.fq (mul x x) (sit.fq xx)))
540+ (norm (pro.fq x ii))
541+ (norm x)
542+ ::
543+
544+XX document
545+
546+### `++ward`
547+
548+ ++ ward :: edwards multiply
549+ |= [pp=[@ @] qq=[@ @]] ^- [@ @]
550+ =+ dp=:(pro.fq d -.pp -.qq +.pp +.qq)
551+ =+ ^= xt
552+ %+ pro.fq
553+ %+ sum.fq
554+ (pro.fq -.pp +.qq)
555+ (pro.fq -.qq +.pp)
556+ (inv.fq (sum.fq 1 dp))
557+ =+ ^= yt
558+ %+ pro.fq
559+ %+ sum.fq
560+ (pro.fq +.pp +.qq)
561+ (pro.fq -.pp -.qq)
562+ (inv.fq (dif.fq 1 dp))
563+ [xt yt]
564+ ::
565+
566+XX document
567+
568+### `++scam`
569+
570+ ++ scam :: scalar multiply
571+ |= [pp=[@ @] e=@] ^- [@ @]
572+ ?: =(0 e)
573+ [0 1]
574+ =+ qq=$(e (div e 2))
575+ => .(qq (ward qq qq))
576+ ?: =(1 (dis 1 e))
577+ (ward qq pp)
578+ qq
579+ ::
580+
581+XX document
582+
583+### `++etch`
584+
585+ ++ etch :: encode point
586+ |= pp=[@ @] ^- @
587+ (can 0 ~[[(sub b 1) +.pp] [1 (dis 1 -.pp)]])
588+ ::
589+
590+XX document
591+
592+### `++curv`
593+
594+ ++ curv :: point on curve?
595+ |= [x=@ y=@] ^- ?
596+ .= 0
597+ %+ dif.fq
598+ %+ sum.fq
599+ (pro.fq (sub q (sit.fq x)) x)
600+ (pro.fq y y)
601+ (sum.fq 1 :(pro.fq d x x y y))
602+ ::
603+
604+XX document
605+
606+### `++deco`
607+
608+ ++ deco :: decode point
609+ |= s=@ ^- (unit ,[@ @])
610+ =+ y=(cut 0 [0 (dec b)] s)
611+ =+ si=(cut 0 [(dec b) 1] s)
612+ =+ x=(xrec y)
613+ => .(x ?:(!=(si (dis 1 x)) (sub q x) x))
614+ =+ pp=[x y]
615+ ?. (curv pp)
616+ ~
617+ [~ pp]
618+ ::
619+
620+XX document
621+
622+### `++bb`
623+
624+ ++ bb
625+ =+ bby=(pro.fq 4 (inv.fq 5))
626+ [(xrec bby) bby]
627+ ::
628+ --
629+ ~% %ed + ~
630+ |%
631+
632+XX document
633+
634+### `++puck`
635+
636+ ++ puck :: public key
637+ ~/ %puck
638+ |= sk=@I ^- @
639+ ?: (gth (met 3 sk) 32) !!
640+ =+ h=(shal (rsh 0 3 b) sk)
641+ =+ ^= a
642+ %+ add
643+ (bex (sub b 2))
644+ (lsh 0 3 (cut 0 [3 (sub b 5)] h))
645+ =+ aa=(scam bb a)
646+ (etch aa)
647+
648+XX document
649+
650+### `++suck`
651+
652+ ++ suck :: keypair from seed
653+ |= se=@I ^- @uJ
654+ =+ pu=(puck se)
655+ (can 0 ~[[b se] [b pu]])
656+ ::
657+
658+XX document
659+
660+### `++sign`
661+
662+ ++ sign :: certify
663+ ~/ %sign
664+ |= [m=@ se=@] ^- @
665+ =+ sk=(suck se)
666+ =+ pk=(cut 0 [b b] sk)
667+ =+ h=(shal (rsh 0 3 b) sk)
668+ =+ ^= a
669+ %+ add
670+ (bex (sub b 2))
671+ (lsh 0 3 (cut 0 [3 (sub b 5)] h))
672+ =+ ^= r
673+ =+ hm=(cut 0 [b b] h)
674+ =+ ^= i
675+ %+ can 0
676+ :~ [b hm]
677+ [(met 0 m) m]
678+ ==
679+ (shaz i)
680+ =+ rr=(scam bb r)
681+ =+ ^= ss
682+ =+ er=(etch rr)
683+ =+ ^= ha
684+ %+ can 0
685+ :~ [b er]
686+ [b pk]
687+ [(met 0 m) m]
688+ ==
689+ (~(sit fo l) (add r (mul (shaz ha) a)))
690+ (can 0 ~[[b (etch rr)] [b ss]])
691+ ::
692+
693+XX document
694+
695+### `++veri`
696+
697+ ++ veri :: validate
698+ ~/ %veri
699+ |= [s=@ m=@ pk=@] ^- ?
700+ ?: (gth (div b 4) (met 3 s)) |
701+ ?: (gth (div b 8) (met 3 pk)) |
702+ =+ cb=(rsh 0 3 b)
703+ =+ rr=(deco (cut 0 [0 b] s))
704+ ?~ rr |
705+ =+ aa=(deco pk)
706+ ?~ aa |
707+ =+ ss=(cut 0 [b b] s)
708+ =+ ha=(can 3 ~[[cb (etch u.rr)] [cb pk] [(met 3 m) m]])
709+ =+ h=(shaz ha)
710+ =((scam bb ss) (ward u.rr (scam u.aa h)))
711+ ::
712+ --
713+ ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
714+
715+XX document
716+
717+------------------------------------------------------------------------
docs/dev/hoon/library/2ey.mdnew file+399
@@ -0,0 +1,399 @@
1+section 2eY, SHA-256
2+====================
3+
4+### `++shad`
5+
6+ ++ shad |=(ruz=@ (shax (shax ruz))) :: double sha-256
7+
8+XX document
9+
10+### `++shaf`
11+
12+ ++ shaf :: half sha-256
13+ |= [sal=@ ruz=@]
14+ =+ haz=(shas sal ruz)
15+ (mix (end 7 1 haz) (rsh 7 1 haz))
16+ ::
17+
18+XX document
19+
20+### `++shak`
21+
22+ ++ shak :: XX shd be PBKDF
23+ |= [who=@p wud=@]
24+ (shas (mix %shak who) wud)
25+ ::
26+
27+XX document
28+
29+### `++sham`
30+
31+ ++ sham :: noun hash
32+ |= yux=* ^- @uvH ^- @
33+ ?@ yux
34+ (shaf %mash yux)
35+ (shaf %sham (jam yux))
36+ ::
37+
38+XX document
39+
40+### `++shas`
41+
42+ ++ shas :: salted hash
43+ |= [sal=@ ruz=@]
44+ (shax (mix sal (shax ruz)))
45+ ::
46+
47+XX document
48+
49+### `++shax`
50+
51+ ++ shax :: sha-256
52+ ~/ %shax
53+ |= ruz=@ ^- @
54+ ~| %sha
55+ =+ [few==>(fe .(a 5)) wac=|=([a=@ b=@] (cut 5 [a 1] b))]
56+ =+ [sum=sum.few ror=ror.few net=net.few inv=inv.few]
57+ =+ ral=(lsh 0 3 (met 3 ruz))
58+ =+ ^= ful
59+ %+ can 0
60+ :~ [ral ruz]
61+ [8 128]
62+ [(mod (sub 960 (mod (add 8 ral) 512)) 512) 0]
63+ [64 (~(net fe 6) ral)]
64+ ==
65+ =+ lex=(met 9 ful)
66+ =+ ^= kbx 0xc671.78f2.bef9.a3f7.a450.6ceb.90be.fffa.
67+ 8cc7.0208.84c8.7814.78a5.636f.748f.82ee.
68+ 682e.6ff3.5b9c.ca4f.4ed8.aa4a.391c.0cb3.
69+ 34b0.bcb5.2748.774c.1e37.6c08.19a4.c116.
70+ 106a.a070.f40e.3585.d699.0624.d192.e819.
71+ c76c.51a3.c24b.8b70.a81a.664b.a2bf.e8a1.
72+ 9272.2c85.81c2.c92e.766a.0abb.650a.7354.
73+ 5338.0d13.4d2c.6dfc.2e1b.2138.27b7.0a85.
74+ 1429.2967.06ca.6351.d5a7.9147.c6e0.0bf3.
75+ bf59.7fc7.b003.27c8.a831.c66d.983e.5152.
76+ 76f9.88da.5cb0.a9dc.4a74.84aa.2de9.2c6f.
77+ 240c.a1cc.0fc1.9dc6.efbe.4786.e49b.69c1.
78+ c19b.f174.9bdc.06a7.80de.b1fe.72be.5d74.
79+ 550c.7dc3.2431.85be.1283.5b01.d807.aa98.
80+ ab1c.5ed5.923f.82a4.59f1.11f1.3956.c25b.
81+ e9b5.dba5.b5c0.fbcf.7137.4491.428a.2f98
82+ =+ ^= hax 0x5be0.cd19.1f83.d9ab.9b05.688c.510e.527f.
83+ a54f.f53a.3c6e.f372.bb67.ae85.6a09.e667
84+ =+ i=0
85+ |- ^- @
86+ ?: =(i lex)
87+ (rep 5 (turn (rip 5 hax) net))
88+ =+ ^= wox
89+ =+ dux=(cut 9 [i 1] ful)
90+ =+ wox=(rep 5 (turn (rip 5 dux) net))
91+ =+ j=16
92+ |- ^- @
93+ ?: =(64 j)
94+ wox
95+ =+ :* l=(wac (sub j 15) wox)
96+ m=(wac (sub j 2) wox)
97+ n=(wac (sub j 16) wox)
98+ o=(wac (sub j 7) wox)
99+ ==
100+ =+ x=:(mix (ror 0 7 l) (ror 0 18 l) (rsh 0 3 l))
101+ =+ y=:(mix (ror 0 17 m) (ror 0 19 m) (rsh 0 10 m))
102+ =+ z=:(sum n x o y)
103+ $(wox (con (lsh 5 j z) wox), j +(j))
104+ =+ j=0
105+ =+ :* a=(wac 0 hax)
106+ b=(wac 1 hax)
107+ c=(wac 2 hax)
108+ d=(wac 3 hax)
109+ e=(wac 4 hax)
110+ f=(wac 5 hax)
111+ g=(wac 6 hax)
112+ h=(wac 7 hax)
113+ ==
114+ |- ^- @
115+ ?: =(64 j)
116+ %= ^$
117+ i +(i)
118+ hax %+ rep 5
119+ :~ (sum a (wac 0 hax))
120+ (sum b (wac 1 hax))
121+ (sum c (wac 2 hax))
122+ (sum d (wac 3 hax))
123+ (sum e (wac 4 hax))
124+ (sum f (wac 5 hax))
125+ (sum g (wac 6 hax))
126+ (sum h (wac 7 hax))
127+ ==
128+ ==
129+ =+ l=:(mix (ror 0 2 a) (ror 0 13 a) (ror 0 22 a)) :: s0
130+ =+ m=:(mix (dis a b) (dis a c) (dis b c)) :: maj
131+ =+ n=(sum l m) :: t2
132+ =+ o=:(mix (ror 0 6 e) (ror 0 11 e) (ror 0 25 e)) :: s1
133+ =+ p=(mix (dis e f) (dis (inv e) g)) :: ch
134+ =+ q=:(sum h o p (wac j kbx) (wac j wox)) :: t1
135+ $(j +(j), a (sum q n), b a, c b, d c, e (sum d q), f e, g f, h g)
136+ ::
137+
138+XX document
139+
140+### `++shaw`
141+
142+ ++ shaw :: hash to nbits
143+ |= [sal=@ len=@ ruz=@]
144+ (~(raw og (shas sal (mix len ruz))) len)
145+ ::
146+
147+XX document
148+
149+### `++og`
150+
151+ ++ og :: shax-powered rng
152+ ~/ %og
153+ |_ a=@
154+
155+XX document
156+
157+### `++rad`
158+
159+ ++ rad :: random in range
160+ |= b=@ ^- @
161+ =+ c=(raw (met 0 b))
162+ ?:((lth c b) c $(a +(a)))
163+ ::
164+
165+XX document
166+
167+### `++rads`
168+
169+ ++ rads :: random continuation
170+ |= b=@
171+ =+ r=(rad b)
172+ [r +>.$(a (shas %og-s r))]
173+
174+XX document
175+
176+### `++raw`
177+
178+ ++ raw :: random bits
179+ ~/ %raw
180+ |= b=@ ^- @
181+ %+ can
182+ 0
183+ =+ c=(shas %og-a (mix b a))
184+ |- ^- (list ,[@ @])
185+ ?: =(0 b)
186+ ~
187+ =+ d=(shas %og-b (mix b (mix a c)))
188+ ?: (lth b 256)
189+ [[b (end 0 b d)] ~]
190+ [[256 d] $(c d, b (sub b 256))]
191+
192+XX document
193+
194+### `++raws`
195+
196+ ++ raws :: random bits continuation
197+ |= b=@
198+ =+ r=(raw b)
199+ [r +>.$(a (shas %og-s r))]
200+ --
201+
202+XX document
203+
204+### `++shaz`
205+
206+ ++ shaz :: sha-512
207+ |= ruz=@ ^- @
208+ (shal [(met 3 ruz) ruz])
209+
210+XX document
211+
212+### `++shal`
213+
214+ ++ shal :: sha-512 with length
215+ ~/ %shal
216+ |= [len=@ ruz=@] ^- @
217+ => .(ruz (cut 3 [0 len] ruz))
218+ =+ [few==>(fe .(a 6)) wac=|=([a=@ b=@] (cut 6 [a 1] b))]
219+ =+ [sum=sum.few ror=ror.few net=net.few inv=inv.few]
220+ =+ ral=(lsh 0 3 len)
221+ =+ ^= ful
222+ %+ can 0
223+ :~ [ral ruz]
224+ [8 128]
225+ [(mod (sub 1.920 (mod (add 8 ral) 1.024)) 1.024) 0]
226+ [128 (~(net fe 7) ral)]
227+ ==
228+ =+ lex=(met 10 ful)
229+ =+ ^= kbx 0x6c44.198c.4a47.5817.5fcb.6fab.3ad6.faec.
230+ 597f.299c.fc65.7e2a.4cc5.d4be.cb3e.42b6.
231+ 431d.67c4.9c10.0d4c.3c9e.be0a.15c9.bebc.
232+ 32ca.ab7b.40c7.2493.28db.77f5.2304.7d84.
233+ 1b71.0b35.131c.471b.113f.9804.bef9.0dae.
234+ 0a63.7dc5.a2c8.98a6.06f0.67aa.7217.6fba.
235+ f57d.4f7f.ee6e.d178.eada.7dd6.cde0.eb1e.
236+ d186.b8c7.21c0.c207.ca27.3ece.ea26.619c.
237+ c671.78f2.e372.532b.bef9.a3f7.b2c6.7915.
238+ a450.6ceb.de82.bde9.90be.fffa.2363.1e28.
239+ 8cc7.0208.1a64.39ec.84c8.7814.a1f0.ab72.
240+ 78a5.636f.4317.2f60.748f.82ee.5def.b2fc.
241+ 682e.6ff3.d6b2.b8a3.5b9c.ca4f.7763.e373.
242+ 4ed8.aa4a.e341.8acb.391c.0cb3.c5c9.5a63.
243+ 34b0.bcb5.e19b.48a8.2748.774c.df8e.eb99.
244+ 1e37.6c08.5141.ab53.19a4.c116.b8d2.d0c8.
245+ 106a.a070.32bb.d1b8.f40e.3585.5771.202a.
246+ d699.0624.5565.a910.d192.e819.d6ef.5218.
247+ c76c.51a3.0654.be30.c24b.8b70.d0f8.9791.
248+ a81a.664b.bc42.3001.a2bf.e8a1.4cf1.0364.
249+ 9272.2c85.1482.353b.81c2.c92e.47ed.aee6.
250+ 766a.0abb.3c77.b2a8.650a.7354.8baf.63de.
251+ 5338.0d13.9d95.b3df.4d2c.6dfc.5ac4.2aed.
252+ 2e1b.2138.5c26.c926.27b7.0a85.46d2.2ffc.
253+ 1429.2967.0a0e.6e70.06ca.6351.e003.826f.
254+ d5a7.9147.930a.a725.c6e0.0bf3.3da8.8fc2.
255+ bf59.7fc7.beef.0ee4.b003.27c8.98fb.213f.
256+ a831.c66d.2db4.3210.983e.5152.ee66.dfab.
257+ 76f9.88da.8311.53b5.5cb0.a9dc.bd41.fbd4.
258+ 4a74.84aa.6ea6.e483.2de9.2c6f.592b.0275.
259+ 240c.a1cc.77ac.9c65.0fc1.9dc6.8b8c.d5b5.
260+ efbe.4786.384f.25e3.e49b.69c1.9ef1.4ad2.
261+ c19b.f174.cf69.2694.9bdc.06a7.25c7.1235.
262+ 80de.b1fe.3b16.96b1.72be.5d74.f27b.896f.
263+ 550c.7dc3.d5ff.b4e2.2431.85be.4ee4.b28c.
264+ 1283.5b01.4570.6fbe.d807.aa98.a303.0242.
265+ ab1c.5ed5.da6d.8118.923f.82a4.af19.4f9b.
266+ 59f1.11f1.b605.d019.3956.c25b.f348.b538.
267+ e9b5.dba5.8189.dbbc.b5c0.fbcf.ec4d.3b2f.
268+ 7137.4491.23ef.65cd.428a.2f98.d728.ae22
269+ =+ ^= hax 0x5be0.cd19.137e.2179.1f83.d9ab.fb41.bd6b.
270+ 9b05.688c.2b3e.6c1f.510e.527f.ade6.82d1.
271+ a54f.f53a.5f1d.36f1.3c6e.f372.fe94.f82b.
272+ bb67.ae85.84ca.a73b.6a09.e667.f3bc.c908
273+ =+ i=0
274+ |- ^- @
275+ ?: =(i lex)
276+ (rep 6 (turn (rip 6 hax) net))
277+ =+ ^= wox
278+ =+ dux=(cut 10 [i 1] ful)
279+ =+ wox=(rep 6 (turn (rip 6 dux) net))
280+ =+ j=16
281+ |- ^- @
282+ ?: =(80 j)
283+ wox
284+ =+ :* l=(wac (sub j 15) wox)
285+ m=(wac (sub j 2) wox)
286+ n=(wac (sub j 16) wox)
287+ o=(wac (sub j 7) wox)
288+ ==
289+ =+ x=:(mix (ror 0 1 l) (ror 0 8 l) (rsh 0 7 l))
290+ =+ y=:(mix (ror 0 19 m) (ror 0 61 m) (rsh 0 6 m))
291+ =+ z=:(sum n x o y)
292+ $(wox (con (lsh 6 j z) wox), j +(j))
293+ =+ j=0
294+ =+ :* a=(wac 0 hax)
295+ b=(wac 1 hax)
296+ c=(wac 2 hax)
297+ d=(wac 3 hax)
298+ e=(wac 4 hax)
299+ f=(wac 5 hax)
300+ g=(wac 6 hax)
301+ h=(wac 7 hax)
302+ ==
303+ |- ^- @
304+ ?: =(80 j)
305+ %= ^$
306+ i +(i)
307+ hax %+ rep 6
308+ :~ (sum a (wac 0 hax))
309+ (sum b (wac 1 hax))
310+ (sum c (wac 2 hax))
311+ (sum d (wac 3 hax))
312+ (sum e (wac 4 hax))
313+ (sum f (wac 5 hax))
314+ (sum g (wac 6 hax))
315+ (sum h (wac 7 hax))
316+ ==
317+ ==
318+ =+ l=:(mix (ror 0 28 a) (ror 0 34 a) (ror 0 39 a)) :: S0
319+ =+ m=:(mix (dis a b) (dis a c) (dis b c)) :: maj
320+ =+ n=(sum l m) :: t2
321+ =+ o=:(mix (ror 0 14 e) (ror 0 18 e) (ror 0 41 e)) :: S1
322+ =+ p=(mix (dis e f) (dis (inv e) g)) :: ch
323+ =+ q=:(sum h o p (wac j kbx) (wac j wox)) :: t1
324+ $(j +(j), a (sum q n), b a, c b, d c, e (sum d q), f e, g f, h g)
325+ ::
326+
327+XX document
328+
329+### `++shan`
330+
331+ ++ shan :: sha-1 (deprecated)
332+ |= ruz=@
333+ =+ [few==>(fe .(a 5)) wac=|=([a=@ b=@] (cut 5 [a 1] b))]
334+ =+ [sum=sum.few ror=ror.few rol=rol.few net=net.few inv=inv.few]
335+ =+ ral=(lsh 0 3 (met 3 ruz))
336+ =+ ^= ful
337+ %+ can 0
338+ :~ [ral ruz]
339+ [8 128]
340+ [(mod (sub 960 (mod (add 8 ral) 512)) 512) 0]
341+ [64 (~(net fe 6) ral)]
342+ ==
343+ =+ lex=(met 9 ful)
344+ =+ kbx=0xca62.c1d6.8f1b.bcdc.6ed9.eba1.5a82.7999
345+ =+ hax=0xc3d2.e1f0.1032.5476.98ba.dcfe.efcd.ab89.6745.2301
346+ =+ i=0
347+ |-
348+ ?: =(i lex)
349+ (rep 5 (flop (rip 5 hax)))
350+ =+ ^= wox
351+ =+ dux=(cut 9 [i 1] ful)
352+ =+ wox=(rep 5 (turn (rip 5 dux) net))
353+ =+ j=16
354+ |- ^- @
355+ ?: =(80 j)
356+ wox
357+ =+ :* l=(wac (sub j 3) wox)
358+ m=(wac (sub j 8) wox)
359+ n=(wac (sub j 14) wox)
360+ o=(wac (sub j 16) wox)
361+ ==
362+ =+ z=(rol 0 1 :(mix l m n o))
363+ $(wox (con (lsh 5 j z) wox), j +(j))
364+ =+ j=0
365+ =+ :* a=(wac 0 hax)
366+ b=(wac 1 hax)
367+ c=(wac 2 hax)
368+ d=(wac 3 hax)
369+ e=(wac 4 hax)
370+ ==
371+ |- ^- @
372+ ?: =(80 j)
373+ %= ^$
374+ i +(i)
375+ hax %+ rep 5
376+ :~
377+ (sum a (wac 0 hax))
378+ (sum b (wac 1 hax))
379+ (sum c (wac 2 hax))
380+ (sum d (wac 3 hax))
381+ (sum e (wac 4 hax))
382+ ==
383+ ==
384+ =+ fx=(con (dis b c) (dis (not 5 1 b) d))
385+ =+ fy=:(mix b c d)
386+ =+ fz=:(con (dis b c) (dis b d) (dis c d))
387+ =+ ^= tem
388+ ?: &((gte j 0) (lte j 19))
389+ :(sum (rol 0 5 a) fx e (wac 0 kbx) (wac j wox))
390+ ?: &((gte j 20) (lte j 39))
391+ :(sum (rol 0 5 a) fy e (wac 1 kbx) (wac j wox))
392+ ?: &((gte j 40) (lte j 59))
393+ :(sum (rol 0 5 a) fz e (wac 2 kbx) (wac j wox))
394+ :(sum (rol 0 5 a) fy e (wac 3 kbx) (wac j wox))
395+ $(j +(j), a tem, b a, c (rol 0 30 b), d c, e d)
396+
397+XX document
398+
399+--
docs/dev/hoon/library/2ez.mdnew file+250
@@ -0,0 +1,250 @@
1+section 2eZ, OLD rendering
2+==========================
3+
4+### `++show`
5+
6+ ++ show :: XX deprecated, use type
7+ |= vem=*
8+ |^ ^- tank
9+ ?: ?=(@ vem)
10+ [%leaf (mesc (trip vem))]
11+ ?- vem
12+ [s=~ c=*]
13+ [%leaf '\'' (weld (mesc (tape +.vem)) `tape`['\'' ~])]
14+ ::
15+ [s=%a c=@] [%leaf (mesc (trip c.vem))]
16+ [s=%b c=*] (shop c.vem |=(a=@ ~(rub at a)))
17+ [s=[%c p=@] c=*]
18+ :+ %palm
19+ [['.' ~] ['-' ~] ~ ~]
20+ [[%leaf (mesc (trip p.s.vem))] $(vem c.vem) ~]
21+ ::
22+ [s=%d c=*] (shop c.vem |=(a=@ ~(rud at a)))
23+ [s=%k c=*] (tank c.vem)
24+ [s=%h c=*]
25+ ?: =(0 c.vem) :: XX remove after 220
26+ [%leaf '#' ~]
27+ :+ %rose
28+ [['/' ~] ['/' ~] ~]
29+ =+ yol=((list ,@ta) c.vem)
30+ (turn yol |=(a=@ta [%leaf (trip a)]))
31+ ::
32+ [s=%o c=*]
33+ %= $
34+ vem
35+ :- [%m '%h:<[%d %d].[%d %d]>']
36+ [-.c.vem +<-.c.vem +<+.c.vem +>-.c.vem +>+.c.vem ~]
37+ ==
38+ ::
39+ [s=%p c=*] (shop c.vem |=(a=@ ~(rup at a)))
40+ [s=%q c=*] (shop c.vem |=(a=@ ~(r at a)))
41+ [s=%r c=*] $(vem [[%r ' ' '{' '}'] c.vem])
42+ [s=%t c=*] (shop c.vem |=(a=@ ~(rt at a)))
43+ [s=%v c=*] (shop c.vem |=(a=@ ~(ruv at a)))
44+ [s=%x c=*] (shop c.vem |=(a=@ ~(rux at a)))
45+ [s=[%m p=@] c=*] (shep p.s.vem c.vem)
46+ [s=[%r p=@] c=*]
47+ $(vem [[%r ' ' (cut 3 [0 1] p.s.vem) (cut 3 [1 1] p.s.vem)] c.vem])
48+ ::
49+ [s=[%r p=@ q=@ r=@] c=*]
50+ :+ %rose
51+ :* p=(mesc (trip p.s.vem))
52+ q=(mesc (trip q.s.vem))
53+ r=(mesc (trip r.s.vem))
54+ ==
55+ |- ^- (list tank)
56+ ?@ c.vem
57+ ~
58+ [^$(vem -.c.vem) $(c.vem +.c.vem)]
59+ ::
60+ [s=%z c=*] $(vem [[%r %$ %$ %$] c.vem])
61+ * !!
62+ ==
63+
64+XX document
65+
66+### `++shep`
67+
68+ ++ shep
69+ |= [fom=@ gar=*]
70+ ^- tank
71+ =+ l=(met 3 fom)
72+ =+ i=0
73+ :- %leaf
74+ |- ^- tape
75+ ?: (gte i l)
76+ ~
77+ =+ c=(cut 3 [i 1] fom)
78+ ?. =(37 c)
79+ (weld (mesc [c ~]) $(i +(i)))
80+ =+ d=(cut 3 [+(i) 1] fom)
81+ ?. .?(gar)
82+ ['\\' '#' $(i (add 2 i))]
83+ (weld ~(ram re (show d -.gar)) $(i (add 2 i), gar +.gar))
84+ ::
85+
86+XX document
87+
88+### `++shop`
89+
90+ ++ shop
91+ |= [aug=* vel=$+(a=@ tape)]
92+ ^- tank
93+ ?: ?=(@ aug)
94+ [%leaf (vel aug)]
95+ :+ %rose
96+ [[' ' ~] ['[' ~] [']' ~]]
97+ => .(aug `*`aug)
98+ |- ^- (list tank)
99+ ?: ?=(@ aug)
100+ [^$ ~]
101+ [^$(aug -.aug) $(aug +.aug)]
102+ --
103+
104+XX document
105+
106+### `++at`
107+
108+ ++ at
109+ |_ a=@
110+
111+XX document
112+
113+### `++r`
114+
115+ ++ r
116+ ?: ?& (gte (met 3 a) 2)
117+ |-
118+ ?: =(0 a)
119+ &
120+ =+ vis=(end 3 1 a)
121+ ?& ?|(=('-' vis) ?&((gte vis 'a') (lte vis 'z')))
122+ $(a (rsh 3 1 a))
123+ ==
124+ ==
125+ rtam
126+ ?: (lte (met 3 a) 2)
127+ rud
128+ rux
129+ ::
130+
131+XX document
132+
133+### `++rf`
134+
135+ ++ rf `tape`[?-(a & '&', | '|', * !!) ~]
136+
137+XX document
138+
139+### `++rn`
140+
141+ ++ rn `tape`[?>(=(0 a) '~') ~]
142+
143+XX document
144+
145+### `++rt`
146+
147+ ++ rt `tape`['\'' (weld (mesc (trip a)) `tape`['\'' ~])]
148+
149+XX document
150+
151+### `++rta`
152+
153+ ++ rta rt
154+
155+XX document
156+
157+### `++rtam`
158+
159+ ++ rtam `tape`['%' (trip a)]
160+
161+XX document
162+
163+### `++rub`
164+
165+ ++ rub `tape`['0' 'b' (rum 2 ~ |=(b=@ (add '0' b)))]
166+
167+XX document
168+
169+### `++rud`
170+
171+ ++ rud (rum 10 ~ |=(b=@ (add '0' b)))
172+
173+XX document
174+
175+### `++rum`
176+
177+ ++ rum
178+ |= [b=@ c=tape d=$+(@ @)]
179+ ^- tape
180+ ?: =(0 a)
181+ [(d 0) c]
182+ =+ e=0
183+ |- ^- tape
184+ ?: =(0 a)
185+ c
186+ =+ f=&(!=(0 e) =(0 (mod e ?:(=(10 b) 3 4))))
187+ %= $
188+ a (div a b)
189+ c [(d (mod a b)) ?:(f [?:(=(10 b) ',' '-') c] c)]
190+ e +(e)
191+ ==
192+ ::
193+
194+XX document
195+
196+### `++rup`
197+
198+ ++ rup
199+ =+ b=(met 3 a)
200+ ^- tape
201+ :- '-'
202+ |- ^- tape
203+ ?: (gth (met 5 a) 1)
204+ %+ weld
205+ $(a (rsh 5 1 a), b (sub b 4))
206+ `tape`['-' '-' $(a (end 5 1 a), b 4)]
207+ ?: =(0 b)
208+ ['~' ~]
209+ ?: (lte b 1)
210+ (trip (tos:po a))
211+ |- ^- tape
212+ ?: =(2 b)
213+ =+ c=(rsh 3 1 a)
214+ =+ d=(end 3 1 a)
215+ (weld (trip (tod:po c)) (trip (tos:po (mix c d))))
216+ =+ c=(rsh 3 2 a)
217+ =+ d=(end 3 2 a)
218+ (weld ^$(a c, b (met 3 c)) `tape`['-' $(a (mix c d), b 2)])
219+ ::
220+
221+XX document
222+
223+### `++ruv`
224+
225+ ++ ruv
226+ ^- tape
227+ :+ '0'
228+ 'v'
229+ %^ rum
230+ 64
231+ ~
232+ |= b=@
233+ ?: =(63 b)
234+ '+'
235+ ?: =(62 b)
236+ '-'
237+ ?:((lth b 26) (add 65 b) ?:((lth b 52) (add 71 b) (sub b 4)))
238+ ::
239+
240+XX document
241+
242+### `++rux`
243+
244+ ++ rux `tape`['0' 'x' (rum 16 ~ |=(b=@ (add b ?:((lth b 10) 48 87))))]
245+ --
246+ :::::::::::::::::::::::::::::::::::::::::::::::::::::: ::
247+
248+XX document
249+
250+------------------------------------------------------------------------
docs/dev/hoon/library/3ba.mdnew file+67
@@ -0,0 +1,67 @@
1+section 3bA, lite number theory
2+===============================
3+
4+### `++fu`
5+
6+ ++ fu :: modulo (mul p q)
7+ |= a=[p=@ q=@]
8+ =+ b=?:(=([0 0] a) 0 (~(inv fo p.a) (~(sit fo p.a) q.a)))
9+ |%
10+
11+XX document
12+
13+### `++dif`
14+
15+ ++ dif
16+ |= [c=[@ @] d=[@ @]]
17+ [(~(dif fo p.a) -.c -.d) (~(dif fo q.a) +.c +.d)]
18+ ::
19+
20+XX document
21+
22+### `++exp`
23+
24+ ++ exp
25+ |= [c=@ d=[@ @]]
26+ :- (~(exp fo p.a) (mod c (dec p.a)) -.d)
27+ (~(exp fo q.a) (mod c (dec q.a)) +.d)
28+ ::
29+
30+XX document
31+
32+### `++out`
33+
34+ ++ out :: garner's formula
35+ |= c=[@ @]
36+ %+ add
37+ +.c
38+ (mul q.a (~(pro fo p.a) b (~(dif fo p.a) -.c (~(sit fo p.a) +.c))))
39+ ::
40+
41+XX document
42+
43+### `++pro`
44+
45+ ++ pro
46+ |= [c=[@ @] d=[@ @]]
47+ [(~(pro fo p.a) -.c -.d) (~(pro fo q.a) +.c +.d)]
48+ ::
49+
50+XX document
51+
52+### `++sum`
53+
54+ ++ sum
55+ |= [c=[@ @] d=[@ @]]
56+ [(~(sum fo p.a) -.c -.d) (~(sum fo q.a) +.c +.d)]
57+ ::
58+
59+XX document
60+
61+### `++sit`
62+
63+ ++ sit
64+ |= c=@
65+ [(mod c p.a) (mod c q.a)]
66+
67+XX document
docs/dev/hoon/library/3bb.mdnew file+600
@@ -0,0 +1,600 @@
1+section 3bB, cryptosuites
2+=========================
3+
4+### `++crua`
5+
6+ ++ crua !: :: cryptosuite A (RSA)
7+ ^- acru
8+ =| [mos=@ pon=(unit ,[p=@ q=@ r=[p=@ q=@] s=_*fu])]
9+ => |%
10+
11+XX document
12+
13+### `++mx`
14+
15+ ++ mx (dec (met 0 mos)) :: bit length
16+
17+XX document
18+
19+### `++dap`
20+
21+ ++ dap :: OEAP decode
22+ |= [wid=@ xar=@ dog=@] ^- [p=@ q=@]
23+ =+ pav=(sub wid xar)
24+ =+ qoy=(cut 0 [xar pav] dog)
25+ =+ dez=(mix (end 0 xar dog) (shaw %pad-b xar qoy))
26+ [dez (mix qoy (shaw %pad-a pav dez))]
27+ ::
28+
29+XX document
30+
31+### `++pad`
32+
33+ ++ pad :: OEAP encode
34+ |= [wid=@ rax=[p=@ q=@] meg=@] ^- @
35+ =+ pav=(sub wid p.rax)
36+ ?> (gte pav (met 0 meg))
37+ ^- @
38+ =+ qoy=(mix meg (shaw %pad-a pav q.rax))
39+ =+ dez=(mix q.rax (shaw %pad-b p.rax qoy))
40+ (can 0 [p.rax dez] [pav qoy] ~)
41+ |%
42+
43+XX document
44+
45+### `++pull`
46+
47+ ++ pull |=(a=@ (~(exp fo mos) 3 a))
48+
49+XX document
50+
51+### `++push`
52+
53+ ++ push |=(a=@ (~(exp fo mos) 5 a))
54+
55+XX document
56+
57+### `++pump`
58+
59+ ++ pump
60+ |= a=@ ^- @
61+ ?~ pon !!
62+ (out.s.u.pon (exp.s.u.pon p.r.u.pon (sit.s.u.pon a)))
63+ ::
64+
65+XX document
66+
67+### `++punt`
68+
69+ ++ punt
70+ |= a=@ ^- @
71+ ?~ pon !!
72+ (out.s.u.pon (exp.s.u.pon q.r.u.pon (sit.s.u.pon a)))
73+ |%
74+
75+XX document
76+
77+### `++as`
78+
79+ ++ as
80+ => |%
81+
82+XX document
83+
84+### `++haul`
85+
86+ ++ haul :: revealing haul
87+ |= a=pass
88+ !!
89+ ^?
90+ |% ++ seal
91+ |= [a=pass b=@ c=@]
92+ ^- @
93+ !!
94+
95+XX document
96+
97+### `++seal`
98+
99+
100+ XX document
101+
102+ ###++sign
103+
104+ ```
105+ ++ sign
106+ |= [a=@ b=@] ^- @
107+ !!
108+ ```
109+
110+ XX document
111+
112+ ###++sure
113+
114+ ```
115+ ++ sure
116+ |= [a=@ b=@]
117+ ^- (unit ,@)
118+ !!
119+ ```
120+
121+ XX document
122+
123+ ###++tear
124+
125+ ```
126+ ++ tear
127+ |= [a=pass b=@]
128+ ^- (unit ,[p=@ q=@])
129+ !!
130+ ::
131+ ```
132+
133+ XX document
134+
135+ ###++de
136+
137+ ```
138+ ++ de
139+ |+ [key=@ cep=@] ^- (unit ,@)
140+ !!
141+ ::
142+ ```
143+
144+ XX document
145+
146+ ###++dy
147+
148+ ```
149+ ++ dy
150+ |+ [a=@ b=@] ^- @
151+ !!
152+ ```
153+
154+ XX document
155+
156+ ###++en
157+
158+ ```
159+ ++ en
160+ |+ [key=@ msg=@] ^- @ux
161+ !!
162+ ::
163+ ```
164+
165+ XX document
166+
167+ ###++ex
168+
169+ ```
170+ ++ ex ^?
171+ |% ++ fig ^- @uvH (shaf %bfig puc)
172+ ```
173+
174+ XX document
175+
176+ ###++fig
177+
178+XX document
179+
180+### `++pac`
181+
182+ ++ pac ^- @uvG (end 6 1 (shaf %acod sec))
183+
184+XX document
185+
186+### `++pub`
187+
188+ ++ pub ^- pass (cat 3 'b' puc)
189+
190+XX document
191+
192+### `++sec`
193+
194+ ++ sec ^- ring sed
195+ ::
196+
197+XX document
198+
199+### `++nu`
200+
201+ ++ nu
202+ ^?
203+ |% ++ com
204+ |= a=@
205+ ^+ ^?(..nu)
206+ ..nu(sed ~, puc a)
207+ ::
208+
209+XX document
210+
211+### `++elcm`
212+
213+ ++ elcm
214+ |= [a=@ b=@]
215+ (div (mul a b) d:(egcd a b))
216+ ::
217+
218+XX document
219+
220+### `++eldm`
221+
222+ ++ eldm
223+ |= [a=@ b=@ c=@]
224+ (~(inv fo (elcm (dec b) (dec c))) a)
225+ ::
226+
227+XX document
228+
229+### `++ersa`
230+
231+ ++ ersa
232+ |= [a=@ b=@]
233+ [a b [(eldm 3 a b) (eldm 5 a b)] (fu a b)]
234+ ^?
235+ |% ++ com
236+ |= a=@
237+ ^+ ^?(..nu)
238+ ..nu(mos a, pon ~)
239+ ::
240+
241+XX document
242+
243+### `++com`
244+
245+
246+ XX document
247+
248+ ###++pit
249+
250+ ```
251+ ++ pit
252+ |= [a=@ b=@]
253+ ^+ ^?(..nu)
254+ ..nu(sed b, puc (puck:ed b))
255+ ::
256+ ```
257+
258+ XX document
259+
260+ ###++nol
261+
262+ ```
263+ ++ nol
264+ |= a=@
265+ ^+ ^?(..nu)
266+ ..nu(sed a, puc (puck:ed a))
267+ ```
268+
269+ XX document
270+
271+ ###++bruw
272+
273+ ```
274+ ++ bruw :: create keypair
275+ |= [a=@ b=@] :: width seed
276+ ^- acru
277+ (pit:nu:crua a b)
278+ ::
279+ ```
280+
281+ XX document
282+
283+ ###++haul
284+
285+ ```
286+ ++ haul :: revealing haul
287+ |= a=pass
288+ !!
289+ ^?
290+ |% ++ seal
291+ |= [a=pass b=@ c=@]
292+ ^- @
293+ !!
294+ ```
295+
296+ XX document
297+
298+ ###++weur
299+
300+ ```
301+ ++ weur :: activate secret key
302+ |= a=ring
303+ ^- acru
304+ =+ [mag=(end 3 1 a) bod=(rsh 3 1 a)]
305+ ?> =('A' mag)
306+ (nol:nu:crua bod)
307+ ::
308+ ```
309+
310+ XX document
311+
312+ ###++trua
313+
314+ ```
315+ ++ trua :: test rsa
316+ |= msg=@tas
317+ ^- @
318+ =+ ali=(bruw 1.024 (shax 'ali'))
319+ =+ bob=(bruw 1.024 (shax 'bob'))
320+ =+ tef=(sign:as.ali [0 msg])
321+ =+ lov=(sure:as.ali [0 tef])
322+ ?. &(?=(^ lov) =(msg u.lov))
323+ ~|(%test-fail-sign !!)
324+ =+ key=(shax (shax (shax msg)))
325+ =+ sax=(seal:as.ali pub:ex.bob key msg)
326+ =+ tin=(tear:as.bob pub:ex.ali sax)
327+ ?. &(?=(^ tin) =(key p.u.tin) =(msg q.u.tin))
328+ ~|(%test-fail-seal !!)
329+ msg
330+ ::
331+ ```
332+
333+ XX document
334+
335+ ###++crub
336+
337+ ```
338+ ++ crub :: cryptosuite B (Ed)
339+ ^- acru
340+ =| [puc=pass sed=ring]
341+ => |%
342+ ```
343+
344+ XX document
345+
346+ ###++dap
347+
348+ ```
349+ ++ dap :: OEAP decode
350+ |= [wid=@ xar=@ dog=@] ^- [p=@ q=@]
351+ =+ pav=(sub wid xar)
352+ =+ qoy=(cut 0 [xar pav] dog)
353+ =+ dez=(mix (end 0 xar dog) (shaw %pad-b xar qoy))
354+ [dez (mix qoy (shaw %pad-a pav dez))]
355+ ::
356+ ```
357+
358+ XX document
359+
360+ ###++pad
361+
362+ ```
363+ ++ pad :: OEAP encode
364+ |= [wid=@ rax=[p=@ q=@] meg=@] ^- @
365+ =+ pav=(sub wid p.rax)
366+ ?> (gte pav (met 0 meg))
367+ ^- @
368+ =+ qoy=(mix meg (shaw %pad-a pav q.rax))
369+ =+ dez=(mix q.rax (shaw %pad-b p.rax qoy))
370+ (can 0 [p.rax dez] [pav qoy] ~)
371+ |%
372+ ```
373+
374+ XX document
375+
376+ ###++as
377+
378+ ```
379+ ++ as
380+ => |%
381+ ```
382+
383+ XX document
384+
385+ ###++haul
386+
387+ ```
388+ ++ haul :: revealing haul
389+ |= a=pass
390+ !!
391+ ^?
392+ |% ++ seal
393+ |= [a=pass b=@ c=@]
394+ ^- @
395+ !!
396+ ```
397+
398+ XX document
399+
400+ ###++seal
401+
402+XX document
403+
404+### `++sign`
405+
406+ ++ sign
407+ |= [a=@ b=@] ^- @
408+ !!
409+
410+XX document
411+
412+### `++sure`
413+
414+ ++ sure
415+ |= [a=@ b=@]
416+ ^- (unit ,@)
417+ !!
418+
419+XX document
420+
421+### `++tear`
422+
423+ ++ tear
424+ |= [a=pass b=@]
425+ ^- (unit ,[p=@ q=@])
426+ !!
427+ ::
428+
429+XX document
430+
431+### `++de`
432+
433+ ++ de
434+ |+ [key=@ cep=@] ^- (unit ,@)
435+ !!
436+ ::
437+
438+XX document
439+
440+### `++dy`
441+
442+ ++ dy
443+ |+ [a=@ b=@] ^- @
444+ !!
445+
446+XX document
447+
448+### `++en`
449+
450+ ++ en
451+ |+ [key=@ msg=@] ^- @ux
452+ !!
453+ ::
454+
455+XX document
456+
457+### `++ex`
458+
459+ ++ ex ^?
460+ |% ++ fig ^- @uvH (shaf %bfig puc)
461+
462+XX document
463+
464+### `++fig`
465+
466+
467+ XX document
468+
469+ ###++pac
470+
471+ ```
472+ ++ pac ^- @uvG (end 6 1 (shaf %acod sec))
473+ ```
474+
475+ XX document
476+
477+ ###++pub
478+
479+ ```
480+ ++ pub ^- pass (cat 3 'b' puc)
481+ ```
482+
483+ XX document
484+
485+ ###++sec
486+
487+ ```
488+ ++ sec ^- ring sed
489+ ::
490+ ```
491+
492+ XX document
493+
494+ ###++nu
495+
496+ ```
497+ ++ nu
498+ ^?
499+ |% ++ com
500+ |= a=@
501+ ^+ ^?(..nu)
502+ ..nu(sed ~, puc a)
503+ ::
504+ ```
505+
506+ XX document
507+
508+ ###++com
509+
510+XX document
511+
512+### `++pit`
513+
514+ ++ pit
515+ |= [a=@ b=@]
516+ ^+ ^?(..nu)
517+ ..nu(sed b, puc (puck:ed b))
518+ ::
519+
520+XX document
521+
522+### `++nol`
523+
524+ ++ nol
525+ |= a=@
526+ ^+ ^?(..nu)
527+ ..nu(sed a, puc (puck:ed a))
528+
529+XX document
530+
531+### `++brew`
532+
533+ ++ brew :: create keypair
534+ |= [a=@ b=@] :: width seed
535+ ^- acru
536+ (pit:nu:crub a b)
537+ ::
538+
539+XX document
540+
541+### `++hail`
542+
543+ ++ hail :: activate public key
544+ |= a=pass
545+ ^- acru
546+ =+ [mag=(end 3 1 a) bod=(rsh 3 1 a)]
547+ ?> =('b' mag)
548+ (com:nu:crub bod)
549+ ::
550+
551+XX document
552+
553+### `++wear`
554+
555+ ++ wear :: activate secret key
556+ |= a=ring
557+ ^- acru
558+ =+ [mag=(end 3 1 a) bod=(rsh 3 1 a)]
559+ ?> =('b' mag)
560+ (nol:nu:crub bod)
561+ ::
562+
563+XX document
564+
565+### `++trub`
566+
567+ ++ trub :: test ed
568+ |= msg=@tas
569+ ^- @
570+ =+ ali=(brew 1.024 (shax 'ali'))
571+ =+ bob=(brew 1.024 (shax 'bob'))
572+ =+ tef=(sign:as.ali [0 msg])
573+ =+ lov=(sure:as.ali [0 tef])
574+ ?. &(?=(^ lov) =(msg u.lov))
575+ ~|(%test-fail-sign !!)
576+ =+ key=(shax (shax (shax msg)))
577+ =+ sax=(seal:as.ali pub:ex.bob key msg)
578+ =+ tin=(tear:as.bob pub:ex.ali sax)
579+ ?. &(?=(^ tin) =(key p.u.tin) =(msg q.u.tin))
580+ ~|(%test-fail-seal !!)
581+ msg
582+ ::
583+
584+XX document
585+
586+### `++hmac`
587+
588+ ++ hmac :: HMAC-SHA1
589+ |= [key=@ mes=@]
590+ =+ ip=(fil 3 64 0x36)
591+ =+ op=(fil 3 64 0x5c)
592+ =+ ^= kex
593+ ?: (gth (met 3 key) 64)
594+ (lsh 3 44 (shan (swap 3 key)))
595+ (lsh 3 (sub 64 (met 3 key)) (swap 3 key))
596+ =+ inn=(shan (swap 3 (cat 3 (swap 3 mes) (mix ip kex))))
597+ (shan (swap 3 (cat 3 inn (mix op kex))))
598+ ::
599+
600+XX document
docs/dev/hoon/library/3bc.mdnew file+382
@@ -0,0 +1,382 @@
1+section 3bC, Gregorian UTC
2+==========================
3+
4+### `++dawn`
5+
6+Weekday of Jan 1
7+
8+ ++ dawn :: weekday of jan 1
9+ |= yer=@ud
10+ =+ yet=(sub yer 1)
11+ %- mod :_ 7
12+ :(add 1 (mul 5 (mod yet 4)) (mul 4 (mod yet 100)) (mul 6 (mod yet 400)))
13+ ::
14+
15+Computes which day of the week January 1st falls on for a year `yer`,
16+producing an atom. Weeks are zero-indexed beginning on Sunday.
17+
18+`yer` is an unsigned decimal, [`@ud`]().
19+
20+ ~zod/try=> (dawn 2.015)
21+ 4
22+ ~zod/try=> (dawn 1)
23+ 1
24+ ~zod/try=> (dawn 0)
25+ ! subtract-underflow
26+ ! exit
27+
28+------------------------------------------------------------------------
29+
30+### `++daws`
31+
32+Weekday of date
33+
34+ ++ daws :: weekday of date
35+ |= yed=date
36+ %- mod :_ 7
37+ (add (dawn y.yed) (sub (yawn [y.yed m.yed d.t.yed]) (yawn y.yed 1 1)))
38+ ::
39+
40+Produces the day of the week of a given date `yed` as an atom. Weeks are
41+zero-indexed beginning on Sunday.
42+
43+`yed` is a [`date`]().
44+
45+ ~zod/try=> (daws [[a=%.y y=2.014] m=6 t=[d=6 h=21 m=9 s=15 f=~[0xa16]]])
46+ 5
47+ ~zod/try=> (daws (yore -<-))
48+ 2
49+
50+(second example always returns the current date).
51+
52+------------------------------------------------------------------------
53+
54+### `++deal`
55+
56+Add leap seconds
57+
58+ ++ deal :: to leap sec time
59+ |= yer=@da
60+ =+ n=0
61+ =+ yud=(yore yer)
62+ |- ^- date
63+ ?: (gte yer (add (snag n lef:yu) ~s1))
64+ (yore (year yud(s.t (add n s.t.yud))))
65+ ?: &((gte yer (snag n lef:yu)) (lth yer (add (snag n lef:yu) ~s1)))
66+ yud(s.t (add +(n) s.t.yud))
67+ ?: =(+(n) (lent lef:yu))
68+ (yore (year yud(s.t (add +(n) s.t.yud))))
69+ $(n +(n))
70+ ::
71+
72+Produces a [`date`]() with the 25 leap seconds added.
73+
74+`yer` is an absolute date, [`@da`]().
75+
76+ ~zod/try=> (yore (bex 127))
77+ [[a=%.y y=226] m=12 t=[d=5 h=15 m=30 s=8 f=~]]
78+ ~zod/try=> (deal `@da`(bex 127))
79+ [[a=%.y y=226] m=12 t=[d=5 h=15 m=30 s=33 f=~]]
80+ ~zod/try=> (yore (bex 126))
81+ [[a=%.n y=146.138.512.088] m=6 t=[d=19 h=7 m=45 s=4 f=~]]
82+
83+------------------------------------------------------------------------
84+
85+### `++lead`
86+
87+Subtract leap seconds
88+
89+ ++ lead :: from leap sec time
90+ |= ley=date
91+ =+ ler=(year ley)
92+ =+ n=0
93+ |- ^- @da
94+ =+ led=(sub ler (mul n ~s1))
95+ ?: (gte ler (add (snag n les:yu) ~s1))
96+ led
97+ ?: &((gte ler (snag n les:yu)) (lth ler (add (snag n les:yu) ~s1)))
98+ ?: =(s.t.ley 60)
99+ (sub led ~s1)
100+ led
101+ ?: =(+(n) (lent les:yu))
102+ (sub led ~s1)
103+ $(n +(n))
104+ ::
105+
106+Produces an absolute date ([`@ud`]()) with the 25 leap seconds
107+subtracted.
108+
109+`ley` is a [`date`]().
110+
111+ ~zod/try=> (yore `@da`(bex 127))
112+ [[a=%.y y=226] m=12 t=[d=5 h=15 m=30 s=8 f=~]]
113+ ~zod/try=> (lead (yore `@da`(bex 127)))
114+ ~226.12.5..15.29.43
115+ ~zod/try=> (lead (yore `@da`(bex 126)))
116+ ~146138512088-.6.19..07.44.39
117+
118+------------------------------------------------------------------------
119+
120+### `++dust`
121+
122+Print UTC format
123+
124+ ++ dust :: print UTC format
125+ |= yed=date
126+ ^- tape
127+ =+ wey=(daws yed)
128+ ;: weld
129+ `tape`(snag wey (turn wik:yu |=(a=tape (scag 3 a))))
130+ ", " ~(rud at d.t.yed) " "
131+ `tape`(snag (dec m.yed) (turn mon:yu |=(a=tape (scag 3 a))))
132+ " " (scag 1 ~(rud at y.yed)) (slag 2 ~(rud at y.yed)) " "
133+ ~(rud at h.t.yed) ":" ~(rud at m.t.yed) ":" ~(rud at s.t.yed)
134+ " " "+0000"
135+ ==
136+ ::
137+
138+Produces a [tape]() of the date in UTC format.
139+
140+`yed` is a [`date`]().
141+
142+ ~zod/try=> (dust (yore ->-))
143+ "Tue, 21 Oct 2014 21:35:12 +0000"
144+ ~zod/try=> (dust [[a=%.y y=2.002] m=10 t=[d=11 h=12 m=20 s=55 f=~]])
145+ "Fri, 11 Oct 2002 12:20:55 +0000"
146+
147+------------------------------------------------------------------------
148+
149+### `++stud`
150+
151+Parse UTC format
152+
153+ ++ stud :: parse UTC format
154+ |= cud=tape
155+ ^- (unit date)
156+ =- ?~ tud ~
157+ `[[%.y &3.u.tud] &2.u.tud &1.u.tud &4.u.tud &5.u.tud &6.u.tud ~]
158+ ^= tud
159+ %+ rust cud
160+ ;~ plug
161+ ;~(pfix (stun [5 5] next) dim:ag)
162+ ::
163+ %+ cook
164+ |= a=tape
165+ =+ b=0
166+ |- ^- @
167+ ?: =(a (snag b (turn mon:yu |=(a=tape (scag 3 a)))))
168+ +(b)
169+ $(b +(b))
170+ (ifix [ace ace] (star alf))
171+ ::
172+ ;~(sfix dim:ag ace)
173+ ;~(sfix dim:ag col)
174+ ;~(sfix dim:ag col)
175+ dim:ag
176+ (cold ~ (star next))
177+ ==
178+ ::
179+
180+Accepts a [tape]() containing a date in UTC format and produces the
181+[unit]() of a [`date`]().
182+
183+ ~zod/try=> (stud "Tue, 21 Oct 2014 21:21:55 +0000")
184+ [~ [[a=%.y y=2.014] m=10 t=[d=21 h=21 m=21 s=55 f=~]]]
185+ ~zod/try=> (stud "Wed, 11 Oct 2002 12:20:55 +0000")
186+ [~ [[a=%.y y=2.002] m=10 t=[d=11 h=12 m=20 s=55 f=~]]]
187+ ~zod/try=> (stud "Wed, 11 Oct 2002")
188+ ~
189+
190+------------------------------------------------------------------------
191+
192+### `++unt`
193+
194+UGT to UTC time
195+
196+ ++ unt :: UGT to UTC time
197+ |= a=@da
198+ (div (sub a ~1970.1.1) (bex 64))
199+ ::
200+
201+ ~zod/try=/hom> (unt -<-)
202+ 1.413.927.704
203+ ~zod/try=> (unt ~20014.1.1)
204+ 569.413.670.400
205+ ~zod/try=> (unt ~2014.1.1)
206+ 1.388.534.400
207+
208+Transforms Urbit Galactic Time to UTC time, producing an atom.
209+
210+`a` is an [atom]().
211+
212+------------------------------------------------------------------------
213+
214+### `++yu`
215+
216+UTC format constants
217+
218+ ++ yu :: UTC format constants
219+ |%
220+
221+ ~zod/try=/hom> yu
222+ <4.pgn 250.tmw 41.cmo 414.rvm 101.jzo 1.ypj %164>
223+
224+------------------------------------------------------------------------
225+
226+### `++mon`
227+
228+Months
229+
230+ ++ mon ^- (list tape)
231+ :~ "January" "February" "March" "April" "May" "June" "July"
232+ "August" "September" "October" "November" "December"
233+ ==
234+ ::
235+
236+Produces a list of [tapes]() containing the 12 months of the year.
237+
238+ ~zod/try=/hom> mon:yu
239+ <<
240+ "January"
241+ "February"
242+ "March"
243+ "April"
244+ "May"
245+ "June"
246+ "July"
247+ "August"
248+ "September"
249+ "October"
250+ "November"
251+ "December"
252+ >>
253+ ~zod/try=/hom> (snag 1 mon:yu)
254+ "February"
255+
256+------------------------------------------------------------------------
257+
258+### `++wik`
259+
260+Weeks
261+
262+ ++ wik ^- (list tape)
263+ :~ "Sunday" "Monday" "Tuesday" "Wednesday" "Thursday"
264+ "Friday" "Saturday"
265+ ==
266+ ::
267+
268+Produces a list of [tapes]() containing the 7 days of the week,
269+beginning with Sunday.
270+
271+ ~zod/try=/hom> wik:yu
272+ <<"Sunday" "Monday" "Tuesday" "Wednesday" "Thursday" "Friday" "Saturday">>
273+ ~zod/try=/hom> (snag 2 wik:yu)
274+ "Tuesday"
275+ ~zod/try=/hom> (snag (daws (yore -<-)) wik:yu)
276+ "Tuesday"
277+
278+------------------------------------------------------------------------
279+
280+### `++les`
281+
282+Leap second dates
283+
284+ ++ les ^- (list ,@da)
285+ :~ ~2015.7.1 ~2012.7.1 ~2009.1.1 ~2006.1.1 ~1999.1.1 ~1997.7.1
286+ ~1996.1.1 ~1994.7.1 ~1993.7.1 ~1992.7.1 ~1991.1.1 ~1990.1.1
287+ ~1988.1.1 ~1985.7.1 ~1983.7.1 ~1982.7.1 ~1981.7.1 ~1980.1.1
288+ ~1979.1.1 ~1978.1.1 ~1977.1.1 ~1976.1.1 ~1975.1.1 ~1974.1.1
289+ ~1973.1.1 ~1972.7.1
290+ ==
291+
292+Produces a list of the (absolute) dates ([`@da`]) of the 25 leap seconds
293+
294+ ~zod/try=/hom> les:yu
295+ ~[
296+ ~2015.7.1
297+ ~2012.7.1
298+ ~2009.1.1
299+ ~2006.1.1
300+ ~1999.1.1
301+ ~1997.7.1
302+ ~1996.1.1
303+ ~1994.7.1
304+ ~1993.7.1
305+ ~1992.7.1
306+ ~1991.1.1
307+ ~1990.1.1
308+ ~1988.1.1
309+ ~1985.7.1
310+ ~1983.7.1
311+ ~1982.7.1
312+ ~1981.7.1
313+ ~1980.1.1
314+ ~1979.1.1
315+ ~1978.1.1
316+ ~1977.1.1
317+ ~1976.1.1
318+ ~1975.1.1
319+ ~1974.1.1
320+ ~1973.1.1
321+ ~1972.7.1
322+ ]
323+ ~zod/try=/hom> (snag 2 les:yu)
324+ ~2006.1.1
325+
326+------------------------------------------------------------------------
327+
328+### `++lef`
329+
330+Back-shifted leap second dates
331+
332+ ++ lef ^- (list ,@da)
333+ :~ ~2015.6.30..23.59.59 ~2012.6.30..23.59.59
334+ ~2008.12.31..23.59.58 ~2005.12.31..23.59.57
335+ ~1998.12.31..23.59.56 ~1997.6.30..23.59.55
336+ ~1995.12.31..23.59.54 ~1994.6.30..23.59.53
337+ ~1993.6.30..23.59.52 ~1992.6.30..23.59.51
338+ ~1990.12.31..23.59.50 ~1989.12.31..23.59.49
339+ ~1987.12.31..23.59.48 ~1985.6.30..23.59.47
340+ ~1983.6.30..23.59.46 ~1982.6.30..23.59.45
341+ ~1981.6.30..23.59.44 ~1979.12.31..23.59.43
342+ ~1978.12.31..23.59.42 ~1977.12.31..23.59.41
343+ ~1976.12.31..23.59.40 ~1975.12.31..23.59.39
344+ ~1974.12.31..23.59.38 ~1973.12.31..23.59.37
345+ ~1972.12.31..23.59.36 ~1972.6.30..23.59.35
346+ ==
347+ ::
348+
349+Produces a list of absolute dates ([`@da`]()) that represent the Urbit
350+Galactc Time equivalents of the UTC leap second dates in [`++les`](/doc/hoon/library/3bc#++les).
351+
352+ ~zod/try=/hom> lef:yu
353+ ~[
354+ ~2015.6.30..23.59.59
355+ ~2012.6.30..23.59.59
356+ ~2008.12.31..23.59.58
357+ ~2005.12.31..23.59.57
358+ ~1998.12.31..23.59.56
359+ ~1997.6.30..23.59.55
360+ ~1995.12.31..23.59.54
361+ ~1994.6.30..23.59.53
362+ ~1993.6.30..23.59.52
363+ ~1992.6.30..23.59.51
364+ ~1990.12.31..23.59.50
365+ ~1989.12.31..23.59.49
366+ ~1987.12.31..23.59.48
367+ ~1985.6.30..23.59.47
368+ ~1983.6.30..23.59.46
369+ ~1982.6.30..23.59.45
370+ ~1981.6.30..23.59.44
371+ ~1979.12.31..23.59.43
372+ ~1978.12.31..23.59.42
373+ ~1977.12.31..23.59.41
374+ ~1976.12.31..23.59.40
375+ ~1975.12.31..23.59.39
376+ ~1974.12.31..23.59.38
377+ ~1973.12.31..23.59.37
378+ ~1972.12.31..23.59.36
379+ ~1972.6.30..23.59.35
380+ ]
381+ ~zod/try=/hom> (snag 2 lef:yu)
382+ ~2005.12.31..23.59.57
docs/dev/hoon/library/3bd.mdnew file+1807

This diff is too big to show here.

docs/dev/hoon/library/3be.mdnew file+1316

This diff is too big to show here.

docs/dev/hoon/library/3bf.mdnew file+267

This diff is too big to show here.

docs/dev/hoon/library/3bg.mdnew file+943

This diff is too big to show here.

docs/dev/hoon/library/3bh.mdnew file+479

This diff is too big to show here.

docs/dev/hoon/library/3bi.mdnew file+1483

This diff is too big to show here.

docs/dev/hoon/principles.mdnew file+18

This diff is too big to show here.

docs/dev/hoon/principles/0-nouns.mdnew file+286

This diff is too big to show here.

docs/dev/hoon/principles/1-twigs.mdnew file+286

This diff is too big to show here.

docs/dev/hoon/principles/2-syntax.mdnew file+475

This diff is too big to show here.

docs/dev/hoon/principles/3-program.mdnew file+350

This diff is too big to show here.

docs/dev/hoon/principles/4-functions.mdnew file+327

This diff is too big to show here.

docs/dev/hoon/reference.mdnew file+7

This diff is too big to show here.

docs/dev/hoon/reference/odors.mdnew file+686

This diff is too big to show here.

docs/dev/hoon/reference/pronunciation.mdnew file+68

This diff is too big to show here.

docs/dev/hoon/runes.mdnew file+132

This diff is too big to show here.

docs/dev/hoon/runes/bc.mdnew file+49

This diff is too big to show here.

docs/dev/hoon/runes/bc/bcbr.mdnew file+52

This diff is too big to show here.

docs/dev/hoon/runes/bc/bccb.mdnew file+43

This diff is too big to show here.

docs/dev/hoon/runes/bc/bccl.mdnew file+44

This diff is too big to show here.

docs/dev/hoon/runes/bc/bccm.mdnew file+61

This diff is too big to show here.

docs/dev/hoon/runes/bc/bccn.mdnew file+64

This diff is too big to show here.

docs/dev/hoon/runes/bc/bckt.mdnew file+49

This diff is too big to show here.

docs/dev/hoon/runes/bc/bcls.mdnew file+62

This diff is too big to show here.

docs/dev/hoon/runes/bc/bcpm.mdnew file+39

This diff is too big to show here.

docs/dev/hoon/runes/bc/bcpt.mdnew file+37

This diff is too big to show here.

docs/dev/hoon/runes/bc/bctr.mdnew file+38

This diff is too big to show here.

docs/dev/hoon/runes/bc/bcts.mdnew file+53

This diff is too big to show here.

docs/dev/hoon/runes/bc/bcwt.mdnew file+48

This diff is too big to show here.

docs/dev/hoon/runes/bc/bczp.mdnew file+40

This diff is too big to show here.

docs/dev/hoon/runes/br.mdnew file+47

This diff is too big to show here.

docs/dev/hoon/runes/br/brcb.mdnew file+118

This diff is too big to show here.

docs/dev/hoon/runes/br/brcn.mdnew file+135

This diff is too big to show here.

docs/dev/hoon/runes/br/brdt.mdnew file+114

This diff is too big to show here.

docs/dev/hoon/runes/br/brfs.mdnew file+105

This diff is too big to show here.

docs/dev/hoon/runes/br/brhp.mdnew file+78

This diff is too big to show here.

docs/dev/hoon/runes/br/brkt.mdnew file+103

This diff is too big to show here.

docs/dev/hoon/runes/br/brls.mdnew file+63

This diff is too big to show here.

docs/dev/hoon/runes/br/brtr.mdnew file+73

This diff is too big to show here.

docs/dev/hoon/runes/br/brts.mdnew file+71

This diff is too big to show here.

docs/dev/hoon/runes/br/brwt.mdnew file+54

This diff is too big to show here.

docs/dev/hoon/runes/cl.mdnew file+44

This diff is too big to show here.

docs/dev/hoon/runes/cl/clcb.mdnew file+56

This diff is too big to show here.

docs/dev/hoon/runes/cl/clfs.mdnew file+47

This diff is too big to show here.

docs/dev/hoon/runes/cl/clhp.mdnew file+85

This diff is too big to show here.

docs/dev/hoon/runes/cl/clkt.mdnew file+68

This diff is too big to show here.

docs/dev/hoon/runes/cl/clls.mdnew file+61

This diff is too big to show here.

docs/dev/hoon/runes/cl/clsg.mdnew file+69

This diff is too big to show here.

docs/dev/hoon/runes/cl/cltr.mdnew file+57

This diff is too big to show here.

docs/dev/hoon/runes/cn.mdnew file+41

This diff is too big to show here.

docs/dev/hoon/runes/cn/cncb.mdnew file+74

This diff is too big to show here.

docs/dev/hoon/runes/cn/cncl.mdnew file+55

This diff is too big to show here.

docs/dev/hoon/runes/cn/cndt.mdnew file+62

This diff is too big to show here.

docs/dev/hoon/runes/cn/cnhp.mdnew file+39

This diff is too big to show here.

docs/dev/hoon/runes/cn/cnkt.mdnew file+46

This diff is too big to show here.

docs/dev/hoon/runes/cn/cnls.mdnew file+59

This diff is too big to show here.

docs/dev/hoon/runes/cn/cnsg.mdnew file+70

This diff is too big to show here.

docs/dev/hoon/runes/cn/cntr.mdnew file+60

This diff is too big to show here.

docs/dev/hoon/runes/cn/cnts.mdnew file+71

This diff is too big to show here.

docs/dev/hoon/runes/cn/cnzy.mdnew file+40

This diff is too big to show here.

docs/dev/hoon/runes/cn/cnzz.mdnew file+43

This diff is too big to show here.

docs/dev/hoon/runes/dt.mdnew file+33

This diff is too big to show here.

docs/dev/hoon/runes/dt/dtkt.mdnew file+56

This diff is too big to show here.

docs/dev/hoon/runes/dt/dtls.mdnew file+66

This diff is too big to show here.

docs/dev/hoon/runes/dt/dttr.mdnew file+57

This diff is too big to show here.

docs/dev/hoon/runes/dt/dtts.mdnew file+77

This diff is too big to show here.

docs/dev/hoon/runes/dt/dtwt.mdnew file+59

This diff is too big to show here.

docs/dev/hoon/runes/dt/dtzy.mdnew file+47

This diff is too big to show here.

docs/dev/hoon/runes/dt/dtzz.mdnew file+52

This diff is too big to show here.

docs/dev/hoon/runes/hx.mdnew file+19

This diff is too big to show here.

docs/dev/hoon/runes/hx/hxgl.mdnew file+62

This diff is too big to show here.

docs/dev/hoon/runes/hx/hxgr.mdnew file+83

This diff is too big to show here.

docs/dev/hoon/runes/index.hooknew file+13

This diff is too big to show here.

docs/dev/hoon/runes/kt.mdnew file+40

This diff is too big to show here.

docs/dev/hoon/runes/kt/ktbr.mdnew file+61

This diff is too big to show here.

docs/dev/hoon/runes/kt/ktdt.mdnew file+47

This diff is too big to show here.

docs/dev/hoon/runes/kt/kthp.mdnew file+70

This diff is too big to show here.

docs/dev/hoon/runes/kt/ktls.mdnew file+80

This diff is too big to show here.

docs/dev/hoon/runes/kt/ktpm.mdnew file+46

This diff is too big to show here.

docs/dev/hoon/runes/kt/ktsg.mdnew file+47

This diff is too big to show here.

docs/dev/hoon/runes/kt/ktts.mdnew file+52

This diff is too big to show here.

docs/dev/hoon/runes/kt/ktwt.mdnew file+45

This diff is too big to show here.

docs/dev/hoon/runes/sg.mdnew file+32

This diff is too big to show here.

docs/dev/hoon/runes/sg/sgbc.mdnew file+43

This diff is too big to show here.

docs/dev/hoon/runes/sg/sgbr.mdnew file+36

This diff is too big to show here.

docs/dev/hoon/runes/sg/sgcb.mdnew file+41

This diff is too big to show here.

docs/dev/hoon/runes/sg/sgcn.mdnew file+64

This diff is too big to show here.

docs/dev/hoon/runes/sg/sgfs.mdnew file+44

This diff is too big to show here.

docs/dev/hoon/runes/sg/sggl.mdnew file+50

This diff is too big to show here.

docs/dev/hoon/runes/sg/sggr.mdnew file+48

This diff is too big to show here.

docs/dev/hoon/runes/sg/sgls.mdnew file+50

This diff is too big to show here.

docs/dev/hoon/runes/sg/sgpm.mdnew file+64

This diff is too big to show here.

docs/dev/hoon/runes/sg/sgts.mdnew file+49

This diff is too big to show here.

docs/dev/hoon/runes/sg/sgwt.mdnew file+64

This diff is too big to show here.

docs/dev/hoon/runes/sg/sgzp.mdnew file+59

This diff is too big to show here.

docs/dev/hoon/runes/sm.mdnew file+42

This diff is too big to show here.

docs/dev/hoon/runes/sm/smcl.mdnew file+63

This diff is too big to show here.

docs/dev/hoon/runes/sm/smcn.mdnew file+93

This diff is too big to show here.

docs/dev/hoon/runes/sm/smdq.mdnew file+56

This diff is too big to show here.

docs/dev/hoon/runes/sm/smhp.mdnew file+55

This diff is too big to show here.

docs/dev/hoon/runes/sm/smls.mdnew file+58

This diff is too big to show here.

docs/dev/hoon/runes/sm/smsg.mdnew file+162

This diff is too big to show here.

docs/dev/hoon/runes/sm/smsm.mdnew file+52

This diff is too big to show here.

docs/dev/hoon/runes/sm/smtr.mdnew file+61

This diff is too big to show here.

docs/dev/hoon/runes/sm/smzz.mdnew file+84

This diff is too big to show here.

docs/dev/hoon/runes/ts.mdnew file+49

This diff is too big to show here.

docs/dev/hoon/runes/ts/tsbr.mdnew file+55

This diff is too big to show here.

docs/dev/hoon/runes/ts/tscl.mdnew file+57

This diff is too big to show here.

docs/dev/hoon/runes/ts/tsdt.mdnew file+55

This diff is too big to show here.

docs/dev/hoon/runes/ts/tsgl.mdnew file+63

This diff is too big to show here.

docs/dev/hoon/runes/ts/tsgr.mdnew file+68

This diff is too big to show here.

docs/dev/hoon/runes/ts/tshp.mdnew file+62

This diff is too big to show here.

docs/dev/hoon/runes/ts/tskt.mdnew file+66

This diff is too big to show here.

docs/dev/hoon/runes/ts/tsls.mdnew file+65

This diff is too big to show here.

docs/dev/hoon/runes/ts/tssg.mdnew file+49

This diff is too big to show here.

docs/dev/hoon/runes/ts/tstr.mdnew file+51

This diff is too big to show here.

docs/dev/hoon/runes/wt.mdnew file+39

This diff is too big to show here.

docs/dev/hoon/runes/wt/wtbr.mdnew file+55

This diff is too big to show here.

docs/dev/hoon/runes/wt/wtcl.mdnew file+54

This diff is too big to show here.

docs/dev/hoon/runes/wt/wtdt.mdnew file+58

This diff is too big to show here.

docs/dev/hoon/runes/wt/wtgl.mdnew file+52

This diff is too big to show here.

docs/dev/hoon/runes/wt/wtgr.mdnew file+52

This diff is too big to show here.

docs/dev/hoon/runes/wt/wthp.mdnew file+99

This diff is too big to show here.

docs/dev/hoon/runes/wt/wthz.mdnew file+52

This diff is too big to show here.

docs/dev/hoon/runes/wt/wtkt.mdnew file+70

This diff is too big to show here.

docs/dev/hoon/runes/wt/wtkz.mdnew file+34

This diff is too big to show here.

docs/dev/hoon/runes/wt/wtls.mdnew file+115

This diff is too big to show here.

docs/dev/hoon/runes/wt/wtlz.mdnew file+35

This diff is too big to show here.

docs/dev/hoon/runes/wt/wtpm.mdnew file+49

This diff is too big to show here.

docs/dev/hoon/runes/wt/wtpt.mdnew file+59

This diff is too big to show here.

docs/dev/hoon/runes/wt/wtpz.mdnew file+34

This diff is too big to show here.

docs/dev/hoon/runes/wt/wtsg.mdnew file+50

This diff is too big to show here.

docs/dev/hoon/runes/wt/wtsz.mdnew file+37

This diff is too big to show here.

docs/dev/hoon/runes/wt/wtts.mdnew file+45

This diff is too big to show here.

docs/dev/hoon/runes/wt/wttz.mdnew file+35

This diff is too big to show here.

docs/dev/hoon/runes/wt/wtzp.mdnew file+46

This diff is too big to show here.

docs/dev/hoon/runes/zp.mdnew file+23

This diff is too big to show here.

docs/dev/hoon/runes/zp/zpcb.mdnew file+57

This diff is too big to show here.

docs/dev/hoon/runes/zp/zpcm.mdnew file+36

This diff is too big to show here.

docs/dev/hoon/runes/zp/zpfs.mdnew file+64

This diff is too big to show here.

docs/dev/hoon/runes/zp/zpgr.mdnew file+62

This diff is too big to show here.

docs/dev/hoon/runes/zp/zpsm.mdnew file+43

This diff is too big to show here.

docs/dev/hoon/runes/zp/zpts.mdnew file+55

This diff is too big to show here.

docs/dev/hoon/runes/zp/zpwt.mdnew file+49

This diff is too big to show here.

docs/dev/hoon/runes/zp/zpzp.mdnew file+48

This diff is too big to show here.

docs/dev/interpreter.mdnew file+12

This diff is too big to show here.

docs/dev/interpreter/u3.mdnew file+1570

This diff is too big to show here.

docs/dev/nock.mdnew file+52

This diff is too big to show here.

docs/dev/nock/reference.mdnew file+737

This diff is too big to show here.

docs/dev/nock/tutorial.mdnew file+1044

This diff is too big to show here.

docs/theory.mdnew file+26

This diff is too big to show here.

docs/theory/network-goals.mdnew file+565

This diff is too big to show here.

docs/theory/old.mdnew file+21

This diff is too big to show here.

docs/theory/part-i.mdnew file+512

This diff is too big to show here.

docs/theory/part-ii.mdnew file+462

This diff is too big to show here.

docs/theory/whitepaper.mdnew file+2346

This diff is too big to show here.

docs/user.mdnew file+25

This diff is too big to show here.

docs/user/appliance.mdnew file+274

This diff is too big to show here.

docs/user/basic.mdnew file+143

This diff is too big to show here.

docs/user/clay.mdnew file+420

This diff is too big to show here.

docs/user/dojo.mdnew file+547

This diff is too big to show here.

docs/user/install.mdnew file+111

This diff is too big to show here.

docs/user/intro.mdnew file+137

This diff is too big to show here.

docs/user/launch.mdnew file+112

This diff is too big to show here.

docs/user/talk.mdnew file+314

This diff is too big to show here.

docs/user/tour.mdnew file+209

This diff is too big to show here.