on master help sign in
Merge pull request #320 from joshuareagan/2018-era-draft
7fa97bdJoshua Reagan
docs.mddeleted−48
@@ -1,48 +0,0 @@
1−---
2−anchor: none
3−footer: true
4−title: Docs
5−sort: 4
6−---
7−
8−<div class="lead">
9− <div class="logo inverse"></div>
10− <h1 class="i-b">Urbit docs</h1>
11−</div>
12−
13−<div class="col-md-12 head">
14−
15−<div class="col-md-8">
16−
17−**Urbit** is a secure peer-to-peer network of personal servers, built on a clean-slate system software stack.
18−
19−Check out the [technical overview](about/overview) for a high-level
20−architecture description. To install and run Urbit, head to the Using section, starting with the [installation guide](using/install) and continuing forward.
21−
22−To begin developing for Urbit, start by walking through [Urbytes](urbyte/0). After that, delve into Hoon [syntax](hoon/syntax) directly, then walk through the [Arvo tutorials](arvo). The examples and exercises in Arvo will teach you to build high-level programs and interact with the network.
23−
24−Dig into the mechanics of Urbit with [Core Hoon](hoon). Refer back
25−there for pure-code exercises and functions in the [standard library](hoon/library).
26−
27−Anyone obsessed with math, theory, fundamentals of computation,
28−etc, should start with the [Nock definition](nock/definition) and work upward from there.
29−
30−</div>
31−
32−<div class="col-md-4">
33−
34−<b>Community & contact</b>
35−<ul>
36−<li>Chat with us on <a href="https://urbit.org/stream">Talk</a></li>
37−<li>Our discussion forum <a href="http://urbit.org/fora">Fora</a></li>
38−<li>On Twitter <a href="https://twitter.com/urbit">@urbit</a></li>
39−<li>Or email us at <a href="mailto:urbit@urbit.org">urbit@urbit.org</a></li>
40−</ul>
41−
42−</div>
43−
44−</div>
45−
46−<div class="sections">
47− <kids grid="true"></kids>
48−</div>
docs.umdnew file+49
@@ -0,0 +1,49 @@
1+:- :~ anchor/'none'
2+ footer/'true'
3+ title/'Docs'
4+ sort/'4'
5+ ==
6+;>
7+
8+;div(class "lead")
9+ ;div(class "logo inverse");
10+ ;h1.i-b: Urbit docs
11+==
12+
13+;div(class "col-md-12 head")
14+ ;div(class "col-md-8")
15+
16+*Urbit* is a secure peer-to-peer network of personal servers, built on a clean-slate system software stack.
17+
18+Check out the [technical overview](about/overview) for a high-level architecture description. To install and run Urbit head to the Using section, starting with the [installation guide](using/install) and continuing forward.
19+
20+To begin developing for Urbit, you can start by walking through the tutorial series for [Hoon](tutorials/ch1). Hoon is Urbit's high-level programming language. Anyone obsessed with math, theory, fundamentals of computation, etc., should start with [Nock](tutorials/nock), the low-level language to which Hoon is compiled.
21+
22+ ==
23+
24+ ;div(class "col-md-4")
25+ ;b: Community & contact
26+ ;ul
27+ ;li
28+ ; Chat with us on
29+ ;a/"https://urbit.org/stream": Talk
30+ ==
31+ ;li
32+ ; Our discussion forum
33+ ;a/"http://urbit.org/fora": Fora
34+ ==
35+ ;li
36+ ; On Twitter
37+ ;a/"https://twitter.com/urbit": @urbit
38+ ==
39+ ;li
40+ ; Or email us at
41+ ;a/"mailto:urbit@urbit.org": urbit@urbit.org
42+ ==
43+ ==
44+ ==
45+==
46+
47+;div(class "sections")
48+ ;kids(grid "true");
49+==
docs/about.md → docs/about.umdrenamed+6−6
@@ -1,11 +1,11 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−sort: 2
2+ sort/'1'
4−title: About
3+ title/'About'
5−---
4+ ==
5+;>
6
6
7# About
7# About
8
8
9Learn more about the Urbit project here before delving deeper into the developer documentation.
9Learn more about the Urbit project here before delving deeper into the developer documentation.
10
10
11−<list/>
11+;list;
docs/about/contributing.md → docs/about/contributing.umdrenamed+7−11
@@ -1,9 +1,9 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−navuptwo: true
2+ navuptwo/'true'
4−sort: 4
3+ sort/'3'
5−title: Contributing
4+ title/'Contributing'
6−---
5+ ==
6+;>
7
7
8# Contributing
8# Contributing
9
9
@@ -15,8 +15,4 @@ for improving our [code](https://github.com/urbit/urbit/) and
15
15
16Our official guide to contributing can be found
16Our official guide to contributing can be found
17[here](https://github.com/urbit/urbit/blob/master/CONTRIBUTING.md),
17[here](https://github.com/urbit/urbit/blob/master/CONTRIBUTING.md),
18−which is most useful for large and low-level changes. For simpler
18+which is most useful for large and low-level changes. For a good example of preferred Hoon coding style, see [ford.hoon](https://github.com/urbit/arvo/blob/master/sys/vane/ford.hoon).
19−revisions, refer to [Hoon Syntax](../../hoon/syntax) for an in-depth guide to
20−good Hoon. Alternatively, [browse the
21−source](https://github.com/urbit/arvo/).
22−
docs/about/objections.mddeleted−269
@@ -1,269 +0,0 @@
1−---
2−navhome: /docs/
3−navuptwo: true
4−next: true
5−sort: 2
6−title: Common objections
7−---
8−
9−# Common objections to Urbit
10−
11−"We choose to go to the moon, not because it is easy, but because it is hard." -- John F. Kennedy
12−
13−We're strong believers in crowdsourced criticism. We've heard a lot of great objections from all kinds of directions. Surely there's more out there -- if you think of a reason Urbit can't work, and it's not listed here, please add it in a comment at the bottom, post it somewhere and send us a link, etc, etc.
14−
15−## Urbit is a total scamcoin. It's 100% premined.
16−
17−Like a cryptocurrency, Urbit is a digital title. But Urbit is digital land, not digital money. If you assess it as a currency, it's a lousy currency. If you assess a cat as a dog, it's a lousy dog.
18−
19−In real-world economics, the crucial distinction between land and money is that land (a) has intrinsic utility and (b) is non-fungible.
20−
21−Because of (b) alone, frictionless transactions in land are impossible. A blockchain is only needed to ensure zero-cost high-frequency transactions. So digital land doesn't need a blockchain. Which means it doesn't need mining.
22−
23−Of course, just because a digital title system doesn't need mining, doesn't mean it can't distribute an initial allocation by proof-of-work -- or by any other arbitrary method which is careful not to benefit the system's own developers. Could we give away the Urbit address space randomly? Sure. But why?
24−
25−Probably the purest design is the "proof-of-burn" initial allocation used by some coins. By any standard, proof-of-burn is technically beautiful and results in an extraordinary level of ethical independence. We can't help but admire it.
26−
27−But any altcoin or metacoin is just way less work than Urbit. An altcoin can afford to burn even its creation energy, capturing no value at all from its seigniorage. Your altcoin doesn't have a clean-slate OS to fund, and no one started building it in 2002.
28−
29−Ethically, what makes "premining" feel wrong is that the creators of the currency are rewarded disproportionately for their effort. The scamcoin is a get-rich-quick scheme, vaguely pyramid-shaped. Nothing about Urbit matches this pattern at all.
30−
31−To put it bluntly, Galen drives a 2004 Saab and Curtis drives a moldy '99 Cougar covered with raven shit. And we both love cars. We also have kids. And our spouses are more skeptical of Urbit than anyone else could ever be. (Our next startup definitely *will* be a get-rich-quick scheme, though.)
32−
33−Curtis created Urbit. So by the [homesteading principle](https://en.wikipedia.org/wiki/Homestead_principle), he started out owning all of it. But by now, Urbit's 8-bit galaxies have already been distributed among [57 separate individuals](https://github.com/urbit/arvo/blob/master/sys/vane/ames.hoon#L117-L372). Curtis owns 4 -- or 24, counting his whole family. (Some of whom he still owes money.)
34−
35−Tlon, the corporation which still runs Urbit development, has 95. (Without Tlon, there is basically no Arvo.) 50 are reserved for a hypothetical Urbit Foundation. Tlon employees have another 16.
36−
37−The rest of the galaxies belong to donors, investors, contributors, contest winners, and just random people who were in the right place at the right time. One is a Silicon Valley tycoon. Another is an Orthodox nun in a monastery in Greece. A couple are ex-Tlon employees who might totally hate us. There is nothing they all have in common, which is sort of the point.
38−
39−This property distribution looks a lot like land ownership in the real world -- complex and asymmetrical. That's no accident. If you have a problem living in New York because New York's real estate is not distributed equally among its residents, you may have a similar problem with Urbit. The reality is that Urbit, like New York, wasn't born yesterday and comes with a complex ownership history which we couldn't possibly change, even if we wanted to.
40−
41−Also, even in Manhattan you can just sleep in your van, and in Urbit you can always make your own comet. But people can't be prevented from thinking this means you're a weirdo.
42−
43−## Urbit isn't even really decentralized! It has a government!
44−
45−TLDR: yeah. But at least it's not the DAO.
46−
47−Real TLDR: it's technically impossible for Urbit to be decentralized at this stage of its life. Urbit is designed to achieve decentralization, not be born with it.
48−
49−A young network can't afford to be decentralized. It has to act as a unit. Because it has no network effect, it needs every scrap of efficiency it can get. Right now, Urbit needs a central government about ten times over.
50−
51−As we found out with the DAO, if a network isn't ready to be decentralized, its developers shouldn't even try. If Ethereum is hard-forked to roll back the DAO (which looks like the most probable result), it acknowledges that it both has a central government, and needs a central government. Decentralization is good. Pretend decentralization -- "decentralization theater" -- is harmful, and not a effective path to actual decentralization.
52−
53−Urbit did not have to get hacked to realize that a decentralized network can only be bootstrapped by a central government. It's part of Urbit's basic design. For example, by default your urbit upgrades its OS automatically (like an "evergreen" browser) with signed network updates. Whoever signs these updates is a central government by definition.
54−
55−But the test of a free software project is whether it can fork. So long as the unity of the PKI and the protocol is maintained, Urbit development can fork easily without disrupting the network. Any stress will fragment this central government, and as it fragments it grows more limited and stable.
56−
57−Urbit is designed to govern itself collectively by address space ownership -- effectively, "proof of stake." Any arbitrary power, will tend to fracture along these property lines. For instance, our hot updates are sent through the galaxy hierarchy; in a development fork, active galaxies would pick sides. This would actually be awesome for Urbit.
58−
59−By fragmenting the galaxy space into 57 separate partitions, we've created a global property map which is much more likely to splinter further, than reunite.
60−
61−In the long run, every galaxy should have a separate owner, who is a human being rather than a corporation. Combining galaxy holdings is regarded as creepy, and damages the value of both galaxies. Splitting up any remaining clumps is meritorious.
62−
63−The technical goal of Urbit is to create a network which, *if it actually takes over the world*, inevitably becomes decentralized. Even if Urbit takes over the world, nobody takes over the world. World domination must be technically implausible.
64−
65−This is the goal of all the new "web3" decentralized systems. If IPFS, Sandstorm or Ethereum takes over the world, nobody takes over the world. (The same is almost true of the Internet -- though it wouldn't be that surprising if a time traveler from 2116 revealed that ICANN had become a planetary government.)
66−
67−Urbit, by starting out as a centralized network, just reduces the technical problem to match the actual goal. Only long-term decentralization matters.
68−
69−It's very important that Urbit in 2116 be fully decentralized. For Urbit in 2016, pretending to be decentralized would be a joke at best, and a hoax at worst. And of course, no one can DAO us -- since the property system is still just a central registry.
70−
71−## {Sandstorm, IPFS, Ethereum, ...} is way ahead of Urbit.
72−
73−In general, web3 (next distributed web) solutions don't compete with each other. They support each other. Concretely, they are all part of each others' network effect.
74−
75−IPFS, Sandstorm, Ethereum, ZeroTier, and Urbit can all take over the world at the same time. None of them competes with the others. They enable each other. For instance, IPFS is not a computer; Urbit will be a great computer to use IPFS from; IPFS is a great CDN for Urbit. Moar IPFS now!
76−
77−The closest thing to a competitor that Urbit has is Sandstorm. Sandstorm, which by the way rocks, is also a personal server.
78−
79−But Sandstorm and Urbit compete in the way that, on the PC, the OS and the browser compete. In theory, the OS could solve the problems that the browser solves; or the browser could be the OS. In practice, Windows is a great OS to run a browser on.
80−
81−Similarly, a world in which Sandstorm takes off is an awesome world for Urbit, because everyone who has a Sandstorm instance has a great platform for running Urbit on. (Although Sandstorm could still work on its UDP capabilities.)
82−
83−Urbit on Sandstorm will be a sort of "double-hulled" personal server, even safer and more friendly than either system alone. And Sandstorm is not its own P2P network, like Urbit.
84−
85−## Urbit doesn't have enough planets for every human being.
86−
87−A planet is a tool, not a toy. Like a car, it's a device for a responsible and civilized adult. There aren't 4 billion cars in the world, nor 4 billion responsible adults.
88−
89−And limiting the supply of anything doesn't create a shortage. It sets a price. Ideally, in the long run, we think a planet should cost about $10. This could be off by an order of magnitude either way, and it wouldn't be the end of the world.
90−
91−If a planet costs $10, that means you paid $10 to get a planet. A planet with no reputation has a positive reputation, because someone paid $10 for it and hasn't yet done anything wrong. Positive default reputation is the single quality that makes a social network social.
92−
93−There is always a tradeoff between free speech and free beer. Urbit will always choose free speech.
94−
95−## Cloud computing is inherently non-private.
96−
97−TLDR: a general-purpose cloud computer is much, much more private than a special-purpose cloud computer. In general, a VM is secure against corporations but not governments.
98−
99−One reason we want the decentralized Internet is that we're tired of giant corporations spying on us. Think about it this way: Amazon is Netflix's main competitor. And yet, Netflix runs its whole operation on AWS. Why is Netflix sure that Amazon won't spy on it?
100−
101−A general-purpose virtual machine is special from a privacy standpoint, just because it's commercially realistic to design terms of service that prevent the host from peeking and poking at the customer's machine. Crossing this moat is technically nontrivial and can't possibly happen by any reasonable accident. No hosting contract could contemplate it.
102−
103−Whereas when your cloud computer is a special-purpose machine -- just a database row on some corporation's mainframe -- there is no way these services can promise not to handle your data. Handling your data is *what they do*. On a special-purpose server, the concept of privacy is not even defined.
104−
105−Where even a general-purpose server falls down is where the user has a sovereign adversary, which can secretly violate explicit or implicit hosting contracts. Users with a sovereign adversary must rely only on their own physical security. However, most users don't have a sovereign adversary. And those who do maximize their "herd immunity" if they can use the same protocols as those who don't.
106−
107−Also, the portability of a cloud server image is critical. Of course, since Urbit is formally specified, it's trivially portable. In fact, one strategy against sovereign adversaries may be continuous rotation between hosts, like an MX missile.
108−
109−## "Jets" are, like, a total hoax.
110−
111−TLDR: like, all of computing is a hoax. You can't compare a hoax to nothing. You can only compare it to all the other hoaxes.
112−
113−A "jet" is a sort of software device driver in Urbit. Urbit is precisely defined in terms of an interpreter that fits on a T-shirt, Nock. But a naive implementation of Nock is nowhere near practical, because Nock has only one integer operation: increment. For example, to decrement a number in Nock, you increment a counter up to the number under it.
114−
115−The only way an efficient Nock interpreter can work is to recognize algorithms like decrement, and implement them non-naively. By far the easiest way to do this is not to analyze arbitrary code as it's being executed, but to register and match well-known implementations in the standard library. No one should be writing their own decrement.
116−
117−But the semantics of the interpreter, *so long as the jet and the jet harness are defined correctly*, are exactly those of Nock. We are not extending or changing Nock in any way. We are just taking a shortcut in certain cases we understand perfectly.
118−
119−It's not at all unprecedented to have implementations much more complex than the corresponding specification. The x86 instruction set is relatively simple; the complexity of its decoding and execution path in a modern CPU is enormous. This path may well have "peephole optimizations" that replace matched algorithms, and if it doesn't the modern C compiler does.
120−
121−So jets are *morally* defensible. The fact remains, however, that a Nock interpreter without jets is completely useless. And there is not even an informal document that tells you what jets you need for a reasonably efficient Urbit. (This last, we can agree, should be corrected.)
122−
123−The correct way to think about jets is not to compare them to a perfect interpreter implemented by unicorns. Jets are a combined replacement for two other techniques in language implementation: intrinsics and a foreign-function interface.
124−
125−Compared to both intrinsics and an FFI, your jets have one key disadvantage: they need to be specified in pure code. You may not have this executable specification, which means you need to write it. Is this really so bad for your development process? An executable specification? Which can be trivially tested against the efficient implementation?
126−
127−Compared to intrinsics, jets give you true separation between mechanism and policy; only the interpreter, not the programmer and not the compiler, needs to know what's accelerated.
128−
129−Compared to an FFI, jets preclude I/O, so can be trivially sandboxed. Except that the programmer needs to mark routines which may benefit from optimization with a hint, here too we separate mechanism (efficient implementation) from policy.
130−
131−Yes, formal verification of jet equivalence is desirable. However, in the real world, many specifications, including quite complex ones, are tested into equivalence by brute force.
132−
133−Urbit has some jet abuses. The equivalence between our markdown parser in Hoon and the CommonMark C library is super dubious. It should be taken out and shot.
134−
135−However, the miscomputation resulting from a minor jet discrepancy is not a security hole or even fatal. It effectively means the event history does not match the current state. The way to resolve this conflict is for the current state to win, and the event history to be discarded -- not abnormal anyway. See the next question.
136−
137−## Urbit needs an infinitely extending packet/event log.
138−
139−TLDR: no, it doesn't.
140−
141−We can prune the event log because the Urbit transition function doesn't have any access to the event history -- just the current state and the current event.
142−
143−Urbit defines the semantics of a complete event log. It doesn't and can't require an implementation to maintain the whole log. It can maintain a checkpoint and the log since that checkpoint. The current implementation of Urbit keeps the whole log, but the next release will optionally prune it.
144−
145−## Urbit will never be able to call any existing code.
146−
147−TLDR: neither will Javascript. And dear Unix, the browser does not miss interacting with your `$LD_LIBRARY_PATH` at all.
148−
149−You can't talk to the OS or use system libraries from Javascript. Therefore, there is no point in having any kind of gateway, compatibility bridge, native methods, or other interface between Javascript and C.
150−
151−When in doubt, remember that Urbit is "the browser for the server side." It plays by the same general rules. Isolation means isolation.
152−
153−## There's no way Urbit will ever be adopted. It's too weird.
154−
155−TLDR: Urbit adoption is designed to be driven by ordinary end users. Urbit isn't ready for ordinary end users yet. We're working on it -- come help.
156−
157−Right now, Urbit is a developer tool. Or rather, a developer toy -- since the only thing it's useful for is developing Urbit. It also could be a much better toy. We're working on that too.
158−
159−But it's absolutely wrong to think of Urbit being adopted as a developer tool in the conventional sense. If you think this is almost impossible, you're right.
160−
161−If we look at the way most successful platforms are adopted, they're not adopted for their own virtues. They're adopted because they're part of a larger solution. It's very hard to displace a native component of an existing platform. Urbit is not trying to do this.
162−
163−C is a better language than Pascal, but it didn't beat Pascal because it's a better language. C beat Pascal because C was the native language of Unix, and people wanted to program in Unix. People don't use Javascript because Javascript is a great language, but because it's the native language of the browser. Replacing the native language of a platform may be doable -- but it's incredibly hard.
164−
165−Hoon is not competing with C, or even Haskell, as a Unix programming language. The only reason to program in Hoon is that it's the native language of Urbit. Urbit is not competing with node.js or Rails as a Web backend. The only reason to run Urbit is to run Urbit.
166−
167−Nock is cool, but it only gets adopted if Hoon gets adopted. Hoon is cool, but it only gets adopted if Urbit gets adopted. Urbit only gets adopted if it's useful as a personal server for human beings -- most of whom won't be Hoon programmers, or programmers at all.
168−
169−## Hoon is too weird. No one will be able to program in it.
170−
171−TLDR: Hoon is ridiculously simple. Our documentation and tooling are just immature.
172−
173−It's pretty fair to assume that (a) functional programming is hard and weird, (b) Hoon is weird even for a functional language, so (c) Hoon must be hard-squared.
174−
175−Actually, Hoon is weird even for a functional language because it's an attempt to remove the hardest things about functional programming: category theory, lazy evaluation, and gratuitous abstraction. To know a language is to know what the compiler is doing; all the semantics of the Hoon compiler fit in 2000 lines of code.
176−
177−It's too easy for us to wind up living in Isaac Asimov's Trantor, a world in which everything got invented thousands of years ago and the idea of new technology is just weird and scary. History isn't over yet, and nor is technical history.
178−
179−New things are harder to learn than old things. We ask smart high-school students to learn calculus. Think about how much harder it was for Newton and Leibniz to invent calculus, or for their first students to pick it up.
180−
181−Most of the difference is just the collective certainty that our society conveys to a high-school student that calculus is learnable. When you're learning Urbit, you don't have this collective knowledge; so you don't have the confidence that the problem is solvable. Confidence makes a huge difference. Moreover, any bug or glitch in the developer experience destroys this confidence and takes a long time to heal.
182−
183−Yes, we know: Hoon remains quite hard to learn. Again, we have no reason to think this problem isn't solvable. Public enlightenment remains our main priority.
184−
185−## Urbit programmers are stuck with Hoon.
186−
187−TLDR: patience, grasshopper.
188−
189−There's quite a straightforward way to implement any perfectly specified language with a reliable interpreter in Hoon. First, write an interpreter for that language in Hoon. Second, jet that intepreter function with the existing implementation.
190−
191−It is not clear that Javascript is *quite* well-defined enough for this treatment. But Lua probably is.
192−
193−## Ordinary users will never be able to manage an Urbit server.
194−
195−TLDR: Urbit's technical simplicity has always been designed to drive human usability. But the polish is the last thing that goes on. So we can't evaluate this claim right now.
196−
197−Right now, Urbit is only for geeks. You already need to be able to wrangle a Unix machine to run it. What's the point?
198−
199−This Urbit isn't the real Urbit. It's an early milestone on the way to the real Urbit.
200−
201−The real Urbit -- for normal human beings -- is a hosted service. Getting a planet is as easy as signing up for Facebook. Probably many users will think of it as another web account. They might not even know it can run more apps than the ones they use.
202−
203−A deterministic, persistent cloud computer is something different from a traditional server. Normally when we think of a server in the cloud, we think of it like a live animal -- a creature that needs to be cared for, fed, and herded. A file in the cloud is more like a rock -- you can forget about it for ten years.
204−
205−An urbit is a general-purpose computer, but it doesn't even have the concept of a reboot. It upgrades itself. If you don't feed it any packets for ten years, then turn it back on, it will spend a day or two upgrading itself, then be back to normal. Maybe it's something in between a rock and an animal -- a cactus?
206−
207−Another huge difference versus an Internet server is that we're confident that Urbit's limited supply of identities will make it easy to keep abusers off the network. So far, so good -- but of course, no one abuses a young network.
208−
209−The bottom line is that managing your urbit has to be as easy as managing your iPhone. Normally, it consists of deciding what apps you want to be running, and how much you trust them. Resources can't be free, so sometimes you have to play memory police. Humans have shown that they can handle these tasks.
210−
211−Our '70s OSes and networks, which were great designs in their day and have matured into excellent industrial tools, give us a totally misleading impression of how hard it should be to manage a general-purpose computer. Computing isn't scary or dangerous. Unix and the Internet are scary and dangerous. That's fine for an industrial tool, but not a personal tool.
212−
213−## Urbit has no killer app.
214−
215−TLDR: the killer app is personal API aggregation.
216−
217−It's a truism that any new platform has to be fundamentally much better at solving some problem than the mature platform it seeks to replace.
218−
219−We can look at Urbit's killer app from two perspectives: as a developer, and as a user.
220−
221−From the developer's perspective, Urbit's advantage is that it's a network stack which provides exactly-once delivery of typed, validated, transactional, encrypted and authenticated messages. The difference between an Urbit API and a REST API is like the difference between a paved road and a dirt road. On the other hand, you do need to learn a new functional language.
222−
223−From the user's perspective, there's one task that any personal server can perform, that can't be performed by any Web service: unrestricted API aggregation.
224−
225−Well before Urbit is ready to *replace* any conventional web services, it should be ready to *command* them in place by API. (Or if needed, by scraping.) If all you care about is being in control of your own data, it's fine to leave it in the hands of these services, as you have the API secrets to get it out.
226−
227−Managing a set of security connections to your existing services is one of the first important tasks of a modern personal server. This is a stateful task that typically requires both a durable API key and a temporary OAuth token. APIs change all the time, so connection maintenance also requires evergreen updates.
228−
229−The origin of this API key will vary, but usually the best way to set it is BYOK: the user registers their own urbit as an "app." And the neat thing about having your own API keys, for multiple services, on a single general-purpose computer, is that none of these services really has any practical way to control what you do with your own data.
230−
231−Terms of service which constrain the use of data (as opposed to the abuse of the service) simply aren't realistic and will no longer apply. This enables a variety of novel user experiences which aren't implementable as traditional web services, and also aren't available via conventional third-party API aggregators.
232−
233−Also, since Urbit is after all quite immature, it doesn't make much sense to restrict this security state to code within Urbit. The Urbit interpreter `vere` runs as a Unix daemon that implements the FUSE user-level filesystem protocol, and maps the data on your services into the Unix filesystem. For example, one of our demos lets you `ls` your Github issues.
234−
235−So it's straightforward to build, for instance, a Python app that uses Urbit as a gateway to mash up a bunch of web services. As a Unix programmer, you might even just regard Urbit as a generic Web API gateway daemon, without worrying about its internals.
236−
237−We have other ideas for initial killer apps. But this, we feel, is the best one. API libraries for `npm` et al abound. Stateful, self-updating, generic API aggregators with FUSE integration, also integrated with a reactive web server, are more rare. So perhaps there's a small niche here.
238−
239−## Urbit is sneered at by brilliant talking horses.
240−
241−It's difficult to categorize this [brilliant essay of Fare's](http://ngnghm.github.io/blog/2016/06/11/chapter-10-houyhnhnms-vs-martians/) in a single bullet point. So I've saved it for last.
242−
243−We've already addressed the point most commonly made by others: that jets are a sham. It's not always trivial to decode this critique, which is quite abstract. But Fare' makes a few other points.
244−
245−### Event-sourcing and/or caching is a pattern, not a layer
246−
247−Fare' is perfectly right that "one size does not fit all" in persistence. Generally, Urbit uses event-sourced persistence.
248−
249−But it has multiple layers of event-sourcing: in the definition of Urbit itself; in the application sandbox vane (Gall), and in the application itself. Urbit also has a completely orthogonal revision control system (Clay).
250−
251−And there is not a single cache across the whole system, though arguably there should be; for instance, the functional build system (Ford, which Fare' the master of build systems might appreciate) has its own internal cache.
252−
253−It is a common mistake to confuse a design pattern with a layer or feature, and equally fatal whichever direction you fail.
254−
255−### Let's be clear about why DSLs suck
256−
257−DSLs suck not because they are difficult to newbies in the base language. DSLs suck because every time a programmer, even one *experienced* in the base language, comes into a new codebase or project, she has to learn a new custom language.
258−
259−You need enormous wins to justify this cost. It's the goal of the base language designer to preempt these wins, creating a language which is almost never so tiresome and full of boilerplate that it requires a DSL or template layer.
260−
261−Hoon is almost entirely made of macros -- but they are internal, fixed, built-in macros (with no gensyms). This fixed set of macros is essentially enough. Occasionally we want to add one or two. But we never, ever pine for context-dependent macros.
262−
263−### Determinism is not consensus, and is not constraining
264−
265−Fare' is totally right that an urbit's data is meant for itself alone. In fact, an urbit has the right to compute incorrectly if it wants. We go to considerable lengths to ensure that you can't gain any particular advantage by incorrect computing.
266−
267−The whole point of Nock is that it's so low-level that there is no conceivable advantage in upgrading it. Divergence is just pointless. This is not a question of network integrity, just of practical standardization.
268−
269−This consistency stops at Nock. Without anyone violating the correctness of their lifecycle functions, anyone or everyone in Urbit could replace Hoon with Javascript. Determinism does not cramp Urbit's semantic style in any way, shape or form.
docs/about/overview.mddeleted−90
@@ -1,90 +0,0 @@
1−---
2−navhome: /docs/
3−navuptwo: true
4−next: true
5−sort: 1
6−title: Technical overview
7−---
8−
9−# Technical overview
10−
11−Urbit is a clean-slate system software stack defined as a
12−deterministic computer. An encrypted P2P network, `%ames`, runs
13−on a functional operating system, Arvo, written in a strict,
14−typed functional language, Hoon, which compiles itself to a
15−combinator interpreter, Nock, whose spec gzips to 340 bytes.
16−
17−## Architectural overview
18−
19−A deterministic computer? Urbit's state is a pure function of
20−its event history. In practice it uses a memory checkpoint and
21−an append-only log. Every event is a transaction; Urbit is an
22−ACID database and a single-level store. Urbit runs on Unix now,
23−but it's easy to imagine on a hypervisor or even bare metal.
24−
25−A purely functional OS? Urbit is pure -- no code inside it can
26−make system calls or otherwise affect the underlying platform.
27−Instead, the top-level event function defines an I/O protocol.
28−It maps an input event and the current state to a list of output
29−actions and the subsequent state. In Hoon:
30−
31−```
32−$-([event state] [(list action) state])
33−```
34−
35−### Nock
36−
37−Nock is a sort of nano-Lisp without syntax, symbols or lambdas.
38−Most Lisps are one-layer: they create a practical language by
39−extending a theoretically simple interpreter. The abstraction is
40−simple and the implementation is practical; there is no actual
41−codebase both simple and practical. Hoon and Nock are two
42−layers: Hoon compiles itself to pure Nock. Since Urbit is
43−defined in Nock, not Hoon, we can upgrade Hoon over the air.
44−
45−The Nock data model is especially trivial. A *noun* is an atom
46−or a cell. An atom is any unsigned integer. A cell is an
47−ordered pair of nouns. Nouns are acyclic and expose no pointer
48−equality test.
49−
50−### Hoon
51−
52−Hoon is a strict combinator language that avoids mathematical
53−theory and notation. It aims at a mechanical, imperative feel.
54−Hoon uses ASCII digraphs instead of keywords; there are no
55−user-level macros. The type system infers only forward and does
56−not use unification, but is not much weaker than Haskell's. The
57−compiler and inference engine is about 2000 lines of Hoon.
58−
59−### Arvo
60−
61−Arvo is an event-driven OS written in Hoon. It can upgrade
62−itself and everything inside it over the network. The Arvo
63−kernel proper is 500 lines of Hoon, which implements a typed
64−event system with explicit call-stack structure. Arvo ships
65−with modules that provide P2P networking (Ames), a revision-
66−control system (Clay), a web client/server (Eyre), a
67−functional build system (Ford), and an application engine
68−(Gall).
69−
70−### Ames
71−
72−Ames, the Urbit network, is an encrypted P2P protocol over UDP.
73−Its address space is semi-decentralized; 64-bit addresses are
74−hierarchically distributed, 128-bit addresses are self-created.
75−Addresses (or *plots*) are rendered in a phonemic syntax for
76−memorability. The scarcity of short plots helps control spam and
77−other Sybil attacks. The short plot hierarchy is also reused as
78−a supernode routing system for NAT traversal.
79−
80−### Dojo and talk
81−
82−Urbit ships with two default applications: a REPL and shell
83−_Dojo_, and a distributed user-level message-bus _Hall_.
84−Hall under the hood resembles NNTP; to the user, through the
85−client _Talk_, it looks like a self-hosted Slack or persistent
86−IRC.
87−
88−The full Urbit stack (compiler, standard library, kernel,
89−modules, and applications) is about 30,000 lines of Hoon.
90−Urbit is patent-free and MIT licensed.
docs/about/overview.umdnew file+80
@@ -0,0 +1,80 @@
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3+ next/'true'
4+ sort/'1'
5+ title/'Technical overview'
6+ ==
7+;>
8+
9+# Technical overview
10+
11+Urbit is a clean-slate software stack designed to implement an encrypted P2P network of general-purpose personal servers. Each server on this network is a deterministic computer called an 'urbit' that runs on a Unix-based virtual machine.
12+
13+The current Urbit stack includes (among other things):
14+
15+- Arvo: the functional operating system of each urbit, written in Hoon.
16+- Hoon: a strictly typed functional programming language whose standard library includes a Hoon-to-Nock compiler.
17+- Nock: a low-level combinator language whose formal specification gzips to 340 bytes.
18+- Vere: a Nock interpreter and Unix-based virtual machine that mediates between each urbit and the Unix software layer.
19+
20+## Anatomy of a personal server
21+
22+Your urbit is a deterministic computer in the sense that its state is a pure function of its event history. Every event in this history is a [transaction](https://en.wikipedia.org/wiki/Transaction_processing); your urbit's state is effectively an [ACID database](https://en.wikipedia.org/wiki/ACID).
23+
24+Because each urbit is deterministic we can describe its role appropriately in purely functional terms: it maps an input event and the old urbit state to a list of output actions and the subsequent state. This is the Urbit transition function.
25+
26+```
27+<input event, old state> -> <output actions, new state>
28+```
29+
30+For example, one input event could be a keystroke from the terminal, say `[enter]` after having already typed `(add 2 2)`; and an output action could be to print in the terminal window the resulting value of a computation performed when the user hit `[enter]`, in this case `4`. The input event is stored in the urbit's event history.
31+
32+Events always start from outside of your urbit, whether they're local to the computer running the urbit (e.g., a keystroke in the terminal) or they originate elsewhere (e.g., a packet received from another urbit). When an event is processed, various parts of the urbit state can be modified before the resulting list of output actions is returned.
33+
34+Can output actions from your urbit cause side-effects in the outside world? The answer had better be "yes," because a personal server without side effects isn't useful for much. In another sense the answer had better be "no," or else there is a risk of losing functional purity; your urbit cannot _guarantee_ that the side effects in question actually occur. What's the solution?
35+
36+Each urbit is [sandboxed](https://en.wikipedia.org/wiki/Sandbox_(computer_security)) in a virtual machine, Vere, which runs on Unix. Code running in your urbit cannot make Unix system calls or otherwise directly affect the underlying platform. Strictly speaking, internal urbit code can only change internal urbit state; it has no way of sending events outside of its runtime environment. Functional purity is preserved.
37+
38+In practical terms, however, you don't want your urbit to be an impotent [brain in a vat](https://en.wikipedia.org/wiki/Brain_in_a_vat). That's why Vere also serves as the intermediary between your urbit and Unix. Vere observes the list of output events, and when external action is called for makes the appropriate system calls itself. When external events relevant to your urbit occur in the Unix layer, Vere encodes and delivers them as input events.
39+
40+### Arvo
41+
42+Arvo is a purely functional, [non-preemptive](https://en.wikipedia.org/wiki/Cooperative_multitasking) OS, written in Hoon, that serves as the event manager of your urbit. It can upgrade itself from over the network without downtime. The Arvo kernel proper is quite simple -- it's only about 600 lines of code, excluding its various modules.
43+
44+The Urbit transition function is implemented in Arvo. Upon being 'poked' by Vere with the pair of `<input event, state>`, Arvo directs the event to the appropriate OS module. The result of each Vere 'poke' is a pair of `<output events, new state>`. Events are typed, and each has an explicit call-stack structure indicating the event's source module in Arvo.
45+
46+Arvo modules are also called 'vanes'. Arvo's vanes are:
47+
48+- Ames: defines and implements Urbit's encrypted P2P network protocol, as well as Urbit's identity protocol.
49+- Behn: manages timer events for other vanes.
50+- Clay: global, version-controlled, and referentially-transparent file system.
51+- Dill: terminal driver.
52+- Eyre: HTTP web client and server.
53+- Ford: typed functional build system.
54+- Gall: application sandbox and manager.
55+ - Dojo (app): Shell and Hoon REPL.
56+ - Talk (app): Chat client.
57+
58+### Hoon
59+
60+Hoon is a strictly typed functional programming language that compiles itself to Nock and is designed to support higher-order functional programming without requiring knowledge of category theory or other advanced mathematics. Haskell is fun but it isn't for everybody.
61+
62+Hoon aspires to a concrete, imperative feel. To discourage the creation of write-only code, Hoon forbids user-level macros and uses ASCII digraphs instead of keywords. The type system infers only forward and does not use unification, but is not much weaker than Haskell's. The compiler and inference engine is about 3000 lines of Hoon.
63+
64+### Nock
65+
66+Nock is a low-level [homoiconic](https://en.wikipedia.org/wiki/Homoiconicity) combinator language. It's so simple that its [specification](../../nock/definition) fits on a t-shirt. In some ways Nock resembles a nano-Lisp but its ambitions are more narrow. Most Lisps are one-layer: a practical language is to be created by extending a theoretically simple interpreter. The abstraction is simple and the implementation is practical. Unfortunately it's far more difficult to enforce both simplicity and practicality in an actual Lisp codebase. Hoon and Nock are two layers: Hoon, the practical layer, compiles itself to Nock, the simple layer. Your urbit runs in Vere, which includes a Nock interpreter, so it can upgrade Hoon over the network without downtime.
67+
68+The Nock data model is quite simple. Every piece of data is a 'noun'. A noun is an atom or a cell. An atom is any unsigned integer. A cell is an ordered pair of nouns. Nouns are acyclic and expose no pointer equality test.
69+
70+### Vere
71+
72+Vere is the Nock runtime environment and Urbit VM. It's written in C, runs on Unix, and is the intermediate layer between your urbit and Unix. As noted earlier, Unix system calls are made by Vere, not Arvo; Vere must also encode and deliver relevant external events to Arvo. Vere is also responsible for implementing jets and maintaining the persistent state of each urbit.
73+
74+In principle, Vere keeps a comprehensive log of every event from the time you initially booted your urbit. What happens if the physical machine loses power and your urbit's state is 'lost' from memory? When your urbit restarts it will replay its entire event history and totally recover its latest state from scratch.
75+
76+In practice, event logs become large and unwieldy over time. Periodically a snapshot of the permanent state is taken and the logs are pruned. You're still able to rebuild your state in case of power outage, down to the last keystroke.
77+
78+Vere is not essential to the Urbit stack; one can imagine using Urbit on a hypervisor, or even bare metal. One member of the community is even working on an independent implementation of Urbit using Graal/Truffle on the JVM.
79+
80+The Urbit stack (compiler, standard library, kernel, modules, and applications, but excluding Vere) is about 30,000 lines of Hoon. Urbit is patent-free and MIT licensed.
docs/about/source.mddeleted−48
@@ -1,48 +0,0 @@
1−---
2−navhome: /docs/
3−navuptwo: true
4−sort: 3
5−title: Source code
6−next: true
7−---
8−
9−# Source code overview
10−
11−We host all our source code on GitHub at [github.com/urbit](https://github.com/urbit).
12−
13−Since there's quite a number of repos, we'll talk about a few of the most important ones here:
14−
15−<ul class="list spaced">
16− <li>
17− <h1><a href="https://github.com/urbit/urbit"><code>urbit/urbit</code></a></h1><br />
18− This is the main Urbit repo. It contains the Urbit interpreter (all of the C code) and is the main entry point if you're going to build from source.
19− </li>
20− <li>
21− <h1><a href="https://github.com/urbit/arvo"><code>urbit/arvo</code></a><br /></h1>
22− Arvo is the Urbit operating system (written in Hoon). When you boot your Urbit, you get this over the air. The source code is kept here, and you'll need it if you want to do any heavy development work.
23− </li>
24− <li><h1><a href="https://github.com/urbit/examples"><code>urbit/examples</code></a></h1><br />
25− At Urbit we love the concept of "see one, do one, teach one". This is the repository for Urbit example apps, generators, libraries, web pages and API connectors. Start with the simple examples taught in the Arvo docs to wrap your head around the fundamental concepts. Then try to understand the more sophisticated web apps. Then make your own app and PR this repo.
26− </li>
27− <li><h1><a href="https://github.com/urbit/docs"><code>urbit/docs</code></a></h1><br />
28− It's become a bit of a rite of passage for new Urbit contributors to solidify their understandings of Hoon and Arvo by contributing to the docs. This repository is where all this collaboration happens. The docs themselves are just markdown files hosted on a live ship.
29− </li>
30− <li><h1><a href="https://github.com/urbit/urbit.org"><code>urbit/urbit.org</code></a></h1><br />
31− This is where the source code for urbit.org lives. Like the docs, the urbit.org website is just a collection of a few markdown files rendered by Tree, the Urbit web publishing system.
32− </li>
33− <li><h1><a href="https://github.com/urbit/base-css"><code>urbit/base-css</code></a></h1><br />
34− We're working on a new Urbit style guide for urbit.org, the docs and Urbit web apps. If you're into visual design or are a CSS fanatic, jump in here.
35− </li>
36− <li><h1><a href="https://github.com/urbit/constitution"><code>urbit/constitution</code></a></h1><br />
37− We're <a href="https://urbit.org/blog/2017.9-eth/">bootstrapping Urbit from Ethereum</a>. This means formally defining the Urbit governance model and public-key infrastructure formally in a simple smart contract deployed on the Ethereum blockchain. If you're into Solidity, or just want to see how this works, check out this repo. Currently getting audited.
38− </li>
39− <li><h1><a href="https://github.com/urbit/etherwallet"><code>urbit/etherwallet</code></a></h1><br />
40− Urbit will soon need a secure, robust frontend interface for buying and selling Urbit address space and interacting directly with the Urbit constitution smart contract. We decided to fork MyEtherWallet, which already has strong security and support for things like multisig and hardware wallet, and modify it to support Urbit. Dive in!
41− </li>
42− <li><h1><a href="https://github.com/urbit/tree"><code>urbit/tree</code></a></h1><br />
43− Tree is the main Urbit web interface written as a React/Flux app in CoffeeScript. We're working on porting this to ES6 and simplifying the architecture generally. If you're into frontend frameworks and web apps, reach out to us and we'll help you get started.
44− </li>
45− <li><h1><a href="https://github.com/urbit/talk"><code>urbit/talk</code></a></h1><br />
46− The main web interface for Urbit's distributed chat and notifications protocol. Currently, like Tree, a simple React/Flux app written in CoffeeScript. With lots of changes happening to the Talk Hoon backend app in the coming releases, our frontend Talk interface will need a lot of development and design work. We've also started the process of porting this to ES6. Ask us how you can start helping out!
47− </li>
48−</ul>
docs/about/source.umdnew file+88
@@ -0,0 +1,88 @@
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3+ next/'true'
4+ sort/'2'
5+ title/'Source code'
6+ ==
7+;>
8+
9+# Source code overview
10+
11+We host all our source code on GitHub at [github.com/urbit](https://github.com/urbit).
12+
13+Since there's quite a number of repos, we'll talk about a few of the most important ones here:
14+
15+;ul(class "list spaced")
16+ ;li
17+ ;h1
18+ ;a/"https://github.com/urbit/urbit"
19+ ;code: urbit/urbit
20+ ==
21+ ==
22+ This is the main Urbit repo. It contains the Urbit interpreter (all of the C code) and is the main entry point if you're going to build from source.
23+ ==
24+ ;li
25+ ;h1
26+ ;a/"https://github.com/urbit/arvo"
27+ ;code: urbit/arvo
28+ ==
29+ ==
30+ Arvo is the Urbit operating system (written in Hoon). When you boot your Urbit, you get this over the air. The source code is kept here, and you'll need it if you want to do any heavy development work.
31+ ==
32+ ;li
33+ ;h1
34+ ;a/"https://github.com/urbit/docs"
35+ ;code: urbit/docs
36+ ==
37+ ==
38+ Interesting in working on Urbit documentation? This repository is where all the collaboration happens. The docs themselves are just markdown files hosted on a live ship.
39+ ==
40+ ;li
41+ ;h1
42+ ;a/"https://github.com/urbit/urbit.org"
43+ ;code: urbit/urbit.org
44+ ==
45+ ==
46+ This is where the source code for urbit.org lives. Like the docs, the urbit.org website is just a collection of a few markdown files rendered by Tree, the Urbit web publishing system.
47+ ==
48+ ;li
49+ ;h1
50+ ;a/"https://github.com/urbit/base-css"
51+ ;code: urbit/base-css
52+ ==
53+ ==
54+ We're working on a new Urbit style guide for urbit.org, the docs and Urbit web apps. If you're into visual design or are a CSS fanatic, jump in here.
55+ ==
56+ ;li
57+ ;h1
58+ ;a/"https://github.com/urbit/constitution"
59+ ;code: urbit/constitution
60+ ==
61+ ==
62+ We're [bootstrapping Urbit from Ethereum](https://urbit.org/blog/2017.9-eth/). This means formally defining the Urbit governance model and public-key infrastructure formally in a simple smart contract deployed on the Ethereum blockchain. If you're into Solidity, or just want to see how this works, check out this repo. Currently getting audited.
63+ ==
64+ ;li
65+ ;h1
66+ ;a/"https://github.com/urbit/etherwallet"
67+ ;code: urbit/etherwallet
68+ ==
69+ ==
70+ Urbit will soon need a secure, robust frontend interface for buying and selling Urbit address space and interacting directly with the Urbit constitution smart contract. We decided to fork MyEtherWallet, which already has strong security and support for things like multisig and hardware wallet, and modify it to support Urbit. Dive in!
71+ ==
72+ ;li
73+ ;h1
74+ ;a/"https://github.com/urbit/tree"
75+ ;code: urbit/tree
76+ ==
77+ ==
78+ Tree is the main Urbit web interface written as a React/Flux app in CoffeeScript. We're working on porting this to ES6 and simplifying the architecture generally. If you're into frontend frameworks and web apps, reach out to us and we'll help you get started.
79+ ==
80+ ;li
81+ ;h1
82+ ;a/"https://github.com/urbit/talk"
83+ ;code: urbit/talk
84+ ==
85+ ==
86+ The main web interface for Urbit's distributed chat and notifications protocol. Currently, like Tree, a simple React/Flux app written in CoffeeScript. With lots of changes happening to the Talk Hoon backend app in the coming releases, our frontend Talk interface will need a lot of development and design work. We've also started the process of porting this to ES6. Ask us how you can start helping out!
87+ ==
88+==
docs/arvo.mddeleted−14
@@ -1,14 +0,0 @@
1−---
2−navhome: /docs/
3−next: true
4−sort: 6
5−title: Arvo
6−---
7−
8−# Arvo
9−
10−Fast, pragmatic tutorials which show you how to build simple programs in Hoon and Arvo.
11−
12−If you learn by getting things done, not by exploring fundamentals, start here.
13−
14−<list/>
docs/arvo/basic.mddeleted−337
@@ -1,337 +0,0 @@
1−---
2−navhome: /docs/
3−sort: 11
4−next: true
5−title: Basic Hoon
6−---
7−
8−Basic Hoon
9−==========
10−
11−Our goal is to get you programming interesting and useful things as soon
12−as possible. To get there, we have to quickly cover some of the
13−fundamentals of [Hoon](/docs/hoon/). To do this, we'll walk through two simple
14−programs: the first [Project Euler](https://projecteuler.net/) problem
15−and [fizzbuzz](https://en.wikipedia.org/wiki/Fizz_buzz).
16−
17−To run this code, you'll need an urbit, and will have to either sync or copy the
18−[examples repo](https://github.com/urbit/examples) into it.
19−
20−## Installation
21−
22−First, you'll need a running urbit. Follow our urbit.org [install
23−instructions](https://urbit.org/docs/using/install), then
24−[setup](https://urbit.org/docs/using/setup) and urbit.
25−
26−Follow the *Network install* below if your urbit is running on the live network
27−(comets are usually best for development). Follow the *Local install* instead
28−if you're on a
29−[fake ship](https://urbit.org/fora/posts/~2017.1.5..21.31.04..20f3~/) or are
30−otherwise experiencing problems with the network install.
31−
32−### Network install
33−
34−In your urbit's `:dojo`, run the command:
35−
36− ~your-urbit:dojo> |sync %examples ~ladnub-lorwyn %examples
37−
38−Depending on network traffic, this initial merge and sync could take anywhere
39−between thirty seconds to several minutes. Upon a successful sync you'll see the
40−output:
41−
42− sync succeeded from %examples on ~ladnub-lorwyn to %examples
43−
44−In which case, next run the commands:
45−
46− ~your-urbit:dojo> =dir /=examples=
47− ~your-urbit:dojo/examples> |serve %/web
48− ~your-urbit:dojo/examples> |mount %
49−
50−If your sync isn't succeeding after a few minutes for whatever reason, run
51−`|cancel %examples` in your `:dojo` and follow the local install below instead.
52−
53−### Local install
54−
55−In your urbit's `:dojo`:
56−
57− ~your-urbit:dojo> |merge %examples our %base, =gem %init
58− ~your-urbit:dojo> =dir /=examples=
59− ~your-urbit:dojo/examples> |serve %/web
60− ~your-urbit:dojo/examples> |mount %
61−
62−If `~your-urbit` was installed at `/urbit/path` on your Unix machine, you can
63−now find your `%examples` desk at the path `/urbit/path/your-urbit/examples`.
64−
65−Lastly, in Unix, clone this repo somewhere and copy in the `examples` files to
66−your urbit's new mounted `%examples` desk. You can run the following shell
67−commands (*replacing your urbit's examples desk path as necessary*):
68−
69− $ git clone https://github.com/urbit/examples
70− $ for dir in {app,gen,lib,mar,sec,sur,web}; do cp -r ./examples/$dir* /urbit/path/your-urbit/examples; done
71−
72−Your `%clay` filesystem should acknowledge the newly added files.
73−
74−## Get started!
75−
76−Run an example to ensure it worked:
77−
78− ~fintud-macrep:dojo/examples> +project-euler-p1
79− 233.168
80−
81−Euler 1
82−-------
83−
84−Let's check out the code for Euler 1. First, the problem:
85−
86− If we list all the natural numbers below 10 that are multiples of
87− 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
88−
89− Find the sum of all the multiples of 3 or 5 below 1000.
90−
91−Here is the hoon solution (which should be in your pier directory under
92−`/examples/gen/project-euler/p1`):
93−
94− :: Project Euler 1
95− :: https://projecteuler.net/problem=1
96− ::
97− :: run in dojo with:
98− :: ~your-urbit:dojo/examples> +project-euler/p1
99− ::
100− :::: /===/gen/project-euler/p1/hoon
101− ::
102− !:
103− ::
104− :- %say |= *
105− :- %noun
106− =< (sum 1.000)
107− ::
108− |%
109− ++ three
110− |= a/@
111− =| b/@
112− |- ^- @u
113− ?: (lth a b)
114− 0
115− (add b $(b (add 3 b)))
116− ::
117− ++ five
118− |= a/@
119− =| b/@
120− |- ^- @
121− ?: (lte a b)
122− 0
123− ?: =((mod b 3) 0)
124− $(b (add b 5))
125− (add b $(b (add b 5)))
126− ::
127− ++ sum
128− |= a/@u
129− (add (five a) (three a))
130− --
131−
132−> Hoon is not generally whitespace sensitive, but we do have two
133−> different kinds of whitespace: a single space and a gap, which is two
134−> or more spaces or a linebreak. Tabs are taboo. Do not use them.
135−> Really. For a more detailed explanation of when to use spaces vs.
136−> gaps, see the syntax section before the first exercises.
137−
138−### Lines 1-13:
139−
140−Any line that begins with `::` is a comment.
141−
142− :- %say |= *
143− :- %noun
144− =< (sum 1.000)
145−
146−All you need to know about the lines above is that they call the `++sum`
147−function with an argument of `1.000`. We'll cover them in more detail
148−later.
149−
150−### How to form expressions
151−
152−Hoon does not typically use reserved words to form expressions. Instead,
153−expressions are formed with *runes*: digraphs of two ASCII symbols. Each
154−rune takes a specific number of children, either expressions formed by
155−other runes or literals that produce their own value (some runes take
156−*N* children, and are usually closed with `==`).
157−
158−For example, the rune `?:` from line 20 is the classic 'if-then-else' statement,
159−and thus takes three children:
160−
161− ?: (lth a b) :: if first child evals to true
162− 0 :: then produce result of second
163− (add b $(b (add 3 b))) :: else, produce result of third
164−
165−Since runes are such a fundamental structure in Hoon, we found ourselves
166−speaking them out loud frequently. It quickly grew cumbersome to have to
167−say "question mark, colon" to describe `?:`. To alleviate this problem,
168−we came up with our own naming scheme: each ASCII glyph has a
169−single-syllable pronunciation phonetically designed to be both easily
170−remembered and easily pronounced in conjunction with the other glyphs
171−(when forming a rune).
172−
173−See the entire naming scheme below.
174−
175− ace [1 space] gal < pal (
176− bar | gap [>1 space, nl] par )
177− bas \ gar > sel [
178− buc $ hax # sem ;
179− cab _ hep - ser ]
180− cen % kel { sig ~
181− col : ker } soq '
182− com , ket ^ tar *
183− doq " lus + tec `
184− dot . pam & tis =
185− fas / pat @ wut ?
186− zap !
187−
188−Using this scheme, we would pronounce `?:` as 'wutcol'.
189−
190−### Lines 14-37
191−
192−Now let's quickly walk through this code line-by-line. Lines 14-37 are wrapped
193−in a `|%` ('[barcen](../../hoon/rune/bar/cen/)'), which produces a
194−core. Cores are a fundamental datatype in Hoon, similar to a struct, class, or
195−object. A core is just a map of names to any kind of code, whether it be
196−functions or data. Each element, called an arm, in this map begins with a `++`
197−followed by the name and the corresponding code. Since `|%` takes an arbitrary
198−number of children, it needs to be closed with a `--`.
199−
200−> `++` ('luslus') is not technically a rune, since it is only used in
201−> core syntax, as shown above.
202−
203−Let's step into each of the three arms within our core.
204−
205−### `++ sum`
206−
207− ++ sum
208− |= a/@u
209− (add (five a) (three a))
210− --
211−
212− `|=` ('[bartis](../../hoon/rune/bar/tis/)') produces a function, much like a lambda in lisp. It
213−takes two children:
214−
215−1. A set of argument(s). In this case our argument set only contains
216− one: `a`, which is required to be an atom or natural number, denoted
217− by `@`.
218−
219−2. The body of the function itself, which is executed when the function is
220− called (in this case, with `(sum 1.000)`). This particular function adds the
221− results of evaluating the gates `++five` and `++three` with each of their
222− respective input parameters set to `a`.
223−
224−### ++ three
225−
226− ++ three
227− |= a/@
228− =| b/@
229− |- ^- @u
230− ?: (lth a b)
231− 0
232− (add b $(b (add 3 b)))
233−
234−As above, `++three` takes an integer argument, `a`, and then executes
235−the remainder of the code with `a` set to the actual arguments.
236−
237−Similarly, `=|` ('[tisbar](../../hoon/rune/tis-flow/bar-new/)') pushes its first child, `b` into our context
238−(in other words, it declares a variable `b`) and executes the remainder
239−of the code. However, `b` is not an argument; `=|` sets `b` to the
240−default value of whatever type it is declared as. Since the default
241−value of an atom is `0`, b is set to `0`.
242−
243−> To produce the default value of any given type, use `*` ('tar')
244−> followed by the type. This operaction is called *bunt*.
245−>
246−> > *@ :: produce the default value of atom @
247−> 0
248−>
249−> > *@p :: produce the phonemic base of atom @
250−> ~zod
251−
252−So now we have two variables: `a` is set to our input, and `b` is
253−initialized to `0`.
254−
255−One way to think about `|-` ('[barhep](../../hoon/rune/bar/hep/)') is that it lays down a recursion
256−point. More on this later.
257−
258−`^-` ('[kethep](../../hoon/rune/ket/hep/)') is just a cast that sets the result of the remainder of
259−the code to an unsigned integer, `@u`.
260−
261−In pseudocode, the last three lines read like this: if `a` is less than
262−`b`, produce zero. Else, add `b` to the result of rerunning the segment
263−of the function following the `|-` with the value of `b` changed to `b`
264−plus three.
265−
266−The only thing that should look completely unfamiliar to you here is the
267−`$(b (add 3 b))`, which causes us to recurse back to our last recursion
268−point with the value of `b` set to `(add 3 b)`. Note that we only
269−specify what changes (`b` in this case). If you recurse by an actual
270−function call, then you have to specify every argument.
271−
272−> If you're familiar with Clojure, `|-` is `loop` and `$()` is `recur`.
273−
274−**Exercises**:
275−
276−Tweak your code to complete the following exercises.
277−
278−There are a few runes and some syntax that we have yet to cover that you
279−will need to complete the exercises below. For these, please refer to
280−our cheatsheat at the bottom.
281−
282−1. Read and understand `++five` line by line.
283−
284−2. Change `++sum` to accept two variables, `a` and `b`. Pass `a` to
285− `three` and `b` to `five`. Then run the code with `a` set to `1.000`
286− and `b` set to `2.000`.
287−
288−3. Check if this new result is under one thousand. If it is, return the
289− string `'result < 1.000'`. If not, return `'result >= 1.000'`.
290−
291−### Review
292−
293− |% ('barcen') start core (collection of named ++ arms; an "object")
294− |= ('bartis') define function
295− =| ('tisbar') define variable from type with default value
296− |- ('barhep') drop a recursion point
297− ^- ('kethep') cast
298− ?: ('wutcol') if-then-else
299− =(a b) test equality
300− (function args ...) call function with args
301−
302−Lookup each of these expressions (and all others!) in the [Rune Expressions](../../hoon/rune/) definition.
303−
304−### New material
305−
306−1. There are two syntaxes for writing Hoon: tallform and wideform.
307−
308− In tallform, expressions are formed with either two spaces or a line
309− break separating both a rune from its children and each of its children
310− from one another. We use tallform when writing multiline expressions.
311−
312− For more concise expressions, we use wideform, which is always a single
313− line. Wideform can be used inside tallform expressions, but not vice
314− versa.
315−
316− Wideform expressions are formed with a rune followed by `()` containing
317− its children, all of which are separated by a single space. For example,
318− to make a cell of two elements, use `:-(a b)`.
319−
320− We've already seen wideform in action, for example with
321− `=((mod b 3) 0)`. In this case, `=` is actually an irregular form of
322− `.=`, which tests its two children for equality.
323−
324− Surrounding a function with `()` is an irregular wide form syntax for
325− calling a function with *N* arguments. More on this later.
326−
327−2. For a set of multiple arguments following `|=` ('[bartis](../../hoon/rune/bar/tis/)'), use `{` 'kel' and `}` 'ker.' For example: `{a/@u b/@u}`.
328−
329−3. `:-` makes a cell of values. The irregular wide form of this is
330− `[a b]`, with two expressions separated by a single space. While the
331− regular form of this rune takes a fixed number of children (two),
332− its irregular wide form can accept *N* expressions: `[a1..an]`.
333−
334−4. Cords are one datatype for text in Hoon. They're just a big atom
335− formed from adjacent unicode bytes -- a "c string". To produce a
336− cord, enclose text within single quotes. To set the type of an
337− argument to a cord, use `@t`.
docs/arvo/internals/ford/commentary.mddeleted−2576
@@ -1,2576 +0,0 @@
1−---
2−navhome: /docs/
3−---
4−
5−
6−Reference
7−=========
8−
9−Data Models
10−-----------
11−
12−### `++axle`, formal state
13−
14− ++ axle :: all %ford state
15− $: %1 :: version for update
16− pol=(map ship baby) ::
17− == ::
18−
19−This is the formal state of our vane. Anything that must be remembered
20−between calls to ford must be stored here. The number `%1` is a version
21−number for our state that allows us to upgrade the structure of our
22−state in the future if we wish.
23−
24−`pol` is the a map from every ship on our pier to their individual ford
25−state. There is no shared ford state -- every ship is entirely separate.
26−
27−### `++baby`, state by ship
28−
29− ++ baby :: state by ship
30− $: tad=[p=@ud q=(map ,@ud task)] :: tasks by number
31− dym=(map duct ,@ud) :: duct to task number
32− jav=(map ,* calx) :: cache
33− == ::
34−
35−This is the state specific to each ship.
36−
37−`tad` and `dym` keep track of the tasks we're currently working on.
38−`dym` is a map from ducts to task numbers, and `q.tad` is a map from
39−task number to the task itself. `p.tad` is the next available task
40−number. Thus, the keys of `q.tad` are a subset of the numbers less than
41−`p.tad`, and ford has attempted exactly `p.tad` tasks so far.
42−
43−`jav` is the cache of previously-solved problems. The keys are a pair of
44−a term (either `%hood`, `%slap`, or `%slam`) and a noun that represents
45−the exact problem solved. In the case of a `%hood`, then, the key is of
46−the form `[%hood beam cage]`. For `%slap`, there is `[%slap vase hoon]`.
47−For `%slam`, there is `[%slam vase vase]`. The values are the result of
48−solving the problem. Note that this cache is wiped in `++stay` when ford
49−is reloaded.
50−
51−### `++task`, problem in progress
52−
53− ++ task :: problem in progress
54− $: nah=duct :: cause
55− kas=silk :: problem
56− kig=[p=@ud q=(map ,@ud beam)] :: blocks
57− == ::
58−
59−This is all the state we keep regarding a particular task. `nah` is the
60−duct which asked us to solve the problem, and `kas` is the most recent
61−statement of the problem.
62−
63−`kig` keeps track of which resources we are blocked on. Our blocks are
64−stored by index in `q.kig`, and the next available index is `p.kig`.
65−
66−### `++silk`, problem
67−
68− ++ silk :: construction layer
69− $& [p=silk q=silk] :: cons
70− $% [%bake p=mark q=beam r=path] :: local synthesis
71− [%boil p=mark q=beam r=path] :: general synthesis
72− [%call p=silk q=silk] :: slam
73− [%cast p=mark q=silk] :: translate
74− [%diff p=silk q=silk] :: diff
75− [%done p=(set beam) q=cage] :: literal
76− [%dude p=tank q=silk] :: error wrap
77− [%dune p=(set beam) q=(unit cage)] :: unit literal
78− [%mute p=silk q=(list (pair wing silk))] :: mutant
79− [%pact p=silk q=silk] :: patch
80− [%plan p=beam q=spur r=hood] :: structured assembly
81− [%reef ~] :: kernel reef
82− [%ride p=hoon q=silk] :: silk thru hoon
83− [%vale p=mark q=ship r=*] :: validate [our his]
84− == ::
85−
86−This is the every type of problem we can solve. Every `%exec` kiss that
87−requests us to solve a problem must choose one of these problems to
88−solve.
89−
90−Because this is both an internal structure used in ford and the public
91−interface to ford, we choose to document this structure in our
92−discussion of the public interface to ford below.
93−
94−### `++calx`, cache line
95−
96− ++ calx :: concrete cache line
97− $% [%hood p=calm q=(pair beam cage) r=hood] :: compile
98− [%slap p=calm q=[p=vase q=hoon] r=vase] :: compute
99− [%slam p=calm q=[p=vase q=vase] r=vase] :: compute
100− == ::
101−
102−There are three kinds of cache entries. Every entry includes some
103−metadata in `p` and is the combination of an input and its output.
104−
105−The input to a `%hood` is the location of the resource and a cage
106−representing the data at that location. The output is the hood found by
107−compiling the given cage at the given location.
108−
109−The input to a `%slap` is the vase of the subject and the hoon of the
110−formula against which we are slapping the subject. The output is the
111−vase produced by slapping them.
112−
113−The input to a `%slam` is the vase of the subject and the vase of the
114−gate which we are slapping. The output is the vase produced by slamming
115−them.
116−
117−### `++calm`, cache line metadata
118−
119− ++ calm :: cache metadata
120− $: laz=@da :: last accessed
121− dep=(set beam) :: dependencies
122− == ::
123−
124−Every line in the cache needs to have two pieces of metadata. We must
125−know the last time this line in the cache was accessed, and we must know
126−what are the dependencies of this line.
127−
128−### `++hood`, assembly components
129−
130− ++ hood :: assembly plan
131− $: zus=@ud :: zuse kelvin
132− sur=(list hoot) :: structures
133− lib=(list hoof) :: libraries
134− fan=(list horn) :: resources
135− src=(list hoop) :: program
136− == ::
137−
138−When assembling a hook file, we split it into several sections.
139−
140−`zus` is the kelvin version of the required zuse. In general, we assume
141−that any newer (lower-numbered) zuse will retain backward compatibility,
142−so any newer zuse is also permissible. This number is set with a `/?` at
143−the beginning of the file.
144−
145−`sur` is the set of structures included. These are included with the
146−`/-` rune. When a structure is included, we look in `/=main=/sur` for
147−the given structure and we load the gate there. When compiling, all the
148−included structures are collected into a single core placed in the
149−subject of the body with a `=>`.
150−
151−`lib` is the set of librarires included. These are included with the
152−`/+` rune. When a library is included, we look in `/=main=/lib` for the
153−given library and we load the library there. As with structures, all the
154−included libraries are collected into a single core placed in the
155−subject of the body with a `=>`.
156−
157−`fan` is the set of resources included. These are loaded in many
158−different ways and may load resources from any location. These are
159−placed in the subject of the body with a `=~`.
160−
161−`src` is the set of hoons or references to hoons in the body of the
162−program. Generally, each of these will represent a core, but this is not
163−required. When compiling, these are strung together in a `=~`.
164−
165−### `++hoot`
166−
167− ++ hoot (pair bean hoof) :: structure gate/core
168−
169−A structures may be either a direct gate or a core. These are
170−syntactically distinguished by adding a `*` to the beginning of the
171−structure name for a core. The structure itself is a `hoof`.
172−
173−### `++hoof`
174−
175− ++ hoof (pair term (unit (pair case ship))) :: resource reference
176−
177−A hoof, which is either a structure or a library, has a name, and it may
178−also specify which version of the resource to use and which ship to
179−retrieve it from.
180−
181−### `++horn`
182−
183− ++ horn :: resource tree
184− $% [%ape p=hoon] :: /~ hoon by hand
185− [%arg p=hoon] :: /$ argument
186− [%day p=horn] :: /| list by @dr
187− [%dub p=term q=horn] :: /= apply face
188− [%fan p=(list horn)] :: /. list
189− [%for p=path q=horn] :: /, descend
190− [%hub p=horn] :: /@ list by @ud
191− [%man p=(map span horn)] :: /* hetero map
192− [%nap p=horn] :: /% homo map
193− [%now p=horn] :: /& list by @da
194− [%saw p=hoon q=horn] :: /; operate on
195− [%see p=beam q=horn] :: /: relative to
196− [%sic p=tile q=horn] :: /^ cast
197− [%toy p=mark] :: /mark/ static
198− == ::
199−
200−This is how we represent the static resources hook files can load. The
201−discussion of their use from a user's perspective is documented in the [runes
202−documentation](https://urbit.org/docs/arvo/internals/runes), so we will here
203−only give a description of the data structure itself.
204−
205−A `%ape` horn is simply a hoon that gets evaluated and placed in the
206−subject.
207−
208−A `%arg` is a gate that gets evaluated with a sample of our location and
209−our heel.
210−
211−A `%day` is a horn that applies to each of a list of `@dr`-named files
212−in the directory.
213−
214−A `%dub` is a term and horn, where the result of a horn is given the
215−face of the term.
216−
217−A `%fan` is a list of horns, all at the current directory level.
218−
219−A `%for` is a path and a horn, where the horn is evaluated relative to
220−the given path, where the given path is relative to the current
221−location.
222−
223−A `%hub` is a horn that applies to each of a list of `@ud`-named files
224−in the directory.
225−
226−A `%man` is a map of spans to horns where the result is a set of each
227−horn applied to the current directory given the associated face.
228−
229−A `%nap` is a homogenous map where each entry in a directory is handled
230−with the same horn and is given a face according to its name.
231−
232−A `%now` is a horn that applies to each of a list of `@da`-named files
233−in the directory.
234−
235−A `%saw` is a hoon and a horn, where the hoon operates on the result of
236−the horn.
237−
238−A `%see` is a beam and a horn, where the horn is evaluated at a location
239−of the given beam.
240−
241−A `%sic` is a tile and a horn, where the horn is evaluated and cast to
242−the type associated with the tile.
243−
244−A `%toy` is simply a mark to be baked.
245−
246−### `++hoop`, body
247−
248− ++ hoop :: source in hood
249− $% [%& p=hoon] :: direct hoon
250− [%| p=beam] :: resource location
251− == ::
252−
253−This is an entry in the body of the hook file. The hoop can either be
254−defined directly in the given file or it can be a reference to another
255−file. The second is specified with a `//` rune.
256−
257−### `++bolt`, monadic edge
258−
259− ++ bolt :: gonadic edge
260− |* a=$+(* *) :: product clam
261− $: p=cafe :: cache
262− $= q ::
263− $% [%0 p=(set beam) q=a] :: depends/product
264− [%1 p=(set ,[p=beam q=(list tank)])] :: blocks
265− [%2 p=(list tank)] :: error
266− == ::
267− == ::
268−
269−Throughout our computation, we let our result flow through with the set
270−of dependencies of the value. At various times, we may wish to either
271−throw an error or declare that the actual result cannot be found until a
272−particular resource is retrieved. This is a perfect case for a monad, so
273−here we define a data structure for it.
274−
275−At every step, we have a cache, so we store that in `p`. In `q` we store
276−the data.
277−
278−In the case of `%0`, we have the result in `q` and the set of
279−dependencies in `p`.
280−
281−In the case of `%1`, we have a set of dependencies on which we are
282−blocking. When this happens, we make a call to clay to get the
283−dependencies, and we proceed with the computation when we receive them.
284−Technically, we restart the computation, but since every expensive step
285−is cached, there is no significant performance penalty to doing this.
286−Referential transparency has its uses.
287−
288−In the case of `%2`, we have a hit an error. This gets passed all the
289−way through to the calling duct. The list of tanks is some description
290−of what went wrong, often including a stack trace.
291−
292−### `++burg`, monadic rule
293−
294− ++ burg :: gonadic rule
295− |* [a=$+(* *) b=$+(* *)] :: from and to
296− $+([c=cafe d=a] (bolt b)) ::
297− :: ::
298−
299−To operate on bolts, we use `++cope` as our bind operator, and the
300−functions it works on are of type `burg`. Our functions that operate on
301−bolts should have a sample of the cache and a value. Their output should
302−be a bolt of the output value. Then, `++cope` will only call the
303−function when necessary (in the `%0` case), and it will do so without
304−the wrapping of a bolt.
305−
306−If you understand monads, this is probably fairly obvious. Otherwise,
307−see the discussion on `++cope` (link).
308−
309−Public Interface
310−----------------
311−
312−Ford does not export a scry interface, so the only way to interact with
313−ford is by sending kisses and receiving gifts. In fact, ford only sends
314−accepts one kiss and gives one gift. This is, of course, misleading
315−because ford actually does many different things. It does, however, only
316−produce one type of thing -- a result of a computation, which is either
317−an error or the value produced along with the set of dependencies
318−referenced by it.
319−
320− ++ kiss :: in request ->$
321− $% [%exec p=@p q=(unit silk)] :: make / kill
322− == ::
323−
324−The `%exec` gift requests ford to perform a computation on behalf of a
325−particular ship. `p` is the ship, and `q` is the computation. If `q` is
326−null, then we are requesting that ford cancel the computation that it is
327−currently being run along this duct. Thus, if you wish to cancel a
328−computation, you must send the kiss along the same duct as the original
329−request.
330−
331−Otherwise, we ask ford to perform a certain computation, as defined in
332−`++silk`. Since all computations produce the same type of result, we
333−will discuss that result before we jump into `++silk`.
334−
335− ++ gift :: out result <-$
336− $% [%made p=(each bead (list tank))] :: computed result
337− == ::
338−
339−We give either a `bead`, which is a result, or a list of tanks, which is
340−an error messge, often including a stack trace.
341−
342− ++ bead ,[p=(set beam) q=cage] :: computed result
343−
344−This is a set of dependencies required to compute this value and a cage
345−of the result with its associated mark.
346−
347−There are twelve possible computations defined in `++silk`.
348−
349− ++ silk :: construction layer
350− $& [p=silk q=silk] :: cons
351− $% [%bake p=mark q=beam r=path] :: local synthesis
352− [%boil p=mark q=beam r=path] :: general synthesis
353− [%call p=silk q=silk] :: slam
354− [%cast p=mark q=silk] :: translate
355− [%done p=(set beam) q=cage] :: literal
356− [%dude p=tank q=silk] :: error wrap
357− [%dune p=(set beam) q=(unit cage)] :: unit literal
358− [%mute p=silk q=(list (pair wing silk))] :: mutant
359− [%plan p=beam q=spur r=hood] :: structured assembly
360− [%reef ~] :: kernel reef
361− [%ride p=hoon q=silk] :: silk thru hoon
362− [%vale p=mark q=ship r=*] :: validate [our his]
363− == ::
364−
365−First, we allow silks to autocons. A cell of silks is also a silk, and
366−the product vase is a cell of the two silks. This obviously extends to
367−an arbitrary number of silks.
368−
369−`%bake` tries to functionally produce the file at a given beam with the
370−given mark and heel. It fails if there is no way to translate at this
371−level.
372−
373−`%boil` functionally produces the file at a given beam with the given
374−mark and heel. If there is no way to translate at this beam, we pop
375−levels off the stack and attempt to bake there until we find a level we
376−can bake. This should almost always be called instead of `%bake`.
377−
378−`%call` slams the result of one silk against the result of another.
379−
380−`%cast` translates the given silk to the given mark, if possible. This
381−is one of the critical and fundamental operations of ford.
382−
383−`%done` produces exactly its input. This is rarely used on its own, but
384−many silks are recursively defined in terms of other silks, so we often
385−need a silk that simply produces its input. A monadic return, if you
386−will.
387−
388−`%diff` diffs the two given silks (which must be of the same mark),
389−producing a cage of the mark specified in `++mark` in `++grad` for the
390−mark of the two silks.
391−
392−`%dude` computes the given silk with the given tank as part of the stack
393−trace if there is an error.
394−
395−`%dune` produces an error if the cage is empty. Otherwise, it produces
396−the value in the unit.
397−
398−`%mute` takes a silk and a list of changes to make to the silk. At each
399−wing in the list we put the value of the associated silk.
400−
401−`%pact` applies the second silk as a patch to the first silk. The second
402−silk must be of the mark specified in `++mark` in `++grad` for the mark
403−of the first silk.
404−
405−`%plan` performs a structured assembly directly. This is not generally
406−directly useful because several other silks perform supersets of this
407−functionality. We don't usually have naked hoods outside ford.
408−
409−`%reef` produces a core containing the entirety of zuse and hoon,
410−suitable for running arbitrary code against. The mark is `%noun`.
411−
412−`%ride` slaps a hoon against a subject silk. The mark of the result is
413−`%noun`.
414−
415−`%vale` validates untyped data from a ship against a given mark. This is
416−an extremely useful function.
417−
418−Commentary
419−==========
420−
421−Parsing Hook Files
422−------------------
423−
424−In the commentary on other vanes, we have traced through the lifecycle
425−of various external requests. This is generally a very reasonable order
426−to examine vanes since it will eventually cover the entire vane, and we
427−are never left wondering why we are doing something.
428−
429−For ford, however, it makes more sense to begin by discussing the
430−parsing and assembliing of hook files. Many of the possible requests
431−require us to assemble hook files, so we may as well examine this
432−immediately.
433−
434−First, we will examine the parsing. We parse a file at a beam to a hood
435−in `++fade:zo:za`. The top-level parsing rule is `++fair`, which takes a
436−beam and produces a rule to parse an entire hood file.
437−
438−A note on the naming scheme: the parsing the combinators that parse into
439−a particular structure are conventionally given the same name as the
440−structure. Although this locally clobbers the type names, this pattern
441−makes obvious the intent of the parsing combinators.
442−
443−We kick off with `++hood:fair`.
444−
445− ++ hood
446− %+ ifix [gay gay]
447− ;~ plug
448− ;~ pose
449− (ifix [;~(plug fas wut gap) gap] dem)
450− (easy zuse)
451− ==
452− ::
453− ;~ pose
454− (ifix [;~(plug fas hep gap) gap] (most ;~(plug com gaw) hoot))
455− (easy ~)
456− ==
457− ::
458− ;~ pose
459− (ifix [;~(plug fas lus gap) gap] (most ;~(plug com gaw) hoof))
460− (easy ~)
461− ==
462− ::
463− (star ;~(sfix horn gap))
464− (most gap hoop)
465− ==
466−
467−There are five sections to a hood: system version, structures,
468−libraries, resources, and body.
469−
470−First, we parse the requested version number of the system. This is
471−specified with a unary `/?` rune. If not present, then we default to the
472−current version.
473−
474−Second, we may have zero or more `/-` runes followed by a parsing of a
475−`++hoot`, which represents a shared structure.
476−
477−Third, we may have zero or more `/+` runes followed by a parsing of a
478−`++hoof`, which represents a shared library.
479−
480−Fourth, we may have zero or more other `/` runes (as described in
481−`++horn`), which represent program-specific resources to be loaded.
482−
483−Fifth and finally, we must have one or more body statements (hoops),
484−which are either direct hoons or `//` runes.
485−
486− ++ hoot
487− ;~ pose
488− (stag %| ;~(pfix tar hoof))
489− (stag %& hoof)
490− ==
491−
492−A structure can either be a direct gate, or it can be a simple core.
493−Either one is parsed with `++hoof`, so we distinguish the two cases by
494−requiring core references to be prefixed by a `*`.
495−
496− ++ hoof
497− %+ cook |=(a=^hoof a)
498− ;~ plug
499− sym
500− ;~ pose
501− %+ stag ~
502− ;~(plug ;~(pfix fas case) ;~(pfix ;~(plug fas sig) fed:ag))
503− (easy ~)
504− ==
505− ==
506−
507−A hoof must have a name, which is a term. Optionally, we also include a
508−case and a ship. This is marked by appending a `/` followed by a case to
509−denote the requested version of the resource and a `/` followed by a
510−ship name to denote the requested source of the resource. For example,
511−`resource/1/~zod` requests the first version of `resource` on `~zod`.
512−
513− ++ case
514− %- sear
515− :_ nuck:so
516− |= a=coin
517− ?. ?=([%$ ?(%da %ud %tas) *] a) ~
518− [~ u=(^case a)]
519−
520−Here, we parse a literal with `++nuck:so`, and we accept the input if it
521−is either an absolute date, an unsigned decimal, or a label.
522−
523−This leaves only horns and hoops to parse. Hoops are much simple to
524−parse, so we'll discuss those first.
525−
526− ++ hoop
527− ;~ pose
528− (stag %| ;~(pfix ;~(plug fas fas gap) have))
529− (stag %& tall:vez)
530− ==
531−
532−There are two types of hoops. Direct hoons are parsed with
533−`++tall:vast`, which is the just the Hoon parser for a tall-form rune.
534−
535−References to external hoons are marked with a `//` rune followed by a
536−beam, which is parsed with `++have`.
537−
538− ++ hath (sear plex:voz (stag %clsg poor:voz)) :: hood path
539− ++ have (sear tome ;~(pfix fas hath)) :: hood beam
540−
541−`++have` parses a path with `++hath`, and then it converts the path into
542−a beam with `++tome`.
543−
544−`++hath` parses a `/`-separated list with `++poor:vast`, then converts
545−it to an actual path with `++plex:vast`.
546−
547−This leaves only horns to parse.
548−
549− ++ horn
550− =< apex
551− =| tol=?
552− |%
553− ++ apex
554− %+ knee *^horn |. ~+
555− ;~ pfix fas
556− ;~ pose
557− (stag %toy ;~(sfix sym fas))
558− (stag %ape ;~(pfix sig ape:read))
559− (stag %arg ;~(pfix buc ape:read))
560− (stag %day ;~(pfix bar day:read))
561− (stag %dub ;~(pfix tis dub:read))
562− (stag %fan ;~(pfix dot fan:read))
563− (stag %for ;~(pfix com for:read))
564− (stag %hub ;~(pfix pat day:read))
565− (stag %man ;~(pfix tar man:read))
566− (stag %nap ;~(pfix cen day:read))
567− (stag %now ;~(pfix pam day:read))
568− (stag %saw ;~(pfix sem saw:read))
569− (stag %see ;~(pfix col see:read))
570− (stag %sic ;~(pfix ket sic:read))
571− ==
572− ==
573−
574−Horn parsing is slightly complex, so we create an internal core to
575−organize our code. Our core has a global variable of `tol`, which is
576−true if tall form is permissible and false if we're already in wide
577−form. We kick off the parsing with `++apex`.
578−
579−`++apex` specifies how each rune is parsed. This allows us to offload
580−the different ways of parsing the arguments to these runes into separate
581−arms. The exception here is that the `%toy` horn is simply of the form
582−`/mark/`.
583−
584−We'll examine each of the horn parsing arms right after we discuss
585−`++rail`, which is used in each one.
586−
587− ++ rail
588− |* [wid=_rule tal=_rule]
589− ?. tol wid
590− ;~(pose wid tal)
591−
592−This takes a wide-form and a tall-form parsing rule. If tall form is
593−permissible, then it allows either rule to match; else, it allows only
594−the wide form rule.
595−
596− ++ read
597− |% ++ ape
598− %+ rail
599− (ifix [sel ser] (stag %cltr (most ace wide:vez)))
600− ;~(pfix gap tall:vez)
601−
602−`++ape:read` parses for both the `/~` and the `/$` runes. It produces a
603−hoon. The wide form is a tuple of one or more ace-separated wide-form
604−hoons parsed with `++wide:vast` and surrounded by `[` and `]`. The tall
605−form is a single tall form hoon parsed by `++tall:vast`
606−
607− ++ day
608− %+ rail
609− apex(tol |)
610− ;~(pfix gap apex)
611−
612−This parses for the `/|`, `/@`, `/%`, and `/&` runes. It produces a
613−horn. The wide form is, recursively, the entire horn parser with tall
614−form disabled. The tall form is a gap followed by, recursively, the
615−entire horn parser.
616−
617− ++ dub
618− %+ rail
619− ;~(plug sym ;~(pfix tis apex(tol |)))
620− ;~(pfix gap ;~(plug sym ;~(pfix gap apex)))
621−
622−This parses for the `/=` rune. It produces a term followed by a horn.
623−The wide form is a symbol name followed by a `=` and, recursively, the
624−entire horn parser with tall form disabled. The tall form is a gap
625−followed by a symbol name, another gap, and, recursively, the entire
626−horn parser.
627−
628− ++ fan
629− %+ rail fail
630− ;~(sfix (star ;~(pfix gap apex)) ;~(plug gap duz))
631−
632−This parses for the `/.` rune. It produces a list of horns. There is no
633−wide form. The tall form is a stet-terminated series of gap-separated
634−recursive calls to the entire horn parser.
635−
636− ++ for
637− %+ rail
638− ;~(plug (ifix [sel ser] hath) apex(tol |))
639− ;~(pfix gap ;~(plug hath ;~(pfix gap apex)))
640−
641−This parses for the `/,` rune. It produces a path and a horn. The wide
642−form is a `[`-`]`-surrounded path followed by, recursively, the entire
643−horn parser with tall form disabled. The tall form is a gap followed by
644−a path, another gap, and, recursively, the entire horn parser.
645−
646− ++ man
647− %+ rail fail
648− %- sear
649− :_ ;~(sfix (star ;~(pfix gap apex)) ;~(plug gap duz))
650− |= fan=(list ^horn)
651− =| naf=(list (pair term ^horn))
652− |- ^- (unit (map term ^horn))
653− ?~ fan (some (~(gas by *(map term ^horn)) naf))
654− ?. ?=(%dub -.i.fan) ~
655− $(fan t.fan, naf [[p.i.fan q.i.fan] naf])
656−
657−This parses for the `/*` rune. It produces a map of spans to horns.
658−There is no wide form. The tall form is a stet-terminated series of
659−gap-separated recursive calls to the entire horn parser. All produced
660−horns are expected to be from `/=` runes. The term and horn in each `/=`
661−horn is inserted into the produced map as a key-value pair.
662−
663− ++ saw
664− %+ rail
665− ;~(plug ;~(sfix wide:vez sem) apex(tol |))
666− ;~(pfix gap ;~(plug tall:vez ;~(pfix gap apex)))
667−
668−This parses for the `/;` rune. It produces a hoon and a horn. The wide
669−form is a wide-form hoon followed by a `;` and, recursively, the entire
670−horn parser with tall form disabled. The tall form is a gap followed by
671−a tall-form hoon, another gap, and, recursively, the entire horn parser.
672−
673− ++ see
674− %+ rail
675− ;~(plug ;~(sfix have col) apex(tol |))
676− ;~(pfix gap ;~(plug have ;~(pfix gap apex)))
677−
678−This parses for the `/:` rune. It produces a beam and a horn. The wide
679−form is a beam followed by a `;` and, recursively, the entire horn
680−parser with tall form disabled. The tall form is a gap followed by a
681−beam, another gap, and, recursively, the entire horn parser.
682−
683− ++ sic
684− %+ rail
685− ;~(plug ;~(sfix toil:vez ket) apex(tol |))
686− ;~(pfix gap ;~(plug howl:vez ;~(pfix gap apex)))
687− --
688−
689−This parses for the `/^` rune. It produces a tile and a horn. The wide
690−form is a wide-form tile, parsed with `++toil:vast`, followed by a `^`
691−and, recursively, the entire horn parser with tall form disabled. The
692−tall form is a gap followed by a tall-form tile, parsed with
693−`++howl:vast`, another gap, and, recursively, the entire horn parser.
694−
695−Assembling Hook Files
696−---------------------
697−
698−At this point, we've parsed a hook file into a hood. We will now
699−describe exactly how this hood is assembled into a vase. The problem of
700−assembling is handled entirely within the `++meow:zo:za` core.
701−
702− ++ meow :: assemble
703− |= [how=beam arg=heel]
704− =| $: rop=(map term (pair hoof hoon)) :: structure/complex
705− zog=(set term) :: structure guard
706− bil=(map term (pair hoof hoon)) :: libraries known
707− lot=(list term) :: library stack
708− zeg=(set term) :: library guard
709− boy=(list hoon) :: body stack
710− hol=? :: horns allowed?
711− ==
712− |%
713−
714−We take two arguments and keep seven pieces of state. `how` is the
715−location of the hook file we're assembling, and `arg` is the heel, or
716−virtual path extension, of the file.
717−
718−In `rop`, we maintain a map of terms to pairs of hooves and hoons to
719−represent the structures we've encountered that we will put together in
720−a core at the top of the file.
721−
722−In `zog`, we maintain the set of structures we're in the middle of
723−loading. If we try to load a structure already in our dependency
724−ancestry, then we fail because we do not allow circular dependencies.
725−This enforces that our structure dependency graph is a DAG.
726−
727−In `bil`, we maintain a map of terms to pairs of hooves and hoons to
728−represent the libraries we've encountered that we will put together in a
729−series of cores after the structure core.
730−
731−In `lot`, we maintain a stack of library names as they are encountered
732−during a depth-first search. More precisely, we push a library onto the
733−stack after we've processed all its children. Thus, every library
734−depends only on things deeper in the list. The libraries must be loaded
735−in the reverse of this order. Concisely, this is a topological sort of
736−the library dependency partial ordering.
737−
738−In `zeg`, we maintain the set of libraries we're in the middle of
739−loading. If we try to load a library already in our dependency ancestry,
740−then we fail because we do not allow circular dependencies. This
741−enforces that our library dependency graph is a DAG.
742−
743−In `boy`, we maintain a stack of body hoons, which we'll put together in
744−a series of cores at the end of the file.
745−
746−In `hol`, we decide if we're allowed to contain horns. Libraries and
747−structures are not allowed to contain horns.
748−
749−We in every case enter `++meow` through `++abut`. You'll notice that
750−there are four (count 'em, four!) calls to `++cope` in `++abut`. If
751−you've glanced at the ford code in general, you've probably seen cope
752−over and over. It is called in 79 different places. We need to discuss
753−the use of this critical function in detail, so we may as well do it
754−here.
755−
756− ++ cope :: bolt along
757− |* [hoc=(bolt) fun=(burg)]
758− ?- -.q.hoc
759− %2 hoc
760− %1 hoc
761− %0 =+ nuf=(fun p.hoc q.q.hoc)
762− :- p=p.nuf
763− ^= q
764− ?- -.q.nuf
765− %2 q.nuf
766− %1 q.nuf
767− %0 [%0 p=(grom `_p.q.nuf`p.q.hoc p.q.nuf) q=q.q.nuf]
768− == ==
769−
770−In monad-speak, this is the bind operator for the bolt monad. If monads
771−aren't your thing, don't worry, we're going to explain the use of cope
772−without further reference to them.
773−
774−Recall that there are three different types of bolt. A `%2` error bolt
775−contains a list of tanks describing the error, a `%1` block bolt
776−contains a set of resources we're blocked on, and a `%0` value bolt
777−contains an actual value and the set of its dependencies.
778−
779−We most commonly want to perform an operation on the value in a bolt if
780−it is a `%0` bolt. If it's not a `%0` bolt, we want to leave it alone.
781−This requires us to write a certain amount of boilerplate between each
782−of our operations to see if any of them produced a `%1` or a `%2` bolt.
783−This gets tiresome, so we pull it out into a separate arm and call it
784−`++cope`.
785−
786−Intuitively, we're calling the function `fun` with the value in `hoc`,
787−where `fun` takes an argument of type whatever is the value in a `%0`
788−case of `hoc`, and it produces a bolt of some (possibly different) type.
789−For brevity, we will refer to the type of the of the value in the `%0`
790−case of a bolt as the "type of the bolt".
791−
792−If the `hoc` bolt we're given as input to `fun` is already a `%1` or a
793−`%2` bolt, then we simply produce that. We don't even try to run `fun`
794−on it.
795−
796−Otherwise, we run `fun` with the arguments from the bolt and, if it
797−produces a `%1` or a `%2` bolt, we simply produce that. If it produces a
798−`%0` bolt, then we produce that with the old set of dependencies merged
799−in with the new set.
800−
801−We'll see more about how the bolt monad works as we run into more
802−interesting uses of it. For now, this is sufficient to move on with
803−`++abut`.
804−
805− ++ abut :: generate
806− |= [cof=cafe hyd=hood]
807− ^- (bolt vase)
808− %+ cope (apex cof hyd)
809− |= [cof=cafe sel=_..abut]
810− =. ..abut sel
811− %+ cope (maim cof pit able)
812− |= [cof=cafe bax=vase]
813− %+ cope (chap cof bax [%fan fan.hyd])
814− |= [cof=cafe gox=vase]
815− %+ cope (maim cof (slop gox bax) [%tssg (flop boy)])
816− |= [cof=cafe fin=vase]
817− (fine cof fin)
818−
819−Our job is simple: we must assemble a hood file into a vase. Hopefully,
820−the usage of `++cope` is fairly understandable. The correct way to read
821−this is that it does essentially five things.
822−
823−First, we call `++apex` to process the structures, libraries, and body.
824−This changes our state, so we set our context to the produced context.
825−Second, we call `++able` to assemble the strucutres and libraries into a
826−hoon, which we slap against zuse with `++maim`. Third, we call `++chap`
827−to process the resources in the context of the already-loaded structures
828−and libraries. Fourth, we slap the body against the structures,
829−libraries, and resources. Fifth and finally, we produce the resultant
830−vase.
831−
832− ++ apex :: build to body
833− |= [cof=cafe hyd=hood]
834− ^- (bolt ,_..apex)
835− ?. |(hol ?=(~ fan.hyd))
836− %+ flaw cof :_ ~ :- %leaf
837− "horns not allowed in structures and libraries: {<[how arg]>}"
838− %+ cope (body cof src.hyd)
839− |= [cof=cafe sel=_..apex]
840− =. ..apex sel
841− %+ cope (neck cof lib.hyd)
842− |= [cof=cafe sel=_..apex]
843− =. ..apex sel(boy boy)
844− %+ cope (head cof sur.hyd)
845− |= [cof=cafe sel=_..apex]
846− (fine cof sel)
847−
848−First, we make sure that if we're not allowed to have horns, we don't.
849−Otherwise, we produce and error with `++flaw`.
850−
851− ++ flaw |=([a=cafe b=(list tank)] [p=a q=[%2 p=b]]) :: bolt from error
852−
853−This produces a `%2` error bolt from a list of tanks. Fairly trivial.
854−
855−We should be starting to get used to the cope syntax, so we can see that
856−we really only do three things here. We process the body with `++body`,
857−the libraries with `++neck`, and the structures with `++head`.
858−
859− ++ body :: produce functions
860− |= [cof=cafe src=(list hoop)]
861− ^- (bolt _..body)
862− ?~ src (fine cof ..body)
863− %+ cope (wilt cof i.src)
864− |= [cof=cafe sel=_..body]
865− ^$(cof cof, src t.src, ..body sel)
866−
867−We must process a list of hoops that represent our body. If there are no
868−more hoops, we just produce our context in a `%0` bolt with `++fine`.
869−
870− ++ fine |* [a=cafe b=*] :: bolt from data
871− [p=`cafe`a q=[%0 p=*(set beam) q=b]] ::
872−
873−In monad-speak, this is the return operator. For us, this just means
874−that we're producing a `%0` bolt, which contains a path and a set of
875−dependencies. We assume there are no dependencies for the given data, or
876−that they will be added later.
877−
878−If there are more hoops in `++body`, we call `++wilt` to process an
879−individual hoop and recurse.
880−
881− ++ wilt :: process body entry
882− |= [cof=cafe hop=hoop]
883− ^- (bolt _..wilt)
884− ?- -.hop
885− %& (fine cof ..wilt(boy [p.hop boy]))
886− %|
887− %+ cool |.(leaf/"ford: wilt {<[(tope p.hop)]>}")
888− %+ cope (lend cof p.hop)
889− |= [cof=cafe arc=arch]
890− ?: (~(has by r.arc) %hoon)
891− %+ cope (fade cof %hoon p.hop)
892− |= [cof=cafe hyd=hood]
893− %+ cope (apex(boy ~) cof hyd)
894− |= [cof=cafe sel=_..wilt]
895− (fine cof sel(boy [[%tssg boy.sel] boy]))
896− =+ [all=(lark (slat %tas) arc) sel=..wilt]
897− %+ cope
898− |- ^- (bolt (pair (map term foot) _..wilt))
899− ?~ all (fine cof ~ ..wilt)
900− %+ cope $(all l.all)
901− |= [cof=cafe lef=(map term foot) sel=_..wilt]
902− %+ cope ^$(all r.all, cof cof, sel sel)
903− |= [cof=cafe rig=(map term foot) sel=_..wilt]
904− %+ cope
905− %= ^^^^$
906− cof cof
907− ..wilt sel(boy ~)
908− s.p.hop [p.n.all s.p.hop]
909− ==
910− |= [cof=cafe sel=_..wilt]
911− %+ fine cof
912− [`(map term foot)`[[p.n.all [%ash [%tssg boy.sel]]] lef rig] sel]
913− |= [cof=cafe mav=(map term foot) sel=_..wilt]
914− ?~ mav
915− (flaw cof [%leaf "source missing: {<(tope p.hop)>}"]~)
916− (fine cof sel(boy [[%brcn mav] boy]))
917− ==
918−
919−In the case of a direct hoon hoop, we just push it onto `boy` and we're
920−done. In the case of an indirect hoop, we must compile the referenced
921−file.
922−
923−First, we push onto the stack trace a message indicating which file
924−exactly we're compiling at the moment with `++cool`.
925−
926− ++ cool :: error caption
927− |* [cyt=trap hoc=(bolt)]
928− ?. ?=(%2 -.q.hoc) hoc
929− [p.hoc [%2 *cyt p.q.hoc]]
930−
931−If an error occurred in computing `hoc`, we put the bunt of `cyt` onto
932−the stack trace. Thus, `cyt` is not evaluated at all unless an error
933−occurred.
934−
935−Next in `++wilt`, we load the information about the filesystem node
936−referenced by the hoop with `++lend`.
937−
938− ++ lend :: load arch
939− |= [cof=cafe bem=beam]
940− ^- (bolt arch)
941− =+ von=(ska %cy (tope bem))
942− ?~ von [p=cof q=[%1 [bem ~] ~ ~]]
943− (fine cof ((hard arch) (need u.von)))
944−
945−This is a simple call to the namespace. If the resource does not yet
946−exist, we block on it by producing a `%1` bolt. Otherwise, we cast it to
947−an arch and produce this.
948−
949−Continuing in `++wilt`, we examine the produced arch. If the referenced
950−filesystem node has a `hoon` child node, then we've found the required
951−source, so we parse it with `++fade`. Recall that we referred earlier to
952−`++fade`. The salient point there is that it takes a beam, reads in the
953−hook file there, and parses it into a hood file with `++fair`.
954−
955−Now, we simply recurse on `++apex` to compile the new hood. Note that,
956−while we do clear the `boy` list, we do not clear the other lists. Thus,
957−we are accumulating all the structures and libraries referenced in all
958−the referenced hook files in one group, which we will put at the top of
959−the product.
960−
961−After this, we put the new list of body hoons into a `=~`, push this
962−onto our old list of body hoons, and produce the result.
963−
964−If there is no hoon file here, then we descend into each of our children
965−until we find a hoon file. First, we produce a list of all our children
966−whose names are terms with `++lark`.
967−
968− ++ lark :: filter arch names
969− |= [wox=$+(span (unit ,@)) arc=arch]
970− ^- (map ,@ span)
971− %- ~(gas by *(map ,@ span))
972− =| rac=(list (pair ,@ span))
973− |- ^+ rac
974− ?~ r.arc rac
975− =. rac $(r.arc l.r.arc, rac $(r.arc r.r.arc))
976− =+ gib=(wox p.n.r.arc)
977− ?~(gib rac [[u.gib p.n.r.arc] rac])
978−
979−We traverse the children map of `arc` to filter out those children whose
980−names aren't accepted by `wox` and produce a map from the product of
981−`wox` to the original name. `++lark` is used in many cases to parse
982−names into other types, like numbers or dates, ignoring those which do
983−not fit the format. In `++wilt`, though, we simply want to filter out
984−those children whose names are not terms.
985−
986−Next, we will produce a map from terms to feet. Each of these feet will
987−be placed in a core named by the child name, and it will contain arms
988−according to its children. Thus, if the indirect hoop references
989−`/path`, then to access the hoon defined in `/path/to/hoon/hoon`, our
990−body must refer to `hoon:to`.
991−
992−If there are no more children, then we are done, so we produce our
993−current context.
994−
995−Else, we recurse into the left and right sides of our map. Finally, we
996−process our current entry in the map. We first recurse by calling
997−`++wilt` one level down. Thus, in the previous example, the first time
998−we get to this point we are processing `/path`, so we recurse on
999−`++wilt` with path `/path/to`. We also remove our current body from the
1000−recursion, so that we may add it back in later the way we want to.
1001−
1002−After recursing, we push the new body onto our map, keyed by its name.
1003−We also produce the new context so that all external structures,
1004−libraries, and resources are collected into the same place.
1005−
1006−Finally, we have a map of names to feet. If this map is empty, then
1007−there were no hoons at the requested path, so we give an error with
1008−`++flaw`.
1009−
1010−If the map is nonempty, then we finally produce our context with with
1011−one thing pushed onto the front: a core made out of the map we just
1012−produced.
1013−
1014−This concludes our discussion of `++wilt` and `++body`. Thus, it remains
1015−in `++apex` to discuss `++neck` and `++head`.
1016−
1017− ++ neck :: consume libraries
1018− |= [cof=cafe bir=(list hoof)]
1019− ^- (bolt ,_..neck)
1020− ?~ bir (fine cof ..neck)
1021− ?: (~(has in zeg) p.i.bir)
1022− (flaw cof [%leaf "circular library dependency: {<i.bir>}"]~)
1023− =+ gez=(~(put in zeg) p.i.bir)
1024− =+ byf=(~(get by bil) p.i.bir)
1025− ?^ byf
1026− ?. =(`hoof`i.bir `hoof`p.u.byf)
1027− (flaw cof [%leaf "library mismatch: {<~[p.u.byf i.bir]>}"]~)
1028− $(bir t.bir)
1029− =+ bem=(hone %core %lib i.bir)
1030− %+ cope (fade cof %hook bem)
1031− |= [cof=cafe hyd=hood]
1032− %+ cope (apex(zeg gez, hol |, boy ~) cof hyd)
1033− |= [cof=cafe sel=_..neck]
1034− =. ..neck
1035− %= sel
1036− zeg zeg
1037− hol hol
1038− lot [p.i.bir lot]
1039− bil (~(put by bil) p.i.bir [i.bir [%tssg (flop boy.sel)]])
1040− ==
1041− ^^$(cof cof, bir t.bir)
1042−
1043−Here, we're going to consume the list of libraries and place them in
1044−`bil`. If there are no more libraries, we're done, so we just produce
1045−our current context.
1046−
1047−Otherwise, we check to see if the next library in the list is in `zeg`.
1048−If so, then this library is one of the libraries that we're already in
1049−the middle of compiling. There is a circular dependency, so we fail.
1050−
1051−Otherwise, we let `gez` be `zeg` plus the current library so that while
1052−compiling the dependencies of this library we don't later create a
1053−circular dependency. We check next to see if this library is alredy in
1054−`bil`. If so, then we have already included this library earlier, so we
1055−check to see if this is the same version of the library as we included
1056−earlier. If so, we skip it. Else, we fail since we can't include two
1057−different versions of a library. We really should allow for newer
1058−versions of a library since in kelvin versioning we assume backwards
1059−compatibility, but for now we require an exact match.
1060−
1061−If we haven't already included this library, then we're going to do
1062−that. First, we get the location of the library with `++hone`.
1063−
1064− ++ hone :: plant hoof
1065− |= [for=@tas way=@tas huf=hoof]
1066− ^- beam
1067− ?~ q.huf
1068− how(s ~[for p.huf way])
1069− [[q.u.q.huf %main p.u.q.huf] ~[for p.huf way]]
1070−
1071−If we haven't specified the version of the library, we use the current
1072−ship, desk, and case. Otherwise, we use the given ship and case on desk
1073−`%main`. In either case, the path is `/way/p.huf/for`. In the case of
1074−`++neck`, this means `/lib/core/[library name]`.
1075−
1076−In `++neck`, we next compile the hook file at that location with
1077−`++fade`. Again, we will delay the discussion of `++fade`, noting only
1078−that it takes a beam and parses the hook file there into a hood.
1079−
1080−We recurse on this to compile the library. During the compilation, we
1081−let `zeg` be `gez` to avoid circular dependencies, we let `hol` be false
1082−since we don't allow horns in libraries, and we let `boy` be null so
1083−that we can isolate the new body hoons.
1084−
1085−Next, we reintegrate the new data into our context. We use the context
1086−created by the recursion with four changes. First, we reset `zeg` to our
1087−old `zeg`. Second, we reset `hol` to our old `hol`. Third, we put the
1088−name of our library onto the stack of libraries. This means all of a
1089−libraries dependencies will be earlier in `lot` than the library itself,
1090−making `lot` a topological ordering on the dependency graph. Fourth, we
1091−put in `bil` the library hoof and body (with all body hoons collected in
1092−a `=~`), keyed by the library name.
1093−
1094−Finally, we recurse, processing the next library in our list.
1095−
1096−To complete our disucssion of `++apex`, we must process our structures.
1097−
1098− ++ head :: consume structures
1099− |= [cof=cafe bir=(list hoot)]
1100− |- ^- (bolt ,_..head)
1101− ?~ bir
1102− (fine cof ..head)
1103− ?: (~(has in zog) p.q.i.bir)
1104− (flaw cof [%leaf "circular structure dependency: {<i.bir>}"]~)
1105− =+ goz=(~(put in zog) p.q.i.bir)
1106− =+ byf=(~(get by rop) p.q.i.bir)
1107− ?^ byf
1108− ?. =(`hoof`q.i.bir `hoof`p.u.byf)
1109− (flaw cof [%leaf "structure mismatch: {<~[p.u.byf q.i.bir]>}"]~)
1110− $(bir t.bir)
1111− =+ bem=(hone ?:(p.i.bir %gate %core) %sur q.i.bir)
1112− %+ cope (fade cof %hook bem)
1113− |= [cof=cafe hyd=hood]
1114− %+ cope (apex(zog goz, hol |, boy ~) cof hyd)
1115− |= [cof=cafe sel=_..head]
1116− ?. =(bil bil.sel)
1117− (flaw cof [%leaf "structures cannot include libraries: {<i.bir>}"]~)
1118− =. ..head
1119− %= sel
1120− boy ?: p.i.bir
1121− boy
1122− (welp boy [[[%cnzy p.q.i.bir] [%$ 1]] ~])
1123− zog zog
1124− hol hol
1125− rop %+ ~(put by (~(uni by rop) rop.sel))
1126− p.q.i.bir
1127− [q.i.bir [%tssg (flop boy.sel)]]
1128− ==
1129− ^^$(cof cof, bir t.bir)
1130−
1131−The processing of our structures is very similar to that of our
1132−libraries. For clarity, we'll use many of the same phrases in describing
1133−the parallel natures. First, we check to see if there are more
1134−structures to process. If not, we're done, so we produce our context.
1135−
1136−Otherwise, we let `goz` be `zog` plus the current structure so that
1137−while compiling the dependencies of this structure we don't later create
1138−a circular dependency. We check next to see if this structure is already
1139−in `rop`. If so, then we have already included this structure earlier,
1140−so we check to see if this is the same version of the structure as we
1141−included earlier. If so, we skip it. Else, we fail since we can't
1142−include two different versions of a structure.
1143−
1144−If we haven't loaded this structure, then we call `++hone` to get the
1145−beam where the file structure should be. If the loobean in the hoot is
1146−true, then we're looking for a gate; otherwise, we're looking for a
1147−core. We parse this file with `++fade`.
1148−
1149−Now, we recurse on this to compile the structure. During the recursion,
1150−there we have three changes. Frist, we let `zog` be `goz` so that we
1151−don't create a circular dependency. Second, we let `hol` be false since
1152−we do not allow horns in structures. Third, we let `boy` be null so that
1153−we can isolate the new body hoons.
1154−
1155−Next, we reintegrate the new data into our context. We use the context
1156−cretaed by the recursion with four changes. First, if we're including a
1157−gate structure, then we reset the body to its original body. Else we put
1158−on the top of our list of body hoons what is essentially a
1159−`=+ structure-name` to take off the face of the structure. Second, we
1160−reset `zog` to our old `zog`. Third, we reset `hol` to our old `hol`.
1161−Finally, we put in `rop` the structure hoof and body (with all body
1162−hoongs collected in a `=~`), keyed by the structure name.
1163−
1164−Finally, we recurse, processing the next structure in our list.
1165−
1166−This concludes our discussion of `++apex`.
1167−
1168− ++ abut :: generate
1169− |= [cof=cafe hyd=hood]
1170− ^- (bolt vase)
1171− %+ cope (apex cof hyd)
1172− |= [cof=cafe sel=_..abut]
1173− =. ..abut sel
1174− %+ cope (maim cof pit able)
1175− |= [cof=cafe bax=vase]
1176− %+ cope (chap cof bax [%fan fan.hyd])
1177− |= [cof=cafe gox=vase]
1178− %+ cope (maim cof (slop gox bax) [%tssg (flop boy)])
1179− |= [cof=cafe fin=vase]
1180− (fine cof fin)
1181−
1182−Returning to `++abut`, we have now processed the structures, libraries
1183−and body hoons. Next, we slap our preamble (structures and libraries)
1184−against zuse. First, we construct our preamble in `++able`.
1185−
1186− ++ able :: assemble preamble
1187− ^- hoon
1188− :+ %tsgr
1189− ?:(=(~ rop) [%$ 1] [%brcn (~(run by rop) |=([* a=hoon] [%ash a]))])
1190− [%tssg (turn (flop lot) |=(a=term q:(need (~(get by bil) a))))]
1191−
1192−We first put the structures in `rop` into a single `|%` at the top and
1193−`=>` it onto a `=~` of our libraries, in the reverse order that they
1194−appear in `lot`. Thus, the structures are in a single core while the
1195−libraries are in consecutive cores.
1196−
1197−We slap the preamble against zuse with `++maim`.
1198−
1199− ++ maim :: slap
1200− |= [cof=cafe vax=vase gen=hoon]
1201− ^- (bolt vase)
1202− %+ (clef %slap) (fine cof vax gen)
1203− |= [cof=cafe vax=vase gen=hoon]
1204− =+ puz=(mule |.((~(mint ut p.vax) [%noun gen])))
1205− ?- -.puz
1206− | (flaw cof p.puz)
1207− & %+ (coup cof) (mock [q.vax q.p.puz] (mole ska))
1208− |= val=*
1209− `vase`[p.p.puz val]
1210− ==
1211−
1212−Here we start to get into ford's caching system. We wrap our computation
1213−in a call to `++clef` so that we only actually compute it if the result
1214−is not already in our cache. First we'll discuss the computation, then
1215−we'll discuss the caching system.
1216−
1217−We call `++mule` with a call to `++mint:ut` on the type of our subject
1218−vase against the given hoon. In other words, we're compiling the hoon
1219−with against the subject type in the given subject vase.
1220−
1221−If compilation fails, then we produce an error bolt with the produced
1222−stack trace. Otherwise, we run the produced nock with `++mock` and our
1223−sky function. We convert the produced toon to a bolt with `++coup` and
1224−use the type from `puz` combined with the value from `mock` to produce
1225−our vase.
1226−
1227−If this process seems harder than just calling `++slap`, it's because it
1228−is. We have two requirements that `++slap` doesn't satisfy. First, we
1229−want the to use an explicit sky function for use with `.^`. With
1230−`++slap`, you get whatever sky function is available in the calling
1231−context, which in ford is none. Second, we want to explicitly handle the
1232−stack trace on failure. `++slap` would cause crash on failure.
1233−
1234−We haven't yet discussed either `++clef` or `++coup`. We'll start with
1235−`++coup` to finish the discussion of the computation.
1236−
1237−\``++ coup :: toon to bolt |= cof=cafe |* [ton=toon fun=$+(* *)] :- p=cof ^= q ?- -.ton %2 [%2 p=p.ton] %0 [%0 p=*(set beam) q=(fun p.ton)] %1 ~& [%coup-need ((list path) p.ton)] =- ?- -.faw & [%1 p=(sa (turn p.faw |=(a=beam [a *(list tank)])))] | [%2 p=p.faw] == ^= faw |- ^- (each (list beam) (list tank)) ?~ p.ton [%& ~] =+ nex=$(p.ton t.p.ton) =+ pax=(path i.p.ton) ?~ pax [%| (smyt pax) ?:(?=(& -.nex) ~ p.nex)] =+ zis=(tome t.pax) ?~ zis [%| (smyt pax) ?:(?=(& -.nex) ~ p.nex)] ?- -.nex & [%& u.zis p.nex] | nex == ==`
1238−
1239−Recall that a toon is either a `%0` value, a `%1` block, or a `%2`
1240−failure. Converting a `%2` toon failure into a `%2` bolt failure is
1241−trivial. Converting a `%0` toon value into a `%0` bolt value is easy
1242−since we assume there were no dependencies. Converting the blocks is
1243−rather more difficult.
1244−
1245−To compute `faw`, we recurse through the list of paths in the `%1` toon.
1246−At each one, we make sure with `++tome` that it is, in fact, a beam. If
1247−so, then we check to see if the later paths succeed as well. If so, we
1248−append the current path to the list of other paths. If not, we produce
1249−the error message we got from processing the rest of the paths. If this
1250−path is not a beam, then we fail, producing a list of tanks including
1251−this path and, if later paths fail too, those paths as well.
1252−
1253−If some paths were not beams, then we produce a `%2` error bolt. If all
1254−paths were correct, then we produce a `%1` blocking bolt.
1255−
1256−We will now discuss `++clef`. This is where the cache magic happens.
1257−
1258− ++ clef :: cache a result
1259− |* sem=*
1260− |* [hoc=(bolt) fun=(burg)]
1261− ?- -.q.hoc
1262− %2 hoc
1263− %1 hoc
1264− %0
1265− =^ cux p.hoc ((calk p.hoc) sem q.q.hoc)
1266− ?~ cux
1267− =+ nuf=(cope hoc fun)
1268− ?- -.q.nuf
1269− %2 nuf
1270− %1 nuf
1271− %0
1272− :- p=(came p.nuf `calx`[sem `calm`[now p.q.nuf] q.q.hoc q.q.nuf])
1273− q=q.nuf
1274− ==
1275− [p=p.hoc q=[%0 p=p.q.hoc q=((calf sem) u.cux)]]
1276− ==
1277−
1278−If the value is already an error or a block, we just pass that through.
1279−Otherwise, we look up the request in the cache with `++calk`.
1280−
1281− ++ calk :: cache lookup
1282− |= a=cafe ::
1283− |= [b=@tas c=*] ::
1284− ^- [(unit calx) cafe] ::
1285− =+ d=(~(get by q.a) [b c]) ::
1286− ?~ d [~ a] ::
1287− [d a(p (~(put in p.a) u.d))] ::
1288−
1289−When looking up something in the cache, we mark it if we find it. This
1290−way, we have in our cache the set of all cache entries that have been
1291−referenced. While we do not at present do anything with this data, it
1292−should be used to clear out old and unused entries in the cache.
1293−
1294−Moving on in `++clef`, we check to see if we actually found anything. If
1295−we didn't find a cache entry, then we run the computation in `fun`, and
1296−examine its result. If it produced a `%2` error or `%1` block bolt, we
1297−just pass that through. Otherwise, we produce both the value and an
1298−updated cache with this new entry. We add the entry with `++came`.
1299−
1300− ++ came ::
1301− |= [a=cafe b=calx] :: cache install
1302− ^- cafe ::
1303− a(q (~(put by q.a) [-.b q.b] b)) ::
1304−
1305−We key cache entries by the type of computation (`-:calx`) and the
1306−inputs to the computation (`q:calc`). This just puts the cache line in
1307−the cache at the correct key.
1308−
1309−Back in `++clef`, if we did find a cache entry, then we just produce the
1310−value at that cache line. We convert the cache line into a value with
1311−`++calf`.
1312−
1313− ++ calf :: reduce calx
1314− |* sem=* :: a typesystem hack
1315− |= cax=calx
1316− ?+ sem !!
1317− %hood ?>(?=(%hood -.cax) r.cax)
1318− %slap ?>(?=(%slap -.cax) r.cax)
1319− %slam ?>(?=(%slam -.cax) r.cax)
1320− ==
1321−
1322−This is simply a typesystem hack. Because the `sem` is passed in through
1323−a wet gate, we know at type time which of the three cases will be
1324−chosen. Thus, the correct type of the value in the cache line gets
1325−passed through to the caller. This also depends on the fact that
1326−`++clef` is wet. The type stuff here is mathematically interesting, but
1327−the action is simple: we get the value from the cache line.
1328−
1329−This concludes our discussion of `++clef` and `++maim`.
1330−
1331−Back in `++abut`, recall that we processed the structures, libraries,
1332−and body with `++apex`. Then, we slapped our preamble (structures and
1333−libraries) against zuse with `++maim`. Next, we process our resources
1334−with `++chap`. Note that we pass in the preamble so that we may refer to
1335−anything in there in our resources.
1336−
1337−`++chap` is broken up into a different case for each horn. We'll go
1338−through them one by one.
1339−
1340− ++ chap :: produce resources
1341− |= [cof=cafe bax=vase hon=horn]
1342− ^- (bolt vase)
1343− ?- -.hon
1344− %ape (maim cof bax p.hon)
1345−
1346−This is `/~`. We slap the hoon against our context.
1347−
1348− %arg
1349− %+ cope (maim cof bax p.hon)
1350− |= [cof=cafe gat=vase]
1351− (maul cof gat !>([how arg]))
1352−
1353−This is `/$`. We slap the hoon against our context, which we expect to
1354−produce a gate. We slam this gate with a sample of `how` and `arg`,
1355−which is our location and the heel (virtual path extension).
1356−
1357−`++maul` is similar to `++maim`, but it slams instead of slaps.
1358−
1359− ++ maul :: slam
1360− |= [cof=cafe gat=vase sam=vase]
1361− ^- (bolt vase)
1362− %+ (clef %slam) (fine cof gat sam)
1363− |= [cof=cafe gat=vase sam=vase]
1364− =+ top=(mule |.((slit p.gat p.sam)))
1365− ?- -.top
1366− | (flaw cof p.top)
1367− & %+ (coup cof) (mong [q.gat q.sam] (mole ska))
1368− |= val=*
1369− `vase`[p.top val]
1370− ==
1371−
1372−We cache slams exactly as we cache slaps. We use `++slit` to find the
1373−type of the product of the slam given the types of the gate and the
1374−sample.
1375−
1376−If this type fails, we produce the given stack trace as a `%2` error
1377−bolt. Otherwise, we produce the top produced above combined with the
1378−value we get from slamming the values in the vases with `++mong`.
1379−
1380−Back to `++chap`.
1381−
1382− %day (chad cof bax %dr p.hon)
1383−
1384−This is `/|`. We call `++chad` to convert textual names to relative
1385−dates and process the next horn against each of the discovered paths.
1386−
1387− ++ chad :: atomic list
1388− |= [cof=cafe bax=vase doe=term hon=horn]
1389− ^- (bolt vase)
1390− %+ cope ((lash (slat doe)) cof how)
1391− |= [cof=cafe yep=(map ,@ span)]
1392− =+ ^= poy ^- (list (pair ,@ span))
1393− %+ sort (~(tap by yep) ~)
1394− |=([a=[@ *] b=[@ *]] (lth -.a -.b))
1395− %+ cope
1396− |- ^- (bolt (list (pair ,@ vase)))
1397− ?~ poy (fine cof ~)
1398− %+ cope $(poy t.poy)
1399− |= [cof=cafe nex=(list (pair ,@ vase))]
1400− %+ cope (chap(s.how [q.i.poy s.how]) cof bax hon)
1401− |= [cof=cafe elt=vase]
1402− (fine cof [[p.i.poy elt] nex])
1403− |= [cof=cafe yal=(list (pair ,@ vase))]
1404− %+ fine cof
1405− |- ^- vase
1406− ?~ yal [[%cube 0 [%atom %n]] 0]
1407− (slop (slop [[%atom doe] p.i.yal] q.i.yal) $(yal t.yal))
1408−
1409−First, we call `++lash` to parse the children of the current beam and
1410−pick out those ones that are of the requested format.
1411−
1412− ++ lash :: atomic sequence
1413− |= wox=$+(span (unit ,@))
1414− |= [cof=cafe bem=beam]
1415− ^- (bolt (map ,@ span))
1416− %+ cope (lend cof bem)
1417− |= [cof=cafe arc=arch]
1418− (fine cof (lark wox arc))
1419−
1420−First, we get the arch with `++lend`, as described above. We filter and
1421−parse the child names with `++lark` according to the given parser
1422−function.
1423−
1424−In `++chad`, this parser function is `(slat doe)`, which will parse a
1425−cord into an atom of the requested odor. For `%day` the odor is for
1426−relative dates.
1427−
1428−Thus, we now have a map from atoms of the given odor to the actual child
1429−names. We next turn this map into a list and sort it in increasing order
1430−by the atom.
1431−
1432−We next convert this list of pairs of atoms and spans to a list of pairs
1433−of atoms and vases. We process the given horn once at every child beam,
1434−producing the resource at that location.
1435−
1436−Finally, we convert this list of pairs of atoms and vases to a vase of a
1437−list of pairs of atoms to (well-typed) values. Each entry in the list is
1438−of type atom with the given odor combined with the type of the produced
1439−vase.
1440−
1441−Back in `++chap`, we continue parsing resources.
1442−
1443− %dub
1444− %+ cope $(hon q.hon)
1445− |= [cof=cafe vax=vase]
1446− (fine cof [[%face p.hon p.vax] q.vax])
1447−
1448−This is `/=`. We process the given horn, giving us a vase. We put as a
1449−face on the vase so that it may be referred to later by name.
1450−
1451− %fan
1452− %+ cope
1453− |- ^- (bolt (list vase))
1454− ?~ p.hon (fine cof ~)
1455− %+ cope ^$(hon i.p.hon)
1456− |= [cof=cafe vax=vase]
1457− %+ cope ^$(cof cof, p.hon t.p.hon)
1458− |= [cof=cafe tev=(list vase)]
1459− (fine cof [vax tev])
1460− |= [cof=cafe tev=(list vase)]
1461− %+ fine cof
1462− |- ^- vase
1463− ?~ tev [[%cube 0 [%atom %n]] 0]
1464− (slop i.tev $(tev t.tev))
1465−
1466−This is `/.`. We first process each of the child horns, producing a list
1467−of vases. This is done by just recursing on `++chap`. Then, we simply
1468−fold over this list to create a vase of the list of values.
1469−
1470− %for $(hon q.hon, s.how (weld (flop p.hon) s.how))
1471−
1472−This is `/,`. We simply recurse on the horn with the given path welded
1473−onto our current beam.
1474−
1475− %hub (chad cof bax %ud p.hon)
1476−
1477−This is `/@`. This is exactly like the processing of `%day` except we
1478−expect the children to be named as unsigned integers rather than
1479−relative dates. We process the horn at each of the children's locations
1480−and produce a list of pairs of absolute dates and values.
1481−
1482− %man
1483− |- ^- (bolt vase)
1484− ?~ p.hon (fine cof [[%cube 0 [%atom %n]] 0])
1485− %+ cope $(p.hon l.p.hon)
1486− |= [cof=cafe lef=vase]
1487− %+ cope ^$(cof cof, p.hon r.p.hon)
1488− |= [cof=cafe rig=vase]
1489− %+ cope ^^^$(cof cof, hon q.n.p.hon)
1490− |= [cof=cafe vax=vase]
1491− %+ fine cof
1492− %+ slop
1493− (slop [[%atom %tas] p.n.p.hon] vax)
1494− (slop lef rig)
1495−
1496−This is `/*`. We process each of the horns in the given map by recursion
1497−through `++chap`. Once we have these vases, we create a vase of a map
1498−from the given textual names to the produced values.
1499−
1500− %now (chad cof bax %da p.hon)
1501−
1502−This is `/&`. This is exactly like the processing of `%now` except we
1503−expect the children to be names as absolute dates rather than relative
1504−dates. We process the horn at each of the children's locations and
1505−produce a list of pairs of absolute dates and values.
1506−
1507− %nap (chai cof bax p.hon)
1508−
1509−This is `/%`. Here, we process the horn at each of our children with
1510−`++chai`.
1511−
1512− ++ chai :: atomic map
1513− |= [cof=cafe bax=vase hon=horn]
1514− ^- (bolt vase)
1515− %+ cope (lend cof how)
1516− |= [cof=cafe arc=arch]
1517− %+ cope
1518− |- ^- (bolt (map ,@ vase))
1519− ?~ r.arc (fine cof ~)
1520− %+ cope $(r.arc l.r.arc)
1521− |= [cof=cafe lef=(map ,@ vase)]
1522− %+ cope `(bolt (map ,@ vase))`^$(cof cof, r.arc r.r.arc)
1523− |= [cof=cafe rig=(map ,@ vase)]
1524− %+ cope (chap(s.how [p.n.r.arc s.how]) cof bax hon)
1525− |= [cof=cafe nod=vase]
1526− (fine cof [[p.n.r.arc nod] lef rig])
1527− |= [cof=cafe doy=(map ,@ vase)]
1528− %+ fine cof
1529− |- ^- vase
1530− ?~ doy [[%cube 0 [%atom %n]] 0]
1531− %+ slop
1532− (slop [[%atom %a] p.n.doy] q.n.doy)
1533− (slop $(doy l.doy) $(doy r.doy))
1534−
1535−We get the arch at our current beam with `++lend`. Then, we process the
1536−horn at each of our children to give us a map of atoms to vases.
1537−Finally, we convert that into a vase of a map of these atoms to the
1538−values. This is very similar to `++chad` and the handling of `%man`.
1539−
1540− %see $(hon q.hon, how p.hon)
1541−
1542−This is `/:`. We process the given horn at the given beam.
1543−
1544− %saw
1545− %+ cope $(hon q.hon)
1546− |= [cof=cafe sam=vase]
1547− %+ cope (maim cof bax p.hon)
1548− |= [cof=cafe gat=vase]
1549− (maul cof gat sam)
1550−
1551−This is `/;`. First, we process the given horn. Then, we slap the given
1552−hoon against our context to produce (hopefully) a gate. Finally, we slam
1553−the vase we got from processing the horn against the gate.
1554−
1555− %sic
1556− %+ cope $(hon q.hon)
1557− |= [cof=cafe vax=vase]
1558− %+ cope (maim cof bax [%bctr p.hon])
1559− |= [cof=cafe tug=vase]
1560− ?. (~(nest ut p.tug) | p.vax)
1561− (flaw cof [%leaf "type error: {<p.hon>} {<q.hon>}"]~)
1562− (fine cof [p.tug q.vax])
1563−
1564−This is `/^`. First, we process the given horn. Then, we slap the the
1565−bunt of the given tile against our context. This will produce a vase
1566−with the correct type. We test to see if this type nests within the type
1567−of the vase we got from processing the horn. If so, we produce the value
1568−from the horn along with the type from the tile. Otherwise, we produce a
1569−`%2` error bolt.
1570−
1571− %toy (cope (make cof %bake p.hon how ~) feel)
1572− ==
1573−
1574−This is `/mark/`. Here, we simply run the `%bake` silk on the given
1575−mark, producing a cage. We convert this cage into a vase with `++feel`,
1576−which is exactly as simple as it sounds like it should be.
1577−
1578− ++ feel |=([a=cafe b=cage] (fine a q.b)) :: cage to vase
1579−
1580−This is trivial.
1581−
1582−We will discuss later `++make` and how `%bake` is processed. Suffice it
1583−to say that baking a resource with a given mark gets the resource and
1584−converts it, if necessary, to the requested mark.
1585−
1586−This concludes our discussion of `++chap`.
1587−
1588−We return once more to `++abut`.
1589−
1590− ++ abut :: generate
1591− |= [cof=cafe hyd=hood]
1592− ^- (bolt vase)
1593− %+ cope (apex cof hyd)
1594− |= [cof=cafe sel=_..abut]
1595− =. ..abut sel
1596− %+ cope (maim cof pit able)
1597− |= [cof=cafe bax=vase]
1598− %+ cope (chap cof bax [%fan fan.hyd])
1599− |= [cof=cafe gox=vase]
1600− %+ cope (maim cof (slop gox bax) [%tssg (flop boy)])
1601− |= [cof=cafe fin=vase]
1602− (fine cof fin)
1603−
1604−Recall that we processed our structures, libraries and body with
1605−`++apex`. We slapped our structures and libraries against zuse with
1606−`++maim`. We processed our resources with `++chap`. Now, all our body
1607−hoons are collected in a `=~` and slapped against our structures,
1608−libraries, and resources. This produces our final result.
1609−
1610−The hook file has been assembled. And there was great rejoicing.
1611−
1612−Lifecycle of a Kiss
1613−-------------------
1614−
1615−We're now going to go through a series of lifecycle descriptions. When a
1616−user of ford sends a kiss, it is one of a dozen different types of silk.
1617−We'll go through each one, tracing through the flow of control of each
1618−of these.
1619−
1620−First, though, we'll describe the common handling to all kisses.
1621−
1622−The silk in a `%exec` kiss to ford ends up in `++apex`, so we'll enter
1623−the narrative here.
1624−
1625− ++ apex :: call
1626− |= kus=(unit silk)
1627− ^+ +>
1628− ?~ kus
1629− =+ nym=(~(get by dym.bay) hen)
1630− ?~ nym :: XX should never
1631− ~& [%ford-mystery hen]
1632− +>.$
1633− =+ tas=(need (~(get by q.tad.bay) u.nym))
1634− amok:~(camo zo [u.nym tas])
1635− =+ num=p.tad.bay
1636− ?< (~(has by dym.bay) hen)
1637− =: p.tad.bay +(p.tad.bay)
1638− dym.bay (~(put by dym.bay) hen num)
1639− ==
1640− ~(exec zo [num `task`[hen u.kus 0 ~]])
1641−
1642−Recall that a `%exec` kiss actually sends a unit silk. If it's null,
1643−we're trying to cancel the request. We first look up the task number
1644−keyed by duct. If we don't find it, then we're trying to cancel a
1645−request that either was never started or has already completed. We print
1646−out `%ford-mystery` and do nothing. If we do find the task number, then
1647−we look up the task from it, call `++camo:zo` to cancel pending
1648−requests, and call `++amok:zo` to remove the task from our task lists.
1649−
1650− ++ camo :: stop requests
1651− ^+ .
1652− =+ kiz=(~(tap by q.kig) *(list ,[p=@ud q=beam]))
1653− |- ^+ +>
1654− ?~ kiz +>
1655− %= $
1656− kiz t.kiz
1657− mow :_ mow
1658− :- hen
1659− :^ %pass [(scot %p our) (scot %ud num) (scot %ud p.i.kiz) ~]
1660− %c
1661− [%warp [our p.q.i.kiz] q.q.i.kiz ~]
1662− ==
1663−
1664−Our list of blocks is in `q.kig`, so we iterate over it, cancelling our
1665−pending requests for each block. Our requests are all to clay, so we
1666−need only to send `%warp` kisses with a null instead of a rave.
1667−
1668− ++ amok
1669− %_ ..zo
1670− q.tad.bay (~(del by q.tad.bay) num)
1671− dym.bay (~(del by dym.bay) nah)
1672− ==
1673−
1674−We remove the task number from the map of numbers to tasks and the duct
1675−from the map of ducts to task numbers.
1676−
1677−Back in `++apex`, if we were given a silk, we need to process it. We add
1678−the task to our maps, increment the next task number, and call
1679−`++exec:zo` on the new task.
1680−
1681− ++ exec :: execute app
1682− ^+ ..zo
1683− ?: !=(~ q.kig) ..zo
1684− |- ^+ ..zo
1685− =+ bot=(make [~ jav.bay] kas)
1686− =. ..exec (dash p.bot)
1687− ?- -.q.bot
1688− %0 amok:(expo [%made %& p.q.bot q.q.bot])
1689− %2 amok:(expo [%made %| p.q.bot])
1690− %1 =+ zuk=(~(tap by p.q.bot) ~)
1691− =< abet
1692− |- ^+ ..exec
1693− ?~ zuk ..exec
1694− =+ foo=`_..exec`(camp %x `beam`p.i.zuk)
1695− $(zuk t.zuk, ..exec foo)
1696− ==
1697−
1698−If we're still blocked on something in `q.kig`, we don't do anything.
1699−
1700−Otherwise, we try to process the silk with `++make`. `++make` handles
1701−each individual request and will be the entire focus of the remainder of
1702−this doc after this section. It produces a bolt of a cage.
1703−
1704−We put the new cache in our state with `++dash`.
1705−
1706− ++ dash :: process cache
1707− |= cof=cafe
1708− ^+ +>
1709− %_(+> jav.bay q.cof)
1710−
1711−The cache is put in the baby so that it gets stored across calls to
1712−ford.
1713−
1714−In `++exec`, we process the bolt in three different ways according to
1715−the type of bolt produced. If we produced a `%0` value bolt, we use
1716−`++expo` to give the produced value and set of dependencies as a `%made`
1717−gift, and we remove ourselves from the task list with `++amok`.
1718−
1719− ++ expo :: return gift
1720− |= gef=gift
1721− %_(+> mow :_(mow [hen %give gef]))
1722−
1723−We simply push the gift onto our list of moves.
1724−
1725−In `++exec`, if we produced a `%2` error bolt, we produce a `%made` gift
1726−with the stack trace.
1727−
1728−If we produced a `%1` block bolt, we iterate through each of the blocks
1729−and call `++camp` to produce a clay request for the resource.
1730−
1731− ++ camp :: request a file
1732− |= [ren=care bem=beam]
1733− ^+ +>
1734− %= +>
1735− kig [+(p.kig) (~(put by q.kig) p.kig bem)]
1736− mow :_ mow
1737− :- hen
1738− :^ %pass [(scot %p our) (scot %ud num) (scot %ud p.kig) ~]
1739− %c
1740− [%warp [our p.bem] q.bem [~ %& %x r.bem s.bem]]
1741− ==
1742−
1743−We put the resource in our block list in `q.kig` so that we save the
1744−fact that we're blocked. We then produce the `%warp` request to clay for
1745−the resource. Our request path has the format
1746−\`/[our-ship]/[task-number]/[block-number]'.
1747−
1748−We'll now describe how each of the individual silks are processed in
1749−`++make`.
1750−
1751−Lifecycle of a Cell
1752−-------------------
1753−
1754− ^
1755− %. [cof p.kas q.kas]
1756− ;~ cope
1757− ;~ coax
1758− |=([cof=cafe p=silk q=silk] ^$(cof cof, kas p.kas))
1759− |=([cof=cafe p=silk q=silk] ^$(cof cof, kas q.kas))
1760− ==
1761− ::
1762− |= [cof=cafe bor=cage heg=cage] ^- (bolt cage)
1763− [p=cof q=[%0 ~ [%$ (slop q.bor q.heg)]]]
1764− ==
1765−
1766−Silks autocons. The product of a cell of silks is a cell of the products
1767−of the silks, so we evaluate the two silks in parallel with `++coax` and
1768−slop together the results in a cell vase. We mark the product with `%$`,
1769−which means we know no more mark information than that it is a noun.
1770−
1771− ++ coax :: bolt across
1772− |* [hoc=(bolt) fun=(burg)]
1773− ?- -.q.hoc
1774− %0 =+ nuf=$:fun(..+<- p.hoc)
1775− :- p=p.nuf
1776− ^= q
1777− ?- -.q.nuf
1778− %0 [%0 p=(grom p.q.hoc p.q.nuf) q=[q.q.hoc q.q.nuf]]
1779− %1 q.nuf
1780− %2 q.nuf
1781− ==
1782− %1 =+ nuf=$:fun(..+<- p.hoc)
1783− :- p=p.nuf
1784− ^= q
1785− ?- -.q.nuf
1786− %0 q.hoc
1787− %1 [%1 p=(grom p.q.nuf p.q.hoc)]
1788− %2 q.nuf
1789− ==
1790− %2 hoc
1791− ==
1792−
1793−If the first bolt is a value, we evaluate the burg to get the next bolt.
1794−If that also produces a value, we merge the dependency sets and produce
1795−a cell of the two values. Otherwise, we produce the block or error of
1796−the second bolt.
1797−
1798−If the first bolt is a block, we evaluate the burg to get the next bolt.
1799−If that produces a value, we just produce the block. If it produces a
1800−block, we merge the two block sets. If it produces an error, we produce
1801−that error.
1802−
1803−If the first bolt is already an error, we just pass that through.
1804−
1805−Note that `++coax` (and, indeed, `++cope`) is reasonable to use with
1806−`;~`.
1807−
1808−Lifecycle of a `%bake`
1809−----------------------
1810−
1811− %bake
1812− %+ cool |.(leaf/"ford: bake {<p.kas>} {<(tope q.kas)>}")
1813− %+ cope (lima cof p.kas q.kas r.kas)
1814− |= [cof=cafe vux=(unit vase)]
1815− ?~ vux
1816− (flaw cof (smyt (tope q.kas)) ~)
1817− (fine cof [p.kas u.vux])
1818−
1819−This is one of the most critical silks. We are going to functionally
1820−produce the hook file at the given beam with the given heel. The result
1821−will be of the correct mark, even if we need to run conversion
1822−functions. The functionality is encapsulated in `++lime`. If it produces
1823−null, then we produce an error. Otherwise, we take the vase produced and
1824−give it the correct mark.
1825−
1826− ++ lima :: load at depth
1827− |= [cof=cafe for=mark bem=beam arg=heel]
1828− ^- (bolt (unit vase))
1829− %+ cope (lend cof bem)
1830− |= [cof=cafe arc=arch]
1831− ^- (bolt (unit vase))
1832− ?: (~(has by r.arc) for)
1833− (lace cof for bem(s [for s.bem]) arg)
1834− =+ haz=(turn (~(tap by r.arc) ~) |=([a=@tas b=~] a))
1835− ?~ haz (fine cof ~)
1836− %+ cope (lion cof for -.bem haz)
1837− |= [cof=cafe wuy=(unit (list ,@tas))]
1838− ?~ wuy (fine cof ~)
1839− ?> ?=(^ u.wuy)
1840− %+ cope (make cof %bake i.u.wuy bem arg)
1841− |= [cof=cafe hoc=cage]
1842− %+ cope (lope cof i.u.wuy t.u.wuy -.bem q.hoc)
1843− |= [cof=cafe vax=vase]
1844− (fine cof ~ vax)
1845−
1846−First, we load the arch at the given beam with `++lend`. If we have a
1847−child named the mark, our job is straightforward, so we go ahead and
1848−load that with `++lace`.
1849−
1850−Otherwise, we iterate through our children. If we have no children, we
1851−produce null, signifying that we didn't find any way to convert to the
1852−requested mark. Otherwise, we call `++lion` to find a translation path
1853−from one of the available marks into the target mark. We recursively
1854−bake the child that has a path to the target mark, and then we call
1855−`++lope` to translate this mark into the target mark.
1856−
1857−We'll first discuss the direct case of when one of our children is of
1858−the correct mark.
1859−
1860− ++ lace :: load and check
1861− |= [cof=cafe for=mark bem=beam arg=heel]
1862− ^- (bolt (unit vase))
1863− =+ bek=`beak`[p.bem q.bem r.bem]
1864− %+ cope (lend cof bem)
1865− |= [cof=cafe arc=arch]
1866− ?^ q.arc
1867− (cope (cope (liar cof bem) (lake for bek)) fest)
1868− ?: (~(has by r.arc) %hook)
1869− %+ cope (fade cof %hook bem)
1870− |= [cof=cafe hyd=hood]
1871− (cope (cope (abut:(meow bem arg) cof hyd) (lake for bek)) fest)
1872− (fine cof ~)
1873−
1874−First, we get the arch at the given beam with `++lend`. If this is a
1875−file, we load the file with `++liar` and coerce the type with `++lake`.
1876−Otherwise, we check to see if we have a hook file here. If so, we parse
1877−it with `++fade`, compile it with `++abut:meow`, and coerce the type
1878−with `++lake`.
1879−
1880−Otherwise, there is no way to translate this, so we produce null.
1881−
1882−`++fest` is one line, so we'll get that one out of the way first.
1883−
1884− ++ fest |*([a=cafe b=*] (fine a [~ u=b])) :: bolt to unit
1885−
1886−This is just `++some` for bolts.
1887−
1888−We've delayed the discussion of `++fade` far too many times. It's not
1889−complicated, we just wanted to spare a premature discussion of `++make`
1890−and the `%bake` silk. We 're now able to discuss everything in `++fade`
1891−with ease.
1892−
1893− ++ fade :: compile to hood
1894− |= [cof=cafe for=mark bem=beam]
1895− ^- (bolt hood)
1896− %+ cool |.(leaf/"ford: fade {<[(tope bem)]>}")
1897− %+ cope (make cof [%bake for bem ~])
1898− |= [cof=cafe cay=cage]
1899− %+ (clef %hood) (fine cof bem cay)
1900− ^- (burg (pair beam cage) hood)
1901− |= [cof=cafe bum=beam cay=cage]
1902− =+ rul=(fair bem)
1903− ?. ?=(@ q.q.cay)
1904− (flaw cof ~)
1905− =+ vex=((full rul) [[1 1] (trip q.q.cay)])
1906− ?~ q.vex
1907− (flaw cof [%leaf "syntax error: {<p.p.vex>} {<q.p.vex>}"] ~)
1908− (fine cof p.u.q.vex)
1909−
1910−We first push a line onto a stack trace to say that we're parsing into a
1911−hood file.
1912−
1913−We bake the given beam with the given mark and no heel. Recall that
1914−baking gate, core, door, hoon, and hook files produces simply an atom of
1915−the text. We check to make sure that our value is an atom, failing
1916−otherwise.
1917−
1918−The parsing step is run within `++clef` so that the result is cached. We
1919−call `++fair` with the current beam to generate the parsing rule, and we
1920−parse the file. If parsing fails, we fail giving a syntax error with the
1921−line and column number. Otherwise, we produce the value.
1922−
1923− ++ liar :: load vase
1924− |= [cof=cafe bem=beam]
1925− ^- (bolt vase)
1926− =+ von=(ska %cx (tope bem))
1927− ?~ von
1928− [p=*cafe q=[%1 [[bem ~] ~ ~]]]
1929− ?~ u.von
1930− (flaw cof (smyt (tope bem)) ~)
1931− (fine cof ?^(u.u.von [%cell %noun %noun] [%atom %$]) u.u.von)
1932−
1933−This takes a beam and loads the file at that location. If our sky
1934−function produces null, that means the resource is currently
1935−unavailable, so we block on it. If it produces `[~ ~]`, that means our
1936−resource is permanently unavailable, so we produce an error. Otherwise,
1937−we produce the value there with a type of either a cell of two nouns or
1938−an atom, depending on whether the value is a cell or not.
1939−
1940−Back in `++lima`, recall that we call `++lion` to find a translation
1941−path.
1942−
1943− ++ lion :: translation search
1944− |= [cof=cafe too=@tas bek=beak fro=(list ,@tas)]
1945− ^- (bolt (unit (list ,@tas)))
1946− =| war=(set ,@tas)
1947− =< -:(apex (fine cof fro))
1948− |%
1949− ++ apex
1950− |= rof=(bolt (list ,@tas))
1951− ^- [(bolt (unit (list ,@tas))) _+>]
1952− ?. ?=(%0 -.q.rof) [rof +>.$]
1953− ?~ q.q.rof
1954− [[p.rof [%0 p.q.rof ~]] +>.$]
1955− =^ orf +>.$ (apse cof i.q.q.rof)
1956− ?. ?=(%0 -.q.orf)
1957− [orf +>.$]
1958− ?~ q.q.orf
1959− $(cof p.orf, q.q.rof t.q.q.rof)
1960− [[p.orf [%0 (grom p.q.rof p.q.orf) q.q.orf]] +>.$]
1961− ::
1962− ++ apse
1963− |= [cof=cafe for=@tas]
1964− ^- [(bolt (unit (list ,@tas))) _+>]
1965− ?: =(for too)
1966− [(fine cof [~ too ~]) +>.$]
1967− ?: (~(has in war) for) [(fine cof ~) +>]
1968− =. war (~(put in war) for)
1969− =^ hoc +>.$ (apex (lily cof for bek))
1970− :_ +>.$
1971− %+ cope hoc
1972− |= [cof=cafe ked=(unit (list ,@tas))]
1973− (fine cof ?~(ked ~ [~ for u.ked]))
1974− --
1975−
1976−At a high level, we have `++apex` and `++apse`. `++apex` takes a list of
1977−marks to try in succession until we find one that can be translated into
1978−the target mark. On each one, it calls `++apse`, which takes a single
1979−mark and tries to find a translation path from this mark to the target.
1980−To do this, it sees which marks we know how to directly translate to,
1981−and calls `++apex` on this list. The result of this mututal recursion is
1982−a depth-first search of the translation graph to find the target mark.
1983−Since the translation graph is not necessarily acyclic, we maintain a
1984−set of marks that we've already tried.
1985−
1986−We kick off our search in `++apex`, starting with the given initial list
1987−of marks that we know how to get to.
1988−
1989−If `++apex` is called with a bolt other than a `%0` value bolt, we
1990−simply produce it. Otherwise, we check to see if the list of available
1991−marks to investigate is null. If so, then we're done, so we produce a
1992−`%0` bolt with a null list of accessible marks.
1993−
1994−Otherwise, we process this next mark with `++apse`, which will produce a
1995−possible list of marks from this one to the target mark. If it fails to
1996−produce a `%0` bolt, we just produce that. Otherwise, if it produces
1997−null, we can't get to our target through this mark, so we move on to the
1998−next one.
1999−
2000−If it doesn't produce null, then we have successfully found a
2001−translation path, so we produce it.
2002−
2003−In `++apse`, we first test to see if we've arrived at the target path.
2004−If so, we're done, so we produce a list including just ourself.
2005−Otherwise, we check to see if we've already tried this mark. If so, we
2006−know we can't succeed here, so we produce null. Otherwise, we put
2007−ourselves in the set of already-tried marks, and we move on.
2008−
2009−We call `++lily` to get the list of marks we can translate this one
2010−into.
2011−
2012− ++ lily :: translation targets
2013− |= [cof=cafe for=mark bek=beak]
2014− ^- (bolt (list ,@tas))
2015− =+ raf=(fang cof for bek)
2016− ?: =(%2 -.q.raf) (fine p.raf ~)
2017− %+ cope raf
2018− |= [cof=cafe vax=vase]
2019− %+ fine cof
2020− %+ weld
2021− ^- (list ,@tas)
2022− ?. (slab %garb p.vax) ~
2023− =+ gav=((soft (list ,@tas)) q:(slap vax [%cnzy %garb]))
2024− ?~(gav ~ u.gav)
2025− ?. (slab %grow p.vax) ~
2026− =+ gow=(slap vax [%cnzy %grow])
2027− (sloe p.gow)
2028−
2029−We call `++fang` to get the mark definition door. This is documented
2030−under `%vale`. If getting the mark fails, we produce null because we
2031−can't translate a non-existent mark into anything.
2032−
2033−Otherwise, we examine the door. The door may have a `++garb`, which is
2034−simply a list of marks which know how to translate from the current one.
2035−There must be a corresponding `++grab` in the definition of the other
2036−mark, though we don't check that here.
2037−
2038−The door may also have a `++grow`, which defines how to translate this
2039−mark into another one. Each arm in `++grow` is the name of a mark we can
2040−translate into. The call to `++sloe` simply produces a list of arm names
2041−in `++grow`.
2042−
2043−Back in `++apse:lion`, we take the list of translation targets we just
2044−found and call `++apex` on it. If we got back a null, we produce a null;
2045−otherwise, we produce the list of marks we got back plus the current
2046−mark.
2047−
2048−This concludes our discussion of `++lion`.
2049−
2050−The final piece of `++lima` is `++lope`, which performs the actual
2051−translation along the path we just computed.
2052−
2053− ++ lope :: translation pipe
2054− |= [cof=cafe for=mark yaw=(list mark) bek=beak vax=vase]
2055− ^- (bolt vase)
2056− ?~ yaw (fine cof vax)
2057− %+ cope (link cof i.yaw for bek vax)
2058− |= [cof=cafe yed=vase]
2059− ^$(cof cof, for i.yaw, yaw t.yaw, vax yed)
2060−
2061−We iterate through our list, calling `++link` on every adjacent pair of
2062−marks, translating from one mark to the next until we finish the list of
2063−marks. A call to `++link` is equivalent to a `%cast` silk, so we
2064−document it there. After we've called performed every step in the
2065−translation pipeline, we're done.
2066−
2067−Lifecycle of a `%boil`
2068−----------------------
2069−
2070− %boil
2071− %+ cool |.(leaf/"ford: boil {<p.kas>} {<(tope q.kas)>} {<r.kas>}")
2072− %+ cope (lamp cof q.kas)
2073− |= [cof=cafe bem=beam]
2074− %+ cope (lime cof p.kas bem r.kas)
2075− |= [cof=cafe vax=vase]
2076− (fine cof `cage`[p.kas vax])
2077−
2078−At a high level, we try to bake at the given beam, and if it fails, we
2079−go up a level and try again. This is the usual semantics of ford, and
2080−this should nearly always be preferred over directly baking.
2081−
2082−First, we normalize the version case to a number with `++lamp`. This
2083−allows caching to be based on revision number rather than something more
2084−ephemeral like a particular time.
2085−
2086− ++ lamp :: normalize version
2087− |= [cof=cafe bem=beam]
2088− ^- (bolt beam)
2089− =+ von=(ska %cw (tope bem(s ~)))
2090− ?~ von [p=cof q=[%1 [bem ~] ~ ~]]
2091− (fine cof bem(r [%ud ((hard ,@) (need u.von))]))
2092−
2093−We call the sky function with `%cw`, asking clay for the revision number
2094−at this case. If the case refers to a revision that isn't there yet, we
2095−produce a `%1` blocking bolt. Otherwise, we require that the value exist
2096−and that it's a number, both of which are guaranteed by clay. We produce
2097−this number.
2098−
2099−Next for `%boil` we call `++lime` to try to load the beam.
2100−
2101− ++ lime :: load beam
2102− |= [cof=cafe for=mark bem=beam arg=heel]
2103− =+ [mob=bem mer=(flop arg)]
2104− |- ^- (bolt vase)
2105− %+ cope (lima cof for mob (flop mer))
2106− |= [cof=cafe vux=(unit vase)]
2107− ?^ vux (fine cof u.vux)
2108− ?~ s.mob
2109− (flaw cof (smyt (tope bem)) ~)
2110− ^$(s.mob t.s.mob, mer [i.s.mob mer])
2111−
2112−We start at the given beam and try to bake it. If it succeeds, we're
2113−good. Otherwise, we pop off the top level of the path and put it in our
2114−heel (virtual path extension). We do this recursively until either we
2115−find something we can bake or we've gone all the way up to the root path
2116−of the desk, in which case we fail.
2117−
2118−Lifecycle of a `%call`
2119−----------------------
2120−
2121− %call
2122− %+ cool |.(leaf/"ford: call {<`@p`(mug kas)>}")
2123− %. [cof p.kas q.kas]
2124− ;~ cope
2125− ;~ coax
2126− |=([cof=cafe p=silk q=silk] ^$(cof cof, kas p))
2127− |=([cof=cafe p=silk q=silk] ^$(cof cof, kas q))
2128− ==
2129− ::
2130− |= [cof=cafe gat=cage sam=cage]
2131− (maul cof q.gat q.sam)
2132− ::
2133− |= [cof=cafe vax=vase]
2134− (fine cof %noun vax)
2135− ==
2136−
2137−This is slam for silks. We process both of the given silks in parallel
2138−with `++coax`. We then slam the two produced vases together with
2139−`++maul` and mark the produced vase with `%noun` since we don't know any
2140−more specific mark.
2141−
2142−`++coax` is documented under Lifecycle of a Cell.
2143−
2144−Lifecycle of a `%cast`
2145−----------------------
2146−
2147− %cast
2148− %+ cool |.(leaf/"ford: cast {<p.kas>}")
2149− %+ cope $(kas q.kas)
2150− |= [cof=cafe cay=cage]
2151− %+ cope (link cof p.kas p.cay [our %main %da now] q.cay)
2152− |= [cof=cafe vax=vase]
2153− (fine cof [p.kas vax])
2154−
2155−This is a request to convert data of one mark to another mark directly.
2156−We evaluate the given silk and pass the result into `++link`, which
2157−performs the actual translation. Note that this will not search for
2158−indirect conversion paths, so the conversion must be defined either in
2159−the `++grow` of the given mark or the `++grab` of the target mark.
2160−
2161− ++ link :: translate
2162− |= [cof=cafe too=mark for=mark bek=beak vax=vase]
2163− ^- (bolt vase)
2164− ?: =(too for) (fine cof vax)
2165− ?: |(=(%noun for) =(%$ for))
2166− ((lake too bek) cof vax)
2167− %+ cope (fang cof for bek)
2168− |= [cof=cafe pro=vase]
2169− ?: &((slab %grow p.pro) (slab too p:(slap pro [%cnzy %grow])))
2170− %+ cope (keel cof pro [[%& 6]~ vax]~)
2171− |= [cof=cafe pox=vase]
2172− (maim cof pox [%tsgr [%cnzy %grow] [%cnzy too]])
2173− %+ cope (fang cof too bek)
2174− |= [cof=cafe pro=vase]
2175− =+ ^= zat ^- (unit vase)
2176− ?. (slab %grab p.pro) ~
2177− =+ gab=(slap pro [%cnzy %grab])
2178− ?. (slab for p.gab) ~
2179− `(slap gab [%cnzy for])
2180− ?~ zat
2181− (flaw cof [%leaf "ford: no link: {<[for too]>}"]~)
2182− (maul cof u.zat vax)
2183−
2184−This performs one step in the translation pipeline. If the given and
2185−target marks are the same, we're done. If we're translating from a noun
2186−or the empty mark, we coerce with `++lake` (documented in `%vale`).
2187−Otherwise, we're translating from a user-defined mark.
2188−
2189−We load the definition of the given mark with `++fang`, and we check to
2190−see if it has an arm in `++grow` named the target mark. If so, we place
2191−our data in the sample of the door with `++keel` and slap the arm.
2192−`++keel` is equivalent to a `%mute` silk, so we document it there.
2193−
2194−If there is no arm in `++grow` of the given mark named the target mark,
2195−we suppose there must be an arm in `++grab` of the target mark named the
2196−given mark. We get the definition of the target mark and check to see if
2197−it has the required arm, failing if it doesn't. Finally, we slam the
2198−data against the correct arm, producing the translated data.
2199−
2200−If you're confused as to why the handling of `++grow` and `++grab` look
2201−superficially so different, remember that the correct arm in `++grow`
2202−does not have a sample while the one in `++grab` does. This means they
2203−must be called rather differently.
2204−
2205−Lifecycle of a `%diff`
2206−----------------------
2207−
2208− %diff
2209− %+ cool |.(leaf/"ford: diff {<`@p`(mug p.kas)>} {<`@p`(mug q.kas)>}")
2210− (diff cof p.kas q.kas)
2211−
2212−We push debug information onto the trace and go right to `++diff`.
2213−
2214− ++ diff
2215− |= [cof=cafe kas=silk kos=silk]
2216− ^- (bolt cage)
2217− %. [cof kas kos]
2218− ;~ cope
2219− ;~ coax
2220− |=([cof=cafe p=silk q=silk] (make cof p))
2221− |=([cof=cafe p=silk q=silk] (make cof q))
2222− ==
2223− |= [cof=cafe cay=cage coy=cage]
2224−
2225−First, we process the two given silks to get our arguments.
2226−
2227− ?. =(p.cay p.coy)
2228− %+ flaw cof :_ ~
2229− leaf/"diff on data of different marks: {(trip p.cay)} {(trip p.coy)}"
2230−
2231−If the two cages have different marks, then we can't diff them, so we
2232−complain.
2233−
2234− %+ cope (fang cof p.cay [our %main %da now])
2235− |= [cof=cafe pro=vase]
2236−
2237−We pull in the relevant mark's definition.
2238−
2239− ?. (slab %grad p.pro)
2240− (flaw cof leaf/"no ++grad" ~)
2241− =+ gar=(slap pro [%cnzy %grad])
2242− ?. (slab %form p.gar)
2243− ?. (slab %sted p.gar)
2244− (flaw cof leaf/"no ++form:grad nor ++sted:grad" ~)
2245− =+ for=((soft ,@tas) q:(slap gar [%cnzy %sted]))
2246− ?~ for
2247− (flaw cof leaf/"bad ++sted:grad" ~)
2248− (make cof %diff [%cast u.for kas] [%cast u.for kos])
2249−
2250−If there's no `++grad`, we complain. If there's no `++form:grad`, then
2251−we look for a `++sted:grad`. If we can't find either, or if
2252−`++sted:grad` isn't a term, then we complain. If `++sted:grad` exists
2253−and is a term, then it represents the mark we should use as a proxy to
2254−get our diff. So, we cast both our given cages to the new mark and start
2255−the dance again.
2256−
2257− ?. (slab %diff p.gar)
2258− (flaw cof leaf/"no ++diff:grad" ~)
2259−
2260−Otherwise, we expect a `++diff:grad`.
2261−
2262− %+ cope (keel cof pro [[%& 6]~ q.cay]~)
2263− |= [cof=cafe pox=vase]
2264−
2265−We put the first cage's data into the sample of the given mark's
2266−definition.
2267−
2268− %+ cope
2269− %^ maul cof
2270− (slap (slap pox [%cnzy %grad]) [%cnzy %diff])
2271− q.coy
2272− |= [cof=cafe dif=vase]
2273−
2274−We run `++diff:grad` with a sample of the second cage's data.
2275−
2276− =+ for=((soft ,@tas) q:(slap gar [%cnzy %form]))
2277− ?~ for
2278− (flaw cof leaf/"bad ++form:grad" ~)
2279− (fine cof u.for dif)
2280− ==
2281−
2282−We check that `++form:grad` exists, and we tag the result with it to
2283−give the final cage.
2284−
2285−Lifecycle of a `%done`
2286−----------------------
2287−
2288− %done [cof %0 p.kas q.kas]
2289−
2290−This is trivial. We simply produce the given cage with the given set of
2291−dependencies. This is used when we already have a cage that we want to
2292−insert into another silk that requires a silk argument. It's analogous
2293−to the return operator in a monad -- which makes it sound way more
2294−complicated than it is.
2295−
2296−Lifecycle of a `%dude`
2297−----------------------
2298−
2299− %dude (cool |.(p.kas) $(kas q.kas))
2300−
2301−This simply puts a given tank on the stack trace if the given silk
2302−produces an error. This is implemented as a simple call to `++cool`.
2303−
2304−Lifecycle of a `%dune`
2305−----------------------
2306−
2307− %dune
2308− ?~ q.kas [cof [%2 [%leaf "no data"]~]]
2309− $(kas [%done p.kas u.q.kas])
2310−
2311−This is a sort of a `++need` for silks. If there is no data in the unit
2312−cage, we produce an error. Else, we simply produce the data in the cage.
2313−
2314−Lifcycle of a `%mute`
2315−---------------------
2316−
2317− %mute (kale cof p.kas q.kas)
2318−
2319−This mutates a silk by putting the values of other silks at particular
2320−axes. This is useful in, for example, replacing the sample of the door
2321−in a mark definition.
2322−
2323− ++ kale :: mutate
2324− |= [cof=cafe kas=silk muy=(list (pair wing silk))]
2325− ^- (bolt cage)
2326− %+ cope
2327− |- ^- (bolt (list (pair wing vase)))
2328− ?~ muy (fine cof ~)
2329− %+ cope (make cof q.i.muy)
2330− |= [cof=cafe cay=cage]
2331− %+ cope ^$(muy t.muy)
2332− |= [cof=cafe rex=(list (pair wing vase))]
2333− (fine cof [[p.i.muy q.cay] rex])
2334− |= [cof=cafe yom=(list (pair wing vase))]
2335− %+ cope (make cof kas)
2336− |= [cof=cafe cay=cage]
2337− %+ cope (keel cof q.cay yom)
2338− |= [cof=cafe vax=vase]
2339− (fine cof p.cay vax)
2340−
2341−First, we process each of the silks by calling `++make` on them. We pass
2342−the resultant vase and list of pairs of wings and silks to `++keel` to
2343−do the actual mutation. We assume the mutation doesn't change the mark
2344−of the main silk, so we mark the produced vase with the original mark.
2345−
2346− ++ keel :: apply mutations
2347− |= [cof=cafe suh=vase yom=(list (pair wing vase))]
2348− ^- (bolt vase)
2349− %^ maim cof
2350− %+ slop suh
2351− |- ^- vase
2352− ?~ yom [[%atom %n] ~]
2353− (slop q.i.yom $(yom t.yom))
2354− ^- hoon
2355− :+ %cncb [%& 2]~
2356− =+ axe=3
2357− |- ^- (list (pair wing hoon))
2358− ?~ yom ~
2359− :- [p.i.yom [%$ (peg axe 2)]]
2360− $(yom t.yom, axe (peg axe 3))
2361−
2362−We first put the vases together in one big tuple starting with the
2363−subject and going through the mutations. We slap against this tuple a
2364−`%_` hoon we directly construct. Since a `%_` hoon takes a list of pairs
2365−of wings and hoons, we simply have to generate hoons referring to the
2366−correct axes in the subject. This is very easy since we just recur on
2367−axis 3 of whatever axis we were already at.
2368−
2369−Note the use of `%_` instead of `%=` enforces that our mutations don't
2370−change the type of the subject, which justifies our use of the original
2371−mark.
2372−
2373−Lifecycle of a `%pact`
2374−----------------------
2375−
2376− %pact
2377− %+ cool |.(leaf/"ford: pact {<`@p`(mug p.kas)>} {<`@p`(mug q.kas)>}")
2378− (pact cof p.kas q.kas)
2379−
2380−We push debug information onto the trace and go right to `++pact`.
2381−
2382− ++ pact :: patch
2383− |= [cof=cafe kas=silk kos=silk]
2384− ^- (bolt cage)
2385− %. [cof kas kos]
2386− ;~ cope
2387− ;~ coax
2388− |=([cof=cafe p=silk q=silk] (make cof p))
2389− |=([cof=cafe p=silk q=silk] (make cof q))
2390− ==
2391− |= [cof=cafe cay=cage coy=cage]
2392−
2393−First, we process the two given silks to get our arguments.
2394−
2395− %+ cope (fang cof p.cay [our %main %da now])
2396− |= [cof=cafe pro=vase]
2397−
2398−We pull in the relevant mark's definition.
2399−
2400− ?. (slab %grad p.pro)
2401− (flaw cof leaf/"no ++grad" ~)
2402− =+ gar=(slap pro [%cnzy %grad])
2403− ?. (slab %form p.gar)
2404− ?. (slab %sted p.gar)
2405− (flaw cof leaf/"no ++form:grad nor ++sted:grad" ~)
2406− =+ for=((soft ,@tas) q:(slap gar [%cnzy %sted]))
2407− ?~ for
2408− (flaw cof leaf/"bad ++sted:grad" ~)
2409− (make cof %cast p.cay %pact [%cast u.for kas] kos)
2410−
2411−If there's no `++grad`, we complain. If there's no `++form:grad`, then
2412−we look for a `++sted:grad`. If we can't find either, or if
2413−`++sted:grad` isn't a term, then we complain. If `++sted:grad` exists
2414−and is a term, then it represents the mark we should use as a proxy to
2415−get our diff. So, we cast the first argument to the new mark, then try
2416−to patch. Afterward, we cast the result back to the original mark.
2417−
2418− =+ for=((soft ,@tas) q:(slap gar [%cnzy %form]))
2419− ?~ for
2420− (flaw cof leaf/"bad ++form:grad" ~)
2421− ?. =(u.for p.coy)
2422− %+ flaw cof :_ ~
2423− =< leaf/"pact on data with wrong form: {-} {+<} {+>}"
2424− [(trip p.cay) (trip u.for) (trip p.coy)]
2425−
2426−If `++form:grad` isn't a term, or else our second argument isn't of that
2427−mark, we complain.
2428−
2429− ?. (slab %pact p.gar)
2430− (flaw cof leaf/"no ++pact:grad" ~)
2431−
2432−If we don't have a `++pact:grad`, we complain.
2433−
2434− %+ cope (keel cof pro [[%& 6]~ q.cay]~)
2435− |= [cof=cafe pox=vase]
2436−
2437−We put the first cage's data into the sample of the given mark's
2438−definition.
2439−
2440− %+ cope
2441− %^ maul cof
2442− (slap (slap pox [%cnzy %grad]) [%cnzy %pact])
2443− q.coy
2444− |= [cof=cafe pat=vase]
2445−
2446−We run `++pact:grad` with a sample of the second cage's data, which is
2447−the diff.
2448−
2449− (fine cof p.cay pat)
2450− ==
2451−
2452−We tag the result with the mark of our first argument.
2453−
2454−Lifecycle of a `%plan`
2455−----------------------
2456−
2457− %plan
2458− %+ cope (abut:(meow p.kas q.kas) cof r.kas)
2459− |= [cof=cafe vax=vase]
2460− (fine cof %noun vax)
2461−
2462−This is a direct request to compile a hood at a given beam with a heel
2463−of the given path. We comply by calling `++abut` with the given
2464−arguments and producing the vase with a mark of `%noun`.
2465−
2466−Lifecycle of a `%reef`
2467−----------------------
2468−
2469− %reef (fine cof %noun pit)
2470−
2471−This is one of the simplest silks. We simply produce our context, which
2472−is zuse compiled against hoon. The mark is a `%noun`.
2473−
2474−Lifcycle of a `%ride`
2475−---------------------
2476−
2477− %ride
2478− %+ cool |.(leaf/"ford: ride {<`@p`(mug kas)>}")
2479− %+ cope $(kas q.kas)
2480− |= [cof=cafe cay=cage]
2481− %+ cope (maim cof q.cay p.kas)
2482− |= [cof=cafe vax=vase]
2483− (fine cof %noun vax)
2484−
2485−This slaps evaluates the given silk, then it slaps the result against
2486−the given hoon. Since we don't know what of what mark (if any) is the
2487−result, we give it a mark of `%noun`.
2488−
2489−Lifecycle of a `%vale`
2490−----------------------
2491−
2492− %vale
2493− %+ cool |.(leaf/"ford: vale {<p.kas>} {<q.kas>} {<`@p`(mug r.kas)>}")
2494− %+ cope (lave cof p.kas q.kas r.kas)
2495− |= [cof=cafe vax=vase]
2496− (fine cof `cage`[p.kas vax])
2497−
2498−This checks whether given data is of the given mark. If we don't have
2499−the definition of the mark, we check the given ship for it.
2500−
2501−We call `++lave` to perform the check, producing a vase. We produce this
2502−vase tagged with the given mark.
2503−
2504− ++ lave :: validate
2505− |= [cof=cafe for=mark his=ship som=*]
2506− ^- (bolt vase)
2507− ((lake for [our %main [%da now]]) cof [%noun som])
2508−
2509−This is a thinly-veiled wrapper over `++lake`. Note that, contrary to
2510−documented opinion, we do not in fact check the other ship's definition
2511−of a mark. This is likely a bug.
2512−
2513−At any rate, `++lake` coerces a noun into the correct type for a mark.
2514−
2515− ++ lake :: check/coerce
2516− |= [for=mark bek=beak]
2517− |= [cof=cafe sam=vase]
2518− ^- (bolt vase)
2519− %+ cool |.(leaf/"ford: check {<[for bek `@p`(mug q.sam)]>}")
2520− ?: ?=(?(%gate %core %door %hoon %hook) for)
2521− :: ~& [%lake-easy for bek]
2522− (fine cof sam)
2523− %+ cope (fang cof for bek)
2524− |= [cof=cafe tux=vase]
2525− =+ bob=(slot 6 tux)
2526− ?: (~(nest ut p.bob) | p.sam)
2527− (fine cof sam)
2528− ?. (slab %grab p.tux)
2529− (flaw cof [%leaf "ford: no grab: {<[for bek]>}"]~)
2530− =+ gab=(slap tux [%cnzy %grab])
2531− ?. (slab %noun p.gab)
2532− (flaw cof [%leaf "ford: no noun: {<[for bek]>}"]~)
2533− %+ cope (maul cof (slap gab [%cnzy %noun]) [%noun q.sam])
2534− |= [cof=cafe pro=vase]
2535− ?: =(+<.q.pro q.sam)
2536− (fine cof (slot 6 pro))
2537− (flaw cof [%leaf "ford: invalid content: {<[for bek]>}"]~)
2538−
2539−This is going to coerce the sample into the correct type for the mark.
2540−First, we push a line onto the stack trace saying that we're checking
2541−the type. If the requested mark is a gate, core, door, hoon, or hook,
2542−then we don't do any more type information than just saying it's a noun,
2543−so we're done.
2544−
2545−Otherwise, we get the mark definition from our `/=main=/mar` directory
2546−with `++fang`, which we'll describe below.
2547−
2548−We check to see if our sample type nests within the type of the sample
2549−to the door. If so, then we're already of the correct type, so we're
2550−done.
2551−
2552−Otherwise, we check to see if there's a `++grab` in the door, and a
2553−`++noun` in the `++grab`. If not, there's no way we can translate to
2554−this mark, so we fail.
2555−
2556−If we have everything we need, we slam our sample (typed as a noun)
2557−against the `++noun` in `++grab`. If the sample of the door is the same
2558−as our sample, then the check succeeded, so we produce the well-typed
2559−sample of the door. Otherwise, we fail.
2560−
2561− ++ fang :: protocol door
2562− |= [cof=cafe for=mark bek=beak]
2563− ^- (bolt vase)
2564− =+ pax=/door/[for]/mar
2565− =+ ^= bem ^- beam
2566− :_ pax
2567− ?: =(p.bek our) bek
2568− =+ oak=[our %main %da now]
2569− ?. =(~ (ska %cy (tope [oak pax]))) oak
2570− bek
2571− (cope (fade cof %hook bem) abut:(meow bem ~))
2572−
2573−A mark's definition is generally in
2574−`/=main=/mar/[mark-name]/door/hook'. If we don't find it there, we look in`/[given-beak]/mar/[mark-name]/door/hook'.
2575−We parse the mark definition with `++fade` and assemble it with
2576−`++abut:meow`. `++fade` is defined under the `%bake` silk.
docs/arvo/subject.mddeleted−105
@@ -1,105 +0,0 @@
1−---
2−navhome: /docs/
3−sort: 12
4−next: true
5−title: The subject
6−---
7−
8−The subject
9−===========
10−
11−Now we're going to cover the boiler plate that we skimmed over earlier.
12−
13− :- %say |= *
14− :- %noun
15− =< (sum [1.000 2.000])
16−
17−The first rune, `:-` (colhep, aka
18−[:cons](../../hoon/rune/col/hep/)), constructs the 2-element cell
19−that will be our program. The first element, `%say`, tells the
20−interpreter what to produce--in this case a value.
21−
22−The second element is `|=`, which we know produces a function. `|=`'s
23−first child is its argument(s), which in this case is any noun (`*`).
24−Its second child is the remainder of the program.
25−
26−Similarly, the rest of the program (which we construct with another
27−`:-`) is a cell of the literal `%noun`, which tells the shell that we're
28−producing a value of type `noun`, and the code that we run to actually
29−produce our value of the type `noun`.
30−
31−`=<` ([tisgal](../../hoon/rune/tis/gal/)) is a rune that takes two
32−children. The second child is the context against which we run the first
33−child. So in this case, we are running the expression
34−`(sum [1.000 2.000])` against everything contained within the `|%`. In
35−Hoon, we call the code executed the "formula" and its context the
36−"subject".
37−
38− ::::::::::::::::::::::::::::::
39− =< (sum [1.000 2.000]) :: formula
40− ::::::::::::::::::::::::::::::
41− |% ::
42− ++ three ::
43− |= a/@ ::
44− =| b/@ ::
45− |- ^- @u ::
46− ?: (lth a b) ::
47− 0 ::
48− (add b $(b (add 3 b))) ::
49− :: ::
50− ++ five ::
51− |= a/@ :: subject
52− =| b/@ ::
53− |- ^- @ ::
54− ?: (lte a b) ::
55− 0 ::
56− ?: =((mod b 3) 0) ::
57− $(b (add b 5)) ::
58− (add b $(b (add b 5))) ::
59− :: ::
60− ++ sum ::
61− |= {a/@u b/@u} ::
62− (add (five a) (three b)) ::
63− -- ::
64− ::::::::::::::::::::::::::::::
65−
66−In nearly every language there is a similar concept of a "context" in
67−which expressions are executed. For example, in C this includes things
68−like the call stack, stack variables, and so on.
69−
70−Hoon is unique in that this context is a first-class value. Scheme
71−allows a sort of reification of the context through continuations, and
72−some may see a parallel to Forth's stack, but Hoon takes the
73−concept one step further.
74−
75−Our starting subject is the [standard library](../../hoon/library), which is
76−defined in `/arvo/hoon.hoon` and `/arvo/zuse.hoon`. This is where
77−functions like `add` are defined. When we define a core with `|%`, we
78−don't throw away the subject (i.e. the standard library); rather, we
79−stack the new core on top of the old subject so that both are
80−accessible.
81−
82−**Exercises**:
83−
84−- Pass `++sum` its arguments (`2.000` and `3.000`) from the
85− command line.
86−
87−- Comment out all of the arms of the `|%`. Now add another arm and
88− call it `++add`, have it accept two arguments and produce 42
89− (regardless of input). Change the `=<` line to
90− `[(add 5 7) (^add 5 7)]`. Can you recognize what's happening?
91−
92−Cheatsheet:
93−
94−- To pass arguments from the command line to a program, you replace
95− the `*` in the first line of the boiler plate to
96− `[^ [[arg=TYPE ~] ~]]` where `TYPE` is replaced with the type of
97− argument you're expecting. Then `+euler1 a` from the dojo sets `arg`
98− to `a`.
99−- The empty list is `~`
100−- Lisp-style cons (construct a cell/prepend an element) is
101− `[new-element list]`
102−- For example, the first three positive integers are `[1 2 3 ~]`
103−- `(gte a b)` tests whether `a` is greater than or equal to `b`.
104−- `(mod a b)` runs the modulo operation on two atoms.
105−- See the basic math section in `/arvo/hoon.hoon` for more info.
docs/community.mddeleted−31
@@ -1,31 +0,0 @@
1−---
2−navhome: /docs/
3−sort: 9
4−title: Community docs
5−---
6−
7−# Community docs
8−
9−<div>
10−
11−<ul>
12−
13−<li><code>~master-morzod</code>
14−<br />
15−<a href="https://mardev.urbit.org/docs/">Docs</a>, <a href="https://urbit.org/fora/posts/~2016.12.25..06.35.44..a1ec~/">Fora post</a></li>
16−
17−<li><code>~hidduc-posmeg</code>
18−<br />
19−<a href="https://fosnut-dandut.urbit.org/pages/hidducs-notes/tutorial/">Docs</a>, <a href="https://urbit.org/fora/posts/~2017.2.12..21.54.40..6fde~/">Fora post</a></li>
20−
21−<li><code>~palfun-foslup</code>
22−<br />
23−<a href="https://github.com/Fang-/Urbit-By-Doing">Urbit by Doing</a></li>
24−
25−<li><code>@knubie</code>
26−<br />
27−<a href="https://github.com/knubie/learning-hoon">Learning Hoon</a></li>
28−
29−</ul>
30−
31−</div>
docs/hoon.mddeleted−13
@@ -1,13 +0,0 @@
1−---
2−navhome: /docs/
3−next: true
4−sort: 5
5−title: Hoon
6−---
7−
8−# Hoon
9−
10−An in-depth technical reference for Hoon. Best for readers with
11−an interest or background in programming languages.
12−
13−<list/>
docs/hoon/atom.mddeleted−17
@@ -1,17 +0,0 @@
1−---
2−navhome: /docs/
3−next: true
4−sort: 19
5−title: Atoms and strings
6−---
7−
8−# Atoms and strings
9−
10−The simplest expressions in every language are constants:
11−atoms, strings, paths. (Strings aren't all constants per
12−se, because they have interpolations.)
13−
14−## Stems
15−
16−<list dataPreview="true" className="runes"></list>
17−
docs/hoon/atom/knit.mddeleted−44
@@ -1,44 +0,0 @@
1−---
2−navhome: /docs/
3−sort: 3
4−title: Knit
5−---
6−
7−# Knit
8−
9−`[%knit p=(list (each @t hoon))]`: text string with interpolation.
10−
11−### Produces
12−
13−A list-shaped string (`tape`) of the items in `p`, which are
14−either constant `@t` multibyte UTF-8 strings (`cord`) or hoons
15−producing a `tape`.
16−
17−### Syntax
18−
19−Irregular: `"foobar"`.
20−
21−Irregular: `"foo{(weld "moo" "baz")}bar"`.
22−
23−### Examples
24−
25−String:
26−
27−```
28−~zod:dojo> "hello, world."
29−"hello, world."
30−```
31−
32−String with interpolation:
33−
34−```
35−~zod:dojo> =+(planet="world" "hello, {planet}.")
36−"hello, world."
37−```
38−
39−String with interpolated prettyprinting:
40−
41−```
42−~zod:dojo> =+(planet=%world "hello, {<planet>}.")
43−"hello, %world."
44−```
docs/hoon/atom/path.mddeleted−31
@@ -1,31 +0,0 @@
1−---
2−navhome: /docs/
3−sort: 4
4−title: Path
5−---
6−
7−# Path
8−
9−`[%path p=(list (each @ta hoon))]`: path with interpolation.
10−
11−### Produces
12−
13−A null-terminated list if of the items in `p`, which are either constant
14−`@ta` atoms (`knot`), or hoons producing a `knot`.
15−
16−### Syntax
17−
18−Irregular: `/foo/bar/baz`.
19−
20−### Examples
21−
22−```
23−~zod/dojo> /foo/bar/baz
24−/foo/bar/baz
25−
26−~zod/dojo> `path`/foo/[`@ta`(cat 3 %moo %bar)]/baz
27−/foo/moobar/baz/
28−
29−~zod:dojo> /
30−~
31−```
docs/hoon/atom/rock.mddeleted−37
@@ -1,37 +0,0 @@
1−---
2−navhome: /docs/
3−sort: 2
4−title: Rock
5−---
6−
7−# Rock
8−
9−`[%rock p=term q=@]`; a constant, cold atom.
10−
11−### Produces
12−
13−A cold (fixed) atom `q` with aura `a`.
14−
15−### Syntax
16−
17−Irregular: any warm atom [(`%sand`)](../sand/) form, prefixed with `%`.
18−
19−Irregular: `%foo`, `@tas`, symbol. Character constraints: `a-z`
20−lowercase to start, `a-z` or `0-9` thereafter, with infix
21−hyphens (`hep`), "kebab-case."
22−
23−Irregular: `~`, `@n`, null (`0`).
24−
25−### Examples
26−
27−```
28−~zod:dojo> ?? %foobar
29− [%atom %tas [~ u=125.762.588.864.358]]
30−%foobar
31−~zod:dojo> ?? %'foobar'
32− [%atom %t [~ u=125.762.588.864.358]]
33−%'foobar'
34−~zod:dojo> ?? 'foobar'
35− [%atom %t ~]
36−'foobar'
37−```
docs/hoon/basic.mddeleted−234
@@ -1,234 +0,0 @@
1−---
2−navhome: /docs/
3−sort: 15
4−next: true
5−title: Basic types
6−---
7−
8−# Basic types
9−
10−A Hoon `type` is a set of nouns. There is no syntax for directly
11−defining the data type of a Hoon expression. Instead, the compiler
12−infers the type of a Hoon expression by calculating the range of
13−possible values of that expression.
14−
15−Working with a type in Hoon normally requires the use of a `mold`.
16−Each type is defined by a mold. To define a custom type, you must
17−create a custom mold.
18−
19−## Molds
20−
21−A mathematical function is a mapping from one set (the domain) to
22−another (the range). Pass an object from the domain to some
23−function *f*, and *f* returns an object from the range. In Hoon we
24−can think of a `gate` as a function, where the gate's `sample` is
25−its argument.
26−
27−A `mold` is an idempotent function whose domain is the set of all
28−nouns. (That is, it's an idempotent gate that takes any noun for its
29−sample.) An idempotent function *f* is one such that, if *f(x)*
30−terminates, *f(x) = f(f(x))*. The product range of a mold is the
31−type defined by that mold. That is, each mold's type is the set of
32−possible outputs of that mold.
33−
34−Essentially, molds are constructor functions. You can pass a mold
35−any data you like, and the product is guaranteed be of the type
36−defined by that mold. Molds are the perfect tool for validating
37−untrusted foreign data. Just call the relevant mold with that data
38−and check that the input equals the output. This is one reason why
39−molds must be idempotent; if the untrusted data is of the correct
40−type, passing it to the mold shouldn't change it. But this use case
41−is unusual for beginners; in normal practice you shouldn't call
42−molds directly.
43−
44−More frequently, molds are used when we want to `cast`. We use a
45−cast when we want the Hoon compiler's type-checker to test whether
46−a Hoon expression is guaranteed to evaluate to a product of the
47−desired type. If it isn't, then the compiler will halt with a
48−`nest-fail` crash. Proper Hoon code will include a cast for the
49−product type of each gate.
50−
51−The `^` family of runes is for casting. In particular, `^-` allows
52−us to cast with a mold. For example, we can cast for an `atom` using
53−the `@` mold as follows:
54−
55−```
56−^- @
57−17
58−```
59−
60−Evaluating the above in `dojo` should return 17, because 17 is of
61−the type `atom`. On the other hand,
62−
63−```
64−^- @
65−[17 18]
66−```
67−
68−...this should result in a `nest-fail`, because `[17 18]` is a cell,
69−not an atom.
70−
71−See the documentation on the [`^` family](../rune/ket/) of runes
72−for more information on casts. See the documentation on the
73−[`$` family](../rune/buc/) of runes for building molds.
74−(Also check out the irregular `,` operator.)
75−
76−## `type`: a set of types
77−
78−Below is the mold for `type`, which effectively defines all the types
79−available in Hoon.
80−
81−Strictly speaking, this mold defines the tree data structure the Hoon
82−compiler uses to represent type information. It has a label for each
83−of the base types, and it's recursive, so a complex type is
84−represented as a nested combination of base types and various other
85−odds and ends.
86−
87−You haven't seen this syntax before, and we haven't explained it yet;
88−just treat it as pseudocode.
89−
90−This is a slightly simplified version of `type`. We undo and
91−explain the simplifications in the [advanced types](../advanced)
92−section.
93−
94−```
95−++ term @tas
96−++ type
97− $@ $? %noun
98− %void
99− == $% [%atom p=term q=(unit atom)]
100− [%cell p=type q=type]
101− [%core p=type q=(map term hoon)]
102− [%face p=term q=type]
103− [%fork p=(set type)]
104− [%hold p=type q=hoon]
105− ==
106−```
107−
108−If the `type`-tree is an atom, it's either a `%noun` or a `%void`; if
109−the `type`-tree is a cell, it's a tuple with one of the heads `%atom`,
110−`%cell`, `%core`, etc. We'll go through each of these cases below.
111−these cases below.
112−
113−### `?(%noun %void)`
114−
115−`%noun` is the label for the set of all nouns. `%void` is the label
116−for the empty set.
117−
118−(For now, don't worry too much about the switch from `$` to `%`.)
119−
120−### `[%cell p=type q=type]`
121−
122−`[%cell p=type q=type]` is for the set of all cells with head `p` and
123−tail `q`.
124−
125−### `[%fork p=(set type)]`
126−
127−`[%fork p=(set type)]` is for the union of all types in the set `p`.
128−
129−### `[%hold p=type q=hoon]`
130−
131−A `%hold` type, with type `p` and hoon `q`, is a lazy reference
132−to the type of `(mint p q)`. In English, it means: "the type of
133−the product when we compile `q` against subject `p`."
134−
135−Note that this means we can have parsed Hoon AST data in the
136−`type`-tree.
137−
138−### `[%face p=term q=type]`
139−
140−A `[%face p=term q=type]` wraps the label `p` around the type
141−`q`. `p` is a `term` or `@tas`, an atomic ASCII string which
142−obeys symbol rules: lowercase and digit only, infix hyphen,
143−first character must be lowercase.
144−
145−See [`%limb`](../limb/limb/) for how labels are resolved. It's
146−nontrivial.
147−
148−### `[%atom p=term q=(unit atom))]`
149−
150−`%atom` is for an atom, with two twists. `q` is a `unit`, Hoon's
151−equivalent of a nullable pointer or a Haskell `Maybe`. If `q`
152−is `~`, null, the type is *warm*; any atom is in the type.
153−If `q` is `[~ x]`, where `x` is any atom, the type is *cold*;
154−its only legal value is the constant `x`.
155−
156−`p` in the atom is a terminal used as an *aura*, or soft atom
157−type. Auras are a lightweight, advisory representation of the
158−units, semantics, and/or syntax of an atom. An aura is an atomic
159−string; two auras are compatible if one is a prefix of the other.
160−
161−For instance, `@t` means UTF-8 text (LSB low), `@ta` means ASCII
162−text, and `@tas` means an ASCII symbol. `@u` means an unsigned
163−integer, `@ud` an unsigned decimal, `@ux` an unsigned
164−hexadecimal. You can use a `@ud` atom as a `@u` or vice versa,
165−but not as a `@tas`.
166−
167−Auras can also end with an optional, capitalized suffix, which
168−defines the atom's bitwidth as a log starting from `A`. For
169−example, `@udD` is an unsigned decimal byte; `@uxG` is an
170−unsigned 64-bit hexadecimal.
171−
172−You can make up your own auras and are encouraged to do so, but
173−here are some conventions bound to constant syntax:
174−
175−```
176−@c UTF-32 codepoint
177−@d date
178− @da absolute date
179− @dr relative date (ie, timespan)
180−@n nil
181−@p phonemic base (plot)
182−@r IEEE floating-point
183− @rd double precision (64 bits)
184− @rh half precision (16 bits)
185− @rq quad precision (128 bits)
186− @rs single precision (32 bits)
187−@s signed integer, sign bit low
188− @sb signed binary
189− @sd signed decimal
190− @sv signed base32
191− @sw signed base64
192− @sx signed hexadecimal
193−@t UTF-8 text (cord)
194− @ta ASCII text (knot)
195− @tas ASCII text symbol (term)
196−@u unsigned integer
197− @ub unsigned binary
198− @ud unsigned decimal
199− @uv unsigned base32
200− @uw unsigned base64
201− @ux unsigned hexadecimal
202−```
203−
204−Auras are truly soft; you can turn any aura into any other,
205−statically, by casting through the empty aura `@`. Hoon is not
206−dependently typed and can't statically enforce data constraints
207−(for example, it can't enforce that a `@tas` is really a symbol).
208−
209−### `[%core p=type q=(map term type)]`
210−
211−`%core` is for a code-data cell. The data (or *payload*) is the
212−tail; the code (or *battery*) is the head. `p`, a type, is the
213−type of the payload. `q`, a name-hoon table, is the source code
214−for the battery.
215−
216−Each hoon in the battery source is compiled to a formula, with
217−the core itself as the subject. The battery is a tree of these
218−formulas, or *arms*. An arm is a computed attribute against its
219−core.
220−
221−All code-data structures in normal languages (functions, objects,
222−modules, etc) become cores in Hoon. A Hoon battery looks a bit
223−like a method table, but not every arm is a "method" in the OO
224−sense. An arm is a computed attribute. A method is an arm whose
225−product is a Hoon function (or *gate*).
226−
227−A gate (function, lambda, etc) is a core with one arm, whose name
228−is the empty symbol `$`, and a payload whose shape is `[sample
229−context]`. The *context* is the subject in which the gate was
230−defined; the *sample* is the argument.
231−
232−To call this function on an argument `x`, replace the sample (at
233−tree address `6` in the core) with `x`, then compute the arm.
234−(Of course, we don't mutate the noun, we make a mutant copy.)
docs/hoon/concepts.mddeleted−260
@@ -1,260 +0,0 @@
1−---
2−navhome: /docs/
3−sort: 14
4−next: true
5−title: Concepts
6−---
7−
8−# Concepts and terminology
9−
10−Usually, a new language is an improvement on one you already
11−know. If it isn't, it probably at least shares concepts with a
12−large family of relatives. These concepts come with words, like
13−_variable_ or _function_, that map cleanly onto its semantics.
14−
15−In Hoon we throw away many of these words and invent new
16−ones, which mean almost the same things. But why?
17−
18−## Motivation
19−
20−Hoon has no close relatives. The normal jargon of programming
21−maps poorly onto its semantics. Some of the common concepts used
22−only informally in Hoon include "function," "object," "event,"
23−"variable," "label," "closure", "environment," "scope," and probably
24−a few more. We do use these words informally, but we're always
25−making an analogy whose precision depends on context.
26−
27−Hoon has concepts *like* all these abstractions, but they remain
28−*false cognates*. The closer an inexact cognate, the more
29−unsettling it feels when the abstractions don't match. Learning
30−a few new words is a small price for avoiding this pain point.
31−
32−## Concepts
33−
34−A few major Hoon concepts: `noun` (data), `nock` (interpreter),
35−[`hoon`](#-hoon) (AST node), [`mint`](#-mint) (compiler), [`type`](#-type) (type),
36−`gate` (function), `mold` (constructor), `core` (object), `mark`
37−(protocol).
38−
39−### <a name="-noun">`noun`</a> (data value)
40−
41−A value in Hoon is called a `noun`. A noun is either a
42−unsigned integer of any size (`atom`), or an ordered pair of any
43−two nouns (`cell`). Nouns are like Lisp S-expressions, but
44−simpler (Lisp atoms effectively have dynamic type bits).
45−
46−The simplest noun syntax uses brackets, like `[a b]` for the cell
47−of `a` and `b`. Brackets nest right; `[a b c d]` is `[a [b [c
48−d]]]`.
49−
50−A noun list, by convention, goes from left to right and is
51−null-terminated. That said, Hoon uses tuples (improper nouns) more
52−freely than Lisp; only genuinely iterative structures are
53−null-terminated lists.
54−
55−When an atom is used as a string (a `cord`), the bytes are always UTF-8
56−in LSB first order. When you see `'foo'` and `%foo`, this refers to the
57−integer `0x6f.6f66`, aka `7.303.014`. (Hoon syntax uses `.` to break
58−integer atoms in the German style, because `.`'s are URL-safe and `,`'s
59−aren't.)
60−
61−One common operation on nouns is `slot`, a tree addressing
62−scheme which maps an atom to a subtree. The whole noun is slot
63−`1`; the left child of `n` is `2n`, the right child `2n+1`.
64−
65−Nothing in Nock, Hoon, or Urbit can create cycles in a noun or
66−detect pointer equivalence. Nouns are generally implemented
67−with reference counting, and have a lazy short Merkle hash to
68−help with equality testing and associative containers.
69−
70−### <a name="-nock">`nock`</a> (interpreter)
71−
72−Hoon compiles itself to the [Nock](../../nock) VM. Nock is a
73−Turing-complete, non-lambda combinator function. The function
74−takes a cell `{subject formula}`, and produces a noun `product`.
75−
76−To program in Hoon, this is all you need to know about Nock. But
77−it's still fun and useful to [learn more](../../nock).
78−
79−## Compilation concepts
80−
81−### <a name="-hoon">`hoon`</a> (AST node)
82−
83−A [`hoon`](../reference) is the result of parsing a Hoon source
84−expression into an AST node. These AST nodes are nouns, like all
85−other Hoon data. Because every Hoon program is, in its entirety, a
86−single expression of Hoon, the result of parsing the whole thing
87−into an AST is a single `hoon`.
88−
89−A hoon is a tagged union of the form `[%tag data]`, where the tag
90−is a constant such as `%brts` (from the source `|=`, i.e. "bartis"),
91−and is matched up with the appropriate type of data (often more
92−`hoon`s, from source subexpressions). For example, the expression
93−`:-(2 17)`, once parsed into an AST, becomes the following:
94−
95−```
96−[%clhp p=[%sand p=%ud q=2] q=[%sand p=%ud q=17]]
97−```
98−
99−The `%clhp` is produced from the rune `:-` (i.e. "colhep"). The 2 and
100−17 have each been parsed as `%sand`-tagged hoons, which represent
101−atoms (in this case each with an aura of `%ud`, i.e. unsigned
102−decimal).
103−
104−To parse Hoon source into a hoon AST, use `ream` on a `cord`
105−containing Hoon source. Try the following in `dojo`:
106−
107−```
108−(ream ':+(12 7 %a)')
109−```
110−
111−The result should be:
112−
113−```
114−[%clls p=[%sand p=%ud q=12] q=[%sand p=%ud q=7] r=[%rock p=%tas q=97]]
115−```
116−
117−### <a name="-mint">`mint`</a> (compiler)
118−
119−[`mint`](#-mint) is the Hoon compiler. It maps a cell `[type hoon]`
120−to a cell `[type nock]`, where a [`type`](#-type) is type
121−information, a [`hoon`](#-hoon) is a parsed expression (AST), and a
122−`nock` is a Nock formula. `mint` takes as input the subject type
123−and a parsed source expression; it produces a product type and an
124−executable formula.
125−
126−Calculating the output type from the input `hoon` and subject type
127−is called "type inference". If you've used another typed functional
128−language, like Haskell, the Hoon compiler's type inference does the
129−same job but with less intelligence.
130−
131−Haskell infers backward and forward; Hoon only infers forward.
132−Hoon can't figure out the type of a noun from how you use it,
133−only from how you make it. Hoon can infer tail recursion, but
134−not head recursion.
135−
136−Low-powered type inference means you need more type annotations,
137−which makes your program more readable anyway. Also, the dumber
138−the compiler, the easier it is for a dumb human to understand
139−what the compiler is thinking.
140−
141−The `mint` gate is inside the core `++ ut`, so call it using the
142−following syntax:
143−
144−```
145−(~(<gate> <core> <arg 1>) <arg 2> <arg 3>)
146−```
147−
148−The `<gate>` is mint, the `<core>` is `ut`, `<arg 1>` is the subject
149−type, and `<arg 3>` is the parsed Hoon AST (i.e., a `hoon` from the
150−last section). What's `<arg 2>`? It's another piece of type
151−information. As part of the type-checking process, mint checks that
152−the output type "nests" within the input type, i.e. that the output
153−type is a subset of the input type. If not, mint halts with a
154−`nest-fail` crash.
155−
156−Let's compile an example `hoon` from the last subsection into Nock.
157−Try the following in Dojo:
158−
159−(~(mint ut %noun) %noun [%clhp p=[%sand p=%ud q=2] q=[%sand p=%ud q=17]])
160−
161−### <a name="-type">`type`</a> (type, as range)
162−
163−A `type` defines a set (finite or infinite) of nouns and ascribes
164−some semantics to it. There is no direct syntax for defining
165−types; they are always defined by inference (i.e., by
166−[`mint`](#-mint)), usually using a constructor (`mold`).
167−
168−All types are assembled out of base types defined in `++type`.
169−(Look up `++ type` in hoon.hoon for examples.) When the compiler
170−does type-inference on a program, it assembles complex types out
171−of the simpler built-in types.
172−
173−### <a name="-gate">`gate`</a> (function)
174−
175−A `gate` is a Hoon function (lambda or closure). Other
176−constructs in Urbit are functions in the mathematical sense -- for
177−instance, a Nock formula is also a function. But a gate is not a
178−formula. The gate's argument is its *sample*; the result is its
179−*product*.
180−
181−### <a name="-core">`core`</a> (object)
182−
183−A `core` has no exact equivalent in conventional languages, but
184−the closest equivalent is an object. An object has methods; a
185−core has functionally computed attributes (*arms*). An arm that
186−produces a gate is the Hoon equivalent of a conventional method;
187−think of it as a computed attribute whose value is a lambda.
188−
189−A gate is a special case of a core: a core with one arm, whose
190−name is the empty string. The shape of a core is `[battery
191−payload]`, where *battery* is a tree of Nock formulas
192−
193−### <a name="-mold">`mold`</a> (constructor)
194−
195−A `mold` is a constructor function (`gate`). Its sample is any
196−noun; its product is a structured noun. A mold is idempotent;
197−`(mold (mold x))` always equals `(mold x)`.
198−
199−Because there's no such thing as a [`type`](#-type) declaration,
200−we use molds to define useful types by example; we also use them
201−to validate untrusted network data.
202−
203−### <a name="-face">`face`</a> (named variable)
204−
205−In a conventional language, we have a scope, environment or
206−symbol table. Declaring a variable, like e.g. `int foo = 3`,
207−adds the name `foo` to the table with type `int`.
208−
209−The Hoon analogue is `=/(foo atom 3 ...)`, where `foo` is a `face`
210−and `atom` is the type. But Hoon has a homoiconic heap; there is no
211−inscrutable scope or environment. There is just the subject, which
212−is one noun. To "declare a variable" is to make a cell
213−`[variable old-subject]`, and use that as the subject of the next
214−expression.
215−
216−The label `foo` isn't a key in a symbol table; it's stored as a kind
217−of metadata, in the type ([`type`](#-type)) of the new value. It's not
218−a variable named `foo`, whose value is of type `atom`; it's a subtree
219−of type `foo:atom`.
220−
221−### <a name="-limb">`limb`</a> (attribute or variable reference)
222−
223−A [`limb`](../limb/limb/), like `foo`, is Hoon's equivalent of a variable
224−reference. A limb is a [`hoon`](#-hoon); given a subject [`type`](#-type),
225−[`mint`](#-mint) resolves it to a Nock formula and a product [`type`](#-type).
226−
227−To resolve limb `foo`, [`mint`](#-mint) searches the subject depth-first,
228−head-first for either a `face` named `foo`, or a `core` with the
229−arm `foo`. If it finds a face, the product is a *leg*, or
230−subtree of the subject. If it finds a core, it computes the arm
231−formula with that core as the subject. A limb can also be a slot
232−(direct tree address), like `+15`.
233−
234−The hoon compiler always resolves a limb to a tree axis lookup,
235−regardless of the kind of limb.
236−
237−`boo:[foo=12 baz=23 boo=34]` evaluates to `34`.
238−`+6:[foo=12 baz=23 boo=34]` evaluates to `baz=23`.
239−
240−### <a name="-wing">`wing`</a> ([`limb`](#-limb) path)
241−
242−A [wing](../limb/wing/) is a list of limbs. Like attribute
243−references in a conventional language, it uses the syntax `a.b.c`,
244−but inside out: Hoon `a.b.c` means "a within b within c", the equivalent
245−of `c.b.a` in any other language. All limbs but the last, here `a`,
246−must be legs.
247−
248−### <a name="-mark">`mark`</a> (type, as protocol name)
249−
250−A `mark` (really an Arvo concept, not a Hoon concept) is Urbit's
251−version of a MIME type, if a MIME type was an executable
252−specification. The mark is just a label that's used as a path to
253−a local source file in the Arvo filesystem. This source file
254−defines a core that can mold untrusted data, diff and patch,
255−convert to other marks, etc.
256−
257−If this sounds like magic, it isn't quite magic. There's no way
258−for different urbits to make sure they mean the same thing by the
259−same mark. However, when incompatibility happens, marks ensure
260−that we at least handle the situation in a predictable way.
docs/hoon/demo.mddeleted−83
@@ -1,83 +0,0 @@
1−---
2−navhome: /docs/
3−sort: 12
4−next: true
5−title: Demo
6−---
7−
8−# Demo
9−
10−Here's everyone's favorite whiteboard example,
11−[FizzBuzz](https://en.wikipedia.org/wiki/Fizz_buzz). Each
12−line is commented with its number:
13−
14−```
15−|= end=@ :: 1
16−=/ count=@ 1 :: 2
17−|- :: 3
18−^- (list tape) :: 4
19−?: =(end count) :: 5
20− ~ :: 6
21−:- :: 7
22− ?: =(0 (mod count 15)) :: 8
23− "FizzBuzz" :: 9
24− ?: =(0 (mod count 5)) :: 10
25− "Fizz" :: 11
26− ?: =(0 (mod count 3)) :: 12
27− "Buzz" :: 13
28− <count> :: 14
29−$(count (add 1 count)) :: 15
30−```
31−
32−When FizzBuzz is written in non-functional languages, the
33−output is generated as a side effect of the program, e.g., with
34−`printf()`. Hoon is a functional language, so technically it
35−has no side effects. Accordingly, the code above *produces* a
36−list of strings; it doesn't print them. (If you run it from the
37−Urbit shell, [_Dojo_](../../using/shell), you will of course be
38−able to see the product.)
39−
40−The code produces a list in which each item is either a number,
41−"Fizz", "Buzz", or "Fizzbuzz". The value `~` is "null" and indicates
42−the end of the list.
43−
44−Line 1 uses the _[rune](../../about/glossary#rune)_ `|=` to define
45−a function that takes one input, `end`. The input value must be of
46−the type `@`, an atom (i.e., an unsigned integer).
47−
48−Line 2 uses `=/` to declare a variable, `count`, as an atom with an
49−initial value of `1`.
50−
51−Line 3 uses `|-` to indicate the starting point of a loop.
52−
53−Line 4 defines the product of the loop as a list of `tape`s.
54−(A `tape` is a list of characters, one of Hoon's two string
55−types.) The rune `^-` is used for defining the type of value the
56−function is required to produce.
57−
58−Line 5 uses the rune `?:` which is an ordinary "if-then-else"
59−conditional. If `=(end count)` evaluates as true, then line 6 is
60−evaluated next. Otherwise line 7 and on is evaluated.
61−
62−If the values of `count` and `end` are equal then line 6 produces the
63−value `~`, indicating the end of the list. The program is finished.
64−
65−If not, line 7 uses the rune `:-` to produce an
66−[ordered pair](https://en.wikipedia.org/wiki/Ordered_pair) of values.
67−The pair created will be `[a b]`: (a) the product of lines 8-14; and
68−(b) the product of line 15.
69−
70−(a) The first value of the pair is: (i) "FizzBuzz", or "Fizz", or
71−"Buzz", if the respective conditional tests hit; otherwise, it's
72−(ii) the number in question, `count`. In case (ii), line 14
73−uses the `< >` symbols to convert `count` from an `@` to a `tape`.
74−
75−(b) The second value of the pair -- i.e., the rest of the output
76−list -- is produced by line 15. This line uses `$()` to loop back
77−to the `|-` in line 3, but with `count` increased in value by `1`.
78−
79−You can test this code for yourself by (i) entering `|mount %` in the
80−Dojo to mount your home desk, if you haven't already done so; (ii)
81−saving the above code as `home/gen/fizzbuzz.hoon` in your Urbit's
82−[pier](../../about/glossary#pier); then (iii) entering `+fizzbuzz 100`
83−in the dojo.
docs/hoon/examples.mddeleted−595
@@ -1,595 +0,0 @@
1−---
2−navhome: /docs/
3−next: true
4−sort: 21
5−title: Examples
6−---
7−
8−# Examples
9−
10−Now we know enough to write two quick examples: the Sieve of
11−Eratosthenes (a naive prime sieve) and a tic-tac-toe engine.
12−
13−(Note that these are not examples of perfect Hoon code; they are
14−meant for teaching. They err, more than usual for Hoon, on the
15−side of simple manual construction over high-octane FP.)
16−
17−## `sieve`: code in basic style
18−
19−A function that produces the list of primes less than or equal to
20−its argument, an atom:
21−
22−```
23−|= thru=@ :: 1
24−^- (list @) :: 2
25−=/ field=(set @) (sy (gulf 2 thru)) :: 3
26−=< abet:main :: 4
27−|% :: 5
28−++ abet :: 6
29− (sort ~(tap in field) lth) :: 7
30−:: :: 8
31−++ main :: 9
32− =/ factor=@ 2 :: 10
33− |- ^+ ..main :: 11
34− ?: (gth (mul factor factor) thru) :: 12
35− ..main :: 13
36− $(factor +(factor), ..main (reap factor)) :: 14
37−:: :: 15
38−++ reap :: 16
39− |= factor=@ :: 17
40− =/ count=@ (mul 2 factor) :: 18
41− |- ^+ ..reap :: 19
42− ?: (gth count thru) :: 20
43− ..reap :: 21
44− %= $ :: 22
45− count (add count factor) :: 23
46− field (~(del in field) count) :: 24
47− == :: 25
48−-- :: 26
49−```
50−
51−## `sieve`: explanation
52−
53−```
54−|= thru=@ :: 1
55−^- (list @) :: 2
56−=/ field=(set @) (sy (gulf 2 thru)) :: 3
57−```
58−
59−Line `1`: we are building a gate (function) whose sample
60−(argument) is `thru`, an atom.
61−
62−Line `2`: the product of this gate is a list of atoms.
63−
64−Line `3`: we introduce a variable `field`, whose type is a set of
65−atoms. The `sy` function converts a list to a set. The `gulf`
66−function creates the range `2` through `thru` inclusive, as a
67−list of atoms.
68−
69−Line `4`: below, we introduce a core which does our work. With
70−reverse flow, we compute `main` on this core, then `abet` on the
71−product of `main`. (`abet:main` means `=<(abet main)`.)
72−
73−The core is a state machine; `main` produces the core itself,
74−with the computation completed. `abet` then extracts the result.
75−
76−```
77−|% :: 5
78−++ abet :: 6
79− (sort ~(tap in field) lth) :: 7
80−```
81−
82−Line `5`: we wrap a core around our existing subject. The
83−`field` and `thru` atoms are within the payload and of course
84−remain accessible.
85−
86−Lines `6` and `7`: the `abet` arm, which produces the field as a
87−sorted list. `in` is the set core; `tap` is an arm that exports
88−the set as a list. We sort this list in ascending order with
89−`lth` (less-than).
90−
91−```
92−++ main :: 9
93− =/ factor=@ 2 :: 10
94− |- ^+ ..main :: 11
95−```
96−
97−Line `9`: the `main` arm, which performs the main calculation.
98−
99−Line `10`: we declare a counter, `factor`, which will iterate
100−up through the factors we're removing.
101−
102−Line `11`: we start a loop. The product of the loop is cast to
103−`..main`, which is the core we're in (`+1.main`).
104−
105−```
106− ?: (gth (mul factor factor) thru) :: 12
107− ..main :: 13
108− $(factor +(factor), ..main (reap factor)) :: 14
109−```
110−
111−Lines `12` and `13`: we terminate the loop, returning `..main`,
112−if the square of the counter exceeds the range.
113−
114−Line `14`: repeats the loop, incrementing the counter, and
115−replacing the core with a version sieved by `reap`.
116−
117−```
118−++ reap :: 16
119− |= factor=@ :: 17
120− =/ count=@ (mul 2 factor) :: 18
121−```
122−
123−Lines `16` and `17`: the `reap` arm, which produces a gate that
124−removes multiples of a factor from the field (set of possible
125−primes). The sample of this gate is the factor to remove.
126−
127−Line `18`: we declare a variable `count`, an atom, with the
128−initial value `(mul 2 factor)`.
129−
130−```
131− |- ^+ ..reap :: 19
132− ?: (gth count thru) :: 20
133− ..reap :: 21
134− %= $ :: 22
135− count (add count factor) :: 23
136− field (~(del in field) count) :: 24
137− == :: 25
138−-- :: 26
139−```
140−
141−Line `19`: we enter a loop. This loop produces the core itself.
142−
143−Lines `20` and `21`: we are done if the counter is out of range.
144−
145−Lines `22` to `25`: repeat the loop, stepping `count` to the next
146−multiple of `factor`, and deleting it from `field`.
147−
148−## `sieve`: code in kernel style
149−
150−Finally, the same code in a more concise "kernel" style.
151−```
152−|= top=@
153−^- (list @)
154−=+ fed=(sy (gulf 2 top))
155−=< abet:main
156−|%
157−++ abet (sort (~(tap in fed)) lth)
158−++ main
159− =+ fac=2
160− |- ^+ ..main
161− ?: (gth (mul fac fac) top)
162− ..main
163− $(fac +(fac), ..main (reap fac))
164−::
165−++ reap
166− |= fac=@
167− =+ cot=(mul 2 fac)
168− |- ^+ ..reap
169− ?: (gth cot top)
170− ..reap
171− $(cot (add cot fac), fed (~(del in fed) cot))
172−--
173−```
174−
175−### `toe`: tic-tac-toe engine
176−
177−The `toe` tic-tac-toe engine applies a list of events to a game
178−state, producing a list of game actions. Events are tic-tac-toe
179−moves (`move)`; actions are tic-tac-toe results (`fact`).
180−
181−```
182−=< |= feed/(list move) :: 1
183− =| game/game :: 2
184− |- ^- (list fact) :: 3
185− ?~ feed ~ :: 4
186− =^ this/(unit fact) :: 5
187− game :: 6
188− (~(do go game) i.feed) :: 7
189− =/ rest/(list fact) $(feed t.feed) :: 8
190− ?~(this rest [u.this rest]) :: 9
191−:: :: 10
192−=> |% :: 11
193− ++ side @ :: 12
194− ++ spot {x/@ y/@} :: 13
195− ++ fact $% {$tie $~} :: 14
196− {$win p/cord} :: 15
197− == :: 16
198− ++ move $% {$x p/spot} :: 17
199− {$o p/spot} :: 18
200− {$z $~} :: 19
201− == :: 20
202− ++ game $: w/? :: 21
203− a/side :: 22
204− z/side :: 23
205− == :: 24
206− -- :: 25
207−|% :: 26
208−++ bo :: 27
209− |_ half/side :: 28
210− ++ bit |=(a/@ =(1 (cut 0 [a 1] half))) :: 29
211− ++ off |=(a/spot (add x.a (mul 3 y.a))) :: 30
212− ++ get |=(a/spot (bit (off a))) :: 31
213− ++ set |=(a/spot (con half (bex (off a)))) :: 32
214− ++ win %+ lien :: 33
215− (rip 4 0wl04h0.4A0Aw.4A00s.0e070) :: 34
216− |=(a/@ =(a (dis a half))) :: 35
217− -- :: 36
218−++ go :: 37
219− |_ game/game :: 38
220− ++ do :: 39
221− |= act/move :: 40
222− ^- {(unit fact) ^game} :: 41
223− ?- act :: 42
224− {$x *} ?>(w.game ~(mo on p.act)) :: 43
225− {$o *} ?<(w.game ~(mo on p.act)) :: 44
226− {$z *} [~ nu] :: 45
227− == :: 46
228− :: :: 47
229− ++ nu ^+(game [& 0 0]) :: 48
230− ++ on :: 49
231− |_ here/spot :: 50
232− ++ is ?| (~(get bo a.game) here) :: 51
233− (~(get bo z.game) here) :: 52
234− == :: 53
235− ++ mo ^- {(unit fact) ^game} :: 54
236− ?< is :: 55
237− =/ next/side (~(set bo a.game) here) :: 56
238− ?: ~(win bo next) :: 57
239− [[~ %win ?:(w.game %x %o)] nu] :: 58
240− [~ game(w !w.game, a z.game, z next)] :: 59
241− -- :: 60
242− -- :: 62
243−-- :: 63
244−```
245−
246−### `toe`: explanation
247−
248−```
249−=< |= feed/(list move) :: 1
250− =| game/game :: 2
251− |- ^- (list fact) :: 3
252− ?~ feed ~ :: 4
253−```
254−
255−Line `1` wraps a conclusion around a stack of cores. The cores
256−at `11` and `26` are the data structures and functions of the
257−engine; the conclusion is the interface and top-level logic. It
258−produces a gate whose sample is `feed`, a list of `move`.
259−
260−Line `2` declares a blank new variable named `game`, whose type
261−is the `game` mold (tic-tac-toe game state) defined on line `21`.
262−Under line `2`, `game` pulls the variable and `^game` the mold.
263−
264−Line `3` enters a loop producing a list of game events, `fact`.
265−
266−Line `4` produces nil, `~`, if `feed` is empty.
267−
268−```
269− =^ this/(unit fact) :: 5
270− game :: 6
271− (~(do go game) i.feed) :: 7
272−```
273−
274−Lines `5` through `7` apply the move. We open a `go` core on the
275−current game state, produce a `do` gate, and call that gate on
276−the move. The product of the `do` gate is a pair; the head is
277−`(unit fact)`, either `~` or `[~ fact]`; the tail is a new
278−`game`. The `=^` hoon declares the head as a new variable,
279−`this`; it modifies the subject by setting `game` to the tail.
280−
281−```
282− =/ rest/(list fact) $(feed t.feed) :: 8
283− ?~(this rest [u.this rest]) :: 9
284−```
285−
286−Line `8` declares a new variable, `rest`, which is all the facts
287−generated by the moves in `t.feed`, the tail of the move list.
288−(Yes, this is gratuitous head recursion.) Line `9` produces
289−`rest` if the `i.feed` move produced no fact; otherwise it
290−prepends the new fact to `rest`.
291−
292−```
293−=> |% :: 11
294− ++ side @ :: 12
295− ++ spot {x/@ y/@} :: 13
296−```
297−
298−Line `11` wraps a library core around a data structure core, a
299−common pattern. (You could put the molds and the gates in the
300−same core, but the compiler couldn't constant-fold gate samples
301−that use these molds, an efficiency cost.)
302−
303−Line `12` defines the `side` mold, an alias for `atom` (`@`).
304−A side is a half of the board, as a marked/unmarked bitfield.
305−
306−Line `13` defines the `spot` mold, a 2D coordinate.
307−
308−```
309− ++ fact $% {$tie $~} :: 14
310− {$win p/cord} :: 15
311− == :: 16
312−```
313−
314−Lines `14` to `16` define the `fact` mold, a game event (i.e.,
315−output action), as a book (tagged union). There are two forms of
316−`fact`: `[%tie ~]` (reporting a tie), and `[%win cord]`
317−(reporting that `'X'` or `'O'` won a game.
318−
319−```
320− ++ move $% {$x p/spot} :: 17
321− {$o p/spot} :: 18
322− {$z $~} :: 19
323− == :: 20
324−```
325−
326−Lines `17` to `20` define the `move` mold, a game move. This is
327−either `[%x spot]`, `[%o spot]`, or `[%z ~]` to reset the board.
328−
329−```
330− ++ game $: w/? :: 21
331− a/side :: 22
332− z/side :: 23
333− == :: 24
334− -- :: 25
335−```
336−
337−Lines `21` to `23` define the `game` mold, the game state. This
338−is an `a` side, the next side to move; a `z` side, the other
339−side; and `w`, which is `&` (yes) if `a` is X and `b` is O; `|`
340−otherwise. (Obviously, we swap `a` and `z` on every move.)
341−
342−```
343−|% :: 26
344−++ bo :: 27
345− |_ half/side :: 28
346− ++ bit |=(a/@ =(1 (cut 0 [a 1] half))) :: 29
347− ++ off |=(a/spot (add x.a (mul 3 y.a))) :: 30
348− ++ get |=(a/spot (bit (off a))) :: 31
349− ++ set |=(a/spot (con half (bex (off a)))) :: 32
350−```
351−
352−Line `26` introduces the library core, which contains the doors
353−`bo` (for `side` bitfields) and `go` (for game state).
354−
355−Lines `27` to `28` begin the `bo` core, a door around `half`, a
356−board side.
357−
358−Line `29` is the `bit` gate, which tests a bit in `half`.
359−
360−Line `30` is the `off` gate, which maps from a `spot` (coordinate)
361−to a bit index.
362−
363−Line `31` is the `get` gate, which produces the bit at a `spot`.
364−
365−Line `32` is the `set` gate, which produces a new side with the
366−bit at a `spot` set. It works by ORing (`con`) `half` with the
367−binary exponent (`bex`) of the offset (`off`) of the spot.
368−
369−```
370− ++ win %+ lien :: 33
371− (rip 4 0wl04h0.4A0Aw.4A00s.0e070) :: 34
372− |=(a/@ =(a (dis a half))) :: 35
373− -- :: 36
374−```
375−
376−Lines `33` to `35` are a victory test. It calls the
377−standard `lien` function, which iterates a boolean gate over a
378−list and produces `&` (yes) if any item tests as true, against a
379−list of magic bitfields (expanded from a base64 constant), each
380−of which must equal itself when ANDed (`dis`) with `half`.
381−
382−```
383−++ go :: 37
384− |_ game/game :: 38
385− ++ do :: 39
386− |= act/move :: 40
387− ^- {(unit fact) ^game} :: 41
388−```
389−
390−Lines `37` to `38` begin the `go` core, a door around a `game`.
391−Again we name the sample `game`. (This is a legitimate style,
392−but not used much.)
393−
394−Lines `40` to `42` begin the `do` gate, whose sample is `act`, a
395−move. The product is cast to a pair of `(unit fact)` and a new
396−game state, written `^game` to skip to the second binding.
397−
398−```
399− ?- act :: 42
400− {$x *} ?>(w.game ~(mo on p.act)) :: 43
401− {$o *} ?<(w.game ~(mo on p.act)) :: 44
402− {$z *} [~ nu] :: 45
403− == :: 46
404− :: :: 47
405−```
406−
407−Lines `42` through `46` switch on the form of `act`. If it's an
408−`%x` or `%o` move, we assert that it's the right turn, then use
409−the `mo` door to apply the move. If it's a `%z` move, we clear
410−the board.
411−
412−```
413− ++ nu ^+(game [& 0 0]) :: 48
414− ++ on :: 49
415− |_ here/spot :: 50
416− ++ is ?| (~(get bo a.game) here) :: 51
417− (~(get bo z.game) here) :: 52
418− == :: 53
419−```
420−
421−Line `48` is the `nu` arm, which produces a blank game state.
422−
423−Lines `49` to `50` begin the `on` door, a door around `here`, a
424−`spot`. Just as we have multiple computed attributes against the
425−game state, we have multiple computed attributes (`is` and `mo`)
426−against the combination of game state and coordinate.
427−
428−Lines `51` to `53` define the `is` arm, which is `&` (yes) if
429−either `a` or `z` has played `here`.
430−
431−```
432− ++ mo ^- {(unit fact) ^game} :: 54
433− ?< is :: 55
434− =/ next/side (~(set bo a.game) here) :: 56
435− ?: ~(win bo next) :: 57
436− [[~ %win ?:(w.game %x %o)] nu] :: 58
437− [~ game(w !w.game, a z.game, z next)] :: 59
438− -- :: 60
439− -- :: 62
440−-- :: 63
441−```
442−
443−Line `54` begins the `mo` arm, which produces (with a
444−nonessential cast) a pair of `(unit fact)` and game state.
445−Again we see `^game` to pull the mold, since `game` is the
446−current game state in the `go` core.
447−
448−Line `55` asserts that no one has yet played `here`.
449−
450−Line `56` declares a variable `next`, as game side `a` with
451−`here` played in it.
452−
453−Lines `57` and `58` test if `a` has won with this move. If so,
454−we produce the win fact and a blank game state.
455−
456−Line `59` produces no fact (since nothing has happened), but
457−inverts the `w` turn indicator, replaces side `a` with the other
458−side `z`, and replaces `z` with `next`.
459−
460−### `toe`: code, kernel style
461−
462−```
463−=< |= fed/(list move)
464− =| mag/game
465− |- ^- (list fact)
466− ?~ fed ~
467− =^ did/(unit fact) mag (~(do go mag) i.fed)
468− =+ res=$(fed t.fed)
469− ?~(did res [u.did res])
470−=> |%
471− ++ side @
472− ++ spot {x/@ y/@}
473− ++ fact $% {$tie $~}
474− {$win p/cord}
475− ==
476− ++ move $% {$x p/spot}
477− {$o p/spot}
478− {$z $~}
479− ==
480− ++ game $: w/?
481− a/side
482− z/side
483− ==
484− --
485−|%
486−++ bo
487− |_ haf/side
488− ++ bit |=(a/@ =(1 (cut 0 [a 1] haf)))
489− ++ get |=(a/spot (bit (off a)))
490− ++ off |=(a/spot (add x.a (mul 3 y.a)))
491− ++ set |=(a/spot (con haf (bex (off a))))
492− ++ win %+ lien
493− (rip 4 0wl04h0.4A0Aw.4A00s.0e070)
494− |=(a/@ =(a (dis a haf)))
495− --
496−++ go
497− |_ mag/game
498− ++ do
499− |= act/move
500− ^- {(unit fact) game}
501− ?- act
502− {$x *} ?>(w.mag ~(mo on p.act))
503− {$o *} ?<(w.mag ~(mo on p.act))
504− {$z *} [~ nu]
505− ==
506− ::
507− ++ nu `game`[& 0 0]
508− ++ on
509− =| her/spot
510− |%
511− ++ is ?| (~(get bo a.mag) her)
512− (~(get bo z.mag) her)
513− ==
514− ++ mo ^- {(unit fact) game}
515− ?< is
516− =+ next=(~(set bo a.mag) her)
517− ?: ~(win bo next)
518− [[~ %win ?:(w.mag %x %o)] nu]
519− [~ mag(w !w.mag, a z.mag, z next)]
520− --
521− --
522−--
523−```
524−
525−## Basic molds
526−```
527−++ atom @ :: just an atom
528−++ axis @ :: tree address
529−++ bean ? :: 0=&=yes, 1=|=no
530−++ bloq @ :: blockclass
531−++ char @tD :: UTF-8 byte
532−++ cord @t :: text atom (UTF-8)
533−++ gate $-(* *) :: general gate
534−++ knot @ta :: ASCII text
535−++ noun * :: any noun
536−++ null $~ :: null, nil, etc
537−++ time @da :: galactic time
538−++ path (list knot) :: eg, fs location
539−++ tang (list tank) :: error trace
540−++ tank ::
541− $% {$leaf p/tape} :: printing formats
542− $: $palm :: backstep list
543− p/{p/tape q/tape r/tape s/tape} ::
544− q/(list tank) ::
545− == ::
546− $: $rose :: flat list
547− p/{p/tape q/tape r/tape} :: mid open close
548− q/(list tank) ::
549− == ::
550− == ::
551−++ tanq :: future tank
552− $? {$~ p/(list tanq)} :: list of printables
553− {$~ $~ p/tape} :: simple string
554− (pair @tas tanq) :: captioned
555− == ::
556−++ tape (list char) :: string as list
557−++ term @tas :: ascii symbol
558−++ wall (list tape) :: text lines (no \n)
559−++ wain (list cord) :: text lines (no \n)
560−
561−::::
562−::::
563−
564−++ tree |* a/gate :: binary tree
565− $@($~ {n/a l/(tree a) r/(tree a)}) ::
566−++ trap |*(a/_* _|?(*a)) :: makes perfect sense
567−++ trel |* {a/gate b/gate c/gate} :: just a triple
568− {p/a q/b r/c} ::
569−++ each |* {a/gate b/gate} :: either a or b
570− $%({$& p/a} {$| p/b}) :: a default
571−
572−++ qual |* {a/gate b/gate c/gate d/gate} :: just a quadruple
573− {p/a q/b r/c s/d} ::
574−++ pair |*({a/gate b/gate} {p/a q/b}) :: just a pair
575−++ quid |*({a/gate b/*} {a _b}) :: for =^
576−++ quip |*({a/gate b/*} {(list a) _b}) :: for =^
577−++ unit |* a/gate :: maybe
578− $@($~ {$~ u/a}) ::
579−++ list |* a/gate :: null-term list
580− $@($~ {i/a t/(list a)}) ::
581−++ lone |*(a/gate p/a) :: just one thing
582−
583−::::
584−::::
585−++ map |* {a/gate b/gate} :: associative tree
586− $@($~ {n/{p/a q/b} l/(map a b) r/(map a b)}) ::
587−++ qeu |* a/gate :: queue
588− $@($~ {n/a l/(qeu a) r/(qeu a)}) ::
589−++ set |* a/gate :: set
590− $@($~ {n/a l/(set a) r/(set a)}) ::
591−++ jar |*({a/gate b/gate} (map a (list b))) :: map of lists
592−++ jug |*({a/gate b/gate} (map a (set b))) :: map of sets
593−```
594−
595−### Basic libraries
docs/hoon/exercises.mddeleted−18
@@ -1,18 +0,0 @@
1−---
2−navhome: /docs/
3−next: true
4−sort: 22
5−title: Exercises
6−---
7−
8−# Exercises
9−
10−The best way to cement this knowledge in your mind is to do
11−exercises. These are roughly in order of ascending difficulty,
12−and they are intended to form a sort of primer to Hoon.
13−
14−Feel free to ask questions in the comments. You can subscribe to the
15−`/comments` `:talk` channel on this ship to keep abreast of the
16−conversation.
17−
18−<list />
docs/hoon/exercises/data-structures.mddeleted−62
@@ -1,62 +0,0 @@
1−---
2−navhome: /docs/
3−sort: 4
4−comments: true
5−---
6−
7−# Sets and Maps
8−
9−Sets are constructed with `++silt`. A set is a non-ordered
10−collection of unique elements.
11−
12−```
13−(silt `(list @t)`['urbit' 'arvo' 'hoon' 'arvo' ~])
14−```
15−
16−We'll refer to this particular set as `s` in the exercises. It
17−is of type `(set @t)` since each element is a `@t`.
18−
19−The `++in` core contains library functions for dealing with sets.
20−For example, `++has:in` checks whether an element is in the set.
21−Thus, `(~(has in s) 'arvo')` returns yes. To complete these
22−exercises, you'll need to refer to the [library reference for
23−`++in`](/docs/hoon/library/2h).
24−
25−1. Create another set, `l`, with members `'c'`, `'hoon'`,
26− `'javacript'`, `'python'`.
27−
28−1. At the dojo, take the union of `s` and `l`. Delete
29− `'javascript'` from the result, and add `'coffeescript'`.
30−
31−1. Create an alphabetized list of the members of the set created
32− in the previous exercise.
33−
34−1. Take the Cartesian product of `s` and `l`. The Cartesian
35− product of two sets is the set of all cells `[a b]` where
36− `a` is in `s` and `b` is in `l`.
37−
38−The `++by` core is to maps as `++in` is to sets. Refer to its
39−[library reference](/docs/hoon/library/2i). Note that since a
40−map is basically a set of pairs (although not every set of pairs
41−is a map), most functions in `++in` have analogues in `++by`.
42−
43−The constructor for maps is `++malt`.
44−
45−```
46−(malt `(list {@t @ud})`[['kaylee' 3] ['wash' 2] ['mal' 4] ['summer' 1] ~])
47−```
48−
49−Let this map be `m`.
50−
51−1. Create another map, `s`, with `'spring'` mapped to `1`,
52− `'summer'` mapped to `2`, `'autumn'` mapped to `'3'`, and
53− `'winter'` mapped to `4`.
54−
55−1. In `m`, change the value at `'mal'` to 5 and add `'cobb'`
56− with value 4.
57−
58−1. Take the union of `m` and `s`, then get the value at the key
59− `summer`. Try taking the union of `s` and `m` (i.e. flip the
60− order) and see if it makes a difference. Try intersecting
61− them in both orders.
62−
docs/hoon/exercises/fizzbuzz.mddeleted−38
@@ -1,38 +0,0 @@
1−---
2−navhome: /docs/
3−sort: 1
4−comments: true
5−---
6−
7−# Friends of FizzBuzz
8−
9−1. Consider the following implementation of FizzBuzz, which is
10− equivalent to the one in the [Demo](../../demo) section.
11−
12− ```
13− |= end/atom
14− =+ count=1
15− |-
16− ^- (list tape)
17− ?: =(end count)
18− ~
19− :-
20− ?: =(0 (mod count 15))
21− "FizzBuzz"
22− ?: =(0 (mod count 5))
23− "Fizz"
24− ?: =(0 (mod count 3))
25− "Buzz"
26− (scow %ud count)
27− $(count (add 1 count))
28− ```
29−
30− Modify this to produce "Fuzz" when the number is divisible by
31− 7, "Fuzz" when divisible by 21, "FuzzFizz" when divisible by 35,
32− and "FuzzFizzBuzz" when divisible by 105.
33−
34−1. Modify FizzBuzz from the previous exercise to take both a
35− start and an end number.
36−
37−1. Modify FizzBuzz from the previous exercise to count down
38− instead of up.
docs/hoon/exercises/life.mddeleted−121
@@ -1,121 +0,0 @@
1−---
2−navhome: /docs/
3−sort: 5
4−comments: true
5−---
6−
7−# Conway's Game of Life
8−
9−Conway's Game of Life is a zero-player game played on an `n`x`n`
10−grid of spaces, each of which is either "alive" or "dead". Every
11−iteration, some or all of the spaces change from alive to dead or
12−from dead to alive.
13−
14−Specifically, for each iteration, each dead space becomes alive
15−if and only if it is adjacent to exactly three live spaces. Each
16−live remains alive if and only if it is adjacent to either two or
17−three live spaces. In this context, "adjacent to" includes the
18−eight spaces that share either a side or a corner with the space.
19−Thus, in the following map, the center space (dead) is adjacent
20−to exactly three live spaces, so it will be alive in the next
21−iteration. `#` signifies a live space and `.` signifies a dead
22−space.
23−
24− ..#
25− ...
26− ##.
27−
28−
29−1. Write a function `next-generation` that takes nine loobean
30− inputs, `nw`, `nc`, `ne`, `cw`, `cc`, `ce`, `sw`, `sc`, and
31− `se`. Produce 'yes' if the center space will be alive in the
32− next generation and 'no' if it will be dead.
33−
34−1. Write a function `create-board` that takes an integer `n` and
35− produces an `n` by `n` grid of loobeans, (hereafter,
36− "board"), initialized to 'no'. This grid should be
37− represented as a list of `n` lists of length `n`.
38−
39−1. Write a function `toggle-space` that takes a board, a row
40− index, and a column index, and produces a new board,
41− identical to the old except that the state of the space
42− referred to by the row and column indices has been toggled.
43−
44−1. Use the following function `print-board` to pretty-print the
45− board. For bonus points, try to follow what it's doing.
46−
47− ```
48− :: XX test
49− |= board/(list (list ?))
50− ^- tang
51− %+ turn board
52− |= row/(list ?)
53− :- %leaf
54− ^- tape
55− %+ turn row
56− |= space/?
57− ?: space
58− '# '
59− '. '
60− ```
61−
62− If you run this function with a board, you'll get a
63− pretty-printable object (a `tang`), but it won't be
64− pretty-printed. When running the generator from the dojo,
65− run `&tang +generator arguments` to mark the result as a
66− `tang`, which will tell the dojo to intelligently
67− pretty-print it.
68−
69−1. Using the functions created in the previous exercises, create
70− a 10 by 10 board, and flip the states of the spaces at
71− coordinates (counting from the top left, indexed from 0)
72− `(2,1)`, `(3,2)`, `(1,3)`, `(2,3)`, and `(3,3)`. Use the
73− pretty printer to print out the board. Your output should be
74− the following:
75−
76− ```
77− . . . . . . . . . .
78− . . # . . . . . . .
79− . . . # . . . . . .
80− . # # # . . . . . .
81− . . . . . . . . . .
82− . . . . . . . . . .
83− . . . . . . . . . .
84− . . . . . . . . . .
85− . . . . . . . . . .
86− . . . . . . . . . .
87− ```
88−
89−1. Write a function `step` that iterates every space on the
90− board. Print out the new board. It should look like this:
91−
92− ```
93− . . . . . . . . . .
94− . . . . . . . . . .
95− . # . # . . . . . .
96− . . # # . . . . . .
97− . . # . . . . . . .
98− . . . . . . . . . .
99− . . . . . . . . . .
100− . . . . . . . . . .
101− . . . . . . . . . .
102− . . . . . . . . . .
103− ```
104−
105− > Note that the spaces on the edge don't have the full nine
106− > neighbors. For now, assume that they're always dead.
107−
108−1. Write a function `life` that runs the above function `n`
109− times on the board. Observe the board as the game
110− progresses. Congratulations, you've written Conway's Game of
111− Life in Hoon!
112−
113−1. One common way to handle the edge of the board is to pretend
114− that it "wraps around", forming a torus. In other words, say
115− that the spaces on the left edge of the map are adjacent to
116− the ones on the right edge, and the spaces on the top edge
117− are adjacent to the spaces on the bottom edge. Modify `step`
118− to act this way. Pay special attention to the corners.
119−
120−1. Modify `create-board` to use `++og` to randomly initialize
121− the board with live or dead spaces.
docs/hoon/exercises/lists.mddeleted−40
@@ -1,40 +0,0 @@
1−---
2−navhome: /docs/
3−sort: 3
4−comments: true
5−---
6−
7−# Lists
8−
9−In the following exercises, let `l` be `` `(list @t)`['u' 'r' 'b'
10−'i' 't' ~]``
11−
12−1. A list is a null-terminated tuple of values. For example,
13− `[1 2 3 ~]` is a list of three integers, and
14− `['a' 'b' 'c' ~]` is a list of three cords. Try casting
15− `['a' 'b' 'c' ~]` to `(list @t)` and to `(list @)`. Lists
16− are parameterized with the type of the values.
17−
18−1. `++flop` takes a list and produces its reverse. Use it to
19− reverse `l`.
20−
21−1. Repeat the above exercise without using `++flop`.
22−
23−1. `++sort` takes a list and a comparison function to sort a
24− list. The function must take two elements of the list and
25− produce true if the first element is "less than" the other.
26− Sort `l` alphabetically. Sort it reverse alphabetically.
27−
28−1. `++turn` takes a list and a function and applies the function
29− to each element in the list, forming a new list of the
30− results. This is called "map" in many functional languages.
31− The function must accept an element of the list. Use the
32− fact that subtracting 32 from a lowercase letter gives the
33− equivalent uppercase letter (i.e. `(sub 'a' 'A')` is 32) to
34− change every character in `l` to uppercase.
35−
36−1. `++welp` concatentates two lists. Concatenate `l` with the
37− reverse of `l`.
38−
39−1. `++snag` takes a number `n` and a list and produces the
40− element at index `n`. Pull out the `'i'` in `l`.
docs/hoon/exercises/math.mddeleted−27
@@ -1,27 +0,0 @@
1−---
2−navhome: /docs/
3−sort: 2
4−comments: true
5−---
6−
7−# Math
8−
9−1. Write a function that produces a list of the first `n`
10− triangular numbers. The `n`th triangular number is the sum
11− of the first `n` positive integers.
12−
13−1. Using the program from the previous exercise, write a
14− function that produces the first `n` tetrahedral numbers.
15− The `n`th tetrahedral number is the sum of the first `n`
16− triangular numbers.
17−
18−1. The Fibonacci numbers are defined on the natural numbers as
19− follows:
20−
21− ```
22− fib(0) = 0
23− fib(1) = 1
24− fib(n) = fib(n-1) + fib(n-2)
25− ```
26−
27− Write a function that computes the `nth` Fibonacci number.
docs/hoon/library.mddeleted−9
@@ -1,9 +0,0 @@
1−---
2−navhome: /docs/
3−sort: 18
4−title: Standard library
5−---
6−
7−# Standard library
8−
9−<list dataPreview="true" titlesOnly="true"></list>
docs/hoon/limb.mddeleted−25
@@ -1,25 +0,0 @@
1−---
2−navhome: /docs/
3−next: true
4−sort: 20
5−title: Limbs and wings
6−---
7−
8−# Limbs and wings
9−
10−One feature Hoon lacks: a context that isn't a first-class value.
11−Hoon has no concept of scope, environment, etc. A hoon has one
12−data source, the *subject*, a noun like any other.
13−
14−In most languages "variable" and "attribute" are different
15−things. They are both symbols, but a variable is in "the
16−environment" and a attribute is on "an object." In Hoon, "the
17−environment" is "an object" -- the subject.
18−
19−`%limb` and `%wing` are two basic hoon stems that extract
20−information from the subject. A `limb` is an attribute; a `wing`
21−is an attribute path, ie, a list of limbs.
22−
23−## Stems
24−
25−<list dataPreview="true" className="runes"></list>
docs/hoon/limb/limb.mddeleted−81
@@ -1,81 +0,0 @@
1−---
2−navhome: /docs/
3−next: true
4−sort: 1
5−title: Limb
6−---
7−
8−# Limb
9−
10−`[%limb p=(each @ud [p=@ud q=@tas])]`: attribute of subject.
11−
12−### Produces
13−
14−If `p` matches `[%& p=@ud]`, slot `p.p` of the subject.
15−
16−If `p` matches `[%| p=@ud q=@tas]`, the `p`th match for `q`,
17−using the search traverse below.
18−
19−### Syntax
20−
21−Irregular: `+15` is slot `15`, `[%& 15]`.
22−
23−Irregular: `.` is slot `1`, the whole subject.
24−
25−Irregular: `&4` is slot `30`, the 4th element of a tuple
26−with at least 5 elements.
27−
28−Irregular: `|4` is slot `31`, the elements that follow `&4`.
29−
30−Irregular: `foobar` is `[%| 0 %foobar]`.
31−
32−Irregular: `^^^foobar` is `[%| 3 %foobar]`.
33−
34−Irregular: `+<-` is "take the tail, then take the head of
35−that, then the head of that." `+` and `>` mean "tail" while
36−`-` and `<` mean "head." This limb syntax starts on `+` or `-`
37−and alternates for readability.
38−
39−### Traverse
40−
41−The search traverse takes a name `q` and a *skip count* `p`.
42−
43−The search product may be an *arm* or a *leg*. A *leg* is a
44−subtree of the subject. An arm defines a Nock formula and a
45−subject leg to compute the result. Logically, a limb is an
46−attribute -- computation or subtree, "synthesized" or "natural"
47−-- of the subject.
48−
49−We search the subject type headfirst, depth-first, and pre-order.
50−If we descend to a `%face` type whose label matches the limb
51−symbol, the descent address is a leg. The type is the type
52−beneath the label. But if the `%face` label differs, the search
53−skips this whole subtree.
54−
55−If we descend into a `%core` type in which the limb symbol is an
56−arm, we produce that arm. If the limb symbol is not bound, we
57−descend into the payload (data) of the core.
58−
59−If the skip count `p` is nonzero, we pretend our first `p`
60−matches are actually mismatches. This lets the programmer "look
61−through" an overriding label. No label anywhere is inaccessible.
62−
63−### Examples
64−
65−The Dojo prompt gives you a subject with a decent namespace.
66−Try
67−
68−```
69−~zod:dojo> now
70−~2016.4.25..01.39.59..a0f0
71−```
72−
73−You can also add variables to the subject, then use them. (Note
74−that `=variable value` is not Hoon (language) syntax; it's Dojo
75−(shell) syntax.)
76−
77−```
78−~zod:dojo> =foo %bar
79−~zod:dojo> foo
80−%bar
81−```
docs/hoon/limb/wing.mddeleted−50
@@ -1,50 +0,0 @@
1−---
2−navhome: /docs/
3−sort: 2
4−title: Wing
5−---
6−
7−# Wing
8−
9−`[%wing p=(list limb)]`; a limb search path.
10−
11−### Produces
12−
13−If `p` is null, the subject at leg `1`. Otherwise, let `x` be
14−the `%wing` of `t.p`. `x` is either an arm or a leg. We compute
15−limb `i.p` on some subject leg `s`, where:
16−
17−If `x` is a leg/slot number, `s` is `x`.
18−
19−If `x` is an arm/subject-formula pair `[s f]`, `s` is `s.x`.
20−
21−### Syntax
22−
23−Irregular: `a.b` finds limb `a` within limb `b` of the subject.
24−
25−### Discussion
26−
27−It may be slightly hard to follow the formal definition above.
28−
29−Intuitively, Hoon wings are written in the opposite order
30−from attribute dot-paths in most languages. Hoon `a.b.c` is Java
31−`c.b.a`; it means "a within b within c."
32−
33−Any item in the wing can resolve to a leg (fragment) or arm
34−(computation). But if a non-terminal item in the wing would
35−resolve to an arm, it resolves instead to the subject of the arm
36−-- in other words, the core exporting that name.
37−
38−The mysterious idiom `..foo` produces the leg `foo` if `foo`
39−is a leg; the core exporting `foo` if `foo` is an arm. Since `.`
40−is the same limb as `+`, `..foo` is the same wing as `+1.foo`.
41−
42−### Examples
43−
44−```
45−~zod:dojo> =a [foo=3 bar=[baz=1 moo=2]]
46−~zod:dojo> bar.a
47−[baz=1 moo=2]
48−~zod:dojo> moo.bar.a
49−2
50−```
docs/hoon/mission.mddeleted−46
@@ -1,46 +0,0 @@
1−---
2−navhome: /docs/
3−sort: 11
4−next: true
5−title: Mission
6−---
7−
8−# Mission
9−
10−Hoon is a strict, typed functional language which compiles itself
11−to [Nock](../../nock), a combinator interpreter whose spec fits
12−on a T-shirt.
13−
14−Hoon's design goal is to support higher-order typed functional
15−programming without category theory, formal logic, or other
16−interesting math. The reasoning: (a) a programming language is a
17−user interface for programmers; (b) most programmers are not very
18−good at math.
19−
20−Hoon is not quite as expressive as Haskell, though fairly close.
21−But good Hoon style isn't good Haskell style. Hoon encourages
22−coders to use higher-order programming as little as possible --
23−again, simply for UI reasons. For example, multiple arguments
24−are curried by default in Haskell and tupled by default in Hoon.
25−The Hoon style has been described as "procedural programming in
26−a functional language."
27−
28−Hoon is objectively simple: its complexity is bounded by the size
29−of the compiler, about 3000 lines of Hoon. This is split evenly
30−between frontend (parsing and macro expansion) and backend (code
31−generation and type inference).
32−
33−Compared to most languages, Hoon has a heavier front end (more
34−complex syntax) and a lighter back end (less complex semantics).
35−This ratio reflects the belief that our brains are better than
36−everyone thinks at learning languages (symbols and/or grammars),
37−and worse at learning abstractions (proofs and/or algorithms).
38−At first glance, Hoon may look gnarly (though its squiggles are
39−more structured than most ASCII-heavy languages). But under the
40−hood, there's much less complexity than you might expect.
41−
42−Keeping the Hoon-to-Nock mapping simple and transparent is a
43−priority. In a sense, Hoon is to Haskell as C is to Pascal.
44−There is no opaque high-level abstraction of Hoon's semantics;
45−the language is what the compiler does. This design only works
46−when the compilation process is trivial or nearly so.
docs/hoon/reference.mddeleted−83
@@ -1,83 +0,0 @@
1−---
2−navhome: /docs/
3−next: true
4−sort: 24
5−title: Expression reference
6−---
7−
8−# Expression reference
9−
10−#### A catalog of expressions:
11−
12−<div class="book">
13−
14−### [Atoms and strings](../atom/)
15−
16−### [Limbs and wings](../limb/)
17−
18−## `. dot` (nock)
19−
20−<list src="../rune/dot" dataPreview="true" className="runes" childIsFragment="true"></list>
21−
22−---
23−
24−## `! zap` (wild)
25−
26−<list src="../rune/zap" dataPreview="true" className="runes" childIsFragment="true"></list>
27−
28−---
29−
30−## `= tis` (flow)
31−
32−<list src="../rune/tis" dataPreview="true" className="runes" childIsFragment="true"></list>
33−
34−---
35−
36−## `? wut` (test)
37−
38−<list src="../rune/wut" dataPreview="true" className="runes" childIsFragment="true"></list>
39−
40−---
41−
42−## `| bar` (core)
43−
44−<list src="../rune/bar" dataPreview="true" className="runes" childIsFragment="true"></list>
45−
46−---
47−
48−## `~ sig` (hint)
49−
50−<list src="../rune/sig" dataPreview="true" className="runes" childIsFragment="true"></list>
51−
52−---
53−
54−## `: col` (cell)
55−
56−<list src="../rune/col" dataPreview="true" className="runes" childIsFragment="true"></list>
57−
58−---
59−
60−## `% cen` (call)
61−
62−<list src="../rune/cen" dataPreview="true" className="runes" childIsFragment="true"></list>
63−
64−---
65−
66−## `^ ket` (cast)
67−
68−<list src="../rune/ket" dataPreview="true" className="runes" childIsFragment="true"></list>
69−
70−---
71−
72−## `$ buc` (mold)
73−
74−<list src="../rune/buc" dataPreview="true" className="runes" childIsFragment="true"></list>
75−
76−---
77−
78−## `; sem` (make)
79−
80−<list src="../rune/sem" dataPreview="true" className="runes" childIsFragment="true"></list>
81−
82−</div>
83−
docs/hoon/rune.mddeleted−77
@@ -1,77 +0,0 @@
1−---
2−navhome: /docs/
3−next: true
4−sort: 17
5−title: Runes
6−---
7−
8−# Runes
9−
10−<div class="book">
11−
12−## `. dot` (nock)
13−
14−<list src="./dot" dataPreview="true" className="runes" childIsFragment="true"></list>
15−
16−---
17−
18−## `! zap` (wild)
19−
20−<list src="./zap" dataPreview="true" className="runes" childIsFragment="true"></list>
21−
22−---
23−
24−## `= tis` (flow)
25−
26−<list src="./tis" dataPreview="true" className="runes" childIsFragment="true"></list>
27−
28−---
29−
30−## `? wut` (test)
31−
32−<list src="./wut" dataPreview="true" className="runes" childIsFragment="true"></list>
33−
34−---
35−
36−## `| bar` (core)
37−
38−<list src="./bar" dataPreview="true" className="runes" childIsFragment="true"></list>
39−
40−---
41−
42−## `~ sig` (hint)
43−
44−<list src="./sig" dataPreview="true" className="runes" childIsFragment="true"></list>
45−
46−---
47−
48−## `: col` (cell)
49−
50−<list src="./col" dataPreview="true" className="runes" childIsFragment="true"></list>
51−
52−---
53−
54−## `% cen` (call)
55−
56−<list src="./cen" dataPreview="true" className="runes" childIsFragment="true"></list>
57−
58−---
59−
60−## `^ ket` (cast)
61−
62−<list src="./ket" dataPreview="true" className="runes" childIsFragment="true"></list>
63−
64−---
65−
66−## `$ buc` (mold)
67−
68−<list src="./buc" dataPreview="true" className="runes" childIsFragment="true"></list>
69−
70−---
71−
72−## `; sem` (make)
73−
74−<list src="./sem" dataPreview="true" className="runes" childIsFragment="true"></list>
75−
76−</div>
77−
docs/hoon/rune/bar.mddeleted−27
@@ -1,27 +0,0 @@
1−---
2−navhome: /docs/
3−next: true
4−sort: 15
5−title: Core | "bar"
6−---
7−
8−# Core `|` "bar"
9−
10−Core hoons are flow hoons. The compiler essentially pins a Nock
11−formula, or battery of formulas, to the subject.
12−
13−All `|` hoons are macros around `%core`. (See the `%core`
14−section in [`type`](../../basic#-core-p-type-q-map-term-type) above.)
15−`%core` uses the subject as the payload of a battery, whose arms are
16−compiled with the core itself as the subject.
17−
18−Four of these hoons (`|=`, `|.`, `|-`, and `|*`) produce a
19−core with a single arm, named `$`. We can recompute this arm
20−with changes, useful for recursion among other things:
21−
22−> `$()` expands to `%=($)` (["cenhep"](../cen/hep)), accepting
23−> a *jogging* body containing a list of changes to the subject.
24−
25−## Hoons
26−
27−<list dataPreview="true" className="runes"></list>
docs/hoon/rune/bar/col.mddeleted−26
@@ -1,26 +0,0 @@
1−---
2−navhome: /docs/
3−next: true
4−sort: 8
5−title: |: "barcol"
6−---
7−
8−# `|: "barcol"`
9−
10−`[%brcl p=hoon q=hoon]`: form a gate with burnt sample.
11−
12−## Expands to
13−
14−```
15−=> ^~ p
16− |. q
17−```
18−
19−## Discussion
20−
21−Note that `p` is a hoon, not a model; `|:` doesn't bunt your sample as
22−[`|=`](../tis) does.
23−
24−## Syntax
25−
26−Regular: *2-fixed*.
docs/hoon/rune/buc.mddeleted−53
@@ -1,53 +0,0 @@
1−---
2−navhome: /docs/
3−next: true
4−sort: 20
5−title: Mold $ "buc"
6−---
7−
8−# Mold `$` "buc"
9−
10−A *mold* is a `gate` (function) that helps us build simple and
11−rigorous data structures. (In fact, since "mold" sounds nasty,
12−we often call molds and mold builders "structures.")
13−
14−## Overview
15−
16−A correct mold is a *normalizer*: an idempotent function across
17−all nouns. If the sample of a gate has type `%noun`, and its
18−body obeys the constraint that for any x, `=((mold x) (mold (mold
19−x)))`, it's a normalizer and can be used as a mold.
20−
21−(Hoon is not dependently typed and so can't check idempotence
22−statically, so we can't actually tell if a mold matches this
23−definition perfectly. This is not actually a problem.)
24−
25−Runes in the `$` family are macros designed for making molds.
26−But any hoon may produce a mold. (This is why `model` is a
27−synonym for `hoon`).
28−
29−Many macros *bunt* a mold, producing `^~(=>(mold $))`. This
30−produces a constant default value. The formal range of a mold
31−(the type of its bunt) is called its *icon*.
32−
33−Molds have two uses: defining simple and rigorous structures, and
34−validating untrusted input data. Validation, though very
35−important, is a rare use case. Except for direct raw input,
36−it's generally a faux pas to rectify nouns at runtime -- or even
37−in userspace.
38−
39−As a structure definition, a mold has three common uses. One,
40−we bunt it for a default value (such as the sample in a gate).
41−Two, the product of some computation is cast to its icon, both
42−checking the type and regularizing it. Three, it's used as a
43−building block in other molds.
44−
45−In any case, since molds are just functions, we can use
46−functional programming to assemble interesting molds. For
47−instance, `(map foo bar)` is a table from mold `foo` to mold
48−`bar`. `map` is not a mold; it's a function that makes a mold.
49−Molds and mold builders are generally described together.
50−
51−## Hoons
52−
53−<list dataPreview="true" className="runes"></list>
docs/hoon/rune/buc/base.mddeleted−34
@@ -1,34 +0,0 @@
1−---
2−navhome: /docs/
3−next: true
4−sort: 1
5−title: Base molds
6−---
7−
8−# Base molds
9−
10−`[%base p=$@(?(%noun %cell %bean %null) [%atom p=aura])]`: trivial molds.
11−
12−## Produces
13−
14−A mold for the base in `p`. `%noun` is any noun; `%atom` is any
15−atom; `%cell` is a cell of nouns; `%bean` is a loobean, ``?(`@f`0
16−`@f`1)``. `%null` is zero with aura `@n`.
17−
18−## Syntax
19−
20−Irregular: `*` makes `,%noun`, `^` makes `,%cell`, `?` makes
21−`,%bean`, `,~` makes `,%null`, `@aura` makes atom `aura`.
22−
23−## Examples
24−
25−```
26−~zod:dojo> (* %foo)
27−7.303.014
28−~zod:dojo> (,~ 0)
29−~
30−~zod:dojo> (^ 0)
31−^
32−~zod:dojo> (@ux [1 1])
33−0x0
34−```
docs/hoon/rune/buc/col.mddeleted−45
@@ -1,45 +0,0 @@
1−---
2−navhome: /docs/
3−next: true
4−sort: 3
5−title: $: "buccol"
6−---
7−
8−# `$: "buccol"`
9−
10−`[%bccl p=(list model)]`: form a mold which recognizes a tuple.
11−
12−## Normalizes
13−
14−The tuple the length of `p`, normalizing each item, defaulting
15−where the tuple does not match.
16−
17−Void if `p` is empty.
18−
19−## Defaults to
20−
21−The tuple the length of `p`, defaulting each items.
22−
23−Crashes if `p` is empty.
24−
25−## Syntax
26−
27−Regular: *running*.
28−
29−Irregular (noun mode): `,[a b c]` is `$:(a b c)`.
30−Irregular (mold mode): `[a b c]` is `$:(a b c)`.
31−
32−## Examples
33−
34−```
35−~zod:dojo> =foo $:(p=@ud q=@tas)
36−
37−~zod:dojo> (foo 33 %foo)
38−[p=33 q=%foo]
39−
40−~zod:dojo> `foo`[33 %foo]
41−[p=33 q=%foo]
42−
43−~zod:dojo> $:foo
44−[p=0 q=%$]
45−```
docs/hoon/rune/buc/hep.mddeleted−35
@@ -1,35 +0,0 @@
1−---
2−navhome: /docs/
3−sort: 10
4−title: $- "buchep"
5−---
6−
7−# `$- "buchep"`
8−
9−`[%bchp p=model q=model]`: mold which normalizes to an example gate.
10−
11−## Expands to
12−
13−```
14−$_ ^|
15−|=(p $:q)
16−```
17−
18−## Syntax
19−
20−Regular: *2-fixed*.
21−
22−## Discussion
23−
24−Since a `$-` ("buchep") is a [`$_` ("buccab")](../cab/), it is not useful for
25−normalizing, just for typechecking. In particular, the existence of `$-`s does
26−*not* let us send gates or other cores over the network!
27−
28−## Examples
29−
30−```
31−~zod:dojo> =foo $-(%foo %bar)
32−
33−~zod:dojo> ($:foo %foo)
34−%bar
35−```
docs/hoon/rune/buc/wut.mddeleted−49
@@ -1,49 +0,0 @@
1−---
2−navhome: /docs/
3−next: true
4−sort: 4
5−title: $? "bucwut"
6−---
7−
8−# `$? "bucwut"`
9−
10−`[%bcwt p=(list model)]`: mold which normalizes a general union.
11−
12−## Normalizes to
13−
14−The first item in `p` which normalizes the sample to itself;
15−otherwise, default.
16−
17−Void, if `p` is empty.
18−
19−## Defaults to
20−
21−The first item in `p`.
22−
23−## Syntax
24−
25−Regular: *running*.
26−
27−Irregular: `?(%foo %bar)` is `$?(%foo %bar)`.
28−
29−## Discussion
30−
31−For a union of atoms, a `$?` ("bucwut") is fine. For more complex nouns,
32−always try to use a [`$%` ("buccen")](../cen/), [`$@` ("bucpat")](../pat/) or
33−[`$^` ("bucket")](../ket/), at least if you expect your mold to be used as a
34−normalizer.
35−
36−## Examples
37−
38−```
39−~zod:dojo> =a ?(%foo %bar %baz)
40−
41−~zod:dojo> (a %baz)
42−%baz
43−
44−~zod:dojo> (a [37 45])
45−%baz
46−
47−~zod:dojo> $:a
48−%baz
49−```
docs/hoon/rune/cen.mddeleted−16
@@ -1,16 +0,0 @@
1−---
2−navhome: /docs/
3−next: true
4−sort: 18
5−title: Call % ("cen")
6−---
7−
8−# Call `%` ("cen")
9−
10−We've already covered [`%wing`](../limb/wing) and [`%limb`](../limb/limb). These are simple
11−forms of the *invocation* family of hoons, `%`, whose general
12−form is `%=` ("centis").
13−
14−## Hoons
15−
16−<list dataPreview="true" className="runes"></list>
docs/hoon/rune/col.mddeleted−16
@@ -1,16 +0,0 @@
1−---
2−navhome: /docs/
3−next: true
4−sort: 17
5−title: Cell : ("col")
6−---
7−
8−# Cell `:` ("col")
9−
10−The `:` ("col") hoons, `:-` and friends, are simple and regular.
11−All `:` hoons expand to `:-` ("colhep"), which makes a pair
12−(just like the Lisp [`cons`](https://en.wikipedia.org/wiki/Cons) operator).
13−
14−## Hoons
15−
16−<list dataPreview="true" className="runes"></list>
docs/hoon/rune/dot.mddeleted−14
@@ -1,14 +0,0 @@
1−---
2−navhome: /docs/
3−next: true
4−sort: 11
5−title: Nock . ("dot")
6−---
7−
8−# Nock `.` ("dot")
9−
10−Anything Nock can do, Hoon can do also.
11−
12−## Hoons
13−
14−<list dataPreview="true" className="runes"></list>
docs/hoon/rune/dot/ket.mddeleted−22
@@ -1,22 +0,0 @@
1−---
2−navhome: /docs/
3−sort: 5
4−title: .^ "dotket"
5−---
6−
7−# `.^ "dotket"`
8−
9−`[%dtkt p=model q=value]`: load from the Arvo namespace with Nock `11`.
10−
11−## Produces
12−
13−The noun whose name is `q`, cast to the icon of `p`.
14−
15−## Discussion
16−
17−Nock has no `11` instruction, of course. But the virtual Nock
18−used to run userspace code does. Nock `11` loads from a
19−typed immutable namespace defined by its virtual context.
20−
21−We don't remold dynamically nouns in a `.^`, but we do check
22−that the type of the value nests in `p`.
docs/hoon/rune/dot/tar.mddeleted−41
@@ -1,41 +0,0 @@
1−---
2−navhome: /docs/
3−next: true
4−sort: 1
5−title: .* "dottar"
6−---
7−
8−# `.* "dottar"`
9−
10−`[%dttr p=hoon q=hoon]`: evaluate with Nock `2`.
11−
12−## Produces
13−
14−Nock of formula `q` and subject `p`, with type `%noun`.
15−
16−## Syntax
17−
18−Regular: *2-fixed*.
19−
20−## Discussion
21−
22−Note that `.*` ("dottar") can be used to bypass the type system,
23−though its product contains no type information. It's
24−perfectly practical to use Hoon as a typeless language.
25−
26−## Examples
27−
28−```
29−~zod:dojo> .*([20 30] [0 2])
30−20
31−~zod:dojo> .*(33 [4 0 1])
32−34
33−~zod:dojo> .*(|.(50) [9 2 0 1])
34−50
35−~zod:dojo> .*(12 [7 [`1 [4 `1]] [`2 `3 `2]])
36−[12 13 12]
37−~zod:dojo> .*(~ [5 1^4 [4 1^3]])
38−0
39−~zod:dojo> .*(~ [5 1^5 [4 1^3]])
40−1
41−```
docs/hoon/rune/dot/wut.mddeleted−27
@@ -1,27 +0,0 @@
1−---
2−navhome: /docs/
3−next: true
4−sort: 2
5−title: .? "dotwut"
6−---
7−
8−# `.? "dotwut"`
9−
10−`[%dtwt p=hoon]`: test for cell or atom with Nock `3`.
11−
12−## Produces
13−
14−`&`, `%.y`, `0` if `p` is a cell; otherwise `|`, `%.n`, `1`.
15−
16−## Syntax
17−
18−Regular: *1-fixed*.
19−
20−## Examples
21−
22−```
23−~zod:dojo> .?(42)
24−%.n
25−~zod:dojo> .?([42 43])
26−%.y
27−```
docs/hoon/rune/ket.mddeleted−19
@@ -1,19 +0,0 @@
1−---
2−navhome: /docs/
3−next: true
4−sort: 19
5−title: Cast ^ ("ket")
6−---
7−
8−# Cast `^` ("ket")
9−
10−[`^-` ("kethep")](./hep/), [`^+` ("ketlus")](./lus/), and
11−[`^=` ("kettis")](./tis/) let us adjust types without violating type
12−constraints.
13−
14−The `nest` algorithm which tests subtyping is conservative;
15−it never allows invalid nests, it sometimes rejects valid nests.
16−
17−## Hoons
18−
19−<list dataPreview="true" className="runes"></list>
docs/hoon/rune/ket/lus.mddeleted−26
@@ -1,26 +0,0 @@
1−---
2−navhome: /docs/
3−next: true
4−sort: 2
5−title: ^+ "ketlus"
6−---
7−
8−# `^+ "ketlus"`
9−
10−`[%ktls p=value q=value]`: typecast by example (hoon).
11−
12−## Produces
13−
14−The value of `q` with the type of `p`, if the type of `q` nests
15−within the type of `p`. Otherwise, `nest-fail`.
16−
17−## Syntax
18−
19−Regular: *2-fixed*.
20−
21−## Examples
22−
23−```
24−~zod:dojo> ^+('text' %a)
25−'a'
26−```
docs/hoon/rune/sem.mddeleted−13
@@ -1,13 +0,0 @@
1−---
2−navhome: /docs/
3−sort: 21
4−title: Make ; ("sem")
5−---
6−
7−# Make `;` ("sem")
8−
9−Miscellaneous useful macros.
10−
11−## Hoons
12−
13−<list dataPreview="true" className="runes"></list>
docs/hoon/rune/sem/fas.mddeleted−21
@@ -1,21 +0,0 @@
1−---
2−navhome: /docs/
3−sort: 4
4−title: ;/ "semfas"
5−---
6−
7−# `;/ "semfas"`
8−
9−`[%smfs p=hoon]`: tape as XML element.
10−
11−## Expands to
12−
13−```
14−~[%$ ~[%$ 'p']]
15−```
16−
17−## Examples
18−```
19−~zod/try=> :/"foo"
20−[[%~. [%~. "foo] ~] ~]
21−```
docs/hoon/rune/sig.mddeleted−15
@@ -1,15 +0,0 @@
1−---
2−navhome: /docs/
3−next: true
4−sort: 16
5−title: Hint ~ ("sig")
6−---
7−
8−# Hint `~` ("sig")
9−
10−Runes that use Nock `10` to pass non-semantic info to the
11−interpreter.
12−
13−## Hoons
14−
15−<list dataPreview="true" className="runes"></list>
docs/hoon/rune/tis.mddeleted−35
@@ -1,35 +0,0 @@
1−---
2−navhome: /docs/
3−next: true
4−sort: 13
5−title: Flow = ("tis")
6−---
7−
8−# Flow `=` ("tis")
9−
10−Flow hoons change the subject. (Or more precisely, a flow hoon
11−compiles at least one of its subhoons with a different subject.)
12−All non-flow hoons (except cores) pass the subject down unchanged.
13−
14−## Overview
15−
16−The simplest way to change the subject is to compose two hoons,
17−`p` and `q`. Let `x` be `(mint subject p)`, with product type
18−`p.x` and nock formula `q.x`. Let `y` be `(mint p.x q)`. Then
19−their composition is `[p.y [7 q.x q.y]]`.
20−
21−This composition is the `=>` ("tisgar") rune. A close relative is
22−`=+` ("tislus"), which is `=>` over `[p .]`. The new subject is a
23−cell of `p` and the old subject. `=+` is the simplest Hoon equivalent of
24−"declaring a variable" (introducing new data into the subject).
25−
26−Another way to change the subject is to mutate it. With the
27−`=.` ("tisdot") rune, given a wing that resolves to a leg, we can write
28−instead of reading, *installing* a new value at that leg. Of
29−course, we are creating a copy, not modifying the original.
30−
31−There are many flow stems, all small variations on these three.
32−
33−## Hoons
34−
35−<list dataPreview="true" className="runes"></list>
docs/hoon/rune/tis/dot.mddeleted−39
@@ -1,39 +0,0 @@
1−---
2−navhome: /docs/
3−next: true
4−sort: 10
5−title: =. "tisdot"
6−---
7−
8−# `=. "tisdot"`
9−
10−`[%tsdt p=wing q=hoon r=hoon]`: change one leg in the subject.
11−
12−## Expands to
13−
14−```
15−=>(%_(. p q) r)
16−```
17−
18−## Syntax
19−
20−Regular: *3-fixed*.
21−
22−## Discussion
23−
24−As usual, we are not actually mutating the subject, just creating
25−a new subject with a changed value. Note that the mutation uses
26−[`%_` ("cencab")](../../cen/cab/), so the type doesn't change.
27−
28−## Examples
29−
30−```
31−~zod:dojo> =+ a=[b=1 c=2]
32− =. b.a 3
33− a
34−[b=3 c=2]
35−
36−~zod:dojo> =+ a=[b=1 c=2]
37− =.(b.a 3 a)
38−[b=3 c=2]
39−```
docs/hoon/rune/tis/gar.mddeleted−27
@@ -1,27 +0,0 @@
1−---
2−navhome: /docs/
3−next: true
4−sort: 1
5−title: => "tisgar"
6−---
7−
8−# `=> "tisgar"`
9−
10−`[%tsgr p=hoon q=hoon]`: compose two hoons.
11−
12−## Produces
13−
14−`q`, compiled against the product of `p`.
15−
16−## Syntax
17−
18−Regular: *2-fixed*.
19−
20−## Examples
21−
22−```
23−~zod:dojo> =>([a=1 b=2 c=3] b)
24−2
25−~zod:dojo> =>((add 2 4) [. .])
26−[6 6]
27−```
docs/hoon/rune/zap.mddeleted−12
@@ -1,12 +0,0 @@
1−---
2−navhome: /docs/
3−next: true
4−sort: 12
5−title: Wild ! ("zap")
6−---
7−
8−# Wild `!` ("zap")
9−
10−## Hoons
11−
12−<list dataPreview="true" className="runes"></list>
docs/hoon/rune/zap/gar.mddeleted−30
@@ -1,30 +0,0 @@
1−---
2−navhome: /docs/
3−next: true
4−sort: 3
5−title: !> "zapgar"
6−---
7−
8−# `!> "zapgar"`
9−
10−`[%zpgr p=hoon]`: wrap a noun in its type.
11−
12−## Produces
13−
14−A cell whose tail is `p`, and whose head is the static type of p.
15−
16−## Syntax
17−
18−Regular: *1-fixed*.
19−
20−## Discussion
21−
22−In Hoon, dynamic type is static type compiled at runtime. This
23−type-noun cell is generally called a `vase`.
24−
25−## Examples
26−
27−```
28−~zod:dojo> !>(1)
29−[p=#t/@ud q=1]
30−```
docs/hoon/rune/zap/tis.mddeleted−29
@@ -1,29 +0,0 @@
1−---
2−navhome: /docs/
3−next: true
4−sort: 2
5−title: != "zaptis"
6−---
7−
8−# `!= "zaptis"`
9−
10−`[%zpts p=hoon]`: make the Nock formula for a hoon.
11−
12−## Produces
13−
14−The Nock generated by `p`.
15−
16−## Syntax
17−
18−Regular: *1-fixed*.
19−
20−## Examples
21−
22−```
23−~zod:dojo> !=(20)
24−[1 20]
25−~zod:dojo> !=(~zod)
26−[1 0]
27−~zod:dojo> !=((add 2 2))
28−[8 [9 3.110.356 0 31] 9 2 [0 4] [7 [0 3] 1 2 2] 0 11]
29−```
docs/hoon/syntax.mddeleted−391
@@ -1,391 +0,0 @@
1−---
2−navhome: /docs/
3−sort: 13
4−next: true
5−title: Syntax
6−---
7−
8−# Hoon syntax
9−
10−Hoon's syntax is unusual, and to beginners it can look a lot more
11−complex than it really is. However, we believe that anyone who
12−learns Hoon syntax will find that it has a number of advantages.
13−
14−# Motivation
15−
16−Hoon syntax is trying to solve three serious
17−problems in functional syntax design. These are *terminator
18−piles*, *indentation creep*, and *feature/label confusion*.
19−
20−## Terminator piles
21−
22−*Terminator piles* are like Lisp's stacks of right parentheses.
23−Significant whitespace solves this problem and creates others.
24−
25−Hoon has no terminator piles. Except for a 1-space / more-space
26−distinction, it has no significant whitespace.
27−
28−## Indentation creep
29−
30−*Indentation creep* is a problem caused by indentation conventions
31−where the indentation point is a function of expression tree
32−depth. This problem is especially irritating when working with
33−long functions. It's true that short functions are better, but
34−long ones sometimes need to be written.
35−
36−A procedural block has a backbone of statements which flows
37−straight down. Most expressions are flat and of limited depth.
38−With some bulging, a long function flows *down* the page.
39−
40−A functional language lacks the expression/statement distinction.
41−So a long function means a deep tree. Given normal indentation
42−conventions, a long function wants to flow *down and across*.
43−This *diagonal* shape fits poorly into most editor windows.
44−
45−Thanks to backstep indentation (see below), Hoon programs are
46−shaped more or less like procedural programs.
47−
48−## Feature/label confusion
49−
50−*Feature/label confusion* (FLC) is the result of any syntax that
51−makes it hard for the eye to tell whether a token on the screen is
52−a feature of the language, or a label in the program. For example,
53−in Lisp a special form has the same syntax as a function call.
54−
55−The worst-case result of FLC is "DSL cancer." Every source file
56−is effectively written in its own domain-specific language. To
57−read a new file is to learn a new language&mdash;"write-only code."
58−
59−User-level macros, operator overloading, even excessive use of
60−higher-order programming, can all lead quickly to the tragedy of
61−write-only code.
62−
63−Hoon has no FLC, user-level macros, or overloading. It does
64−support higher-order programming; write-only Hoon can certainly be
65−(and has been) written. But good Hoon style is to avoid it.
66−
67−# Design
68−
69−Hoon has a general syntax design with common principles and
70−regularities. We'll cover those here.
71−
72−## Glyphs and characters
73−
74−Hoon source uses ASCII text. Hoon does not accept non-ASCII
75−text in source files, except UTF-8 in quoted strings. Hard
76−tab characters are illegal.
77−
78−Hoon is a heavy punctuation user. Reading off code aloud
79−using the proper names of ASCII symbols is tedious, so we've
80−mapped each punctuation glyph to a syllable:
81−
82−```
83−ace [1 space] gal < pal (
84−bar | gap [>1 space, nl] par )
85−bas \ gar > sel [
86−buc $ hax # sem ;
87−cab _ hep - ser ]
88−cen % kel { sig ~
89−col : ker } soq '
90−com , ket ^ tar *
91−doq " lus + tec `
92−dot . pam & tis =
93−fas / pat @ wut ?
94−zap !
95−```
96−
97−You don't need to memorize these glyph names, but it might help.
98−Code is often vocalized or subvocalized. "pal" is easier to say,
99−aloud or silently, than "left paren".
100−
101−Note that the list includes two separate whitespace forms: `ace`
102−for a single space; `gap` is either 2+ spaces or a newline. In Hoon,
103−the only significance in whitespace is the difference between
104−`ace` and `gap`. Comments also count as `gap` whitespace&mdash;they
105−start with `::` and run to the end of the line.
106−
107−An 80-column right margin is strongly encouraged. Really
108−well-groomed Hoon uses a 55-column code margin and puts a standard
109−line comment at column 57.
110−
111−## Expressions and Runes
112−
113−Each regular Hoon expression begins with a
114−[rune](../about/glossary/#-rune). A rune is a pair
115−of ASCII punctuation marks (a digraph)&mdash;e.g., `:-`. The first
116−glyph in the rune indicates the category&mdash;e.g., `:` runes make
117−[cells](../about/glossary/#-cell) (i.e., ordered
118−pairs). We pronounce runes using their glyph names&mdash;for `:-`,
119−we say "colhep".
120−
121−Each rune is followed by one or more subexpressions. The number and
122−kind of subexpressions depend on the rune used.
123−
124−```
125−:- 25
126−3
127−```
128−
129−This Hoon uses `:-` to produce a cell: `[25 3]`. There are always two
130−subexpressions following the `:-` in syntactically correct Hoon code,
131−the first of which, when evaluated, becomes the *head* (i.e., the left)
132−and the second of which becomes the *tail* (i.e., the right).
133−
134−Hoon expressions are just called
135−[hoons](../about/glossary/#-a-hoon), because a rune's subexpression can itself
136−be a Hoon expression (i.e. another rune). You'll start to see this tree-like,
137−recursive structure the more you program in Hoon. You can think of one Hoon
138−file being composed of multiple hoons. The subexpressions following the
139−rune are sometimes called the *children* of that hoon.
140−
141−## Tall and flat forms
142−
143−There are two kinds of Hoon expression syntax: *tall* and *flat*.
144−Most runes can be used in both tall and flat hoons. Tall hoons can
145−contain flat hoons, but not vice versa.
146−
147−The `:-` expression in the last subsection was in tall form. Here's
148−the flat equivalent:
149−
150−`:-(25 3)`
151−
152−Visually, a tall hoon looks like a "statement" and a flat hoon
153−like an "expression," preserving the attractive visual shape of
154−procedural code without the nasty side effects.
155−
156−## Regular and irregular forms
157−
158−Most runes have *regular forms*, which share a common design.
159−There is a regular flat form and a regular tall form; most runes
160−have both kinds of implementation. All tall forms are regular.
161−
162−Some runes also have *irregular forms*, which follow no
163−principles at all. All irregular forms are flat.
164−
165−```
166−.= 22
167−23
168−```
169−
170−The `.=` rune tests for equality the two subexpressions that
171−follow, and returns a boolean. Above is the tall, regular form of
172−`.=`. Below is the irregular form:
173−
174−`=(22 23)`
175−
176−Some hoons have *only* irregular forms.
177−
178−## Tall regular form
179−
180−Tall regular forms start with a rune followed by a `gap`.
181−(Remember, a `gap` is any whitespace other than `ace`.) After
182−that are the number and types of subexpressions appropriate for
183−that rune. Each subexpression is separated from its neighboring
184−subexpressions by a `gap`.
185−
186−Let's call everything in the hoon after the initial rune the hoon
187−*body*. There are four body subtypes: *fixed*, *running*, *jogging*,
188−and *[battery](../about/glossary/#-battery)*.
189−
190−Runes with a *fixed* number of subexpressions self-terminate. For
191−instance, the `:-` and `.=` runes each have two subexpressions
192−and are self-terminating. Otherwise the hoon is terminated by both
193−a `gap`, then either `==` (*running* or *jogging*, most hoons) or
194−`--` (*battery*).
195−
196−The *running* body has a list of *children* (i.e., subexpressions).
197−The *jogging* body has a list of child pairs, where the members of
198−each pair are separated by a `gap`. The *battery* body is
199−a list of symbol-child pairs, separated by a gap, prefixed by `++`
200−and then a gap.
201−
202−This definition is enough to write Hoon that will parse. But
203−writing code with optimal whitespace management requires some
204−additional informal conventions.
205−
206−Whitespace design in Hoon is an art, not a science. It involves
207−both tall/flat mode switches and well-shaped gaps. (Hoon layout
208−could probably be done automatically with reasonable quality.
209−But it would at least take machine learning, not a rule engine.)
210−
211−There are only two real *rules* in Hoon whitespace design: don't
212−go past 80 characters, and don't use (completely) blank lines.
213−Otherwise, if it looks good and is easy to read, it's good. The
214−best way to learn the art is to do everything by convention
215−until you know what you're doing. Here are the conventions:
216−
217−### Conventions: *fixed*
218−
219−Rune bodies with *fixed* fanout use "backstep" indentation, which
220−slopes backward and to the right by two spaces per line. The first
221−hoon child is two spaces after the end of the rune.
222−
223−Some *1-fixed*, *2-fixed*, *3-fixed* and *4-fixed* examples:
224−
225−```
226−|.
227−p
228−
229−=| p
230−q
231−
232−?: p
233− q
234−r
235−
236−%^ p
237− q
238− r
239−s
240−```
241−
242−In optimal usage of backstep indentation, the most complicated hoons
243−are at the bottom, keeping code flow vertical rather than diagonal.
244−
245−### Conventions: *running*
246−
247−A *running* hoon body (a simple child list) puts the first child two
248−spaces after the end of the rune, and the following children straight
249−down:
250−
251−A *running* example:
252−
253−```
254−:* p
255− q
256− r
257− s
258− t
259−==
260−```
261−
262−### Conventions: *jogging*
263−
264−A *jogging* hoon body (a list of child pairs) is like a running
265−body, but with a pair of children on each line, separated by
266−two spaces. Most jogging bodies start with a *fixed* sequence;
267−the first jogging pair is below and two steps backward from the
268−last fixed child.
269−
270−There are two jogging conventions: *flat* (pair on one line) and
271−*tall* (pair split across lines).
272−
273−A *flat jogging* example (preceded by *1-fixed* `p`)
274−
275−```
276−?- p
277− q r
278− s t
279− u v
280−==
281−```
282−
283−A *tall jogging* example (preceded by *1-fixed* `p`):
284−
285−```
286−?- p
287− q
288− r
289− s
290− t
291− u
292− v
293−==
294−```
295−
296−### Conventions: *battery*
297−
298−A *battery* body has a list of symbol-child pairs, for the
299−[battery](../about/glossary/#-battery)
300−of a
301−[core](../about/glossary/#-core). A
302−conventional example:
303−
304−```
305−|%
306−++ dry-arm-foo
307− %p
308−++ dry-arm-bar
309− %q
310−+- wet-arm-baz
311− %r
312−--
313−```
314−
315−## Flat regular form
316−
317−Flat regular form starts with the rune, followed by `pal`, `(`
318−(left parenthesis), followed by a body whose subexpressions
319−are separated by `ace` (one space), followed by `par`, `)` (right
320−parenthesis).
321−
322−A hoon in flat form, `?:` ("wutcol"), `[%if p=hoon q=hoon r=hoon]`:
323−
324−`?:(p q r)`
325−
326−The only exception is *jogging* bodies, in which subexpression
327−pairs are separated by commas:
328−
329−```
330−foo(bar 42, baz 55, moo 17)
331−```
332−
333−There is no flat regular form for *battery* bodies. Be tall.
334−
335−## Naming conventions
336−
337−Hoon does not enforce any rule on symbols, except that capitals
338−are not allowed (use kebab-case). However, a lot of system code
339−is written using "lapidary" conventions that need explanation.
340−
341−Naming things is one of the hard problems in CS. Dodging this
342−problem is one of the reasons mathematicians use Greek letters,
343−not variable names. Meaningful names also interpose a verbal
344−interpretation, distracting at best and confusing at worst, on
345−the formula or algorithm. Greek letters are not *meaningful*,
346−but they are *memorable*. And their interpretation is defined by
347−the formula and nothing else.
348−
349−### Lapidary and ultralapidary
350−
351−In the *lapidary* naming style, labels are pronounceable
352−three-letter strings, usually CVC (consonant-vowel-consonant).
353−Sometimes they encode a mnemonic, but usually they are just
354−memorable. Labels are reused wherever the analogy seems
355−appropriate.
356−
357−In the *ultralapidary* naming style, labels are single letters,
358−starting in order of construction from `a`, or within a tuple
359−[mold](../about/glossary/#-mold) `p`. Hoon
360−uses single-letter names for the same reason Algol style
361−languages pass arguments by order, rather than keyword. Naming
362−items by order makes sense when there are no more than three or
363−four; five is stretching it; six is outright ridiculous.
364−
365−For example, when defining `add`, we want to name the operands
366−`a` and `b`. It's silly to call them `foo` and `bar`, let alone
367−`left-operand` and `right-operand`. The smaller the scale of an
368−algorithm, the simpler its names should be.
369−
370−### When in doubt, don't be lapidary
371−
372−This works in the other direction: namelessness doesn't scale.
373−Most normal code shouldn't use lapidary naming at all. (Everyone
374−agrees: there is *way* too much lapidary Hoon in Urbit.)
375−
376−Lapidary naming is only for *inherently simple code*: code that
377−both aspires to high elegance and clarity, and *is solving a
378−simple and elegant problem*.
379−
380−Given an ugly or complex problem, lapidary naming is a liability,
381−no matter the excellence of the programmer. When in doubt, use
382−long names and/or kebab-case.
383−
384−## Freedom
385−
386−If you came all this way to learn how to write apps, you're all
387−set. This is about all you need to know to start getting your
388−hands dirty. Refer back here or to the [standard library](../library/) when
389−needed, but for now, move on to [Arvo](../../arvo/) to continue learning.
390−
391−If, however, good enough is *not* enough, feel free to dive deeper:
docs/nock.mddeleted−12
@@ -1,12 +0,0 @@
1−---
2−navhome: /docs/
3−next: true
4−sort: 4
5−title: Nock
6−---
7−
8−# Nock
9−
10−Nock is our nano-VM. If you want to understand the foundation of Urbit, dive in.
11−
12−<list/>
docs/reference.umdnew file+11
@@ -0,0 +1,11 @@
1+:- :~ navhome/'/docs/'
2+ sort/'4'
3+ title/'Reference'
4+ ==
5+;>
6+
7+# Reference
8+
9+Various reference documents are stored here, particularly for Hoon, but also for other parts of the system.
10+
11+;list;
docs/hoon/advanced.md → docs/reference/advanced.umdrenamed+36−33
@@ -1,49 +1,54 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ navuptwo/'true'
4−sort: 16
3+ sort/'5'
5−title: Advanced types
4+ title/'Advanced Types'
6−---
5+ ==
6+;>
7
7
8# Advanced types
8# Advanced types
9
9
10−As we noted, the definition of `type` in the last chapter is a
11−subset. The Hoon type system is simple, but not *that* simple.
10+The definition of `type` in the 'Basic Types' section is only a simplified version. The Hoon type system is simple, but not *that* simple.
12
11
13The good news is that you can *skip this section*, at least when
12The good news is that you can *skip this section*, at least when
14you're first learning Hoon. Polymorphism and aliasing are mainly
13you're first learning Hoon. Polymorphism and aliasing are mainly
15for advanced programmers writing complex infrastructure and/or
14for advanced programmers writing complex infrastructure and/or
16large functions. Don't worry about them for a little while.
15large functions. Don't worry about them for a little while.
17
16
18−## The complete, uncensored `type`
17+## The Full Version of `$type`
19
18
20```
19```
20++$ type $~ %noun
21−++ type $@ $? %noun
21+ $@ $? %noun
22 %void
22 %void
23− == $% [%atom p=term q=(unit atom)]
24− [%cell p=type q=type]
25− [%core p=type q=coil]
26− [%face p=$@(term tune) q=type]
27− [%fork p=(set type)]
28− [%hold p=type q=hoon]
29 ==
23 ==
24+ $% [$atom p=term q=(unit @)]
25+ [$cell p=type q=type]
26+ [$core p=type q=coil]
27+ [$face p=$@(term tune) q=type]
28+ [$fork p=(set type)]
29+ [$hint p=(pair type note) q=type]
30+ [$hold p=type q=hoon]
31+ ==
30::
32::
31−++ coil $: p=?(%gold %iron %lead %zinc)
33++$ coil $: p=[p=(unit term) q=poly r=vair]
32 q=type
34 q=type
33− r=[p=?(~ ^) q=(map term foot)]
35+ r=[p=seminoun q=(map term tome)]
34− ==
36+::
35−++ foot $% [%dry p=hoon]
37++$ poly ?(%wet %dry)
36− [%wet p=hoon]
38++$ vair ?($gold $iron $lead $zinc)
37− ==
39++$ tome (pair what (map term hoon))
38−++ tune
40++$ tune
41+ $~ [~ ~]
39 $: p=(map term (unit hoon))
42 $: p=(map term (unit hoon))
40 q=(list hoon)
43 q=(list hoon)
41 ==
44 ==
42```
45```
43
46
44If you compare this to the basic `type`, you'll see that we've
47If you compare this to the basic `type`, you'll see that we've
45−changed two stems: `%core` and `%face`. We added polymorphism to
48+changed two parts: `%core` and `%face`. We added polymorphism to
46−`%core`, aliases and bridges to `%face`.
49+`%core`, and aliases and bridges to `%face`.
50+
51+(We also added `%hint` for hint expressions.)
47
52
48## `%core`: advanced polymorphism
53## `%core`: advanced polymorphism
49
54
@@ -64,9 +69,7 @@ the payload the core was compiled with is `q.q`.
64
69
65In the Bertrand Meyer tradition of type theory, there are two
70In the Bertrand Meyer tradition of type theory, there are two
66forms of polymorphism: variance and genericity. In Hoon this
71forms of polymorphism: variance and genericity. In Hoon this
67−choice is per arm, which is why our battery went from `(map term
68−hoon)` to `(map term foot)` when it went into the coil. A `foot`
69−is `%dry` or `%wet`. Dry polymorphism relies on variance; wet
72+choice is per core, hence the `poly` label in `coil`: it can be either `%wet` or `%dry`. Dry polymorphism relies on variance; wet
70polymorphism relies on genericity.
73polymorphism relies on genericity.
71
74
72### Dry arms
75### Dry arms
@@ -77,8 +80,8 @@ test as in `^-` ("kethep") or any type comparison (`nest`). Intuitively,
77we ask: "is the new payload compatible with the old payload?"
80we ask: "is the new payload compatible with the old payload?"
78
81
79For a core `a`, if `p.a` fits in `q.q.a`, we can use arms on the
82For a core `a`, if `p.a` fits in `q.q.a`, we can use arms on the
80−core. The product of a dry arm whose hoon is `b` is always
83+core. The product of a dry arm whose expression is `b` is always
81−defined as `[%hold a(p q.q.a, p.q %gold) b]`.
84+defined as `[%hold a(p q.q.a, r.p.q %gold) b]`.
82
85
83In other words, the subject of the arm computation is the
86In other words, the subject of the arm computation is the
84original core type. The type of the modified payload, `p`, is
87original core type. The type of the modified payload, `p`, is
@@ -101,7 +104,7 @@ variance. Again, this is traditional Meyer type theory; don't
101worry if you don't know it. These rules should make sense if you
104worry if you don't know it. These rules should make sense if you
102just think about them intuitively.
105just think about them intuitively.
103
106
104−Each core has a "metal" `p.q` which defines its variance model.
107+Each core has a "metal" `r.p.q` which defines its variance model.
105A core can be *invariant* (`%gold`), *bivariant* (`%lead`),
108A core can be *invariant* (`%gold`), *bivariant* (`%lead`),
106*covariant* (`%zinc`), or *contravariant* (`%iron`). The default
109*covariant* (`%zinc`), or *contravariant* (`%iron`). The default
107is gold; a gold core can be cast or converted to any metal, and
110is gold; a gold core can be cast or converted to any metal, and
@@ -183,13 +186,13 @@ of secret superpowers for hacking the namespace. Remember that
183Hoon doesn't have anything like a symbol table; to resolve a
186Hoon doesn't have anything like a symbol table; to resolve a
184limb, we just search the type depth-first.
187limb, we just search the type depth-first.
185
188
186−If a name is in the `p.p` map, it's an alias. The map contains a
189+If a name is in the `p.p` map, it's an alias. (An alias is defined using the `=*` rune.) The map contains a
187`(unit hoon)`; if the unit is full, the name resolves to that
190`(unit hoon)`; if the unit is full, the name resolves to that
188hoon (compiled against the `q` type). If the unit is empty,
191hoon (compiled against the `q` type). If the unit is empty,
189the name is blocked / skipped (see [limb](../limb/) for what
192the name is blocked / skipped (see [limb](../limb/) for what
190this means).
193this means).
191
194
192−If a name is in the `q.p` map, it's a bridge. When we search for
195+If a name is in the `q.p` map, it's a bridge. (A bridge is defined using the `=,` rune.) When we search for
193a name, we also compile the bridge, and check if the name
196a name, we also compile the bridge, and check if the name
194resolves against the bridge product. If so, we use it.
197resolves against the bridge product. If so, we use it.
195
198
docs/reference/basic.umdnew file+154
@@ -0,0 +1,154 @@
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3+ sort/'4'
4+ title/'Basic Types'
5+ ==
6+;>
7+
8+# Basic types
9+
10+A type is usually understood to be a set of values. Hoon values are all nouns, so a Hoon type is a set of nouns.
11+
12+Hoon's type system conducts various type-checks at compile time in order to ensure type safety. For example, one's program might have an integer squaring function, such that given some atom `n` the return value is `n^2`. The output value should be an unsigned integer (i.e., an atom). Hoon uses type inference on the expression that defines the squaring function in to determine what possible values it could produce. If the inferred type 'nests' under the desired type then the program compiles; otherwise the compile fails with a `nest-fail` crash.
13+
14+(For an introduction on how to use Hoon's type system, see Chapter 2 of the Hoon tutorial.)
15+
16+In this document we discuss the recursive data structure Hoon uses for type inference. Because the Hoon compiler is written in Hoon this structure is likewise defined in Hoon.
17+
18+## `$type`
19+
20+Below is a simplified version the `+$ type` arm, which defines the data structure Hoon uses to keep track of types. But this data structure is used for more than simply type inference. It also handles the resolution of names, including both faces and arm names. (See Chapter 1 of the Hoon tutorial for an introduction to name resolution.)
21+
22+As noted, this is a simplified version of `type`. We undo and
23+explain the simplifications in the [advanced types](../advanced)
24+section.
25+
26+```
27++$ term @tas
28++$ type $~ %noun
29+ $@ $? %noun
30+ %void
31+ ==
32+ $% [%atom p=term q=(unit @)]
33+ [%cell p=type q=type]
34+ [%core p=type q=(map term hoon)]
35+ [%face p=term q=type]
36+ [%fork p=(set type)]
37+ [%hold p=type q=hoon]
38+ ==
39+```
40+
41+Effectively this structure defines a set of nouns that Hoon uses to keep track track of (1) type information, and (2) name resolution information. This set of nouns is recursively defined.
42+
43+### `?(%noun %void)`
44+
45+`%noun` is the label for a noun about which nothing else is known. Every piece of Hoon data is a noun, so everything nests under `%noun`.
46+
47+`%void` is the label for the empty set.
48+
49+### `[%cell p=type q=type]`
50+
51+`[%cell p=type q=type]` is for cells. The `type` of the head is labelled `p` and the tail `type` is `q`.
52+
53+### `[%fork p=(set type)]`
54+
55+`[%fork p=(set type)]` is for the union of all types in the set `p`. That is, when the type of an expression is known to be a `%fork`, the expression must evaluate as one of the types in `p`.
56+
57+Hoon uses branching (usually with conditional runes of the `?` family) for type inference in order to rule out which of the types in `p` can apply.
58+
59+### `[%hold p=type q=hoon]`
60+
61+A `%hold` type, with type `p` and hoon `q`, is a lazy reference to the type of `(mint p q)`. In English, it means: "the type of the product when we compile Hoon expression `q` against a subject with type `p`."
62+
63+### `[%face p=term q=type]`
64+
65+A `[%face p=term q=type]` wraps the label `p` around the type `q`. `p` is a `term` or `@tas`, an atomic ASCII string which obeys symbol rules: lowercase and digit only, infix hyphen, first character must be a lowercase letter.
66+
67+### `[%atom p=term q=(unit atom))]`
68+
69+`%atom` is for an atom, with two twists. `q` is a `unit`, Hoon's
70+equivalent of a nullable pointer or a Haskell `Maybe`. If `q`
71+is `~`, null, the type is *warm*; any atom is in the type.
72+If `q` is `[~ x]`, where `x` is any atom, the type is *cold*;
73+its only legal value is the constant `x`.
74+
75+`p` in the atom is a terminal used as an *aura*, or soft atom
76+type. Auras are a lightweight, advisory representation of the
77+units, semantics, and/or syntax of an atom. An aura is an atomic
78+string; two auras are compatible if one is a prefix of the other.
79+
80+For instance, `@t` means UTF-8 text (LSB low), `@ta` means ASCII
81+text, and `@tas` means an ASCII symbol. `@u` means an unsigned
82+integer, `@ud` an unsigned decimal, `@ux` an unsigned
83+hexadecimal. You can use a `@ud` atom as a `@u` or vice versa,
84+but not as a `@tas`.
85+
86+Auras can also end with an optional, capitalized suffix, which
87+defines the atom's bitwidth as a log starting from `A`. For
88+example, `@udD` is an unsigned decimal byte; `@uxG` is an
89+unsigned 64-bit hexadecimal.
90+
91+You can make up your own auras and are encouraged to do so, but
92+here are some conventions bound to constant syntax:
93+
94+```
95+@c UTF-32 codepoint
96+@d date
97+ @da absolute date
98+ @dr relative date (ie, timespan)
99+@n nil
100+@p phonemic base (plot)
101+@r IEEE floating-point
102+ @rd double precision (64 bits)
103+ @rh half precision (16 bits)
104+ @rq quad precision (128 bits)
105+ @rs single precision (32 bits)
106+@s signed integer, sign bit low
107+ @sb signed binary
108+ @sd signed decimal
109+ @sv signed base32
110+ @sw signed base64
111+ @sx signed hexadecimal
112+@t UTF-8 text (cord)
113+ @ta ASCII text (knot)
114+ @tas ASCII text symbol (term)
115+@u unsigned integer
116+ @ub unsigned binary
117+ @ud unsigned decimal
118+ @uv unsigned base32
119+ @uw unsigned base64
120+ @ux unsigned hexadecimal
121+```
122+
123+Auras are truly soft; you can turn any aura into any other,
124+statically, by casting through the empty aura `@`. Hoon is not
125+dependently typed and can't statically enforce data constraints
126+(for example, it can't enforce that a `@tas` is really a symbol).
127+
128+### `[%core p=type q=(map term hoon)]`
129+
130+`%core` is for a code-data cell. The data (or *payload*) is the
131+tail; the code (or *battery*) is the head. `p`, a type, is the
132+type of the payload. `q` is a mapping of arm names and Hoon expressions. It is the source code for the core battery.
133+
134+(For an introduction to cores and arms, see Chapter 1 of the Hoon tutorial.)
135+
136+Each expression in the battery source is compiled to a formula, with
137+the core itself as the subject. The battery is a tree of these
138+formulas, or *arms*. An arm is a computed attribute against its
139+core.
140+
141+All code-data structures in normal languages (functions, objects,
142+modules, etc) become cores in Hoon. A Hoon battery looks a bit
143+like a method table, but not every arm is a "method" in the OO
144+sense. An arm is a computed attribute. A method is an arm whose
145+product is a Hoon function (or *gate*).
146+
147+A gate (function, lambda, etc) is a core with one arm, whose name
148+is the empty symbol `$`, and a payload whose shape is `[sample
149+context]`. The *context* is the subject in which the gate was
150+defined; the *sample* is the argument.
151+
152+To call this function on an argument `x`, replace the sample (at
153+tree address `6` in the core) with `x`, then compute the arm.
154+(Of course, we don't mutate the noun, we make a mutant copy.)
docs/hoon/cheat-sheet.md → docs/reference/cheat-sheet.umdrenamed+9−8
@@ -1,19 +1,20 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−sort: 26
2+ sort/'8'
4−title: Cheat sheet
3+ title/'Cheat sheet'
5−---
4+ ==
5+;>
6
6
7# Hoon cheat sheet
7# Hoon cheat sheet
8+
8##### `~rovnys-ricfer`
9##### `~rovnys-ricfer`
9
10
10−_Original Fora post_ [*here*](https://urbit.org/fora/posts/~2017.9.18..22.31.06..24d5~).
11+_Original Fora post_ [here](https://urbit.org/fora/posts/~2017.9.18..22.31.06..24d5~).
11
12
12−<br />
13+;br;
13
14
14[Download .pdf](https://storage.googleapis.com/media.urbit.org/docs/hoon-cheat-sheet--2017-12-12.pdf)
15[Download .pdf](https://storage.googleapis.com/media.urbit.org/docs/hoon-cheat-sheet--2017-12-12.pdf)
15
16
16−<br />
17+;br;
17
18
18We've found it's useful to have a quick reference of Hoon's syntax always at
19We've found it's useful to have a quick reference of Hoon's syntax always at
19hand. So above is a download link to a Hoon cheatsheet .pdf. It's missing a
20hand. So above is a download link to a Hoon cheatsheet .pdf. It's missing a
docs/about/glossary.md → docs/reference/glossary.umdrenamed+381−278
@@ -1,9 +1,10 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−navuptwo: true
2+ navuptwo/'true'
4−sort: 5
3+ sort/'1'
5−title: Glossary
4+ title/'Glossary'
6−---
5+ ==
6+
7+;>
7
8
8# Glossary
9# Glossary
9
10
@@ -13,39 +14,45 @@ from the strange words within.
13As Dijkstra put it: "The purpose of abstraction is not to be vague, but
14As Dijkstra put it: "The purpose of abstraction is not to be vague, but
14to create a new semantic level in which one can be absolutely precise."
15to create a new semantic level in which one can be absolutely precise."
15
16
17+;h3
16−### application
18+ ;div(id "application"): application
19+==
17
20
18−Also known as an “app,” an *application* is a Hoon program that can hold state.
21+Also known as an “app,” an _application_ is a Hoon program that can hold state.
19
22
23+;h3
20−### arm
24+ ;div(id "arm"): arm
25+==
21
26
22−An *arm* is a named, functionally-computed attribute of a [core](#-core).
27+An _arm_ is a named, functionally-computed attribute of a [core](#core).
23
28
24−The [hoon](#-a-hoon) of each arm is compiled to a Nock formula, with the
29+The [hoon](#a-hoon) of each arm is compiled to a Nock formula, with the
25−enclosing [core](#-core) itself as the subject.
30+enclosing [core](#core) itself as the subject.
26
31
27−There are two kinds of arms: *dry* and *wet*. Most arms are
32+There are two kinds of arms: _dry_ and _wet_. Most arms are
28dry.
33dry.
29
34
30−- ##### dry:
35+- ##### dry:
31
36
32− normal, `++`, polymorphic by means of *variance*
37+ normal, `++`, polymorphic by means of _variance_
33
38
34− For a dry arm, we ask: is the new payload compatible with the old
39+ For a dry arm, we ask: is the new payload compatible with the old
35− payload (against which the core was compiled)?
40+ payload (against which the core was compiled)?
36
41
37−- ##### wet:
42+- ##### wet:
38
43
39− unusual, `+-`, polymorphic by means of *genericity*
44+ unusual, `+-`, polymorphic by means of _genericity_
40
45
41− A wet arm uses the hoon as a macro. We create a new type analysis
46+ A wet arm uses the hoon as a macro. We create a new type analysis
42− path, which works as if we expanded the callee with the caller's
47+ path, which works as if we expanded the callee with the caller's
43− context.
48+ context.
44
49
45−*See [advanced types](../../hoon/advanced/)*.
50+_See [advanced types](../../hoon/advanced/)_.
46
51
47
52
53+;h3
48−### Arvo
54+ ;div(id "arvo"): Arvo
55+==
49
56
50The Urbit operating system and kernel. Arvo's state is a pure function of its
57The Urbit operating system and kernel. Arvo's state is a pure function of its
51event log, and it serves as the Urbit event manager. It contains vanes, which are
58event log, and it serves as the Urbit event manager. It contains vanes, which are
@@ -53,141 +60,146 @@ kernel modules that perform essential system operations. Arvo itself can only
53deal with one file at a time. For more, it relies on Ford, the build-system
60deal with one file at a time. For more, it relies on Ford, the build-system
54vane.
61vane.
55
62
56−Arvo being purely functional means that the it is a function that is:
63+Arvo being purely functional means that the it is a function that is:
57
64
58−> (state, event) → (state, effects).
65+`(state, event) → (state, effects)`
59
66
60Arvo coordinates and reloads vanes. It can be thought of as a traffic-director.
67Arvo coordinates and reloads vanes. It can be thought of as a traffic-director.
61Any vane needs to go through Arvo before reaching another vane. Events and
68Any vane needs to go through Arvo before reaching another vane. Events and
62their effects happen like so:
69their effects happen like so:
63
70
64−> Unix event → vere (the virtual machine that runs Urbit) → Arvo → vane → Arvo
71+`Unix event → vere (the virtual machine that runs Urbit) → Arvo → vane → Arvo`
65
72
66−Arvo is located in `/home/sys/arvo.hoon` within your urbit.
73+Arvo is located in `/home/sys/arvo.hoon` within your urbit.
67
74
68More in-depth information on Arvo can be found
75More in-depth information on Arvo can be found
69[`here`](https://urbit.org/docs/arvo/internals/).
76[`here`](https://urbit.org/docs/arvo/internals/).
70
77
71Below are Arvo modules, which are called "vanes".
78Below are Arvo modules, which are called "vanes".
72
79
73−- #### Ames
80+- ##### Ames
74−
75−The networking vane. Ames handles all things UDP. Here live the protocols for
76−discovering and interacting with other urbits. It’s also the name for the Urbit
77−network itself. All communication is signed and encrypted.
78
81
79−Ames is located in `/home/sys/vane/ames.hoon` within your urbit.
82+ The networking vane. Ames handles all things UDP. Here live the protocols for
83+ discovering and interacting with other urbits. It’s also the name for the Urbit
84+ network itself. All communication is signed and encrypted.
80
85
81−More in-depth information on Ames can be found
86+ Ames is located in `/home/sys/vane/ames.hoon` within your urbit.
82−[`here`](https://urbit.org/docs/arvo/internals/ames/commentary/).
83
87
84−- #### Behn
88+ More in-depth information on Ames can be found
89+ [`here`](https://urbit.org/docs/arvo/internals/ames/commentary/).
85
90
86−The timing vane. Behn allows for applications to schedule events, which are
91+- ##### Behn
87−managed in a simple priority queue. For example, Clay, the Urbit filesystem,
88−uses Behn to keep track of time-specific file requests. Eyre, the Urbit web
89−vane, uses Behn for timing-out HTTP sessions.
90
92
91−Behn is located in `/home/sys/vane/behn.hoon` within your urbit.
93+ The timing vane. Behn allows for applications to schedule events, which are
94+ managed in a simple priority queue. For example, Clay, the Urbit filesystem,
95+ uses Behn to keep track of time-specific file requests. Eyre, the Urbit web
96+ vane, uses Behn for timing-out HTTP sessions.
92
97
93−- #### Clay
98+ Behn is located in `/home/sys/vane/behn.hoon` within your urbit.
94
99
95−The filesystem and typed revision-control vane. Think of Clay as a
100+- ##### Clay
96−continuously synced git. It handles file-change events and maps them from Urbit
97−to Unix and vice versa.
98
101
99−A common way to use it is to create a pier, a directory that exists in and is
102+ The filesystem and typed revision-control vane. Think of Clay as a
100−visible in Unix. Changes are automatically recorded from Urbit to the Unix
103+ continuously synced git. It handles file-change events and maps them from Urbit
101−directory, and vice versa. Just set it and forget it!
104+ to Unix and vice versa.
102
105
103−Clay is located at `/home/sys/vane/clay.hoon` within your urbit.
106+ A common way to use it is to create a pier, a directory that exists in and is
107+ visible in Unix. Changes are automatically recorded from Urbit to the Unix
108+ directory, and vice versa. Just set it and forget it!
104
109
105−Basic information on using Clay can be found
110+ Clay is located at `/home/sys/vane/clay.hoon` within your urbit.
106−[`here`](https://urbit.org/docs/using/filesystem/). An in-depth explanation
107−of the architecture can be found
108−[`here`](https://urbit.org/docs/arvo/internals/clay/architecture/).
109
111
110−- #### Dill
112+ Basic information on using Clay can be found
113+ [`here`](https://urbit.org/docs/using/filesystem/). An in-depth explanation
114+ of the architecture can be found
115+ [`here`](https://urbit.org/docs/arvo/internals/clay/architecture/).
111
116
112−The terminal-driver vane. You run your urbit in your Unix terminal, and
117+- ##### Dill
113−Unix sends every event -- such as a keystroke or a change in the dimensions of
114−the terminal window -- to be handled by Dill. Dill acts as an intermediary for
115−anything that uses keyboard events. This is why there’s some input lag in
116−Urbit’s command-line interface. (Optimization will come later!)
117
118
118−A keyboard event's journey from Unix to Dojo, the Urbit shell, can be imagined
119+ The terminal-driver vane. You run your urbit in your Unix terminal, and
119− as diagrammed below:
120+ Unix sends every event -- such as a keystroke or a change in the dimensions of
121+ the terminal window -- to be handled by Dill. Dill acts as an intermediary for
122+ anything that uses keyboard events. This is why there’s some input lag in
123+ Urbit’s command-line interface. (Optimization will come later!)
120
124
125+ A keyboard event's journey from Unix to Dojo, the Urbit shell, can be imagined
126+ as diagrammed below:
127+ ```
121−> Keystroke in Unix terminal -> Vere (virtual machine) -> Arvo -> Dill ->
128+ Keystroke in Unix -> Vere (virtual machine) -> Arvo -> Dill -> the Dojo
122−> the Dojo
129+ ```
123
130
124−Dill is located at `/home/sys/vane/clay.hoon` within your urbit.
131+ Dill is located at `/home/sys/vane/clay.hoon` within your urbit.
125
132
126−More in-depth information on Eyre can be found
133+ More in-depth information on Eyre can be found
127−[`here`](https://urbit.org/docs/arvo/internals/dill/).
134+ [`here`](https://urbit.org/docs/arvo/internals/dill/).
128
135
129−- #### Eyre
136+- ##### Eyre
130
137
131−The web-server vane. Anything HTTP-related lives here. Unix sends HTTP messages
138+ The web-server vane. Anything HTTP-related lives here. Unix sends HTTP messages
132−though to Eyre, and Eyre produces HTTP messages in response.
139+ though to Eyre, and Eyre produces HTTP messages in response.
133
140
134−In general, apps and vanes do not call Eyre; rather, Eyre calls apps and vanes.
141+ In general, apps and vanes do not call Eyre; rather, Eyre calls apps and vanes.
135−Eyre uses Ford and Gall to functionally publish pages and facilitate
142+ Eyre uses Ford and Gall to functionally publish pages and facilitate
136−communication with apps.
143+ communication with apps.
137
144
138−Eyre is located at `/home/sys/vane/eyre.hoon` within your urbit.
145+ Eyre is located at `/home/sys/vane/eyre.hoon` within your urbit.
139
146
140−More in-depth information on Eyre can be found
147+ More in-depth information on Eyre can be found
141−[`here`](https://urbit.org/docs/using/web/).
148+ [`here`](https://urbit.org/docs/using/web/).
142
149
143−- #### Ford
150+- ##### Ford
144
151
145−The build-system vane. Ford is capable of sequencing generic asynchronous
152+ The build-system vane. Ford is capable of sequencing generic asynchronous
146−computations. Its uses include linking source files into programs, assembling
153+ computations. Its uses include linking source files into programs, assembling
147−live-updating websites, and performing file-type conversions.
154+ live-updating websites, and performing file-type conversions.
148
155
149−Ford neither accepts Unix events nor produces Unix effects. It exists
156+ Ford neither accepts Unix events nor produces Unix effects. It exists
150−entirely for the benefit of Urbit applications and other vanes, in particular
157+ entirely for the benefit of Urbit applications and other vanes, in particular
151−Gall.
158+ Gall.
152
159
153−Ford is located at `/home/sys/vane/ford.hoon` within your urbit.
160+ Ford is located at `/home/sys/vane/ford.hoon` within your urbit.
154
161
155−More in-depth information on Ford can be found
162+ More in-depth information on Ford can be found
156−[`here`](https://urbit.org/docs/arvo/internals/ford/).
163+ [`here`](https://urbit.org/docs/arvo/internals/ford/).
157
164
158−- #### Gall
165+- ##### Gall
159
166
160−The application-management vane. Userspace apps -- daemons, really -- are
167+ The application-management vane. Userspace apps -- daemons, really -- are
161−started, stopped, and sandboxed by Gall. Gall provides developers with a
168+ started, stopped, and sandboxed by Gall. Gall provides developers with a
162−consistent interface for hooking their app up to the operating system. It allows
169+ consistent interface for hooking their app up to the operating system. It allows
163−applications and other vanes to send messages to applications and subscribe to
170+ applications and other vanes to send messages to applications and subscribe to
164−data streams. Messages coming into Gall are routed to the intended application,
171+ data streams. Messages coming into Gall are routed to the intended application,
165−and the response comes back along the same route. If the intended target is on
172+ and the response comes back along the same route. If the intended target is on
166−another ship, Gall will route it, behind the scenes, through Ames to the other
173+ another ship, Gall will route it, behind the scenes, through Ames to the other
167−ship.
174+ ship.
168
175
169−Gall is located at `/home/sys/vane/gall.hoon` within your urbit.
176+ Gall is located at `/home/sys/vane/gall.hoon` within your urbit.
170
177
171−More in-depth information on Ford can be found
178+ More in-depth information on Ford can be found
172−[`here`](https://urbit.org/docs/arvo/internals/gall/).
179+ [`here`](https://urbit.org/docs/arvo/internals/gall/).
173
180
174### atom
181### atom
175
182
176An atom is any natural number, including zero. The atom is the most basic data
183An atom is any natural number, including zero. The atom is the most basic data
177−type in [Nock](#-nock) and [Hoon](#-hoon). A Hoon atom type describes a Nock
184+type in [Nock](#nock) and [Hoon](#hoon). A Hoon atom type describes a Nock
178−atom with two additional pieces of metadata: an [*aura*](#-aura), and an
185+atom with two additional pieces of metadata: an [_aura_](#aura), and an
179optional constant.
186optional constant.
180
187
181−An atom type is *warm* or *cold* based on whether the constant exists.
188+An atom type is _warm_ or _cold_ based on whether the constant exists.
189+
190+- ##### warm:
191+
192+ If the constant is `~` (null), any atom is in the type.
182
193
183−- ##### warm:
184− if the constant is `~` (null), any atom is in the type.
185−- ##### cold:
194+- ##### cold:
186− if the constant is `[~ atom]`, its only legal value is `atom`.
187
195
188−*See [basic types](../../hoon/basic/#-atom-p-term-q-unit-atom)*
196+ If the constant is `[~ atom]`, its only legal value is `atom`.
189
197
190−### Aura
198+_See [basic types](../../hoon/basic/#-atom-p-term-q-unit-atom)_
199+
200+;h3
201+ ;div(id "aura"): aura
202+==
191
203
192An aura a soft atom type. They appear as strings beginning with `@`. Auras
204An aura a soft atom type. They appear as strings beginning with `@`. Auras
193represent the structure of an atom, print format, or other semantics. Its
205represent the structure of an atom, print format, or other semantics. Its
@@ -196,9 +208,11 @@ constraints on the value of an atom aren't enforced in any way.
196You can cast something to an aura, like a decimal, and get back its hexademical.
208You can cast something to an aura, like a decimal, and get back its hexademical.
197For example:
209For example:
198
210
211+```
199 > =a `@`29
212 > =a `@`29
200 > ^- @ux a
213 > ^- @ux a
201− 0x1d
214+ 0x1d
215+```
202
216
203Auras are an advisory type system. You can go up or down, but not sideways in
217Auras are an advisory type system. You can go up or down, but not sideways in
204the hierarchy. `@t` and `@` can each be cast to the other, but @t can’t be cast
218the hierarchy. `@t` and `@` can each be cast to the other, but @t can’t be cast
@@ -206,11 +220,13 @@ to `@u`, for example, without first being cast to the empty aura `@`.
206
220
207For example
221For example
208
222
223+```
209 > ^- @ 'c' :: 'c' is of the aura @t
224 > ^- @ 'c' :: 'c' is of the aura @t
210 99
225 99
211
226
212 > ^- @u 'c'
227 > ^- @u 'c'
213 ! exit
228 ! exit
229+```
214
230
215Here is a non-exhaustive list of auras:
231Here is a non-exhaustive list of auras:
216
232
@@ -258,7 +274,7 @@ we write `^- (list @)`. The irregular form of that expression is ``(list @)``.
258
274
259### cell
275### cell
260
276
261−In Nock and Hoon, a *cell* is an ordered pair of [nouns](#-noun).
277+In Nock and Hoon, a _cell_ is an ordered pair of [nouns](#noun).
262
278
263Syntax: `[a b]`.
279Syntax: `[a b]`.
264
280
@@ -271,31 +287,39 @@ Cells orient to the right; for example, the noun [2 6 14 15] is short for
271A clam is the use of a structure as a gate. Usually used to verify marks from
287A clam is the use of a structure as a gate. Usually used to verify marks from
272other urbits.
288other urbits.
273
289
290+```
274 > ((list @t) [97 98 ~])
291 > ((list @t) [97 98 ~])
275 <|a b|>
292 <|a b|>
293+```
276
294
277### cord
295### cord
278
296
279In Hoon, `cord` is an aura for representing atoms as strings. UTF-8,
297In Hoon, `cord` is an aura for representing atoms as strings. UTF-8,
280least-significant bit first. Represented as the aura `@t`.
298least-significant bit first. Represented as the aura `@t`.
281
299
300+```
282 > `@t`478.560.413.032
301 > `@t`478.560.413.032
283 'hello'
302 'hello'
303+```
284
304
305+;h3
285−#### core
306+ ;div(id "core"): core
307+==
286
308
287−A *core* is a [cell](#-nock-cell) of `[code data]`, where we call the
309+A _core_ is a [cell](#nock-cell) of `[code data]`, where we call the
288−code head the *battery* and the data tail the *payload*. All code-data
310+code head the _battery_ and the data tail the _payload_. All code-data
289structures in normal languages (functions, objects, modules, etc.)
311structures in normal languages (functions, objects, modules, etc.)
290translate to cores in Hoon.
312translate to cores in Hoon.
291
313
292−- ##### battery
314+- ##### battery
315+
293− The code-containing head of a core.
316+ The code-containing head of a core.
317+
318+- ##### payload
294
319
295−- ##### payload
296− The data-containing tail of a core.
320+ The data-containing tail of a core.
297
321
298−*See [basic types](../../hoon/basic)*.
322+_See [basic types](../../hoon/basic)._
299
323
300### Dojo
324### Dojo
301
325
@@ -307,7 +331,7 @@ Unix terminal, and more analogous to a Hoon REPL.
307You’ll notice that many things can’t be written here; this is normal. The Dojo
331You’ll notice that many things can’t be written here; this is normal. The Dojo
308enforces syntactical correctness right at the command line. Strings that can’t
332enforces syntactical correctness right at the command line. Strings that can’t
309be continued into a valid expression are automatically trimmed back to something
333be continued into a valid expression are automatically trimmed back to something
310− that can be. Some syntactically invalid expressions can be completed, but the
334+that can be. Some syntactically invalid expressions can be completed, but the
311Dojo will prevent them from being entered as a command. You can play around
335Dojo will prevent them from being entered as a command. You can play around
312with this functionality learn what syntax is kosher.
336with this functionality learn what syntax is kosher.
313
337
@@ -322,72 +346,79 @@ is, in turn, a knot.
322
346
323### face
347### face
324
348
325−A *face* is the Hoon analog to what is a variable name in most other
349+A _face_ is the Hoon analog to what is a variable name in most other
326programming languages. Faces are metadata labels for legs, allowing us to
350programming languages. Faces are metadata labels for legs, allowing us to
327address parts. Because there is no metadata in Nock, faces cannot exist in Nock.
351address parts. Because there is no metadata in Nock, faces cannot exist in Nock.
328
352
353+```
329 > a=2
354 > a=2
330 a=2
355 a=2
356+```
331
357
332In the above example, `a` is the face and `2` is the value.
358In the above example, `a` is the face and `2` is the value.
333
359
334Hoon has no scope or symbol-table; there is only the subject. To "declare" a
360Hoon has no scope or symbol-table; there is only the subject. To "declare" a
335"variable" is to construct a new subject: `[name=value old-subject]`.
361"variable" is to construct a new subject: `[name=value old-subject]`.
336
362
337−*See [advanced types](../../hoon/advanced/#-face-aliases-and-bridges)*.
363+_See [advanced types](../../hoon/advanced/#-face-aliases-and-bridges)_.
338
364
339
365
340### flag
366### flag
341
367
342−A `flag` is Hoon's version of a boolean. `0` (`%.y`) is *yes*, `1` (`%.n`) is
368+A `flag` is Hoon's version of a boolean. `0` (`%.y`) is _yes_, `1` (`%.n`) is
343−*no*.
369+_no_.
344
370
345−> Why? It's fresh, it's different, it's new. And it's annoying. And it
371+Why? It's fresh, it's different, it's new. And it's annoying. And it
346−> keeps you on your toes. And it's also just intuitively right.
372+keeps you on your toes. And it's also just intuitively right.
347
373
374+;h3
348−### gate
375+ ;div(id "gate"): gate
376+==
349
377
350−A *gate* is a [core](#-core) with one [arm](#-arm) -- Hoon's closest
378+A _gate_ is a [core](#core) with one [arm](#arm) -- Hoon's closest
351analog to a function. To call a gate on an argument, replace the sample
379analog to a function. To call a gate on an argument, replace the sample
352(at [tree address](../../hoon/limb/limb/) `+6`
380(at [tree address](../../hoon/limb/limb/) `+6`
353in the core) with the argument, and then compute the arm.
381in the core) with the argument, and then compute the arm.
354
382
355The payload of a gate has a shape of `[sample context]`.
383The payload of a gate has a shape of `[sample context]`.
356
384
357−- ##### sample
385+- ##### sample
386+
358− The argument tuple.
387+ The argument tuple.
388+
359−- ##### context
389+- ##### context
360− The subject in which the gate was defined.
361
390
391+ The subject in which the gate was defined.
392+
362−*See [basic types](../../hoon/basic/#-core-p-type-q-map-term-type),
393+_See [basic types](../../hoon/basic/#-core-p-type-q-map-term-type),
363[`%-` ("cenhep")](../../hoon/rune/cen/hep/) (the
394[`%-` ("cenhep")](../../hoon/rune/cen/hep/) (the
364−[rune](#-rune) for calling a `gate`).*
395+[rune](#rune) for calling a `gate`)._
365
396
366### generator
397### generator
367
398
368−A *generator* is like a limited Hoon script: it’s a shell command that produces
399+A _generator_ is like a limited Hoon script: it’s a shell command that produces
369−a value before disappearing. Generators take an input [noun](#-noun) (a value)
400+a value before disappearing. Generators take an input [noun](#noun) (a value)
370and produce an output `noun` by performing calculations on its arguments,
401and produce an output `noun` by performing calculations on its arguments,
371prompting for input, or making HTTP requests.
402prompting for input, or making HTTP requests.
372
403
373You need a `bar` rune like `|=` in your generator, because a generator is
404You need a `bar` rune like `|=` in your generator, because a generator is
374essentially a function that you’re calling.
405essentially a function that you’re calling.
375
406
376−Generators, unlike [apps](#-application), hold no state. They are pure,
407+Generators, unlike [apps](#application), hold no state. They are pure,
377−stateless functions, and they cannot send [moves](#-move). Because of this,
408+stateless functions, and they cannot send [moves](#move). Because of this,
378generators are have a more narrow use than apps. Among the non-trivial uses of
409generators are have a more narrow use than apps. Among the non-trivial uses of
379a a generator is moving data into apps -- they’re the backbone of Urbit’s
410a a generator is moving data into apps -- they’re the backbone of Urbit’s
380information pipeline.
411information pipeline.
381
412
382Generators are run from the `/gen` directory of your current desk. For example,
413Generators are run from the `/gen` directory of your current desk. For example,
383−to run a generator named whatever.hoon, you would type `> +whatever` in the
414+to run a generator named `whatever.hoon`, you would type `> +whatever` in the
384[Dojo](../dojo).
415[Dojo](../dojo).
385
416
386### glyph
417### glyph
387
418
388−A *glyph* is a single, non-alphanumeric ASCII character. Each glyph has its own
419+A _glyph_ is a single, non-alphanumeric ASCII character. Each glyph has its own
389monosyllabic name, which allows the efficient communication of Hoon-related
420monosyllabic name, which allows the efficient communication of Hoon-related
390−information in speech. [`Runes`](#-rune) are composed of two glyphs.
421+information in speech. [`Runes`](#rune) are composed of two glyphs.
391Below is a complete list of glyphs with their associated pronunciations.
422Below is a complete list of glyphs with their associated pronunciations.
392
423
393```
424```
@@ -401,56 +432,66 @@ cen % lus + vat @
401col : mic ; wut ?
432col : mic ; wut ?
402com , net / yel "
433com , net / yel "
403dot . pad & zap !
434dot . pad & zap !
404−gap [>1 space, nl] rac ]
435+gap [>1 space, nl] rac ]
405hax # rit )
436hax # rit )
406```
437```
407
438
408### Hall
439### Hall
409
440
410−*Hall* is the Urbit communication back-end. It’s a messaging bus that can work
441+_Hall_ is the Urbit communication back-end. It’s a messaging bus that can work
411−with clients of all sorts. [`:talk`](#-talk), the built-in chat client, is one
442+with clients of all sorts. [`:talk`](#talk), the built-in chat client, is one
412such app that uses Hall.
443such app that uses Hall.
413
444
414−*More information on Hall can be found [here](../hall).*
445+_More information on Hall can be found [here](../hall)._
415
446
416−- #### circle
447+- ##### circle
417
448
418− A circle is the “audience” of your messages -- who can receive them. It can be
449+ A circle is the “audience” of your messages -- who can receive them. It can be
419− thought of as a chat channel, but this is a little too narrow. More
450+ thought of as a chat channel, but this is a little too narrow. More
420− specifically, it’s a named collection of messages created by and hosted on a
451+ specifically, it’s a named collection of messages created by and hosted on a
421− ship’s Hall, usually represented as `~ship-name/circle-name`. On Talk,
452+ ship’s Hall, usually represented as `~ship-name/circle-name`. On Talk,
422− Urbit’s built-in chat front-end, the first circle that you will likely
453+ Urbit’s built-in chat front-end, the first circle that you will likely
423− encounter is `/urbit-meta`.
454+ encounter is `/urbit-meta`.
424
455
425### Hood
456### Hood
426
457
427−*Hood* orchestrates many of the Urbit initialization systems necessary
458+_Hood_ orchestrates many of the Urbit initialization systems necessary
428for boot.
459for boot.
429
460
461+;h3
430−### Hoon
462+ ;div(id "hoon"): Hoon
463+==
431
464
432Hoon is a strict, higher-order typed functional language that compiles itself
465Hoon is a strict, higher-order typed functional language that compiles itself
433to Nock.
466to Nock.
434
467
435−The Hoon source file is located in `/home/sys/hoon.hoon` within your urbit.
468+The Hoon source file is located in `/home/sys/hoon.hoon` within your urbit.
436
469
437−*More information can be found in the [hoon](../../hoon) section.*
470+_More information can be found in the [hoon](../../hoon) section._
438
471
472+- ;div
473+ ;h5
439−- #### Mint
474+ ;div(id "mint"): Mint
475+ ==
476+ ==
440
477
441− *Mint* is the Hoon compiler function. Mint takes the subject type and the
478+ _Mint_ is the Hoon compiler function. Mint takes the subject type and the
442− expression source (a [hoon](#-a-hoon), for example) and produces the product
479+ expression source (a [hoon](#a-hoon), for example) and produces the product
443− type and nock formula. So [type hoon] is mapped to [type nock].
480+ type and nock formula. So [type hoon] is mapped to [type nock].
444
481
482+;=
483+ ;h3
445−### <a id="-a-hoon">hoon</a>
484+ ;div(id "a-hoon"): hoon
485+ ==
486+==
446
487
447−A *hoon* (lowercase) is the result of parsing a Hoon source expression into an
488+A _hoon_ (lowercase) is the result of parsing a Hoon source expression into an
448AST node. These AST nodes are nouns, like all other Hoon data. Because every
489AST node. These AST nodes are nouns, like all other Hoon data. Because every
449Hoon program is, in its entirety, a single expression of Hoon, the result of
490Hoon program is, in its entirety, a single expression of Hoon, the result of
450parsing the whole thing into an AST is a single `hoon`.
491parsing the whole thing into an AST is a single `hoon`.
451
492
452A hoon is a tagged union of the form `[%tag data]`, where the tag
493A hoon is a tagged union of the form `[%tag data]`, where the tag
453−is a constant such as `%brts` (from the source [rune](#-rune) `|=`,
494+is a constant such as `%brts` (from the source [rune](#rune) `|=`,
454i.e. "bartis"), and is matched up with the appropriate type of data
495i.e. "bartis"), and is matched up with the appropriate type of data
455(often more `hoon`s, from source subexpressions). For example, the
496(often more `hoon`s, from source subexpressions). For example, the
456expression `:-(2 17)`, once parsed into an AST, becomes the following:
497expression `:-(2 17)`, once parsed into an AST, becomes the following:
@@ -486,12 +527,12 @@ Irregular forms are alternative ways of writing Hoon expressions, alternatives
486to the digraphic runes such as `:~`. Irregular forms are usually more compact
527to the digraphic runes such as `:~`. Irregular forms are usually more compact
487than regular forms.=
528than regular forms.=
488
529
489−*See [irregular forms](../../hoon/irregular).*
530+_See [irregular forms](../../hoon/irregular)._
490
531
491### jet
532### jet
492
533
493−A *jet* is a piece of C code that have equivalent products to a piece of Hoon or
534+A _jet_ is a piece of C code that have equivalent products to a piece of Hoon or
494− Nock code. They are used for performance reasons; jets are meant to be faster
535+Nock code. They are used for performance reasons; jets are meant to be faster
495than the code that they are substituting for.
536than the code that they are substituting for.
496
537
497Jets are necessary for mathematics, performance-wise, because Nock handles it
538Jets are necessary for mathematics, performance-wise, because Nock handles it
@@ -499,11 +540,11 @@ so inefficiently. Nock, for example, can’t decrement (reduce a number by one)
499except by starting building a loop that starts from zero and increments to a
540except by starting building a loop that starts from zero and increments to a
500number just below.
541number just below.
501
542
502−*See [API overview](../../vere/api).*
543+_See [API overview](../../vere/api)._
503
544
504### lark
545### lark
505
546
506−A lark is an expression that returns a [limb](#-limb) at the specified
547+A lark is an expression that returns a [limb](#limb) at the specified
507address in a cell. Using `-` by itself returns the head of the subject, and
548address in a cell. Using `-` by itself returns the head of the subject, and
508using `+` by itself returns the tail:
549using `+` by itself returns the tail:
509
550
@@ -529,55 +570,109 @@ you desire.
52915
57015
530```
571```
531
572
573+;h3
532−### limb
574+ ;div(id "limb"): limb
575+==
533
576
534−A *limb* is an attribute or variable reference. A limb is an [arm](#-arm) or a
577+A _limb_ is an attribute or variable reference. A limb is an [arm](#arm) or a
535−[leg](#-leg).
578+[leg](#leg).
536
579
537−To resolve a *limb* named "foo", the subject is searched depth-first,
580+To resolve a _limb_ named "foo", the subject is searched depth-first,
538head-first for either a face named "foo" or a core with an arm of
581head-first for either a face named "foo" or a core with an arm of
539"foo". If a face is found, the result is a leg, if a core is
582"foo". If a face is found, the result is a leg, if a core is
540found, the result is the product of the arm.
583found, the result is the product of the arm.
541
584
542−- ##### leg
585+- ##### leg
543− a subexpression, or subtree of the
544− [subject](#nock-subject).
545−-
546−- ##### wing
547− a search path into the subject, composed of
548− limbs. Search occurs from right to left (`a.b` means `b` within `a`).
549
586
550−*See [Limbs and wings](../../hoon/limb/)*
587+ a subexpression, or subtree of the
588+ [subject](#nock-subject).
551
589
552−### move
590+- ##### wing
553
591
554−A move is the [Arvo](#-arvo) equivalent of a syscall.
592+ a search path into the subject, composed of
593+ limbs. Search occurs from right to left (`a.b` means `b` within `a`).
555
594
556−### noun
595+_See [Limbs and wings](../../hoon/limb/)_
557
596
558−In [Nock](#-nock) and [Hoon](#-hoon), a *noun* is an atom or a cell.
559
597
598+;h3
599+ ;div(id "move"): formula
600+==
560
601
561−### Nock
602+A move is the [Arvo](#arvo) equivalent of a syscall.
562
603
563−Nock is Nock is a Turing-complete, non-lambda combinator interpreter. It's
564−Urbit's low-level programming language. Nock is functional and typeless.
565
604
605+;h3
566−- <h5 id="-nock-noun">noun:</h5> an *atom* or a *cell*.
606+ ;div(id "noun"): noun
567−- <h5 id="-nock-atom">atom:</h5> any natural number, including zero.
607+==
568−- <h5 id="-nock-cell">cell:</h5> any ordered pair of nouns.
608+
569−- <h5 id="-nock-subject">subject:</h5> a noun - the data against which a
609+In [Nock](#nock) and [Hoon](#hoon), a _noun_ is an atom or a cell.
570− *formula* is evaluated.
571−- <h5 id="-nock-formula">formula:</h5> a noun - a function at the Nock level.
572−- <h5 id="-nock-product">product:</h5> a noun - the result of evaluating a
573− formula against a subject.
574
610
575−*See the [Nock definition](../../nock/definition/).*
576
611
612+;h3
613+ ;div(id "nock"): Nock
614+==
577
615
578−#### mark
616+Nock is a Turing-complete, non-lambda combinator interpreter. It's
617+Urbit's low-level programming language. Nock is functional and typeless.
579
618
619+- ;div
620+ ;h5
621+ ;div(id "nock-noun"): noun
622+ ==
623+ ;div: an _atom_ or a _cell_.
624+ ==
625+
626+- ;div
627+ ;h5
628+ ;div(id "nock-atom"): atom
629+ ==
630+ any natural number, including zero.
631+ ==
632+
633+ - ;div
634+ ;h5
635+ ;div(id "nock-cell"): cell
636+ ==
637+ any ordered pair of nouns.
638+ ==
639+
640+ - ;div
641+ ;h5
642+ ;div(id "nock-cell"): cell
643+ ==
644+ any ordered pair of nouns.
645+ ==
646+
647+ - ;div
648+ ;h5
649+ ;div(id "nock-subject"): subject
650+ ==
651+ a noun - the data against which a _formula_ is evaluated.
652+ ==
653+
654+ - ;div
655+ ;h5
656+ ;div(id "nock-formula"): formula
657+ ==
658+ a noun - a function at the nock level.
659+ ==
660+
661+ - ;div
662+ ;h5
663+ ;div(id "nock-product"): product
664+ ==
665+ a noun - the result of evaluating a formula against a subject.
666+ ==
667+
668+_See the [Nock definition](../../nock/definition/)._
669+
670+
671+;h3
672+ ;div(id "mark"): mark
673+==
674+
580−A *mark* is Urbit's version of a MIME type, if a MIME type was an
675+A _mark_ is Urbit's version of a MIME type, if a MIME type was an
581executable specification. The mark is just a label that's used as a path
676executable specification. The mark is just a label that's used as a path
582to a local source file in the Arvo filesystem. This source file defines
677to a local source file in the Arvo filesystem. This source file defines
583a core that can mold untrusted data, diff and patch, convert to other
678a core that can mold untrusted data, diff and patch, convert to other
@@ -585,28 +680,29 @@ marks, etc.
585
680
586If this sounds like magic, it isn't quite magic. There's no way
681If this sounds like magic, it isn't quite magic. There's no way
587for different urbits to make sure they mean the same thing by the
682for different urbits to make sure they mean the same thing by the
588−same mark. However, when incompatibility happens, marks ensure
683+same mark. However, when incompatibility happens, marks ensure
589that we at least handle the situation in a predictable way.
684that we at least handle the situation in a predictable way.
590
685
591#### metal
686#### metal
592
687
593−Every core has a *metal* which defines its variance model (ie, the
688+Every core has a _metal_ which defines its variance model (ie, the
594properties of the type of a compatible core). The default is `gold`
689properties of the type of a compatible core). The default is `gold`
595(invariant).
690(invariant).
596
691
597−- `gold`: *invariant*
692+- `gold`: _invariant_
598−- `lead`: *bivariant*
693+- `lead`: _bivariant_
599−- `zinc`: *covariant*
694+- `zinc`: _covariant_
600−- `iron`: *contravariant*
695+- `iron`: _contravariant_
601
696
602−*See [advanced types](../../hoon/advanced)*.
697+_See [advanced types](../../hoon/advanced)_.
603
698
604### ship
699### ship
605
700
606−An Urbit *ship* is: a cryptographic title on a *will* signed by private key; a
701+An Urbit _ship_ is: a cryptographic title on a _will_ signed by private key; a
607human-memorable name; and a packet-routing address. Ships are classed by the
702human-memorable name; and a packet-routing address. Ships are classed by the
608number of bits in their address:
703number of bits in their address:
609
704
705+```
610 Size Name Parent Object Example
706 Size Name Parent Object Example
611 ----- ------ ------ ------ -------
707 ----- ------ ------ ------ -------
612 2^8 galaxy ~ supernode ~zod
708 2^8 galaxy ~ supernode ~zod
@@ -614,19 +710,20 @@ number of bits in their address:
614 2^32 planet star user ~tasfyn-partyv
710 2^32 planet star user ~tasfyn-partyv
615 2^64 moon planet device ~sigsam-nimbot-tasfyn-partyv
711 2^64 moon planet device ~sigsam-nimbot-tasfyn-partyv
616 2^128 comet ~ bot ~racmus-mollen-fallyt-linpex--watres-sibbur-modlux-rinmex
712 2^128 comet ~ bot ~racmus-mollen-fallyt-linpex--watres-sibbur-modlux-rinmex
713+```
617
714
618−Any ship can be called an *urbit*. The lowercase "u" distinguishes it from Urbit
715+Any ship can be called an _urbit_. The lowercase "u" distinguishes it from Urbit
619− the software stack and Urbit the network.
716+the software stack and Urbit the network.
620
717
621−> You can find a longer-form summary here:
718+_You can find a longer-form summary here:
622−> [`urbit.org/posts/address-space/`](https://urbit.org/posts/address-space/).
719+[`urbit.org/posts/address-space/`](https://urbit.org/posts/address-space/)._
623
720
624An Urbit identity is a string like `~firbyr-napbes`. It means nothing,
721An Urbit identity is a string like `~firbyr-napbes`. It means nothing,
625but it's easy to remember and say out loud. `~firbyr-napbes` is actually
722but it's easy to remember and say out loud. `~firbyr-napbes` is actually
626just a 32-bit number (`3.237.967.392`, to be exact), like an IP address,
723just a 32-bit number (`3.237.967.392`, to be exact), like an IP address,
627that we turn into a human-memorable string. The full name of this string
724that we turn into a human-memorable string. The full name of this string
628can be viewed by typing `our` in the Dojo, Urbit's shell. This is useful
725can be viewed by typing `our` in the Dojo, Urbit's shell. This is useful
629−when running a ship with a longer name, such as a *moon* or a *comet*.
726+when running a ship with a longer name, such as a _moon_ or a _comet_.
630
727
631Technically, an urbit is a secure digital identity that you own and
728Technically, an urbit is a secure digital identity that you own and
632control with a cryptographic key, like a Bitcoin wallet. As in Bitcoin,
729control with a cryptographic key, like a Bitcoin wallet. As in Bitcoin,
@@ -638,57 +735,59 @@ Shorter names are easier to remember, so they're more valuable. So
638urbits are classified by the number of bits in their name. (A ship name
735urbits are classified by the number of bits in their name. (A ship name
639is just a scrambled base-256 representation of the number.)
736is just a scrambled base-256 representation of the number.)
640
737
641−A 32-bit urbit (like `~firbyr-napbes`) is called a *planet.* A 16-bit
738+A 32-bit urbit (like `~firbyr-napbes`) is called a _planet._ A 16-bit
642−urbit (like `~pollev)` is a *star.* An 8-bit ship (like `~mun`) is a
739+urbit (like `~pollev)` is a _star._ An 8-bit ship (like `~mun`) is a
643−*galaxy.* A planet is an identity for an independent, adult human. Stars
740+_galaxy._ A planet is an identity for an independent, adult human. Stars
644and galaxies are network infrastructure.
741and galaxies are network infrastructure.
645
742
646−Each planet or star is launched by its *parent,* the star or galaxy
743+Each planet or star is launched by its _parent,_ the star or galaxy
647whose number is its bottom half. So the planet `~firbyr-napbes`,
744whose number is its bottom half. So the planet `~firbyr-napbes`,
648`0xdead.beef` or `3.735.928.559`, is the child of `~pollev`, `0xbeef` or
745`0xdead.beef` or `3.735.928.559`, is the child of `~pollev`, `0xbeef` or
649`48.879`, whose parent is `~mun`, `0xef`, `239`. The galaxy at the address of
746`48.879`, whose parent is `~mun`, `0xef`, `239`. The galaxy at the address of
650`0` is `~zod`.
747`0` is `~zod`.
651
748
652
749
653− - #### pier
750+- ##### pier
654−
655− A ship's *pier* is its Unix directory. For planets, the name of the pier is
656− usually the planet name.
657
751
752+ A ship's _pier_ is its Unix directory. For planets, the name of the pier is
753+ usually the planet name.
658
754
755+;h3
756+ ;div(id "structure"): structure
757+==
659
758
660−### structure
661−
662−A *structure* is an idempotent [gate](#-gate) (function) that constructs and
759+A _structure_ is an idempotent [gate](#gate) (function) that constructs and
663validates types in Hoon.
760validates types in Hoon.
664
761
665−An example: Arvo [marks](#-marks) use Hoon's type system via structures to
762+An example: Arvo [marks](#mark) use Hoon's type system via structures to
666validate untrusted network data.
763validate untrusted network data.
667
764
668Here's some common structure terminology:
765Here's some common structure terminology:
669
766
670−- #### bunt:
767+- ##### bunt:
671
768
672− A bunt is the default value of a [structure](#-structure). It's also a verb;
769+ A bunt is the default value of a [structure](#structure). It's also a verb;
673− to *bunt* a structure is to produce the bunt of that structure. For example,
770+ to _bunt_ a structure is to produce the bunt of that structure. For example,
674− bunting `@` results in `0`, and bunting `@t` results in `''`. Bunting is
771+ bunting `@` results in `0`, and bunting `@t` results in `''`. Bunting is
675− performed with `*` followed by the structure in question:
772+ performed with `*` followed by the structure in question:
676− ~~~
677− > *@
678− 0
679− > *@t
680− ''
681− ~~~
682
773
683−- #### icon: The type of the mold's range.
774+ ```
775+ > *@
776+ 0
777+ > *@t
778+ ''
779+ ```
684
780
685−*See [mold hoons](../../hoon/rune/buc/).*
781+- ##### icon: The type of the mold's range.
686
782
783+_See [mold hoons](../../hoon/rune/buc/)._
687
784
785+;h3
688−#### rune
786+ ;div(id "rune"): rune
787+==
689
788
690A Hoon _rune_ is a pair of ASCII symbols used to begin a
789A Hoon _rune_ is a pair of ASCII symbols used to begin a
691−[Hoon expression](#-a-hoon).
790+[Hoon expression](#a-hoon).
692
791
693For example, the rune [`?:`](../../hoon/rune/wut/col/) is
792For example, the rune [`?:`](../../hoon/rune/wut/col/) is
694Hoon's most common conditional, a branch on a boolean test. The first
793Hoon's most common conditional, a branch on a boolean test. The first
@@ -697,48 +796,50 @@ symbol in a rune represents a family of related runes. For example, the
697
796
698The result of parsing a Hoon source expression&mdash;the rune, followed
797The result of parsing a Hoon source expression&mdash;the rune, followed
699by its respective children&mdash;into an AST node is simply called
798by its respective children&mdash;into an AST node is simply called
700−a [`hoon`](#-a-hoon).
799+a [`hoon`](#a-hoon).
800+
801+Runes have two syntactic forms, _tall_ and _flat_:
802+
803+- ##### tall:
701
804
702−Runes have two syntactic forms, *tall* and *flat*:
805+ multiple lines, no parentheses, two or more spaces between tokens
703
806
704−- ##### tall:
807+ Example:
705− multiple lines, no parentheses, two or more spaces between tokens
706
808
707− Example:
809+ ```
810+ > %+ add 2 2
811+ 4
812+ ```
708
813
709− ```
710− ~zod:dojo> %+ add 2 2
711− 4
712− ```
713−- ##### flat:
814+- ##### flat:
714− one line, parentheses, one space between tokens
715
815
716− Example:
816+ one line, parentheses, one space between tokens
717
817
718− ```
818+ Example:
819+ ```
719− ~zod:dojo> %+(add 2 2) :: regular flat form
820+ > %+(add 2 2) :: regular flat form
720− 4
821+ 4
721
822
722− ~zod:dojo> (add 2 2) :: irregular flat form
823+ > (add 2 2) :: irregular flat form
723− 4
824+ 4
724− ```
825+ ```
725
826
726Tall hoons can contain flat hoons, but not vice versa. All irregular
827Tall hoons can contain flat hoons, but not vice versa. All irregular
727forms are flat.
828forms are flat.
728
829
729−*See [hoon concept](../../hoon/concepts/#-hoon),
830+_See [hoon concept](../../hoon/concepts/#-hoon),
730−[expressions](../../hoon/rune/), and [syntax](../../hoon/syntax/)*.
831+[expressions](../../hoon/rune/), and [syntax](../../hoon/syntax/)_.
731
832
732### Sail
833### Sail
733
834
734−*Sail* is the Hoon markup language for XML.
835+_Sail_ is the Hoon markup language for XML.
735
836
736### scry
837### scry
737
838
738−To *scry* means to request data from the Arvo namespace and bring it
839+To _scry_ means to request data from the Arvo namespace and bring it
739to userspace.
840to userspace.
740
841
741−*See [.^ (dot-ket)](../../hoon/rune/dot/ket/).*
842+_See [.^ (dot-ket)](../../hoon/rune/dot/ket/)._
742
843
743### slot
844### slot
744
845
@@ -752,52 +853,54 @@ The head of `+n` is `+2n`, the tail is `+(2n+1)`.
752`+7` is a special address for gates, because the position is defined
853`+7` is a special address for gates, because the position is defined
753(by convention) as the context of a gate and of all cores.
854(by convention) as the context of a gate and of all cores.
754
855
755−### Talk
856+;h3
857+ ;div(id "talk"): talk
858+==
756
859
757−*Talk* is Urbit's built-in chat app. It’s one example of an app that can be
860+_Talk_ is Urbit's built-in chat app. It’s one example of an app that can be
758built on top of Hall, the Urbit back-end messaging system.
861built on top of Hall, the Urbit back-end messaging system.
759
862
760−*See [Messaging](../using/messaging). for more information.*
863+_See [Messaging](../using/messaging). for more information._
761
864
762### type
865### type
763
866
764−A Hoon *type* defines a set (finite or infinite) of nouns and ascribes
867+A Hoon _type_ defines a set (finite or infinite) of nouns and ascribes
765some semantics to it. There is no direct syntax for defining
868some semantics to it. There is no direct syntax for defining
766types; they are always defined by inference (i.e., by
869types; they are always defined by inference (i.e., by
767−[`mint`](#-mint)), usually using a constructor ([`mold`](#-mold)).
870+[`mint`](#mint)), usually using a constructor ([structure](#structure)).
768
871
769All types are assembled out of base types defined in `++type`.
872All types are assembled out of base types defined in `++type`.
770(Look up `++ type` in hoon.hoon for examples.) When the compiler
873(Look up `++ type` in hoon.hoon for examples.) When the compiler
771does type-inference on a program, it assembles complex types out
874does type-inference on a program, it assembles complex types out
772of the simpler built-in types.
875of the simpler built-in types.
773
876
774−- #### nest
877+- ##### nest
775
878
776− `nest` is an internal Hoon function on two types which performs a type
879+ `nest` is an internal Hoon function on two types which performs a type
777− compatibility test. `nest` produces yes if the
880+ compatibility test. `nest` produces yes if the
778− set of nouns in the second type is provably a subset of the first.
881+ set of nouns in the second type is provably a subset of the first.
779− If `nest` produces no, the Hoon programmer will receive a `nest-fail`
882+ If `nest` produces no, the Hoon programmer will receive a `nest-fail`
780− error. This is one of the most commons errors in Hoon programming.
883+ error. This is one of the most commons errors in Hoon programming.
781
884
782− *See [advanced types](../../hoon/advanced/)*.
885+ _See [advanced types](../../hoon/advanced/)_.
783− *See [troubleshooting](../../hoon/troubleshooting/#-nest-fail)*.
886+ _See [troubleshooting](../../hoon/troubleshooting/#-nest-fail)_.
784
887
785
888
786### Unit
889### Unit
787
890
788Hoon's equivalent of a nullable pointer or a Haskell Maybe. If `q` is `~`,
891Hoon's equivalent of a nullable pointer or a Haskell Maybe. If `q` is `~`,
789−null, the type is *warm*; any atom is in the type. If `q` is `[~ x]`, where
892+null, the type is _warm_; any atom is in the type. If `q` is `[~ x]`, where
790−`x` is any atom, the type is *cold*; its only legal value is the constant `x`.
893+`x` is any atom, the type is _cold_; its only legal value is the constant `x`.
791
894
792### Vane
895### Vane
793
896
794−A *vane* is an [Arvo](#-arvo) module. Each Vane is a single file because Arvo
897+A _vane_ is an [Arvo](#arvo) module. Each Vane is a single file because Arvo
795cannot, on its own, deal with programs that are split between multiple files.
898cannot, on its own, deal with programs that are split between multiple files.
796Some vanes can do this, however.
899Some vanes can do this, however.
797
900
798### Vere (pronounced “vair”)
901### Vere (pronounced “vair”)
799
902
800−The runtime system, written in C, that implements [Nock](#-nock). All
903+The runtime system, written in C, that implements [Nock](#nock). All
801It’s written in C. Vere-level errors are prepended with as `bail:`.
904It’s written in C. Vere-level errors are prepended with as `bail:`.
802
905
803Vere is a virtual machine: it pretends to be hardware, and is the single point
906Vere is a virtual machine: it pretends to be hardware, and is the single point
@@ -808,7 +911,7 @@ applying effects to Unix.
808
911
809### Zuse
912### Zuse
810
913
811−*Zuse* is a defined interface for vanes. It contains the part of the Hoon
914+_Zuse_ is a defined interface for vanes. It contains the part of the Hoon
812standard library that is specific to Arvo functionality.
915standard library that is specific to Arvo functionality.
813
916
814−Arvo is located in `/home/sys/zuse.hoon` within your urbit.
917+Arvo is located in `/home/sys/zuse.hoon` within your urbit.
docs/hoon/irregular.md → docs/reference/irregular.umdrenamed+69−67
@@ -1,18 +1,19 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−sort: 25
2+ sort/'7'
4−title: Irregular forms
3+ title/'Irregular forms'
5−comments: true
4+ ==
6−---
5+;>
7
6
8## Irregular forms, a compilation
7## Irregular forms, a compilation
8+
9##### `~palfun-foslup`
9##### `~palfun-foslup`
10
10
11−<br />
11+;br;
12
12
13−*Original Fora post* [*here*](https://urbit.org/fora/posts/~2016.12.29..19.37.08..89d5~/).
13+*Original Fora post* [here](https://urbit.org/fora/posts/~2016.12.29..19.37.08..89d5~/).
14
14
15##### Reading guide
15##### Reading guide
16+
16Headings contain runes, phonetics and tokens. Description contains a link to the docs and a short description of the rune. Both regular (R) and irregular (I) forms are given.
17Headings contain runes, phonetics and tokens. Description contains a link to the docs and a short description of the rune. Both regular (R) and irregular (I) forms are given.
17
18
18Want to `Ctrl-f` to find out the meaning of something weird you saw? Search for `\symbol`. ie `\?` or `\=`. It'll show you to the irregular forms that uses that symbol.
19Want to `Ctrl-f` to find out the meaning of something weird you saw? Search for `\symbol`. ie `\?` or `\=`. It'll show you to the irregular forms that uses that symbol.
@@ -23,18 +24,18 @@ Anything Nock can do, Hoon can do also.
23
24
24### .+ dotlus
25### .+ dotlus
25
26
26−[docs](../rune/dot/lus/) \\+
27+[docs](../rune/dot/lus/) \\+
27`[%dtls p=atom]`: increment an atom with Nock 4.
28`[%dtls p=atom]`: increment an atom with Nock 4.
28
29
29−R: `.+(p)`
30+R: `.+(p)`
30I: `+(p)`
31I: `+(p)`
31
32
32### .= dottis
33### .= dottis
33
34
34−[docs](../rune/dot/tis/) \\=
35+[docs](../rune/dot/tis/) \\=
35`[%dtls p=hoon q=hoon]`: test for equality with Nock 5.
36`[%dtls p=hoon q=hoon]`: test for equality with Nock 5.
36
37
37−R: `.=(p q)`
38+R: `.=(p q)`
38I: `=(p q)`
39I: `=(p q)`
39
40
40## ; sem (make)
41## ; sem (make)
@@ -43,10 +44,10 @@ Miscellaneous useful macros.
43
44
44### ;: semcol
45### ;: semcol
45
46
46−[docs](../rune/sem/col/) \\:
47+[docs](../rune/sem/col/) \\:
47`[%smcl p=hoon q=(list hoon)]`: call a binary function as an n-ary function.
48`[%smcl p=hoon q=(list hoon)]`: call a binary function as an n-ary function.
48
49
49−R: `;:(p q)`
50+R: `;:(p q)`
50I: `:(p q)`
51I: `:(p q)`
51
52
52## : col (cells)
53## : col (cells)
@@ -55,10 +56,10 @@ The cell runes.
55
56
56### :- colhep
57### :- colhep
57
58
58−[docs](../rune/col/hep/) \\[\\]\\^\\+\\\`\\~
59+[docs](../rune/col/hep/) \\[\\]\\^\\+\\\`\\~
59`[%clhp p=hoon q=hoon]`: construct a cell (2-tuple).
60`[%clhp p=hoon q=hoon]`: construct a cell (2-tuple).
60
61
61−R: `:-(p q)`
62+R: `:-(p q)`
62I:
63I:
63
64
64```
65```
@@ -77,23 +78,23 @@ Flow hoons change the subject. All non-flow hoons (except cores) pass the subjec
77
78
78### =< tisgar
79### =< tisgar
79
80
80−[docs](../rune/tis/gal/) \\:
81+[docs](../rune/tis/gal/) \\:
81`[%tsgl p=hoon q=hoon]`: compose two hoons, inverted.
82`[%tsgl p=hoon q=hoon]`: compose two hoons, inverted.
82
83
83−R: `=<(p q)`
84+R: `=<(p q)`
84I: `p:q`
85I: `p:q`
85
86
86## | bar (core)
87## | bar (core)
87
88
88−[docs](../rune/bar/) \\$
89+[docs](../rune/bar/) \\$
89Core hoons are flow hoon.
90Core hoons are flow hoon.
90
91
91Technically not irregular syntax, but worth mentioning.
92Technically not irregular syntax, but worth mentioning.
92
93
93−* `|= bartis` (gate)
94+- `|= bartis`
94−* `|. bardot` (trap)
95+- `|. bardot`
95−* `|- barhep` (loop)
96+- `|- barhep`
96−* `|* bartar` (gill)
97+- `|* bartar`
97
98
98The above runes produce a core with a single arm, named `$` ("buc"). We can recompute this arm with changes, useful for recursion among other things. Commonly used with the irregular syntax for `%=`, `:make`, like so: `$()`.
99The above runes produce a core with a single arm, named `$` ("buc"). We can recompute this arm with changes, useful for recursion among other things. Commonly used with the irregular syntax for `%=`, `:make`, like so: `$()`.
99
100
@@ -103,26 +104,26 @@ The invocation family of runes.
103
104
104### %= centis
105### %= centis
105
106
106−[docs](../rune/cen/tis/) \\(\\)
107+[docs](../rune/cen/tis/) \\(\\)
107`[%cnts p=wing q=(list (pair wing hoon))]`: take a wing with changes.
108`[%cnts p=wing q=(list (pair wing hoon))]`: take a wing with changes.
108
109
109−R: `%=(p a 1)`
110+R: `%=(p a 1)`
110I: `p(a 1)`
111I: `p(a 1)`
111
112
112### %~ censig
113### %~ censig
113
114
114−[docs](../rune/cen/sig/) \\~
115+[docs](../rune/cen/sig/) \\~
115`[%cnsg p=wing q=hoon r=hoon]`: call with multi-armed door.
116`[%cnsg p=wing q=hoon r=hoon]`: call with multi-armed door.
116
117
117−R: `%~(p q r)`
118+R: `%~(p q r)`
118I: `~(p q r)`
119I: `~(p q r)`
119
120
120### %- cenhep
121### %- cenhep
121
122
122−[docs](../rune/cen/hep/) \\(\\)
123+[docs](../rune/cen/hep/) \\(\\)
123`[%cnhp p=hoon q=hoon]`: call a gate (function).
124`[%cnhp p=hoon q=hoon]`: call a gate (function).
124
125
125−R: `%-(p q)`
126+R: `%-(p q)`
126I: `(p q)`
127I: `(p q)`
127
128
128Note: `(p)` becomes `$:p` (`=<($ p)`), which behaves as you would expect (func call w/o args).
129Note: `(p)` becomes `$:p` (`=<($ p)`), which behaves as you would expect (func call w/o args).
@@ -133,18 +134,18 @@ A mold is a gate (function) that helps us build simple and rigorous data structu
133
134
134### $? bucwut
135### $? bucwut
135
136
136−[docs](../rune/buc/wut/) \\?
137+[docs](../rune/buc/wut/) \\?
137`[%bcwt p=(list model)]`: mold which normalizes a general union.
138`[%bcwt p=(list model)]`: mold which normalizes a general union.
138
139
139−R: `$?(p)`
140+R: `$?(p)`
140I: `?(p)`
141I: `?(p)`
141
142
142### $_ buccab
143### $_ buccab
143
144
144−[docs](../rune/buc/cab/) \\_
145+[docs](../rune/buc/cab/) \\_
145`[%bccb p=value]`: mold which normalizes to an example.
146`[%bccb p=value]`: mold which normalizes to an example.
146
147
147−R: `$_(p)`
148+R: `$_(p)`
148I: `_p`
149I: `_p`
149
150
150## ? wut (test)
151## ? wut (test)
@@ -153,26 +154,26 @@ Hoon has the usual branches and logical tests.
153
154
154### ?! wutzap
155### ?! wutzap
155
156
156−[docs](../rune/wut/zap/) \\!
157+[docs](../rune/wut/zap/) \\!
157`[%wtzp p=hoon]`: logical not.
158`[%wtzp p=hoon]`: logical not.
158
159
159−R: `?!(p)`
160+R: `?!(p)`
160I: `!(p)`
161I: `!(p)`
161
162
162### ?& wutpam
163### ?& wutpam
163
164
164−[docs](../rune/wut/pam/) \\&
165+[docs](../rune/wut/pam/) \\&
165`[%wtpm p=(list hoon)]`: logical and.
166`[%wtpm p=(list hoon)]`: logical and.
166
167
167−R: `?&(p)`
168+R: `?&(p)`
168I: `&(p)`
169I: `&(p)`
169
170
170### ?| wutbar
171### ?| wutbar
171
172
172−[docs](../rune/wut/bar/) \\|
173+[docs](../rune/wut/bar/) \\|
173`[%wtbr p=(list hoon)]`: logical or.
174`[%wtbr p=(list hoon)]`: logical or.
174
175
175−R: `?|(p)`
176+R: `?|(p)`
176I: `|(p)`
177I: `|(p)`
177
178
178## ^ ket (cast)
179## ^ ket (cast)
@@ -181,18 +182,18 @@ Lets us adjust types without violating type constraints.
181
182
182### ^- kethep
183### ^- kethep
183
184
184−[docs](../rune/ket/hep/) \\\`
185+[docs](../rune/ket/hep/) \\\`
185`[%kthp p=model q=value]`: typecast by mold.
186`[%kthp p=model q=value]`: typecast by mold.
186
187
187−R: `^-(p q)`
188+R: `^-(p q)`
188I: `` `p`q ``
189I: `` `p`q ``
189
190
190### ^= kettis
191### ^= kettis
191
192
192−[docs](../rune/ket/tis/) \\=
193+[docs](../rune/ket/tis/) \\=
193`[%ktts p=toga q=value]`: name a value.
194`[%ktts p=toga q=value]`: name a value.
194
195
195−R: `^=(p q)`
196+R: `^=(p q)`
196I: `p=q`
197I: `p=q`
197
198
198## Miscellaneous
199## Miscellaneous
@@ -201,36 +202,38 @@ I: `p=q`
201
202
202\\*\\^\\?
203\\*\\^\\?
203
204
204−* `*` noun.
205+- `*` noun.
206+- `@` atom.
205−* `^` cell.
207+- `^` cell.
206−* `?` loobean.
208+- `?` loobean.
207−* `~` null.
209+- `~` null.
208
210
209### Values
211### Values
210
212
211\\~\\-\\.\\&\\|
213\\~\\-\\.\\&\\|
212−}
214+
213−* `~` null.
215+- `~` null.
214−* `&` loobean true.
216+- `&` loobean true.
215−* `|` loobean false.
217+- `|` loobean false.
216−* `%a` constant `a`, where `a` can be an ((ir)regularly defined) atom or a symbol.
218+- `%a` constant `a`, where `a` can be an ((ir)regularly defined) atom or a symbol.
217
219
218See [%sand](../atom/sand/) for other irregular definitions of atoms.
220See [%sand](../atom/sand/) for other irregular definitions of atoms.
219
221
220−### List addressing}
222+### List addressing
223+
221−* `&n` nth element of a list.
224+- `&n` nth element of a list.
222−* `|n` tail of list after nth element (i.e. n is the head).
225+- `|n` tail of list after nth element (i.e. n is the head).
223
226
224### Limbs
227### Limbs
225
228
226−[docs](../limb/limb/) \\+\\.\\^
229+[docs](../limb/limb/) \\+\\.\\^
227`[%limb p=(each @ud [p=@ud q=@tas])]`: attribute of subject.
230`[%limb p=(each @ud [p=@ud q=@tas])]`: attribute of subject.
228
231
229−* `+15` is slot 15
232+- `+15` is slot 15
230−* `.` is the whole subject (slot 1)
233+- `.` is the whole subject (slot 1)
231−* `^a` is the `a` "of a higher scope", i.e. "resolve variable a, ignoring the first one found".
234+- `^a` is the `a` "of a higher scope", i.e. "resolve variable a, ignoring the first one found".
232−* `^^p` even higher, etc.
235+- `^^p` even higher, etc.
233−* 'Lark' syntax for slots / tree addressing:
236+- 'Lark' syntax for slots / tree addressing:
234```
237```
235+1
238+1
236+2 -
239+2 -
@@ -246,18 +249,17 @@ See [%sand](../atom/sand/) for other irregular definitions of atoms.
246
249
247### Wings
250### Wings
248
251
249−[docs](../limb/wing/) \\.
252+[docs](../limb/wing/)
250`[%wing p=(list limb)]`; a limb search path.
253`[%wing p=(list limb)]`; a limb search path.
251−}
252`a.b` finds limb `a` within limb `b` ("var" `a` within "var" `b`).
254`a.b` finds limb `a` within limb `b` ("var" `a` within "var" `b`).
253
255
254### Printing stuff
256### Printing stuff
255
257
256−* `<a b c>` prints a [tape](../library/2q/#-tape).
258+- `<a b c>` prints a [tape](../library/2q/#-tape).
257−* `>a b c<` prints a [tank](../library/2q/#-tank).
259+- `>a b c<` prints a [tank](../library/2q/#-tank).
258
260
259## Commentary
261## Commentary
260
262
261− In our in-house examples throughout our documentation, we use irregular forms instead of regular for the sake of verbosity. But remember with irregular forms: everything is just runes! Like magic. In general, irregular forms (usually) read better, but of course regular forms provide more information about what you're doing by showing you the full rune. Of course, it's up to you, the Hoon programmer, as to whether or not you want to use these.
263+In our in-house examples throughout our documentation, we use irregular forms instead of regular for the sake of verbosity. But remember with irregular forms: everything is just runes! Like magic. In general, irregular forms (usually) read better, but of course regular forms provide more information about what you're doing by showing you the full rune. Of course, it's up to you, the Hoon programmer, as to whether or not you want to use these.
262
264
263− ##### If we missed any, or if you saw something weird that's not in here, feel free to comment below!
265+##### If we missed any, or if you saw something weird that's not in here, feel free to comment below!
docs/reference/library.umdnew file+9
@@ -0,0 +1,9 @@
1+:- :~ navhome/'/docs/'
2+ sort/'3'
3+ title/'Standard library'
4+ ==
5+;>
6+
7+# Standard library
8+
9+;list(datapreview "true", titlesonly "true");
docs/hoon/library/1a.md → docs/reference/library/1a.umdrenamed

The content is the same.

docs/hoon/library/1b.md → docs/reference/library/1b.umdrenamed

The content is the same.

docs/hoon/library/1c.md → docs/reference/library/1c.umdrenamed

The content is the same.

docs/hoon/library/2a.md → docs/reference/library/2a.umdrenamed

The content is the same.

docs/hoon/library/2b.md → docs/reference/library/2b.umdrenamed

The content is the same.

docs/hoon/library/2c.md → docs/reference/library/2c.umdrenamed

The content is the same.

docs/hoon/library/2d.md → docs/reference/library/2d.umdrenamed

The content is the same.

docs/hoon/library/2e.md → docs/reference/library/2e.umdrenamed

The content is the same.

docs/hoon/library/2f.md → docs/reference/library/2f.umdrenamed

The content is the same.

docs/hoon/library/2g.md → docs/reference/library/2g.umdrenamed

The content is the same.

docs/hoon/library/2h.md → docs/reference/library/2h.umdrenamed

The content is the same.

docs/hoon/library/2i.md → docs/reference/library/2i.umdrenamed

The content is the same.

docs/hoon/library/2j.md → docs/reference/library/2j.umdrenamed

The content is the same.

docs/hoon/library/2k.md → docs/reference/library/2k.umdrenamed

The content is the same.

docs/hoon/library/2l.md → docs/reference/library/2l.umdrenamed

The content is the same.

docs/hoon/library/2m.md → docs/reference/library/2m.umdrenamed

The content is the same.

docs/hoon/library/2n.md → docs/reference/library/2n.umdrenamed

The content is the same.

docs/hoon/library/2o.md → docs/reference/library/2o.umdrenamed

The content is the same.

docs/hoon/library/2p.md → docs/reference/library/2p.umdrenamed

The content is the same.

docs/hoon/library/2q.md → docs/reference/library/2q.umdrenamed

The content is the same.

docs/hoon/library/3a.md → docs/reference/library/3a.umdrenamed

The content is the same.

docs/hoon/library/3b.md → docs/reference/library/3b.umdrenamed

The content is the same.

docs/hoon/library/3c.md → docs/reference/library/3c.umdrenamed

The content is the same.

docs/hoon/library/3d.md → docs/reference/library/3d.umdrenamed

The content is the same.

docs/hoon/library/3e.md → docs/reference/library/3e.umdrenamed

The content is the same.

docs/hoon/library/3f.md → docs/reference/library/3f.umdrenamed

The content is the same.

docs/hoon/library/3g.md → docs/reference/library/3g.umdrenamed

The content is the same.

docs/hoon/library/4a.md → docs/reference/library/4a.umdrenamed

The content is the same.

docs/hoon/library/4b.md → docs/reference/library/4b.umdrenamed

The content is the same.

docs/hoon/library/4c.md → docs/reference/library/4c.umdrenamed

The content is the same.

docs/hoon/library/4d.md → docs/reference/library/4d.umdrenamed

The content is the same.

docs/hoon/library/4e.md → docs/reference/library/4e.umdrenamed

The content is the same.

docs/hoon/library/4f.md → docs/reference/library/4f.umdrenamed

The content is the same.

docs/hoon/library/4g.md → docs/reference/library/4g.umdrenamed

The content is the same.

docs/hoon/library/4h.md → docs/reference/library/4h.umdrenamed

The content is the same.

docs/hoon/library/4i.md → docs/reference/library/4i.umdrenamed

The content is the same.

docs/hoon/library/4j.md → docs/reference/library/4j.umdrenamed

The content is the same.

docs/hoon/library/4k.md → docs/reference/library/4k.umdrenamed

The content is the same.

docs/hoon/library/4l.md → docs/reference/library/4l.umdrenamed

The content is the same.

docs/hoon/library/4m.md → docs/reference/library/4m.umdrenamed

The content is the same.

docs/hoon/library/4n.md → docs/reference/library/4n.umdrenamed

The content is the same.

docs/hoon/library/4o.md → docs/reference/library/4o.umdrenamed

The content is the same.

docs/hoon/library/5a.md → docs/reference/library/5a.umdrenamed

The content is the same.

docs/hoon/library/5b.md → docs/reference/library/5b.umdrenamed

The content is the same.

docs/hoon/library/5c.md → docs/reference/library/5c.umdrenamed

The content is the same.

docs/hoon/library/5d.md → docs/reference/library/5d.umdrenamed

The content is the same.

docs/hoon/library/5e.md → docs/reference/library/5e.umdrenamed

The content is the same.

docs/hoon/library/5f.md → docs/reference/library/5f.umdrenamed

The content is the same.

docs/hoon/library/5g.md → docs/reference/library/5g.umdrenamed

The content is the same.

docs/hoon/library/zuse.md → docs/reference/library/zuse.umdrenamed

The content is the same.

docs/hoon/library/zuse/core/crua.md → docs/reference/library/zuse/core/crua.umdrenamed

The content is the same.

docs/hoon/library/zuse/core/epur.md → docs/reference/library/zuse/core/epur.umdrenamed

The content is the same.

docs/hoon/library/zuse/core/fu.md → docs/reference/library/zuse/core/fu.umdrenamed

The content is the same.

docs/hoon/library/zuse/core/jo.md → docs/reference/library/zuse/core/jo.umdrenamed

The content is the same.

docs/hoon/library/zuse/core/poja.md → docs/reference/library/zuse/core/poja.umdrenamed

The content is the same.

docs/hoon/library/zuse/core/poxa.md → docs/reference/library/zuse/core/poxa.umdrenamed

The content is the same.

docs/hoon/library/zuse/core/poxo.md → docs/reference/library/zuse/core/poxo.umdrenamed

The content is the same.

docs/hoon/library/zuse/core/yu.md → docs/reference/library/zuse/core/yu.umdrenamed

The content is the same.

docs/hoon/library/zuse/diff.md → docs/reference/library/zuse/diff.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/clan.md → docs/reference/library/zuse/gate/clan.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/dawn.md → docs/reference/library/zuse/gate/dawn.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/daws.md → docs/reference/library/zuse/gate/daws.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/deal.md → docs/reference/library/zuse/gate/deal.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/deft.md → docs/reference/library/zuse/gate/deft.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/dust.md → docs/reference/library/zuse/gate/dust.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/earl.md → docs/reference/library/zuse/gate/earl.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/earn.md → docs/reference/library/zuse/gate/earn.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/fain.md → docs/reference/library/zuse/gate/fain.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/feel.md → docs/reference/library/zuse/gate/feel.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/file.md → docs/reference/library/zuse/gate/file.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/foal.md → docs/reference/library/zuse/gate/foal.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/fray.md → docs/reference/library/zuse/gate/fray.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/fuel.md → docs/reference/library/zuse/gate/fuel.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/furl.md → docs/reference/library/zuse/gate/furl.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/glam.md → docs/reference/library/zuse/gate/glam.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/glon.md → docs/reference/library/zuse/gate/glon.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/gnom.md → docs/reference/library/zuse/gate/gnom.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/jape.md → docs/reference/library/zuse/gate/jape.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/jesc.md → docs/reference/library/zuse/gate/jesc.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/joba.md → docs/reference/library/zuse/gate/joba.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/jobe.md → docs/reference/library/zuse/gate/jobe.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/jone.md → docs/reference/library/zuse/gate/jone.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/lead.md → docs/reference/library/zuse/gate/lead.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/mang.md → docs/reference/library/zuse/gate/mang.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/meat.md → docs/reference/library/zuse/gate/meat.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/moon.md → docs/reference/library/zuse/gate/moon.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/mung.md → docs/reference/library/zuse/gate/mung.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/perk.md → docs/reference/library/zuse/gate/perk.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/pojo.md → docs/reference/library/zuse/gate/pojo.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/saxo.md → docs/reference/library/zuse/gate/saxo.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/scanf.md → docs/reference/library/zuse/gate/scanf.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/sein.md → docs/reference/library/zuse/gate/sein.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/sifo.md → docs/reference/library/zuse/gate/sifo.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/stud.md → docs/reference/library/zuse/gate/stud.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/taco.md → docs/reference/library/zuse/gate/taco.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/tact.md → docs/reference/library/zuse/gate/tact.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/tame.md → docs/reference/library/zuse/gate/tame.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/tell.md → docs/reference/library/zuse/gate/tell.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/tome.md → docs/reference/library/zuse/gate/tome.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/tope.md → docs/reference/library/zuse/gate/tope.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/txml.md → docs/reference/library/zuse/gate/txml.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/unt.md → docs/reference/library/zuse/gate/unt.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/urld.md → docs/reference/library/zuse/gate/urld.umdrenamed

The content is the same.

docs/hoon/library/zuse/gate/urle.md → docs/reference/library/zuse/gate/urle.umdrenamed

The content is the same.

docs/hoon/library/zuse/mold/udal.md → docs/reference/library/zuse/mold/udal.umdrenamed

The content is the same.

docs/hoon/library/zuse/mold/udon.md → docs/reference/library/zuse/mold/udon.umdrenamed

The content is the same.

docs/hoon/library/zuse/mold/umph.md → docs/reference/library/zuse/mold/umph.umdrenamed

The content is the same.

docs/hoon/library/zuse/mold/unce.md → docs/reference/library/zuse/mold/unce.umdrenamed

The content is the same.

docs/hoon/library/zuse/mold/upas.md → docs/reference/library/zuse/mold/upas.umdrenamed

The content is the same.

docs/hoon/library/zuse/mold/urge.md → docs/reference/library/zuse/mold/urge.umdrenamed

The content is the same.

docs/hoon/library/zuse/rsa.md → docs/reference/library/zuse/rsa.umdrenamed

The content is the same.

docs/reference/rune.umdnew file+93
@@ -0,0 +1,93 @@
1+:- :~ navhome/'/docs/'
2+ sort/'2'
3+ title/'Runes'
4+ ==
5+;>
6+
7+# Runes
8+
9+### _...and how to form Hoon expressions_
10+
11+;div(class "book")
12+
13+## Constants (and Interpolations)
14+
15+Hoon uses runes to form expressions, but not all expressions have runes in them. First, we have constant expressions (and also expressions that would be constant, but that they allow for interpolations):
16+
17+;list(src "./constants");
18+
19+;br;
20+
21+## Limbs and Wings
22+
23+Limb and wing expressions also lack runes:
24+
25+;list(src "./limb");
26+
27+;br;
28+
29+## `. dot` (Nock)
30+
31+;list(src "./dot");
32+
33+;br;
34+
35+## `! zap` (wild)
36+
37+;list(src "./zap");
38+
39+;br;
40+
41+## `= tis` (Subject Modification)
42+
43+;list(src "./tis");
44+
45+;br;
46+
47+## `? wut` (Conditionals)
48+
49+;list(src "./wut");
50+
51+;br;
52+
53+## `| bar` (Cores)
54+
55+;list(src "./bar");
56+
57+;br;
58+
59+## `~ sig` (Hints)
60+
61+;list(src "./sig");
62+
63+;br;
64+
65+## `: col` (Cells)
66+
67+;list(src "./col");
68+
69+;br;
70+
71+## `% cen` (Calls)
72+
73+;list(src "./cen");
74+
75+;br;
76+
77+## `^ ket` (Casts)
78+
79+;list(src "./ket");
80+
81+;br;
82+
83+## `$ bus` (Structures)
84+
85+;list(src "./bus");
86+
87+;br;
88+
89+## `; mic` (Make)
90+
91+;list(src "./mic");
92+
93+==
docs/reference/rune/bar.umdnew file+18
@@ -0,0 +1,18 @@
1+:- :~ navhome/'/docs/'
2+ next/'true'
3+ sort/'7'
4+ title/'Cores | ("bar")'
5+ ==
6+;>
7+
8+# Cores `|` "bar"
9+
10+Core expressions produce cores. A core is a cell of `[battery payload]`. The `battery` is code, a battery of Nock formulas. The `payload` is the data needed to run those formulas correctly.
11+
12+Four core runes (`|=`, `|.`, `|-`, and `|*`) produce a
13+core with a single arm, named `$`. We can recompute this arm
14+with changes, which useful for recursion among other things:
15+
16+## Runes
17+
18+;list(datapreview "true", classname "runes");
docs/hoon/rune/bar/cab.md → docs/reference/rune/bar/cab.umdrenamed+9−9
@@ -1,13 +1,13 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 3
3+ sort/'5'
5−title: |_ "barcab"
4+ title/'|= "barcab"'
6−---
5+ ==
6+;>
7
7
8−# `|_ "barcab"`
8+# `|_ "barcab"`
9
9
10−`[%brcb p=model q=(map term foot)]`: form a door, a many-armed core
10+`[%brcb p=spec q=(map term hoon)]`: form a door, a many-armed core
11with a sample.
11with a sample.
12
12
13## Expands to
13## Expands to
@@ -25,7 +25,7 @@ Regular: *1-fixed*, then *battery*.
25## Discussion
25## Discussion
26
26
27A door is the general case of a gate (function). A gate is a
27A door is the general case of a gate (function). A gate is a
28−door with only one arm, the empty name `$`.
28+door with only one arm, which has the empty name `$`.
29
29
30Other languages have no real equivalent of a door, but we often
30Other languages have no real equivalent of a door, but we often
31see the pattern of multiple functions with the same argument
31see the pattern of multiple functions with the same argument
docs/hoon/rune/bar/cen.md → docs/reference/rune/bar/cen.umdrenamed+7−8
@@ -1,13 +1,13 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 1
3+ sort/'1'
5−title: |% "barcen"
4+ title/'|% "barcen"'
6−---
5+ ==
6+;>
7
7
8# `|% "barcen"`
8# `|% "barcen"`
9
9
10−[%brcb p=(map term foot)]: Form a core `[battery payload]` with subject as the payload.
10+[%brcn p=(map term hoon)]: Form a core `[battery payload]` with subject as the payload.
11
11
12## Produces
12## Produces
13
13
@@ -39,4 +39,3 @@ A trivial core:
39~zod:dojo> (g.foo 1)
39~zod:dojo> (g.foo 1)
40101
40101
41```
41```
42−
docs/reference/rune/bar/col.umdnew file+26
@@ -0,0 +1,26 @@
1+:- :~ navhome/'/docs/'
2+ next/'true'
3+ sort/'9'
4+ title/'|: "barcol"'
5+ ==
6+;>
7+
8+# `|: "barcol"`
9+
10+`[%brcl p=hoon q=hoon]`: form a gate with burnt sample.
11+
12+## Expands to
13+
14+```
15+=> ^~ p
16+ |. q
17+```
18+
19+## Discussion
20+
21+Pick your own default value for the sample. Note that `p` is an ordinary expression, not a type; `|:` doesn't bunt a sample as
22+[`|=`](../tis) does.
23+
24+## Syntax
25+
26+Regular: *2-fixed*.
docs/hoon/rune/bar/dot.md → docs/reference/rune/bar/dot.umdrenamed+7−9
@@ -1,9 +1,9 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 4
3+ sort/'6'
5−title: |. "bardot"
4+ title/'|. "bardot"'
6−---
5+ ==
6+;>
7
7
8# `|. "bardot"`
8# `|. "bardot"`
9
9
@@ -53,6 +53,4 @@ A more interesting trap:
53Note that we can use `$()` to recurse back into the
53Note that we can use `$()` to recurse back into the
54trap, since it's a core with an `$` arm.
54trap, since it's a core with an `$` arm.
55
55
56−> `$()` expands to `%=($)` (["centis"](../../cen/tis)),
57−> accepting a *jogging* body containing a list of changes
56+> `$()` expands to `%=($)` (["centis"](../../cen/tis)), accepting a *jogging* body containing a list of changes to the subject.
58−> to the subject.
docs/hoon/rune/bar/hep.md → docs/reference/rune/bar/hep.umdrenamed+10−10
@@ -1,9 +1,9 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 5
3+ sort/'7'
5−title: |- "barhep"
4+ title/'|- "barhep"'
6−---
5+ ==
6+;>
7
7
8# `|- "barhep"`
8# `|- "barhep"`
9
9
@@ -21,12 +21,12 @@ Regular: *1-fixed*.
21
21
22## Discussion
22## Discussion
23
23
24−The `|-` ("barhep") rune can be thought of as a "recursion
24+The `|-` ("barhep") rune can be thought of as a "recursion
25−point". Since `|-` makes a `|.` (["bardot"](../dot), a core
25+point". Since `|-` makes a `|.` (["bardot"](../dot), a core
26with one arm named `$`, we can recurse back into it with `$()`.
26with one arm named `$`, we can recurse back into it with `$()`.
27
27
28−> `$()` expands to `%=($)` (["centis"](../../cen/tis)),
28+> `$()` expands to `%=($)` (["centis"](../../cen/tis)),
29−> accepting a *jogging* body containing a list of changes to
29+> accepting a *jogging* body containing a list of changes to
30> the subject.
30> the subject.
31
31
32## Examples
32## Examples
docs/hoon/rune/bar/ket.md → docs/reference/rune/bar/ket.umdrenamed+8−9
@@ -1,14 +1,14 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 6
3+ sort/'8'
5−title: |^ "barket"
4+ title/'|^ "barket"'
6−---
5+ ==
6+;>
7
7
8# `|^ "barket"`
8# `|^ "barket"`
9
9
10−`[%brkt p=hoon q=(map term foot)]`: form a core with battery and
10+`[%brkt p=hoon q=(map term hoon)]`: form a core with battery and
11−anonymous arm `$` and kick it.
11+anonymous arm `$` and kick it.
12
12
13## Expands to
13## Expands to
14
14
@@ -36,4 +36,3 @@ A trivial cork:
36 --
36 --
37100
37100
38```
38```
39−
docs/hoon/rune/bar/sig.md → docs/reference/rune/bar/sig.umdrenamed+7−7
@@ -1,13 +1,13 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 10
3+ sort/'2'
5−title: |~ "barsig"
4+ title/'|~ "barsig"'
6−---
5+ ==
6+;>
7
7
8# `|~ "barsig"`
8# `|~ "barsig"`
9
9
10−`[%brsg p=model q=hoon]`: form an iron gate.
10+`[%brsg p=spec q=hoon]`: form an iron gate.
11
11
12## Expands to
12## Expands to
13
13
docs/hoon/rune/bar/tar.md → docs/reference/rune/bar/tar.umdrenamed+11−12
@@ -1,14 +1,13 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 9
3+ sort/'10'
5−title: |* "bartar"
4+ title/'|* "bartar"'
6−---
5+ ==
6+;>
7
7
8−# `|* "bartar"`
8+# `|* "bartar"`
9
9
10−`[%brtr p=model q=hoon]`: form a gill, a wet one-armed
10+`[%brtr p=spec q=hoon]`: form a gill, a wet one-armed core with sample.
11−core with sample.
12
11
13## Expands to
12## Expands to
14
13
@@ -32,12 +31,12 @@ passes through the function, rather as if it was a macro (there
32is still only one copy of the code, however).
31is still only one copy of the code, however).
33
32
34Genericity is a powerful and dangerous tool. Use gills only if
33Genericity is a powerful and dangerous tool. Use gills only if
35−you think you know what you're doing.
34+you think you know what you're doing.
36
35
37−Just as with a [gate](../tis), we can recurse back into a gill
36+Just as with a [gate](../tis), we can recurse back into a gill
38with `$()`.
37with `$()`.
39
38
40−> `$()` expands to `%=($)` (["centis"](../../cen/tis)), accepting
39+> `$()` expands to `%=($)` (["centis"](../../cen/tis)), accepting
41> a *jogging* body containing a list of changes to the subject.
40> a *jogging* body containing a list of changes to the subject.
42
41
43## Examples
42## Examples
docs/hoon/rune/bar/tis.md → docs/reference/rune/bar/tis.umdrenamed+9−9
@@ -1,11 +1,11 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 2
3+ sort/'4'
5−title: |= "bartis"
4+ title/'|= "bartis"'
6−---
5+ ==
6+;>
7
7
8−# `|= "bartis"`
8+# `|= "bartis"`
9
9
10`[%brts p=model q=hoon]`: form a gate, a dry one-armed core with sample.
10`[%brts p=model q=hoon]`: form a gate, a dry one-armed core with sample.
11
11
@@ -23,10 +23,10 @@ Regular: *2-fixed*.
23
23
24## Discussion
24## Discussion
25
25
26−A gate is a core with one arm named `$`, so, just as with
26+A gate is a core with one arm named `$`, so, just as with
27[`|-` ("barhep")](../hep), we can recurse back into it with `$()`.
27[`|-` ("barhep")](../hep), we can recurse back into it with `$()`.
28
28
29−> `$()` expands to `%=($)` (["centis"](../../cen/tis)), accepting
29+> `$()` expands to `%=($)` (["centis"](../../cen/tis)), accepting
30> a *jogging* body containing a list of changes to the subject.
30> a *jogging* body containing a list of changes to the subject.
31
31
32## Examples
32## Examples
docs/hoon/rune/bar/wut.md → docs/reference/rune/bar/wut.umdrenamed+6−5
@@ -1,8 +1,9 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
2+ next/'true'
3−sort: 11
3+ sort/'3'
4−title: |? "barwut"
4+ title/'|? "barwut"'
5−---
5+ ==
6+;>
6
7
7# `|? "barwut"`
8# `|? "barwut"`
8
9
docs/reference/rune/bus.umdnew file+36
@@ -0,0 +1,36 @@
1+:- :~ navhome/'/docs/'
2+ next/'true'
3+ sort/'12'
4+ title/'Structures $ ("bus")'
5+ ==
6+;>
7+
8+# Structures $ ("bus")
9+
10+The `$` family of runes is used for defining custom types. Strictly speaking, these runes are used to produce 'structures'. A structure is a compile-time value that at runtime can be converted to either an example value (sometimes called a 'bunt' value) for its corresponding type, or to a 'factory' (sometimes called a 'mold'). An example value is used as a placeholder for sample values, among other things. A factory/mold is used as a data validator.
11+
12+## Overview
13+
14+A correct mold is a *normalizer*: an idempotent function across
15+all nouns. If the sample of a gate has type `%noun`, and its
16+body obeys the constraint that for any x, `=((mold x) (mold (mold
17+x)))`, it's a normalizer and can be used as a mold.
18+
19+(Hoon is not dependently typed and so can't check idempotence
20+statically, so we can't actually tell if a mold matches this
21+definition perfectly. This is not actually a problem.)
22+
23+Validation, though very
24+important, is a rare use case. Except for direct raw input,
25+it's generally a faux pas to rectify nouns at runtime -- or even
26+in userspace.
27+
28+In any case, since molds are just functions, we can use
29+functional programming to assemble interesting molds. For
30+instance, `(map foo bar)` is a table from mold `foo` to mold
31+`bar`. `map` is not a mold; it's a function that makes a mold.
32+Molds and mold builders are generally described together.
33+
34+## Runes
35+
36+;list(datapreview "true", classname "runes");
docs/reference/rune/bus/base.umdnew file+34
@@ -0,0 +1,34 @@
1+:- :~ navhome/'/docs/'
2+ next/'true'
3+ sort/'1'
4+ title/'Base Structures'
5+ ==
6+;>
7+
8+# Base Structures
9+
10+`[%base p=$@(?(%noun %cell %bean %null) [%atom p=aura])]`: trivial structures (types).
11+
12+## Produces
13+
14+A structure for the base in `p`. `%noun` is any noun; `%atom` is any
15+atom; `%cell` is a cell of nouns; `%bean` is a loobean, ``?(`@f`0
16+`@f`1)``. `%null` is zero with aura `@n`.
17+
18+## Syntax
19+
20+Irregular: `*` makes `%noun`, `^` makes `%cell`, `?` makes
21+`%bean`, `~` makes `%null`, `@aura` makes atom `aura`.
22+
23+## Examples
24+
25+```
26+~zod:dojo> (* %foo)
27+7.303.014
28+~zod:dojo> (,~ 0)
29+~
30+~zod:dojo> (^ 0)
31+^
32+~zod:dojo> (@ux [1 1])
33+0x0
34+```
docs/hoon/rune/buc/cab.md → docs/reference/rune/bus/cab.umdrenamed+9−9
@@ -1,13 +1,13 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 9
3+ sort/'9'
5−title: $_ "buccab"
4+ title/'$_ "buscab"'
6−---
5+ ==
6+;>
7
7
8−# `$_ "buccab"`
8+# `$_ "buscab"`
9
9
10−`[%bccb p=hoon]`: mold which normalizes to an example.
10+`[%bscb p=hoon]`: structure that normalizes to an example.
11
11
12## Expands to
12## Expands to
13
13
@@ -23,7 +23,7 @@ Irregular: `_foo` is `$_(foo)`.
23
23
24## Discussion
24## Discussion
25
25
26−`$_` ("buccab") discards the sample it's supposedly normalizing
26+`$_` ("buscab") discards the sample it's supposedly normalizing
27and produces its *example* instead.
27and produces its *example* instead.
28
28
29## Examples
29## Examples
docs/hoon/rune/buc/cen.md → docs/reference/rune/bus/cen.umdrenamed+11−11
@@ -1,13 +1,13 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 5
3+ sort/'5'
5−title: $% "buccen"
4+ title/'$% "buscen"'
6−---
5+ ==
6+;>
7
7
8−# `$% "buccen"`
8+# `$% "buscen"`
9
9
10−`[%bccn p=(list [[aura @] model])]`: mold which recognizes a union tagged by head atom.
10+`[%bscn p=(list [[aura @] spec])]`: structure which recognizes a union tagged by head atom.
11
11
12## Normalizes to
12## Normalizes to
13
13
@@ -21,15 +21,15 @@ Void if `p` is empty.
21For the first item `i` in `p`, the cell `[q.p.i.p $:q.i.p]`.
21For the first item `i` in `p`, the cell `[q.p.i.p $:q.i.p]`.
22Crashes if `p` is empty.
22Crashes if `p` is empty.
23
23
24−## Syntax
24+## Syntax
25
25
26Regular form: *2-running*.
26Regular form: *2-running*.
27
27
28## Discussion
28## Discussion
29
29
30−A `$%` ("buccen") is a tagged union, an extremely common data model.
30+A `$%` ("buscen") is a tagged union, an extremely common data model.
31
31
32−Make sure the first item in your `$%` terminates, or the default will
32+Make sure the first item in your `$%` terminates, or the default will
33be an infinite loop!
33be an infinite loop!
34
34
35## Examples
35## Examples
docs/reference/rune/bus/col.umdnew file+40
@@ -0,0 +1,40 @@
1+:- :~ navhome/'/docs/'
2+ next/'true'
3+ sort/'3'
4+ title/'$: "buscol"'
5+ ==
6+;>
7+
8+# `$: "buscol"`
9+
10+`[%bscl p=(list spec)]`: form a cell type.
11+
12+## Normalizes
13+
14+The tuple the length of `p`, normalizing each item.
15+
16+## Defaults to
17+
18+The tuple the length of `p`.
19+
20+## Syntax
21+
22+Regular: *running*.
23+
24+Irregular (noun mode): `,[a b c]` is `$:(a b c)`.
25+Irregular (structure mode): `[a b c]` is `$:(a b c)`.
26+
27+## Examples
28+
29+```
30+~zod:dojo> =foo $:(p=@ud q=@tas)
31+
32+~zod:dojo> (foo 33 %foo)
33+[p=33 q=%foo]
34+
35+~zod:dojo> `foo`[33 %foo]
36+[p=33 q=%foo]
37+
38+~zod:dojo> $:foo
39+[p=0 q=%$]
40+```
docs/reference/rune/bus/hep.umdnew file+34
@@ -0,0 +1,34 @@
1+:- :~ navhome/'/docs/'
2+ next/'true'
3+ sort/'2'
4+ title/'$- "bushep"'
5+ ==
6+;>
7+
8+# `$- "buchep"`
9+
10+`[%bshp p=spec q=spec]`: structure that normalizes to an example gate.
11+
12+## Expands to
13+
14+```
15+$_ ^|
16+|=(p $:q)
17+```
18+
19+## Syntax
20+
21+Regular: *2-fixed*.
22+
23+## Discussion
24+
25+Since a `$-` ("bushep") is a [`$_` ("buscab")](../cab/), it is not useful for normalizing, just for typechecking. In particular, the existence of `$-`s does *not* let us send gates or other cores over the network!
26+
27+## Examples
28+
29+```
30+~zod:dojo> =foo $-(%foo %bar)
31+
32+~zod:dojo> ($:foo %foo)
33+%bar
34+```
docs/hoon/rune/buc/ket.md → docs/reference/rune/bus/ket.umdrenamed+9−10
@@ -1,13 +1,13 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 7
3+ sort/'7'
5−title: $^ "bucket"
4+ title/'$^ "busket"'
6−---
5+ ==
6+;>
7
7
8−# `$^ "bucket"`
8+# `$^ "busket"`
9
9
10−`[%bckt p=model q=model]`: mold which normalizes a union tagged by head depth (cell).
10+`[%bskt p=spec q=spec]`: structure which normalizes a union tagged by head depth (cell).
11
11
12## Normalizes to
12## Normalizes to
13
13
@@ -35,7 +35,6 @@ Regular: *2-fixed*.
35~zod:dojo> (b [%foo 19 22])
35~zod:dojo> (b [%foo 19 22])
36[%foo p=19 q=22]
36[%foo p=19 q=22]
37
37
38−~zod:dojo> $:b
38+~zod:dojo> $:b
39[%bar p=0]
39[%bar p=0]
40```
40```
41−
docs/hoon/rune/buc/tis.md → docs/reference/rune/bus/tis.umdrenamed+8−8
@@ -1,13 +1,13 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 8
3+ sort/'8'
5−title: $= "buctis"
4+ title/'$= "bustis"'
6−---
5+ ==
6+;>
7
7
8−# `$= "buctis"`
8+# `$= "bustis"`
9
9
10−`[%bcts p=@tas q=model]`: mold which wraps a face around another mold.
10+`[%bsts p=@tas q=spec]`: structure which wraps a face around another structure.
11
11
12## Expands to
12## Expands to
13
13
docs/hoon/rune/buc/pat.md → docs/reference/rune/bus/vat.umdrenamed+10−10
@@ -1,14 +1,14 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 6
3+ sort/'6'
5−title: $@ "bucpat"
4+ title/'$@ "busvat"'
6−---
5+ ==
6+;>
7
7
8−# `$@ "bucpat"`
8+# `$@ "busvat"`
9+
10+`[%bsvt p=spec q=spec]`: structure which normalizes a union tagged by head depth (atom).
9
11
10−`[%bcpt p=model q=model]`: mold which normalizes a union tagged by head depth (atom).
11−
12## Normalizes to
12## Normalizes to
13
13
14Default, if the sample is an atom; `p`, if the head of the sample
14Default, if the sample is an atom; `p`, if the head of the sample
@@ -22,7 +22,7 @@ The default of `p`.
22
22
23Regular: *2-fixed*.
23Regular: *2-fixed*.
24
24
25−Product: a mold which applies `p` if its sample is an atom,
25+Product: a structure which applies `p` if its sample is an atom,
26`q` if its sample is a cell.
26`q` if its sample is a cell.
27
27
28Regular form: *2-fixed*.
28Regular form: *2-fixed*.
docs/reference/rune/bus/wut.umdnew file+49
@@ -0,0 +1,49 @@
1+:- :~ navhome/'/docs/'
2+ next/'true'
3+ sort/'4'
4+ title/'$? "buswut"'
5+ ==
6+;>
7+
8+# `$? "buswut"`
9+
10+`[%bswt p=(list spec)]`: form a type from a union of other types.
11+
12+## Normalizes to
13+
14+The first item in `p` which normalizes the sample to itself;
15+otherwise, default.
16+
17+Void, if `p` is empty.
18+
19+## Defaults to
20+
21+The first item in `p`.
22+
23+## Syntax
24+
25+Regular: *running*.
26+
27+Irregular: `?(%foo %bar)` is `$?(%foo %bar)`.
28+
29+## Discussion
30+
31+For a union of atoms, a `$?` ("buswut") is fine. For more complex nouns,
32+always try to use a [`$%` ("buscen")](../cen/), [`$@` ("busvat")](../vat/) or
33+[`$^` ("busket")](../ket/), at least if you expect your structure to be used as a
34+normalizer.
35+
36+## Examples
37+
38+```
39+~zod:dojo> =a ?(%foo %bar %baz)
40+
41+~zod:dojo> (a %baz)
42+%baz
43+
44+~zod:dojo> (a [37 45])
45+%baz
46+
47+~zod:dojo> $:a
48+%baz
49+```
docs/reference/rune/cen.umdnew file+16
@@ -0,0 +1,16 @@
1+:- :~ navhome/'/docs/'
2+ next/'true'
3+ sort/'10'
4+ title/'Calls % ("cen")'
5+ ==
6+;>
7+
8+# Calls `%` ("cen")
9+
10+The `%` family of runes is used for making 'function calls' in Hoon. To be more precise, these runes evaluate the `$` arm in cores, usually after modifying the sample. (The default sample is replaced with the input values given in the call.)
11+
12+These runes reduce to the `%=` rune
13+
14+## Runes
15+
16+;list(datapreview "true", classname "runes");
docs/hoon/rune/cen/cab.md → docs/reference/rune/cen/cab.umdrenamed+12−8
@@ -1,13 +1,13 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
2+ next/'true'
3−sort: 8
3+ sort/'8'
4−title: %_ "cencab"
4+ title/'%_ "cencab"'
5−---
5+ ==
6+;>
6
7
7# `%_ "cencab"`
8# `%_ "cencab"`
8
9
9−`[%cncb p=wing q=(list (pair wing hoon))]`: take a wing with changes,
10+`[%cncb p=wing q=(list (pair wing hoon))]`: take a wing with changes, preserving type.
10−preserving type.
11
11
12## Expands to
12## Expands to
13
13
@@ -21,19 +21,23 @@ Regular: *1-fixed*, then *jogging*.
21
21
22## Discussion
22## Discussion
23
23
24−`%_` ("cencab") is different from `%=` ("centis") because `%=`
24+`%_` ("cencab") is different from `%=` ("centis") because `%=`
25can change the type of a limb with mutations.
25can change the type of a limb with mutations.
26
26
27## Examples
27## Examples
28
28
29```
29```
30~zod:dojo> =foo [p=42 q=6]
30~zod:dojo> =foo [p=42 q=6]
31+
31~zod:dojo> foo(p %bar)
32~zod:dojo> foo(p %bar)
32[p=%bar q=6]
33[p=%bar q=6]
34+
33~zod:dojo> foo(p [55 99])
35~zod:dojo> foo(p [55 99])
34[p=[55 99] q=6]
36[p=[55 99] q=6]
37+
35~zod:dojo> %_(foo p %bar)
38~zod:dojo> %_(foo p %bar)
36[p=7.496.034 99]
39[p=7.496.034 99]
40+
37~zod:dojo> %_(foo p [55 99])
41~zod:dojo> %_(foo p [55 99])
38! nest-fail
42! nest-fail
39```
43```
docs/hoon/rune/cen/dot.md → docs/reference/rune/cen/dot.umdrenamed+8−8
@@ -1,11 +1,11 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 3
3+ sort/'3'
5−title: %. "cendot"
4+ title/'%. "cendot"'
6−---
5+ ==
6+;>
7
7
8−# `%. "cendot"`
8+# `%. "cendot"`
9
9
10`[%cndt p=hoon q=hoon]`: call a gate (function), reversed.
10`[%cndt p=hoon q=hoon]`: call a gate (function), reversed.
11
11
@@ -23,7 +23,7 @@ Regular: *2-fixed*.
23
23
24```
24```
25~zod:dojo> =add-triple |=([a=@ b=@ c=@] :(add a b c))
25~zod:dojo> =add-triple |=([a=@ b=@ c=@] :(add a b c))
26+
26~zod:dojo> %.([1 2 3] add-triple)
27~zod:dojo> %.([1 2 3] add-triple)
276
286
28```
29```
29−
docs/hoon/rune/cen/hep.md → docs/reference/rune/cen/hep.umdrenamed+9−10
@@ -1,9 +1,9 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 2
3+ sort/'2'
5−title: %- "cenhep"
4+ title/'%- "cenhep"'
6−---
5+ ==
6+;>
7
7
8# `%- "cenhep"`
8# `%- "cenhep"`
9
9
@@ -23,8 +23,8 @@ Irregular: `(a)` is `$:a`; `(a b c d)` is `%-(a [b c d])`.
23
23
24## Discussion
24## Discussion
25
25
26−`%-` ("cenhep") is a function call; `p` is the function ([`gate`](../../bar/tis),
26+`%-` ("cenhep") is a function call; `p` is the function ([`gate`](../../bar/tis),
27−`q` the argument. `%-` is a special case of [`%~` ("censig")](../sig), and a gate
27+`q` the argument. `%-` is a special case of [`%~` ("censig")](../sig), and a gate
28is a special case of a [door](../../bar/cab).
28is a special case of a [door](../../bar/cab).
29
29
30In a gate, the modified core has only one anonymous arm; in a
30In a gate, the modified core has only one anonymous arm; in a
@@ -32,7 +32,7 @@ door it gets a full battery. Intuitively, a gate defines one
32algorithm it can compute upon its sample, `+6`. A door defines
32algorithm it can compute upon its sample, `+6`. A door defines
33many such algorithms.
33many such algorithms.
34
34
35−In classical languages, doors correspond to groups of functions
35+In classical languages, doors correspond to groups of functions
36with the same argument list, or at least sharing a prefix. In
36with the same argument list, or at least sharing a prefix. In
37Hoon, this shared sample is likely to be pulled into a door.
37Hoon, this shared sample is likely to be pulled into a door.
38
38
@@ -45,4 +45,3 @@ Hoon, this shared sample is likely to be pulled into a door.
45~zod:dojo> %-(add-triple [1 2 3])
45~zod:dojo> %-(add-triple [1 2 3])
466
466
47```
47```
48−
docs/hoon/rune/cen/ket.md → docs/reference/rune/cen/ket.umdrenamed+8−7
@@ -1,11 +1,11 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 5
3+ sort/'5'
5−title: %^ "cenket"
4+ title/'%^ "cenket"'
6−---
5+ ==
6+;>
7
7
8−# `%^ "cenket"`
8+# `%^ "cenket"`
9
9
10`[%cnkt p=hoon q=hoon r=hoon s=hoon]`: call with triple sample.
10`[%cnkt p=hoon q=hoon r=hoon s=hoon]`: call with triple sample.
11
11
@@ -23,6 +23,7 @@ Regular: *4-fixed*.
23
23
24```
24```
25~zod:dojo> =add-triple |=([a/@ b/@ c/@] :(add a b c))
25~zod:dojo> =add-triple |=([a/@ b/@ c/@] :(add a b c))
26+
26~zod:dojo> %^(add-triple 1 2 3)
27~zod:dojo> %^(add-triple 1 2 3)
276
286
28```
29```
docs/hoon/rune/cen/lus.md → docs/reference/rune/cen/lus.umdrenamed+8−7
@@ -1,11 +1,11 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 4
3+ sort/'4'
5−title: %+ "cenlus"
4+ title/'%+ "cenlus"'
6−---
5+ ==
6+;>
7
7
8−# `%+ "cenlus"`
8+# `%+ "cenlus"`
9
9
10`[%cnls p=hoon q=hoon r=hoon]`: call with pair sample.
10`[%cnls p=hoon q=hoon r=hoon]`: call with pair sample.
11
11
@@ -23,6 +23,7 @@ Regular: *3-fixed*.
23
23
24```
24```
25~zod:dojo> =add-triple |=([a=@ b=@ c=@] :(add a b c))
25~zod:dojo> =add-triple |=([a=@ b=@ c=@] :(add a b c))
26+
26~zod:dojo> %+(add-triple 1 [2 3])
27~zod:dojo> %+(add-triple 1 [2 3])
276
286
28```
29```
docs/hoon/rune/cen/sig.md → docs/reference/rune/cen/sig.umdrenamed+7−9
@@ -1,9 +1,9 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 6
3+ sort/'6'
5−title: %~ "censig"
4+ title/'%~ "censig"'
6−---
5+ ==
6+;>
7
7
8# `%~ "censig"`
8# `%~ "censig"`
9
9
@@ -16,8 +16,7 @@ title: %~ "censig"
16=<(p %=(a +6 r))
16=<(p %=(a +6 r))
17```
17```
18
18
19−> Note: the expansion implementation is hygienic -- it doesn't actually add the
19+> Note: the expansion implementation is hygienic -- it doesn't actually add the `a` face to the subject. It's shown here because `%=` ("centis") requires a `wing`.
20−> `a` face to the subject. It's shown here because `%=` ("centis") requires a `wing`.
21
20
22## Syntax
21## Syntax
23
22
@@ -39,4 +38,3 @@ learn to step outside your linear, Western way of thinking."
39## Examples
38## Examples
40
39
41See [`|_`](../../bar/cab).
40See [`|_`](../../bar/cab).
42−
docs/hoon/rune/cen/tar.md → docs/reference/rune/cen/tar.umdrenamed+13−10
@@ -1,14 +1,13 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 7
3+ sort/'7'
5−title: %* "centar"
4+ title/'%* "centar"'
6−---
5+ ==
6+;>
7
7
8# `%* "centar"`
8# `%* "centar"`
9
9
10−`[%cntr p=wing q=hoon r=(list (pair wing hoon))]`: make
10+`[%cntr p=wing q=hoon r=(list (pair wing hoon))]`: make with arbitrary expression.
11−with arbitrary hoon.
12
11
13## Expands to
12## Expands to
14
13
@@ -24,8 +23,8 @@ Regular: *2-fixed*, then *jogging*.
24
23
25## Discussion
24## Discussion
26
25
27−`%*` makes a limb from a hoon, with changes. It's useful when you want
26+`%*` makes a limb from an expression, with changes. It's useful when you want
28−evaluate a hoon, pull out a single limb from the result,
27+evaluate an expression, pull out a single limb from the result,
29and then change some parts of the limb before using it.
28and then change some parts of the limb before using it.
30
29
31## Examples
30## Examples
@@ -33,11 +32,15 @@ and then change some parts of the limb before using it.
33```
32```
34~zod:dojo> %*($ add a 2, b 3)
33~zod:dojo> %*($ add a 2, b 3)
355
345
35+
36~zod:dojo> =foo [a=1 b=2 c=3 d=4]
36~zod:dojo> =foo [a=1 b=2 c=3 d=4]
37+
37~zod:dojo> %*(+ foo c %hello, d %world)
38~zod:dojo> %*(+ foo c %hello, d %world)
38[b=2 c=%hello d=%world]
39[b=2 c=%hello d=%world]
40+
39~zod:dojo> =+(foo=[a=1 b=2 c=3] foo(b 7, c 10))
41~zod:dojo> =+(foo=[a=1 b=2 c=3] foo(b 7, c 10))
40[a=1 b=7 c=10]
42[a=1 b=7 c=10]
43+
41~zod:dojo> %*(foo [foo=[a=1 b=2 c=3]] b 7, c 10)
44~zod:dojo> %*(foo [foo=[a=1 b=2 c=3]] b 7, c 10)
42[a=1 b=7 c=10]
45[a=1 b=7 c=10]
43```
46```
docs/hoon/rune/cen/tis.md → docs/reference/rune/cen/tis.umdrenamed+8−8
@@ -1,9 +1,9 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 1
3+ sort/'1'
5−title: %= "centis"
4+ title/'%= "centis"'
6−---
5+ ==
6+;>
7
7
8# `%= "centis"`
8# `%= "centis"`
9
9
@@ -25,8 +25,8 @@ Irregular: `foo(x 1, y 2, z 3)` is `%=(foo x 1, y 2, z 3)`.
25
25
26## Discussion
26## Discussion
27
27
28−Note that `p` is a wing, not a hoon. Knowing that a function
28+Note that `p` is a wing, not just any expression. Knowing that a function
29−call `(foo bar)` involves making `foo`, replacing its sample
29+call `(foo bar)` involves making `foo`, replacing its sample
30at slot `+6` with `bar`, and taking the `$` limb, you might think
30at slot `+6` with `bar`, and taking the `$` limb, you might think
31`(foo bar)` would mean `%=(foo +6 bar)`.
31`(foo bar)` would mean `%=(foo +6 bar)`.
32
32
docs/reference/rune/col.umdnew file+14
@@ -0,0 +1,14 @@
1+:- :~ navhome/'/docs/'
2+ next/'true'
3+ sort/'9'
4+ title/'Cells : ("col")'
5+ ==
6+;>
7+
8+# Cells `:` ("col")
9+
10+The `:` ("col") expressions are used to produce cells, which are pairs of values. E.g., `:-(p q)` produces the cell `[p q]`. All `:` runes reduce to `:-`.
11+
12+## Runes
13+
14+;list(datapreview "true", classname "runes");
docs/hoon/rune/col/cab.md → docs/reference/rune/col/cab.umdrenamed+6−6
@@ -1,9 +1,9 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 2
3+ sort/'2'
5−title: :_ "colcab"
4+ title/':_ "colcab"'
6−---
5+ ==
6+;>
7
7
8# `:_ "colcab"`
8# `:_ "colcab"`
9
9
docs/hoon/rune/col/hep.md → docs/reference/rune/col/hep.umdrenamed+12−9
@@ -1,9 +1,9 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 1
3+ sort/'1'
5−title: :- "colhep"
4+ title/':- "colhep"'
6−---
5+ ==
6+;>
7
7
8# `:- "colhep"`
8# `:- "colhep"`
9
9
@@ -33,19 +33,22 @@ Irregular: `[a b c]~` is `[[a b c] ~]`.
33
33
34## Discussion
34## Discussion
35
35
36−Hoon hoons actually use the same "autocons" pattern as Nock
36+Hoon expressions actually use the same "autocons" pattern as Nock
37−formulas. If you're assembling hoons (which usually only the
37+formulas. If you're assembling expressions (which usually only the
38compiler does), `[a b]` is the same as `[%clhp a b]`.
38compiler does), `[a b]` is the same as `[%clhp a b]`.
39
39
40## Examples
40## Examples
41
41
42```
42```
43~zod:dojo> :-(1 2)
43~zod:dojo> :-(1 2)
44−[1 2]
44+[1 2
45+
45~zod:dojo> 1^2
46~zod:dojo> 1^2
46[1 2]
47[1 2]
48+
47~zod:dojo> 1/2
49~zod:dojo> 1/2
48[%1 2]
50[%1 2]
51+
49~zod:dojo> `1
52~zod:dojo> `1
50[~ 1]
53[~ 1]
51```
54```
docs/hoon/rune/col/ket.md → docs/reference/rune/col/ket.umdrenamed+12−11
@@ -1,9 +1,9 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 4
3+ sort/'4'
5−title: :^ "colket"
4+ title/':^ "colket"'
6−---
5+ ==
6+;>
7
7
8# `:^ "colket"`
8# `:^ "colket"`
9
9
@@ -22,11 +22,12 @@ Regular: *4-fixed*.
22## Examples
22## Examples
23
23
24```
24```
25−/~zod:dojo> :^(1 2 3 4)
25+~zod:dojo> :^(1 2 3 4)
26[1 2 3 4]
26[1 2 3 4]
27+
27−/~zod:dojo> :^ 5
28+~zod:dojo> :^ 5
28− 6
29+ 6
29− 7
30+ 7
30− 8
31+ 8
31[5 6 7 8]
32[5 6 7 8]
32```
33```
docs/hoon/rune/col/lus.md → docs/reference/rune/col/lus.umdrenamed+8−7
@@ -1,9 +1,9 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 3
3+ sort/'3'
5−title: :+ "collus"
4+ title/':+ "collus"'
6−---
5+ ==
6+;>
7
7
8# `:+ "collus"`
8# `:+ "collus"`
9
9
@@ -26,6 +26,7 @@ Regular: *3-fixed*.
26 2
26 2
27 3
27 3
28[1 2 3]
28[1 2 3]
29+
29−/~zod:dojo> :+(%a ~ 'b')
30+~zod:dojo> :+(%a ~ 'b')
30[%a ~ 'b']
31[%a ~ 'b']
31```
32```
docs/hoon/rune/col/sig.md → docs/reference/rune/col/sig.umdrenamed+8−5
@@ -1,8 +1,9 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
2+ next/'true'
3−sort: 6
3+ sort/'6'
4−title: :~ "colsig"
4+ title/':~ "colsig"'
5−---
5+ ==
6+;>
6
7
7# `:~ "colsig"`
8# `:~ "colsig"`
8
9
@@ -35,8 +36,10 @@ Regular: *running*.
35```
36```
36~zod:dojo> :~(5 3 4 2 1)
37~zod:dojo> :~(5 3 4 2 1)
37[5 3 4 2 1 ~]
38[5 3 4 2 1 ~]
39+
38~zod:dojo> ~[5 3 4 2 1]
40~zod:dojo> ~[5 3 4 2 1]
39[5 3 4 2 1 ~]
41[5 3 4 2 1 ~]
42+
40~zod:dojo> :~ 5
43~zod:dojo> :~ 5
41 3
44 3
42 4
45 4
docs/hoon/rune/col/tar.md → docs/reference/rune/col/tar.umdrenamed+12−10
@@ -1,9 +1,9 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 5
3+ sort/'5'
5−title: :* "coltar"
4+ title/':* "coltar"'
6−---
5+ ==
6+;>
7
7
8# `:* "coltar"`
8# `:* "coltar"`
9
9
@@ -36,13 +36,15 @@ Regular: *running*.
36## Examples
36## Examples
37
37
38```
38```
39−/~zod:dojo> :*(5 3 4 1 4 9 0 ~ 'a')
39+~zod:dojo> :*(5 3 4 1 4 9 0 ~ 'a')
40[5 3 4 1 4 9 0 ~ 'a']
40[5 3 4 1 4 9 0 ~ 'a']
41+
41−/~zod:dojo> [5 3 4 1 4 9 0 ~ 'a']
42+~zod:dojo> [5 3 4 1 4 9 0 ~ 'a']
42[5 3 4 1 4 9 0 ~ 'a']
43[5 3 4 1 4 9 0 ~ 'a']
44+
43−/~zod:dojo> :* 5
45+~zod:dojo> :* 5
44 3
46 3
45− 4
47+ 4
46 1
48 1
47 4
49 4
48 9
50 9
docs/reference/rune/constants.umdnew file+16
@@ -0,0 +1,16 @@
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3+ sort/'1'
4+ title/'Atoms and strings'
5+ ==
6+;>
7+
8+# Atoms and strings
9+
10+The simplest expressions in every language are constants:
11+atoms, strings, paths. (Strings and paths aren't all constants per
12+se, because they have interpolations.)
13+
14+## Expressions
15+
16+;list(datapreview "true", classname "runes");
docs/reference/rune/constants/cold.umdnew file+40
@@ -0,0 +1,40 @@
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3+ sort/'2'
4+ title/'Cold Atoms'
5+ ==
6+;>
7+
8+# Cold Atoms
9+
10+`[%rock p=term q=@]`; a constant, cold atom.
11+
12+A cold atom is one whose type is inferred to be of a single atom constant.
13+
14+### Produces
15+
16+A cold (fixed) atom `q` with aura `p`.
17+
18+### Syntax
19+
20+Irregular: any warm atom [(`%sand`)](../sand/) form, prefixed with `%`.
21+
22+Irregular: e.g., `%hi`. Character constraints: `a-z`
23+lowercase to start, `a-z` or `0-9` thereafter, with infix
24+hyphens (`hep`), "kebab-case."
25+
26+Irregular: `~`, `@n`, null (`0`).
27+
28+### Examples
29+
30+We can see the contrast with warm atoms by using the compiler parser function, `ream`:
31+
32+```
33+> (ream '%hi')
34+[%rock p=%tas q=26.984]
35+
36+> (ream '\'hi\'')
37+[%sand p=%t q=26.984]
38+```
39+
40+Cold atoms all have the aura `@tas`. (Hence the `p=%tas` in the parsed result of `%12`.)
docs/reference/rune/constants/path.umdnew file+35
@@ -0,0 +1,35 @@
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3+ sort/'4'
4+ title/'Paths'
5+ ==
6+;>
7+
8+# Paths
9+
10+`[%path p=(list (each @ta hoon))]`: path with interpolation.
11+
12+### Produces
13+
14+A null-terminated list of the items in `p`, which are either constant
15+`@ta` atoms (`knots`), or expressions producing a `knot`.
16+
17+### Syntax
18+
19+Irregular: `/this/is/a/path`.
20+
21+### Examples
22+
23+```
24+> `path`/this/is/a/path
25+/this/is/a/path
26+
27+> `path`/this/is/[`@ta`(cat 3 %a- %test)]/path
28+/this/is/a-test/path
29+
30+> `path`/this/is/(scot %tas 'test')/path
31+/this/is/test/path
32+
33+> /
34+~
35+```
docs/reference/rune/constants/text.umdnew file+51
@@ -0,0 +1,51 @@
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3+ sort/'3'
4+ title/'Text /w Interpolation'
5+ ==
6+;>
7+
8+# Text with Interpolation
9+
10+`[%knit p=(list (each @t hoon))]`: text string with interpolation.
11+
12+### Produces
13+
14+A tape.
15+
16+### Syntax
17+
18+Irregular: `"abcdefg"`.
19+
20+Irregular: `"abc{(weld "lmnop" "xyz")}defg"`.
21+
22+```
23+> "abcdefg"
24+"abcdefg"
25+
26+> "abc{(weld "lmnop" "xyz")}defg"
27+"abclmnopxyzdefg"
28+```
29+
30+### Examples
31+
32+String:
33+
34+```
35+> "hello, world."
36+"hello, world."
37+```
38+
39+String with interpolation:
40+
41+```
42+> =+(planet="world" "hello, {planet}.")
43+"hello, world."
44+```
45+
46+String with interpolated prettyprinting:
47+
48+```
49+> =+(planet=%world "hello, {<planet>}.")
50+"hello, %world."
51+```
docs/hoon/atom/sand.md → docs/reference/rune/constants/warm.umdrenamed+28−9
@@ -1,16 +1,35 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3−sort: 1
3+ sort/'1'
4−title: Sand
4+ title/'Warm Atoms'
5−---
5+ ==
6+;>
6
7
7−# Sand
8+# Warm Atoms
8
9
9`[%sand p=term q=@]`; a constant, warm atom.
10`[%sand p=term q=@]`; a constant, warm atom.
10
11
12+A 'warm' atom is one whose type is inferred to be general, i.e., not just a single atom type.
13+
14+```
15+> `@`12
16+12
17+
18+> `%12`12
19+nest-fail
20+```
21+
11### Produces
22### Produces
12
23
13−A warm (variable) atom `q` with aura `a`.
24+A warm (variable) atom `q` with aura `p`. Use the Hoon compiler parser function `ream` to take a closer look:
25+
26+```
27+> (ream '12')
28+[%sand p=%ud q=12]
29+
30+> (ream '\'Hello!\'')
31+[%sand p=%t q=36.762.444.129.608]
32+```
14
33
15### Syntax by example
34### Syntax by example
16
35
@@ -48,10 +67,10 @@ Irregular. A table of examples:
48@uc bitcoin address 0c1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa
67@uc bitcoin address 0c1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa
49@ud unsigned decimal 42 (42)
68@ud unsigned decimal 42 (42)
50 1.420 (1420)
69 1.420 (1420)
51−@uv unsigned base32 0v3ic5h.6urr6
70+@uv unsigned base32 0v3ic5h.6urr6
52@uw unsigned base64 0wsC5.yrSZC
71@uw unsigned base64 0wsC5.yrSZC
53@ux unsigned hexadecimal 0xcafe.babe
72@ux unsigned hexadecimal 0xcafe.babe
54```
73```
55
74
56−The `@uv` characters are `0-9`, `a-v`. The `@uw` characters are
75+The `@uv` characters are `0-9`, `a-v`. The `@uw` characters are
57`0-9`, `a-z`, `A-Z`, `-` and `~`.
76`0-9`, `a-z`, `A-Z`, `-` and `~`.
docs/reference/rune/dot.umdnew file+14
@@ -0,0 +1,14 @@
1+:- :~ navhome/'/docs/'
2+ next/'true'
3+ sort/'3'
4+ title/'Nock . ("dot")'
5+ ==
6+;>
7+
8+# Nock `.` ("dot")
9+
10+Anything Nock can do, Hoon can do also. These runes are used for carrying out Nock operations in Hoon.
11+
12+## Runes
13+
14+;list(datapreview "true", classname "runes");
docs/reference/rune/dot/ket.umdnew file+80
@@ -0,0 +1,80 @@
1+:- :~ navhome/'/docs/'
2+ sort/'5'
3+ title/'.^ "dotket"'
4+ ==
5+;>
6+
7+# `.^ "dotket"`
8+
9+`[%dtkt p=spec q=hoon]`: load from the Arvo namespace with Nock `11`.
10+
11+## Produces
12+
13+The noun `q`, cast to the type `p`.
14+
15+## Discussion
16+
17+Nock has no `11` instruction, of course. But the virtual Nock
18+used to run userspace code does. Nock `11` loads from a
19+typed immutable namespace defined by its virtual context.
20+
21+Ordinarily a Hoon expression has access to no information but whatever can be found in the subject. The one exception is with the `.^` rune. It essentially allows you to request information from one of the Arvo vanes (modules).
22+
23+`.^` checks that the type of the value retrieved from Arvo nests under `p`. `p` is a `path` which includes information about which vane is being queried, and what sort of information is requested.
24+
25+In principle `.^` takes two subexpressions, but in practice `q` is often given in two parts: the first part includes the vane to be queried (e.g., `%a` for Ames, `%b` for Behn, `%c` for Clay, etc.) and the kind of request. The second part is a path that corresponds to the kind of request.
26+
27+## Examples
28+
29+In the dojo we can ask Clay for a listing of the files at our current path, `%`:
30+
31+```
32+> .^(arch %cy %)
33+[ fil=~
34+ dir
35+ { [p=~.web q=~]
36+ [p=~.LICENSE q=~]
37+ [p=~.app q=~]
38+ [p=~.lib q=~]
39+ [p=~.sec q=~]
40+ [p=~.sys q=~]
41+ [p=~.ren q=~]
42+ [p=~.sur q=~]
43+ [p=~.tests q=~]
44+ [p=~.mar q=~]
45+ [p=~.gen q=~]
46+ }
47+]
48+```
49+
50+The `%c` is for Clay, and the `y` is for the request type. `arch` is the type of the listing. See `gen/cat.hoon` to see how this information is printed more prettily.
51+
52+The `%` is for the current path in the dojo:
53+
54+```
55+> `path`%
56+/~zod/home/~2018.9.20..23.05.35..0231
57+```
58+
59+You can modify the time of the file listing quite simply and ask for a listing from 5 hours ago. (Remember that Clay is a revision-controlled file system.)
60+
61+```
62+> .^(arch %cy /(scot %p our)/home/(scot %da (sub now ~h5)))
63+[ fil=~
64+ dir
65+ { [p=~.web q=~]
66+ [p=~.LICENSE q=~]
67+ [p=~.app q=~]
68+ [p=~.lib q=~]
69+ [p=~.sec q=~]
70+ [p=~.sys q=~]
71+ [p=~.ren q=~]
72+ [p=~.sur q=~]
73+ [p=~.tests q=~]
74+ [p=~.mar q=~]
75+ [p=~.gen q=~]
76+ }
77+]
78+```
79+
80+`our` is the value for your ship's name.
docs/hoon/rune/dot/lus.md → docs/reference/rune/dot/lus.umdrenamed+15−13
@@ -1,9 +1,9 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 3
3+ sort/'3'
5−title: .+ "dotlus"
4+ title/'.+ "dotlus"'
6−---
5+ ==
6+;>
7
7
8# `.+ "dotlus"`
8# `.+ "dotlus"`
9
9
@@ -11,8 +11,7 @@ title: .+ "dotlus"
11
11
12## Produces
12## Produces
13
13
14−`p` plus `1` if `p` is an atom; otherwise, crashes. The product
14+`p` plus `1` if `p` is an atom; otherwise, crashes. The product atom has no aura.
15−atom has no aura.
16
15
17## Syntax
16## Syntax
18
17
@@ -23,12 +22,15 @@ Irregular: `+(6)` is `.+(6)`.
23## Examples
22## Examples
24
23
25```
24```
26−~zod:dojo> .+(6)
25+> .+(6)
277
267
28−~zod:dojo> +(6)
27+
28+> +(6)
297
297
30+
30−~zod:dojo> +(%foo)
31+> +(%foo)
317.303.015
327.303.015
32−~zod:dojo> +([1 2])
33+
34+> +([1 2])
33−! nest-fail
35+nest-fail
34```
36```
docs/reference/rune/dot/tar.umdnew file+48
@@ -0,0 +1,48 @@
1+:- :~ navhome/'/docs/'
2+ next/'true'
3+ sort/'1'
4+ title/'.* "dottar"'
5+ ==
6+;>
7+
8+# `.* "dottar"`
9+
10+`[%dttr p=hoon q=hoon]`: evaluate with Nock `2`.
11+
12+## Produces
13+
14+Nock of formula `q` and subject `p`, with type `%noun`.
15+
16+## Syntax
17+
18+Regular: *2-fixed*.
19+
20+## Discussion
21+
22+Keep in mind that `p` and `q` can be arbitrary Hoon expressions, as long as they evaluate to the appropriate nouns for Nock evaluation.
23+
24+Note that `.*` ("dottar") can be used to bypass the type system,
25+though its product contains no type information. It's
26+perfectly possible to use Hoon as a typeless language.
27+
28+## Examples
29+
30+```
31+> .*([20 30] [0 2])
32+20
33+
34+> .*(33 [4 0 1])
35+34
36+
37+> .*(|.(50) [9 2 0 1])
38+50
39+
40+> .*(12 [7 [`1 [4 `1]] [`2 `3 `2]])
41+[12 13 12]
42+
43+> .*(~ [5 1^4 [4 1^3]])
44+0
45+
46+> .*(~ [5 1^5 [4 1^3]])
47+1
48+```
docs/hoon/rune/dot/tis.md → docs/reference/rune/dot/tis.umdrenamed+22−14
@@ -1,17 +1,17 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 4
3+ sort/'4'
5−title: .= "dottis"
4+ title/'.= "dottis"'
6−---
5+ ==
6+;>
7
7
8−# `.= "dottis"`
8+# `.= "dottis"`
9
9
10`[%dtts p=hoon q=hoon]`: test for equality with Nock `5`.
10`[%dtts p=hoon q=hoon]`: test for equality with Nock `5`.
11
11
12## Produces
12## Produces
13
13
14−`&`, `%.y`, `0` if `p` equals `q`; otherwise `|`, `%.n`, `1`.
14+%.y` if `p` equals `q`; otherwise `%.n`.
15
15
16## Syntax
16## Syntax
17
17
@@ -21,22 +21,30 @@ Irregular: `=(a b)` is `.=(a b)`.
21
21
22## Discussion
22## Discussion
23
23
24+The test for equality includes a type check. Either the type of `p` must nest under the type of `q`, or _vice versa_. Otherwise the result is a crash.
25+
24Like Nock equality, `.=` ("dottis") tests if two nouns are the same,
26Like Nock equality, `.=` ("dottis") tests if two nouns are the same,
25ignoring invisible pointer structure. Because in a conventional
27ignoring invisible pointer structure. Because in a conventional
26−noun implementation each noun has a lazy short hash, comparisons
28+noun implementation each noun has a lazy short hash, comparisons
27are fast unless the hash needs to be computed, or we are comparing
29are fast unless the hash needs to be computed, or we are comparing
28−separate copies of identical nouns. (Comparing large duplicates
30+separate copies of identical nouns. (Comparing large duplicates
29is a common cause of performance bugs.)
31is a common cause of performance bugs.)
30
32
31## Examples
33## Examples
32
34
33```
35```
34−~zod:dojo> .=(0 0)
36+> .=(0 0)
35%.y
37%.y
36−~zod:dojo> =(0 0)
38+
39+> =(0 0)
37%.y
40%.y
38−~zod:dojo> .=(1 2)
41+
42+> .=(1 2)
39%.n
43%.n
40−~zod:dojo> =(1 2)
44+
45+> =(1 2)
41%.n
46%.n
47+
48+> =(12 [12 14])
49+nest-fail
42```
50```
docs/reference/rune/dot/wut.umdnew file+28
@@ -0,0 +1,28 @@
1+:- :~ navhome/'/docs/'
2+ next/'true'
3+ sort/'2'
4+ title/'.? "dotwut"'
5+ ==
6+;>
7+
8+# `.? "dotwut"`
9+
10+`[%dtwt p=hoon]`: test for cell or atom with Nock `3`.
11+
12+## Produces
13+
14+`%.y` if `p` is a cell; otherwise `%.n`.
15+
16+## Syntax
17+
18+Regular: *1-fixed*.
19+
20+## Examples
21+
22+```
23+> .?(42)
24+%.n
25+
26+> .?([42 43])
27+%.y
28+```
docs/reference/rune/ket.umdnew file+19
@@ -0,0 +1,19 @@
1+:- :~ navhome/'/docs/'
2+ next/'true'
3+ sort/'11'
4+ title/'Casts ^ ("ket")'
5+ ==
6+;>
7+
8+# Casts `^` ("ket")
9+
10+[`^-` ("kethep")](./hep/), [`^+` ("ketlus")](./lus/), and
11+[`^=` ("kettis")](./tis/) let us adjust types without violating type
12+constraints.
13+
14+The `nest` algorithm which tests subtyping is conservative;
15+it never allows invalid nests, it sometimes rejects valid nests.
16+
17+## Runes
18+
19+;list(datapreview "true", classname "runes");
docs/hoon/rune/ket/bar.md → docs/reference/rune/ket/bar.umdrenamed+7−7
@@ -1,9 +1,9 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 5
3+ sort/'5'
5−title: ^| "ketbar"
4+ title/'^| "ketbar"'
6−---
5+ ==
6+;>
7
7
8# `^| "ketbar"`
8# `^| "ketbar"`
9
9
@@ -36,7 +36,7 @@ The prettyprinter shows the core metal (`.` gold, `|` iron):
36```
36```
37~zod:dojo> |=(@ 1)
37~zod:dojo> |=(@ 1)
38<1.gcq [@ @n <250.yur 41.wda 374.hzt 100.kzl 1.ypj %151>]>
38<1.gcq [@ @n <250.yur 41.wda 374.hzt 100.kzl 1.ypj %151>]>
39+
39~zod:dojo> ^|(|=(@ 1))
40~zod:dojo> ^|(|=(@ 1))
40<1|gcq [@ @n <250.yur 41.wda 374.hzt 100.kzl 1.ypj %151>]>
41<1|gcq [@ @n <250.yur 41.wda 374.hzt 100.kzl 1.ypj %151>]>
41```
42```
42−
docs/hoon/rune/ket/hep.md → docs/reference/rune/ket/hep.umdrenamed+12−8
@@ -1,13 +1,13 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 1
3+ sort/'1'
5−title: ^- "kethep"
4+ title/'^- "kethep"'
6−---
5+ ==
6+;>
7
7
8# `^- "kethep"`
8# `^- "kethep"`
9
9
10−`[%kthp p=model q=value]`: typecast by mold.
10+`[%kthp p=spec q=hoon]`: typecast by explicit type label.
11
11
12## Expands to
12## Expands to
13
13
@@ -26,7 +26,7 @@ Irregular: `` `foo`bar`` is `^-(foo bar)`.
26It's a good practice to put a `^-` ("kethep") at the top of every arm
26It's a good practice to put a `^-` ("kethep") at the top of every arm
27(including gates, loops, etc). This cast is strictly necessary
27(including gates, loops, etc). This cast is strictly necessary
28only in the presence of head recursion (otherwise you'll get a
28only in the presence of head recursion (otherwise you'll get a
29−`rest-loop` error, or if you really screw up spectacularly an
29+`rest-loop` error, or if you really screw up spectacularly an
30infinite loop in the compiler).
30infinite loop in the compiler).
31
31
32## Examples
32## Examples
@@ -34,13 +34,17 @@ infinite loop in the compiler).
34```
34```
35~zod:dojo> (add 90 7)
35~zod:dojo> (add 90 7)
3697
3697
37+
37~zod:dojo> `@t`(add 90 7)
38~zod:dojo> `@t`(add 90 7)
38'a'
39'a'
40+
39~zod:dojo> ^-(@t (add 90 7))
41~zod:dojo> ^-(@t (add 90 7))
40'a'
42'a'
43+
41/~zod:dojo> =foo |= a=@tas
44/~zod:dojo> =foo |= a=@tas
42 ^- (unit @ta)
45 ^- (unit @ta)
43 `a
46 `a
47+
44/~zod:dojo> (foo 97)
48/~zod:dojo> (foo 97)
45[~ ~.a]
49[~ ~.a]
46```
50```
docs/reference/rune/ket/lus.umdnew file+25
@@ -0,0 +1,25 @@
1+:- :~ navhome/'/docs/'
2+ next/'true'
3+ sort/'2'
4+ title/'^+ "ketlus"'
5+ ==
6+;>
7+
8+# `^+ "ketlus"`
9+
10+`[%ktls p=hoon q=hoon]`: typecast by inferred type.
11+
12+## Produces
13+
14+The value of `q` with the type of `p`, if the type of `q` nests within the type of `p`. Otherwise, `nest-fail`.
15+
16+## Syntax
17+
18+Regular: *2-fixed*.
19+
20+## Examples
21+
22+```
23+~zod:dojo> ^+('text' %a)
24+'a'
25+```
docs/hoon/rune/ket/sig.md → docs/reference/rune/ket/sig.umdrenamed+7−7
@@ -1,9 +1,9 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 4
3+ sort/'4'
5−title: ^~ "ketsig"
4+ title/'^~ "ketsig"'
6−---
5+ ==
6+;>
7
7
8# `^~ "ketsig"`
8# `^~ "ketsig"`
9
9
@@ -22,7 +22,7 @@ Regular: *1-fixed*.
22```
22```
23~zod:dojo> (make '|-(42)')
23~zod:dojo> (make '|-(42)')
24[%8 p=[%1 p=[1 42]] q=[%9 p=2 q=[%0 p=1]]]
24[%8 p=[%1 p=[1 42]] q=[%9 p=2 q=[%0 p=1]]]
25+
25~zod:dojo> (make '^~(|-(42))')
26~zod:dojo> (make '^~(|-(42))')
26[%1 p=42]
27[%1 p=42]
27```
28```
28−
docs/hoon/rune/ket/tis.md → docs/reference/rune/ket/tis.umdrenamed+8−9
@@ -1,19 +1,18 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 3
3+ sort/'3'
5−title: ^= "kettis"
4+ title/'^= "kettis"'
6−---
5+ ==
7−
6+;>
8
7
9# `^= "kettis"`
8# `^= "kettis"`
10
9
11−`[%ktts p=toga q=value]`: name a value.
10+`[%ktts p=skin q=hoon]`: Bind name to a value.
12
11
13## Produces
12## Produces
14
13
15If `p` is a term, the product `q` with type `[%face p q]`. `p`
14If `p` is a term, the product `q` with type `[%face p q]`. `p`
16−may also be a tuple of terms, or a term-toga pair; the type of
15+may also be a tuple of terms, or a term-skin pair; the type of
17`q` must divide evenly into cells to match it.
16`q` must divide evenly into cells to match it.
18
17
19## Syntax
18## Syntax
docs/hoon/rune/ket/wut.md → docs/reference/rune/ket/wut.umdrenamed+8−7
@@ -1,8 +1,9 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
2+ next/'true'
3−sort: 6
3+ sort/'6'
4−title: ^? "ketwut"
4+ title/'^? "ketwut"'
5−---
5+ ==
6+;>
6
7
7# `^? "ketwut"`
8# `^? "ketwut"`
8
9
@@ -18,7 +19,7 @@ Regular: *1-fixed*.
18
19
19## Discussion
20## Discussion
20
21
21−A lead core is an opaque generator; the payload can't be read or
22+A lead core is an opaque generator; the payload can't be read or
22written.
23written.
23
24
24Theorem: if type `x` nests within type `a`, a lead core producing
25Theorem: if type `x` nests within type `a`, a lead core producing
@@ -34,7 +35,7 @@ The prettyprinter shows the core metal (`.` gold, `?` lead):
34```
35```
35~zod:dojo> |=(@ 1)
36~zod:dojo> |=(@ 1)
36<1.gcq [@ @n <250.yur 41.wda 374.hzt 100.kzl 1.ypj %151>]>
37<1.gcq [@ @n <250.yur 41.wda 374.hzt 100.kzl 1.ypj %151>]>
38+
37~zod:dojo> ^?(|=(@ 1))
39~zod:dojo> ^?(|=(@ 1))
38<1?gcq [@ @n <250.yur 41.wda 374.hzt 100.kzl 1.ypj %151>]>
40<1?gcq [@ @n <250.yur 41.wda 374.hzt 100.kzl 1.ypj %151>]>
39```
41```
40−
docs/reference/rune/limb.umdnew file+14
@@ -0,0 +1,14 @@
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3+ sort/'2'
4+ title/'Limbs and Wings'
5+ ==
6+;>
7+
8+# Limbs and wings
9+
10+One feature Hoon lacks: a context that isn't a first-class value. Hoon has no concept of scope, environment, etc. An expression has exactly one data source, the *subject*, a noun like any other.
11+
12+In Hoon we use 'wings' to extract information from the subject. A wing is a list of limbs (including a trivial list of one limb). A limb is used to resolve to a piece of data in the subject. A wing is thus a resolution path into the subject.
13+
14+;list(datapreview "true", classname "runes");
docs/reference/rune/limb/limb.umdnew file+74
@@ -0,0 +1,74 @@
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3+ sort/'1'
4+ title/'Limbs'
5+ ==
6+;>
7+
8+# Limbs
9+
10+Attribute of subject.
11+
12+### Produces
13+
14+If a limb resolves to a leg of the subject, the leg is produced. If a limb resolves to an arm by way of an arm name, then the arm is evaluated with its parent core as the subject and the result of that evaluation is produced.
15+
16+An arm is a Nock formula in the battery of a core. A leg is any other piece of data in the subject.
17+
18+### Syntax
19+
20+Irregular: `+15` is slot `15`. The value at address `15` of the subject is produced.
21+
22+Irregular: `.` is slot `1`, the whole subject.
23+
24+Irregular: `&4` is slot `30`, the 4th element of a tuple with at least 5 elements.
25+
26+Irregular: `|4` is slot `31`, the elements that follow `&4`.
27+
28+Irregular: `abc` is a name that can resolve either to an arm or a leg of the subject.
29+
30+Irregular: `^^^abc` is the name `abc`, but which will skip the first three name matches in the subject.
31+
32+Irregular: `+<-` is "take the tail, then take the head of that, then the head of that." `+` and `>` mean "tail" while `-` and `<` mean "head." This limb syntax starts on `+` or `-` and alternates with `>` or `<` for readability.
33+
34+### Traverse
35+
36+Name resolution happens by way of a search through the subject. The search traverse takes a name `q` and a *skip count* `p`.
37+
38+The search product may be an *arm* or a *leg*. A *leg* is a subtree of the subject. An arm is a Nock formula paired with a core to compute the result. You can think of the limb as an attribute -- computation or subtree, "synthesized" or "natural"
39+-- of the subject.
40+
41+We search the subject type headfirst, depth-first, and pre-order.
42+If we descend to a `%face` type whose label matches the limb
43+symbol, the descent address is a leg. The type is the type
44+beneath the label. But if the `%face` label differs, the search
45+skips this whole subtree.
46+
47+If we descend into a `%core` type in which the limb symbol is an
48+arm, we produce that arm. If the limb symbol is not found, we
49+descend into the payload (data) of the core.
50+
51+If the skip count `p` is nonzero, we pretend our first `p`
52+matches are actually mismatches. This lets the programmer "look
53+through" an overriding label.
54+
55+### Examples
56+
57+The Dojo prompt gives you a subject with a decent namespace.
58+Try:
59+
60+```
61+> now
62+~2016.4.25..01.39.59..a0f0
63+```
64+
65+You can also add variables to the subject, then use them. (Note
66+that `=variable value` is not Hoon (language) syntax; it's Dojo
67+(shell) syntax.)
68+
69+```
70+> =a 12
71+
72+> a
73+12
74+```
docs/reference/rune/limb/wing.umdnew file+43
@@ -0,0 +1,43 @@
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3+ sort/'2'
4+ title/'Wings'
5+ ==
6+;>
7+
8+# Wings
9+
10+`[%wing p=(list limb)]`; a limb search path into the subject.
11+
12+### Produces
13+
14+A wing is a list of limbs (including a trivial list of one limb). The limbs are resolved to values in the subject in succession, and the result of the last limb resolution is the value produced by the wing.
15+
16+### Syntax
17+
18+Irregular: `a.b.c`. Read this as '`a` in `b` in `c`'. Finds limb `a` within limb `b` within limb `c` of the subject.
19+
20+### Discussion
21+
22+Intuitively, Hoon wings are written in the opposite order
23+from attribute dot-paths in most languages. Hoon `a.b.c` is Java's
24+`c.b.a`; it means "a within b within c."
25+
26+Any item in the wing can resolve to a leg (fragment) or arm
27+(computation). But if a non-terminal item in the wing would
28+resolve to an arm, it resolves instead to the subject of the arm
29+-- in other words, the core exporting that name.
30+
31+The mysterious idiom `..b` produces the leg `b` if `b`
32+is a leg; the core exporting `b` if `b` is an arm. Since `.`
33+is the same limb as `+`, `..b` is the same wing as `+1.foo`.
34+
35+### Examples
36+
37+```
38+~zod:dojo> =a [fod=3 bat=[baz=1 moo=2]]
39+~zod:dojo> bat.a
40+[baz=1 moo=2]
41+~zod:dojo> moo.bat.a
42+2
43+```
docs/reference/rune/mic.umdnew file+14
@@ -0,0 +1,14 @@
1+:- :~ navhome/'/docs/'
2+ next/'true'
3+ sort/'13'
4+ title/'Make ; ("mic")'
5+ ==
6+;>
7+
8+# Make `;` ("sem")
9+
10+Miscellaneous useful macros.
11+
12+## Runes
13+
14+;list(datapreview "true", classname "runes");
docs/hoon/rune/sem/col.md → docs/reference/rune/mic/col.umdrenamed+8−8
@@ -1,13 +1,13 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 1
3+ sort/'1'
5−title: ;: "semcol"
4+ title/';: "miccol"'
6−---
5+ ==
6+;>
7
7
8−# `;: "semcol"`
8+# `;: "miccol"`
9
9
10−`[%smcl p=hoon q=(list hoon)]`: call a binary function as an n-ary function.
10+`[%mccl p=hoon q=(list hoon)]`: call a binary function as an n-ary function.
11
11
12## Expands to
12## Expands to
13
13
docs/hoon/rune/sem/sem.md → docs/reference/rune/mic/mic.umdrenamed+8−8
@@ -1,13 +1,13 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 3
3+ sort/'3'
5−title: ;; "semsem"
4+ title/';; "micmic"'
6−---
5+ ==
6+;>
7
7
8−# `;; "semsem"`
8+# `;; "micmic"`
9
9
10−`[%smsm p=model q=value]`: normalize with a mold, asserting fixpoint.
10+`[%mcmc p=spec q=hoon]`: normalize with a mold, asserting fixpoint.
11
11
12## Expands to
12## Expands to
13
13
docs/reference/rune/mic/net.umdnew file+23
@@ -0,0 +1,23 @@
1+:- :~ navhome/'/docs/'
2+ next/'true'
3+ sort/'4'
4+ title/';/ "micnet"'
5+ ==
6+;>
7+
8+# `;/ "micnet"`
9+
10+`[%mcnt p=hoon]`: tape as XML element.
11+
12+## Expands to
13+
14+```
15+~[%$ ~[%$ 'p']]
16+```
17+
18+## Examples
19+
20+```
21+~zod/try=> :/"foo"
22+[[%~. [%~. "foo] ~] ~]
23+```
docs/hoon/rune/sem/sig.md → docs/reference/rune/mic/sig.umdrenamed+10−10
@@ -1,18 +1,18 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 2
3+ sort/'2'
5−title: ;~ "semsig"
4+ title/';~ "micsig"'
6−---
5+ ==
6+;>
7
7
8−# `;~ "semsig"`
8+# `;~ "micsig"`
9
9
10−`[%smsg p=hoon q=(list hoon)]`: glue a pipeline together with a
10+`[%mcsg p=hoon q=(list hoon)]`: glue a pipeline together with a
11product-sample adapter.
11product-sample adapter.
12
12
13## Produces
13## Produces
14
14
15−The gates in `q` connected together using the gate `p`, which
15+The gates in `q` connected together using the gate `p`, which
16transforms a `q` product and a `q` gate into a `q` sample.
16transforms a `q` product and a `q` gate into a `q` sample.
17
17
18## Expands to
18## Expands to
@@ -51,7 +51,7 @@ transforms a `q` product and a `q` gate into a `q` sample.
51
51
52## Discussion
52## Discussion
53
53
54−Apparently `;~` ("semsig") is a "Kleisli arrow." Whatevs. It's also
54+Apparently `;~` ("micsig") is a "Kleisli arrow." It's also
55a close cousin of the infamous "monad." Don't let that bother
55a close cousin of the infamous "monad." Don't let that bother
56you either. Hoon doesn't know anything about category theory,
56you either. Hoon doesn't know anything about category theory,
57so you don't need to either.
57so you don't need to either.
docs/reference/rune/sig.umdnew file+14
@@ -0,0 +1,14 @@
1+:- :~ navhome/'/docs/'
2+ next/'true'
3+ sort/'8'
4+ title/'Hints ~ ("sig")'
5+ ==
6+;>
7+
8+# Hints `~` ("sig")
9+
10+Runes that use Nock `10` to pass non-semantic info to the interpreter.
11+
12+## Runes
13+
14+;list(datapreview "true", classname "runes");
docs/hoon/rune/sig/gar.md → docs/reference/rune/sig/ban.umdrenamed+8−8
@@ -1,11 +1,11 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 11
3+ sort/'3'
5−title: ~> "siggar"
4+ title/'~> "sigban"'
6−---
5+ ==
7−
6+;>
8−# `~> "siggar"`
7+
8+# `~> "sigban"`
9
9
10`[%sggr p=$@(term [p=term q=hoon]) q=hoon]`: raw hint, applied
10`[%sggr p=$@(term [p=term q=hoon]) q=hoon]`: raw hint, applied
11to computation.
11to computation.
docs/hoon/rune/sig/bar.md → docs/reference/rune/sig/bar.umdrenamed+7−7
@@ -1,9 +1,9 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 4
3+ sort/'7'
5−title: ~| "sigbar"
4+ title/'~| "sigbar"'
6−---
5+ ==
6+;>
7
7
8# `~| "sigbar"`
8# `~| "sigbar"`
9
9
@@ -28,7 +28,7 @@ Regular: *2-fixed*.
28'sample error message'
28'sample error message'
29ford: build failed
29ford: build failed
30
30
31−~zod:dojo> ~| 'sample error message'
31+~zod:dojo> ~| 'sample error message'
32 !!
32 !!
33'sample error message'
33'sample error message'
34ford: build failed
34ford: build failed
docs/hoon/rune/sig/buc.md → docs/reference/rune/sig/bus.umdrenamed+8−8
@@ -1,11 +1,11 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 8
3+ sort/'11'
5−title: ~$ "sigbuc"
4+ title/'~$ "sigbus"'
6−---
5+ ==
7−
6+;>
8−# `~$ "sigbuc"`
7+
8+# `~$ "sigbus"`
9
9
10`[%sgbc p=term q=hoon]`: profiling hit counter.
10`[%sgbc p=term q=hoon]`: profiling hit counter.
11
11
docs/hoon/rune/sig/cab.md → docs/reference/rune/sig/cab.umdrenamed+7−7
@@ -1,9 +1,9 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 5
3+ sort/'8'
5−title: ~_ "sigcab"
4+ title/'~_ "sigcab"'
6−---
5+ ==
6+;>
7
7
8# `~_ "sigcab"`
8# `~_ "sigcab"`
9
9
@@ -28,7 +28,7 @@ Shows `p` in stacktrace if `q` crashes.
28"sample error message"
28"sample error message"
29ford: build failed
29ford: build failed
30
30
31−~zod:dojo> ~_ [%leaf "sample error message"]
31+~zod:dojo> ~_ [%leaf "sample error message"]
32 !!
32 !!
33"sample error message"
33"sample error message"
34ford: build failed
34ford: build failed
docs/hoon/rune/sig/cen.md → docs/reference/rune/sig/cen.umdrenamed+11−12
@@ -1,9 +1,9 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 10
3+ sort/'2'
5−title: ~% "sigcen"
4+ title/'~% "sigcen"'
6−---
5+ ==
6+;>
7
7
8# `~% "sigcen"`
8# `~% "sigcen"`
9
9
@@ -20,7 +20,7 @@ the named formulas `r`, constructed by `s`.
20
20
21## Syntax
21## Syntax
22
22
23−Regular: *4-fixed*. For `r`, use `~` if empty. Otherwise, *jogging*
23+Regular: *4-fixed*. For `r`, use `~` if empty. Otherwise, *jogging*
24between opening and closing `==`.
24between opening and closing `==`.
25
25
26## Discussion
26## Discussion
@@ -64,10 +64,7 @@ a core, we state the leg to its parent, in the form of wing `q`.
64We assume that the parent -- any core within the payload -- is
64We assume that the parent -- any core within the payload -- is
65already registered.
65already registered.
66
66
67−must already be registered.
68−The interpreter can thus
69−
70−`p` is the name of this core within its parent; `q` is a the leg
67+`p` is the name of this core within its parent; `q` is a the leg
71
68
72Registers a jet in core `s` so that it can be called when that code is run.
69Registers a jet in core `s` so that it can be called when that code is run.
73
70
@@ -75,8 +72,9 @@ Regularm form: *4-fixed*
75
72
76## Examples
73## Examples
77
74
78−Here's the AES
75+Here's the AES
79
76
77+```
80 ++ aesc :: AES-256
78 ++ aesc :: AES-256
81 ~% %aesc + ~
79 ~% %aesc + ~
82 |%
80 |%
@@ -91,6 +89,7 @@ Here's the AES
91 =+ ahem
89 =+ ahem
92 (be | (ix (ex a)) b)
90 (be | (ix (ex a)) b)
93 --
91 --
92+```
94
93
95Here we label the entire `++aesc` core for optimization. You can see the
94Here we label the entire `++aesc` core for optimization. You can see the
96jet in `jets/e/aesc.c`.
95jet in `jets/e/aesc.c`.
docs/hoon/rune/sig/gal.md → docs/reference/rune/sig/led.umdrenamed+11−10
@@ -1,12 +1,13 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
2+ next/'true'
3−sort: 12
3+ sort/'4'
4−title: ~< "siggal"
4+ title/'~< "sigled"'
5−---
5+ ==
6+;>
6
7
7−# `~< "siggal"`
8+# `~< "sigled"`
8
9
9−`[%sggl p=$@(term [p=term q=hoon]) q=hoon]`: raw hint, applied to
10+`[%sggl p=$@(term [p=term q=hoon]) q=hoon]`: raw hint, applied to
10product.
11product.
11
12
12## Expands to
13## Expands to
@@ -19,9 +20,9 @@ Regular: *2-fixed*. For the dynamic form, write `%term.hoon`.
19
20
20## Discussion
21## Discussion
21
22
22−`~<` ("siggal") is only used for jet hints ([`~/` ("sigfas")](../fas/)
23+`~<` ("siggal") is only used for jet hints ([`~/` ("sigfas")](../fas/)
23−and [`~%` ("sigcen")](../cen/)) at the moment; we are not telling the
24+and [`~%` ("sigcen")](../cen/)) at the moment; we are not telling the
24−interpreter something about the computation we're about to perform, but
25+interpreter something about the computation we're about to perform, but
25rather about its product.
26rather about its product.
26
27
27## Examples
28## Examples
docs/hoon/rune/sig/lus.md → docs/reference/rune/sig/lus.umdrenamed+7−7
@@ -1,9 +1,9 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 6
3+ sort/'9'
5−title: ~+ "siglus"
4+ title/'~+ "siglus"'
6−---
5+ ==
6+;>
7
7
8# `~+ "siglus"`
8# `~+ "siglus"`
9
9
@@ -15,7 +15,7 @@ title: ~+ "siglus"
15
15
16## Convention
16## Convention
17
17
18−Caches the formula and subject of `p` in a local cache (generally
18+Caches the formula and subject of `p` in a local cache (generally
19transient in the current event).
19transient in the current event).
20
20
21## Syntax
21## Syntax
docs/hoon/rune/sig/fas.md → docs/reference/rune/sig/net.umdrenamed+8−8
@@ -1,11 +1,11 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 9
3+ sort/'12'
5−title: ~/ "sigfas"
4+ title/'~/ "signet"'
6−---
5+ ==
6+;>
7
7
8−# `~/ "sigfas"`
8+# `~/ "signet"`
9
9
10`[%sgfs p=term q=hoon]`: jet registration for gate with
10`[%sgfs p=term q=hoon]`: jet registration for gate with
11registered context.
11registered context.
@@ -22,7 +22,7 @@ Regular: *2-fixed*.
22
22
23## Examples
23## Examples
24
24
25−From the kernel:
25+From the kernel:
26```
26```
27++ add
27++ add
28 ~/ %add
28 ~/ %add
docs/hoon/rune/sig/pam.md → docs/reference/rune/sig/pad.umdrenamed+9−9
@@ -1,11 +1,11 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 1
3+ sort/'1'
5−title: ~& "sigpam"
4+ title/'~& "sigpad"'
6−---
5+ ==
6+;>
7
7
8−# `~& "sigpam"`
8+# `~& "sigpad"`
9
9
10`[%sgpm p=hoon q=hoon]`: debugging printf.
10`[%sgpm p=hoon q=hoon]`: debugging printf.
11
11
@@ -15,7 +15,7 @@ title: ~& "sigpam"
15
15
16## Convention
16## Convention
17
17
18−Prettyprints `p` on the console before computing `q`.
18+Prettyprints `p` on the console before computing `q`.
19
19
20## Syntax
20## Syntax
21
21
@@ -28,7 +28,7 @@ Regular: *2-fixed*.
28'halp'
28'halp'
29~
29~
30
30
31−~zod:dojo> ~& 'halp'
31+~zod:dojo> ~& 'halp'
32 ~
32 ~
33'halp'
33'halp'
34~
34~
docs/hoon/rune/sig/tis.md → docs/reference/rune/sig/tis.umdrenamed+8−8
@@ -1,11 +1,11 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 7
3+ sort/'10'
5−title: ~= "sigtis"
4+ title/'~= "sigtis"'
6−---
5+ ==
6+;>
7
7
8−# `~= "sigtis"`
8+# `~= "sigtis"`
9
9
10`[%sgts p=hoon q=hoon]`: detect duplicate.
10`[%sgts p=hoon q=hoon]`: detect duplicate.
11
11
@@ -28,7 +28,7 @@ This code traverses a tree and replaces all instances of `42` with
28`420`:
28`420`:
29
29
30```
30```
31−~zod:dojo> =foo |= a=(tree)
31+~zod:dojo> =foo |= a=(tree)
32 ?~(a ~ ~=(a [?:(=(n.a 42) 420 n.a) $(a l.a) $(a r.a)]))
32 ?~(a ~ ~=(a [?:(=(n.a 42) 420 n.a) $(a l.a) $(a r.a)]))
33~zod:dojo> (foo 42 ~ ~)
33~zod:dojo> (foo 42 ~ ~)
34[420 ~ ~]
34[420 ~ ~]
docs/hoon/rune/sig/wut.md → docs/reference/rune/sig/wut.umdrenamed+10−10
@@ -1,9 +1,9 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 2
3+ sort/'5'
5−title: ~? "sigwut"
4+ title/'~? "sigwut"'
6−---
5+ ==
6+;>
7
7
8# `~? "sigwut"`
8# `~? "sigwut"`
9
9
@@ -13,7 +13,7 @@ title: ~? "sigwut"
13
13
14`r`.
14`r`.
15
15
16−## Convention
16+## Convention
17
17
18If `p` is true, prettyprints `q` on the console before computing `r`.
18If `p` is true, prettyprints `q` on the console before computing `r`.
19
19
@@ -31,12 +31,12 @@ Regular: *4-fixed*.
31'oops'
31'oops'
32~
32~
33
33
34−~zod:dojo> ~? (gth 1 2)
34+~zod:dojo> ~? (gth 1 2)
35− 'oops'
35+ 'oops'
36 ~
36 ~
37~
37~
38
38
39−~zod:dojo> ~? (gth 1 0)
39+~zod:dojo> ~? (gth 1 0)
40 'oops'
40 'oops'
41 ~
41 ~
42'oops'
42'oops'
docs/hoon/rune/sig/zap.md → docs/reference/rune/sig/zap.umdrenamed+8−8
@@ -1,11 +1,11 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 3
3+ sort/'6'
5−title: ~! "sigzap"
4+ title/'~? "sigzap"'
6−---
5+ ==
6+;>
7
7
8−# `~! "sigzap"`
8+# `~! "sigzap"`
9
9
10`[%sgzp p=hoon q=hoon]`: print type on compilation fail.
10`[%sgzp p=hoon q=hoon]`: print type on compilation fail.
11
11
@@ -31,7 +31,7 @@ Regular: *2-fixed*.
31! @t
31! @t
32! find.a
32! find.a
33
33
34−~zod:dojo> ~! 'foo'
34+~zod:dojo> ~! 'foo'
35 a
35 a
36! @t
36! @t
37! find.a
37! find.a
docs/reference/rune/tis.umdnew file+23
@@ -0,0 +1,23 @@
1+:- :~ navhome/'/docs/'
2+ next/'true'
3+ sort/'5'
4+ title/'Change Subject = ("tis")'
5+ ==
6+;>
7+
8+# Change Subject `=` ("tis")
9+
10+These runes modify the subject. (Or more precisely, they
11+evaluate at least one of their subexpressions with a modified subject.)
12+
13+## Overview
14+
15+Hoon doesn't have variables in the ordinary sense. If you want to bind a name to a value, e.g., `a` to `12`, you do so by pinning `12` to the subject and associating the name with it. This sort of operation is done with the `=` family of runes.
16+
17+Let's say you have some old subject `p`. To 'pin' a value to the head means to modify the subject by repacing it with a cell of `[new-value p]`. The head of the cell is the new value. So to pin `12` with the face `a` the new subject would be: `[a=12 p]`.
18+
19+Of course there are many variations on ways to modify the subject, useful for different situations. Hence the whole family of `=` runes.
20+
21+## Runes
22+
23+;list(datapreview "true", classname "runes");
docs/reference/rune/tis/ban.umdnew file+28
@@ -0,0 +1,28 @@
1+:- :~ navhome/'/docs/'
2+ next/'true'
3+ sort/'1'
4+ title/'=> "tisban"'
5+ ==
6+;>
7+
8+# `=> "tisban"`
9+
10+`[%tsgr p=hoon q=hoon]`: compose two expressions.
11+
12+## Produces
13+
14+`q`, evaluated with the product of `p` as its subject.
15+
16+## Syntax
17+
18+Regular: *2-fixed*.
19+
20+## Examples
21+
22+```
23+> =>([a=1 b=2 c=3] b)
24+2
25+
26+> =>((add 2 4) [. .])
27+[6 6]
28+```
docs/hoon/rune/tis/bar.md → docs/reference/rune/tis/bar.umdrenamed+9−9
@@ -1,13 +1,13 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 8
3+ sort/'12'
5−title: =| "tisbar"
4+ title/'=| "tisbar"'
6−---
5+ ==
6+;>
7
7
8# `=| "tisbar"`
8# `=| "tisbar"`
9
9
10−`[%tsbr p=model q=value]`: combine a defaulted mold with the subject.
10+`[%tsbr p=spec q=hoon]`: combine a default type value with the subject.
11
11
12## Expands to
12## Expands to
13
13
@@ -21,7 +21,7 @@ Regular: *2-fixed*.
21
21
22## Discussion
22## Discussion
23
23
24−`=|` "declares a variable" which is "uninitialized," presumably
24+`=|` "declares a variable" which is "uninitialized," presumably
25because you'll set it in a loop or similar.
25because you'll set it in a loop or similar.
26
26
27## Examples
27## Examples
@@ -30,7 +30,7 @@ because you'll set it in a loop or similar.
30~zod:dojo> =foo |= a=@
30~zod:dojo> =foo |= a=@
31 =| b=@
31 =| b=@
32 =- :(add a b c)
32 =- :(add a b c)
33− c=2
33+ c=2
34~zod:dojo> (foo 5)
34~zod:dojo> (foo 5)
357
357
36```
36```
docs/hoon/rune/tis/col.md → docs/reference/rune/tis/col.umdrenamed+8−8
@@ -1,11 +1,11 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 11
3+ sort/'3'
5−title: =: "tiscol"
4+ title/'=: "tiscol"'
6−---
5+ ==
7−
6+;>
7+
8−# `=: "tiscol"`
8+# `=: "tiscol"`
9
9
10`[%tscl p=(list (pair wing hoon)) q=hoon]`: change multiple legs in the subject.
10`[%tscl p=(list (pair wing hoon)) q=hoon]`: change multiple legs in the subject.
11
11
docs/hoon/rune/tis/com.md → docs/reference/rune/tis/com.umdrenamed+10−10
@@ -1,17 +1,17 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 13
3+ sort/'5'
5−title: =, "tiscom"
4+ title/'=, "tiscom"'
6−---
5+ ==
6+;>
7
7
8−# `=, "tiscom"`
8+# `=, "tiscom"`
9
9
10`[%tscm p=hoon q=hoon]`: expose namespace
10`[%tscm p=hoon q=hoon]`: expose namespace
11
11
12−`p` evaluates to a noun with some namespace. From within `q` you may access `p`'s
12+`p` evaluates to a noun with some namespace. From within `q` you may access `p`'s
13−names without a wing path (i.e., you can use face `b` rather than `b.p`), or without
13+names without a wing path (i.e., you can use face `b` rather than `b.p`), or without
14−invoking a core name when `p` is a core. This is especially useful for calling arms
14+invoking a core name when `p` is a core. This is especially useful for calling arms
15from an imported library or for calling arms from an stdlib core repeatedly.
15from an imported library or for calling arms from an stdlib core repeatedly.
16
16
17## Syntax
17## Syntax
docs/reference/rune/tis/dot.umdnew file+43
@@ -0,0 +1,43 @@
1+:- :~ navhome/'/docs/'
2+ next/'true'
3+ sort/'2'
4+ title/'=. "tisdot"'
5+ ==
6+;>
7+
8+# `=. "tisdot"`
9+
10+`[%tsdt p=wing q=hoon r=hoon]`: change one leg in the subject.
11+
12+## Expands to
13+
14+```
15+=>(%_(. p q) r)
16+```
17+
18+## Syntax
19+
20+Regular: *3-fixed*.
21+
22+## Discussion
23+
24+As usual, we are not actually mutating the subject, just creating
25+a new subject with a changed value. Note that the mutation uses
26+[`%_` ("cencab")](../../cen/cab/), so the type doesn't change. Trying to change the value type results in a `nest-fail`.
27+
28+## Examples
29+
30+```
31+> =+ a=[b=1 c=2]
32+ =. b.a 3
33+ a
34+[b=3 c=2]
35+
36+> =+ a=[b=1 c=2]
37+ =.(b.a 3 a)
38+[b=3 c=2]
39+
40+> =+ a=[b=1 c=2]
41+ =.(b.a "hello" a)
42+nest-fail
43+```
docs/hoon/rune/tis/hep.md → docs/reference/rune/tis/hep.umdrenamed+10−10
@@ -1,9 +1,9 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 5
3+ sort/'9'
5−title: =- "tishep"
4+ title/'=- "tishep"'
6−---
5+ ==
6+;>
7
7
8# `=- "tishep"`
8# `=- "tishep"`
9
9
@@ -21,16 +21,16 @@ Regular: *2-fixed*.
21
21
22## Discussion
22## Discussion
23
23
24−`=-` looks better than `=+` when the hoon you're pinning
24+`=-` looks better than `=+` when the expression you're pinning
25−is much smaller than the hoon that uses it.
25+is much smaller than the expression that uses it.
26
26
27## Examples
27## Examples
28−
28+
29```
29```
30~zod:dojo> =foo |= a=@
30~zod:dojo> =foo |= a=@
31 =+ b=1
31 =+ b=1
32 =- (add a b c)
32 =- (add a b c)
33− c=2
33+ c=2
34~zod:dojo> (foo 5)
34~zod:dojo> (foo 5)
358
358
36```
36```
docs/hoon/rune/tis/ket.md → docs/reference/rune/tis/ket.umdrenamed+7−6
@@ -1,12 +1,13 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
2+ next/'true'
3−sort: 12
3+ sort/'4'
4−title: =^ "tisket"
4+ title/'=^ "tisket"'
5−---
5+ ==
6+;>
6
7
7# `=^ "tisket"`
8# `=^ "tisket"`
8
9
9−`[%tskt p=taco q=wing r=hoon s=hoon]`: pin the head of a pair; change
10+`[%tskt p=skin q=wing r=hoon s=hoon]`: pin the head of a pair; change
10a leg with the tail.
11a leg with the tail.
11
12
12## Expands to
13## Expands to
docs/hoon/rune/tis/gal.md → docs/reference/rune/tis/led.umdrenamed+13−9
@@ -1,13 +1,13 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 2
3+ sort/'6'
5−title: =< "tisgal"
4+ title/'=< "tisled"'
6−---
5+ ==
6+;>
7
7
8−# `=< "tisgal"`
8+# `=< "tisled"`
9
9
10−`[%tsgl p=hoon q=hoon]`: compose two hoons, inverted.
10+`[%tsgl p=hoon q=hoon]`: compose two expressions, inverted.
11
11
12## Expands to
12## Expands to
13
13
@@ -21,13 +21,17 @@ Regular: *2-fixed*.
21
21
22Irregular: `foo:bar` is `=<(foo bar)`.
22Irregular: `foo:bar` is `=<(foo bar)`.
23
23
24+## Discussion
25+
26+`=<` is just `=>` backwards.
27+
24## Examples
28## Examples
25
29
26```
30```
27~zod:dojo> =<(b [a=1 b=2 c=3])
31~zod:dojo> =<(b [a=1 b=2 c=3])
282
322
29
33
30−~zod:dojo> =< b
34+~zod:dojo> =< b
31 [a=1 b=2 c=3]
35 [a=1 b=2 c=3]
322
362
33
37
docs/hoon/rune/tis/lus.md → docs/reference/rune/tis/lus.umdrenamed+7−7
@@ -1,9 +1,9 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 4
3+ sort/'8'
5−title: =+ "tislus"
4+ title/'=+ "tislus"'
6−---
5+ ==
6+;>
7
7
8# `=+ "tislus"`
8# `=+ "tislus"`
9
9
@@ -24,7 +24,7 @@ Regular: *2-fixed*.
24`=+` ("tislus") is the simplest way of "declaring a variable."
24`=+` ("tislus") is the simplest way of "declaring a variable."
25
25
26## Examples
26## Examples
27−
27+
28```
28```
29~zod:dojo> =foo |= a=@
29~zod:dojo> =foo |= a=@
30 =+ b=1
30 =+ b=1
docs/hoon/rune/tis/sem.md → docs/reference/rune/tis/mic.umdrenamed+8−8
@@ -1,13 +1,13 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 7
3+ sort/'11'
5−title: =; "tissem"
4+ title/'=; "tismic"'
6−---
5+ ==
6+;>
7
7
8−# `=; "tissem"`
8+# `=; "tismic"`
9
9
10−`[%tssm p=taco q=hoon r=hoon]`: combine a named and/or typed noun with the
10+`[%tssm p=skin q=hoon r=hoon]`: combine a named and/or typed noun with the
11subject, inverted.
11subject, inverted.
12
12
13## Expands to
13## Expands to
docs/hoon/rune/tis/fas.md → docs/reference/rune/tis/net.umdrenamed+12−13
@@ -1,24 +1,24 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 6
3+ sort/'10'
5−title: =/ "tisfas"
4+ title/'=/ "tisnet"'
6−---
5+ ==
6+;>
7
7
8−# `=/ "tisfas"`
8+# `=/ "tisnet"`
9
9
10−`[%tsfs p=taco q=hoon r=hoon]`: combine a named and/or typed
10+`[%tsfs p=skin q=hoon r=hoon]`: combine a named and/or typed
11noun with the subject.
11noun with the subject.
12
12
13## Expands to
13## Expands to
14
14
15−*if `p` is a symbol*:
15+*if `p` is a symbol*, (e.g. `a`):
16
16
17```
17```
18=+(^=(p q) r)
18=+(^=(p q) r)
19```
19```
20
20
21−*if `p` is a symbol with a mold*:
21+*if `p` is a symbol with a type* (e.g., `a=@`):
22
22
23```
23```
24=+(^-(p q) r)
24=+(^-(p q) r)
@@ -40,8 +40,8 @@ Regular: *3-fixed*.
40
40
41## Discussion
41## Discussion
42
42
43−`p` can be either a symbol or a symbol/mold. If it's just a symbol,
43+`p` can be either a symbol or a symbol=type. If it's just a symbol,
44−`=/` ("tisfas") "declares a type-inferred variable." If it has a mold, `=/`
44+`=/` ("tisnet") "declares a type-inferred variable." If it has a type, `=/`
45"declares a type-checked variable."
45"declares a type-checked variable."
46
46
47## Examples
47## Examples
@@ -54,4 +54,3 @@ Regular: *3-fixed*.
54~zod:dojo> (foo 5)
54~zod:dojo> (foo 5)
558
558
56```
56```
57−
docs/hoon/rune/tis/sig.md → docs/reference/rune/tis/sig.umdrenamed+11−11
@@ -1,17 +1,17 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 3
3+ sort/'7'
5−title: =~ "tissig"
4+ title/'=~ "tissig"'
6−---
5+ ==
6+;>
7
7
8−# `=~ "tissig"`
8+# `=~ "tissig"`
9
9
10−`[%tssg p=(list hoon)]`: compose many hoons.
10+`[%tssg p=(list hoon)]`: compose many expressions.
11
11
12## Produces
12## Produces
13
13
14−The product of the chain composition.
14+The product of the chain composition.
15
15
16## Syntax
16## Syntax
17
17
@@ -20,7 +20,7 @@ Regular: *running*.
20## Examples
20## Examples
21
21
22```
22```
23−~zod:dojo> =foo =| n=@
23+~zod:dojo> =foo =| n=@
24 =< =~ increment
24 =< =~ increment
25 increment
25 increment
26 increment
26 increment
@@ -28,7 +28,7 @@ Regular: *running*.
28 ==
28 ==
29 |%
29 |%
30 ++ increment
30 ++ increment
31− |-
31+ |-
32 ..increment(n +(n))
32 ..increment(n +(n))
33 --
33 --
34~zod:dojo> foo
34~zod:dojo> foo
docs/hoon/rune/tis/tar.md → docs/reference/rune/tis/tar.umdrenamed+7−7
@@ -1,9 +1,9 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 9
3+ sort/'13'
5−title: =* "tistar"
4+ title/'=* "tistar"'
6−---
5+ ==
6+;>
7
7
8# `=* "tistar"`
8# `=* "tistar"`
9
9
@@ -21,7 +21,7 @@ Regular: *3-fixed*.
21
21
22The difference between aliasing and pinning is that the subject
22The difference between aliasing and pinning is that the subject
23noun stays the same; the alias is just recorded in its type.
23noun stays the same; the alias is just recorded in its type.
24−`q` is calculated every time you use the `p` alias, of course.
24+`q` is calculated every time you use the `p` alias.
25
25
26## Examples
26## Examples
27
27
docs/hoon/rune/tis/wut.md → docs/reference/rune/tis/wut.umdrenamed+6−6
@@ -1,9 +1,9 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 13
3+ sort/'14'
5−title: =? "tiswut"
4+ title/'=? "tiswut"'
6−---
5+ ==
6+;>
7
7
8# `=? "tiswut"`
8# `=? "tiswut"`
9
9
docs/hoon/rune/wut.md → docs/reference/rune/wut.umdrenamed+11−14
@@ -1,20 +1,17 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 14
3+ sort/'6'
5−title: Test ? ("wut")
4+ title/'Conditionals ? ("wut")'
6−---
5+ ==
6+;>
7
7
8−# Test `?` ("wut")
8+# Conditionals ? ("wut")
9
9
10−Hoon has the usual branches and logical tests. For pattern
10+Hoon has the usual program control branches. It also has the usual logical operators: AND `?&`, OR `?|`, and NOT `?!`. It also has a `?=` rune that tests whether a value matches a given type. In the course of type inference, Hoon learns from `?=` tests in the test condition of [`?:` ("wutcol")](./col/) expressions.
11−matching, it also has a [`?=` ("wuttis")](./tis/) rune that tests whether a value
12−matches the icon of a mold. And it has branch inference,
13−learning from `?=` tests in the condition of [`?:` ("wutcol")](./col/) hoons.
14
11
15## Overview
12## Overview
16
13
17−All `?` runes expand to `?:` and/or `?=`.
14+All `?` runes reduce to `?:` and/or `?=`.
18
15
19If the condition of an `?:` is a `?=`, *and* the `?=` is
16If the condition of an `?:` is a `?=`, *and* the `?=` is
20testing a leg of the subject, the compiler specializes the subject
17testing a leg of the subject, the compiler specializes the subject
@@ -30,6 +27,6 @@ analyzed.
30If the compiler detects that the branch is degenerate (only one
27If the compiler detects that the branch is degenerate (only one
31side is taken), it fails with an error.
28side is taken), it fails with an error.
32
29
33−## Hoons
30+## Runes
34
31
35−<list dataPreview="true" className="runes"></list>
32+;list(datapreview "true", classname "runes");
docs/hoon/rune/wut/gar.md → docs/reference/rune/wut/ban.umdrenamed+6−6
@@ -1,9 +1,9 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 3
3+ sort/'7'
5−title: ?> "wutgar"
4+ title/'?> "wutban"'
6−---
5+ ==
6+;>
7
7
8# `?> "wutgar"`
8# `?> "wutgar"`
9
9
docs/hoon/rune/wut/bar.md → docs/reference/rune/wut/bar.umdrenamed+8−8
@@ -1,13 +1,13 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 6
3+ sort/'10'
5−title: ?| "wutbar"
4+ title/'?| "wutbar"'
6−---
5+ ==
6+;>
7
7
8−# `?| "wutbar"`
8+# `?| "wutbar"`
9
9
10−`[%wtbr p=(list hoon)]`: logical or.
10+`[%wtbr p=(list hoon)]`: logical OR.
11
11
12## Expands to
12## Expands to
13
13
docs/hoon/rune/wut/col.md → docs/reference/rune/wut/col.umdrenamed+14−14
@@ -1,9 +1,9 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 1
3+ sort/'1'
5−title: ?: "wutcol"
4+ title/'?: "wutcol"'
6−---
5+ ==
6+;>
7
7
8# `?: "wutcol"`
8# `?: "wutcol"`
9
9
@@ -11,14 +11,14 @@ title: ?: "wutcol"
11
11
12## Produces
12## Produces
13
13
14−If `p` produces yes, then `q`. If `p` produces no, `r`.
14+If `p` produces yes, `%.y`, then `q`. If `p` produces no, `%.n`, then `r`.
15If `p` is not a boolean, compiler yells at you.
15If `p` is not a boolean, compiler yells at you.
16
16
17The subjects of `q` and `r` are constrained to match any
17The subjects of `q` and `r` are constrained to match any
18pattern-matching algebra in `p`. The analysis, which is
18pattern-matching algebra in `p`. The analysis, which is
19−conservative, understands any combination of [`?=` ("wuttis")](../tis/),
19+conservative, understands any combination of [`?=` ("wuttis")](../tis/),
20−[`?&` ("wutpam")](../pam/), [`?|` ("wutbar")](../bar/), and
20+[`?&` ("wutpad")](../pad/), [`?|` ("wutbar")](../bar/), and
21−[`?!` ("wutzap")](../zap/), and reduces the subject appropriately when
21+[`?!` ("wutzap")](../zap/), and reduces the subject appropriately when
22compiling.
22compiling.
23
23
24If test analysis reveals that either branch is not taken,
24If test analysis reveals that either branch is not taken,
@@ -44,16 +44,16 @@ Note also that all other branching hoons reduce to `?:`.
44~zod:dojo> ?:((gth 1 0) 3 4)
44~zod:dojo> ?:((gth 1 0) 3 4)
453
453
46
46
47−~zod:dojo> ?: (gth 1 0)
47+~zod:dojo> ?: (gth 1 0)
48− 3
48+ 3
49 4
49 4
503
503
51
51
52~zod:dojo> ?:((gth 1 2) 3 4)
52~zod:dojo> ?:((gth 1 2) 3 4)
534
534
54
54
55−~zod:dojo> ?: (gth 1 2)
55+~zod:dojo> ?: (gth 1 2)
56− 3
56+ 3
57 4
57 4
584
584
59```
59```
docs/hoon/rune/wut/dot.md → docs/reference/rune/wut/dot.umdrenamed+9−9
@@ -1,11 +1,11 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 2
3+ sort/'6'
5−title: ?. "wutdot"
4+ title/'?. "wutdot"'
6−---
5+ ==
6+;>
7
7
8−# `?. "wutdot"`
8+# `?. "wutdot"`
9
9
10`[%wtdt p=hoon q=hoon r=hoon]`: branch on a boolean test, inverted.
10`[%wtdt p=hoon q=hoon r=hoon]`: branch on a boolean test, inverted.
11
11
@@ -21,8 +21,8 @@ Regular: *3-fixed*.
21
21
22## Discussion
22## Discussion
23
23
24−As usual with inverted forms, use `?.` ("wutdot") when the positive
24+As usual with inverted forms, use `?.` ("wutdot") when the yes-case
25−hoon of an `?:` ("wutcol") is much heavier than the negative hoon.
25+expression is much taller and/or wider than the no-case expression.
26
26
27## Examples
27## Examples
28
28
docs/hoon/rune/wut/hep.md → docs/reference/rune/wut/hep.umdrenamed+12−11
@@ -1,13 +1,13 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 12
3+ sort/'4'
5−title: ?- "wuthep"
4+ title/'?- "wuthep"'
6−---
5+ ==
6+;>
7
7
8−# `?- "wuthep"`
8+# `?- "wuthep"`
9
9
10−`[%wthp p=wing q=(list (pair model value))]`: switch against a
10+`[%wthp p=wing q=(list (pair model value))]`: switch against a
11union, with no default.
11union, with no default.
12
12
13## Expands to
13## Expands to
@@ -45,7 +45,7 @@ not special handling for `?-` ("wuthep"), just a consequence of the
45semantics of `?:` ("wutcol"), which `?-` reduces to.
45semantics of `?:` ("wutcol"), which `?-` reduces to.
46
46
47A missing case will throw the `mint-lost` error. An extra case
47A missing case will throw the `mint-lost` error. An extra case
48−will throw `mint-vain`. (Ecclesiastes did nothing wrong.)
48+will throw `mint-vain`.
49
49
50## Examples
50## Examples
51
51
@@ -55,12 +55,13 @@ will throw `mint-vain`. (Ecclesiastes did nothing wrong.)
55 $a 20
55 $a 20
56 $b 42
56 $b 42
57 ==
57 ==
58+
58~zod:dojo> (cor %a)
59~zod:dojo> (cor %a)
5920
6020
61+
60~zod:dojo> (cor %b)
62~zod:dojo> (cor %b)
6142
6342
64+
62~zod:dojo> (cor %c)
65~zod:dojo> (cor %c)
63! nest-fail
66! nest-fail
64```
67```
65−
66−
docs/hoon/rune/wut/ket.md → docs/reference/rune/wut/ket.umdrenamed+7−7
@@ -1,13 +1,13 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 11
3+ sort/'3'
5−title: ?^ "wutket"
4+ title/'?^ "wutket"'
6−---
5+ ==
6+;>
7
7
8# `?^ "wutket"`
8# `?^ "wutket"`
9
9
10−`[%wtkt p=wing q=hoon r=hoon]`: branch on whether a wing
10+`[%wtkt p=wing q=hoon r=hoon]`: branch on whether a wing
11of the subject is a cell.
11of the subject is a cell.
12
12
13## Expands to
13## Expands to
docs/hoon/rune/wut/gal.md → docs/reference/rune/wut/led.umdrenamed+7−8
@@ -1,11 +1,11 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 4
3+ sort/'8'
5−title: ?< "wutgal"
4+ title/'?< "wutled"'
6−---
5+ ==
6+;>
7
7
8−# `?< "wutgal"`
8+# `?< "wutled"`
9
9
10`[%wtgl p=hoon q=hoon]`: negative assertion.
10`[%wtgl p=hoon q=hoon]`: negative assertion.
11
11
@@ -28,4 +28,3 @@ Regular: *2-fixed*.
28~zod:dojo> ?<(=(3 3) %foo)
28~zod:dojo> ?<(=(3 3) %foo)
29ford: build failed
29ford: build failed
30```
30```
31−
docs/hoon/rune/wut/lus.md → docs/reference/rune/wut/lus.umdrenamed+10−6
@@ -1,12 +1,13 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
2+ next/'true'
3−sort: 13
3+ sort/'5'
4−title: ?+ "wutlus"
4+ title/'?+ "wutlus"'
5−---
5+ ==
6+;>
6
7
7# `?+ "wutlus"`
8# `?+ "wutlus"`
8
9
9−`[%wtls p=wing q=value r=(list (pair model value))]`: switch against
10+`[%wtls p=wing q=hoon r=(list (pair spec hoon))]`: switch against
10a union, with a default.
11a union, with a default.
11
12
12## Expands to
13## Expands to
@@ -48,10 +49,13 @@ An extra case will throw `mint-vain`. A lost case defaults.
48 $a 20
49 $a 20
49 $b 42
50 $b 42
50 ==
51 ==
52+
51~zod:dojo> (cor %a)
53~zod:dojo> (cor %a)
5220
5420
55+
53~zod:dojo> (cor %b)
56~zod:dojo> (cor %b)
5442
5742
58+
55~zod:dojo> (cor %c)
59~zod:dojo> (cor %c)
56240
60240
57```
61```
docs/hoon/rune/wut/pam.md → docs/reference/rune/wut/pad.umdrenamed+8−8
@@ -1,13 +1,13 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 5
3+ sort/'9'
5−title: ?& "wutpam"
4+ title/'?& "wutpad"'
6−---
5+ ==
6+;>
7
7
8−# `?& "wutpam"`
8+# `?& "wutpad"`
9
9
10−`[%wtpm p=(list hoon)]`: logical and.
10+`[%wtpm p=(list hoon)]`: logical AND.
11
11
12## Expands to
12## Expands to
13
13
docs/hoon/rune/wut/sig.md → docs/reference/rune/wut/sig.umdrenamed+10−9
@@ -1,15 +1,15 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 9
3+ sort/'13'
5−title: ?~ "wutsig"
4+ title/'?~ "wutsig"'
6−---
5+ ==
6+;>
7
7
8−# `?~ "wutsig"`
8+# `?~ "wutsig"`
9
9
10−`[%wtsg p=wing q=hoon r=hoon]`: branch on whether a wing
10+`[%wtsg p=wing q=hoon r=hoon]`: branch on whether a wing
11of the subject is null.
11of the subject is null.
12−
12+
13## Expands to
13## Expands to
14
14
15```
15```
@@ -29,6 +29,7 @@ only for a true null, `~`.
29
29
30```
30```
31~zod:dojo> =foo ""
31~zod:dojo> =foo ""
32+
32~zod:dojo> ?~(foo 1 2)
33~zod:dojo> ?~(foo 1 2)
331
341
34```
35```
docs/hoon/rune/wut/tis.md → docs/reference/rune/wut/tis.umdrenamed+12−12
@@ -1,18 +1,18 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 8
3+ sort/'12'
5−title: ?= "wuttis"
4+ title/'?= "wuttis"'
6−---
5+ ==
6+;>
7
7
8# `?= "wuttis"`
8# `?= "wuttis"`
9
9
10−`[%wtts p=model q=wing]`: test pattern match.
10+`[%wtts p=spec q=wing]`: test pattern match.
11
11
12## Produces
12## Produces
13
13
14−`&` (yes) if the noun at `q` is in the icon of `p`;
14+`%.y` (yes) if the noun at `q` is in the type of `p`;
15−`|` (no) otherwise.
15+`%.n` (no) otherwise.
16
16
17## Syntax
17## Syntax
18
18
@@ -21,8 +21,8 @@ Regular: *2-fixed*.
21## Discussion
21## Discussion
22
22
23`?=` ("wuttis") is not as powerful as it might seem. For instance, it
23`?=` ("wuttis") is not as powerful as it might seem. For instance, it
24−can't generate a loop -- you cannot (and should not) use it to
24+can't generate a loop -- you cannot (and should not) use it to
25−test whether a `*` is a `(list @)`. Nor can it validate atomic
25+test whether a `*` is a `(list @)`. Nor can it validate atomic
26auras.
26auras.
27
27
28Patterns should be as weak as possible. Unpack one layer of
28Patterns should be as weak as possible. Unpack one layer of
@@ -32,7 +32,7 @@ For example, when matching a book containing a page `[%foo p=@
32q=[@ @]]`, the proper pattern is `[%foo *]`. You have one
32q=[@ @]]`, the proper pattern is `[%foo *]`. You have one
33question, which is whether the head of the noun is `%foo`.
33question, which is whether the head of the noun is `%foo`.
34
34
35−A common error is `find.$`, meainng `p` is not a mold.
35+A common error is `find.$`, meainng `p` is not a type.
36
36
37## Examples
37## Examples
38
38
docs/hoon/rune/wut/pat.md → docs/reference/rune/wut/vat.umdrenamed+10−8
@@ -1,13 +1,13 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 10
3+ sort/'2'
5−title: ?@ "wutpat"
4+ title/'?@ "wutvat"'
6−---
5+ ==
6+;>
7
7
8−# `?@ "wutpat"`
8+# `?@ "wutvat"`
9
9
10−`[%wtpt p=wing q=hoon r=hoon]`: branch on whether a wing
10+`[%wtpt p=wing q=hoon r=hoon]`: branch on whether a wing
11of the subject is an atom.
11of the subject is an atom.
12
12
13## Expands to
13## Expands to
@@ -26,8 +26,10 @@ Regular: *3-fixed*.
26~zod:dojo> ?@(0 1 2)
26~zod:dojo> ?@(0 1 2)
27! mint-vain
27! mint-vain
28! exit
28! exit
29+
29~zod:dojo> ?@(`*`0 1 2)
30~zod:dojo> ?@(`*`0 1 2)
301
311
32+
31~zod:dojo> ?@(`*`[1 2] 3 4)
33~zod:dojo> ?@(`*`[1 2] 3 4)
324
344
33```
35```
docs/hoon/rune/wut/zap.md → docs/reference/rune/wut/zap.umdrenamed+7−7
@@ -1,13 +1,13 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 7
3+ sort/'11'
5−title: ?! "wutzap"
4+ title/'?! "wutzap"'
6−---
5+ ==
6+;>
7
7
8# `?! "wutzap"`
8# `?! "wutzap"`
9
9
10−`[%wtzp p=hoon]`: logical not.
10+`[%wtzp p=hoon]`: logical NOT.
11
11
12## Expands to
12## Expands to
13
13
docs/reference/rune/zap.umdnew file+12
@@ -0,0 +1,12 @@
1+:- :~ navhome/'/docs/'
2+ next/'true'
3+ sort/'4'
4+ title/'Wild . ("zap")'
5+ ==
6+;>
7+
8+# Wild `!` ("zap")
9+
10+## Runes
11+
12+;list(datapreview "true", classname "runes");
docs/reference/rune/zap/gar.umdnew file+36
@@ -0,0 +1,36 @@
1+:- :~ navhome/'/docs/'
2+ next/'true'
3+ sort/'3'
4+ title/'!> "zapban"'
5+ ==
6+;>
7+
8+# `!> "zapban"`
9+
10+`[%zpgr p=hoon]`: wrap a noun in its type.
11+
12+## Produces
13+
14+A cell whose tail is `p`, and whose head is the static type of `p`.
15+
16+## Syntax
17+
18+Regular: *1-fixed*.
19+
20+## Discussion
21+
22+In Hoon, dynamic type is static type compiled at runtime. This type-noun cell is generally called a `vase`.
23+
24+## Examples
25+
26+```
27+> !>(1)
28+[p=#t/@ud q=1]
29+```
30+
31+If you want just the type value, use a 'type spear'. This is `-:!>`, i.e., the head of the cell produced by `!>`:
32+
33+```
34+> -:!>(1)
35+#t/@ud
36+```
docs/reference/rune/zap/tis.umdnew file+47
@@ -0,0 +1,47 @@
1+:- :~ navhome/'/docs/'
2+ next/'true'
3+ sort/'2'
4+ title/'!= "zaptis"'
5+ ==
6+;>
7+
8+# `!= "zaptis"`
9+
10+`[%zpts p=hoon]`: make the Nock formula for a Hoon expression.
11+
12+## Produces
13+
14+The Nock generated by `p`.
15+
16+## Syntax
17+
18+Regular: *1-fixed*.
19+
20+## Discussion
21+
22+Don't confuse `!=` with a negation, `!`, followed by a test for equality, `=(10 11)`.
23+
24+## Examples
25+
26+```
27+> !=(20)
28+[1 20]
29+
30+> !=(~zod)
31+[1 0]
32+
33+> !=((add 2 2))
34+[8 [9 3.110.356 0 31] 9 2 [0 4] [7 [0 3] 1 2 2] 0 11]
35+```
36+
37+Don't confuse the `!=` rune with:
38+
39+```
40+> !=(10 11)
41+%.y
42+
43+> !=(10 10)
44+%.n
45+```
46+
47+The syntax difference is that a test for equality takes two subexpressions, and the `!=` rune only one.
docs/hoon/rune/zap/wut.md → docs/reference/rune/zap/wut.umdrenamed+10−8
@@ -1,8 +1,8 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−sort: 4
2+ sort/'4'
4−title: !? "zapwut"
3+ title/'!? "zapwut"'
5−---
4+ ==
5+;>
6
6
7# `!? "zapwut"`
7# `!? "zapwut"`
8
8
@@ -20,10 +20,12 @@ Regular: *2-fixed*.
20## Examples
20## Examples
21
21
22```
22```
23−~zod:dojo> !?(264 (add 2 2))
23+> !?(264 (add 2 2))
244
244
25+
25−~zod:dojo> !?(164 (add 2 2))
26+> !?(164 (add 2 2))
264
274
28+
27−~zod:dojo> !?(64 (add 2 2))
29+> !?(64 (add 2 2))
28! exit
30! exit
29```
31```
docs/hoon/rune/zap/zap.md → docs/reference/rune/zap/zap.umdrenamed+7−7
@@ -1,9 +1,9 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ next/'true'
4−sort: 1
3+ sort/'1'
5−title: !! "zapzap"
4+ title/'!! "zapzap"'
6−---
5+ ==
6+;>
7
7
8# `!! "zapzap"`
8# `!! "zapzap"`
9
9
@@ -24,6 +24,6 @@ Nothing. Always crashes, with type `%void`.
24## Examples
24## Examples
25
25
26```
26```
27−~zod:dojo> !!
27+> !!
28ford: build failed
28ford: build failed
29```
29```
docs/hoon/troubleshooting.md → docs/reference/troubleshooting.umdrenamed+11−12
@@ -1,9 +1,8 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
4−sort: 23
2+ sort/'6'
5−title: Troubleshooting
3+ title/'Troubleshooting'
6−---
4+ ==
5+;>
7
6
8# Troubleshooting
7# Troubleshooting
9
8
@@ -24,7 +23,7 @@ a correct Hoon file. These values are always correct.
24Usually, the line and column tell you everything you need to
23Usually, the line and column tell you everything you need to
25know. But the worst-case scenario for a syntax error is that,
24know. But the worst-case scenario for a syntax error is that,
26somewhere above, you've confused Hoon's tall form by using the
25somewhere above, you've confused Hoon's tall form by using the
27−wrong fanout for a rune. For example, `%+` ([*cenlus*](../rune/cen/lus),
26+wrong fanout for a rune. For example, `%+` ([*cenlus*](../rune/cen/lus),
28a function call whose sample is a cell) has three subhoons:
27a function call whose sample is a cell) has three subhoons:
29
28
30```
29```
@@ -126,9 +125,9 @@ In other words, "undeclared variable."
126
125
127The most common subspecies of `find` error is `find.$`, meaning
126The most common subspecies of `find` error is `find.$`, meaning
128the empty name `$` was not found. This often happens when you
127the empty name `$` was not found. This often happens when you
129−use a hoon that does not produce a gate/mold, as a gate/mold. For
128+use a hoon that does not produce a gate/mold, as a gate/mold. For
130−instance, `(foo bar)` will give `find.$` if `foo` is not actually a
129+instance, `(foo bar)` will give `find.$` if `foo` is not actually a
131−function.
130+function.
132
131
133### `mint-vain` and `mint-lost`
132### `mint-vain` and `mint-lost`
134
133
@@ -147,7 +146,7 @@ need to be developing on the local console; otherwise, the
147infinite loop will time out either too slowly or too fast). The
146infinite loop will time out either too slowly or too fast). The
148stack trace will show what your code was doing when interrupted.
147stack trace will show what your code was doing when interrupted.
149
148
150−The counterpart of `~!` for runtime crashes is `~|`
149+The counterpart of `~!` for runtime crashes is `~|`
151([*sigbar*](../rune/sig/bar)):
150([*sigbar*](../rune/sig/bar)):
152
151
153```
152```
@@ -164,7 +163,7 @@ The worst possibility, of course, is that your code runs but does
164the wrong thing. This is relatively unusual in a typed
163the wrong thing. This is relatively unusual in a typed
165functional language, but it still happens.
164functional language, but it still happens.
166
165
167−`~&` ([*sigpam*](../rune/sig/pam)) is Hoon's debugging printf.
166+`~&` ([*sigpam*](../rune/sig/pam)) is Hoon's debugging printf.
168This pretty-prints its argument:
167This pretty-prints its argument:
169
168
170```
169```
docs/tutorials.umdnew file+11
@@ -0,0 +1,11 @@
1+:- :~ navhome/'/docs/'
2+ sort/'3'
3+ title/'Tutorials'
4+ ==
5+;>
6+
7+# Tutorials
8+
9+Whether you want to learn to program in Hoon, walk through the Nock spec, or learn how to use Hoon to interact with Arvo, this is your destination.
10+
11+;list;
docs/tutorials/community.umdnew file+19
@@ -0,0 +1,19 @@
1+:- :~ navhome/'/docs/'
2+ next/'false'
3+ sort/'9'
4+ title/'Community Tutorials'
5+ ==
6+;>
7+
8+# Community docs
9+
10+Here are some tutorials written by members of the Urbit community. Some are a little outdated, but they may still prove useful.
11+
12+- `~master-morzod`
13+ - [Fora post](https://urbit.org/fora/posts/~2016.12.25..06.35.44..a1ec~/)
14+- `~hidduc-posmeg`
15+ - [Fora post](https://urbit.org/fora/posts/~2017.2.12..21.54.40..6fde~/)
16+- `~palfun-foslup`
17+ - [Urbit by Doing](https://github.com/Fang-/Urbit-By-Doing)
18+- `@knubie`
19+ - [Learning Hoon](https://github.com/knubie/learning-hoon)
docs/tutorials/gall.umdnew file+14
@@ -0,0 +1,14 @@
1+:- :~ navhome/'/docs/'
2+ next/'true'
3+ sort/'6'
4+ title/'Gall Apps'
5+ ==
6+;>
7+
8+# Gall Apps
9+
10+This is documentation about how to write Gall apps. Some knowledge of Hoon is assumed.
11+
12+Note: these lessons were first written in 2016. They need to be rewritten; in some ways they are outdated, and in other ways they were not always accessible enough to beginners. We are planning to rewrite these in the near future. In the meantime there is still useful information to be found here.
13+
14+;list;
docs/arvo/api.md → docs/tutorials/gall/api.umdrenamed+98−111
@@ -1,9 +1,9 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ navuptwo/'true'
4−sort: 21
3+ sort/'9'
5−title: API Connectors
4+ title/'API Connectors'
6−---
5+ ==
6+;>
7
7
8# API Connectors
8# API Connectors
9
9
@@ -26,35 +26,45 @@ app accomplishes both for Github.
26After starting `%gh` (`|start %gh`), let's look at the root of
26After starting `%gh` (`|start %gh`), let's look at the root of
27the tree that `%gh` exposes:
27the tree that `%gh` exposes:
28
28
29+```
29 ~your-urbit:dojo> .^(arch %gy /=gh=)
30 ~your-urbit:dojo> .^(arch %gy /=gh=)
30 [fil=~ dir={[p=~.issues q=~]}]
31 [fil=~ dir={[p=~.issues q=~]}]
32+```
31
33
32`%gh` is currently a skeleton -- it contains examples of all the
34`%gh` is currently a skeleton -- it contains examples of all the
33functionality necessary for a connector, but many endpoints
35functionality necessary for a connector, but many endpoints
34aren't implemented. As we can see here, only issues are
36aren't implemented. As we can see here, only issues are
35implemented. We can explore this tree:
37implemented. We can explore this tree:
36
38
39+```
37 ~your-urbit:dojo> .^(arch %gy /=gh=/issues)
40 ~your-urbit:dojo> .^(arch %gy /=gh=/issues)
38 [fil=~ dir={[p=~.by-repo q=~] [p=~.mine q=~]}]
41 [fil=~ dir={[p=~.by-repo q=~] [p=~.mine q=~]}]
42+```
39
43
40And eventually:
44And eventually:
41
45
46+```
42 /- gh
47 /- gh
43 .^(issue:gh %gx /=gh=/issues/by-repo/philipcmonktest/testing/7)
48 .^(issue:gh %gx /=gh=/issues/by-repo/philipcmonktest/testing/7)
44 <issue...>
49 <issue...>
45 login.user:.^(issue:gh %gx /=gh=/issues/by-repo/philipcmonktest/testing/7)
50 login.user:.^(issue:gh %gx /=gh=/issues/by-repo/philipcmonktest/testing/7)
46 'philipcmonktest'
51 'philipcmonktest'
52+```
47
53
48The other thing an API connector needs to do is expose event
54The other thing an API connector needs to do is expose event
49streams. One straightforward way to use this capacity is with
55streams. One straightforward way to use this capacity is with
50the `:pipe` app:
56the `:pipe` app:
51
57
58+```
52 :pipe|connect %gh /listen/philipcmonktest/testing/issues/'issue_comment' %public
59 :pipe|connect %gh /listen/philipcmonktest/testing/issues/'issue_comment' %public
60+```
53
61
54Now creating an issue results in the following message in your
62Now creating an issue results in the following message in your
55`%public` `:talk` channel:
63`%public` `:talk` channel:
56
64
65+```
57 ~your-urbit[philipcmonktest@github]: opened issue #11: i found a bug!
66 ~your-urbit[philipcmonktest@github]: opened issue #11: i found a bug!
67+```
58
68
59You'll also get notifications of issue status changes and
69You'll also get notifications of issue status changes and
60comments.
70comments.
@@ -93,11 +103,14 @@ of `move` and `sub-result` (all the types of data that can be
93returned by a place). This can just be a line at the top of the
103returned by a place). This can just be a line at the top of the
94main core:
104main core:
95
105
106+```
96 =+ connector=(connector move sub-result) :: Set up connector library
107 =+ connector=(connector move sub-result) :: Set up connector library
108+```
97
109
98Most of the Github-specific logic is in `++places`, which is a
110Most of the Github-specific logic is in `++places`, which is a
99list of all the places we can request. A place consists of:
111list of all the places we can request. A place consists of:
100
112
113+```
101 ++ place
114 ++ place
102 $: guard/mold
115 $: guard/mold
103 read-x/$-(path move)
116 read-x/$-(path move)
@@ -105,28 +118,17 @@ list of all the places we can request. A place consists of:
105 sigh-x/$-(jon/json (unit sub-result))
118 sigh-x/$-(jon/json (unit sub-result))
106 sigh-y/$-(jon/json (unit arch))
119 sigh-y/$-(jon/json (unit arch))
107 ==
120 ==
121+```
108
122
109−- `guard`, the type of the paths we should match. For example,
123+- `guard`, the type of the paths we should match. For example, to match `/issues/<user>/<repo>` use `{$issues @t @t $~}`.
110− to match `/issues/<user>/<repo>` use `{$issues @t @t $~}`.
111
124
112−- `read-x`, called when someone tries to read the place with
125+- `read-x`, called when someone tries to read the place with `care` `%x`. Should produce a single move, usually either a `%diff` response if we can immediately answer or a `%hiss` http request if we need to make a request to the api. See the `++read-*` functions in `++helpers` for some common handlers.
113− `care` `%x`. Should produce a single move, usually either a
114− `%diff` response if we can immediately answer or a `%hiss`
115− http request if we need to make a request to the api. See the
116− `++read-*` functions in `++helpers` for some common handlers.
117
126
118−- `read-y`, same as `read-x` except with care `%y`.
127+- `read-y`, same as `read-x` except with care `%y`.
119
128
120−- `sigh-x`, called when an http response comes back on this
129+- `sigh-x`, called when an http response comes back on this place. You're given the json of the result, and you should produce either a result or null. Null represents an error. If you didn't create an http request in `read-x`, then this should never be called. Use `++sigh-strange` from `++helpers` to unconditionally signal an error.
121− place. You're given the json of the result, and you should
122− produce either a result or null. Null represents an error.
123− If you didn't create an http request in `read-x`, then this
124− should never be called. Use `++sigh-strange` from `++helpers`
125− to unconditionally signal an error.
126
130
127−- `sigh-y`, same as `sigh-x` except with care `%y`. Note that a
131+- `sigh-y`, same as `sigh-x` except with care `%y`. Note that a `%y` request must produce an arch, unlike a `%x` request, which may produce data of any mark.
128− `%y` request must produce an arch, unlike a `%x` request,
129− which may produce data of any mark.
130
132
131Filling out the list of places is a lot of grunt work, but most
133Filling out the list of places is a lot of grunt work, but most
132places are fairly straightforward, and the `++read-*` helper
134places are fairly straightforward, and the `++read-*` helper
@@ -138,28 +140,13 @@ control. `++peek` and `++peer-scry` are the interface we expose
138to the rest of the system while `++sigh-httr` and `++sigh-tang`
140to the rest of the system while `++sigh-httr` and `++sigh-tang`
139are used to handle responses when we make HTTP requests.
141are used to handle responses when we make HTTP requests.
140
142
141−- `++peek` should usually just produce `~`. If there are cases
142− where we can respond directly to a `.^` request without
143− blocking on anything, we could do it here, but it's generally
144− not worth the hassle since the same logic should be duplicated
143+- `++peek` should usually just produce `~`. If there are cases where we can respond directly to a `.^` request without blocking on anything, we could do it here, but it's generally not worth the hassle since the same logic should be duplicated in `++peer-scry`.
145− in `++peer-scry`.
144+
146−
145+- `++peer-scry` is where the actual handling for a read request goes. In general, we just need to call `++read` from the `connector` library with the bone, list of places, care, and path. This will match the path to the appropriate place and run either `++read-x` or `++read-y`, depending on the care.
147−- `++peer-scry` is where the actual handling for a read request
146+
148− goes. In general, we just need to call `++read` from the
147+- If `++read-x` or `++read-y` made a successful API request, then the response will come back on `++sigh-httr`. Here, we just need to parse out the wire and call `++sigh` from the `connector` library with the list of places, care, path, and HTTP result. This will match the path to the appropriate place and run either `++sigh-x` or `++sigh-y`, depending on the care.
149− `connector` library with the bone, list of places, care, and
148+
150− path. This will match the path to the appropriate place and
151− run either `++read-x` or `++read-y`, depending on the care.
152−
153−- If `++read-x` or `++read-y` made a successful API request, then
154− the response will come back on `++sigh-httr`. Here, we just
155− need to parse out the wire and call `++sigh` from the
156− `connector` library with the list of places, care, path, and
157− HTTP result. This will match the path to the appropriate place
158− and run either `++sigh-x` or `++sigh-y`, depending on the care.
159−
160−- If `++read-x` or `++read-y` made an API request that failed,
161− then we'll get a stack trace in `++sigh-tang`. Here, we just
149+- If `++read-x` or `++read-y` made an API request that failed, then we'll get a stack trace in `++sigh-tang`. Here, we just print it out and move on.
162− print it out and move on.
163
150
164That's really all there is to the reading portion of API
151That's really all there is to the reading portion of API
165connectors.
152connectors.
@@ -243,56 +230,56 @@ this doc:
243::
230::
244!:
231!:
245=> |%
232=> |%
246− ++ move (pair bone card)
233+ +$ move (pair bone card)
247− ++ card
234+ +$ card
248− $% {$diff sub-result}
235+ $% [%diff sub-result]
249− {$them wire (unit hiss)}
236+ [%them wire (unit hiss)]
250− {$hiss wire {$~ $~} $httr {$hiss hiss}}
237+ [%hiss wire [$~ $~] %httr [%hiss hiss]]
251 ==
238 ==
252 ::
239 ::
253 :: Types of results we produce to subscribers.
240 :: Types of results we produce to subscribers.
254 ::
241 ::
255− ++ sub-result
242+ +$ sub-result
256− $% {$arch arch}
243+ $% [$arch arch]
257− {$gh-issue issue:gh}
244+ [$gh-issue issue:gh]
258− {$gh-list-issues (list issue:gh)}
245+ [$gh-list-issues (list issue:gh)]
259− {$gh-issues issues:gh}
246+ [$gh-issues issues:gh]
260− {$gh-issue-comment issue-comment:gh}
247+ [$gh-issue-comment issue-comment:gh]
261− {$json json}
248+ [$json json]
262− {$null $~}
249+ [$null $~]
263 ==
250 ==
264 ::
251 ::
265 :: Types of webhooks we expect.
252 :: Types of webhooks we expect.
266 ::
253 ::
267− ++ hook-response
254+ +$ hook-response
268− $% {$gh-issues issues:gh}
255+ $% [$gh-issues issues:gh]
269− {$gh-issue-comment issue-comment:gh}
256+ [$gh-issue-comment issue-comment:gh]
270 ==
257 ==
271 --
258 --
272=+ connector=(connector move sub-result) :: Set up connector library
259=+ connector=(connector move sub-result) :: Set up connector library
273::
260::
274−|_ $: hid/bowl
261+|_ $: hid=bowl:gall
275− hook/(map @t {id/@t listeners/(set bone)}) :: map events to listeners
262+ hook=(map @t [id=@t listeners=(set bone)]) :: map events to listeners
276 ==
263 ==
277:: ++ prep _`. :: Clear state when code changes
264:: ++ prep _`. :: Clear state when code changes
278::
265::
279:: List of endpoints
266:: List of endpoints
280::
267::
281++ places
268++ places
282− |= wir/wire
269+ |= wir=wire
283 ^- (list place:connector)
270 ^- (list place:connector)
284 =+ (helpers:connector ost.hid wir "https://api.github.com")
271 =+ (helpers:connector ost.hid wir "https://api.github.com")
285 => |% :: gh-specific helpers
272 => |% :: gh-specific helpers
286 ++ sigh-list-issues-x
273 ++ sigh-list-issues-x
287− |= jon/json
274+ |= jon=json
288 %+ bind ((ar:jo issue:gh-parse) jon)
275 %+ bind ((ar:jo issue:gh-parse) jon)
289− |= issues/(list issue:gh)
276+ |= issues=(list issue:gh)
290 gh-list-issues+issues
277 gh-list-issues+issues
291 ::
278 ::
292 ++ sigh-list-issues-y
279 ++ sigh-list-issues-y
293− |= jon/json
280+ |= jon=json
294 %+ bind ((ar:jo issue:gh-parse) jon)
281 %+ bind ((ar:jo issue:gh-parse) jon)
295− |= issues/(list issue:gh)
282+ |= issues=(list issue:gh)
296 :- `(shax (jam issues))
283 :- `(shax (jam issues))
297 (malt (turn issues |=(issue:gh [(rsh 3 2 (scot %ui number)) ~])))
284 (malt (turn issues |=(issue:gh [(rsh 3 2 (scot %ui number)) ~])))
298 --
285 --
@@ -304,59 +291,59 @@ this doc:
304 sigh-y=sigh-strange
291 sigh-y=sigh-strange
305 ==
292 ==
306 ^- place :: /issues
293 ^- place :: /issues
307− :* guard={$issues $~}
294+ :* guard=[$issues $~]
308 read-x=read-null
295 read-x=read-null
309 read-y=(read-static %mine %by-repo ~)
296 read-y=(read-static %mine %by-repo ~)
310 sigh-x=sigh-strange
297 sigh-x=sigh-strange
311 sigh-y=sigh-strange
298 sigh-y=sigh-strange
312 ==
299 ==
313 ^- place :: /issues/mine
300 ^- place :: /issues/mine
314− :* guard={$issues $mine $~}
301+ :* guard=[$issues $mine $~]
315 read-x=(read-get /issues)
302 read-x=(read-get /issues)
316 read-y=(read-get /issues)
303 read-y=(read-get /issues)
317 sigh-x=sigh-list-issues-x
304 sigh-x=sigh-list-issues-x
318 sigh-y=sigh-list-issues-y
305 sigh-y=sigh-list-issues-y
319 ==
306 ==
320 ^- place :: /issues/by-repo
307 ^- place :: /issues/by-repo
321− :* guard={$issues $by-repo $~}
308+ :* guard=[$issues $by-repo $~]
322 read-x=read-null
309 read-x=read-null
323 ^= read-y
310 ^= read-y
324− |= pax/path
311+ |= pax=path
325 =+ /(scot %p our.hid)/home/(scot %da now.hid)/web/plan
312 =+ /(scot %p our.hid)/home/(scot %da now.hid)/web/plan
326− =+ .^({* acc/(map knot plan-acct)} %cx -)
313+ =+ .^([* acc=(map knot plan-acct)] %cx -)
327 ::
314 ::
328 ((read-static usr:(~(got by acc) %github) ~) pax)
315 ((read-static usr:(~(got by acc) %github) ~) pax)
329 sigh-x=sigh-strange
316 sigh-x=sigh-strange
330 sigh-y=sigh-strange
317 sigh-y=sigh-strange
331 ==
318 ==
332 ^- place :: /issues/by-repo/<user>
319 ^- place :: /issues/by-repo/<user>
333− :* guard={$issues $by-repo @t $~}
320+ :* guard=[$issues $by-repo @t $~]
334 read-x=read-null
321 read-x=read-null
335− read-y=|=(pax/path (get /users/[-.+>.pax]/repos))
322+ read-y=|=(pax=path (get /users/[-.+>.pax]/repos))
336 sigh-x=sigh-strange
323 sigh-x=sigh-strange
337 ^= sigh-y
324 ^= sigh-y
338− |= jon/json
325+ |= jon=json
339 %+ bind ((ar:jo repository:gh-parse) jon)
326 %+ bind ((ar:jo repository:gh-parse) jon)
340− |= repos/(list repository:gh)
327+ |= repos=(list repository:gh)
341 [~ (malt (turn repos |=(repository:gh [name ~])))]
328 [~ (malt (turn repos |=(repository:gh [name ~])))]
342 ==
329 ==
343 ^- place :: /issues/by-repo/<user>/<repo>
330 ^- place :: /issues/by-repo/<user>/<repo>
344− :* guard={$issues $by-repo @t @t $~}
331+ :* guard=[$issues $by-repo @t @t $~]
345− read-x=|=(pax/path (get /repos/[-.+>.pax]/[-.+>+.pax]/issues))
332+ read-x=|=(pax=path (get /repos/[-.+>.pax]/[-.+>+.pax]/issues))
346− read-y=|=(pax/path (get /repos/[-.+>.pax]/[-.+>+.pax]/issues))
333+ read-y=|=(pax=path (get /repos/[-.+>.pax]/[-.+>+.pax]/issues))
347 sigh-x=sigh-list-issues-x
334 sigh-x=sigh-list-issues-x
348 sigh-y=sigh-list-issues-y
335 sigh-y=sigh-list-issues-y
349 ==
336 ==
350 ^- place :: /issues/by-repo/<user>/<repo>
337 ^- place :: /issues/by-repo/<user>/<repo>
351− :* guard={$issues $by-repo @t @t @t $~}
338+ :* guard=[$issues $by-repo @t @t @t $~]
352 ^= read-x
339 ^= read-x
353− |=(pax/path (get /repos/[-.+>.pax]/[-.+>+.pax]/issues/[-.+>+>.pax]))
340+ |=(pax=path (get /repos/[-.+>.pax]/[-.+>+.pax]/issues/[-.+>+>.pax]))
354 ::
341 ::
355 read-y=(read-static ~)
342 read-y=(read-static ~)
356 ^= sigh-x
343 ^= sigh-x
357− |= jon/json
344+ |= jon=json
358 %+ bind (issue:gh-parse jon)
345 %+ bind (issue:gh-parse jon)
359− |= issue/issue:gh
346+ |= issue=issue:gh
360 gh-issue+issue
347 gh-issue+issue
361 ::
348 ::
362 sigh-y=sigh-strange
349 sigh-y=sigh-strange
@@ -370,9 +357,9 @@ this doc:
370:: We hand control to ++scry.
357:: We hand control to ++scry.
371::
358::
372++ peer-scry
359++ peer-scry
373− |= pax/path
360+ |= pax=path
374− ^- {(list move) _+>.$}
361+ ^- [(list move) _+>.$]
375− ?> ?=({care *} pax)
362+ ?> ?=([care *] pax)
376 :_ +>.$ :_ ~
363 :_ +>.$ :_ ~
377 (read:connector ost.hid (places %read pax) i.pax t.pax)
364 (read:connector ost.hid (places %read pax) i.pax t.pax)
378::
365::
@@ -380,9 +367,9 @@ this doc:
380:: produce the result (as JSON) to whoever sent the request.
367:: produce the result (as JSON) to whoever sent the request.
381::
368::
382++ sigh-httr
369++ sigh-httr
383− |= {way/wire res/httr}
370+ |= [way=wire res=httr]
384− ^- {(list move) _+>.$}
371+ ^- [(list move) _+>.$]
385− ?. ?=({$read care @ *} way)
372+ ?. ?=([$read care @ *] way)
386 ~& res=res
373 ~& res=res
387 [~ +>.$]
374 [~ +>.$]
388 =* style i.way
375 =* style i.way
@@ -396,8 +383,8 @@ this doc:
396:: also produce a result so that the request doesn't hang?
383:: also produce a result so that the request doesn't hang?
397::
384::
398++ sigh-tang
385++ sigh-tang
399− |= {way/wire tan/tang}
386+ |= [way=wire tan=tang]
400− ^- {(list move) _+>.$}
387+ ^- [(list move) _+>.$]
401 %- (slog >%gh-sigh-tang< tan)
388 %- (slog >%gh-sigh-tang< tan)
402 [[ost.hid %diff null+~]~ +>.$]
389 [[ost.hid %diff null+~]~ +>.$]
403::
390::
@@ -405,9 +392,9 @@ this doc:
405:: without blocking, so we just block unconditionally.
392:: without blocking, so we just block unconditionally.
406::
393::
407++ peek
394++ peek
408− |= {ren/@tas tyl/path}
395+ |= [ren=@tas tyl=path]
409 ^- (unit (unit (pair mark *)))
396 ^- (unit (unit (pair mark *)))
410− ~ ::``noun/[ren tyl]
397+ ~ ::``noun=[ren tyl]
411::
398::
412::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
399::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
413:: Webhook-powered event streams (/listen) ::
400:: Webhook-powered event streams (/listen) ::
@@ -419,9 +406,9 @@ this doc:
419:: We hand control to ++listen.
406:: We hand control to ++listen.
420::
407::
421++ peer-listen
408++ peer-listen
422− |= pax/path
409+ |= pax=path
423− ^- {(list move) _+>.$}
410+ ^- [(list move) _+>.$]
424− ?. ?=({@ @ *} pax)
411+ ?. ?=([@ @ *] pax)
425 ~& [%bad-listen-path pax]
412 ~& [%bad-listen-path pax]
426 [~ +>.$]
413 [~ +>.$]
427 (listen pax)
414 (listen pax)
@@ -430,16 +417,16 @@ this doc:
430:: updating the webhook flow for each event.
417:: updating the webhook flow for each event.
431::
418::
432++ listen
419++ listen
433− |= pax/path
420+ |= pax=path
434− =| mow/(list move)
421+ =| mow=(list move)
435 =< abet:listen
422 =< abet:listen
436 |%
423 |%
437 ++ abet :: Resolve core.
424 ++ abet :: Resolve core.
438− ^- {(list move) _+>.$}
425+ ^- [(list move) _+>.$]
439 [(flop mow) +>.$]
426 [(flop mow) +>.$]
440 ::
427 ::
441 ++ send-hiss :: Send a hiss
428 ++ send-hiss :: Send a hiss
442− |= hiz/hiss
429+ |= hiz=hiss
443 ^+ +>
430 ^+ +>
444 =+ wir=`wire`[%x %listen pax]
431 =+ wir=`wire`[%x %listen pax]
445 +>.$(mow [[ost.hid %hiss wir `~ %httr [%hiss hiz]] mow])
432 +>.$(mow [[ost.hid %hiss wir `~ %httr [%hiss hiz]] mow])
@@ -449,7 +436,7 @@ this doc:
449 ++ listen
436 ++ listen
450 ^+ .
437 ^+ .
451 =+ pax=pax :: TMI-proofing
438 =+ pax=pax :: TMI-proofing
452− ?> ?=({@ @ *} pax)
439+ ?> ?=([@ @ *] pax)
453 =+ events=t.t.pax
440 =+ events=t.t.pax
454 |- ^+ +>+.$
441 |- ^+ +>+.$
455 ?~ events
442 ?~ events
@@ -461,15 +448,15 @@ this doc:
461 :: Set up a webhook.
448 :: Set up a webhook.
462 ::
449 ::
463 ++ create-hook
450 ++ create-hook
464− |= event/@t
451+ |= event=@t
465 ^+ +>
452 ^+ +>
466− ?> ?=({@ @ *} pax)
453+ ?> ?=([@ @ *] pax)
467− =+ clean-event=`tape`(turn (trip event) |=(a/@tD ?:(=('_' a) '-' a)))
454+ =+ clean-event=`tape`(turn (trip event) |=(a=@tD ?:(=('_' a) '-' a)))
468 =. hook
455 =. hook
469 %+ ~(put by hook) (crip clean-event)
456 %+ ~(put by hook) (crip clean-event)
470 =+ %+ fall
457 =+ %+ fall
471 (~(get by hook) (crip clean-event))
458 (~(get by hook) (crip clean-event))
472− *{id/@t listeners/(set bone)}
459+ *[id=@t listeners=(set bone)]
473 [id (~(put in listeners) ost.hid)]
460 [id (~(put in listeners) ost.hid)]
474 %- send-hiss
461 %- send-hiss
475 :* %+ scan
462 :* %+ scan
@@ -480,7 +467,7 @@ this doc:
480 %- taco %- crip %- pojo %- jobe :~
467 %- taco %- crip %- pojo %- jobe :~
481 name+s+%web
468 name+s+%web
482 active+b+&
469 active+b+&
483− events+a+~[s+event] ::(turn `(list ,@t)`t.t.pax |=(a=@t s/a))
470+ events+a+~[s+event] ::(turn `(list ,@t)`t.t.pax |=(a=@t s=a))
484 :- %config
471 :- %config
485 %- jobe :~
472 %- jobe :~
486 =+ =+ clean-event
473 =+ =+ clean-event
@@ -494,7 +481,7 @@ this doc:
494 :: Add current bone to the list of subscribers for this event.
481 :: Add current bone to the list of subscribers for this event.
495 ::
482 ::
496 ++ update-hook
483 ++ update-hook
497− |= event/@t
484+ |= event=@t
498 ^+ +>
485 ^+ +>
499 =+ hok=(~(got by hook) event)
486 =+ hok=(~(got by hook) event)
500 %_ +>.$
487 %_ +>.$
@@ -511,8 +498,8 @@ this doc:
511:: listening for that event.
498:: listening for that event.
512::
499::
513++ poke
500++ poke
514− |= response/hook-response
501+ |= response=hook-response
515− ^- {(list move) _+>.$}
502+ ^- [(list move) _+>.$]
516 =+ hook-data=(~(get by hook) (rsh 3 3 -.response))
503 =+ hook-data=(~(get by hook) (rsh 3 3 -.response))
517 ?~ hook-data
504 ?~ hook-data
518 ~& [%strange-hook hook response]
505 ~& [%strange-hook hook response]
@@ -520,7 +507,7 @@ this doc:
520 :: ~& response=response
507 :: ~& response=response
521 :_ +>.$
508 :_ +>.$
522 %+ turn (~(tap in listeners.u.hook-data))
509 %+ turn (~(tap in listeners.u.hook-data))
523− |= ost/bone
510+ |= ost=bone
524 [ost %diff response]
511 [ost %diff response]
525--
512--
526```
513```
docs/arvo/generators.md → docs/tutorials/gall/generators.umdrenamed+32−40
@@ -1,9 +1,10 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3−next: true
3+ next/'true'
4−sort: 18
4+ sort/'6'
5−title: Using generators with apps
5+ title/'Using generators with apps'
6−---
6+ ==
7+;>
7
8
8# Generators
9# Generators
9
10
@@ -29,10 +30,12 @@ themselves, so we generally don't pipe the results into an app.
29Another generator is `+hood/merge`. Try running `+hood/merge` with the
30Another generator is `+hood/merge`. Try running `+hood/merge` with the
30normal arguments for `|merge`:
31normal arguments for `|merge`:
31
32
33+```
32 ~fintud-macrep:dojo> +hood/merge %home our %they
34 ~fintud-macrep:dojo> +hood/merge %home our %they
33 [syd=%home her=~fintud-macrep sud=%they gem=%auto]
35 [syd=%home her=~fintud-macrep sud=%they gem=%auto]
34 ~fintud-macrep:dojo> +hood/merge %home our %they, =gem %this
36 ~fintud-macrep:dojo> +hood/merge %home our %they, =gem %this
35 [syd=%home her=~fintud-macrep sud=%they gem=%auto]
37 [syd=%home her=~fintud-macrep sud=%they gem=%auto]
38+```
36
39
37This didn't run any merge, it just constructed the command that, if sent
40This didn't run any merge, it just constructed the command that, if sent
38to `:hood`, would run it. Note first that, even though it's not printed,
41to `:hood`, would run it. Note first that, even though it's not printed,
@@ -68,56 +71,62 @@ We'll need a new mark for our arguments. Let's call it
68> subdirectories in `/mar` are rendered as `-`, so that `ping-message`
71> subdirectories in `/mar` are rendered as `-`, so that `ping-message`
69> is written in (/mar/examples/ping/message.hoon).
72> is written in (/mar/examples/ping/message.hoon).
70
73
74+```
71 ::
75 ::
72 :::: /hoon/message/ping/examples/app
76 :::: /hoon/message/ping/examples/app
73 ::
77 ::
74 /? 314
78 /? 314
75− |_ {to/@p message/@t}
79+ |_ [to=@p message=@t]
76 ++ grab
80 ++ grab
77 |%
81 |%
78− ++ noun {@p @t}
82+ ++ noun [@p @t]
79 --
83 --
80 --
84 --
85+```
81
86
82The app can easily be modified to use this (`/app/examples/ping.hoon`):
87The app can easily be modified to use this (`/app/examples/ping.hoon`):
83
88
89+```
84 :: Allows one ship to ping another with a string of text
90 :: Allows one ship to ping another with a string of text
85 ::
91 ::
86 :::: /hoon/ping/examples/app
92 :::: /hoon/ping/examples/app
87 ::
93 ::
88 /? 314
94 /? 314
89 |%
95 |%
90− ++ move {bone term wire *}
96+ ++ move [bone term wire *]
91 --
97 --
92 !:
98 !:
93− |_ {bowl state/$~}
99+ |_ [bowl:gall state=$~]
94 ::
100 ::
95 ++ poke-examples-ping-message
101 ++ poke-examples-ping-message
96− |= {to/@p message/@t}
102+ |= [to=@p message/@t}
97 ~& 'sent'
103 ~& 'sent'
98− ^- {(list move) _+>.$}
104+ ^- [(list move) _+>.$]
99 :- ^- (list move)
105 :- ^- (list move)
100 :~ `move`[ost %poke /sending [to dap] %atom message]
106 :~ `move`[ost %poke /sending [to dap] %atom message]
101 ==
107 ==
102 +>.$
108 +>.$
103 ::
109 ::
104 ++ poke-atom
110 ++ poke-atom
105− |= arg/@
111+ |= arg=@
106 ~& 'received'
112 ~& 'received'
107− ^- {(list move) _+>.$}
113+ ^- [(list move) _+>.$]
108 ::
114 ::
109 ~& [%receiving (@t arg)]
115 ~& [%receiving (@t arg)]
110 [~ +>.$]
116 [~ +>.$]
111 ::
117 ::
112 ++ coup |=(* `+>)
118 ++ coup |=(* `+>)
113 --
119 --
120+```
114
121
115Now we can run this with:
122Now we can run this with:
116
123
124+```
117 ~fintud-macrep:dojo> |start %examples-ping
125 ~fintud-macrep:dojo> |start %examples-ping
118 >=
126 >=
119 ~fintud-macrep:dojo> :examples-ping &examples-ping-message [~sampel-sipnym 'heyya']
127 ~fintud-macrep:dojo> :examples-ping &examples-ping-message [~sampel-sipnym 'heyya']
120 >=
128 >=
129+```
121
130
122And on `~sampel-sipnym`, assuming it's running `:examples-ping` as well,
131And on `~sampel-sipnym`, assuming it's running `:examples-ping` as well,
123we see `[%receiving 'heyya']`.
132we see `[%receiving 'heyya']`.
@@ -127,11 +136,13 @@ mandatory, and optional arguments are hard. Let's make a generator,
127`+examples-send` to make everything nicer. Since it's specific to
136`+examples-send` to make everything nicer. Since it's specific to
128`:examples-ping`, let's put it in `/gen/examples/ping/send.hoon`:
137`:examples-ping`, let's put it in `/gen/examples/ping/send.hoon`:
129
138
139+```
130 :- %say
140 :- %say
131− |= {^ {to/@p message/?($~ {text/@t $~})} $~}
141+ |= [^ [to=@p message=?($~ [text=@t $~])] $~]
132 [%examples-ping-message to ?~(message 'howdy' text.message)]
142 [%examples-ping-message to ?~(message 'howdy' text.message)]
143+```
133
144
134−A couple of new things here. Firstly, `message/?($~ {text/@t $~})`
145+A couple of new things here. Firstly, `message=?($~ [text=@t $~])`
135should be read as "the message is either null or a pair of text and
146should be read as "the message is either null or a pair of text and
136null". Generator argument lists are always null-terminated, which makes
147null". Generator argument lists are always null-terminated, which makes
137it convenient to accept lists in tail position (which are particularly
148it convenient to accept lists in tail position (which are particularly
@@ -140,39 +151,20 @@ annoying without generators). `?(a b)` is the irregular form of
140anything that's in either `a` or `b`. Thus, in our case,
151anything that's in either `a` or `b`. Thus, in our case,
141`?(~ [text=@t ~])` is either null or a pair of text and null.
152`?(~ [text=@t ~])` is either null or a pair of text and null.
142
153
143−Secondly, `?~(a b c)` is a rune which means "if the `a` is null, do `b`,
144−else `c`". It is roughly equivalent to `?:(=(~ a) b c)`.
145−
146−> `?~(a b c)` is actually equivalent to `?:=(?=(~ a) b c)`, which,
147−> although identical at run time, is subtly different at compile time.
148−> Specifically, using `?=` rather than `=` means that we're checking
149−> whether `a` is in the *type* of `~`, and so the compiler knows that in
150−> the `b` case `a` is null, and in the `c` case `a` is not null. Since
151−> `=` is purely a runtime value check with no type implications, the
152−> compiler doesn't gain any information.
153−>
154−> At any rate, this is the reason why we can refer to `text.message` in
155−> the `c` clause. The compiler knows that `message` is not null, so it
156−> must have `text` within it. If you used
157−> `?:(=(~ message) 'howdy' text.message)` the compiler would complain
158−> that it doesn't know whether `message` has `text` within it.
159−
160This is run as follows:
154This is run as follows:
161
155
156+```
162 ~fintud-macrep:dojo> :examples-ping|send ~sampel-sipnym
157 ~fintud-macrep:dojo> :examples-ping|send ~sampel-sipnym
163 >=
158 >=
164 ~fintud-macrep:dojo> :examples-ping|send ~sampel-sipnym 'how do you do'
159 ~fintud-macrep:dojo> :examples-ping|send ~sampel-sipnym 'how do you do'
165 >=
160 >=
161+```
166
162
167Which causes `~sampel-sipnym` to print `[%receiving 'howdy']` and
163Which causes `~sampel-sipnym` to print `[%receiving 'howdy']` and
168`[%receiving 'how do you do']`.
164`[%receiving 'how do you do']`.
169
165
170−**Exercises**:
166+*Exercises*:
171
167
172−- Create a generator for `:examples-sum` from
173− [State](/docs/arvo/state) so that you can run `:examples-sum|add 5`
168+- Create a generator for `:examples-sum` from [State](../../state) so that you can run `:examples-sum|add 5` to add numbers to it.
174− to add numbers to it.
175
169
176−- Create a generator for `:examples-click` from [Web
170+- Create a generator for `:examples-click` from [Web Apps](../../web-apps) so that you can run `:examples-click|poke` to poke it.
177− Apps](/docs/arvo/web-apps) so that you can run
178− `:examples-click|poke` to poke it.
docs/arvo/http.md → docs/tutorials/gall/http.umdrenamed+26−25
@@ -1,9 +1,10 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3−next: false
3+ next/'true'
4−sort: 19
4+ sort/'7'
5−title: HTTP requests and timers
5+ title/'HTTP requests and timers'
6−---
6+ ==
7+;>
7
8
8# Writing an HTTP request
9# Writing an HTTP request
9
10
@@ -21,20 +22,20 @@ code isn't 2xx. Here's `app/up.hoon`:
21 ::
22 ::
22/? 314
23/? 314
23|%
24|%
24−++ move {bone card}
25++$ move [bone card]
25−++ card
26++$ card
26− $% {$hiss wire unit-iden/$~ mark/$httr cage/{mark/$purl vase/purl}}
27+ $% [%hiss wire unit-iden=$~ mark=%httr cage=[mark=%purl vase=purl]]
27− {$wait wire @da}
28+ [%wait wire @da]
28 ==
29 ==
29−++ action
30++$ action
30− $% {$on $~} :: enable polling('on')
31+ $% [%on $~] :: enable polling('on')
31− {$off $~} :: disable polling('off)
32+ [%off $~] :: disable polling('off)
32− {$target p/cord} :: set poll target('http://...')
33+ [%target p=cord] :: set poll target('http://...')
33 ==
34 ==
34--
35--
35−|_ {hid/bowl on/_| in-progress/_| target/@t}
36+|_ [hid=bowl:gall on=_| in-progress=_| target=@t}
36++ poke-atom
37++ poke-atom
37− |= url-or-command/@t ^- (quip move +>)
38+ |= url-or-command=@t ^- (quip move +>)
38 =+ ^- act/action
39 =+ ^- act/action
39 ?: ?=($on url-or-command) [%on ~]
40 ?: ?=($on url-or-command) [%on ~]
40 ?: ?=($off url-or-command) [%off ~]
41 ?: ?=($off url-or-command) [%off ~]
@@ -48,9 +49,9 @@ code isn't 2xx. Here's `app/up.hoon`:
48 +>.$(on &, in-progress &)
49 +>.$(on &, in-progress &)
49 ==
50 ==
50++ sigh-httr
51++ sigh-httr
51− |= {wir/wire code/@ud headers/mess body/(unit octs)}
52+ |= [wir=wire code=@ud headers=mess body=(unit octs)]
52 ~& 'arrive here'
53 ~& 'arrive here'
53− ^- {(list move) _+>.$}
54+ ^- [(list move) _+>.$]
54 ?: &((gte code 200) (lth code 300))
55 ?: &((gte code 200) (lth code 300))
55 ~& [%all-is-well code]
56 ~& [%all-is-well code]
56 :_ +>.$
57 :_ +>.$
@@ -61,7 +62,7 @@ code isn't 2xx. Here's `app/up.hoon`:
61 :_ +>.$
62 :_ +>.$
62 [ost.hid %wait /timer (add ~s10 now.hid)]~
63 [ost.hid %wait /timer (add ~s10 now.hid)]~
63++ wake-timer
64++ wake-timer
64− |= {wir/wire $~} ^- (quip move +>)
65+ |= [wir=wire $~] ^- (quip move +>)
65 ?: on
66 ?: on
66 :_ +>.$
67 :_ +>.$
67 [ost.hid %hiss /request ~ %httr %purl (need (epur target))]~
68 [ost.hid %hiss /request ~ %httr %purl (need (epur target))]~
@@ -78,10 +79,10 @@ There's two kinds of cards we're sending to arvo. A `%hiss` move tells
78`%eyre` to make an HTTP request. It expects a `(unit iden)`, which will
79`%eyre` to make an HTTP request. It expects a `(unit iden)`, which will
79be null here because we aren't doing any authentication; a mark, in this
80be null here because we aren't doing any authentication; a mark, in this
80case the http request mark `&httr`; and some data in the form of a
81case the http request mark `&httr`; and some data in the form of a
81−`cage`, which is a `{mark vase}`. This is confusing, so the mold in the
82+`cage`, which is a `[mark vase]`. This is confusing, so the mold in the
82code quoted above includes a bunch of otherwise unnecessary faces for
83code quoted above includes a bunch of otherwise unnecessary faces for
83−the purpose of illustration. Compare: `{$hiss p/(unit iden) q/mark
84+the purpose of illustration. Compare: `[%hiss p=(unit iden) q=mark
84−r/cage}` from `zuse`.
85+r=cage]` from `zuse`.
85
86
86> You can grep zuse.hoon and arvo.hoon for most of these definitions.
87> You can grep zuse.hoon and arvo.hoon for most of these definitions.
87> However, beware the ambiguity surrounding "hiss": there's ++hiss in
88> However, beware the ambiguity surrounding "hiss": there's ++hiss in
@@ -98,7 +99,7 @@ r/cage}` from `zuse`.
98A `purl` is a parsed url structure, which can be created with `++epur`,
99A `purl` is a parsed url structure, which can be created with `++epur`,
99which is a function that takes a url as text and parses it into a `(unit
100which is a function that takes a url as text and parses it into a `(unit
100purl)`. Thus, the result is null if and only if the url is malformed.
101purl)`. Thus, the result is null if and only if the url is malformed.
101−'Purl' is also the mark which will be applied to this result.
102+'Purl' is also the mark which will be applied to this result.
102
103
103When you send this request, you can expect a `%sigh` with the
104When you send this request, you can expect a `%sigh` with the
104response, which we handle later on in `++sigh-httr`.
105response, which we handle later on in `++sigh-httr`.
@@ -113,7 +114,7 @@ produce a `%wake` when the time comes.
113Let's take a look at our state:
114Let's take a look at our state:
114
115
115```
116```
116−|_ {hid/bowl on/_| in-progress=_| target/@t}
117+|_ [hid=bowl:gall on=_| in-progress=_| target=@t}
117```
118```
118
119
119We have three pieces of app-specific state. `target` is the url
120We have three pieces of app-specific state. `target` is the url
@@ -157,7 +158,7 @@ Here's the move that sends the HTTP request:
157> ~]` and `\`[a b c]` is `[~ a b c]`. These may be mixed and matched to
158> ~]` and `\`[a b c]` is `[~ a b c]`. These may be mixed and matched to
158> create various convoluted structures and emojis.
159> create various convoluted structures and emojis.
159
160
160−The correspondence between this move and `{bone card}` can be hard to
161+The correspondence between this move and `[bone card]` can be hard to
161visualize on one line. Here it is more pedantically:
162visualize on one line. Here it is more pedantically:
162
163
163```
164```
docs/arvo/marks.md → docs/tutorials/gall/marks.umdrenamed+9−8
@@ -1,9 +1,10 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3−next: true
3+ next/'true'
4−sort: 16
4+ sort/'4'
5−title: Marks
5+ title/'Marks'
6−---
6+ ==
7+;>
7
8
8# Marks
9# Marks
9
10
@@ -18,10 +19,10 @@ text, but there's no predefined mark for it. Let's put the following code in:
18
19
19```
20```
20/? 314
21/? 314
21−|_ cod/@t
22+|_ cod=@t
22++ grab
23++ grab
23 |%
24 |%
24− ++ atom |=(arg/@ `@t`(scot %ud arg))
25+ ++ atom |=(arg=@ `@t`(scot %ud arg))
25 --
26 --
26++ grow
27++ grow
27 |%
28 |%
docs/arvo/network.md → docs/tutorials/gall/network.umdrenamed+77−86
@@ -1,44 +1,44 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3−next: false
3+ next/'true'
4−sort: 13
4+ sort/'1'
5−title: Network messages
5+ title/'Network messages'
6−---
6+ ==
7+;>
7
8
8−Network messages
9+# Network messages
9−================
10
10
11−Now we've learned enough Hoon to do more interesting things. Let's get
11+In the following we assume that you have some knowledge of Hoon. If you don't, check out chapters 1 and 2 of the Hoon tutorial and check back when you're ready.
12−our planets to talk to each other.
13
12
14−All we've written up until now are just shell commands that produce a value and
15−then disappear. To listen for and receive messages from other planets, we'll
13+Let's get our planets to talk to each other. To listen for and receive messages from other planets, we'll need an app. Let's look at a very simple one, `echo.hoon`:
16−need an app. Let's look at a very simple one, `echo.hoon`:
17
14
15+```
18 :: Accepts any noun from dojo and prints it out
16 :: Accepts any noun from dojo and prints it out
19 ::
17 ::
20 :::: /===/app/echo/hoon
18 :::: /===/app/echo/hoon
21 ::
19 ::
22 !: :: enables debug printfs
20 !: :: enables debug printfs
23 |% :: forms a core with subject as payload
21 |% :: forms a core with subject as payload
24− ++ move {bone card} :: defines echo app's arvo move mold
22+ +$ move [bone card] :: defines echo app's arvo move mold
25− ++ card $% $~ :: defines card (data) mold as null tagged union
23+ +$ card $% $~ :: defines card (data) mold as null tagged union
26 == :: end of mold definition; see $%
24 == :: end of mold definition; see $%
27 -- :: end of card arm definition
25 -- :: end of card arm definition
28 :: ::
26 :: ::
29− |_ {bow/bowl:gall $~} :: forms a core with bowl (app state) as sample
27+ |_ [bow=bowl:gall $~] :: forms a core with bowl (app state) as sample
30 ++ poke-noun :: begin definition of poke-noun arm
28 ++ poke-noun :: begin definition of poke-noun arm
31− |= non/* :: forms a gate which accepts any noun
29+ |= non=* :: forms a gate which accepts any noun
32− ^- {(list move) _+>.$} :: casts product to mold of moves and context
30+ ^- [(list move) _+>.$] :: casts product to mold of moves and context
33 ~& echo+noun+non :: debug printf, i.e. '[%echo %noun *]'
31 ~& echo+noun+non :: debug printf, i.e. '[%echo %noun *]'
34 [~ +>.$] :: produce a cell of empty list and our state
32 [~ +>.$] :: produce a cell of empty list and our state
35 -- :: end of poke-noun arm definition
33 -- :: end of poke-noun arm definition
34+```
36
35
37This is a very simple app that does only one thing. If you poke it with
36This is a very simple app that does only one thing. If you poke it with
38a value, it prints that value out. To try this out, you have to start
37a value, it prints that value out. To try this out, you have to start
39the app, then you can poke it from the command line with the following
38the app, then you can poke it from the command line with the following
40commands:
39commands:
41
40
41+```
42 ~fintud-macrep:dojo> |start %echo
42 ~fintud-macrep:dojo> |start %echo
43 >=
43 >=
44 ~fintud-macrep:dojo> :echo 5
44 ~fintud-macrep:dojo> :echo 5
@@ -47,9 +47,10 @@ commands:
47 ~fintud-macrep:dojo> :echo [1 2]
47 ~fintud-macrep:dojo> :echo [1 2]
48 [%echo %noun [1 2]]
48 [%echo %noun [1 2]]
49 >=
49 >=
50+```
50
51
51> There is currently a bug where the `[%echo %noun *]` lines are printed *above*
52> There is currently a bug where the `[%echo %noun *]` lines are printed *above*
52−> the line you entered, so your output may not look exactly like this. `>=`
53+> the line you entered, so your output may not look exactly like this. `>=`
53> means that a command was successfully received and executed.
54> means that a command was successfully received and executed.
54
55
55Most of the app code should be simple enough to guess its function. The
56Most of the app code should be simple enough to guess its function. The
@@ -60,16 +61,16 @@ it by sending it messages. The most straightforward way to do that is to poke it
60from the command line, which we we did with `:echo 5`
61from the command line, which we we did with `:echo 5`
61(`:[app-name] [argument(s)]`).
62(`:[app-name] [argument(s)]`).
62
63
63−In this case, `++poke-noun` takes an argument (*sample*) `arg` and
64+In this case, `++poke-noun` takes an argument (*sample*) `arg` and
64−prints it to dojo with `~&` ([sigpam](../../hoon/rune/sig/pam/)).
65+prints it to dojo with `~&` ([sigpam](../../hoon/rune/sig/pam/)).
65−This is an unusual rune that formally "does nothing", but the interpreter
66+This is an unusual rune that formally "does nothing", but the interpreter
66detects it and printfs the first child, before executing the second as if the
67detects it and printfs the first child, before executing the second as if the
67−first didn't exist. This is a slightly hacky way of printing to the console,
68+first didn't exist. This is a slightly hacky way of printing to the console,
68but we'll get to the correct way later on.
69but we'll get to the correct way later on.
69
70
70But what does `++poke-noun` produce? Recall that `^-` casts to a type. In this
71But what does `++poke-noun` produce? Recall that `^-` casts to a type. In this
71−case, it's declaring that the end result (*product*) of the function
72+case, it's declaring that the end result (*product*) of the function
72−(`++poke-noun`'s *gate*) will be of type `{(list) _+>.$}`. But what does this
73+(`++poke-noun`'s *gate*) will be of type `[(list) _+>.$]`. But what does this
73mean?
74mean?
74
75
75The phrase to remember is "a list of moves and our state". Urbit is a message
76The phrase to remember is "a list of moves and our state". Urbit is a message
@@ -88,31 +89,32 @@ Let's look at another example (edit your code in
88`/app/examples/echo/hoon` to reflect the code below). Say we want to
89`/app/examples/echo/hoon` to reflect the code below). Say we want to
89only accept a number, and then print out the square of that number.
90only accept a number, and then print out the square of that number.
90
91
92+```
91 :: Accepts an atom from the dojo and squares it.
93 :: Accepts an atom from the dojo and squares it.
92 ::
94 ::
93 :::: /===/app/square/hoon
95 :::: /===/app/square/hoon
94 ::
96 ::
95− !:
97+ !:
96− |% ::> no moves in :square
98+ |% :: no moves in :square
97− ++ move {bone card} ::> no cards in :square
99+ +$ move [bone card] :: no cards in :square
98− ++ card $% $~
100+ +$ card $% $~
99− ==
101+ ==
100− --
102+ --
101− :: ::< stateless
103+ :: :: stateless
102− |_ {bow/bowl:gall $~}
104+ |_ [bow=bowl:gall $~]
103 ++ poke-atom
105 ++ poke-atom
104− |= tom/@
106+ |= tom=@
105− ^- {(list move) _+>.$}
107+ ^- [(list move) _+>.$]
106 ~& square+(mul tom tom)
108 ~& square+(mul tom tom)
107− [~ +>.$]
109+ [~ +>.$]
108− --
110+ --
111+```
109
112
110A few things have changed. Firstly, we no longer accept arbitrary nouns because
113A few things have changed. Firstly, we no longer accept arbitrary nouns because
111we can only square atoms (integers, in this case an unsigned one). Thus, our
114we can only square atoms (integers, in this case an unsigned one). Thus, our
112argument is now `tom/@`. Secondly, it's `++poke-atom` rather than `++poke-noun`.
115argument is now `tom/@`. Secondly, it's `++poke-atom` rather than `++poke-noun`.
113
116
114−Intro to marks
117+## Intro to marks
115−==============
116
118
117Are there other `++poke`s? Yes. In fact, `noun` and `atom` are just two
119Are there other `++poke`s? Yes. In fact, `noun` and `atom` are just two
118of arbitrarily many "marks". A mark is fundamentally a type definition,
120of arbitrarily many "marks". A mark is fundamentally a type definition,
@@ -132,6 +134,7 @@ command line is by default marked with `noun`. In this case, the app is
132expecting an atom, so we have to explicitly mark the data with `atom`
134expecting an atom, so we have to explicitly mark the data with `atom`
133using `&[mark]`. Try the following commands:
135using `&[mark]`. Try the following commands:
134
136
137+```
135 ~fintud-macrep:dojo> |start %square
138 ~fintud-macrep:dojo> |start %square
136 >=
139 >=
137 ~fintud-macrep:dojo> :square 6
140 ~fintud-macrep:dojo> :square 6
@@ -139,47 +142,47 @@ using `&[mark]`. Try the following commands:
139 ~fintud-macrep:dojo> :square &atom 6
142 ~fintud-macrep:dojo> :square &atom 6
140 [%square 36]
143 [%square 36]
141 >=
144 >=
145+```
142
146
143> Recall the bug where `%square` may get printed above the input line.
147> Recall the bug where `%square` may get printed above the input line.
144
148
145Marks are powerful, and they're the backbone of Urbit's data pipeline,
149Marks are powerful, and they're the backbone of Urbit's data pipeline,
146so we'll be getting quite used to them.
150so we'll be getting quite used to them.
147
151
148−**Exercise**:
152+*Exercise*:
149
153
150−- Write an app that computes fizzbuzz on its input (as in the previous
154+- Write an app that computes fizzbuzz on its input (as in the previous section).
151− section).
152
155
153−Sending a message to another urbit
156+## Sending a message to another urbit
154−==================================
155
157
156Let's write our first network message! Here's `examples/app/pong.hoon`:
158Let's write our first network message! Here's `examples/app/pong.hoon`:
157
159
160+```
158− :: Allows one urbit to send the string 'Pong' to
161+ :: Allows one urbit to send the string 'Pong' to
159 :: another urbit.
162 :: another urbit.
160 ::
163 ::
161 :::: /===/app/pong/hoon
164 :::: /===/app/pong/hoon
162 ::
165 ::
163 !:
166 !:
164 |%
167 |%
165− ++ move {bone card}
168+ +$ move [bone card]
166− ++ card $% {$poke wire dock poke-contents}
169+ +$ card $% [$poke wire dock poke-contents]
167 ==
170 ==
168− ++ poke-contents $% {$atom @}
171+ +$ poke-contents $% [$atom @]
169 ==
172 ==
170 --
173 --
171− |_ {bow/bowl:gall $~} ::< stateless
174+ |_ [bow=bowl:gall $~] :: stateless
172 ::
175 ::
173 ++ poke-urbit
176 ++ poke-urbit
174− |= to/ship
177+ |= to=ship
175− ^- {(list move) _+>.$}
178+ ^- [(list move) _+>.$]
176 ~& pong+'Outgoing pong!'
179 ~& pong+'Outgoing pong!'
177 :_ +>.$
180 :_ +>.$
178 ~[[ost.bow %poke /sending [to dap.bow] %atom 'Pong']]
181 ~[[ost.bow %poke /sending [to dap.bow] %atom 'Pong']]
179 ::
182 ::
180 ++ poke-atom
183 ++ poke-atom
181− |= tom/@
184+ |= tom=@
182− ^- {(list move) _+>.$}
185+ ^- [(list move) _+>.$]
183 ~& pong+'Incoming pong!'
186 ~& pong+'Incoming pong!'
184 ~& pong+received+`@t`tom
187 ~& pong+received+`@t`tom
185 [~ +>.$]
188 [~ +>.$]
@@ -187,13 +190,17 @@ Let's write our first network message! Here's `examples/app/pong.hoon`:
187 ++ coup |=(* [~ +>.$])
190 ++ coup |=(* [~ +>.$])
188 ::
191 ::
189 --
192 --
190−
193+```
194+
195+
191Run it with these commands:
196Run it with these commands:
192
197
198+```
193 ~fintud-macrep:dojo> |start %pong
199 ~fintud-macrep:dojo> |start %pong
194 >=
200 >=
195 ~fintud-macrep:dojo> :pong &urbit ~sampel-sipnym
201 ~fintud-macrep:dojo> :pong &urbit ~sampel-sipnym
196 >=
202 >=
203+```
197
204
198Replace `~sampel-sipnym` with another urbit. The easiest thing to do is to start
205Replace `~sampel-sipnym` with another urbit. The easiest thing to do is to start
199a comet, a free and disposable Urbit identity. If you don't know how to start a
206a comet, a free and disposable Urbit identity. If you don't know how to start a
@@ -201,23 +208,17 @@ comet, see [the user setup section](/docs/using/setup/). Don't forget to start
201the `%pong` app on that urbit, too. You should see, on the foreign
208the `%pong` app on that urbit, too. You should see, on the foreign
202urbit, this output:
209urbit, this output:
203
210
211+```
204 [%pong 'Incoming pong!']
212 [%pong 'Incoming pong!']
205 [%pong %received 'Pong']
213 [%pong %received 'Pong']
214+```
206
215
207Most of the code should be straightforward. In `++poke-atom`, the only new thing
216Most of the code should be straightforward. In `++poke-atom`, the only new thing
208−is the expression `` `@t`tom ``, which is *casting* the argument `tom` to type
217+is the expression `` `@t`tom ``, which is *casting* the argument `tom` to type
209−`@t`. As we already know, `@t` is the type of "cord" (text string). In Hoon,
218+`@t`. As we already know, `@t` is the type of "cord" (text string).
210−another way to perform a kind of casting is to use a type as a function, like
211−this: `(@t tom)`. When types are called like this, they are called "clams",
212−and they serve as validator functions-- that is, functions whose domain is all
213−nouns, and range is the given type (in this case, `@t`). Clams will "bunt" the
214−default value of the mold whereas casts (`@t`tom) may `nest-fail` if the
215−argument passed to it does not fit. An example of such a failure case is
216−passing a cell to an atom: `` `@`[1 2] ``. Using a clam here instead
217−(`(@ [1 2])`) will bunt the default value of `@`, which is `0`. Try it in dojo!
218
219
219The more interesting part is in `++poke-urbit`. The `urbit` mark is an urbit
220The more interesting part is in `++poke-urbit`. The `urbit` mark is an urbit
220−identity, and the Hoon type associated with it is `ship` or `@p` (the "p"
221+identity, and the Hoon type associated with it is `ship` or `@p` (the "p"
221stands for "phonetic base").
222stands for "phonetic base").
222
223
223Recall that in a `++poke` arm we produce "a list of moves and our state". Until
224Recall that in a `++poke` arm we produce "a list of moves and our state". Until
@@ -225,7 +226,9 @@ now, we've left the list of moves empty, since we haven't wanted to tell Arvo to
225do anything in particular. Now we want to send a message to another urbit. Thus,
226do anything in particular. Now we want to send a message to another urbit. Thus,
226we produce a list with one element:
227we produce a list with one element:
227
228
229+```
228 ~[[ost.bow %poke /sending [to dap.bow] %atom 'Pong]]
230 ~[[ost.bow %poke /sending [to dap.bow] %atom 'Pong]]
231+```
229
232
230### Moves
233### Moves
231
234
@@ -240,7 +243,7 @@ Let's walk through each of these elements step by step.
240#### Bones ("cause")
243#### Bones ("cause")
241
244
242If you look up `++bone` in `hoon.hoon`, you'll see that it's a number (`@ud`),
245If you look up `++bone` in `hoon.hoon`, you'll see that it's a number (`@ud`),
243−and that it's an opaque reference to a duct. `++duct` in `hoon.hoon` is a list
246+and that it's an opaque reference to a duct. `++duct` in `hoon.hoon` is a list
244of `wire`s, where `++wire` is an alias for `++path`. `++path` is a list of
247of `wire`s, where `++wire` is an alias for `++path`. `++path` is a list of
245`++knot`s, which are ASCII text. Thus, a duct is a list of paths, and a bone is
248`++knot`s, which are ASCII text. Thus, a duct is a list of paths, and a bone is
246an opaque reference to it (in the same way that a Unix file descriptor is an
249an opaque reference to it (in the same way that a Unix file descriptor is an
@@ -263,9 +266,9 @@ Furthermore, when one module sends a message to another kernel module or
263application, it also sends along the duct it was given with its new wire tacked
266application, it also sends along the duct it was given with its new wire tacked
264onto the top. Now the duct has two entries, with the unix event on the bottom
267onto the top. Now the duct has two entries, with the unix event on the bottom
265and the kernel module that handled it on top. This process can continue
268and the kernel module that handled it on top. This process can continue
266−indefinitely, pushing more and more wires onto the top of the duct. When an
269+indefinitely, pushing more and more wires onto the top of the duct. When an
267−entity finally produces a result, a wire is popped off the duct, and the result
270+entity finally produces a result, a wire is popped off the duct, and the result
268−is passed all the way back down, repeating the process of wire popping
271+is passed all the way back down, repeating the process of wire popping
269sequentially until the bottom of the duct is reached.
272sequentially until the bottom of the duct is reached.
270
273
271In effect, a duct is an Arvo-level call stack. It's worth noting that while in
274In effect, a duct is an Arvo-level call stack. It's worth noting that while in
@@ -311,23 +314,13 @@ urbit as for sending messages between apps on different urbits.
311> that the `++poke` was called. We don't do anything with this
314> that the `++poke` was called. We don't do anything with this
312> information right now, but we could.
315> information right now, but we could.
313
316
314−**Exercises**:
317+*Exercises*:
315
318
316−- Extend either of the apps in the first two exercises to accept input
319+- Extend either of the apps in the first two exercises to accept input over the network in the same way as `pong`.
317− over the network in the same way as `pong`.
318
320
319−- Modify `pong.hoon` to print out a message when it receives
321+- Modify `pong.hoon` to print out a message when it receives acknowledgement.
320− acknowledgement.
321
322
322−- Write two apps, `even` and `odd`. When you pass an atom to `even`,
323+- Write two apps, `even` and `odd`. When you pass an atom to `even`, check whether it's even. If so, divide it by two and recurse; otherwise, poke `odd` with it. When `odd` receives an atom, check whether it's equal to one. If so, terminate, printing "%success". Otherwise, check whether it's odd. If so, multiply it by three, add one, and recurse; otherwise, poke `even` with it. When either app receives a number, print it out along with the name of the app. In the end, you should be able to watch Collatz's conjecture play out between the two apps. Sample output:
323− check whether it's even. If so, divide it by two and recurse;
324− otherwise, poke `odd` with it. When `odd` receives an atom, check
325− whether it's equal to one. If so, terminate, printing "%success".
326− Otherwise, check whether it's odd. If so, multiply it by three, add
327− one, and recurse; otherwise, poke `even` with it. When either app
328− receives a number, print it out along with the name of the app. In
329− the end, you should be able to watch Collatz's conjecture play out
330− between the two apps. Sample output:
331
324
332```
325```
333~fintud-macrep:dojo> :even &atom 18
326~fintud-macrep:dojo> :even &atom 18
@@ -354,6 +347,4 @@ urbit as for sending messages between apps on different urbits.
354%success
347%success
355```
348```
356
349
357−- Put `even` and `odd` on two separate urbits and pass the messages
350+- Put `even` and `odd` on two separate urbits and pass the messages over the network. Post a link to a working solution in :talk to receive a cookie.
358− over the network. Post a link to a working solution in :talk to
359− receive a cookie.
docs/arvo/security-driver.md → docs/tutorials/gall/security-driver.umdrenamed+29−44
@@ -1,9 +1,10 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3−next: false
3+ next/'true'
4−sort: 20
4+ sort/'8'
5−title: Security drivers
5+ title/'Security Drivers'
6−---
6+ ==
7+;>
7
8
8# Security drivers
9# Security drivers
9
10
@@ -36,7 +37,9 @@ Here, we'll build a connector for the Github API v3. The
36simplest way to interact with the Github API is to just fetch
37simplest way to interact with the Github API is to just fetch
37https://api.github.com from the dojo:
38https://api.github.com from the dojo:
38
39
40+```
39 ~your-urbit:dojo> +https://api.github.com
41 ~your-urbit:dojo> +https://api.github.com
42+```
40
43
41Github exposes a few endpoints to the general web, and the root
44Github exposes a few endpoints to the general web, and the root
42endpoint is one of them. This gives you a textual representation
45endpoint is one of them. This gives you a textual representation
@@ -60,7 +63,7 @@ Here's a simple security driver:
60 ::
63 ::
61/+ basic-auth
64/+ basic-auth
62!:
65!:
63−|_ {bal/(bale keys:basic-auth) $~}
66+|_ [bal=(bale keys:basic-auth) $~]
64++ aut ~(standard basic-auth bal ~)
67++ aut ~(standard basic-auth bal ~)
65++ filter-request out-adding-header:aut
68++ filter-request out-adding-header:aut
66--
69--
@@ -87,7 +90,9 @@ you're logged in as.
87
90
88You can similarly POST:
91You can similarly POST:
89
92
93+```
90 ~your-urbit:dojo> +https://api.github.com/gists &json _(cork poja need) '{"files":{"file1.txt":{"content":"can\'t stop the signal"}}}'
94 ~your-urbit:dojo> +https://api.github.com/gists &json _(cork poja need) '{"files":{"file1.txt":{"content":"can\'t stop the signal"}}}'
95+```
91
96
92This creates a gist, go to `https://gist.github.com/<username>` to
97This creates a gist, go to `https://gist.github.com/<username>` to
93see it.
98see it.
@@ -101,7 +106,9 @@ can send data of any mark as long as it has a conversion path to
101Let's take a look at the code and see if we can figure out what's
106Let's take a look at the code and see if we can figure out what's
102happening here:
107happening here:
103
108
109+```
104 /+ basic-auth
110 /+ basic-auth
111+```
105
112
106First, we load a library called `basic-auth`. This library
113First, we load a library called `basic-auth`. This library
107exposes two items. `keys` is the type of the basic auth key,
114exposes two items. `keys` is the type of the basic auth key,
@@ -115,22 +122,17 @@ in `bale`. `bale` contains:
115- `our`, our urbit name
122- `our`, our urbit name
116- `now`, the current time
123- `now`, the current time
117- `eny`, 256 bits of entropy
124- `eny`, 256 bits of entropy
118−- `byk`, the urbit, desk and case which the security driver is
125+- `byk`, the urbit, desk and case which the security driver is running from
119− running from
120- `usr`, the particular identity we're logging in with
126- `usr`, the particular identity we're logging in with
121- `dom`, the site we're accessing
127- `dom`, the site we're accessing
122−- `key`, the secrets required to authenticate requests. The type
123− for this entry is supplied by the programmer as the argument to
128+- `key`, the secrets required to authenticate requests. The type for this entry is supplied by the programmer as the argument to `++bale`. Thus, in our case, `key` in our bale is of type `keys:basic-auth`.
124− `++bale`. Thus, in our case, `key` in our bale is of type
125− `keys:basic-auth`.
126
129
127Additionally, a security driver contains at least one out of the
130Additionally, a security driver contains at least one out of the
128five "special" arms:
131five "special" arms:
129
132
130−- `++filter-request` is a function which takes a hiss (http
131− request) and produces a `sec-move` (defined in zuse), which is
133+- `++filter-request` is a function which takes a hiss (http request) and produces a `sec-move` (defined in zuse), which is one of:
132− one of:
133
134
135+```
134 * `[%send hiss]`, which sends the new hiss. This is the
136 * `[%send hiss]`, which sends the new hiss. This is the
135 case in, for example, basic auth, where all we need to do is
137 case in, for example, basic auth, where all we need to do is
136 add an extra header to the request.
138 add an extra header to the request.
@@ -141,32 +143,19 @@ five "special" arms:
141 the authentication process.
143 the authentication process.
142 * `[%redo ~]`, which redoes the request.
144 * `[%redo ~]`, which redoes the request.
143
145
144− `%eyre` calls `++filter-request` just before sending an HTTP
146+ * `%eyre` calls `++filter-request` just before sending an HTTP
145 request to the specified domain. This allows the security
147 request to the specified domain. This allows the security
146 driver to filter the requests, decorating them with
148 driver to filter the requests, decorating them with
147 authentication data.
149 authentication data.
150+```
148
151
149−- `++filter-response` is a function which takes an httr and
152+- `++filter-response` is a function which takes an httr and produces a `sec-move`. `%eyre` calls it after receiving an HTTP response from the specified domain. This allows the security driver to handle authentication errors, commonly caused by expired tokens, and retry the request.
150− produces a `sec-move`. `%eyre` calls it after receiving an
151− HTTP response from the specified domain. This allows the
152− security driver to handle authentication errors, commonly
153− caused by expired tokens, and retry the request.
154
153
155−- `++receive-auth-query-string` is a function that takes a `quay`
154+- `++receive-auth-query-string` is a function that takes a `quay` (list of query parameters) and produces a `sec-move`. `%eyre` calls it when it receives a request on the callback url. Generally, this happens in OAuth after the user has granted access to the urbit app, and the service makes a request to the callback url with the code. The security driver should then make a request to convert the code into an access token.
156− (list of query parameters) and produces a `sec-move`. `%eyre`
157− calls it when it receives a request on the callback url.
158− Generally, this happens in OAuth after the user has granted
159− access to the urbit app, and the service makes a request to the
160− callback url with the code. The security driver should then
161− make a request to convert the code into an access token.
162
155
163−- `++receive-auth-response` is a function that takes an httr and
156+- `++receive-auth-response` is a function that takes an httr and produces a `sec-move`. `%eyre` calls it when it gets a response to the request made in `++receive-auth-query-string`.
164− produces a `sec-move`. `%eyre` calls it when it gets a
165− response to the request made in `++receive-auth-query-string`.
166
157
167−- `++update` is a function which converts old state to a new
168− format when the security driver gets updated. If you want to
158+- `++update` is a function which converts old state to a new format when the security driver gets updated. If you want to just get rid of the old state, define `++discard-state` as `~`.
169− just get rid of the old state, define `++discard-state` as `~`.
170
159
171For basic auth, we only have to worry about `++filter-request`,
160For basic auth, we only have to worry about `++filter-request`,
172since all we need to do is add the correct header to each
161since all we need to do is add the correct header to each
@@ -189,15 +178,11 @@ complicated than basic auth, but not hugely so.
189
178
190The basic steps for OAuth2 are these:
179The basic steps for OAuth2 are these:
191
180
192−- create an app and get its client id and client secret (on
181+- create an app and get its client id and client secret (on Github)
193− Github)
194- store these in Urbit (with `|init-oauth2`)
182- store these in Urbit (with `|init-oauth2`)
195−- try to make a request that requires authentication. The
196− security driver should prompt you to visit a particular url.
183+- try to make a request that requires authentication. The security driver should prompt you to visit a particular url.
197−- visit the url and click "authorize", which gives the app access
184+- visit the url and click "authorize", which gives the app access to your account
198− to your account
199−- the security driver will turn the code it receives into an
185+- the security driver will turn the code it receives into an access token
200− access token
201- on every request, include that access token
186- on every request, include that access token
202
187
203Creating an app is easy and
188Creating an app is easy and
@@ -222,7 +207,7 @@ Now we need a security driver. Use this:
222!:
207!:
223::::
208::::
224 ::
209 ::
225−|_ {bal/(bale keys:oauth2) tok/token:oauth2}
210+|_ [bal=(bale keys:oauth2) tok=token:oauth2]
226++ scopes :: comment out scopes to taste
211++ scopes :: comment out scopes to taste
227 :~ 'user' 'user:email' 'user:follow' 'public_repo' 'repo'
212 :~ 'user' 'user:email' 'user:follow' 'public_repo' 'repo'
228 'repo_deployment' 'repo:status' 'delete_repo' 'notifications'
213 'repo_deployment' 'repo:status' 'delete_repo' 'notifications'
docs/arvo/state.md → docs/tutorials/gall/state.umdrenamed+38−33
@@ -1,51 +1,54 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3−next: true
3+ next/'true'
4−sort: 14
4+ sort/'2'
5−title: State
5+ title/'State'
6−---
6+ ==
7+;>
7
8
8−State
9+# State
9−=====
10
10
11In the last section we built a few small apps that sent moves. These apps were
11In the last section we built a few small apps that sent moves. These apps were
12entirely stateless, however. Most useful apps require some amount of state.
12entirely stateless, however. Most useful apps require some amount of state.
13Let's build a trivial stateful app. It'll keep a running the sum of all the
13Let's build a trivial stateful app. It'll keep a running the sum of all the
14atoms we poke it with. Here's `examples/app/sum.hoon`:
14atoms we poke it with. Here's `examples/app/sum.hoon`:
15−
15+
16+```
16− :: Keeps track of the sum of all the atoms it has been
17+ :: Keeps track of the sum of all the atoms it has been
17− :: poked with and prints the sum out
18+ :: poked with and prints the sum out
18 ::
19 ::
19 :::: /===/app/sum/hoon
20 :::: /===/app/sum/hoon
20 ::
21 ::
21 !:
22 !:
22 |%
23 |%
23− ++ move {bone card}
24+ +$ move [bone card]
24− ++ card $% $~
25+ +$ card $% $~
25− ==
26+ ==
26 --
27 --
27− |_ {bow/bowl sum/@}
28+ |_ [bow=bowl:gall sum=@]
28 ::
29 ::
29− ++ poke-atom
30+ ++ poke-atom
30− |= tom/@
31+ |= tom=@
31− ^- {(list move) _+>.$}
32+ ^- [(list move) _+>.$]
32 ~& sum+(add sum tom)
33 ~& sum+(add sum tom)
33 [~ +>.$(sum (add sum tom))]
34 [~ +>.$(sum (add sum tom))]
34 ::
35 ::
35− ++ coup
36+ ++ coup
36− |= {wir/wire err/(unit tang)}
37+ |= [wir=wire err=(unit tang)]
37− ^- {(list move) _+>.$}
38+ ^- [(list move) _+>.$]
38 ?~ err
39 ?~ err
39− ~& sum+success+'Poke succeeded!'
40+ ~& sum+success+'Poke succeeded!'
40− [~ +>.$]
41+ [~ +>.$]
41 ~& sum+error+'Poke failed. Error:'
42 ~& sum+error+'Poke failed. Error:'
42 ~& sum+error+err
43 ~& sum+error+err
43 [~ +>.$]
44 [~ +>.$]
44 ::
45 ::
45 --
46 --
47+```
46
48
47We can start it with `|start %sum`, and then run it:
49We can start it with `|start %sum`, and then run it:
48
50
51+```
49 ~fintud-macrep:dojo> :sum &atom 5
52 ~fintud-macrep:dojo> :sum &atom 5
50 [%sum 5]
53 [%sum 5]
51 >=
54 >=
@@ -55,6 +58,7 @@ We can start it with `|start %sum`, and then run it:
55 ~fintud-macrep:dojo> :sum &atom 15
58 ~fintud-macrep:dojo> :sum &atom 15
56 [%sum 22]
59 [%sum 22]
57 >=
60 >=
61+```
58
62
59We can see that app state is being saved, but when, where, and how?
63We can see that app state is being saved, but when, where, and how?
60
64
@@ -86,11 +90,11 @@ of things in `++bowl`, search for `++ bowl` (note: two spaces) in
86
90
87> This is, perhaps, the most common way to learn Hoon. The easiest way to learn
91> This is, perhaps, the most common way to learn Hoon. The easiest way to learn
88> about an identifier you see in code is to search in `/arvo/zuse.hoon` and
92> about an identifier you see in code is to search in `/arvo/zuse.hoon` and
89−> `/arvo/hoon.hoon` for it.\\ These "standard libraries" are usually simple to
90−> read. Since Urbit's codebase is less than 15000 lines of code combined,
93+> `/arvo/hoon.hoon` for it.\\ Urbit's codebase is less than 30000 lines of code
94+> combined,
91−> including the hoon parser, the compiler, and the `/arvo` microkernel, you can
95+> including the hoon parser, the compiler, and the `/arvo` microkernel, so you
96+> can
92> usually use the code and its comments as a reference doc.
97> usually use the code and its comments as a reference doc.
93−>
94> You can also read
98> You can also read
95> [zuse.hoon](https://github.com/urbit/arvo/blob/master/arvo/zuse.hoon) and
99> [zuse.hoon](https://github.com/urbit/arvo/blob/master/arvo/zuse.hoon) and
96> [hoon.hoon](https://github.com/urbit/arvo/blob/master/arvo/hoon.hoon) in your
100> [hoon.hoon](https://github.com/urbit/arvo/blob/master/arvo/hoon.hoon) in your
@@ -103,17 +107,17 @@ Unix filesystem, you can, but it's not needed for persistence. Urbit has
103transactional events, which makes it an [ACID operating
107transactional events, which makes it an [ACID operating
104system](https://en.wikipedia.org/wiki/ACID). Thus, you don't have to worry about
108system](https://en.wikipedia.org/wiki/ACID). Thus, you don't have to worry about
105persistence when programming in Urbit, or ever go through the hassle of having
109persistence when programming in Urbit, or ever go through the hassle of having
106−to set up and write to a database.
110+to set up and write to a database.
107
111
108−**Exercises**:
112+*Exercises*:
109
113
110−- Modify `:sum` to reset the counter when you poke it with 0.
114+- Modify `:sum` to reset the counter when you poke it with 0.
111
115
112−- Write an app called `last` that prints out the previous value you poked it with.
116+- Write an app called `last` that prints out the previous value you poked it with.
113− Sample output:
114
117
115−<!-- -->
118+Sample output:
116
119
120+```
117 ~fintud-macrep:dojo> :last 7
121 ~fintud-macrep:dojo> :last 7
118 [%last 0]
122 [%last 0]
119 >=
123 >=
@@ -122,3 +126,4 @@ to set up and write to a database.
122 >=
126 >=
123 ~fintud-macrep:dojo> :last 'howdy'
127 ~fintud-macrep:dojo> :last 'howdy'
124 [%last [1 2 3]]
128 [%last [1 2 3]]
129+```
docs/arvo/subscriptions.md → docs/tutorials/gall/subscriptions.umdrenamed+96−122
@@ -1,9 +1,10 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3−next: true
3+ next/'true'
4−sort: 15
4+ sort/'3'
5−title: Subscriptions
5+ title/'Subscriptions'
6−---
6+ ==
7+;>
7
8
8# Subscriptions
9# Subscriptions
9
10
@@ -16,172 +17,136 @@ that it's built into Arvo.
16Let's take a look at two apps, `:source` and `:sink`. First,
17Let's take a look at two apps, `:source` and `:sink`. First,
17`:source`:
18`:source`:
18
19
20+```
19− :: Sends subscription updates to sink.hoon
21+ :: Sends subscription updates to sink.hoon
20 ::
22 ::
21 :::: /===/app/source/hoon
23 :::: /===/app/source/hoon
22 ::
24 ::
23 !:
25 !:
24 ::
26 ::
25 |%
27 |%
26− ++ move {bone card}
28+ +$ move [bone card]
27− ++ card $% {$diff diff-contents}
29+ +$ card $% [%diff diff-contents]
28− ==
30+ ==
29− ++ diff-contents $% {$noun *}
31+ +$ diff-contents $% [%noun *]
30− ==
32+ ==
31 --
33 --
32 ::
34 ::
33− |_ {bow/bowl $~}
35+ |_ [bow=bowl:gall $~]
34 ::
36 ::
35− ++ poke-noun
37+ ++ poke-noun
36− |= non/*
38+ |= non=*
37− ^- {(list move) _+>.$}
39+ ^- [(list move) _+>.$]
38 :_ +>.$
40 :_ +>.$
39− %+ turn (prey /example-path bow)
41+ %+ turn (prey /example-path bow)
40− |=({o/bone *} [o %diff %noun non])
42+ |=({o=bone *} [o %diff %noun non])
41 ::
43 ::
42− ++ peer-example-path
44+ ++ peer-example-path
43 |= pax/path
45 |= pax/path
44− ^- {(list move) _+>.$}
46+ ^- [(list move) _+>.$]
45 ~& source+peer-notify+'Someone subscribed to you!'
47 ~& source+peer-notify+'Someone subscribed to you!'
46 ~& source+[ship+src.bow path+pax]
48 ~& source+[ship+src.bow path+pax]
47 [~ +>.$]
49 [~ +>.$]
48 ::
50 ::
49 ++ coup
51 ++ coup
50− |= {wir/wire err/(unit tang)}
52+ |= {wir=wire err=(unit tang)}
51− ^- {(list move) _+>.$}
53+ ^- [(list move) _+>.$]
52 ?~ err
54 ?~ err
53− ~& source+success+'Poke succeeded!'
55+ ~& source+success+'Poke succeeded!'
54− [~ +>.$]
56+ [~ +>.$]
55 ~& source+error+'Poke failed. Error:'
57 ~& source+error+'Poke failed. Error:'
56 ~& source+error+err
58 ~& source+error+err
57 [~ +>.$]
59 [~ +>.$]
58 ::
60 ::
59− ++ reap
61+ ++ reap
60− |= {wir/wire err/(unit tang)}
62+ |= [wir=wire err=(unit tang)]
61− ^- {(list move) _+>.$}
63+ ^- [(list move) _+>.$]
62 ?~ err
64 ?~ err
63− ~& source+success+'Peer succeeded!'
65+ ~& source+success+'Peer succeeded!'
64− [~ +>.$]
66+ [~ +>.$]
65 ~& source+error+'Peer failed. Error:'
67 ~& source+error+'Peer failed. Error:'
66 ~& source+error+err
68 ~& source+error+err
67 [~ +>.$]
69 [~ +>.$]
68 ::
70 ::
69 --
71 --
72+```
70
73
71And secondly, `:sink`:
74And secondly, `:sink`:
72
75
76+```
73− :: Sets up a simple subscription to source.hoon
77+ :: Sets up a simple subscription to source.hoon
74 ::
78 ::
75 :::: /===/app/sink/hoon
79 :::: /===/app/sink/hoon
76 ::
80 ::
77 !:
81 !:
78 |%
82 |%
79− ++ move {bone card}
83+ +$ move [bone card]
80− ++ card $% {$peer wire dock path}
84+ +$ card $% [%peer wire dock path]
81− {$pull wire dock $~}
85+ [%pull wire dock $~]
82− ==
86+ ==
83 --
87 --
84 ::
88 ::
85− |_ {bow/bowl val/?}
89+ |_ [bow=bowl:gall val=?]
86 ::
90 ::
87− ++ poke-noun
91+ ++ poke-noun
88− |= non/*
92+ |= non=*
89− ^- {(list move) _+>.$}
93+ ^- [(list move) _+>.$]
90 ?: &(=(%on non) val)
94 ?: &(=(%on non) val)
91− :_ +>.$(val |)
95+ :_ +>.$(val |)
92− :~ :* ost.bow
96+ :~ :* ost.bow
93− %peer
97+ %peer
94− /subscribe
98+ /subscribe
95− [our.bow %source]
99+ [our.bow %source]
96− /example-path
100+ /example-path
97− ==
101+ ==
98− ==
102+ ==
99 ?: &(=(%off non) !val)
103 ?: &(=(%off non) !val)
100− :_ +>.$(val &)
104+ :_ +>.$(val &)
101− ~[[ost.bow %pull /subscribe [our.bow %source] ~]]
105+ ~[[ost.bow %pull /subscribe [our.bow %source] ~]]
102 ~& ?: val
106 ~& ?: val
103− sink+unsubscribed+'You are now unsubscribed!'
107+ sink+unsubscribed+'You are now unsubscribed!'
104− sink+subscribed+'You are now subscribed!'
108+ sink+subscribed+'You are now subscribed!'
105 [~ +>.$]
109 [~ +>.$]
106 ::
110 ::
107− ++ diff-noun
111+ ++ diff-noun
108− |= {wir/wire non/*}
112+ |= [wir=wire non=*]
109− ^- {(list move) _+>.$}
113+ ^- [(list move) _+>.$]
110 ~& sink+received-data+'You got something!'
114 ~& sink+received-data+'You got something!'
111 ~& sink+data+non
115 ~& sink+data+non
112 [~ +>.$]
116 [~ +>.$]
113 ::
117 ::
114− ++ coup
118+ ++ coup
115− |= {wir/wire err/(unit tang)}
119+ |= [wir=wire err=(unit tang)]
116− ^- {(list move) _+>.$}
120+ ^- [(list move) _+>.$]
117 ?~ err
121 ?~ err
118− ~& sink+success+'Poke succeeded!'
122+ ~& sink+success+'Poke succeeded!'
119− [~ +>.$]
123+ [~ +>.$]
120 ~& sink+error+'Poke failed. Error:'
124 ~& sink+error+'Poke failed. Error:'
121 ~& sink+error+err
125 ~& sink+error+err
122 [~ +>.$]
126 [~ +>.$]
123 ::
127 ::
124− ++ reap
128+ ++ reap
125− |= {wir/wire err/(unit tang)}
129+ |= [wir=wire err=(unit tang)]
126− ^- {(list move) _+>.$}
130+ ^- [(list move) _+>.$]
127 ?~ err
131 ?~ err
128− ~& sink+success+'Peer succeeded!'
132+ ~& sink+success+'Peer succeeded!'
129− [~ +>.$]
133+ [~ +>.$]
130− ~& sink+error+'Peer f ailed. Error:'
134+ ~& sink+error+'Peer failed. Error:'
131 ~& sink+error+err
135 ~& sink+error+err
132 [~ +>.$]
136 [~ +>.$]
133 ::
137 ::
134 --
138 --
139+```
140+
141+Two notes:
142+
143+- `bowl` is the type of the system state within our app. For example, it includes things like `our`, the name of the host urbit, and `now`, the current time.
135
144
136−Cheat sheet:
145+- You may have noticed the separate `|%` ([barcen](../../hoon/rune/bar/cen/)) above the application core `|_` ([barcab](../../hoon/rune/bar/cab/). We usually put our types in another core on top of the application core. We can access these type from our `|_` because in `hoon.hoon` files, all cores are called against each other. (The shorthand for 'called' is `=>`.) Thus, the `|%` with the types is in the context of the `|_`, as it lies above it: `hoon.hoon` `=> |% w types => |_`
137−
138−- `&` (pam) can either be the boolean true (as can `%.y`, `0`), or
139− the irregular wide form of the `?&`
140− ([wutpam](../../hoon/rune/wut/pam)) rune, which computes
141− logical `AND` on its two children.
142−
143−- Similar to `&`,`|` is either the boolean false (along with `%.n` and
144− `1`), or the irregular short for of `?|`
145− ([wutbar](../../hoon/rune/wut/bar)), which computes logical `OR`
146− on its two children.
147−
148−- `!` is the irregular wide form of `?!`
149− ([wutzap](../../hoon/rune/wut/zap/)), which computes logical
150− `NOT` on its child.
151−
152−- `?~` ([wutsig](../../hoon/rune/wut/sig/)) is basically an
153− if-then-else that checks whether condition `p` is `~` (null). `?~`
154− is slightly different from `?:(~ %tru %fal)` in that `?~` reduces to
155− `?:($=(%type value) %tru %false)`. `$=`
156− ([buctis](../../hoon/rune/buc/tis/)) tests whether value `q` is
157− of type `p`.
158−<!-- One thing to watch out for in Hoon: if you do `?~`, it
159− affects the type of the conditional value: XXexample -->
160−
161−- `:_` ([colcab](../../hoon/rune/col/cab/)) is inverted `:-`: it
162− accepts `p` and `q`, and produces `[q p]`.
163−
164−- `++bowl` is the type of the system state within our app. For
165− example, it includes things like `our`, the name of the host urbit,
166− and `now`, the current time.
167−
168−- `$%` ([buccen](../../hoon/rune/buc/cen/)) is a type
169− constructor: it defines a new type, composed of `n` types that it is
170− passed. For example `$% @ * ^ ==` is the type of either `@`,
171− `*`, or a cell `^`.
172−<!-- XX this is a union, right? -->
173−
174−- You may have noticed the separate `|%`
175− ([barcen](../../hoon/rune/bar/cen/)) above the application core
176− `|_` ([barcab](../../hoon/rune/bar/cab/). We usually put our
177− types in another core on top of the application core. We can access
178− these type from our `|_` because in `hoon.hoon` files, all cores are
179− called against each other. (The shorthand for 'called' is `=>`.)
180− Thus, the `|%` with the types is in the context of the `|_`, as it
181− lies above it: `hoon.hoon` `=> |% w types => |_`
182
146
183Here's some sample output of the two working together:
147Here's some sample output of the two working together:
184
148
149+```
185 ~fintud-macrep:dojo> |start %source
150 ~fintud-macrep:dojo> |start %source
186 >=
151 >=
187 ~fintud-macrep:dojo> |start %sink
152 ~fintud-macrep:dojo> |start %sink
@@ -208,6 +173,7 @@ Here's some sample output of the two working together:
208 [%sink %received-data 'You got something!']
173 [%sink %received-data 'You got something!']
209 [%sink %data 7]
174 [%sink %data 7]
210 >=
175 >=
176+```
211
177
212### :source
178### :source
213
179
@@ -293,13 +259,15 @@ In `++poke-noun` we check our input to see both if it's `%on` and we're
293available (`val` is true). If so, we produce the move to subscribe to
259available (`val` is true). If so, we produce the move to subscribe to
294`:source`:
260`:source`:
295
261
262+```
296− :~ :* ost.bow
263+ :~ :* ost.bow
297− %peer
264+ %peer
298− /subscribe
265+ /subscribe
299− [our.bow %source]
266+ [our.bow %source]
300− /example-path
267+ /example-path
301− ==
268+ ==
302 ==
269 ==
270+```
303
271
304Also, in the preceding lines, we set `val` to false (`|`) with `+>.$(val |)`.
272Also, in the preceding lines, we set `val` to false (`|`) with `+>.$(val |)`.
305Remember that the `:_` constructs an inverted cell, with the first child
273Remember that the `:_` constructs an inverted cell, with the first child
@@ -312,8 +280,10 @@ Otherwise, if our input is `%off` and we're already subscribed (i.e. `val`
312is false), then we unsubscribe from `:source` and set `val` back to true (`&`),
280is false), then we unsubscribe from `:source` and set `val` back to true (`&`),
313again using our handy inverted cell constructor mold `:_`:
281again using our handy inverted cell constructor mold `:_`:
314
282
283+```
315− :_ +>.$(val &)
284+ :_ +>.$(val &)
316 ~[[ost.bow %pull /subscribe [our.bow %source] ~]]
285 ~[[ost.bow %pull /subscribe [our.bow %source] ~]]
286+```
317
287
318It's important to send over the same bone and wire (`/subscribe`) as the
288It's important to send over the same bone and wire (`/subscribe`) as the
319one we originally subscribed on.
289one we originally subscribed on.
@@ -322,18 +292,22 @@ If neither of these cases are true, then we print our current subscription
322state, based on whether `val` is true or false, and return a cell containing
292state, based on whether `val` is true or false, and return a cell containing
323a null list of moves and our unchanged app state:
293a null list of moves and our unchanged app state:
324
294
295+```
325− ~& ?: val
296+ ~& ?: val
326− sink+unsubscribed+'You are now unsubscribed!'
297+ sink+unsubscribed+'You are now unsubscribed!'
327− sink+subscribed+'You are now subscribed!'
298+ sink+subscribed+'You are now subscribed!'
328 [~ +>.$]
299 [~ +>.$]
300+```
329
301
330`++diff-noun` is called when we get a `%diff` update along a subscription with a
302`++diff-noun` is called when we get a `%diff` update along a subscription with a
331mark of `noun`. `++diff-noun` is given the wire that we originally passed with
303mark of `noun`. `++diff-noun` is given the wire that we originally passed with
332the `%peer` subscription request along and the data we got back. In our case we
304the `%peer` subscription request along and the data we got back. In our case we
333just print out the data:
305just print out the data:
334
306
307+```
335− ~& sink+received-data+'You got something!'
308+ ~& sink+received-data+'You got something!'
336− ~& sink+data+non
309+ ~& sink+data+non
310+```
337
311
338`++reap` is called when we receive an acknowledgment as to whether the
312`++reap` is called when we receive an acknowledgment as to whether the
339subscription was handled successfully. You can remember that `++reap` is the
313subscription was handled successfully. You can remember that `++reap` is the
docs/arvo/web-apps.md → docs/tutorials/gall/web-apps.umdrenamed+23−32
@@ -1,9 +1,10 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3−next: true
3+ next/'true'
4−sort: 17
4+ sort/'5'
5−title: Web apps
5+ title/'Web apps'
6−---
6+ ==
7+;>
7
8
8# Backend
9# Backend
9
10
@@ -25,16 +26,16 @@ Let's first checkout the app `/app/examples/click.hoon`:
25/? 314
26/? 314
26!:
27!:
27|%
28|%
28−++ move {bone $diff $mark *}
29+++ move [bone %diff %mark *]
29--
30--
30!:
31!:
31−|_ {hid/bowl clicks/@}
32+|_ [hid=bowl:gall clicks=@]
32++ poke-examples-click-click
33++ poke-examples-click-click
33 |= click/$click
34 |= click/$click
34 ~& [%poked +(clicks)]
35 ~& [%poked +(clicks)]
35 :_ +>.$(clicks +(clicks))
36 :_ +>.$(clicks +(clicks))
36 %+ turn (prey /the-path hid)
37 %+ turn (prey /the-path hid)
37− |=({o/bone *} [o %diff %examples-click-clicks +(clicks)])
38+ |=({o=bone *} [o %diff %examples-click-clicks +(clicks)])
38++ peer-the-path
39++ peer-the-path
39 |= pax/path
40 |= pax/path
40 [[[ost.hid %diff %examples-click-clicks clicks] ~] +>.$]
41 [[[ost.hid %diff %examples-click-clicks clicks] ~] +>.$]
@@ -51,19 +52,19 @@ number of clicks.
51Let's take a look at the new marks. Here's `/mar/examples/click/click.hoon`:
52Let's take a look at the new marks. Here's `/mar/examples/click/click.hoon`:
52
53
53```
54```
54−|_ click/$click
55+|_ click=%click
55++ grab
56++ grab
56 |%
57 |%
57 ++ noun |=(* %click)
58 ++ noun |=(* %click)
58 ++ json
59 ++ json
59− |= jon/^json
60+ |= jon=^json
60 ?> =('click' (need (so:jo jon)))
61 ?> =('click' (need (so:jo jon)))
61 %click
62 %click
62 --
63 --
63--
64--
64```
65```
65
66
66−The mark `examples-click-click` has hoon type `%click`, which means the only
67+The mark `examples-click-click` has type `%click`, which means the only
67valid value is `%click`. We can convert from `noun` by just
68valid value is `%click`. We can convert from `noun` by just
68producing `%click`.
69producing `%click`.
69
70
@@ -72,7 +73,7 @@ asserting the parsing succeeded with `need`, and asserting the
72result was 'click' with `?>`, which asserts that its first child
73result was 'click' with `?>`, which asserts that its first child
73is true.
74is true.
74
75
75−> Note the argument to `++json`is `jon/^json`. Why `^json`?
76+> Note the argument to `++json`is `jon=^json`. Why `^json`?
76> `++json` shadows the type definition, so if we want to refer to
77> `++json` shadows the type definition, so if we want to refer to
77> the type, we have to prepend a `^`. This extends to multiple
78> the type, we have to prepend a `^`. This extends to multiple
78> levels: `^^^foo` means the fourth most innermost instance of `foo`.
79> levels: `^^^foo` means the fourth most innermost instance of `foo`.
@@ -101,7 +102,7 @@ ford: cast %click
101And `/mar/examples/click/clicks.hoon`:
102And `/mar/examples/click/clicks.hoon`:
102
103
103```
104```
104−|_ clicks/@
105+|_ clicks=@
105++ grow
106++ grow
106 |%
107 |%
107 ++ json
108 ++ json
@@ -139,11 +140,9 @@ the app from the command line.
139
140
140Please pardon the awkwardness of the name 'examples-click-click', but we used it to stay true to our examples naming convention.
141Please pardon the awkwardness of the name 'examples-click-click', but we used it to stay true to our examples naming convention.
141
142
142−**Exercise**:
143+*Exercise*:
143
144
144−- Modify `:sink` from the subcriptions chapter to listen to
145− `:click` and print out the subscription updates on the command
145+- Modify `:sink` from the subcriptions chapter to listen to `:click` and print out the subscription updates on the command line.
146− line.
147
146
148# Frontend
147# Frontend
149
148
@@ -180,7 +179,6 @@ javascript file where the client-side application logic can be
180found. It's in `/web/pages/examples/click/click.js`:
179found. It's in `/web/pages/examples/click/click.js`:
181
180
182```
181```
183−
184$(function() {
182$(function() {
185 var clicks, $go, $clicks, $err
183 var clicks, $go, $clicks, $err
186
184
@@ -238,15 +236,10 @@ out the button when it is clicked. It is only reenabled when positive acknowledg
238
236
239Our second event handler is `window.urb.bind`, which is called immediately when the page is loaded, subscribing the page to the specified data stream on the app set with `urb.appl` (which is, in this case, :click). It also takes three arguments: path, parameters, and callback. The path is the path on the app to subscribe to. The parameters are all optional (indeed, we omit them entirely here), but are similar to those for `send`:
237Our second event handler is `window.urb.bind`, which is called immediately when the page is loaded, subscribing the page to the specified data stream on the app set with `urb.appl` (which is, in this case, :click). It also takes three arguments: path, parameters, and callback. The path is the path on the app to subscribe to. The parameters are all optional (indeed, we omit them entirely here), but are similar to those for `send`:
240
238
241−- `ship`: target urbit. Defaults to `window.urb.ship`, which
239+- `ship`: target urbit. Defaults to `window.urb.ship`, which defaults to the urbit which served the page.
242− defaults to the urbit which served the page.
243−- `appl`: target app. Defaults to `window.urb.appl`, which
240+- `appl`: target app. Defaults to `window.urb.appl`, which defaults to null.
244− defaults to null.
245−- `mark`: mark of expected data. Data of other marks is
246− converted to this mark on the server before coming to the web
241+- `mark`: mark of expected data. Data of other marks is converted to this mark on the server before coming to the web front end. Defaults to `window.urb.bind.mark`, which defaults to "json".
247− front end. Defaults to `window.urb.bind.mark`, which defaults
248− to "json".
249−- `wire`: wire of the subscription. Defaults to the given path.
242+- `wire`: wire of the subscription. Defaults to the given path.
250
243
251The callback function here just updates the data in the `clicks`
244The callback function here just updates the data in the `clicks`
252div. A truly robust app would intelligently handle errors, of
245div. A truly robust app would intelligently handle errors, of
@@ -258,8 +251,6 @@ The javascript is fairly pure as well, sending and receiving json
258everywhere. The marks are the translation layer, and they're the
251everywhere. The marks are the translation layer, and they're the
259only things that need to know how the hoon types map to json.
252only things that need to know how the hoon types map to json.
260
253
261−**Exercise**:
254+*Exercise*:
262
255
263−- Open the app in multiple tabs, click the button, and verify
256+- Open the app in multiple tabs, click the button, and verify that all the tabs stay in sink. Poke it manually from the command line and verify the tabs are updated as well.
264− that all the tabs stay in sink. Poke it manually from the
265− command line and verify the tabs are updated as well.
docs/hall.md → docs/tutorials/hall.umdrenamed+9−9
@@ -1,14 +1,14 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3−next: true
3+ next/'true'
4−sort: 8
4+ sort/'7'
5−title: Hall
5+ title/'Hall'
6−---
6+ ==
7+;>
7
8
8# Hall
9# Hall
9
10
10Hall is the Urbit messaging and notifications protocol. Read up on Hall's
11Hall is the Urbit messaging and notifications protocol. Read up on Hall's
11−architecture, its interfaces and the new Gall model it's built to target
12+architecture, its interfaces and the new Gall model it's built to target.
12−in this documentation section.
13
13
14−<list/>
14+;list;
docs/hall/architecture.md → docs/tutorials/hall/architecture.umdrenamed+53−52
@@ -1,10 +1,10 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−navuptwo: true
2+ navuptwo/'true'
4−next: true
3+ next/'true'
5−sort: 1
4+ sort/'1'
6−title: Hall architecture
5+ title/'Hall architecture'
7−---
6+ ==
7+;>
8
8
9# Hall architecture
9# Hall architecture
10
10
@@ -12,33 +12,34 @@ This document is complemented by Hall's source code, but doesn't require it. Def
12
12
13Hall's implementation is structured according to the new Gall model. Familiarity with its concepts is assumed. See [the new Gall model](new-gall).
13Hall's implementation is structured according to the new Gall model. Familiarity with its concepts is assumed. See [the new Gall model](new-gall).
14
14
15−## Table of contents
15+Note: This documentation was written in mid-2017 and uses certain outdated Hoon syntax. We are planning to update it soon, but for now, beware!
16
16
17−* [Introduction](#introduction)
17+## Table of contents
18−* [Structures & functionality](#structures--functionality)
19− * [Circles](#circles)
20− * [Messages](#messages)
21− * [Participant metadata](#participant-metadata)
22− * [Configurations](#configurations)
23− * [Stories](#stories)
24− * [General use](#general-use)
25− * [Federation](#federation)
26− * [Public membership](#public-membership)
27−* [Interfaces for applications](#interfaces-for-applications)
28− * [Interactions](#interactions)
29− * [Queries, prizes and rumors](#queries-prizes-and-rumors)
30−* [Communication between Halls](#communication-between-halls)
31− * [Commands](#commands)
32− * [Querying](#querying)
33− * [Federation implementation](#federation-implementation)
34−* [Hall implementation](#hall-implementation)
35− * [Subscriptions](#subscriptions)
36− * [Rumors](#rumors)
37− * [Messaging](#messaging)
38−* [The future](#the-future)
39− * [Features and functionality](#features-and-functionality)
40−* [Further reading](#further-reading)
41
18
19+- [Introduction](#introduction)
20+- [Structures & functionality](#structures--functionality)
21+ - [Circles](#circles)
22+ - [Messages](#messages)
23+ - [Participant metadata](#participant-metadata)
24+ - [Configurations](#configurations)
25+ - [Stories](#stories)
26+ - [General use](#general-use)
27+ - [Federation](#federation)
28+ - [Public membership](#public-membership)
29+- [Interfaces for applications](#interfaces-for-applications)
30+ - [Interactions](#interactions)
31+ - [Queries, prizes and rumors](#queries-prizes-and-rumors)
32+- [Communication between Halls](#communication-between-halls)
33+ - [Commands](#commands)
34+ - [Querying](#querying)
35+ - [Federation implementation](#federation-implementation)
36+- [Hall implementation](#hall-implementation)
37+ - [Subscriptions](#subscriptions)
38+ - [Rumors](#rumors)
39+ - [Messaging](#messaging)
40+- [The future](#the-future)
41+ - [Features and functionality](#features-and-functionality)
42+- [Further reading](#further-reading)
42
43
43## Introduction
44## Introduction
44
45
@@ -52,7 +53,7 @@ The messaging parts of Talk have been separated from its user-interface parts. W
52### Circles
53### Circles
53
54
54```
55```
55−++ circle {hos/ship nom/term} :< native target
56+++ circle {hos/ship nom/term} :: native target
56```
57```
57
58
58A `circle` is essentially a named collection of messages created by and hosted on a ship's Hall, usually represented as `~ship-name/circle-name`. Most of Hall revolves around doing things with circles.
59A `circle` is essentially a named collection of messages created by and hosted on a ship's Hall, usually represented as `~ship-name/circle-name`. Most of Hall revolves around doing things with circles.
@@ -116,7 +117,7 @@ Messages aren't the only thing a subscription gets us. We're also kept up to dat
116++ truename {fir/cord mid/(unit cord) las/cord} :< real-life name
117++ truename {fir/cord mid/(unit cord) las/cord} :< real-life name
117```
118```
118
119
119−`status` is user-set metadata that describes, well, the status of users in a circle. This encompasses their `presence`, which shows their activity, and their `human` identity, which includes their display handle.
120+`status` is user-set metadata that describes, well, the status of users in a circle. This encompasses their `presence`, which shows their activity, and their `human` identity, which includes their display handle.
120
121
121For reasons we'll discover shortly, circles keep track of both their own `group` and those of the circles they're subscribed to. `crowd` encapsulates this.
122For reasons we'll discover shortly, circles keep track of both their own `group` and those of the circles they're subscribed to. `crowd` encapsulates this.
122
123
@@ -154,9 +155,9 @@ Lastly, there's a `control` structure that contains both a security mode and a l
154 == ::
155 == ::
155```
156```
156
157
157−A `channel` is publicly readable and writable, with a blacklist for blocking.
158+A `channel` is publicly readable and writable, with a blacklist for blocking.
158−A `village` is privately readable and writable, with a whitelist for inviting.
159+A `village` is privately readable and writable, with a whitelist for inviting.
159−A `journal` is publicly readable and privately writable, with a whitelist for authors.
160+A `journal` is publicly readable and privately writable, with a whitelist for authors.
160A `mailbox` is readable by its owner and publicly writable, with a blacklist for blocking.
161A `mailbox` is readable by its owner and publicly writable, with a blacklist for blocking.
161
162
162### Stories
163### Stories
@@ -194,7 +195,7 @@ As an example, Talk operates like this, serving as an interface for reading from
194
195
195Some places, like `urbit-meta`, will want to be easily accessible to everyone on the network, and actually support the load that comes with that. Both of these desires can be achieved through federation.
196Some places, like `urbit-meta`, will want to be easily accessible to everyone on the network, and actually support the load that comes with that. Both of these desires can be achieved through federation.
196
197
197−With federation, stories and any changes to them trickle down from ~zod, to other galaxies, to their stars. Only changes to messages and presence can also move upstream, from stars, to galaxies, to ~zod (and then back down again).
198+With federation, stories and any changes to them trickle down from ~zod, to other galaxies, to their stars. Only changes to messages and presence can also move upstream, from stars, to galaxies, to ~zod (and then back down again).
198
199
199This way, all planets and comets will be able to subscribe to `/urbit-meta` (that is, the `urbit-meta` circle on their parent ship) and get all updates on the story, regardless of where on the network they originated.
200This way, all planets and comets will be able to subscribe to `/urbit-meta` (that is, the `urbit-meta` circle on their parent ship) and get all updates on the story, regardless of where on the network they originated.
200
201
@@ -287,9 +288,9 @@ To receive data from Hall, applications will have to query it. There are two pat
287 == ::
288 == ::
288```
289```
289
290
290−To be clear, the paths for those queries are `/client` and `/circle/[name]/[data]/[start]/[end]`, where data is at least one `circle-data`, and `start` and `end` are optional and can be either a date or a message number.
291+To be clear, the paths for those queries are `/client` and `/circle/[name]/[data]/[start]/[end]`, where data is at least one `circle-data`, and `start` and `end` are optional and can be either a date or a message number.
291
292
292−`/client` queries produce shared UI state. That is, glyph bindings and nicknames.
293+`/client` queries produce shared UI state. That is, glyph bindings and nicknames.
293`/circle` queries produce the entire public state of the requested story, including remotes.
294`/circle` queries produce the entire public state of the requested story, including remotes.
294
295
295Any changes to the results of these queries are communicated via the following `rumor`s. It's a fairly long list of potential changes,
296Any changes to the results of these queries are communicated via the following `rumor`s. It's a fairly long list of potential changes,
@@ -375,7 +376,7 @@ Halls can query other halls. Here's the peer move we send when we open a query o
375== ::
376== ::
376```
377```
377
378
378−Again, the rumor path is what our Hall uses to identify what query a received message originates from. Our circle is specified so that we know what story is interested in the changes we get.
379+Again, the rumor path is what our Hall uses to identify what query a received message originates from. Our circle is specified so that we know what story is interested in the changes we get.
379
380
380The query path is slightly more interesting. Of course it specifies the name of their story we want to subscribe our story to, but also a "start" and "end". These can (optionally) be used to specify the range of messages we want to get from our query. Once that range has passed, we stop receiving updates.
381The query path is slightly more interesting. Of course it specifies the name of their story we want to subscribe our story to, but also a "start" and "end". These can (optionally) be used to specify the range of messages we want to get from our query. Once that range has passed, we stop receiving updates.
381
382
@@ -423,15 +424,15 @@ Now that we know what gets sent over the wire and why, let's see what happens wh
423
424
424First though, it's useful to understand how Hall's code is structured. It consists of primary cores, designed to work optimally with Gall.
425First though, it's useful to understand how Hall's code is structured. It consists of primary cores, designed to work optimally with Gall.
425
426
426−* `++ta` is the transaction core. For every event that happens, be it a poke, peer or diff, the transaction core gets put to work to process it. Once it's done, it produces a list of deltas that describe how our state needs to be modified.
427+- `++ta` is the transaction core. For every event that happens, be it a poke, peer or diff, the transaction core gets put to work to process it. Once it's done, it produces a list of deltas that describe how our state needs to be modified.
427−* `++da` is the delta application core. It is used to apply `++ta`'s deltas to our application state, and produce a list of side-effects.
428+- `++da` is the delta application core. It is used to apply `++ta`'s deltas to our application state, and produce a list of side-effects.
428
429
429Both those cores also have a core within themselves dedicated solely to dealing with stories, `++so` and `++sa` respectively.
430Both those cores also have a core within themselves dedicated solely to dealing with stories, `++so` and `++sa` respectively.
430
431
431Once all work in an engine core has finished, its `-done` arm is called to produce the result of all the core's computation.
432Once all work in an engine core has finished, its `-done` arm is called to produce the result of all the core's computation.
432
433
433−In the diagrams that follow, regular lines indicate flows that always happen. Dashed lines indicate flows that are traversed if the described condition is met.
434+In the diagrams that follow, regular lines indicate flows that always happen. Dashed lines indicate flows that are traversed if the described condition is met.
434−Below the diagrams you will find brief explanations of the involved arms. In a particularly bright future, these might be available on-hover instead.
435+Below the diagrams you will find brief explanations of the involved arms. In a particularly bright future, these might be available on-hover instead.
435For brevity, utility arms that aren't a direct and important part of the flow have been omitted.
436For brevity, utility arms that aren't a direct and important part of the flow have been omitted.
436
437
437(You will find that the origins still use old Gall arms, with some glue code in between. At the time of writing, new Gall has not yet been implemented, so this will have to do.)
438(You will find that the origins still use old Gall arms, with some glue code in between. At the time of writing, new Gall has not yet been implemented, so this will have to do.)
@@ -440,7 +441,7 @@ We will only display the delta generation parts of the flow. Delta application i
440
441
441### Subscriptions
442### Subscriptions
442
443
443−Hall-to-Hall subscriptions happen when a source gets added to a story. This is done with a `%source` action, and results in a `%peer` move being sent (prompted by a `%story %follow` delta).
444+Hall-to-Hall subscriptions happen when a source gets added to a story. This is done with a `%source` action, and results in a `%peer` move being sent (prompted by a `%story %follow` delta).
444Upon receiving a valid peer on a `/circle` path, the subscribing ship is added to that circle's presence map.
445Upon receiving a valid peer on a `/circle` path, the subscribing ship is added to that circle's presence map.
445
446
446![subscriptions implementation flow](https://media.urbit.org/docs/hall/diagrams/flow-subscriptions.png "subscriptions implementation flow")
447![subscriptions implementation flow](https://media.urbit.org/docs/hall/diagrams/flow-subscriptions.png "subscriptions implementation flow")
@@ -502,7 +503,7 @@ To turn Talk into a [sustainable social platform](https://urbit.org/fora/posts/~
502
503
503We want to have some kind of discoverability for circles. This could be realized by making it possible for users to add friends, who would have their Hall subscribe to a list of circles the added friends are in. The existing public membership functionality can be leveraged for this.
504We want to have some kind of discoverability for circles. This could be realized by making it possible for users to add friends, who would have their Hall subscribe to a list of circles the added friends are in. The existing public membership functionality can be leveraged for this.
504
505
505−Eventually, content self-moderation might need to be implemented. Users would flag their content if it is potentially offensive. Others would easily be able to filter out content that might offend them.
506+Eventually, content self-moderation might need to be implemented. Users would flag their content if it is potentially offensive. Others would easily be able to filter out content that might offend them.
506This functionality brings its own large sets of challenges that need to be tackled.
507This functionality brings its own large sets of challenges that need to be tackled.
507
508
508Additionally, federation might be put to broader use. Knowing that a circle is federated could help fall back to alternative hosts in case the one Hall originally subscribed to is unavailable. Implementation-wise, care would need to be taken for this to not get ugly. Not to mention, when/how would availability of a host be verified?
509Additionally, federation might be put to broader use. Knowing that a circle is federated could help fall back to alternative hosts in case the one Hall originally subscribed to is unavailable. Implementation-wise, care would need to be taken for this to not get ugly. Not to mention, when/how would availability of a host be verified?
@@ -510,17 +511,17 @@ Additionally, federation might be put to broader use. Knowing that a circle is f
510Other changes that might have a fair impact on the functioning of Hall are un/read states for messages, and being able to use moons to allow your friends to chat with you in a local channel.
511Other changes that might have a fair impact on the functioning of Hall are un/read states for messages, and being able to use moons to allow your friends to chat with you in a local channel.
511
512
512More minor functionalities that need to be implemented include:
513More minor functionalities that need to be implemented include:
513−* Extended permissions management. Being able to black-/whitelist entire ship classes.
514+- Extended permissions management. Being able to black-/whitelist entire ship classes.
514−* Improved presence functionality. Actually using the presence system, and sending "typing", "idle", etc. statuses.
515+- Improved presence functionality. Actually using the presence system, and sending "typing", "idle", etc. statuses.
515−* Polls.
516+- Polls.
516
517
517And, of course, there's a lot that the Talk client can improve on as well.
518And, of course, there's a lot that the Talk client can improve on as well.
518
519
519
520
520## Further reading
521## Further reading
521
522
522−To gain a more thorough understanding of Hall's inner workings, take a look at its source code. It comes with inline documentation.
523+To gain a more thorough understanding of Hall's inner workings, take a look at its source code. It comes with inline documentation.
523[On Github.](https://github.com/urbit/arvo/blob/master/app/hall.hoon)
524[On Github.](https://github.com/urbit/arvo/blob/master/app/hall.hoon)
524
525
525−To see an expansive example of a Hall client, take a look at the code of Talk. It, too, comes with inline documentation.
526+To see an expansive example of a Hall client, take a look at the code of Talk. It, too, comes with inline documentation.
526[On Github.](https://github.com/urbit/arvo/blob/master/app/talk.hoon)
527[On Github.](https://github.com/urbit/arvo/blob/master/app/talk.hoon)
docs/hall/interface.md → docs/tutorials/hall/interface.umdrenamed+28−31
@@ -1,10 +1,10 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−navuptwo: true
2+ navuptwo/'true'
4−next: true
3+ next/'true'
5−sort: 2
4+ sort/'2'
6−title: Hall interface
5+ title/'Hall interface'
7−---
6+ ==
7+;>
8
8
9# Hall interface
9# Hall interface
10
10
@@ -12,29 +12,27 @@ This document describes the different interfaces Hall provides and the data that
12
12
13While the structures here are given in Hoon, they match fairly closely to their JSON equivalent. Most important to note is that `$%({$x y/z})` becomes accessible as `json.x.y`.
13While the structures here are given in Hoon, they match fairly closely to their JSON equivalent. Most important to note is that `$%({$x y/z})` becomes accessible as `json.x.y`.
14
14
15−
16## Table of contents
15## Table of contents
17
16
18−* [Queries](#queries)
17+- [Queries](#queries)
19− * [/client](#client)
18+ - [/client](#client)
20− * [/client prize](#client-prize)
19+ - [/client prize](#client-prize)
21− * [/client rumor](#client-rumor)
20+ - [/client rumor](#client-rumor)
22− * [/public](#public)
21+ - [/public](#public)
23− * [/public prize](#public-prize)
22+ - [/public prize](#public-prize)
24− * [/public rumor](#public-rumor)
23+ - [/public rumor](#public-rumor)
25− * [/peers](#peers)
24+ - [/peers](#peers)
26− * [/peers prize](#peers-prize)
25+ - [/peers prize](#peers-prize)
27− * [/peers rumor](#peers-rumor)
26+ - [/peers rumor](#peers-rumor)
28− * [/circle](#circle)
27+ - [/circle](#circle)
29− * [/circle prize](#circle-prize)
28+ - [/circle prize](#circle-prize)
30− * [/circle rumor](#circle-rumor)
29+ - [/circle rumor](#circle-rumor)
31−* [Actions](#actions)
30+- [Actions](#actions)
32− * [Circle configuration](#circle-configuration)
31+ - [Circle configuration](#circle-configuration)
33− * [Messaging](#messaging)
32+ - [Messaging](#messaging)
34− * [Personal metadata](#personal-metadata)
33+ - [Personal metadata](#personal-metadata)
35− * [Changing shared UI](#changing-shared-ui)
34+ - [Changing shared UI](#changing-shared-ui)
36− * [Miscellaneous changes](#miscellaneous-changes)
35+ - [Miscellaneous changes](#miscellaneous-changes)
37−
38
36
39## Queries
37## Queries
40
38
@@ -106,7 +104,7 @@ Valid paths include:
106
104
107```
105```
108:> all public memberships
106:> all public memberships
109−/public
107+/public
110```
108```
111
109
112#### /public prize
110#### /public prize
@@ -262,7 +260,7 @@ Contains (where applicable) messages in envelopes (with message numbers), as wel
262
260
263#### /circle rumor
261#### /circle rumor
264
262
265−Contains a detailed change description of the data relevant to the query that changed.
263+Contains a detailed change description of the data relevant to the query that changed.
266
264
267Messages are wrapped in envelopes to include their sequence number, and note the source they were heard from. Configuration and status changes specify the circle they apply to.
265Messages are wrapped in envelopes to include their sequence number, and note the source they were heard from. Configuration and status changes specify the circle they apply to.
268
266
@@ -377,7 +375,6 @@ When the user makes any changes to shared UI elements (elements that should pers
377 ==
375 ==
378```
376```
379
377
380−
381`%glyph`: Adds or removes a binding of a glyph to an audience.
378`%glyph`: Adds or removes a binding of a glyph to an audience.
382
379
383`%nick`: Sets a local nickname for a ship. An empty nickname `''` means the ship has no nickname.
380`%nick`: Sets a local nickname for a ship. An empty nickname `''` means the ship has no nickname.
docs/hall/new-gall.md → docs/tutorials/hall/new-gall.umdrenamed+45−49
@@ -1,9 +1,9 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−navuptwo: true
2+ navuptwo/'true'
4−sort: 3
3+ sort/'3'
5−title: The new Gall model
4+ title/'The new Gall model'
6−---
5+ ==
6+;>
7
7
8# The new Gall model
8# The new Gall model
9
9
@@ -13,43 +13,40 @@ New `%gall` has not yet fully solidified. As such, its structure and naming are
13
13
14## Table of contents
14## Table of contents
15
15
16−* [Renewing a pillar of Arvo](#renewing-a-pillar-of-arvo)
16+- [Renewing a pillar of Arvo](#renewing-a-pillar-of-arvo)
17− * [Problems](#problems)
17+ - [Problems](#problems)
18− * [Solutions](#solutions)
18+ - [Solutions](#solutions)
19−* [As seen in new Gall](#as-seen-in-new-gall)
19+- [As seen in new Gall](#as-seen-in-new-gall)
20− * [Structures](#structures)
20+ - [Structures](#structures)
21− * [Arms](#arms)
21+ - [Arms](#arms)
22−* [By example](#by-example)
22+- [By example](#by-example)
23− * [State & deltas](#state--deltas)
23+ - [State & deltas](#state--deltas)
24− * [Queries & rumors](#queries--rumors)
24+ - [Queries & rumors](#queries--rumors)
25− * [Responding to queries](#responding-to-queries)
25+ - [Responding to queries](#responding-to-queries)
26− * [Updating state & query results](#updating-state--query-results)
26+ - [Updating state & query results](#updating-state--query-results)
27−* [Criticism](#criticism)
27+- [Criticism](#criticism)
28−* [Further reading](#further-reading)
28+- [Further reading](#further-reading)
29
29
30## Renewing a pillar of Arvo
30## Renewing a pillar of Arvo
31
31
32−When you write an app, Gall is responsible for making sure its event arms like `++poke` get called when they need to. In essence, it provides developers with a consistent interface for hooking their app up to the operating system.
32+When you write an app, Gall is responsible for making sure its event arms like `++poke` get called when they need to. In essence, it provides developers with a consistent interface for hooking their app up to the operating system.
33
33
34It's not doing a lot to make sure this is done in a structured way, though, which results in apps (especially larger ones) feeling like big, tangled messes. Something needs to be done about this.
34It's not doing a lot to make sure this is done in a structured way, though, which results in apps (especially larger ones) feeling like big, tangled messes. Something needs to be done about this.
35
35
36### Problems
36### Problems
37
37
38−Imagine a `++poke`, `++diff`, or even a `++peer` arm. In current implementations, you'll often see their product defined through cast as the following:
38+Imagine a `++poke`, `++diff`, or even a `++peer` arm. In current implementations, you'll often see their product defined through cast as the following:
39−`^- (quip move +>)`
39+`^- (quip move +>)`
40−Or (sadly) more commonly:
40+Or (sadly) more commonly:
41`^- {(list move) _+>.$}`
41`^- {(list move) _+>.$}`
42
42
43These arms are producing both side-effects and new state. To do this, their code has to simultaneously figure out "how does this poke/diff/whatever change our state?" and "what side-effects does this change have?"
43These arms are producing both side-effects and new state. To do this, their code has to simultaneously figure out "how does this poke/diff/whatever change our state?" and "what side-effects does this change have?"
44
44
45You'll find that the logic relating to these two often becomes tangled, making the flow of the whole more difficult to understand. And the side-effects more often than not relate to subscriptions, for which the developer may be writing a lot of boilerplate code. Gall currently does not help in either of these places.
45You'll find that the logic relating to these two often becomes tangled, making the flow of the whole more difficult to understand. And the side-effects more often than not relate to subscriptions, for which the developer may be writing a lot of boilerplate code. Gall currently does not help in either of these places.
46
46
47−> The main significant cost of software development is the cost of
48−untangling what the computer is doing, and or is supposed to be doing,
47+> The main significant cost of software development is the cost of untangling what the computer is doing, and or is supposed to be doing, over and over again in your head. Any way of lowering this untangling cost is extremely welcome.
49−over and over again in your head. Any way of lowering this untangling
50−cost is extremely welcome.
51
48
52−-- *~sorreg-namtyv*
49+*~sorreg-namtyv*
53
50
54### Solutions
51### Solutions
55
52
@@ -57,11 +54,11 @@ Let's imagine a world in which Gall *does* help, in both of those places.
57
54
58It would be wonderful if Gall could take care of all standard subscription management logic for you, and direct the flow of code as it concludes is appropriate. Applications, then, would have to help Gall by providing the different parts of this flow, and providing the checks that allow Gall to make the right decisions. This takes some work out of the developer's hands and results in more structured application code.
55It would be wonderful if Gall could take care of all standard subscription management logic for you, and direct the flow of code as it concludes is appropriate. Applications, then, would have to help Gall by providing the different parts of this flow, and providing the checks that allow Gall to make the right decisions. This takes some work out of the developer's hands and results in more structured application code.
59
56
60−If we expand on that a bit, then we can even have Gall help us in untangling state changes from side effects. We do so by separating state changes into two phases: *analyzing* what changes need to be made, and *applying* those changes.
57+If we expand on that a bit, then we can even have Gall help us in untangling state changes from side effects. We do so by separating state changes into two phases: *analyzing* what changes need to be made, and *applying* those changes.
61
58
62−But where do the side-effects go, then? We need to realize there's two kinds: side-effects that are subscription updates, and side-effects that aren't. The latter get produces by applying state changes, while the former get integrated into the Gall flow we described above.
59+But where do the side-effects go, then? We need to realize there's two kinds: side-effects that are subscription updates, and side-effects that aren't. The latter get produces by applying state changes, while the former get integrated into the Gall flow we described above.
63
60
64−Since subscriptions are essentially queries to an app, requesting a specific part of its data/state, we can deduce subscription updates from state changes. We merely provide the logic, and Gall chains it all together. Having Gall support all this allows us to cleanly and structurally untangle state change analysis, application, and subscription logic into their own arms.
61+Since subscriptions are essentially queries to an app, requesting a specific part of its data/state, we can deduce subscription updates from state changes. We merely provide the logic, and Gall chains it all together. Having Gall support all this allows us to cleanly and structurally untangle state change analysis, application, and subscription logic into their own arms.
65
62
66For trivial apps, this might result in some arms with trivial code. Though it may feel like writing cruft, it makes understanding the app just as simple as it actually as. For more complex apps, all logic is no longer a big chunk of "what do we do when x happens?" Rather, it's a few smaller chunks, like "x happened, how does that change our state?" and "if our state changes like y, what does that mean for subscription z?" These are precisely the kinds of questions that application developers should be asked.
63For trivial apps, this might result in some arms with trivial code. Though it may feel like writing cruft, it makes understanding the app just as simple as it actually as. For more complex apps, all logic is no longer a big chunk of "what do we do when x happens?" Rather, it's a few smaller chunks, like "x happened, how does that change our state?" and "if our state changes like y, what does that mean for subscription z?" These are precisely the kinds of questions that application developers should be asked.
67
64
@@ -74,11 +71,11 @@ Of course, for the above to be made into reality, Gall will need to see some cha
74
71
75This wouldn't be Urbit if we didn't have cool terminology for people to learn. These ones are (for the most part) semantically sensible, and you might already see how they relate to the story above.
72This wouldn't be Urbit if we didn't have cool terminology for people to learn. These ones are (for the most part) semantically sensible, and you might already see how they relate to the story above.
76
73
77−`brain`: application state.
74+`brain`: application state.
78−`delta`: change to application state.
75+`delta`: change to application state.
79−`opera`: side-effect, operation, move.
76+`opera`: side-effect, operation, move.
80−`query`: request (to an app) for data on a specific path.
77+`query`: request (to an app) for data on a specific path.
81−`prize`: query result.
78+`prize`: query result.
82`rumor`: change to a query result.
79`rumor`: change to a query result.
83
80
84These should be fairly straightforward. Like packets are to Urbits, `delta`s are to `brain`s and `rumor`s are to `prize`s. If one diligently updates the `prize` they received using all the `rumor`s that are relevant to it, they will always have the same `prize` as if they queried for it all over again.
81These should be fairly straightforward. Like packets are to Urbits, `delta`s are to `brain`s and `rumor`s are to `prize`s. If one diligently updates the `prize` they received using all the `rumor`s that are relevant to it, they will always have the same `prize` as if they queried for it all over again.
@@ -100,17 +97,17 @@ This also wouldn't be Urbit if we couldn't boil that down to a few simple pseudo
100
97
101There. In the first three arms we already have the bulk of new Gall! `++gain` won't be part of it, since most applications don't need to keep track of `prize`s directly. Those that do may still implement and hook it up themselves though.
98There. In the first three arms we already have the bulk of new Gall! `++gain` won't be part of it, since most applications don't need to keep track of `prize`s directly. Those that do may still implement and hook it up themselves though.
102
99
103−Of course, these aren't all of the new Gall arms. Most important to still mention is `++leak`, which takes a `ship` and `query` and checks if the former has permission to ask for the latter.
100+Of course, these aren't all of the new Gall arms. Most important to still mention is `++leak`, which takes a `ship` and `query` and checks if the former has permission to ask for the latter.
104
101
105−There's also `++look` for asynchronous reads, `++hear` for subscription updates (rumors), `++fail` for dealing with process errors, `++cope` for dealing with transaction results, and `++pour` for dealing with responses from Arvo.
102+There's also `++look` for asynchronous reads, `++hear` for subscription updates (rumors), `++fail` for dealing with process errors, `++cope` for dealing with transaction results, and `++pour` for dealing with responses from Arvo.
106−`++prep`, `++poke` and `++pull` continue to function as they do right now.
103+`++prep`, `++poke` and `++pull` continue to function as they do right now.
107
104
108For a more verbose specification of all of these, see the new Gall spec.
105For a more verbose specification of all of these, see the new Gall spec.
109
106
110
107
111## By example
108## By example
112
109
113−To help solidify this and see what this would looks like in the wild, let's make a very simple example app. It's a counter that can go up and down, and can be queried for its value, or whether or not its value is a multiple of x. First we write all the structures that will support our app, and then we implement the arms that operate on them.
110+To help solidify this and see what this would looks like in the wild, let's make a very simple example app. It's a counter that can go up and down, and can be queried for its value, or whether or not its value is a multiple of x. First we write all the structures that will support our app, and then we implement the arms that operate on them.
114(The app code in its entirety can be found [here](example).)
111(The app code in its entirety can be found [here](example).)
115
112
116### State & deltas
113### State & deltas
@@ -235,20 +232,19 @@ As we saw earlier, for `/number` queries the `delta`s match one-on-one with the
235
232
236## Criticism
233## Criticism
237
234
238−* Where event arms currently get passed a `wire`, and the new Gall described above passes them a custom `query` structure, the original new Gall spec gave them `(list coin)`, a "pre-parsed wire". These structures (eg `[%$ p=[p=~.ud q=123]]`) are uncomfortable to work with. Even with a "coin list parsing library" it still doesn't feel ideal. Because of custom structures being easier to work with than lists of `++knot`s or `++coin`s, writing a `++path-to-query` arm by hand is a small cost for huge gains.
235+- Where event arms currently get passed a `wire`, and the new Gall described above passes them a custom `query` structure, the original new Gall spec gave them `(list coin)`, a "pre-parsed wire". These structures (eg `[%$ p=[p=~.ud q=123]]`) are uncomfortable to work with. Even with a "coin list parsing library" it still doesn't feel ideal. Because of custom structures being easier to work with than lists of `++knot`s or `++coin`s, writing a `++path-to-query` arm by hand is a small cost for huge gains.
239
236
240−* Why do `prize` units mean what they do? One would expect `~` to mean "invalid" and `[~ ~]` to mean "unavailable" as opposed to the other way around.
237+- Why do `prize` units mean what they do? One would expect `~` to mean "invalid" and `[~ ~]` to mean "unavailable" as opposed to the other way around.
241
238
242−* The original new Gall spec mentions output lists (like `(list delta)` etc.) to be in reverse order. This was done because adding to the head of a list (`[item list]`) is easier than appending to the tail of a list (`(weld list [item ~])` or other). While it's technically easier to produce a list in reverse order, semantically it's yet another thing to keep in mind. Luckily, most of the "add to x, produce all of it later" code is set-and-forget, so probably not a huge deal. But do we really fear a few stray `++flop`s that much?
239+- The original new Gall spec mentions output lists (like `(list delta)` etc.) to be in reverse order. This was done because adding to the head of a list (`[item list]`) is easier than appending to the tail of a list (`(weld list [item ~])` or other). While it's technically easier to produce a list in reverse order, semantically it's yet another thing to keep in mind. Luckily, most of the "add to x, produce all of it later" code is set-and-forget, so probably not a huge deal. But do we really fear a few stray `++flop`s that much?
243
240
244−* There's some weirdness with relation to relying on old state in `++feel` to determine whether a query result actually changed. Just relying on state in general for delta-to-rumor conversion may or may not violate the new Gall spec.
241+- There's some weirdness with relation to relying on old state in `++feel` to determine whether a query result actually changed. Just relying on state in general for delta-to-rumor conversion may or may not violate the new Gall spec.
245
242
246−* The original new Gall spec specifies `++leak` as taking a `(unit (set ship))`, where `~` means public. Is there a use case for checking more than just a single ship?
243+- The original new Gall spec specifies `++leak` as taking a `(unit (set ship))`, where `~` means public. Is there a use case for checking more than just a single ship?
247−
248−* Gall should probably cache `++feel` results during a single pass, to avoid the cycles of generating what it can be certain of is the same `(unit rumor)`. (But then for eg `/circle/nom/13` and `/circle/nom/14` it would still recalculate. Better than nothing.)
249
244
245+- Gall should probably cache `++feel` results during a single pass, to avoid the cycles of generating what it can be certain of is the same `(unit rumor)`. (But then for eg `/circle/nom/13` and `/circle/nom/14` it would still recalculate. Better than nothing.)
250
246
251## Further reading
247## Further reading
252
248
253−- [Original new-Gall spec by ~sorreg-namtyv](spec)
249+- [Original new-Gall spec by ~sorreg-namtyv](spec)
254−- [A new-Gall example app](example)
250+- [A new-Gall example app](example)
docs/hall/new-gall/example.md → docs/tutorials/hall/new-gall/example.umdrenamed+7−7
@@ -1,11 +1,11 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
3−next: true
2+ navuptwo/'true'
4−sort: 2
3+ sort/'2'
5−title: A new-Gall example app
4+ title/'A new-Gall example app'
6−---
5+ ==
6+;>
7
7
8−# A new-Gall example app
8+# A new-Gall example app
9
9
10```
10```
11:: counter app
11:: counter app
docs/hall/new-gall/spec.md → docs/tutorials/hall/new-gall/spec.umdrenamed+7−8
@@ -1,16 +1,15 @@
1−---
2−navhome: /docs/
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3−next: true
3+ next/'true'
4−sort: 1
4+ sort/'1'
5−title: The original new-Gall spec
5+ title/'The original new-Gall spec'
6−---
6+ ==
7+;>
7
8
8# The original new-Gall spec
9# The original new-Gall spec
9
10
10`~sorreg-namtyv`
11`~sorreg-namtyv`
11
12
12−<br />
13−
14```
13```
15=> |%
14=> |%
16 --
15 --
docs/tutorials/hoon-ch1.umdnew file+18
@@ -0,0 +1,18 @@
1+:- :~ navhome/'/docs/'
2+ next/'true'
3+ sort/'2'
4+ title/'Hoon Chapter 1'
5+ ==
6+;>
7+
8+# Chapter 1: Fundamental Concepts of Subject-oriented Programming
9+
10+Hoon is a high-level, statically typed, functional programming language, custom-designed for use with Urbit. For a functional language it has a surprisingly imperative style, and mastering it doesn't require knowing any advanced mathematics.
11+
12+Hoon is an unusual language in several respects, both in syntax and semantics. It uses runes (i.e., ASCII digraphs) in place of keywords, and the spacing rules are a bit strict. A great deal can be expressed in few lines, though excessively compressed code tends to be hard to read. Hoon has surprisingly simple semantics, but mastering it requires learning concepts that don't have close analogues in other languages. We believe that Hoon, if properly taught, is relatively easy to learn and pleasant to use.
13+
14+This multi-chapter tutorial series is designed to teach you Hoon without assuming you have an extensive programming background. In fact, you should be able to follow much of it even if you have no programming experience at all, though of course experience helps. We strongly encourage you to try out all the examples of each lesson. These lessons are meant for the beginner but they aren't meant to be skimmed.
15+
16+Chapter 1 introduces and explains the fundamental concepts you need in order to understand Hoon's semantics. Hoon is a 'subject-oriented' programming language -- every expression of Hoon is evaluated relative to a *subject*. The subject is a piece of data that represents the environment, or the context, of an expression. After reading Chapter 1 you should understand what the subject is, how to refer to its various parts, and how to carry out function calls using code in the subject. You'll also be able to write your own functions in Hoon, albeit only very simple ones.
17+
18+;list;
docs/tutorials/hoon-ch1/hoon-ch1-1.umdnew file+116
@@ -0,0 +1,116 @@
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3+ next/'true'
4+ sort/'1'
5+ title/'Getting Started'
6+ ==
7+;>
8+
9+# 1.1 Getting Started
10+
11+Before we begin working on Hoon you should first (1) have Urbit installed and (2) boot an 'urbit' that you can use for trying out Hoon examples. Interactive learning is far superior to passive reading.
12+
13+## Installing Urbit
14+
15+You can [install Urbit](../../using/install/) on any Mac or Unix machine. On Windows, make a virtual Linux machine using VirtualBox or a similar tool.
16+
17+Once you're finished you can boot your very own urbit.
18+
19+## What is an urbit?
20+
21+An *urbit* is an Urbit virtual computer with persistent state that can connect to the Urbit network. (Note the lowercase 'u' here. 'Urbit' is the entire software stack, whereas 'an urbit' is a local instance.). Each urbit is associated with a unique number that plays three distinct roles: (1) it's an address on the Urbit network, (2) it's a cryptographic identity, and (3) it's (in principle) a human memorable name. Normally an urbit's name is represented as a string starting with `~`, as in `~zod` or `~taglux-nidsep`.
22+
23+These may not look like numbers, but they are. Each urbit name is written in a base-256 format, where each 'digit' is a syllable. Imagine your phone number as a pronounceable string which sounds like a name in a foreign language. An ordinary user-level urbit is a 'planet', and it's named by a 32-bit number. The latter is represented as a four-syllable string; e.g., the planet name `~taglux-nidsep` is the number 6,095,360.
24+
25+For this tutorial you'll boot and run what we call a 'comet'. *Comets* are urbits whose names are 128-bits or 16 syllables, such as:
26+
27+`~hillyn-pitwet-hasdur-paswer--miszod-rabpex-divrup-fogdur`
28+
29+Comet names aren't quite as memorable as others, but they're disposable identities that anyone can make for free to join the live network. Thus, comets make the ideal urbit for playing around with Hoon, asking for help from other Urbit devs in [Talk](../../using/messaging/) if you need it, and showing off Urbit to your friends.
30+
31+## Booting a Comet
32+
33+To boot your comet, go into the command line and run the following command from the directory that was created during Urbit installation:
34+
35+```
36+$ urbit -c mycomet
37+```
38+
39+This will take a few minutes and will spin out a bunch of boot messages. Toward the end, you'll see something like:
40+
41+```
42+ames: on localhost, UDP 31337.
43+http: live (insecure, public) on 8080
44+http: live ("secure", public) on 8443
45+http: live (insecure, loopback) on 12321
46+~palnul_nocser:dojo>
47+```
48+
49+(There will likely be other messages as well.)
50+
51+Look at the prompt, `~palnul_nocser:dojo>`. To the left of the `:` you'll see an abbreviation of the comet name you just booted, `~palnul_nocser` in this case. To the right is the name of a local application, `dojo`. *Dojo* is the Urbit command line app; it's also a Hoon [REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop) we'll use to run simple Hoon examples.
52+
53+To make sure everything is working, type `(add 2 2)` at the prompt and hit return. Your screen now shows:
54+
55+```
56+ames: on localhost, UDP 31337.
57+http: live (insecure, public) on 8080
58+http: live ("secure", public) on 8443
59+http: live (insecure, loopback) on 12321
60+> (add 2 2)
61+4
62+~palnul_nocser:dojo>
63+```
64+
65+You just used a function from the Hoon standard library, `add`. Next, quit Urbit with `ctrl-d`:
66+
67+```
68+> (add 2 2)
69+4
70+~palnul_nocser:dojo>
71+$
72+```
73+
74+Your comet isn't running anymore and you're back at your computer's normal terminal prompt. You now have a `mycomet` directory for your Urbit comet; this directory is your comet's *pier* and it contains the entirety of your comet's state.
75+
76+Right now the only thing in your pier is your comet's system files:
77+
78+```
79+$ ls -a /path/to/mycomet
80+./ ../ .urb/
81+```
82+
83+Restarting your already-created comet from the terminal is like creating a new one, but without the `-c` flag. (The `-c` is for "create".)
84+
85+```
86+$ urbit mycomet
87+```
88+
89+Because the comet has already been booted it won't take very long to get it running again. There are also fewer startup messages:
90+
91+```
92+$ urbit mycomet
93+[...]
94+ames: on localhost, UDP 31337.
95+http: live (insecure, public) on 8080
96+http: live ("secure", public) on 8443
97+http: live (insecure, loopback) on 12321
98+~palnul_nocser:dojo>
99+```
100+
101+We should note that your comet's state is [ACID](https://en.wikipedia.org/wiki/ACID). You can stop your comet politely with `ctrl-d`, abruptly with `ctrl-z`, even violently with `kill -9`. None of these should cause the comet to lose data. If you do manage to corrupt your comet, it's a bug -- please let us know.
102+
103+## Another Noun
104+
105+You've already used a standard library function to produce one value, in the dojo. Now that your comet is running again, let's try another. Enter the number `17`.
106+
107+_We won't show the `~palnul_nocser:dojo> ` prompt from here on out. We'll just show the echoed command along with its result._
108+
109+You'll see:
110+
111+```
112+> 17
113+17
114+```
115+
116+You asked dojo to evaluate `17` and it echoed the number back at you. This value is a 'noun'. But what is a noun? Move on to lesson 1.2 for the answer.
docs/tutorials/hoon-ch1/hoon-ch1-2.umdnew file+494
@@ -0,0 +1,494 @@
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3+ next/'true'
4+ sort/'2'
5+ title/'Nouns'
6+ ==
7+;>
8+
9+# 1.2 Nouns
10+
11+In Urbit every piece of data (that is, every 'datum') is a noun. In order to understand Hoon one must first understand nouns.
12+
13+## Noun Definition
14+
15+A *noun* is either an atom or a cell. An *atom* is an unsigned integer of any size. A *cell* is an [ordered pair](https://en.wikipedia.org/wiki/Ordered_pair) of nouns, usually indicated with square brackets around the nouns in question; i.e., `[a b]`, where `a` and `b` are nouns.
16+
17+Here are some atoms:
18+
19+- `0`
20+- `87`
21+- `325`
22+
23+Here are some cells:
24+
25+- `[12 13]`
26+- `[12 [487 325]]`
27+- `[[12 13] [87 65]]`
28+- `[[83 [1 17]] [[23 [32 64]] 90]]`
29+
30+All of the above are nouns.
31+
32+## Recursive Definitions
33+
34+You may or may not have noticed that the definition of 'noun' is [recursive](https://en.wikipedia.org/wiki/Recursion). Recursion is an important concept for functional programming, so it's worth taking a moment to understand it better.
35+
36+A recursive definition has three clauses: a base clause, a generating clause, and a closure clause. Let's say you want to use recursion to define some X. The *base clause* of the recursive definition defines one or more objects as trivial instances of X. The *generating clause* defines other objects as also being X by their relationship to previously established instances of X. The *closure clause* asserts that nothing else is an instance of X than what has been given in the first two clauses. Often the closure clause is not explicitly stated.
37+
38+For example, let's say you want to define the phrase 'ancestor of George Washington'. The base clause is simple: the parents of George Washington are trivial ancestors of George Washington. The generating clause is: given that some x is an ancestor of George Washington, the parents of x are also ancestors of George Washington. The closure clause is: no one else is an ancestor of George Washington. That's it!
39+
40+The base clause of the definition of a 'noun' is: all atoms are nouns (where an 'atom' is an unsigned integer). The generating clause is: if x and y are nouns, then the cell `[x y]` is also a noun. (A 'cell' is an ordered pair of nouns.). The closure clause was given implicitly in the following claim: "A *noun* is either an atom or a cell." Nothing else is a noun.
41+
42+We belabor this point about recursion only because it's an important concept for having a firm grasp of functional programming. We'll talk more about recursion at various points in the tutorial series.
43+
44+### Nouns as Binary Trees
45+
46+A [binary tree](https://en.wikipedia.org/wiki/Binary_tree) has a single base node, and each node of the tree may have up to two child nodes (but it need not have any). A node without children is a 'leaf'. You can think of a noun as a binary tree whose leaves are atoms, i.e., unsigned integers. All non-leaf nodes are cells. To visualize this, consider the following representation of the noun: `[12 [17 45]]`:
47+
48+```
49+[12 [17 45]]
50+ .
51+ / \
52+ 12 .
53+ / \
54+ 17 45
55+```
56+
57+Each number is an atom; each dot is a cell. Let's look at another example, this time of `[[7 13] [87 65]]` with the cell nodes shown explicitly:
58+
59+```
60+ [[7 13] [87 65]]
61+ .
62+ / \
63+ [7 13] [87 65]
64+ . .
65+ / \ / \
66+ 7 13 87 65
67+```
68+
69+An atom is a trivial tree of just one node; e.g., `17`.
70+
71+## Atoms
72+
73+Atoms are unsigned integers. These are often represented by the dojo as unsigned integers in decimal notation, e.g., `17`.
74+
75+To be sure we understand Hoon's atom notation, let's enter some atoms into the dojo:
76+
77+```
78+> 3
79+3
80+```
81+
82+Seems straightforward.
83+
84+```
85+> 32
86+32
87+```
88+
89+Why not try it again to make sure?
90+
91+```
92+> 320
93+320
94+```
95+
96+Can we add another zero?
97+
98+```
99+> 320
100+```
101+
102+It didn't work! When you tried to type that next zero and turn `320` into `3200`, the dojo actually _deleted the `0` and beeped at you_.
103+
104+Isn't an atom an unsigned integer of any size? It is. But the way to represent the four-digit number `3200` is actually `3.200`:
105+
106+```
107+> 3.200
108+3.200
109+
110+> (mul 32 100)
111+3.200
112+```
113+
114+Just think of it as "3,200", written the German way with a dot.
115+
116+Why? Long numbers are difficult to read. We know this, so we group digits in threes. For some reason most programming languages don't use this marvelous innovation. Hoon does.
117+
118+English notation for decimals is more common than German notation. Unfortunately, dots are URL-safe and commas aren't. For reasons to be discussed in a later lesson, it's nice to have a regular syntax for atoms that's URL-safe.
119+
120+As for why the dojo deleted your zero: it parses the command line as you type, and rejects any characters after the parser stops. This prevents you from entering expressions that aren't well-formed.
121+
122+### Atom Auras
123+
124+Atoms are nothing more than unsigned integers, but it's often useful to interpret an atom as being a different kind of data. This is done with an *aura* -- the aura of an atom is type meta-data used by Hoon to determine how interpret that atom.
125+
126+We won't fully explain auras and their various uses yet. Auras will be covered more comprehensively in a later lesson. For now let's just look at the various kinds of [literal syntax](https://en.wikipedia.org/wiki/Literal_(computer_programming)) associated with atom auras.
127+
128+In computer science, a 'literal' is an expression that represents and evaluates to a fixed value. The default syntax of an atom literal is the German-style decimal notation, as seen above. Let's look at some other atom literal syntaxes: unsigned binary, unsigned hexadecimal, signed decimal, signed binary and hexadecimal.
129+
130+```
131+> 0b1001
132+0b1001
133+
134+> 0b1001.1101
135+0b1001.1101
136+
137+> 0x9d
138+0x9d
139+
140+> 0xdead.beef
141+0xdead.beef
142+
143+> --9
144+--9
145+
146+> -79
147+-79
148+
149+> --0b1001
150+--0b1001
151+
152+> -0x9d
153+-0x9d
154+```
155+
156+All of the above are atoms. The underlying noun of each is just an unsigned integer, but each is written in a special syntax indicating to Hoon that the atom is to be represented in a different way. To see their values in the default atom notation, you can tell Hoon to throw away the aura information. Do this by preceding each expression above with `` `@` ``.
157+
158+```
159+> `@`0b1001
160+9
161+
162+> `@`0b1001.1101
163+157
164+
165+> `@`0x9d
166+157
167+
168+> `@`0xdead.beef
169+3.735.928.559
170+
171+> `@`--9
172+18
173+
174+> `@`-79
175+157
176+
177+> `@`--0b1001
178+18
179+
180+> `@`-0x9d
181+313
182+```
183+
184+The `` `@` `` syntax is used to 'cast' a value to a raw atom, i.e., an atom without an aura. Don't worry about exactly what `` `@` `` means just yet. Casts will be explained in more detail in a later lesson. For now all you need to know is that a cast doesn't change the underlying value of the noun; it's used here only to change how the value is printed in the dojo output.
185+
186+#### Identities, Cords, and Terms
187+
188+Urbit identities such as `~zod`, `~taglux-nidsep`, and `~sorreg-namtyv` are also atoms with their own distinctive syntax:
189+
190+```
191+> ~zod
192+~zod
193+
194+> ~taglux-nidsep
195+~taglux-nidsep
196+
197+> ~sorreg-namtyv
198+~sorreg-namtyv
199+
200+> `@`~zod
201+0
202+
203+> `@`~taglux-nidsep
204+6.095.360
205+
206+> `@`~sorreg-namtyv
207+5.702.400
208+```
209+
210+Hoon permits the use of atoms as strings. Strings that are encoded as atoms are called *cords*. The literal syntax of a cord is text inside a pair of single-quotes, e.g., `'Hello world!'`.
211+
212+```
213+> 'Howdy!'
214+'Howdy!'
215+
216+> `@`'Howdy!'
217+36.805.260.308.296
218+
219+> 'Hello world!'
220+'Hello world!'
221+
222+> `@`'Hello world!'
223+10.334.410.032.606.748.633.331.426.632
224+```
225+
226+Hoon also has *terms*. These are strings preceded with a `%` and made up of lower-case letters, numbers, and hyphens, i.e., 'kebab case'. The first character after the `%` must be a letter. For example, `%a`, `%hello`, `%this-is-kebab-case123`.
227+
228+```
229+> %howdy
230+%howdy
231+
232+> %this-is-kebab-case123
233+%this-is-kebab-case123
234+
235+> `@`%howdy
236+521.376.591.720
237+
238+> `@`'howdy'
239+521.376.591.720
240+
241+> `@`%this-is-kebab-case123
242+74.823.134.616.534.770.182.309.416.397.866.674.543.716.995.786.868
243+```
244+
245+#### List of Auras
246+
247+Here's a non-exhaustive list of auras, along with examples of corresponding literal syntax:
248+
249+```
250+Aura Meaning Example of Literal Syntax
251+-------------------------------------------------------------------------
252+@d date
253+ @da absolute date ~2018.5.14..22.31.46..1435
254+ @dr relative date (ie, timespan) ~h5.m30.s12
255+@n nil ~
256+@p phonemic base (urbit name) ~sorreg-namtyv
257+@r IEEE floating-point
258+ @rd double precision (64 bits) .~6.02214085774e23
259+ @rh half precision (16 bits) .~~3.14
260+ @rq quad precision (128 bits) .~~~6.02214085774e23
261+ @rs single precision (32 bits) .6.022141e23
262+@s signed integer, sign bit low
263+ @sb signed binary --0b11.1000
264+ @sd signed decimal --1.000.056
265+ @sv signed base32 -0v1df64.49beg
266+ @sw signed base64 --0wbnC.8haTg
267+ @sx signed hexadecimal -0x5f5.e138
268+@t UTF-8 text (cord) 'howdy'
269+ @ta ASCII text (knot) ~.howdy
270+ @tas ASCII text symbol (term) %howdy
271+@u unsigned integer
272+ @ub unsigned binary 0b11.1000
273+ @ud unsigned decimal 1.000.056
274+ @uv unsigned base32 0v1df64.49beg
275+ @uw unsigned base64 0wbnC.8haTg
276+ @ux unsigned hexadecimal 0x5f5.e138
277+```
278+
279+#### Casting to Other Auras
280+
281+You can force Hoon to interpret an atom differently by using the aura symbols in the chart above; e.g., `` `@ux` `` for unsigned hexadecimal, `` `@ub` `` for unsigned binary, etc.:
282+
283+```
284+> `@ux`157
285+0x9d
286+
287+> `@ub`157
288+0b1001.1101
289+
290+> `@ub`0x9d
291+0b1001.1101
292+
293+> `@ux`0b1001.1101
294+0x9d
295+```
296+
297+The atoms in the examples above are all exactly the same value. Only they're interpreted and printed differently, depending on the aura.
298+
299+For more on atoms and auras, see lesson XXXX.
300+
301+## Cells
302+
303+There's not much mystery about cells. The left of a cell is called the *head*, and the right is called the *tail*. Cells are typically represented in Hoon with square brackets around a pair of nouns.
304+
305+```
306+> [32 320]
307+[32 320]
308+```
309+
310+In this cell `32` is the head and `320` is the tail. Cells can contain cells, and atoms of other auras as well:
311+
312+```
313+> [%hello 'world!']
314+[%hello 'world!']
315+
316+> [[%in 0xa] 'cell']
317+[[%in 0xa] 'cell']
318+```
319+
320+I said there isn't _much_ mystery about cells, but there is a little. So far whenever we've entered a cell into the dojo, it not only returned the same cell; the cell was printed in the same way it was entered. This doesn't always happen. The dojo is obligated to evaluate the input and return the correct answer, but it doesn't have to show the result in exactly the same way:
321+
322+```
323+> [6 [62 620]]
324+[6 62 620]
325+
326+> [6 62 620]
327+[6 62 620]
328+
329+> [[6 62] 620]
330+[[6 62] 620]
331+```
332+
333+In the first example, the inner pair of square brackets is dropped. Why did this happen? Why is `[6 62 620]` accepted as a cell despite apparently having more than two atoms in it?
334+
335+In fact, `[6 [62 620]]` and `[6 62 620]` are considered equivalent in Hoon. A cell _must_ be a pair, which means there are always exactly two nouns in it. Whenever cell brackets are left out of the interior of a cell, so that visually there seem to be more than two child nouns, it is implicitly understood that the right-most nouns constitute a cell. That is, the tail of the whole cell is assumed to be a cell of the right-most nouns.
336+
337+This is why `[6 [62 620]]` and `[6 62 620]` are equivalent. `[6 [62 620]]` and `[[6 62] 620]`, on the other hand, are not equivalent. If you look at them as binary trees you can see the difference:
338+
339+```
340+ [6 [62 620]] [[6 62] 620]
341+ . .
342+ / \ / \
343+ 6 . . 620
344+ / \ / \
345+ 62 620 6 62
346+```
347+
348+When the dojo pretty-prints a cell it always removes superfluous cell brackets:
349+
350+```
351+> [[12 13] [[14 15] [16 17]]]
352+[[12 13] [14 15] 16 17]
353+```
354+
355+However, you should always remember that though cells can be presented as lists of more than two nouns, they're always just pairs.
356+
357+### Exercise 1.1.1
358+
359+Without using the dojo, assess whether each of the following pairs of nouns is equivalent. (Answers are at the bottom of the page.)
360+
361+```
362+1. [[1 3] [6 2]] [1 3 [6 2]]
363+2. [[[17 18] 20] 19 21] [[[17 18] 20] [19 21]]
364+3. [[[[[12 13] 14] 15] 16] 17] [12 13 14 15 16 17]
365+4. [12 [13 [14 [15 [16 17]]]]] [12 13 14 15 16 17]
366+5. [37 [99 17] 83] [37 [[99 17] 83]]
367+```
368+
369+## Noun Addresses
370+
371+Nouns have a regular structure that can be exploited to give a unique *address* to each of its 'sub-nouns'. A sub-noun is a part of a noun that is itself a noun; e.g., `[6 2]` is a sub-noun of `[[1 3] [6 2]]`. We can also call these 'noun fragments'.
372+
373+What if you want to refer to a noun fragment, and not the whole thing? For example, what if you want to refer to the `[6 2]` part of `[[1 3] [6 2]]`? One way is to use the unique address of that noun fragment.
374+
375+To define noun addresses we'll need to use recursion. The base case is trivial: address `1` of a noun is the entire noun. The generating case: if the noun at address `n` is a cell, then its head is at address `2n` and its tail is at address `2n + 1`. For example, if address `5` of some noun is a cell, then its head is at address `10` and its tail address `11`.
376+
377+Address 1 of the noun `[[1 3] [6 2]]` is the whole noun: `[[1 3] [6 2]]`. The head of the noun at address `1`, `[1 3]`, is at address `2 x 1`, i.e., `2`. The tail of the noun at address `1`, `[6 2]`, is at address `(2 x 1) + 1`, i.e., `3`.
378+
379+If the way this works isn't immediately clear, remember that each noun can be understood as a binary tree. The following diagram shows the address of several nodes of the tree:
380+
381+```
382+ 1
383+ / \
384+ 2 3
385+ / \ / \
386+ 4 5 6 7
387+ / \
388+ 14 15
389+```
390+
391+Let's do some examples in the dojo. We're going to use the `slot` operator, `+`, to return fragments of a noun. For any unsigned integer `n`, `+n` evaluates to the fragment at address `n`.
392+
393+```
394+> +1:[22 [33 44]]
395+[22 33 44]
396+
397+> +2:[22 [33 44]]
398+22
399+
400+> +3:[22 [33 44]]
401+[33 44]
402+
403+> +6:[22 [33 44]]
404+33
405+
406+> +7:[22 [33 44]]
407+44
408+```
409+
410+You'll notice that we use the `:` symbol between the slot syntax and the noun. Don't worry about what this means yet; we'll explain it in another lesson. For now you can read it as the word "of": `+7:[22 [33 44]]` is "slot `7` of `[22 [33 44]]`".
411+
412+What happens if you ask for a fragment that doesn't exist?
413+
414+```
415+> +4:[22 [33 44]]
416+ford: build failed *stack trace*
417+```
418+
419+Let's do a few more examples:
420+
421+```
422+> +2:[['apple' %pie] [0b1101 0xdad]]
423+['apple' %pie]
424+
425+> +5:[['apple' %pie] [0b1101 0xdad]]
426+%pie
427+
428+> +2:[[%one %two] [%three %four] [%five %six]]
429+[%one %two]
430+
431+> +3:[[%one %two] [%three %four] [%five %six]]
432+[[%three %four] %five %six]
433+
434+> +15:[[%one %two] [%three %four] [%five %six]]
435+%six
436+```
437+
438+For those who prefer to think in terms of binary numbers and binary trees, there is another (equivalent) way to understand noun addressing. When the noun address is expressed as a binary number, you can think of the the number as indicating a tree path from the top node.
439+
440+As before, the root of the binary tree (i.e., the whole noun) is at address `1`. For the node of a tree at any address `b`, where `b` is a binary number, you get the address of its head by concatenating a `0` to the end of `b`; and to get its tail, concatenate a `1` to the end. For example, the head of the node at binary address `111` is at `1110`, and the tail is at `1111`.
441+
442+Address `1110` indicates "the head of the tail of the tail of the noun".
443+
444+### Exercise 1.1.2
445+
446+Without using the dojo, evaluate the following expressions. (Answers are at the bottom of the page.)
447+
448+```
449+1. +6:[[34 54] [86 48]]
450+2. +3:[13 [[[65 35] 54] 77]]
451+3. +12:[13 [[[65 35] 54] 77]]
452+4. +7:[13 [[[65 35] 54] 77]]
453+5. +10:[[[2 4 5] [3 6]] 11]
454+```
455+
456+### Exercise 1.1.3
457+
458+Without using the dojo, for each fragment below provide the address relative to the noun `[51 52 53 54 55]`. (Answers are at the bottom of the page.)
459+
460+```
461+1. 51
462+2. 52
463+3. 53
464+4. [54 55]
465+5. 55
466+```
467+
468+That's it for our basic introduction to nouns. Hit `ctrl-d` to exit your comet, or else move on to the next lesson.
469+
470+## 1.1 Exercise Answers
471+
472+### 1.1.1
473+
474+1. No
475+2. Yes
476+3. No
477+4. Yes
478+5. Yes
479+
480+### 1.1.2
481+
482+1. 86
483+2. [[[65 35] 54] 77]
484+3. [65 35]
485+4. 77
486+5. 3
487+
488+### 1.1.3
489+
490+1. +2
491+2. +6
492+3. +14
493+4. +15
494+5. +31
docs/tutorials/hoon-ch1/hoon-ch1-3.umdnew file+657
@@ -0,0 +1,657 @@
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3+ next/'true'
4+ sort/'3'
5+ title/'The Subject and Its Legs'
6+ ==
7+;>
8+
9+# 1.3 The Subject and Its Legs
10+
11+Hoon isn't an object-oriented programming language; it's a "subject-oriented" programming language. But what's this "subject"?
12+
13+## A Start
14+
15+For now we can say three things about the subject: (1) every Hoon expression is evaluated relative to some subject; (2) roughly, the subject defines the environment in which a Hoon expression is evaluated; and (3) the subject is a noun.
16+
17+In fact, you already created some subjects in lesson 1.2 when you used `+` to return a fragment of a noun:
18+
19+```
20+> +1:[[11 22] 33]
21+[[11 22] 33]
22+
23+> +2:[[11 22] 33]
24+[11 22]
25+
26+> +3:[[11 22] 33]
27+33
28+```
29+
30+The `:` operator does two things. First, it evaluates the expression on the right-hand side; and second, it evaluates the expression on the left-hand side, using the product of the right-hand side as its subject.
31+
32+In the examples above, the expression on the right-hand, `[[11 22] 33]`, evaluates to itself:
33+
34+```
35+> [[11 22] 33]
36+[[11 22] 33]
37+```
38+
39+...so the subject for the left-hand expression is simply `[[11 22] 33]`. The `+` operator is used to produce some fragment of the subject at a given address. E.g., `+2`, returns whatever is at address `2` of the subject. Hence, we may read `+2:[[11 22] 33]` as "address `2` of the subject produced by `[[11 22] 33]`".
40+
41+Let's create a subject with some computations:
42+
43+```
44+> [[(add 22 33) (mul 2 6)] 23]
45+[[55 12] 23]
46+
47+> +1:[[(add 22 33) (mul 2 6)] 23]
48+[[55 12] 23]
49+
50+> +2:[[(add 22 33) (mul 2 6)] 23]
51+[55 12]
52+
53+> +3:[[(add 22 33) (mul 2 6)] 23]
54+23
55+
56+> +4:[[(add 22 33) (mul 2 6)] 23]
57+55
58+```
59+
60+`add` and `mul` are functions of the Hoon standard library. `add` is used to add two atoms, and `mul` is used to multiply them.
61+
62+## Limbs of the Subject
63+
64+The subject is a noun, just like any other piece of Hoon data. In the last lesson we discussed how any noun can be understood as a binary tree. E.g., `[[4 5] [6 [14 15]]]`:
65+
66+```
67+ [[4 5] [6 [14 15]]]
68+ .
69+ / \
70+ . .
71+ / \ / \
72+ 4 5 6 .
73+ / \
74+ 14 15
75+```
76+
77+Each fragment of a noun is itself a noun, and hence can be understood as a binary tree as well. Each fragment or 'subtree' sticks out of the original tree, like a *limb*. A 'limb' is a subtree of the subject.
78+
79+Sometimes a programmer simply wants to produce a value from the subject. In other cases more is desired -- programmers often want to carry out substantive computations on data in the subject. There are two kinds of limbs to accommodate these two cases: arms and legs.
80+
81+*Arms* are limbs of the subject that are used for carrying out substantive computations. We'll talk about arms in the next lesson. *Legs* are limbs that store data. Any limb that isn't an arm is a leg. In this lesson we'll talk about various ways to access legs of the subject.
82+
83+### Address-based Limb Expressions
84+
85+A limb expression is an expression of Hoon that resolves to a limb of the subject. An address-based limb expression evaluates to a limb of the subject based on its address. (You learned about the noun address system in the last lesson.)
86+
87+In the following you'll learn the various limb expressions available in Hoon, as well as how they work when they resolve to legs. First we'll explain the limb expressions that return a leg according to subject address.
88+
89+#### `+` operator
90+
91+You've already used this. For any unsigned integer `n`, `+n` returns the limb of the subject at address `n`. If there is no such limb, the result is a crash.
92+
93+```
94+> +2:[111 222 333]
95+111
96+
97+> +3:[111 222 333]
98+[222 333]
99+
100+> +6:[111 222 333]
101+222
102+```
103+
104+#### `.` expression
105+
106+Using `.` as an expression returns the entire subject. It's equivalent to `+1`.
107+
108+```
109+> .:[[4 5] [6 [14 15]]]
110+[[4 5] 6 14 15]
111+
112+> .:[4 5]
113+[4 5]
114+
115+> .:'The whole subject!'
116+'The whole subject!'
117+```
118+
119+#### 'lark' expressions (`+`, `-`, `+>`, `+<`, `->`, `-<`, etc.)
120+
121+Using `-` by itself returns the head of the subject, and using `+` by itself returns the tail:
122+
123+```
124+> -:[[4 5] [6 [14 15]]]
125+[4 5]
126+
127+> +:[[4 5] [6 [14 15]]]
128+[6 14 15]
129+```
130+
131+To think of it another way, `-` is for the left and `+` is for the right. You can remember this by thinking of a number line -- the negative numbers are to the left, the positive numbers to the right.
132+
133+`-` and `+` only work if the subject is a cell, naturally. An atom doesn't have a head or a tail.
134+
135+```
136+> +:12
137+ford: build failed [crash message]
138+```
139+
140+What if you want the tail of the tail of the subject? You might expect that you can double up on `+` for this: `++`. Not so. Instead, combine `+` with `>`: `+>`. `>` means the same thing as `+`, but is used with `+` to make for easier reading.
141+
142+And the analogous point also holds for `-` and `<`. You can combine `+` or `-` with either of `>` or `<` to get a more specific limb of the subject. `-<` returns the head of the head; `->` returns the tail of the head; and `+<` returns the head of the tail.
143+
144+```
145+> -<:[[4 5] [6 [14 15]]]
146+4
147+
148+> ->:[[4 5] [6 [14 15]]]
149+5
150+
151+> +<:[[4 5] [6 [14 15]]]
152+6
153+
154+> +>:[[4 5] [6 [14 15]]]
155+[14 15]
156+```
157+
158+By alternating the `+`/`-` symbols with `<`/`>` symbols, you can grab an even more specific limb of the subject:
159+
160+```
161+> +>-:[[4 5] [6 [14 15]]]
162+14
163+
164+> +>+:[[4 5] [6 [14 15]]]
165+15
166+```
167+
168+You can think of this sort of lark series -- e.g., `+>-<` -- as indicating a binary tree path to a limb of the subject, starting from the root node of the tree. In the case of `+>-<` this path is: tail, tail, head, head.
169+
170+```
171+ *Root*
172+ / \
173+ Head *Tail*
174+ / \
175+ Head *Tail*
176+ / \
177+ *Head* Tail
178+ / \
179+ *Head* Tail
180+```
181+
182+#### `&` and `|` operators
183+
184+`&n` returns the `n`th item of a list that has at least `n + 1` items. `|n` returns everything after `&n`.
185+
186+But what's a list? There are two kinds of lists: empty and non-empty. The empty list is null, `~`. A non-empty list is a cell whose head is the first item and whose tail is the rest of the list. 'The rest of the list' is itself a list. Hoon lists are null-terminated; that is, the null symbol `~` indicates the end of the list. Consider the following cell of nouns:
187+
188+```
189+> ['first' 'second' 'third' 'fourth' ~]
190+['first' 'second' 'third' 'fourth' ~]
191+```
192+
193+The `'first'` noun is at `+2`, `'second'` is at `+6`, `'third'` is at `+14`, and so on. (Try it!) That's because the above noun is really the following:
194+
195+```
196+> ['first' ['second' ['third' ['fourth' ~]]]]
197+['first' 'second' 'third' 'fourth' ~]
198+```
199+
200+...with the superfluous brackets removed. Rather than using `+2` to produce `'first'` and `+6` to produce `'second'`, you can use `&1` and `&2` to produce the first and second items in the list, respectively:
201+
202+```
203+> &1:['first' 'second' 'third' 'fourth' ~]
204+'first'
205+
206+> &2:['first' 'second' 'third' 'fourth' ~]
207+'second'
208+
209+> &3:['first' 'second' 'third' 'fourth' ~]
210+'third'
211+
212+> &4:['first' 'second' 'third' 'fourth' ~]
213+'fourth'
214+```
215+
216+The list items can themselves be cells:
217+
218+```
219+> &1:[['first' %pair] ['second' %pair] ['third' %pair] ~]
220+['first' %pair]
221+
222+> &2:[['first' %pair] ['second' %pair] ['third' %pair] ~]
223+['second' %pair]
224+
225+> &3:[['first' %pair] ['second' %pair] ['third' %pair] ~]
226+['third' %pair]
227+```
228+
229+We can give an alternate, recursive definition of `&n` for all positive integers `n`. In the base case, `&1` is equivalent to `+2`. For the generating case, assume that `&(n - 1)` is equivalent to `+k`. Then `&n` is equivalent to `+((k x 2) + 2)`.
230+
231+For example, let `n` be 4. What is `&4`? `&3` is equivalent to `+14`. `(14 x 2) + 2` is `30`, so `&4` is equivalent to `+30`.
232+
233+`|n` returns the rest of the list after `&n`:
234+
235+```
236+> |1:['first' 'second' 'third' 'fourth' ~]
237+['second' 'third' 'fourth' ~]
238+
239+> |2:['first' 'second' 'third' 'fourth' ~]
240+['third' 'fourth' ~]
241+
242+> |3:['first' 'second' 'third' 'fourth' ~]
243+['fourth' ~]
244+
245+> |4:['first' 'second' 'third' 'fourth' ~]
246+~
247+```
248+
249+As with `&n`, we can characterize `|n` recursively. In the base case, `|1` is `+3`. In the generating case, assume that `&(n - 1)` is equivalent to `+k`. Then `&n` is equivalent to `+((k x 2) + 3)`.
250+
251+### Other Limb Expressions: Names
252+
253+Working with specific addresses of the subject can be cumbersome even when the subject is small. When the subject is a really large noun -- as is often the case -- it's downright impractical. Thankfully there's a more convenient method for resolving to a limb of the subject: using names.
254+
255+A name can resolve to either an arm or a leg of the subject. Recall that arms are for computations and legs are for data. When a name resolves to an arm, the relevant computation is run and the product of the computation is produced. When a limb name resolves to a leg, the value of that leg is produced. We aren't yet ready to talk about arm resolution; for now let's focus on leg names.
256+
257+#### Faces
258+
259+Hoon doesn't have variables like other programming languages do; it has 'faces'. Faces are like variables in certain respects, but not in others. Faces play various roles in Hoon, but most frequently faces are used simply as labels for legs.
260+
261+A face is a limb expression that consists of a series of alphanumeric characters. A face has a combination of lowercase letters, numbers, and the `-` character. Some example faces: `b`, `c3`, `var`, `this-is-kebab-case123`. Faces must begin with a letter.
262+
263+There are various ways to affix a face to a limb of the subject, but for now we'll use the simplest method: `face=value`. An expression of this form is equivalent in value to simply `value`. Hoon registers the given `face` as metadata about where the value is stored in the subject, so that when that face is invoked later its data is produced.
264+
265+```
266+> b=5
267+b=5
268+
269+> [b=5 cat=6]
270+[b=5 cat=6]
271+
272+> -:[b=5 cat=6]
273+b=5
274+
275+> b:[b=5 cat=6]
276+5
277+
278+> b2:[[4 b2=5] [cat=6 d=[14 15]]]
279+5
280+
281+> d:[[4 b2=5] [cat=6 d=[14 15]]]
282+[14 15]
283+```
284+
285+To be clear, `b=5` is equivalent in value to `5`, and `[[4 b2=5] [cat=6 d=[14 15]]]` is equivalent in value to `[[4 5] 6 14 15]`. The faces are not part of the underlying noun; they're stored as metadata about address values in the subject.
286+
287+If you use a face that isn't in the subject you'll get a `find.[face]` crash:
288+
289+```
290+> a:[b=12 c=14]
291+-find.a
292+[crash message]
293+```
294+
295+You can give your faces faces:
296+
297+```
298+> b:[b=c=123 d=456]
299+c=123
300+```
301+
302+#### Duplicate Faces
303+
304+There is no restriction against using the same face name for multiple limbs of the subject. This is one way in which faces aren't like ordinary variables:
305+
306+```
307+> [[4 b=5] [b=6 b=[14 15]]]
308+[[4 b=5] b=6 b=[14 15]]
309+
310+> b:[[4 b=5] [b=6 b=[14 15]]]
311+5
312+```
313+
314+Why does this return `5` rather than `6` or `[14 15]`? When a face is evaluated against a subject, a head-first binary tree search occurs starting at address `1` of the subject. If there is no matching face for address `n` of the subject, first the head of `n` is searched and then `n`'s tail. The total search path for `[[4 b=5] [b=6 b=[14 15]]]` is:
315+
316+1. `[[4 b=5] [b=6 b=[14 15]]]`
317+1. `[4 b=5]`
318+1. `4`
319+1. `b=5`
320+1. `[b=6 b=[14 15]]`
321+1. `b=6`
322+1. `b=[14 15]`
323+
324+There are matches at steps 4, 6, and 7 of the total search path, but the search ends when the first match is found at step 4.
325+
326+The children of legs bearing names aren't included in the search path. For example, the search path of `[[4 a=5] b=[c=14 15]]` is:
327+
328+1. `[[4 a=5] b=[c=14 15]]`
329+1. `[4 a=5]`
330+1. `4`
331+1. `a=5`
332+1. `b=[c=14 15]`
333+
334+Neither of the legs `c=14` or `15` is checked. Accordingly, a search for `c` of `[[4 a=5] b=[c=14 15]]` fails:
335+
336+```
337+> c:[[4 b=5] [b=6 b=[c=14 15]]]
338+-find.c [crash message]
339+```
340+
341+There are cases when you don't want the limb of the first matching face. You can 'skip' the first match by prepending `^` to the face. Upon discovery of the first match at address `n`, the search skips `n` (as well as its children) and continues the search elsewhere:
342+
343+```
344+> ^b:[[4 b=5] [b=6 b=[14 15]]]
345+6
346+```
347+
348+Recall that the search path for this noun is:
349+
350+1. `[[4 b=5] [b=6 b=[14 15]]]`
351+1. `[4 b=5]`
352+1. `4`
353+1. `b=5`
354+1. `[b=6 b=[14 15]]`
355+1. `b=6`
356+1. `b=[14 15]`
357+
358+The second match in the search path is step 6, `b=6`, so the value at that leg is produced. You can stack `^` characters to skip more than one matching face:
359+
360+```
361+> a:[[[a=1 a=2] a=3] a=4]
362+1
363+
364+> ^a:[[[a=1 a=2] a=3] a=4]
365+2
366+
367+> ^^a:[[[a=1 a=2] a=3] a=4]
368+3
369+
370+> ^^^a:[[[a=1 a=2] a=3] a=4]
371+4
372+```
373+
374+When a face is skipped at some address `n`, neither the head nor the tail of `n` is searched:
375+
376+```
377+> b:[b=[a=1 b=2 c=3] a=11]
378+[a=1 b=2 c=3]
379+
380+> ^b:[b=[a=1 b=2 c=3] a=11]
381+-find.^b
382+```
383+
384+The first `b`, `b=[a=1 b=2 c=3]`, is skipped; so the entire head of the subject is skipped. The tail has no `b`; so `^b` doesn't resolve to a limb when the subject is `[b=[a=1 b=2 c=3] a=11]`.
385+
386+How do you get to that `b=2`? And how do you get to the `c` in `[[4 a=5] b=[c=14 15]]`? In each case you should use a wing.
387+
388+## Wings
389+
390+A wing is a search path into the subject, understood as a series of limbs.
391+
392+A wing expression indicates the search path as a series of limb expressions separated by the `.` character.
393+
394+```
395+[limb1].[limb2].[limb3].[and so on....]
396+```
397+
398+You can read this as `limb1` in `limb2` in `limb3`, etc. You can use a wing to get the value of `c` in `[[4 a=5] b=[c=14 15]]`: `c.b`
399+
400+```
401+> c.b:[[4 a=5] b=[c=14 15]]
402+14
403+```
404+
405+And to get the `b` inside the head of `[b=[a=1 b=2 c=3] a=11]`: `b.b`.
406+
407+```
408+> b.b:[b=[a=1 b=2 c=3] a=11]
409+2
410+
411+> a.b:[b=[a=1 b=2 c=3] a=11]
412+1
413+
414+> c.b:[b=[a=1 b=2 c=3] a=11]
415+3
416+
417+> a:[b=[a=1 b=2 c=3] a=11]
418+11
419+
420+> b.a:[b=[a=1 b=2 c=3] a=11]
421+-find.b.a
422+```
423+
424+Here are some other wing examples:
425+
426+```
427+> g.s:[s=[c=[d=12 e='hello'] g=[h=0xff i=0b11]] r='howdy']
428+[h=0xff i=0b11]
429+
430+> c.s:[s=[c=[d=12 e='hello'] g=[h=0xff i=0b11]] r='howdy']
431+[d=12 e='hello']
432+
433+> e.c.s:[s=[c=[d=12 e='hello'] g=[h=0xff i=0b11]] r='howdy']
434+'hello'
435+
436+> +3:[s=[c=[d=12 e='hello'] g=[h=0xff i=0b11]] r='howdy']
437+r='howdy'
438+
439+> r.+3:[s=[c=[d=12 e='hello'] g=[h=0xff i=0b11]] r='howdy']
440+'howdy'
441+```
442+
443+### Limbs are Trivial Wings
444+
445+As stated before, a wing is a series of limbs indicating a search path into the subject. This definition includes as a trivial case a search path of one limb. Thus, all limbs are wings and all limb expressions are wing expressions.
446+
447+We mention this because it is convenient to refer to all limbs and non-trivial wings as simply 'wings'. This will be our usual practice for the rest of this tutorial series.
448+
449+## Exploring the Subject
450+
451+Earlier we said that every Hoon expression is evaluated relative to a subject. We then showed how the `:` operator uses a Hoon expression on the right-hand side to set the subject for the expression on the left.
452+
453+```
454+> b:[b='Hello world!' c='This is the tail of the subject for the LHS']
455+'Hello world!'
456+```
457+
458+So, the left uses the product of the right as its subject. But what about the right-hand expression? What's _its_ subject? Until now we've included an explicit subject in all the examples, but it's time to remove the training wheels. Usually the subject of a Hoon expression isn't shown explicitly.
459+
460+Consider the expression `(add 2 2)`:
461+
462+```
463+> (add 2 2)
464+4
465+```
466+
467+What's its subject?
468+
469+In fact, you may already know how to find the answer. The subject is a noun and as such its limbs have addresses. To see that noun, use `+1`. You'll see something like the following:
470+
471+```
472+> +1
473+[ [ our=~mipfyl-lodsel-halrul-dilbyt--balluc-havfes-wordeb-pagrem
474+ now=~2018.5.24..23.51.31..f5f2
475+ eny
476+ \/0vfq.npac6.eklcb.19rir.el97m.1jaq4.m3ths.ejfa5.cpjiu.fk1uh.kqf9r.jncko.\/
477+ 7eorl.ciggn.4hi3g.gna8v.qrpvc.rd32q.t60pj.8v7ev.27g2c
478+ \/ \/
479+ ]
480+ ~
481+ <16.swm 19.mtp 41.lur 112.twd 224.bkh 54.tyv 119.wpb 31.ohr 1.jmk $143>
482+]
483+```
484+
485+This noun (or a modified version of it) is the subject used for all Hoon expressions entered into the dojo.
486+
487+We can't explain every part of the subject just yet, but you should be able to recognize some of it. There is a face, `our`, serving as a label for a a comet name. Another face, `now`, is a label for an absolute date. `eny` is a face for an atom serving as [entropy](https://en.wikipedia.org/wiki/Entropy_(computing)). The value for `eny` is different every time it's checked.
488+
489+```
490+> our
491+~mipfyl-lodsel-halrul-dilbyt--balluc-havfes-wordeb-pagrem
492+
493+> now
494+~2018.5.24..23.55.34..1ef0
495+
496+> eny
497+\/0v10v.b4347.pnopi.p2vb4.bohf6.cog4h.m9hld.o2kuq.5pbfg.esrug.1bc0s.u12fo.uit6c\/
498+ .9ets2.g9ssi.kqsg7.j12n3.79aim.d2g3s.aumrs.kis80
499+\/ \/
500+> eny
501+\/0v2q2.va8mn.f6teu.42skq.sc2rh.4p8r6.klrbg.vovm7.7b13l.3tp1g.f33as.7267s.4tj13\/
502+ .p1aa1.um1ee.80fd3.l11b5.sfqen.5aumu.c17vm.3rq45
503+\/
504+```
505+
506+Also embedded in that subject is the Hoon 'standard library', a library of commonly-used functions. We've already used two of them: `add` and `mul`. Have you noticed that these function names look like faces? They aren't faces, but Hoon searches for them like it searches for faces. When we call `add`,
507+
508+```
509+> (add 22 33)
510+55
511+```
512+
513+...it only works because Hoon finds `add` somewhere in the subject. We can make a subject that doesn't have `add` in it and try to use it:
514+
515+```
516+> (add 22 33):[123 456]
517+-find.add
518+
519+> (add 22 33):['This subject' 'is austere.']
520+-find.add
521+```
522+
523+It doesn't work because, as far as Hoon is concerned, `add` doesn't exist for the expression on the left. We can put `add` back into the subject manually, however:
524+
525+```
526+> (add 22 33):[123 456 add]
527+55
528+```
529+
530+And it works! The subject of the right-hand side expression of the `:` is the same implicit subject we have in the dojo.
531+
532+## Dojo Faces
533+
534+We're playing in the Urbit `dojo`. The dojo is like a cross between a Lisp REPL and the Unix shell. (If you know the Unix shell, the Urbit command line has the same history model and Emacs editing commands.)
535+
536+It's worth taking a moment to learn about certain features of the dojo that aren't part of Hoon, but which can be handy to experiment with when learning Hoon.
537+
538+You can use the dojo to add a noun with a face to the subject. Type:
539+
540+```
541+> =a 37
542+```
543+
544+You've added `37` to the dojo subject with the face `a`. Hoon expressions entered into the dojo can now use `a` and it will resolve to this value. So you can write:
545+
546+```
547+> a
548+37
549+
550+> [4 a]
551+[4 37]
552+
553+> (add a a)
554+74
555+
556+> (mul a a)
557+1.369
558+```
559+
560+To unbind `a` and remove its value from the subject, enter `=a` and omit the value:
561+
562+```
563+> =a
564+```
565+
566+You removed `a` from the subject. (We can bind it again later, or bind over it without removing it.)
567+
568+```
569+> [4 a]
570+-find.a
571+```
572+
573+### Dojo Fun
574+
575+We can use dojo faces to get used to how wings work.
576+
577+```
578+> =a [g=37 b=[%hi c=.6.28] h=0xdead.beef]
579+
580+> a
581+[g=37 b=[%hi c=.6.28] h=0xdead.beef]
582+
583+> g.a
584+37
585+
586+> b.a
587+[%hi c=.6.28]
588+
589+> c.b.a
590+.6.28
591+
592+> +2.a
593+g=37
594+
595+> +3.a
596+[b=[%hi c=.6.28] h=0xdead.beef]
597+```
598+
599+Here are a few more examples:
600+
601+```
602+> c:[c=[d=15 e=20] f=[g=45 h=50]]
603+[d=15 e=20]
604+
605+> -.c:[c=[d=15 e=20] f=[g=45 h=50]]
606+d=15
607+
608+> +.c:[c=[d=15 e=20] f=[g=45 h=50]]
609+e=20
610+
611+> +1.c:[c=[d=15 e=20] f=[g=45 h=50]]
612+[d=15 e=20]
613+
614+> ..c:[c=[d=15 e=20] f=[g=45 h=50]]
615+[d=15 e=20]
616+```
617+
618+### Creating a Modified Leg
619+
620+Often a leg of the subject is produced with its value unchanged. But there is a way to produce a modified version of the leg as well. To do so, we use an expression of the form:
621+
622+```
623+wing-of-subject(wing-1 new-value-1, wing-2 new-value 2, ...)
624+```
625+
626+The `wing-of-subject` is a wing path into the subject, followed by a set of parentheses. `wing-1` and `wing-2` are wing paths into the limb indicated by `wing-of subject`, and their values are replaced with `new-value-1` and `new-value-2`, respectively. Commas separate each of the `wing` `new-value` pairs.
627+
628+Let's create a mutant version of the noun we have stored in `a`. To do this, type in the face `a` followed by the desired modifications in parentheses:
629+
630+```
631+> a
632+[g=37 b=[%hi c=.6.28] h=0xdead.beef]
633+
634+> a(g 44)
635+[g=44 b=[%hi c=.6.28] h=0xdead.beef]
636+
637+> a(b 'hello world!')
638+[g=37 b='hello world!' h=0xdead.beef]
639+
640+> a(b 'hello world!', h 0xfeed.beef)
641+[g=37 b='hello world!' h=0xfeed.beef]
642+
643+> a(b 'hello world!', h 0xfeed.beef, g 123)
644+[g=123 b='hello world!' h=0xfeed.beef]
645+
646+> a(+2 r=457.842)
647+[r=457.842 b=[%hi c=.6.28] h=0xdead.beef]
648+```
649+
650+You can also use more complex wings and modify their values as well:
651+
652+```
653+> b.a(c .3.14)
654+[%hi c=.3.14]
655+```
656+
657+At this point you should have at least a rough idea of what the subject is, and a fair understanding of how to get legs of the subject using wings. But legs are only one kind of limb -- we'll talk about arms in the next lesson.
docs/tutorials/hoon-ch1/hoon-ch1-4.umdnew file+481
@@ -0,0 +1,481 @@
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3+ next/'true'
4+ sort/'4'
5+ title/'Arms and Cores'
6+ ==
7+;>
8+
9+# 1.4 Arms and Cores
10+
11+The Hoon subject is made up of arms and legs. In the previous lesson you learned what a leg is, and how to return legs of the subject by various means. In this lesson you'll learn what an arm is. Arms are a bit more complex than legs -- a full understanding of them requires a bit more background knowledge. Accordingly, in this lesson we also (1) give a brief overview on Nock, a low-level functional programming language to which Hoon is compiled, and (2) define an important Hoon data structure: 'cores'.
12+
13+After arms are defined and explained we review wing expressions, this time focusing on wing resolution to arms rather than legs.
14+
15+## Arms: A Preliminary Explanation
16+
17+Arms and legs are limbs of the subject, i.e., noun fragments of the subject. In the last lesson we said that legs are for data and arms are for computations. But what _specifically_ is an arm, and how is it used for computation?
18+
19+Let's begin with a preliminary definition that will be refined later in the lesson. An *arm* is a Nock formula in the battery of a core.
20+
21+Now you just need to know what a 'Nock formula' is, what a 'battery' is, and what a 'core' is! Read on:
22+
23+## Computing Hoon
24+
25+Hoon runs on your urbit, which is a virtual computer. However, this virtual computer doesn't directly understand Hoon; it has a Nock interpreter instead. Any Hoon code you want to run must first be compiled to Nock. You certainly don't have to know Nock to understand Hoon, but it helps to be aware of a few of Nock's general features.
26+
27+Nock is a [low-level](https://en.wikipedia.org/wiki/Low-level_programming_language), [functional programming](https://en.wikipedia.org/wiki/Functional_programming) language. As a consequence Nock itself can be understood as a function, called the 'Nock function'. Nock is officially defined by the Nock spec (link).
28+
29+### What is a Function?
30+
31+The word 'function' is used in various ways in other programming languages, but we mean it in basically its [mathematical sense](https://en.wikipedia.org/wiki/Function_(mathematics)). Roughly put, a function takes one or more arguments (i.e., input values) and returns a value. What the return value is depends solely on the argument(s), and nothing else. For example, we can understand multiplication as a function: it takes two numbers and returns another number. It doesn't matter where you ask, when you ask, or what kind of hat you're wearing when you ask. If you pass the same two numbers (e.g., `3` and `4`), you get the same answer returned every time (`12`).
32+
33+### The Nock Function
34+
35+The 'Nock function' takes two arguments: (1) a subject, and (2) a Nock formula. The subject is a noun. The formula is, loosely speaking, some instructions encoded as another noun. The Nock function takes those two arguments and returns another noun called the 'product'.
36+
37+The Nock function: `[subject formula] -> product`
38+
39+Here's an example of some Nock run in the dojo, using `.*( )`:
40+
41+```
42+> .*([15 17] [[4 0 2] [0 3]])
43+[16 17]
44+```
45+
46+In this example `[15 17]` is the subject, `[[4 0 2] [0 3]]` is the formula, and `[16 17]` is the product.
47+
48+This tutorial series is designed to teach you Hoon. For that purpose it's not important that you know how to read and understand Nock formulas; you just need to know that Nock takes a subject and a formula and returns a product. (Those who who want to learn more about Nock should head over to the Nock tutorial (link).)
49+
50+### Nock Formulas Define Functions
51+
52+Each Nock formula defines a function of the subject.
53+
54+As stated previously, a Nock formula is just a noun that represents a set of instructions. When the Nock interpreter computes the Nock formula against a subject, the 'instructions' can manipulate and/or modify fragments of the subject, but the instructions have access to no other data. Accordingly, we may think of each Nock formula as defining a function with the subject itself as the argument.
55+
56+Urbit community members have written Nock formulas for various functions: addition, multiplication, and more. One obsessive individual went overboard and wrote a Nock formula that tests whether a given number is a counterexample to the [Goldbach conjecture](https://en.wikipedia.org/wiki/Goldbach%27s_conjecture).
57+
58+Keep in mind that Nock is a low-level language. Programming interesting functions in it isn't especially practical. That's why you have Hoon.
59+
60+### Arms are Nock formulas
61+
62+An arm is a _certain kind_ of Nock formula in the battery of a core. Each arm expects the subject to have a certain arrangement so that it can find the data it needs to operate correctly. (This point will be discussed in more detail shortly.) The subject must be a core. What's a core?
63+
64+## Cores
65+
66+A *core* is a cell of a *battery* and a *payload*.
67+
68+```
69+A core: [battery payload]
70+```
71+
72+Simply put, the battery is code and the payload is data. The payload contains all data necessary for running the code in the battery correctly.
73+
74+### Battery
75+
76+A battery is a cell containing one or more arm(s). That is, a battery is one or more Nock formula(s) that, when computed, expect the subject to be organized as a core. For Hoon programming it's not important to know just how those arms are arranged in the battery. Just keep in mind that this is where the core's computations live.
77+
78+### Payload
79+
80+As stated earlier, the payload is data. In principle, the payload of a core can have data arranged in any arbitrary configuration. In practice, the payload often has a predictable structure of its own.
81+
82+The payload of a core *C* contains whatever data is necessary to run the arms of *C* correctly. This data may include other cores. Consequently, *C*'s payload data can include other 'code' -- cores in the payload have their own arms.
83+
84+### Each Arm Computes with its Parent Core as the Subject
85+
86+Arms are Nock formulas. But Nock formulas are primitive in many respects. There is no basic Nock operation for looking up face values in the subject, for example. So how do arm 'instructions' find what they need in the subject? The answer is: by assuming that the subject is organized a particular way.
87+
88+#### Subject Organization for Arm Computation
89+
90+Up to this point in our dojo examples we haven't organized the subject according to any intentional pattern. The subject for most examples was so small that it wasn't worth the effort to bother with tidying it up.
91+
92+However, if a subject is sufficiently large and complex -- e.g., it has a standard library of Hoon functions, as the dojo subject does -- then organization becomes a pressing practical matter. It's much better if the subject can be assumed to have a specific, standard arrangement. This is one reason Hoon enforces subject organization for arm computations.
93+
94+The subject must be organized as a core. But not just any core! For an arm to compute correctly, the subject must be the arm's *parent core*.
95+
96+#### The Parent Core of an Arm
97+
98+Each arm is contained in the battery of a core. That core is the parent core of the arm. In other words: the *parent core* of an arm *A* is the core whose battery contains *A*.
99+
100+Why must an arm have its parent core as the subject, when it's computed? As stated previously, the payload of a core contains all the data needed for computing the arms of that core. Remember that arms can only access data in the subject. By requiring that the parent core be the subject we guarantee that each arm has the appropriate data available to it, in the payload.
101+
102+An arm can also make use of the other arms in its parent core. This is a useful feature of arms that will be discussed in more detail later.
103+
104+## Final Definition of an Arm
105+
106+Now that you have the relevant background knowledge about cores, we can finally give a complete definition of what an arm is.
107+
108+An arm is a Nock formula in the battery of a core, and it's to be computed with its parent core as the subject.
109+
110+## Wings that Resolve to Arms
111+
112+To reinforce your newfound understanding of arms and cores, let's go over various dojo examples illustrating their properties. These examples use and illustrate how wings resolve to arms. Face resolution to a leg of the subject produces the leg value unchanged, but resolution to an arm produces the _computed_ value of that arm.
113+
114+To show how this works, we'll look at how the various wing expressions behave when they resolve to arms instead of legs.
115+
116+### Building a Core of Your Own
117+
118+Before getting to the arm examples we need to produce a simple core. We'll do this using a multi-line Hoon expression that is more complex than the other examples you've seen up to this point. The dojo can be used to input multi-line Hoon expressions; just type each line, hitting 'enter' or 'return' at the end. The expression will be evaluated at the appropriate line break, i.e., when the dojo recognizes it as complete.
119+
120+First let's use the dojo to bind the face `a` to the value `12`, and the face `b` to the value `[22 24]`. These values will be used in the arms of the core we're going to make. Afterward use `.` to see the value of the subject:
121+
122+```
123+> =a 12
124+
125+> =b [22 24]
126+
127+> .
128+[ [ [a=12 b=[22 24]]
129+ our=~bitnus-holleb-rocmeg-fotfer--migsum-nidsym-hilput-patmus
130+ now=~2018.8.17..23.53.43..c6b5
131+ eny
132+ \/0vqg.quub6.1vjms.es43r.rogsb.91okf.bcvtp.eeoih.or9ge.18ere.jtk15.3afb4.5d\/
133+ qp2.f7cqj.tj4bh.m7ja9.r1i9m.5scdh.ih7qa.dqm18.q5b4r
134+ \/ \/
135+ ]
136+ ~
137+ <16.igq 19.rrs 41.xjd 112.hmp 224.nab 54.tyv 119.wim 31.ohr 1.jmk $143>
138+]
139+```
140+
141+You can see that `a` and `b` have the desired values in the dojo subject.
142+
143+#### Using `|%`
144+
145+Now use the following multi-line expression to bind `c` to a core, then evaluate `c` so you can look at the product. Take note of the expression spacing -- Hoon uses significant whitespace. Feel free to cut and paste the following expression into the dojo:
146+
147+```
148+> =c |%
149+ ++ two 2
150+ ++ inc (add 1 a)
151+ ++ double (mul 2 a)
152+ ++ sum (add -.b +.b)
153+ --
154+
155+> c
156+< 4.oep
157+ { {{a/@ud b/{@ud @ud}} our/@p now/@da eny/@uvJ}
158+ $~
159+ <16.igq 19.rrs 41.xjd 112.hmp 224.nab 54.tyv 119.wim 31.ohr 1.jmk $143>
160+ }
161+>
162+```
163+
164+Note: binding `c` to the core created by the `|%` expression will fail unless you have already bound `a` and `b` to the relevant values, as we did above. Our having already bound them is what lets us use them in that expression.
165+
166+`c`, like all cores, is a cell of battery and payload, and it's pretty printed inside a set of angled brackets: `< >`. The battery of four arms is represented by the pretty-printer as `4.oep`. The `4` represents the number of arms in the battery, and the `oep` is a [hash](https://en.wikipedia.org/wiki/Hash_function) of the battery. The tail is a copy of the subject of the `|%` expression (but it's pretty-printed in a slightly different way).
167+
168+(You'll notice that there are several other cores in the payload. For example, `16.igq` is a battery of `16` arms, `19.rrs` is a battery of `19` arms, etc.)
169+
170+#### `|%` Expressions
171+
172+We'll cover Hoon syntax thoroughly in lesson 2.2. For now, take for granted that `|%` is a 'rune' used to produce a core. The `++` runes are used to define the arms of the core's battery, and is followed by both an arm name and a computation. The `--` rune is used to indicate that there are no more arms to be defined, and indicates the end of the expression.
173+
174+The `|%` expression above creates a core with four arms. The first, named `two`, evaluates to the constant `2`. The second arm, `inc`, adds `1` to `a`. `double` returns double the value of `a`, and `sum` returns the sum of the two atoms in `b`. The computations defined by these arms are pretty simple (and in the case of `two`, trivial), but a good starting point for learning about cores.
175+
176+#### Payload and Subject
177+
178+That's enough to specify the battery of the core created by `|%`. But how is the payload defined? The `|%` core payload is simply a copy of the subject of that expression. Remember the subject before we bound `c` to the core?
179+
180+```
181+> .
182+[ [ [a=12 b=[22 24]]
183+ our=~bitnus-holleb-rocmeg-fotfer--migsum-nidsym-hilput-patmus
184+ now=~2018.8.17..23.53.43..c6b5
185+ eny
186+ \/0vqg.quub6.1vjms.es43r.rogsb.91okf.bcvtp.eeoih.or9ge.18ere.jtk15.3afb4.5d\/
187+ qp2.f7cqj.tj4bh.m7ja9.r1i9m.5scdh.ih7qa.dqm18.q5b4r
188+ \/ \/
189+ ]
190+ ~
191+ <16.igq 19.rrs 41.xjd 112.hmp 224.nab 54.tyv 119.wim 31.ohr 1.jmk $143>
192+]
193+```
194+
195+Compare the above with the payload of `c`. We use `+` to look at the tail of `c`:
196+
197+```
198+> +:c
199+[ [ [a=12 b=[22 24]]
200+ our=~bitnus-holleb-rocmeg-fotfer--migsum-nidsym-hilput-patmus
201+ now=~2018.8.17..23.53.43..c6b5
202+ eny
203+ \/0vqk.7dj10.kjlpi.nctqg.mp15l.29i8e.s5228.f7iln.79dl9.onrhn.dtf2i.d3eed.8i\/
204+ qvp.0mlff.62tqo.uh6ke.k10hp.kuc76.pj2j5.qclgb.o4niq
205+ \/ \/
206+ ]
207+ ~
208+ <16.igq 19.rrs 41.xjd 112.hmp 224.nab 54.tyv 119.wim 31.ohr 1.jmk $143>
209+]
210+```
211+
212+### Address-Based Wings
213+
214+In the last lesson, you saw how the following expressions return legs based on an address in the subject: `+n`, `.`, `-`, `+`, `+>`, `+<`, `->`, `-<`, `&`, `|` etc. When these resolve to the part of the subject containing an arm, they *don't* evaluate the arm. They simply return that fragment of the subject, as if it were a leg.
215+
216+Let's use `-.c` to look at the head of `c`, i.e., the battery of the core:
217+
218+```
219+> -.c
220+[ [1 2]
221+ [ [8 [9 318 0 2.047] 9 2 [0 4] [[7 [0 3] 1 2] 0 56] 0 11]
222+ 8
223+ [9 8 0 2.047]
224+ 9
225+ 2
226+ [0 4]
227+ [[7 [0 3] 1 1] 0 56]
228+ 0
229+ 11
230+ ]
231+ 8
232+ [9 8 0 2.047]
233+ 9
234+ 2
235+ [0 4]
236+ [0 57]
237+ 0
238+ 11
239+]
240+```
241+
242+The results is a series of uncomputed Nock formulas. (Don't worry about what they mean -- you don't need to know Nock to become a Hoon expert.) Let's use `-<.c` to look at the head of the head of `c`, i.e., the first arm:
243+
244+```
245+> -<.c
246+[1 2]
247+```
248+
249+The wing `-<.c` correctly resolves to an arm, but returns the uncomputed Nock formula.
250+
251+### Name-based Wings
252+
253+To get the arm of a core to compute you must use its name. The arm names of `c` are in the expression used to create `c`:
254+
255+```
256+> =c |%
257+ ++ two 2
258+ ++ inc (add 1 a)
259+ ++ double (mul 2 a)
260+ ++ sum (add -.b +.b)
261+ --
262+```
263+
264+Remember that `a` is `12` and `b` is `[22 24]`. Let's evaluate some arms:
265+
266+```
267+> two.c
268+2
269+
270+> inc.c
271+13
272+
273+> double.c
274+24
275+
276+> sum.c
277+46
278+```
279+
280+You can also evaluate the arms of `c` as follows:
281+
282+```
283+> two:c
284+2
285+
286+> inc:c
287+13
288+
289+> double:c
290+24
291+
292+> sum:c
293+46
294+```
295+
296+The difference between `two.c` and `two:c` is as follows. `two.c` is an instruction for finding `two` in `c` in the subject. `two:c` is an instruction for setting `c` as the subject, and then finding for `two`. In the examples above both versions amount to the same thing, and so return the same product.
297+
298+What if we unbind `a` and `b` in the dojo subject? Will the arms of `c` still run correctly? Yes.
299+
300+```
301+> =a
302+
303+> =b
304+
305+> a
306+-find.a
307+
308+> inc.c
309+13
310+
311+> sum.c
312+46
313+
314+> a.c
315+12
316+
317+> b.c
318+[22 24]
319+```
320+
321+Notice that `a.c` and `b.c` still evaluate to the values we originally set for `a` and `b`. That's because when we defined `c` those `a` and `b` were stored as part of `c`'s payload. The payload stores all the data needed to compute the arms correctly. That also includes `add` and `mul`, which themselves are arms in a core of the Hoon standard library.
322+
323+### Name Searches and Collisions
324+
325+It's possible to have 'name collisions' with faces and arm names. Nothing prevents one from using the name of some arm as a face too. For example:
326+
327+```
328+> double:c
329+24
330+
331+> double:[double=123 c]
332+123
333+```
334+
335+When `[double=123 c]` is the subject, the result is a cell of: (1) `double=123` and (2) the core `c`:
336+
337+```
338+> [double=123 c]
339+[ double=123
340+ < 4.oep
341+ { {{a/@ud b/{@ud @ud}} our/@p now/@da eny/@uvJ}
342+ $~
343+ <16.igq 19.rrs 41.xjd 112.hmp 224.nab 54.tyv 119.wim 31.ohr 1.jmk $143>
344+ }
345+ >
346+]
347+```
348+
349+Hoon doesn't automatically know whether `double` is a face or an arm name until it conducts a search looking for name matches. If it finds a face first, the value of the face is returned. If it finds an arm first, the arm will be evaluated and the product returned. You may use `^` to indicate that you want to skip the first match, and multiple `^`s to indicate multiple skips:
350+
351+```
352+> double:[double=123 c]
353+123
354+
355+> ^double:[double=123 c]
356+24
357+
358+> ^double:[double=123 double=456 c]
359+456
360+
361+> ^^double:[double=123 double=456 c]
362+24
363+```
364+
365+### Modifying a Core
366+
367+We can produce a modified version of the core `c` in which `a` and `b` have different values. A core is just a noun in the subject, so we can modify it in the way we learned to modify legs in the last lesson. To change `a` to `99`, use `c(a 99)`:
368+
369+```
370+> c(a 99)
371+< 4.oep
372+ { {{a/@ud b/{@ud @ud}} our/@p now/@da eny/@uvJ}
373+ $~
374+ <16.igq 19.rrs 41.xjd 112.hmp 224.nab 54.tyv 119.wim 31.ohr 1.jmk $143>
375+ }
376+>
377+
378+> a.c
379+12
380+```
381+
382+The expression `c(a 99)` produces a core exactly like `c` except that the value of `a` in the payload is `99` instead of `12`. But when we evaluate `a.c` we still get the original value, `12`. Why? The value of `c` in the dojo is bound to the original core value, and will stay that way until we unbind `c` or bind it to something else. We can ask for a modified copy of `c` but that value doesn't automatically persist. It must be put into the subject if we're to find it there. So how do we know that `c(a 99)` successfully modified the value of `a`? We can check by setting the new version of the core as the subject and checking `a`:
383+
384+```
385+> a:c(a 99)
386+99
387+
388+> double:c(a 99)
389+198
390+```
391+
392+To make the modified core persist as `c`, we can rebind `c` to the new value:
393+
394+```
395+> =c c(a 99)
396+
397+> a:c
398+99
399+
400+> double:c
401+198
402+```
403+
404+We can make multiple changes to `c` at once:
405+
406+```
407+> =c c(a 123, b [44 55])
408+
409+> a:c
410+123
411+
412+> b:c
413+[44 55]
414+
415+> two:c
416+2
417+
418+> inc:c
419+124
420+
421+> double:c
422+246
423+
424+> sum:c
425+99
426+```
427+
428+### Arms on the Search Path
429+
430+A wing is a search path into the subject. We've looked at some examples of wings that resolve to arms; e.g., `double.c`, which resolves to `double` in `c` in the subject. In the latter example the arm `double` is the final limb in the search path. What if an arm name in a wing isn't the final limb? What if it's elsewhere on the search path?
431+
432+Normally we might read a wing expression like `two.double.c` as '`two` in `double` in `c`'. Does that make sense when `double` is itself an arm? Try it:
433+
434+```
435+> two.double.c
436+2
437+```
438+
439+It produces the value of `two` of `c`. This is a fact in need of explanation.
440+
441+Arms are raw Nock formulas, and there isn't much reason to follow a search path into those. There are no faces or other names in arm Nock formulas! For this reason, when arm names are included in the search path the search behavior is a little different. Instead of indicating that the search should continue in the arm itself, an arm name indicates that the search should continue in the parent core of the arm.
442+
443+So the meaning of `two.double.c` is, roughly, '`two` in the parent core of `double` in `c`'. Of course, Hoon doesn't know that `double` is an arm until the search for it ends; but once the `double` arm is found, Hoon continues the search from _the parent core of_ `double`, not `double` itself. It turns out in this case that this is a redundant step. `c` is the parent core and was already on the search path. We can illustrate redundancy more dramatically:
444+
445+```
446+> double.two.sum.two.double.inc.c
447+246
448+
449+> two.double.two.sum.two.double.inc.c
450+2
451+
452+> sum.two.double.two.sum.two.double.inc.c
453+99
454+```
455+
456+In each of the following examples, the only wings that matter are `c` and whichever arm name is left-most in the expression. The other arm names in the path simply resolve to their parent core, which is just `c`.
457+
458+### Evaluating an Arm Against a Modified Core
459+
460+Assume `this.is.a.wing` is a wing that resolves to an arm. You can use the `this.is.a.wing(face new-value)` syntax to compute the arm against a modified version of the parent core of `this.is.a.wing`.
461+
462+```
463+> double.c(a 55)
464+110
465+
466+> inc.c(a 55)
467+56
468+```
469+
470+## Summary
471+
472+At this point you should have a pretty good understanding of what an arm is, and how wing resolution to an arm works. But so far the arms you've created have been fairly simple. In the next lesson you'll learn about Hoon functions, and how to create your own.
473+
474+You can now unbind `c` in the dojo -- this will help to keep your dojo subject tidy:
475+
476+```
477+> =c
478+
479+> c
480+-find.c
481+```
docs/tutorials/hoon-ch1/hoon-ch1-5.umdnew file+301
@@ -0,0 +1,301 @@
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3+ next/'true'
4+ sort/'5'
5+ title/'Gates and Hoon Functions'
6+ ==
7+;>
8+
9+# 1.5 Gates and Hoon Functions
10+
11+In this lesson you're going to learn about Hoon functions. A mathematical function takes an input value and returns an output value; and the value of the latter depends solely upon the value of the former. (The latter property of functions is called [referential transparency](https://en.wikipedia.org/wiki/Referential_transparency).) To implement a function in Hoon, use a special kind of core called a *gate*. In this lesson you'll learn what a gate is and how a gate represents a function. Along the way you'll build some example gates of your own.
12+
13+You've already used two functions from the Hoon standard library: `add` and `mul`. These are implemented with gates, and you call them from the dojo in the following way:
14+
15+```
16+> (add 2 3)
17+5
18+
19+> (mul 2 3)
20+6
21+```
22+
23+## What is a Gate?
24+
25+A core is a cell: `[battery payload]`.
26+
27+A gate is a core, but it's not just any core. It has two distinctive properties: (1) the battery of a gate contains exactly one arm, which has the special name `$`; and (2) the payload of a gate consists of a cell of `[sample context]`. The sample is the part of the payload that stores the 'argument' (i.e., input value) of the function call. The context contains all other data that is needed for computing the `$` arm of the gate correctly.
28+
29+```
30+A gate: [$ [sample context]]
31+```
32+
33+To reiterate, the `$` arm is the code for producing the output value, the sample is the input value, and the context is any other data necessary for `$` to run correctly.
34+
35+As a tree, a gate looks like the following:
36+
37+```
38+ Gate
39+ / \
40+ $ .
41+ / \
42+ Sample Context
43+```
44+
45+Like all arms, `$` is computed with its parent core as the subject. When `$` is computed, the resulting value is called the 'product' of the gate. No other data is used to calculate the product other than the data in the gate itself.
46+
47+## Creating Your First Gate
48+
49+Before making a gate, let's take a look at the dojo subject so we can refer to it later:
50+
51+```
52+> .
53+[ [ our=~bitnus-holleb-rocmeg-fotfer--migsum-nidsym-hilput-patmus
54+ now=~2018.8.21..22.03.05..a444
55+ eny
56+ \/0v1hp.ug5b7.i21p4.qd4bt.0cc08.ug5og.j2uru.05a5a.pk3j5.vascn.mudri.pghpu.t\/
57+ 6vs7.h8pg0.ivnr7.smav1.rhova.ang41.347of.l1ahv.vfdvh
58+ \/ \/
59+ ]
60+ ~
61+ <16.igq 19.rrs 41.xjd 112.hmp 224.nab 54.tyv 119.wim 31.ohr 1.jmk $143>
62+]
63+```
64+
65+Let's make a gate that takes any unsigned integer (i.e., an atom) as its sample and returns that value plus one as the product. To do this we'll use the `|=` rune. We'll bind this gate to the face `inc` for 'increment':
66+
67+```
68+> =inc |=(a=@ (add 1 a))
69+
70+> (inc 1)
71+2
72+
73+> (inc 12)
74+13
75+
76+> (inc 123)
77+124
78+```
79+
80+The gate works as promised -- it takes any number `n` and returns `n + 1`. Let's take a closer look at what the `|=` is doing.
81+
82+### The `|=` Rune
83+
84+We can use `|=` to create a gate. There are two subexpressions that go after a `|=` rune. The first defines the gate's sample, and the second defines the gate's product.
85+
86+In the example gate above, `inc`, the sample is defined by `a=@`. This means that the sample is defined as an atom, `@`, and it is given the face `a`. With the face it's easier to refer to the sample in later code, if desired.
87+
88+In `inc`, the product is defined by `(add 1 a)`. There's not much to it -- it returns the value of `a + 1`!
89+
90+The second subexpression after the `|=` rune is used to build the gate's `$` arm. That's where all the computations go. The sample is defined by the first subexpression.
91+
92+The context of the resulting gate is a copy of the subject for the `|=` expression. To see this, let's print the value of `inc` in the dojo:
93+
94+```
95+> inc
96+< 1.viz
97+ { a/@
98+ {our/@p now/@da eny/@uvJ}
99+ $~
100+ <16.igq 19.rrs 41.xjd 112.hmp 224.nab 54.tyv 119.wim 31.ohr 1.jmk $143>
101+ }
102+>
103+```
104+
105+The `1.viz` represents the `$` arm of the gate. The `a/@` is for the sample. And the rest is the dojo subject that was used for the `|=` expression. (Compare it to the dojo subject we printed before binding `inc` to a gate -- it's pretty printed in a slightly different way, but it's the same noun.)
106+
107+## Anatomy of a Gate
108+
109+A gate is a one-armed core with a sample: `[$ [sample context]]`. Let's go over these parts a little more carefully, using `inc` as our example.
110+
111+### The `$` Arm
112+
113+The arm of a gate specifies (in Nock) the instructions for the Hoon function in question. The gate's arm is always located at `+2` of the gate.
114+
115+The pretty printer represents the `$` arm of `inc` as `1.viz`. To see the actual noun of the `$` arm, enter `+2:inc` into the dojo:
116+
117+```
118+> +2:inc
119+[8 [9 8 0 4.095] 9 2 [0 4] [[7 [0 3] 1 1] 0 14] 0 11]
120+```
121+
122+Here we see a Nock formula. For what it's worth, these are the Nock instructions for adding `1` to a number. (Again, you don't need to understand how to read Nock.)
123+
124+It's worth pointing out that the arm name, `$`, can be used like any other name. We can compute `$` directly with `$:add` in the dojo:
125+
126+```
127+> $:inc
128+1
129+```
130+
131+This result may seem a bit strange. We didn't call `inc` or in any other way pass it a number. Yet using `$` to evaluate `inc`'s arm seems to work -- sort of, anyway. Why is it giving us `1` as the return value? We can answer this question after we understand gate samples a little better.
132+
133+### The Sample
134+
135+The sample of a gate is the address reserved for storing the argument(s) to the Hoon function. The sample is always at the head of the gate's tail, i.e., `+6`.
136+
137+Let's look at the gate for `inc` again, paying particular attention to its sample:
138+
139+```
140+> inc
141+< 1.viz
142+ { a/@
143+ {our/@p now/@da eny/@uvJ}
144+ $~
145+ <16.igq 19.rrs 41.xjd 112.hmp 224.nab 54.tyv 119.wim 31.ohr 1.jmk $143>
146+ }
147+>
148+```
149+
150+We see `a/@`. This may not be totally clear, but it should make _some_ sense. This is the pretty-printer's way of indicating an atom with the face `a`. Let's take a closer look:
151+
152+```
153+> +6:inc
154+a=0
155+```
156+
157+We see now that the sample of `inc` is the value `0`, and has `a` as a face. This is a placeholder value for the function argument. If you evaluate the `$` arm of `inc` without passing it an argument the placeholder value is used for the computation, and the return value will thus be `0 + 1`:
158+
159+```
160+> $:inc
161+1
162+```
163+
164+The placeholder value is sometimes called a *bunt* value. The bunt value is determined by the input type; for atoms, `@`, the bunt value is `0`.
165+
166+The face value of `a` comes from the way we defined the gate above: `|=(a=@ (add 1 a))`. It was so we could use `a` to refer to the sample to generate the product with `(add 1 a)`.
167+
168+### The Context
169+
170+The context of a gate contains other data that may be necessary for the `$` arm to evaluate correctly. The context always located at the tail of the tail of the gate, i.e., `+7` of the gate. There is no requirement that the context have any particular arrangement, though often it does.
171+
172+Let's look at the context of `inc`:
173+
174+```
175+> +7:inc
176+[ [ our=~bitnus-holleb-rocmeg-fotfer--migsum-nidsym-hilput-patmus
177+ now=~2018.8.21..22.13.52..828a
178+ eny
179+ \/0v3ui.rq2no.g0eor.f0kjq.njfr4.tlb60.fq340.cvfh5.p4168.rj3r2.pr5d2.0532k.h\/
180+ ite1.r218h.ukqle.cldnl.0e5h5.9pvkm.rhep5.ole0s.hbann
181+ \/ \/
182+ ]
183+ ~
184+ <16.igq 19.rrs 41.xjd 112.hmp 224.nab 54.tyv 119.wim 31.ohr 1.jmk $143>
185+]
186+```
187+
188+You can see that this is exactly the subject before we put `inc` into the subject.
189+
190+### Exercise 1.5.1
191+
192+Write a gate that takes an atom, `a=@`, and which returns double the value of `a`. Bind this gate to `double` and test it in the dojo. A solution is given at the end of this lesson.
193+
194+## Gates Define Functions of the Sample
195+
196+The value of a function's output depends solely upon the input value. This is one of the features that make functions desirable in many programming contexts. It's worth going over how Hoon function calls implement this feature. Let's talk about how function calls work in Hoon.
197+
198+In Hoon one can use `(gate arg)` syntax to make a function call. For example,
199+
200+```
201+> (inc 234)
202+235
203+```
204+
205+The name of the gate is `inc`. How is the `$` arm of `inc` evaluated? When a function call occurs, a copy of the `inc` gate is created, but with one modification; the sample is replaced with the function argument. Then the `$` arm is computed against this modified version of the `inc` gate.
206+
207+Remember that the default or 'bunt' value of the sample of `inc` is `0`. In the function call above, a copy of the `inc` gate is made but with a sample value of `234`. When `$` is computed against this modified core, the product is `235`.
208+
209+Notice that neither the arm nor the context is modified before the arm is evaluated. That means that the only part of the gate that changes before the arm evaluation is the sample. Hence, we may understand each gate as defining a function whose argument is the sample. If you call a gate with the same sample, you'll get the same value returned to you every time.
210+
211+Let's unbind `inc` to keep the subject tidy:
212+
213+```
214+> =inc
215+
216+> inc
217+-find.inc
218+```
219+
220+### Modifying the Context of a Gate
221+
222+It _is_ possible to modify the context of a gate when you make a function call; or, to be more precise, it's possible to call a mutant copy of the gate in which the context is modified. To illustrate this let's use another example gate. Let's write a gate which uses a value from the context to generate the product. Bind `b` to the value `10`:
223+
224+```
225+> =b 10
226+
227+> b
228+10
229+```
230+
231+Now let's write a gate called `ten` that adds `b` to the input value:
232+
233+```
234+> =ten |=(a=@ (add a b))
235+
236+> (ten 10)
237+20
238+
239+> (ten 20)
240+30
241+
242+> (ten 25)
243+35
244+```
245+
246+We can unbind `b` from the dojo subject, and `ten` works just as well because it's using a copy of `b` stored its context:
247+
248+```
249+> =b
250+
251+> (ten 15)
252+25
253+
254+> (ten 35)
255+45
256+
257+> ten
258+< 1.umt
259+ { a/@
260+ {b/@ud our/@p now/@da eny/@uvJ}
261+ $~
262+ <16.igq 19.rrs 41.xjd 112.hmp 224.nab 54.tyv 119.wim 31.ohr 1.jmk $143>
263+ }
264+>
265+
266+> b.+7.ten
267+10
268+```
269+
270+We can use `ten(b 25)` to produce a variant of `ten`. Calling this mutant version of `ten` causes a different value to be returned than we'd get with a normal `ten` call:
271+
272+```
273+> (ten(b 25) 10)
274+35
275+
276+> (ten(b 1) 25)
277+26
278+
279+> (ten(b 75) 100)
280+175
281+```
282+
283+Before finishing the lesson let's unbind `ten`:
284+
285+```
286+> =ten
287+```
288+
289+## Exercise 1.5.1 Solution
290+
291+Write a gate that takes an atom, `a=@`, and which returns double the value of `a`. Bind this gate to `double` and test it in the dojo.
292+
293+```
294+> =double |=(a=@ (mul 2 a))
295+
296+> (double 10)
297+20
298+
299+> (double 25)
300+50
301+```
docs/tutorials/hoon-ch1/hoon-ch1-6.umdnew file+515
@@ -0,0 +1,515 @@
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3+ sort/'6'
4+ title/'Producing Gates with Cores'
5+ ==
6+;>
7+
8+# 1.6 Producing Gates with Cores
9+
10+It's useful to have cores whose arms evaluate to make gates. The use of such cores is common in Hoon; that's how the functions of the Hoon standard library are stored in the subject. Learning about such cores will also deepen the reader's understanding of Hoon semantics, and for that reason alone is worthwhile.
11+
12+In this lesson you'll also learn about a new kind of core, called a 'door'.
13+
14+## Two Kinds of Function Calls
15+
16+There are two ways of making a function call in Hoon. First, you can call a gate in the subject by name. This is what you did with `inc` in the last lesson; you bound `inc` to a gate that adds `1` to an input:
17+
18+```
19+> =inc |=(a=@ (add 1 a))
20+
21+> (inc 10)
22+11
23+
24+> .
25+[ [ inc
26+ < 1.viz
27+ { a/@
28+ {our/@p now/@da eny/@uvJ}
29+ $~
30+ <16.igq 19.rrs 41.xjd 112.hmp 224.nab 54.tyv 119.wim 31.ohr 1.jmk $143>
31+ }
32+ >
33+ our=~bitnus-holleb-rocmeg-fotfer--migsum-nidsym-hilput-patmus
34+ now=~2018.8.24..05.51.53..97b9
35+ eny
36+ \/0v3vd.sdp3o.ds8eq.5mr1s.du2v6.4a12r.poie2.04123.jaq8r.8qoum.mvb63.dblf7.7\/
37+ lt1d.fqebb.pv6dr.lio19.re7lq.016q3.u03ne.c8aiu.7148p
38+ \/ \/
39+ ]
40+ ~
41+ <16.igq 19.rrs 41.xjd 112.hmp 224.nab 54.tyv 119.wim 31.ohr 1.jmk $143>
42+]
43+
44+> =inc
45+```
46+
47+The second way of making a function call involves an expression that _produces_ a gate:
48+
49+```
50+> (|=(a=@ (add 1 a)) 123)
51+124
52+
53+> (|=(a=@ (mul 2 a)) 123)
54+246
55+```
56+
57+Pop quiz: Are calls to `add` and `mul` of the Hoon standard library of the first kind, or the second?
58+
59+```
60+> (add 12 23)
61+35
62+
63+> (mul 12 23)
64+276
65+```
66+
67+They're of the second kind. Neither `add` nor `mul` is a gate; they're each arms that _produce_ gates. Often the difference doesn't matter much. Either way you can do a function call using the `(gate arg)` syntax.
68+
69+It's important to learn the difference, however, because for certain use cases you'll want the extra flexibility that comes with having an already produced core in the subject. This is particularly important when you want to mutate the core as you call it. It's far more straight-forward to mutate a core that already exists in the subject, than to have to produce it first and then mutate it.
70+
71+## A Gate-Building Core
72+
73+Let's make a core with arms that build gates of various kinds. As we did in a previous lesson, we'll use the `|%` rune. Feel free to cut and paste the following into the dojo:
74+
75+```
76+> =c |%
77+ ++ inc |=(a=@ (add 1 a))
78+ ++ add-two |=(a=@ (inc (inc a)))
79+ ++ double |=(a=@ (mul 2 a))
80+ ++ triple |=(a=@ (mul 3 a))
81+ --
82+```
83+
84+Let's try out these arms, using them for function calls:
85+
86+```
87+> (inc:c 10)
88+11
89+
90+> (add-two:c 10)
91+12
92+
93+> (double:c 10)
94+20
95+
96+> (triple:c 10)
97+30
98+```
99+
100+Notice that each arm in core `c` is able to call the other arms of `c` -- `add-two` uses the `inc` arm to increment a number twice. As a reminder, each arm is evaluated with is parent core as the subject. In the case of `add-two` the parent core is `c`, which has `inc` in it.
101+
102+### The `..arm` Syntax
103+
104+Let's say you have a wing that resolves to a leg of the subject. In this wing is an arm name, e.g., `a.b.arm`. As you know from lesson 1.3, this should be read as '`a` in `b` in the parent core of `arm`'. Speaking more directly: the wing search path goes through the parent core of the arm, not the arm itself.
105+
106+Recall that `.` by itself returns the whole subject. With that in mind, take a moment to answer the following question on your own. In general, what should the expression `..arm` produce?
107+
108+Do you have an answer? If not, consider going back and trying to figure it out before moving on.
109+
110+You may read `..arm` as '`.` of the parent core of `arm`'. This amounts to just the parent core of `arm`. Let's try this out with the arms of `c`:
111+
112+```
113+> ..inc:c
114+< 4.vgw
115+ { {our/@p now/@da eny/@uvJ}
116+ $~
117+ <16.igq 19.rrs 41.xjd 112.hmp 224.nab 54.tyv 119.wim 31.ohr 1.jmk $143>
118+ }
119+>
120+
121+> c
122+< 4.vgw
123+ { {our/@p now/@da eny/@uvJ}
124+ $~
125+ <16.igq 19.rrs 41.xjd 112.hmp 224.nab 54.tyv 119.wim 31.ohr 1.jmk $143>
126+ }
127+>
128+```
129+
130+Yes, they match. `..inc` of `c` is just the parent core of `inc`, `c` itself. But why would we ever use `..inc` to refer to `c`? It's much simpler to use `c`.
131+
132+Sometimes the `..arm` syntax is quite useful. Often there is a core in the subject without a face bound to it; i.e., the core might be nameless. In that case you can use an arm name in that core to refer to the whole core.
133+
134+For an example of this, consider the `add` arm of the Hoon standard library. This arm is in a nameless core. To see the parent core of `add`, try `..add`:
135+
136+```
137+> ..add
138+<31.ohr 1.jmk $143>
139+```
140+
141+Here you see a core with a battery of 31 arms, and whose payload is another core with one arm.
142+
143+### Mutating a Gate
144+
145+Let's say you want to modify the default sample of the gate for `double`. We can infer the default sample by calling `double` with no argument:
146+
147+```
148+> (double:c)
149+0
150+```
151+
152+Given that `a x 2 = 0`, `a` must be `0`. (Remember that `a` is the face for the `double` sample, as defined in the core we bound to `c` above.)
153+
154+Let's say we want to modify the default sample to be `25`. There is only one problem: `double` isn't a gate! It's an arm that produces a gate, and every time it does so the default sample is `0`. If you want to mutate the gate produced by `double`, you'll first have to put a copy of that gate into the subject:
155+
156+```
157+> =double-copy double:c
158+
159+> (double-copy 123)
160+246
161+```
162+
163+Now let's mutate the sample to `25`, and check that it worked with `+6`:
164+
165+```
166+> +6:double-copy(a 25)
167+a=25
168+```
169+
170+Good. Let's call it with no argument and see if it returns double the value of the modified sample.
171+
172+```
173+> (double-copy(a 25))
174+50
175+```
176+
177+It does indeed. Unbind `c` and `double-copy` as follows:
178+
179+```
180+> =c
181+> =double-copy
182+```
183+
184+Contrast this with the behavior of `add`. We can look at the sample of the gate for `add` with `+6:add`:
185+
186+```
187+> +6:add
188+[a=0 b=0]
189+```
190+
191+If you try to mutate the default sample of `add`, it won't work:
192+
193+```
194+> add(a 3)
195+-tack.a
196+-find.a
197+```
198+
199+The reason it doesn't work is that `add` is an arm, not a gate. Hoon can't find an `a` to modify in a gate that doesn't exist yet!
200+
201+## Other Functions in the Hoon Standard Library
202+
203+Let's look once more at the parent core of the `add` arm in the Hoon standard library:
204+
205+```
206+> ..add
207+<31.ohr 1.jmk $143>
208+```
209+
210+The battery of this core contains 31 arms, each of which evaluates to a gate in the standard library. This 'library' is nothing more than a core containing useful basic functions that Hoon often makes available as part of the subject. You can see the Hoon code defining these arms near the beginning of [hoon.hoon](https://github.com/urbit/arvo/blob/master/sys/hoon.hoon), starting with [`++ add`](https://github.com/urbit/arvo/blob/master/sys/hoon.hoon#L21). (Yes, the Hoon standard library is written in Hoon.)
211+
212+Here are some of the other gates that can be generated from this core in the Hoon standard library. It should be fairly obvious what they do:
213+
214+```
215+> (dec 18)
216+17
217+
218+> (dec 17)
219+16
220+
221+> (gth 11 7)
222+%.y
223+
224+> (gth 7 11)
225+%.n
226+
227+> (gth 11 11)
228+%.n
229+
230+> (lth 11 7)
231+%.n
232+
233+> (lth 7 11)
234+%.y
235+
236+> (lth 11 11)
237+%.n
238+
239+> (max 12 14)
240+14
241+
242+> (max 14 14)
243+14
244+
245+> (max 14 432)
246+432
247+
248+> (mod 11 7)
249+4
250+
251+> (mod 22 7)
252+1
253+
254+> (mod 33 7)
255+5
256+
257+> (sub 234 123)
258+111
259+```
260+
261+## Doors
262+
263+A brief review: A core is a cell of battery and payload: `[battery payload]`. The battery is code and the payload is data. The battery contains a series of arms, and the payload contains all the data necessary to run those arms correctly.
264+
265+New material: A *door* is a core with a sample. That is, a door is a core whose payload is a cell of sample and context: `[sample context]`.
266+
267+```
268+ door
269+ / \
270+battery .
271+ / \
272+ sample context
273+```
274+
275+It follows from this definition that a gate is a special case of a door. A gate is a door with exactly one arm, named `$`.
276+
277+Gates are useful for defining functions. But there are many-armed doors as well. How are they used? Doors are quite useful data structures. In Chapter 2 of the Hoon tutorial series you'll learn how to use doors to implement state machines, where the sample stores the relevant state data. For let's talk about how to use doors for simpler purposes.
278+
279+### An Example Door
280+
281+Let's write an example door in order to illustrate its features. Each of the arms in the door will define a simple gate. Let's bind the door to `c` as we did with the last core. To make a door we use the `|_` rune:
282+
283+```
284+> =c |_ b=@
285+ ++ plus |=(a=@ (add a b))
286+ ++ times |=(a=@ (mul a b))
287+ ++ greater |=(a=@ (gth a b))
288+ --
289+```
290+
291+If you type this into the dojo manually, make sure you attend carefully to the spacing. Feel free to cut and paste the code, if desired.
292+
293+Before getting into what these arms do, let's cover how the `|_` rune works in general.
294+
295+#### The `|_` Rune
296+
297+The `|_` rune for making a door works exactly like the `|%` rune for making a core, except it takes one additional subexpression.
298+
299+The first subexpression after the `|_` rune defines the door sample. (This is the subexpression the `|%` rune lacks.) Following that are a series of `++` runes, each of which defines an arm of the door. Finally, the expression is terminated with a `--` rune.
300+
301+#### Back to the Example
302+
303+For the door defined above, `c`, the sample is defined as an atom, `@`, and given the face `b`. The `plus` arm defines a gate that takes a single atom as its argument, `a`, and which returns the sum of `a` and `b`. The `times` arm defines a gate that takes a single atom, `a`, and returns `a` times `b`. The `greater` arm defines a gate that takes a single atom, `a`, and if `a` is greater than `b` returns `%.y`; otherwise `%.n`.
304+
305+Let's try out the arms of `c` with ordinary function calls:
306+
307+```
308+> (plus:c 10)
309+10
310+
311+> (times:c 10)
312+0
313+
314+> (greater:c 10)
315+%.y
316+```
317+
318+This works, but the results are not exciting. Passing `10` to the `plus` gate returns `10`, so it must be that the value of `b` is `0`. The products of the other function calls reinforce that assessment. Let's look directly at `+6` of `c`:
319+
320+```
321+> +6:c
322+b=0
323+```
324+
325+Having confirmed that `b` is `0`, let's mutate the `c` sample and then call its arms:
326+
327+```
328+> (plus:c(b 7) 10)
329+17
330+
331+> (times:c(b 7) 10)
332+70
333+
334+> (greater:c(b 7) 10)
335+%.y
336+
337+> (greater:c(b 17) 10)
338+%.n
339+```
340+
341+Doing the same mutation repeatedly can be tedious, so let's bind `c` to the modified version of the door:
342+
343+```
344+> (plus:c 10)
345+17
346+
347+> (times:c 10)
348+70
349+
350+> (greater:c 10)
351+%.y
352+```
353+
354+There's a more direct way of passing arguments for both the door sample and the gate sample simultaneously. We may use the `~(arm door arg)` syntax. This generates the `arm` product after modifying the `door`'s sample to be `arg`.
355+
356+```
357+> (~(plus c 7) 10)
358+17
359+
360+> (~(times c 7) 10)
361+70
362+
363+> (~(greater c 7) 10)
364+%.y
365+
366+> (~(greater c 17) 10)
367+%.n
368+```
369+
370+Readers of a particular mathematical background may notice that `~( )` expressions allow us to [curry](https://en.wikipedia.org/wiki/Currying). For each of the arms above, the `~( )` expression is used to create different versions of the same gate:
371+
372+```
373+> ~(plus c 7)
374+< 1.umt
375+ { a/@
376+ < 3.uvn
377+ { b/@
378+ {our/@p now/@da eny/@uvJ}
379+ $~
380+ <16.igq 19.rrs 41.xjd 112.hmp 224.nab 54.tyv 119.wim 31.ohr 1.jmk $143>
381+ }
382+ >
383+ }
384+>
385+
386+> b:~(plus c 7)
387+7
388+
389+> ~(plus c 17)
390+< 1.umt
391+ { a/@
392+ < 3.uvn
393+ { b/@
394+ {our/@p now/@da eny/@uvJ}
395+ $~
396+ <16.igq 19.rrs 41.xjd 112.hmp 224.nab 54.tyv 119.wim 31.ohr 1.jmk $143>
397+ }
398+ >
399+ }
400+>
401+
402+> b:~(plus c 17)
403+17
404+```
405+
406+Thus, you may think of the `c` door as a function for making functions. Use the `~(arm c arg)` syntax -- `arm` defines which kind of gate is produced (i.e., which arm of the door is used to create the gate), and `arg` defines the value of `b` in that gate, which in turn affects the product value of the gate produced.
407+
408+### Doors in the Hoon Standard Library
409+
410+Back in lesson 1.2 you were introduced to atom auras. (Recall that an aura for an atom is metadata used by Hoon that defines how that atom is interpreted and pretty-printed.) Atoms are unsigned integers, but sometimes programmers want to work with fractions and decimal points. Accordingly, there are auras for [floating point numbers](https://en.wikipedia.org/wiki/Floating-point_arithmetic). Let's work with the aura for doing [single-precision](https://en.wikipedia.org/wiki/Single-precision_floating-point_format) floating point arithmetic: `@rs`.
411+
412+The `@rs` has its own literal syntax. These atoms are represented as a `.` followed by digits, and possibly another `.` (for the decimal point) and more digits. For example, the float 3.14159 can be represented as a single-precision (32 bit) float with the literal expression `.3.14159`.
413+
414+You can't use the ordinary `add` function to get the correct sum of two `@rs` atoms:
415+
416+```
417+> (add .3.14159 .2.22222)
418+2.153.203.882
419+```
420+
421+That's because the `add` gate is designed for use with raw atoms, not floating point values. You can add two `@rs` atoms as follows:
422+
423+```
424+> (add:rs .3.14159 .2.22222)
425+.5.36381
426+```
427+
428+It turns out that the `rs` in `add:rs` is a Hoon standard library arm that produces a door. Let's take a closer look:
429+
430+```
431+> rs
432+<21?vij {r/?($n $u $d $z) <54.tyv 119.wim 31.ohr 1.jmk $143>}>
433+```
434+
435+The battery of this core, pretty-printed as `21?vij`, has 21 arms that define functions specifically for `@rs` atoms. One of these arms is named `add`; it's a different `add` from the standard one we've been using for vanilla atoms. So when you invoke `add:rs` instead of just `add` in a function call, (1) the `rs` door is produced, and then (2) the name search for `add` resolves to the special `add` arm in `rs`. This produces the gate for adding `@rs` atoms:
436+
437+```
438+> add:rs
439+< 1.dfv
440+ {{a/@rs b/@rs} <21.vij {r/?($n $u $d $z) <54.tyv 119.wim 31.ohr 1.jmk $143>}>}
441+>
442+```
443+
444+What about the sample of the `rs` door? The pretty-printer shows `r/?($n $u $d $z)`. What does this mean? Without yet explaining this notation fully, we'll simply say that the `rs` sample can take one of four values: `%n`, `%u`, `%d`, and `%z`. These argument values represent four options for how to round `@rs` numbers:
445+
446+```
447+%n -- round to the nearest value
448+%u -- round up
449+%d -- round down
450+%z -- round to zero
451+```
452+
453+The default value is `%z` -- round to zero. When we invoke `add:rs` to call the addition function, there is no way to modify the `rs` door sample, so the default rounding option is used. How do we change it? We use the `~( )` notation: `~(arm door arg)`.
454+
455+Let's evaluate the `add` arm of `rs`, also modifying the door sample to `%u` for 'round up':
456+
457+```
458+> ~(add rs %u)
459+< 1.dfv
460+ {{a/@rs b/@rs} <21.vij {r/?($n $u $d $z) <54.tyv 119.wim 31.ohr 1.jmk $143>}>}
461+>
462+```
463+
464+This is the gate produced by `add`, and you can see that its sample is a pair of `@rs` atoms. But if you look in the context you'll see the `rs` door. Let's look in the sample of that core to make sure that it changed to `%u`. We'll use the wing `+6.+7` to look at the sample of the gate's context:
465+
466+```
467+> +6.+7:~(add rs %u)
468+r=%u
469+```
470+
471+It did indeed change. We also see that the door sample uses the face `r`, so let's use that instead of the unwieldy `+6.+7`:
472+
473+```
474+> r:~(add rs %u)
475+%u
476+```
477+
478+We can do the same thing for rounding down, `%d`:
479+
480+```
481+> r:~(add rs %d)
482+%d
483+```
484+
485+Let's see the rounding differences in action. Because `~(add rs %u)` produces a gate, we can call it like we would any other gate:
486+
487+```
488+> (~(add rs %u) .3.14159265 .1.11111111)
489+.4.252704
490+
491+> (~(add rs %d) .3.14159265 .1.11111111)
492+.4.2527037
493+```
494+
495+This difference between rounding up and rounding down might seem strange at first. There is a difference of 0.0000003 between the two answers. Why does this gap exist? Single-precision floats are 32-bit and there's only so many distinctions that can be made in floats before you run out of bits.
496+
497+Just as there is a door for `@rs` functions, there is a Hoon standard library door for `@rd` functions (double-precision 64 bit floats), another for `@rq` functions (quad-precision 128 bit floats), and more.
498+
499+### Mutating the `rs` Door
500+
501+Can we mutate the `rs` door so that its sample is `%u`? Let's try it:
502+
503+```
504+> rs(r %u)
505+-tack.r
506+-find.r
507+```
508+
509+Oops! Why didn't this work? Remember, `rs` isn't itself a door; it's an arm that produces a door. The `rs` in `rs(r %u)` resolves to the nameless parent core of `rs`, and the search for `r` commences there. But that face can't be found in that parent core -- it's not where we want to look.
510+
511+It's better simply to use the `~(arm rs arg)` syntax to replace the value of the `rs` door sample with `arg`.
512+
513+## Conclusion
514+
515+You've now reached the end of Chapter 1 of the Hoon tutorial. Ideally you should have a fair understanding of the fundamental concepts of subject-oriented programming: limbs, legs, faces, wings, arms, cores, gates, and doors. If you can master these concepts you should have little or no trouble learning to write substantial Hoon programs. Continue to Chapter 2 to get started.
docs/tutorials/hoon-ch2.umdnew file+14
@@ -0,0 +1,14 @@
1+:- :~ navhome/'/docs/'
2+ next/'true'
3+ sort/'3'
4+ title/'Hoon Chapter 2'
5+ ==
6+;>
7+
8+# Chapter 2: Introduction to Writing Hoon Programs
9+
10+In Chapter 2 we cover the basics of writing full programs in Hoon.
11+
12+Lesson 1 takes you through a simple Hoon program without explaining every detail. Lesson 2 covers Hoon's syntax rules. Lesson 3 covers some of the basic flow control and loop expressions. Lessons 4-6 introduce Hoon's type system. Lessons 7 and 8 show you how to use cores effectively in your Hoon programs, including how to use them as state machines. Lessons 9 and 10 cover some of the basic data structures commonly used in Hoon, such as lists, trees, and sets. Those lessons also introduce many of the standard library functions for use with those data structures. Lesson 11 includes a walk-through of two Hoon programs that are intended to reinforce everything taught earlier in the chapter: a prime sieve and a tic-tac-toe program.
13+
14+;list;
docs/tutorials/hoon-ch2/hoon-ch2-1.umdnew file+160
@@ -0,0 +1,160 @@
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3+ next/'true'
4+ sort/'1'
5+ title/'Hoon Programs'
6+ ==
7+;>
8+
9+# Writing Hoon Programs
10+
11+So far you've only entered short snippets of Hoon code into the dojo. Let's look at some substantive programs!
12+
13+There many kinds of Hoon programs: generators, Gall apps, Sail documents, and more. In this chapter we'll work exclusively with a subset of the first kind: generators. This narrow focus will allow us to set aside complications that aren't necessary for learning the basics of Hoon. We won't even talk about the full range of generators supported in Urbit just yet. Other kinds of programs will be covered in later chapters.
14+
15+## Setup
16+
17+For now we'll work exclusively with 'naked' generators. A naked generator is a gate that can be run from the dojo and that takes exactly one argument for its sample. Generators are to be stored in the `/gen` directory of your urbit's filesystem.
18+
19+To use your favorite text editor to write Hoon programs you'll first need to expose your urbit's filesystem to Unix. If you haven't already done so, 'mount' your home desk as follows:
20+
21+```
22+> |mount %
23+>=
24+```
25+
26+(Note: we are assuming that you have mounted from your 'home' desk in the dojo. If you don't know what this means, don't worry -- this only matters if you have changed directories since you've booted your urbit, and you probably haven't.)
27+
28+Mounting may take a moment. The `>=` response means the command is successful. From within Unix (or your favorite file explorer) you should be able to see a `/home` directory in your urbit's pier, and in that directory is `/gen`. This is where you'll put Hoon source files in order to run them from the dojo.
29+
30+## List of Numbers
31+
32+Let's look at a Hoon program that implements a simple function: it takes as input some atom `n` and returns a list of all the atoms from `1` to `n`. (Remember that an atom is just an unsigned integer.)
33+
34+Each line is commented with a number for convenient line reference:
35+
36+```
37+|= end=@ :: 1
38+=/ count=@ 1 :: 2
39+|- :: 3
40+^- (list @) :: 4
41+?: =(end count) :: 5
42+ ~ :: 6
43+:- count :: 7
44+$(count (add 1 count)) :: 8
45+```
46+
47+Save this as 'listnum.hoon' in `/home/gen` of your urbit's pier. To run it enter `+listnum 25` in the dojo:
48+
49+```
50+> +listnum 25
51+~[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24]
52+```
53+
54+### Function Programming, Runes, and Whitespace
55+
56+Before going over how the above code works we should point out three things.
57+
58+First, when Listnum is written in a non-functional language it's typically simpler to generate the output as a side effect of the program, e.g., with a `printf()` command inside a loop. Hoon is a functional language, so the code above instead defines a function. Functions don't have side effects. The `listnum` function takes an atom as its input, and then returns an entire list of atoms as a single piece of data.
59+
60+Second, one syntactic feature of Hoon that distinguishes it from other programming languages is its use of _runes_ rather than keywords. A rune is just a pair of non-alphanumeric ASCII characters. Below we give a brief explanation of each of the runes used so you can have a rough idea of how the program works.
61+
62+Finally, it's important to know that whitespace is more strictly regulated in Hoon than it is in most other languages. Attempting to run a Hoon program with incorrect spacing results in a syntax error. The spacing rules will be explained in the next lesson.
63+
64+### High Level Overview
65+
66+The program returns a list of numbers, `(list @)`, from `1` up to `end`. But what do we mean by a 'list'?
67+
68+There are two kinds of lists in Hoon: empty and non-empty. The empty list has nothing in it; it's just the null value, `~`. A non-empty list has at least one item and is a cell of the following sort:
69+
70+```
71+[item-1 rest-of-list]
72+```
73+
74+That is, the head of the cell is the first list item, and the tail is the rest of the list. The tail is itself another list. In Hoon, the end of a list is indicated with the null character, `~`. Accordingly, we say that lists in Hoon are 'null-terminated'.
75+
76+Below are binary trees representing a two-item list and a four-item list, respectively:
77+
78+```
79+two items: [item-1 [item-2 ~]]
80+
81+ .
82+ / \
83+ item-1 .
84+ / \
85+ item-2 ~
86+
87+four items: [item-1 [item-2 [item-3 [item-4 ~]]]]
88+
89+ .
90+ / \
91+ item-1 .
92+ / \
93+ item-2 .
94+ / \
95+ item-3 .
96+ / \
97+ item-4 ~
98+```
99+
100+So, for example, the list of atoms `~[1 2 3 4]` is structured as the following noun:
101+
102+```
103+ [1 [2 [3 [4 ~]]]]
104+
105+ .
106+ / \
107+ 1 .
108+ / \
109+ 2 .
110+ / \
111+ 3 .
112+ / \
113+ 4 ~
114+```
115+
116+The program is to generate the appropriate list of numbers given an input value, `end`: `~[1 2 3 ...]`. How?
117+
118+Essentially, the program uses a loop to produce the list. Assuming the initial value of `end` is `> 1`, a cell is created in which the head is the value `count`. The tail is the rest of the list, itself a list. It's created by incrementing `count` by `1`, and then looping and running the same code again. When `count` equals `end`, the list is complete and the program ends.
119+
120+Let's look at the code line-by-line.
121+
122+### Listnum.hoon: Code explanation
123+
124+```
125+|= end=@ :: 1
126+=/ count=@ 1 :: 2
127+|- :: 3
128+^- (list @) :: 4
129+```
130+
131+Line 1 uses the gate rune, `|=`, to define a function that takes one argument (i.e., input value). The argument labelled `end` is stored as the gate's sample; and the sample must be of the type `@`, an atom. The rest of the program determines the value to be returned by the function.
132+
133+Line 2 uses `=/` to put an atom into the subject, `1`, labelled `count`. This is analogous to defining a variable and giving it an initial value in other languages.
134+
135+Line 3 uses `|-` to indicate a loop starting point. We'll give `|-` a more precise definition later in the chapter.
136+
137+Line 4 uses a 'cast' rune, `^-`, to define the product of the loop as a `(list @)`, i.e., as a list of atoms. If the rest of the program following `(list @)` doesn't provably evaluate to a list of atoms, the program will fail to compile.
138+
139+```
140+?: =(end count) :: 5
141+ ~ :: 6
142+```
143+
144+The `?:` rune in line 5 is an ordinary "if-then-else" conditional. If the expression that comes directly after it, `=(end count)`, evaluates to true, then the expression on line 6 is evaluated; otherwise the code starting at line 7 is evaluated. `=(end count)` itself is nothing more than a test of equality on `end` and `count`.
145+
146+If the values of `count` and `end` are equal then line 6 produces the
147+value `~`, null. This indicates the end of the list. When `count` is equal to `end`, the program is finished.
148+
149+Otherwise...
150+
151+```
152+:- count :: 7
153+$(count (add 1 count)) :: 8
154+```
155+
156+If not, line 7 uses the rune `:-` to produce a cell. Why is the program producing a cell here? Remember that cells are used to represent non-null lists in Hoon. The head of the cell is the value `count` and the tail is the product of evaluating `$(count (add 1 count))`.
157+
158+The product of the `$( )` call on line 8 is another list. It essentially says that the value of `count` is to be replaced by `(add 1 count)`, and that the code starting at `|-` is to be run again.
159+
160+And that's it!
docs/tutorials/hoon-ch2/hoon-ch2-10.umdnew file+324
@@ -0,0 +1,324 @@
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3+ next/'true'
4+ sort/'10'
5+ title/'Hoon Standard Library: Trees, Sets, and Maps'
6+ ==
7+;>
8+
9+# Hoon Standard Library: Trees, Sets, and Maps
10+
11+Along with lists, the Hoon standard library also supports trees, sets, and maps as data structures. A Hoon `tree` is the data structure for a binary tree. A Hoon `set` is the data structure for a set of values. A Hoon `map` is the data structure for a set of `[key value]` pairs.
12+
13+In this lesson we'll cover each.
14+
15+## Trees
16+
17+We use `tree` to make a binary tree data structure in Hoon, e.g., `(tree @)` for a binary tree of atoms.
18+
19+There are two kinds of `tree` in Hoon: (1) the null tree, `~`, and (2) a non-null tree which is a cell with three parts. Part (i) is the node value, part (ii) is the left child of the node, and part (iii) is the right child of the node. Each child is itself a tree. The node value has the face `n`, the left child has the face `l`, and the right child has the face `r`. The following diagram provides an illustration of a `(tree @)` (without the faces):
20+
21+```
22+ 12
23+ / \
24+ 8 14
25+ / \ / \
26+ 4 ~ ~ 16
27+ / \ / \
28+~ ~ ~ ~
29+```
30+
31+Hoon supports trees of any type that can be constructed in Hoon, e.g.: `(tree @)`, `(tree ^)`, `(tree [@ ?])`, etc. Let's construct the tree in the diagram above in the dojo, casting it accordingly:
32+
33+```
34+> `(tree @)`[12 [8 [4 ~ ~] ~] [14 ~ [16 ~ ~]]]
35+{4 8 12 14 16}
36+```
37+
38+Notice that we don't have to insert the faces manually; by casting the noun above to a `(tree @)` Hoon inserts the faces for us. Let's put this noun in the dojo subject with the face `b` and pull out the tree at the left child of the `12` node:
39+
40+```
41+> =b `(tree @)`[12 [8 [4 ~ ~] ~] [14 ~ [16 ~ ~]]]
42+
43+> b
44+{4 8 12 14 16}
45+
46+> l.b
47+-find.l.b
48+find-fork-d
49+```
50+
51+This didn't work because we haven't first proved to Hoon that `b` is a non-null tree. A null tree has no `l` in it, after all. Let's try again, using `?~` to prove that `b` isn't null. We can also look at `r` and `n`:
52+
53+```
54+> ?~(b ~ l.b)
55+{4 8}
56+
57+> ?~(b ~ r.b)
58+{14 16}
59+
60+> ?~(b ~ n.b)
61+12
62+```
63+
64+### Find and Replace
65+
66+Here's a program that finds and replaces certain atoms in a `(tree @)`.
67+
68+```
69+|= [nedl=@ hay=(tree @) new=@]
70+^- (tree @)
71+?~ hay ~
72+:+ ?: =(n.hay nedl)
73+ new
74+ n.hay
75+ $(hay l.hay)
76+$(hay r.hay)
77+```
78+
79+`nedl` is the atom to be replaced, `hay` is the tree, and `new` is the new atom with which to replace `nedl`. Save this as `findreplacetree.hoon` and run in the dojo:
80+
81+```
82+> b
83+{4 8 12 14 16}
84+
85+> +findreplacetree [8 b 94]
86+{4 94 12 14 16}
87+
88+> +findreplacetree [14 b 94]
89+{4 8 12 94 16}
90+```
91+
92+## Sets
93+
94+Use `set` to create a data structure for a set of values, e.g., `(set @)` for a set of atoms. The `in` core in the Hoon standard library contains the various functions for operating on sets. See the standard library reference documentation for sets here (include link).
95+
96+As with `list`s and `tree`s, there are two categories of sets: null `~`, and non-null. Hoon implements sets using trees for the underlying noun.
97+
98+Two common methods for populating a set include (1) creating it from a list of values using the `sy` function, and (2) inserting items into a set using the `put` arm of the `in` core.
99+
100+Using `sy`:
101+
102+```
103+> =c (sy ~[11 22 33 44 55])
104+
105+> c
106+[n=11 l={} r={22 33 44 55}]
107+
108+> `(set @)`c
109+{11 22 33 44 55}
110+
111+> =c `(set @)`c
112+```
113+
114+And we can add an item to the set using `put` of `in`:
115+
116+```
117+> (~(put in c) 77)
118+[n=11 l=~ r=[n=77 l={22 33 44 55} r={}]]
119+
120+> `(set @)`(~(put in c) 77)
121+{11 22 33 44 55 77}
122+```
123+
124+You can remove items using `del` of `in`:
125+
126+```
127+> (~(del in c) 55)
128+[n=11 l=~ r=[n=33 l={22} r={44}]]
129+
130+> `(set @)`(~(del in c) 55)
131+{11 22 33 44}
132+```
133+Check whether an item is in the set using `has` of `in`:
134+
135+```
136+> (~(has in c) 33)
137+%.y
138+
139+> (~(has in c) 100)
140+%.n
141+```
142+
143+You can apply a gate to each item of a set using `run` of `in` and produce a new set from the products:
144+
145+```
146+> c
147+{11 22 33 44 55}
148+
149+> (~(run in c) |=(a=@ +(a)))
150+{12 23 34 45 56}
151+```
152+
153+You can also apply a gate to all items of the set and return an accumulated value using `rep` of `in`:
154+
155+```
156+> c
157+{11 22 33 44 55}
158+
159+> (~(rep in c) add)
160+b=165
161+```
162+
163+The standard library also has the union and intersection functions for sets:
164+
165+```
166+> c
167+{11 22 33 44 55}
168+
169+> =d `(set @)`(sy ~[33 44 55 66 77])
170+
171+> d
172+{33 44 55 66 77}
173+
174+> (~(int in c) d)
175+[n=33 l={} r={44 55}]
176+
177+> `(set @)`(~(int in c) d)
178+{33 44 55}
179+
180+> (~(uni in c) d)
181+[n=11 l={} r={22 33 44 55 66 77}]
182+
183+> `(set @)`(~(uni in c) d)
184+{11 22 33 44 55 66 77}
185+```
186+
187+It may be convenient to turn a set into a list for some operation and then operate on the list. You can convert a set to a list using `tap` of `in`:
188+
189+```
190+> c
191+{11 22 33 44 55}
192+
193+> ~(tap in c)
194+~[55 44 33 22 11]
195+```
196+
197+There are other set functions in the Hoon standard library we won't cover here.
198+
199+### Cartesian Product
200+
201+Here's a program that takes two sets of atoms and returns the Cartesian product of those sets. A Cartesian of two sets `a` and `b` is a set of all the cells whose head is a member of `a` and whose tail is a member of `b`.
202+
203+```
204+|= [a=(set @) b=(set @)]
205+=/ c=(list @) ~(tap in a)
206+=/ d=(list @) ~(tap in b)
207+=| acc=(set [@ @])
208+|- ^- (set [@ @])
209+?~ c acc
210+%= $
211+ c t.c
212+ acc |- ?~ d acc
213+ %= $
214+ d t.d
215+ acc (~(put in acc) [i.c i.d])
216+ ==
217+==
218+```
219+
220+Save this as `cartesian.hoon` in your urbit's pier and run in the dojo:
221+
222+```
223+> =c `(set @)`(sy ~[1 2 3])
224+
225+> c
226+{1 3 2}
227+
228+> =d `(set @)`(sy ~[4 5 6])
229+
230+> d
231+{5 4 6}
232+
233+> +cartesian [c d]
234+{[1 5] [1 4] [1 6] [3 5] [3 4] [3 6] [2 5] [2 4] [2 6]}
235+```
236+
237+## Maps
238+
239+Use `map` to create a set of key-value pairs, e.g., `(map @tas *)` for a set of `@tas` and `*` pairs. The `@tas` value serves as the 'key', which is a mechanism for tagging or naming the value, `*`. They key of each key-value pair is unique; every value in a map gets its own unique name.
240+
241+One example use case is for storing customer information as a set of pairs: `(map [employee-name employee-data])`.
242+
243+The `by` core in the Hoon standard library contains the various functions for operating on maps. Many of these functions are similar to the set functions of the `in` core. See the standard library reference documentation for maps here (include link). As was the case with sets, the underlying noun of each map is a tree.
244+
245+Two common methods for populating a map include (1) creating it from a list of key-value cells using the `my` function, and (2) inserting items into a map using the `put` arm of the `my` core.
246+
247+Using `my`:
248+
249+```
250+> =c (my ~[[%one 1] [%two 2] [%three 3]])
251+
252+> c
253+[n=[p=%two q=2] l={[p=%three q=3] [p=%one q=1]} r={}]
254+
255+> =c `(map @tas @)`c
256+
257+> c
258+{[p=%three q=3] [p=%one q=1] [p=%two q=2]}
259+```
260+
261+We can add a key-value pair with `put` of `by`:
262+
263+```
264+> (~(put by c) [%four 4])
265+[n=[p=%two q=2] l={[p=%three q=3] [p=%four q=4] [p=%one q=1]} r={}]
266+
267+> `(map @tas @)`(~(put by c) [%four 4])
268+{[p=%three q=3] [p=%four q=4] [p=%one q=1] [p=%two q=2]}
269+```
270+
271+Delete a key-value pair with `del` of `by`, keeping in mind that you only need to pick the key of the pair to be deleted:
272+
273+```
274+> `(map @tas @)`(~(del by c) %two)
275+{[p=%three q=3] [p=%one q=1]}
276+```
277+
278+You can produce the value of a key-value pair using `get` of `by` on the key:
279+
280+```
281+> (~(get by c) %two)
282+[~ u=2]
283+```
284+
285+This result may be unexpected. Why didn't it just give us `2`? The answer has to do with the possibility that a requested key may not be in the map. For example:
286+
287+```
288+> (~(get by c) %chicken)
289+~
290+```
291+
292+Because there is no `%chicken` key in `c`, `get` simply returns `~` to indicate it's not in the map. Otherwise it returns a pair like the one you see in the next to last example.
293+
294+`get` of `by` returns the key's value as a `unit`, not as raw data. There are two kinds of `unit`s: null `~`, and non-null. A non-null `unit` is a pair of `[~ u=value]`. Unit types are constructed the way list, set, and map types are; for example, `(unit @)` is the type for a unit whose value is an atom.
295+
296+If you want to get some key value without producing a unit, use `got` instead:
297+
298+```
299+> (~(got by c) %two)
300+2
301+
302+> (~(got by c) %chicken)
303+####
304+ford: build failed
305+```
306+
307+Use `has` of `by` to see whether a certain key is in the map:
308+
309+```
310+> (~(has by c) %two)
311+%.y
312+
313+> (~(has by c) %chicken)
314+%.n
315+```
316+
317+You can use `run` of `by` to apply a gate to each value in a map, producing a map with the modified values:
318+
319+```
320+> (~(run by c) |=(a=@ (mul 2 a)))
321+{[p=%three q=6] [p=%one q=2] [p=%two q=4]}
322+```
323+
324+There are other map functions in the Hoon standard library we won't cover here.
docs/tutorials/hoon-ch2/hoon-ch2-11.umdnew file+516
@@ -0,0 +1,516 @@
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3+ sort/'11'
4+ title/'Examples'
5+ ==
6+;>
7+
8+# Examples
9+
10+Let's look at two more examples of Hoon code: the Sieve of Eratosthenes (a naive prime sieve) and a tic-tac-toe engine.
11+
12+## Sieve of Eratosthenes
13+
14+The following program produces the list of primes less than or equal to its argument, an atom:
15+
16+```
17+|= thru=@ :: 1
18+^- (list @) :: 2
19+=/ field=(set @) (sy (gulf 2 thru)) :: 3
20+|^ (sort ~(tap in sieve) lth) :: 4
21+++ sieve :: 5
22+ =/ factor=@ 2 :: 6
23+ |- ^- (set @) :: 7
24+ ?: (gth (mul factor factor) thru) :: 8
25+ field :: 9
26+ $(factor +(factor), field (reap factor)) :: 10
27+:: :: 11
28+++ reap :: 12
29+ |= factor=@ :: 13
30+ =/ count=@ (mul 2 factor) :: 14
31+ |- ^- (set @) :: 15
32+ ?: (gth count thru) :: 16
33+ field :: 17
34+ %= $ :: 18
35+ count (add count factor) :: 19
36+ field (~(del in field) count) :: 20
37+ == :: 21
38+-- :: 22
39+```
40+
41+Save it as `sieve.hoon` in `/gen` of your urbit's pier and run in the dojo:
42+
43+```
44+> +sieve 50
45+~[2 3 5 7 11 13 17 19 23 29 31 37 41 43 47]
46+```
47+
48+### Sieve Explanation
49+
50+```
51+|= thru=@ :: 1
52+^- (list @) :: 2
53+=/ field=(set @) (sy (gulf 2 thru)) :: 3
54+```
55+
56+Line 1: build a gate (function) whose sample (argument) is `thru`, an atom.
57+
58+Line 2: the product of this gate is a list of atoms.
59+
60+Line 3: introduce a face (variable) `field`, whose type is a set of atoms. `gulf` creates a list of atoms, from `2` to `thru` inclusive. The `sy` function converts this list to a set of those same atoms.
61+
62+```
63+|^ (sort ~(tap in sieve) lth) :: 4
64+++ sieve :: 5
65+ ...
66+++ reap :: 12
67+ ...
68+-- :: 22
69+```
70+
71+Before explaining line 4, let's first talk about what the `|^` rune is for. It creates a many-armed core, the first of which is named `$` and evaluated automatically. The first subexpression after the `|^` rune defines the `$` arm. This is followed by a series of arm definitions which is terminated with `--`.
72+
73+Line 4: introduce a core which does the desired work. The `$` arm is defined by the expression `(sort ~(tap in sieve) lth)`. The `sieve` arm of the core evaluates to a set of prime numbers in `field`. `tap` of `in` converts this set to a list, and `sort` arranges this list from least to greatest.
74+
75+```
76+++ sieve :: 5
77+ =/ factor=@ 2 :: 6
78+ |- ^- (set @) :: 7
79+ ?: (gth (mul factor factor) thru) :: 8
80+ field :: 9
81+ $(factor +(factor), field (reap factor)) :: 10
82+```
83+
84+Lines 5-10 define the `sieve` arm of the `|^` core. This arm works as a loop, sieving out non-primes from `field` on every pass until no primes are left.
85+
86+Line 6: the `factor` face (variable) is given an initial value of `2`.
87+
88+Line 7: indicates a recursion start point, i.e., the loop start point. The product of the loop is cast to a `(set @)`, i.e., a set of atoms.
89+
90+Lines 8-9: if `(mul factor factor)` is greater than `thru` then there are no more primes in `field`. In that case, return `field`.
91+
92+Line 10: Otherwise there may still be primes in `field`. Recurse (i.e., loop back to `|-`) but with `factor` increased in value by `1` and with the value of `field` replaced with `(reap factor)`. What does `reap` do?
93+
94+```
95+++ reap :: 12
96+ |= factor=@ :: 13
97+ =/ count=@ (mul 2 factor) :: 14
98+ |- ^- (set @) :: 15
99+ ?: (gth count thru) :: 16
100+ field :: 17
101+ %= $ :: 18
102+ count (add count factor) :: 19
103+ field (~(del in field) count) :: 20
104+ == :: 21
105+```
106+
107+Lines 12-21 define the `reap` arm of the core. This arm removes all multiples of `factor` from field except `factor` itself.
108+
109+Line 13 produces a gate (function) whose sample (argument) is an atom with the face `factor`.
110+
111+Line 14: sets the face (variable) `count` to the initial value of `(mul 2 factor)`.
112+
113+Line 15: indicates a recursion start point, i.e., a loop start point. The value produced by the loop is to be a `(set @)`, i.e., a set of atoms.
114+
115+Lines 16-17: if `count` is greater than `thru`, return `field`.
116+
117+Lines 18-21: otherwise, recurse (i.e. loop back to `|-`), but with the value of `count` changed to `(add count factor)` and `field` changed to `(~(del in field) count)`. `(~(del in field) count)` removes the atom `count` from `field`, if it's there.
118+
119+## Tic-tac-toe
120+
121+```
122+ x | |
123+-----------
124+ | x |
125+-----------
126+ o | x | o
127+```
128+
129+The `toe` tic-tac-toe program below takes a list of tic-tac-toe moves -- for example the move `[%x %2 %1]` indicates an `x` in the bottom-center square -- and returns and end-game result, e.g., `%x-wins`.
130+
131+```
132+=< |= moves=(list move) :: 1
133+ ^- outcome :: 2
134+ ?~ moves ~ :: 3
135+ =^ out game (step i.moves) :: 4
136+ ?~ out $(moves t.moves) :: 5
137+ out :: 6
138+:: :: 7
139+=> |% :: 8
140+ +$ move [=player =spot] :: 9
141+ +$ player ?(%x %o) :: 10
142+ +$ spot [x=num y=num] :: 11
143+ +$ num ?(%1 %2 %3) :: 12
144+ +$ outcome $? ~ :: 13
145+ %x-wins :: 14
146+ %o-wins :: 15
147+ %tie :: 16
148+ == :: 17
149+ -- :: 18
150+:: :: 19
151+|_ [board=(map spot player) last=?] :: 20
152+++ game . :: 21
153+:: :: 22
154+++ step :: 23
155+ |= mov=move :: 24
156+ ^- [outcome _game] :: 25
157+ ?: ?| &(last =(player.mov %o)) :: 26
158+ &(!last =(player.mov %x)) :: 27
159+ == :: 28
160+ ~&(%move-order !!) :: 29
161+ ?: (~(has by board) spot.mov) ~&(%spot-taken !!) :: 30
162+ =. board (~(put by board) [spot.mov player.mov]) :: 31
163+ [outcome-check game(last !last)] :: 32
164+:: :: 33
165+++ outcome-check :: 34
166+ ?: win-check :: 35
167+ ?:(last %x-wins %o-wins) :: 36
168+ ?:(tie-check %tie ~) :: 37
169+:: :: 38
170+++ win-check :: 39
171+ =/ who=player ?:(last %x %o) :: 40
172+ %+ lien winning-rows :: 41
173+ |= a=(list spot) :: 42
174+ %+ levy a :: 43
175+ |= b=spot :: 44
176+ =/ c=(unit player) (~(get by board) b) :: 45
177+ ?~(c | =(who u.c)) :: 46
178+:: :: 47
179+++ tie-check :: 48
180+ =(~(wyt in board) 9) :: 49
181+:: :: 50
182+++ winning-rows :: 51
183+ ^- (list (list spot)) :: 52
184+ :~ ~[[%1 %1] [%2 %1] [%3 %1]] :: 53
185+ ~[[%1 %2] [%2 %2] [%3 %2]] :: 54
186+ ~[[%1 %3] [%2 %3] [%3 %3]] :: 55
187+ ~[[%1 %1] [%1 %2] [%1 %3]] :: 56
188+ ~[[%2 %1] [%2 %2] [%2 %3]] :: 57
189+ ~[[%3 %1] [%3 %2] [%3 %3]] :: 58
190+ ~[[%1 %3] [%2 %2] [%3 %1]] :: 59
191+ ~[[%1 %1] [%2 %2] [%3 %3]] :: 60
192+ == :: 61
193+-- :: 62
194+```
195+
196+Save this as `toe.hoon` in `/gen` of your urbit's pier and run in the dojo:
197+
198+```
199+> +toe ~[[%x %2 %2]]
200+~
201+
202+> +toe ~[[%x %2 %2] [%o %1 %1] [%x %1 %3] [%o %3 %2] [%x %3 %1]]
203+%x-wins
204+
205+> +toe ~[[%x %2 %2] [%o %1 %3] [%x %1 %1] [%o %3 %3] [%x %2 %3] [%o %2 %1] [%x %1 %2] [%o %3 %2] [%x %3 %1]]
206+%tie
207+```
208+
209+### Tic-tac-toe Explanation
210+
211+```
212+=< |= moves=(list move) :: 1
213+ ^- outcome :: 2
214+ ?~ moves ~ :: 3
215+ =^ out game (step i.moves) :: 4
216+ ?~ out $(moves t.moves) :: 5
217+ out :: 6
218+```
219+
220+Lines 1-6 constitute the main loop of the program. The game state (`game`) is modified for each `move` of the sample list until either the game ends in a victory or a tie, or there are no more moves to evaluate.
221+
222+Lines 1-2: the `=<` rune is used to put a core into the subject before running the gate. (We'll look at that core later in the code, but it's important to keep in mind that data from that core is used in lines 1-6.)
223+
224+The `|=` rune produces a gate whose sample is `(list move)`, where a `move` represents a single move of tic-tac-toe. The `^-` is used to cast for an `outcome`. `move` and `outcome` are custom types defined later in the code.
225+
226+Line 3: if there are no more moves in `moves`, the game ends without a victory or a tie.
227+
228+Line 4: additional context is needed to understand this line.
229+
230+`game`, as defined by code later in the program, is a door, i.e., a many-armed core with a sample. This door has two pieces of data in its sample: (1) data representing the current game board arrangement, and (2) data representing which player made the last move, `x` or `o`. We're basically using the `game` core as a state machine, where the core sample is the mutable state.
231+
232+`step` is a function (defined later) that takes a `move` and returns two things: (1) an `outcome`, and (2) a modified version of `game` with the board modified to account the latest move.
233+
234+The `=^` rune is used to evaluate the `step` call, setting the product `outcome` of (1) to `out`, and changing the value of `game` to the newer version from (2).
235+
236+Lines 5-6: if `out` is `~` (i.e., not a victory or a tie), then there is a recursion back to `|-` on the next `move` in the list. Otherwise, `out` is returned.
237+
238+```
239+=> |% :: 8
240+ +$ move [=player =spot] :: 9
241+ +$ player ?(%x %o) :: 10
242+ +$ spot [x=num y=num] :: 11
243+ +$ num ?(%1 %2 %3) :: 12
244+ +$ outcome $? ~ :: 13
245+ %x-wins :: 14
246+ %o-wins :: 15
247+ %tie :: 16
248+ == :: 17
249+ -- :: 18
250+```
251+
252+Lines 8-18 use a `|%` core to define all the custom types used in the program.
253+
254+Line 8: the `=>` rune is used to put the `|%` core into the subject before going on to evaluate something else later in the code. (This 'something else' is another core for defining `game`.)
255+
256+Line 9: the `move` type is for cells in which the head is a `player` and the tail is a `spot`. The `=player` and `=spot` syntax may be unfamiliar to you. The former is used to indicate that the `player` value should have a `player` face on it, and the latter to indicate that the `spot` value should have the `spot` face on it. If value `g` is known to be of the type `move`, you can get the `player` value with `player.g`.
257+
258+Line 10: the `player` type is for the set of two constants: `%x` and `%o`.
259+
260+Line 11: a `spot` is a pair of `num`s, one for the x coordinate and one for the y coordinate.
261+
262+Line 12: `num` is for the set of three constants: `%1`, `%2`, `%3`.
263+
264+Line 13: `outcome` is for the set of four constants: `~`, `%x-wins`, `%o-wins`, and `%tie`.
265+
266+```
267+|_ [board=(map spot player) last=?] :: 20
268+++ game . :: 21
269+:: :: 22
270+++ step :: 23
271+ ...
272+++ outcome-check :: 34
273+ ...
274+++ win-check :: 39
275+ ...
276+++ tie-check :: 48
277+ ...
278+++ winning-rows :: 51
279+ ...
280+-- :: 62
281+```
282+
283+Lines 20-62 produce a door, i.e., a many-armed core with a sample. The sample of this core defines the game state, and the arms define the computations for making appropriate changes to that state. The `game` arm is trivial; it's just the value from `.`. Remember that `.` resolves to the entire subject, and that the subject of an arm computation is the parent core; hence, `game` is effectively a name of the entire door.
284+
285+The door has a two-part sample: `board` is a map from `spot` to `player`. `board` is essentially a record of which moves have already been made. `last` is a simple flag for keeping track of whose turn it is to make a move.
286+
287+```
288+++ step :: 23
289+ |= mov=move :: 24
290+ ^- [outcome _game] :: 25
291+ ?: ?| &(last =(player.mov %o)) :: 26
292+ &(!last =(player.mov %x)) :: 27
293+ == :: 28
294+ ~&(%move-order !!) :: 29
295+ ?: (~(has by board) spot.mov) ~&(%spot-taken !!) :: 30
296+ =. board (~(put by board) [spot.mov player.mov]) :: 31
297+ [outcome-check game(last !last)] :: 32
298+```
299+
300+Lines 23-32 are for the `step` arm. This arm is the step function of the state machine. It takes a `move` and returns a pair of (1) `outcome` and (2) a new state for the `game` door.
301+
302+Lines 24-25: `mov` is the name of the `move` in the sample. The cast on line 25 is for a pair of `outcome` and a core of the same type as `game`. (Remember that `_game` is short for `$_(game)`.)
303+
304+Lines 26-30: these lines are for checking whether the correct player made the latest move. If not, the program will crash.
305+
306+The `?:` conditional on line 26 has a complex condition that spans three lines. If either of `&(last =(player.mov %o))` or `&(!last =(player.mov %x))` is true, the `true` branch is evaluated: `~&(%move-order !!)`.
307+
308+Let's look at the first more carefully. `&( )` is for logical AND, so `&(last =(player.mov %o))` is true if and only if both `last` and `=(player.mov %o)` are true. When `last` is true, it's `x`'s turn to make a move. If `o` moves out of turn, then the `!!` rune is used to crash the program.
309+
310+Line 30: checks whether the latest move is for a `board` square that is already taken. If `spot.mov` already has an assignment in `board`, the `!!` rune is used to crash the program.
311+
312+Line 31: modifies `board` by `put`ing the latest move into it.
313+
314+Line 32: return the pair of `outcome-check` and the `game` core with the `last` flag value flipped. (Remember that `!` is for logical NOT -- `!last` is opposite in value to `last`.) `outcome-check` is another arm in the core.
315+
316+```
317+++ outcome-check :: 34
318+ ?: win-check :: 35
319+ ?:(last %x-wins %o-wins) :: 36
320+ ?:(tie-check %tie ~) :: 37
321+```
322+
323+Lines 34-37 define the `outcome-check` arm, which is used to check the state and see whether a final game outcome has occurred. First a `win-check` is performed to see whether the latest `move` is a winning one. If so, that player wins. Otherwise, a `tie-check` is performed.
324+
325+```
326+++ win-check :: 39
327+ =/ who=player ?:(last %x %o) :: 40
328+ %+ lien winning-rows :: 41
329+ |= a=(list spot) :: 42
330+ %+ levy a :: 43
331+ |= b=spot :: 44
332+ =/ c=(unit player) (~(get by board) b) :: 45
333+ ?~(c | =(who u.c)) :: 46
334+```
335+
336+Lines 39-46 define the `win-check` arm, which is used to see whether the latest `move` is a winning one. `who` is the last player to make a move. This arm uses the `lien` and `levy` functions from the Hoon standard library.
337+
338+`lien` takes a list and a gate that produces a flag, and it applies the gate to each item in the list. If at least one of the resulting products is `%.y`, then `lien` produces `%.y`; otherwise, it produces a `%.n`. (You can think of `lien` as being a logical OR for a list.) For example:
339+
340+```
341+> =g `(list @)`~[10 11 12 13]
342+
343+> =h |=(a=@ (gth a 12))
344+
345+> (lien g h)
346+%.y
347+```
348+
349+`levy` is the same thing, except that it only evaluates to `%.y` if all applications of the gate to list items result in `%.y`. (You can think of `levy` as being a logical AND for a list.) For example:
350+
351+```
352+> =g `(list @)`~[10 11 12 13]
353+
354+> =h |=(a=@ (gth a 12))
355+
356+> (levy g h)
357+%.n
358+
359+> =h |=(a=@ (gth a 7))
360+
361+> (levy g h)
362+%.y
363+```
364+
365+With those functions in mind, let's get back to the code:
366+
367+```
368+++ win-check :: 39
369+ =/ who=player ?:(last %x %o) :: 40
370+ %+ lien winning-rows :: 41
371+ |= a=(list spot) :: 42
372+ %+ levy a :: 43
373+ |= b=spot :: 44
374+ =/ c=(unit player) (~(get by board) b) :: 45
375+ ?~(c | =(who u.c)) :: 46
376+```
377+
378+Lines 41-46: `winning-rows` is an arm that evaluates to a list of the eight victory conditions for tic-tac-toe. `lien` is used to determine if at least one of these eight conditions holds for the last player to make a move.
379+
380+Each victory condition is recorded as a list of spots. `levy` is used to determine whether the player has his mark on all of those spots. If so, the last player wins.
381+
382+The `~(get by board)` call is used to see which player has a mark on the spot in question, `b`. `get` of `by` returns a `unit`, which means that `c` must be a `(unit player)`, not just a `player`. We must use `?~` to test whether `c` is null before we can get the raw player data using `u.c`.
383+
384+If no player has a mark at spot `b`, then the `~(get by board)` call returns `~`, null.
385+
386+```
387+++ tie-check :: 48
388+ =(~(wyt in board) 9) :: 49
389+```
390+
391+Lines 48-49 define the `tie-check` arm, which is used to see if the result is a tie game. The game is tied if all nine `board` squares are taken and no one has won. Because the `win-check` occurs before the `tie-check`, we only need to determine if all nine `board` squares have been taken.
392+
393+We use `wyt` of `in` to check how many squares have been taken; if it's `9`, then return `%.y`, otherwise `%.n`. `wyt` is a function that returns the number of items in a set. It can be used for maps as well.
394+
395+```
396+++ winning-rows :: 51
397+ ^- (list (list spot)) :: 52
398+ :~ ~[[%1 %1] [%2 %1] [%3 %1]] :: 53
399+ ~[[%1 %2] [%2 %2] [%3 %2]] :: 54
400+ ~[[%1 %3] [%2 %3] [%3 %3]] :: 55
401+ ~[[%1 %1] [%1 %2] [%1 %3]] :: 56
402+ ~[[%2 %1] [%2 %2] [%2 %3]] :: 57
403+ ~[[%3 %1] [%3 %2] [%3 %3]] :: 58
404+ ~[[%1 %3] [%2 %2] [%3 %1]] :: 59
405+ ~[[%1 %1] [%2 %2] [%3 %3]] :: 60
406+ == :: 61
407+```
408+
409+Lines 51-61 define the `winning-rows` arm, which produces a list of the eight victory conditions for tic-tac-toe. Each victory condition is a list of three `spot`s. The `:~` rune is used to produce a list from a series of expressions, terminated with `==`.
410+
411+Now you know how to write tic-tac-toe in Hoon!
412+
413+## Exercise: Conway's Game of Life
414+
415+Conway's Game of Life is a zero-player game played on an `n x n` grid of spaces, each of which is either 'alive' or 'dead'. Every iteration, some or all of the spaces change from alive to dead or from dead to alive.
416+
417+Specifically, for each iteration, each dead space becomes alive if and only if it is adjacent to exactly three live spaces. Each live remains alive if and only if it is adjacent to either two or three live spaces. In this context, "adjacent to" includes the eight spaces that share either a side or a corner with the space. Thus, in the following map, the center space (dead) is adjacent to exactly three live spaces, so it will be alive in the next iteration. `#` signifies a live space and `.` signifies a dead space.
418+
419+```
420+ ..#
421+ ...
422+ ##.
423+```
424+
425+1. Write a function `next-generation` that takes nine flag
426+ inputs, `nw`, `nc`, `ne`, `cw`, `cc`, `ce`, `sw`, `sc`, and
427+ `se`. Produce 'yes' if the center space will be alive in the
428+ next generation and 'no' if it will be dead.
429+
430+1. Write a function `create-board` that takes an integer `n` and
431+ produces an `n` by `n` grid of flags, (hereafter,
432+ "board"), initialized to 'no'. This grid should be
433+ represented as a list of `n` lists of length `n`.
434+
435+1. Write a function `toggle-space` that takes a board, a row
436+ index, and a column index, and produces a new board,
437+ identical to the old except that the state of the space
438+ referred to by the row and column indices has been toggled.
439+
440+1. Use the following function `print-board` to pretty-print the
441+ board. For bonus points, try to follow what it's doing.
442+
443+ ```
444+ |= board=(list (list ?))
445+ ^- tang
446+ %+ turn board
447+ |= row=(list ?)
448+ :- %leaf
449+ ^- tape
450+ %+ turn row
451+ |= space=?
452+ ?: space
453+ '# '
454+ '. '
455+ ```
456+
457+ If you run this function with a board, you'll get a
458+ pretty-printable object (a `tang`), but it won't be
459+ pretty-printed. When running the generator from the dojo,
460+ run `&tang +generator arguments` to mark the result as a
461+ `tang`, which will tell the dojo to pretty-print it
462+ appropriately.
463+
464+1. Using the functions created in the previous exercises, create
465+ a 10 by 10 board, and flip the states of the spaces at
466+ coordinates (counting from the top left, indexed from 0)
467+ `(2,1)`, `(3,2)`, `(1,3)`, `(2,3)`, and `(3,3)`. Use the
468+ pretty printer to print out the board. Your output should be
469+ the following:
470+
471+ ```
472+ . . . . . . . . . .
473+ . . # . . . . . . .
474+ . . . # . . . . . .
475+ . # # # . . . . . .
476+ . . . . . . . . . .
477+ . . . . . . . . . .
478+ . . . . . . . . . .
479+ . . . . . . . . . .
480+ . . . . . . . . . .
481+ . . . . . . . . . .
482+ ```
483+
484+1. Write a function `step` that iterates every space on the
485+ board. Print out the new board. It should look like this:
486+
487+ ```
488+ . . . . . . . . . .
489+ . . . . . . . . . .
490+ . # . # . . . . . .
491+ . . # # . . . . . .
492+ . . # . . . . . . .
493+ . . . . . . . . . .
494+ . . . . . . . . . .
495+ . . . . . . . . . .
496+ . . . . . . . . . .
497+ . . . . . . . . . .
498+ ```
499+
500+ > Note that the spaces on the edge don't have the full nine
501+ > neighbors. For now, assume that they're always dead.
502+
503+1. Write a function `life` that runs the above function `n`
504+ times on the board. Observe the board as the game
505+ progresses. Congratulations, you've written Conway's Game of
506+ Life in Hoon!
507+
508+1. One common way to handle the edge of the board is to pretend
509+ that it "wraps around", forming a torus. In other words, say
510+ that the spaces on the left edge of the map are adjacent to
511+ the ones on the right edge, and the spaces on the top edge
512+ are adjacent to the spaces on the bottom edge. Modify `step`
513+ to act this way. Pay special attention to the corners.
514+
515+1. Modify `create-board` to use `++og` to randomly initialize
516+ the board with live or dead spaces.
docs/tutorials/hoon-ch2/hoon-ch2-2.umdnew file+593
@@ -0,0 +1,593 @@
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3+ next/'true'
4+ sort/'2'
5+ title/'Hoon Syntax'
6+ ==
7+;>
8+
9+# Hoon Syntax
10+
11+The study of Hoon can be divided into two parts: syntax and semantics.
12+
13+The [syntax](https://en.wikipedia.org/wiki/Syntax_(programming_languages)) of a programming language is the set of rules that determine what counts as admissible code in that language. It determines which characters may be used in the source, and also how these characters may be assembled to constitute a program. Failing to follow these rules when writing a program and then trying to run it will result in a syntax error.
14+
15+The [semantics](https://en.wikipedia.org/wiki/Semantics_(computer_science)) of a programming language concerns the meaning of the various parts of that language's code.
16+
17+In this lesson we cover Hoon's syntax. A strict account of Hoon's syntax would refrain from making any reference at all to semantics, but for ease of exposition we won't be quite so fastidious.
18+
19+## Hoon Characters
20+
21+Hoon source files are composed almost entirely of the [printable ASCII characters](https://en.wikipedia.org/wiki/ASCII#Printable_characters). Hoon does not accept any other characters in source files except for [UTF-8](https://en.wikipedia.org/wiki/UTF-8) in quoted strings. Hard tab characters are illegal.
22+
23+```
24+> "You can put ½ in quotes, but not elsewhere!"
25+"You can put ½ in quotes, but not elsewhere!"
26+
27+> 'You can put ½ in single quotes too.'
28+'You can put ½ in single quotes too.'
29+
30+> "Some UTF-8: ἄλφα"
31+"Some UTF-8: ἄλφα"
32+```
33+
34+### Reading Hoon Aloud
35+
36+Hoon code makes heavy use of non-alphanumeric symbols. Reading off code aloud using the proper names of ASCII symbols is tedious, so we've mapped syllables to symbols:
37+
38+```
39+ace [1 space] hep - rob }
40+ban > ket ^ say '
41+bar | lac [ sig ~
42+bat \ led < tar *
43+bus $ lit ( tec `
44+cab _ lob { tis =
45+cen % lus + vat @
46+col : mic ; wut ?
47+com , net / yel "
48+dot . pad & zap ~
49+gap [>1 space, nl] rac ]
50+hax # rit )
51+```
52+
53+Learning and using these names of non-alphanumeric symbols is entirely optional; you can become an expert Hoon programmer without them. Many Hoon programmers find them helpful, however.
54+
55+Note that the list includes two separate whitespace forms: `ace` for a single space; `gap` is either 2+ spaces or a newline. In Hoon, the only whitespace significance is the distinction between `ace` and `gap` -- i.e., the distinction between one space and more than one.
56+
57+## Expressions of Hoon
58+
59+An [expression](https://en.wikipedia.org/wiki/Expression_(computer_science)) is a combination of characters that the language interprets and evaluates as producing a value. Hoon programs are made up entirely of expressions.
60+
61+Hoon expressions can be either basic or complex. Basic expressions of Hoon are fundamental, meaning that they can't be broken down into smaller expressions. Complex expressions are made up of smaller expressions (which are called *subexpressions*).
62+
63+There are many categories of Hoon expressions: noun literals, wing expressions, type expressions, and rune expressions. Let's go over each.
64+
65+### Noun Literals
66+
67+A noun is either an atom or a cell. An atom is an unsigned integer and a cell is a pair of nouns.
68+
69+There are [literal](https://en.wikipedia.org/wiki/Literal_(computer_programming)) expressions for each kind of noun. A noun literal is just a notation for representing a fixed noun value.
70+
71+We start with atom literals. Each of these is a basic expression of Hoon that evaluates to itself. Examples:
72+
73+```
74+> 1
75+1
76+
77+> 123
78+123
79+
80+> 123.456
81+123.456
82+
83+> 'hello'
84+'hello'
85+
86+> ~zod
87+~zod
88+
89+> 0xdead.beef
90+0xdead.beef
91+
92+> 0b1101.1001
93+0b1101.1001
94+```
95+
96+Recall from lesson 1.2 (link) that even though atoms are unsigned integers, they can be pretty-printed in different ways. The way an atom is to be represented depends on its aura. The literal syntax for each of the hard-coded auras will be explained further in lesson XXXX.
97+
98+Cell literals can be written in Hoon using `[ ]`. Cell literals are complex, because other expressions are put inside the square brackets. Examples:
99+
100+```
101+> [6 7]
102+[6 7]
103+
104+> [[12 14] [654 123.456 980]]
105+[[12 14] 654 123.456 980]
106+
107+> ['hello' 0xdad]
108+['hello' 0xdad]
109+
110+> [123 [~zod ~ten] .1.2837]
111+[123 [~zod ~ten] .1.2837]
112+```
113+
114+A murkier case involves putting complex expressions inside square brackets to make a cell. These are valid expressions but they aren't cell literals, naturally:
115+
116+```
117+> [(add 22 33) (mul 22 33)]
118+[55 726]
119+```
120+
121+### Wings
122+
123+A wing expression is a series of limb expressions separated by `.`. You learned about these in sections 1.3 (link) and 1.4 (link).
124+
125+Let's start with the base case: a single limb. A limb expression is a trivial wing expression -- there is only one limb in the series. Some one-limb wings:
126+
127+- `+2`
128+- `-`
129+- `+>`
130+- `&4`
131+- `a`
132+- `b`
133+- `add`
134+- `mul`
135+- `kebab-case-123`
136+
137+As a special limb we also have `$`. This is the name of the arm in special one-armed cores called "gates". (We covered the role of `$` in lesson 1.5 (link).)
138+
139+Wing expressions with multiple limbs are complex expressions. Examples:
140+
141+- `+2.+3.+4`
142+- `-.+.+`
143+- `search.path.into.subject`
144+- `+>.$`
145+- `a.b.c`
146+- `-.b.+2`
147+- `-.add`
148+
149+### Type Expressions
150+
151+Hoon is a statically typed language. You'll learn more about the type system later in the chapter. For now, just know that Hoon's type system uses special symbols to indicate certain fundamental types: `~` (null), `*` (noun), `@` (atom), `^` (cell), and `?` (flag). Each of these symbols can be used as a stand-alone expression of Hoon. In the case of `@` there may be a series of letters following it, to indicate an atom aura; e.g., `@s`, `@rs`, `@tas`, and `@tD`.
152+
153+They may also be put in brackets to indicate compound types, e.g., `[@ ^]`, `[@ud @sb]`, `[[? *] ^]`. (Technically these expressions don't _always_ indicate compound types. In certain contexts they're interpreted in a different way. We'll address this variation of meaning in lesson XXXX.)
154+
155+### Rune Expressions
156+
157+A *rune* is just a pair of ASCII characters (a digraph). You've already seen some runes in Chapter 1: `|=`,`|%`, and `|_`. We usually pronounce runes by combining their characters' names, e.g.: 'ket-hep' for `^-`, 'bar-tis' for `|=`, and 'bar-cen' for `|%`. As stated previously, these names are entirely optional.
158+
159+Expressions with a rune at the beginning are rune expressions. Most runes are used at the beginning of a complex expression, but there are exceptions. For example, the runes `--` and `==` are used at the end of certain expressions.
160+
161+Runes are classified by family (with the exceptions of `--` and `==`). The first of the two symbols indicates the family -- e.g., the `^-` rune is in the `^` family of runes, and the `|=` and `|%` runes are in the `|` family. The runes of particular family usually have related meanings. Two simple examples: the runes in the `|` family are all used to create cores, and the runes in the `:` family are all used to create cells.
162+
163+Rune expressions are usually complex, which means they usually have one or more subexpressions. The appropriate syntax varies from rune to rune; after all, they're used for different purposes. To see the correct syntax of a particular rune, consult the rune reference (link). Nevertheless, there are some general principles that hold of all rune expressions.
164+
165+#### Tall and Flat Forms
166+
167+There are two rune syntax forms: *tall* and *flat*. Tall form is usually used for multi-line expressions, and flat form is used for one-line expressions. Most runes can be used in either of tall or flat forms. Tall form expressions may contain flat form subexpressions, but flat form expressions may not contain tall form.
168+
169+The spacing rules differ in the two forms. In tall form, each rune and subexpression must be separated from the others by a `gap` -- that is, by two or more spaces, or a line break. In flat form the rune is immediately followed by parentheses `( )`, and the various subexpressions inside the parentheses must be separated from the others by an `ace` -- that is, by a single space.
170+
171+Seeing an example will help you understand the difference. The `:-` rune is used to produce a cell. Accordingly, it is followed by two subexpressions: the first defines the head of the cell, and the second defines the tail. Here are three different ways to write a `:-` hoon in tall form:
172+
173+```
174+> :- 11 22
175+[11 22]
176+
177+> :- 11
178+ 22
179+[11 22]
180+
181+> :-
182+ 11
183+ 22
184+[11 22]
185+```
186+
187+These all do the same thing. The first example shows that, if you really want to, you can write 'tall' form code on a single line. Notice that there are two spaces between the `:-` rune and `11`, and also between `11` and `22`. This is the minimum spacing necessary between the various parts of a tall form expression -- any fewer will result in a syntax error.
188+
189+Usually one or more line breaks are used to break up a tall form expression. This is especially useful when the subexpressions are themselves long stretches of code. The same `:-` hoon in flat-form is:
190+
191+```
192+> :-(11 22)
193+[11 22]
194+```
195+
196+This is the preferred way to write a hoon on a single line. The rune itself is followed by a set of parentheses, and the subexpressions inside are separated by a single space. Any more spacing than that results in a syntax error.
197+
198+Nearly all rune expressions can be written in either form, but there are exceptions. The `|%` and `|_` expressions, for example, can only be written in tall form. (Those (link) are a bit too complicated to fit comfortably on one line anyway.)
199+
200+#### Irregular Forms
201+
202+Some runes are used so frequently that they have irregular counterparts that are easier to write and which mean precisely the same thing. Irregular rune syntax is hence a form of [syntactic sugar](https://en.wikipedia.org/wiki/Syntactic_sugar). All irregular rune syntax is flat. (It follows from this that all tall form expressions are regular.)
203+
204+Let's look at another example. The `.=` rune takes two subexpressions, evaluates them, and tests the results for equality. If they're equal it produces `%.y` for 'yes'; otherwise `%.n` for 'no'. In tall form:
205+
206+```
207+> .= 22 11
208+%.n
209+
210+> .= 22 (add 11 11)
211+%.y
212+
213+> .= 22
214+ 11
215+%.n
216+
217+> .= 22
218+ (add 11 11)
219+%.y
220+```
221+
222+And in flat form:
223+
224+```
225+> .=(22 11)
226+%.n
227+
228+> .=(22 (add 11 11))
229+%.y
230+```
231+
232+The irregular form of the `.=` rune is just `=( )`:
233+
234+```
235+> =(22 11)
236+%.n
237+
238+> =(22 (add 11 11))
239+%.y
240+```
241+
242+The examples above have another irregular form: `(add 11 11)`. This is the irregular form of `%+`, which calls a gate (i.e., a Hoon function) with two arguments for the sample.
243+
244+```
245+> %+ add 11 11
246+22
247+
248+> %+(add 11 11)
249+22
250+```
251+
252+The irregular `( )` gate-calling syntax is versatile -- it is also a shortcut for calling a gate with one argument, which is what the `%-` rune is for:
253+
254+```
255+> (dec 11)
256+10
257+
258+> %- dec 11
259+10
260+
261+> %-(dec 11)
262+10
263+```
264+
265+The `( )` gate-calling syntax can be used for gates of any other [arity](https://en.wikipedia.org/wiki/Arity) as well.
266+
267+You've already seen two other irregular forms. In lesson 1.5 (link), you made a gate that takes an atom `a` for its sample and returns `a + 1`: `|=(a=@ (add 1 a))`. This expression uses the `|=` rune in flat form.
268+
269+```
270+> =inc |=(a=@ (add 1 a))
271+
272+> (inc 10)
273+11
274+
275+> (inc 15)
276+16
277+```
278+
279+The `a=@` subexpression -- used to define the face and the type of the gate's sample -- is the irregular form of `$=(a @)`:
280+
281+```
282+> =inc |=($=(a @) (add 1 a))
283+
284+> (inc 10)
285+11
286+
287+> (inc 15)
288+16
289+```
290+
291+In the previous chapter you also defined faces in nouns as in the following examples:
292+
293+```
294+> b:[a=15 b=25 c=35]
295+25
296+
297+> c:[a=15 b=25 c=35]
298+35
299+```
300+
301+The `a=15` expression is the irregular form of `^=(a 15)`:
302+
303+```
304+> b:[^=(a 15) ^=(b 25) ^=(c 35)]
305+25
306+
307+> c:[^=(a 15) ^=(b 25) ^=(c 35)]
308+35
309+```
310+
311+You can find other irregular forms in the irregular expression reference document (link).
312+
313+### Expressions That Are Only Irregular
314+
315+There are certain irregular expressions that aren't syntactic sugar for regular form equivalents -- they're solely irregular. There isn't much in general that can be said about these because they're all different, but we can look at some examples.
316+
317+Below we use the `` ` `` symbol to create a cell whose head is null, `~`.
318+
319+```
320+> `12
321+[~ 12]
322+
323+> `[12 14]
324+[~ 12 14]
325+
326+> `[[12 14] 16]
327+[~ [12 14] 16]
328+```
329+
330+Putting `,.` in front of a wing expression removes a face, if there is one.
331+
332+```
333+> -:[a=[12 14] b=[16 18]]
334+a=[12 14]
335+
336+> ,.-:[a=[12 14] b=[16 18]]
337+[12 14]
338+
339+> ,.-:[[12 14] b=[16 18]]
340+[12 14]
341+
342+> +:[a=[12 14] b=[16 18]]
343+b=[16 18]
344+
345+> ,.+:[a=[12 14] b=[16 18]]
346+[16 18]
347+
348+> ,.+:[a=[12 14] [16 18]]
349+[16 18]
350+```
351+
352+To see other irregular expressions, check the irregular expression reference document (link).
353+
354+## Hoon Style
355+
356+In this section we'll talk about preferred Hoon code style. Strictly speaking, all the guidelines in this section are optional -- if you follow the minimum syntax rules, your code should parse and run correctly. On the other hand, code clarity and maintainability are important. We think the following guidelines will help you to write better, clearer code. None of these rules is absolute, however -- use your judgment about what looks neat and clear.
357+
358+### Code Margin, Blank Lines
359+
360+An 80-column right margin is strongly encouraged. Really well-groomed Hoon uses a 55-column code margin and puts a standard line comment at column 57. Use `::` to begin a comment -- Hoon will ignore everything past the `::` until the line break. Here's an example of code that follows these principles:
361+
362+```
363+|= a=@ :: even number checker
364+^- ? :: output is a flag
365+=(0 (mod a 2)) :: =(...) evals to flag
366+```
367+
368+Blank lines are discouraged. If you want vertical space in your code, use `::` at the beginning of one or more lines.
369+
370+```
371+|= a=@ :: even number checker
372+^- ? :: output is a flag
373+::
374+:: lots
375+:: of
376+:: space
377+::
378+=(0 (mod a 2)) :: =(...) evals to flag
379+```
380+
381+### Rune Expression Body Types
382+
383+Let's call everything in the expression after the initial rune the expression *body*. There are four kinds of body: *fixed*, *running*, *jogging*, and *battery*. There is a preferred manner of styling for each body.
384+
385+#### Fixed
386+
387+Some runes have a *fixed* number of subexpressions. For example, the `:-` and `.=` runes each have exactly two.
388+
389+Fixed bodies often use "backstep" indentation in tall form. In backstep indentation the code slopes backward and to the right by two spaces per line. The last subexpression isn't indented at all, and the first subexpression is on the same line as the rune. The indentation of the first subexpression therefore depends upon the total number of subexpressions.
390+
391+We'll use the `:` family of runes to illustrate. The `:-` rune creates a cell from two subexpressions, `:+` creates a cell from three, and `:^` creates a cell from four. In flat form:
392+
393+```
394+> :-(11 22)
395+[11 22]
396+
397+> :+(11 22 33)
398+[11 22 33]
399+
400+> :^(11 22 33 44)
401+[11 22 33 44]
402+```
403+
404+Let's look at these in tall form, using backstep indentation:
405+
406+```
407+> :- 11
408+ 22
409+[11 22]
410+
411+> :+ 11
412+ 22
413+ 33
414+[11 22 33]
415+
416+> :^ 11
417+ 22
418+ 33
419+ 44
420+[11 22 33 44]
421+```
422+
423+
424+Some other *1-fixed*, *2-fixed*, *3-fixed* and *4-fixed* examples, using `p`, `q`, `r`, and `s` for the subexpressions:
425+
426+```
427+|.
428+p
429+
430+=| p
431+q
432+
433+?: p
434+ q
435+r
436+
437+%^ p
438+ q
439+ r
440+s
441+```
442+
443+In optimal usage of backstep indentation the most complicated subexpressions are at the bottom. This helps keep code flow vertical rather than diagonal.
444+
445+#### Running
446+
447+A *running* body doesn't have a fixed number of subexpressions; hoons with running bodies can be arbitrarily long.
448+
449+To indicate the end of such expressions in tall form, use the `==` rune. The first subexpression is two spaces after the initial rune, and all others are indented to line up with the first. The terminating `==` should align vertically with the initial rune. In flat form, parentheses are used around the expression body, so the terminating `==` is unnecessary.
450+
451+The `:*` rune is used to create a cell of arbitrary length:
452+
453+```
454+> :*(11 22 33)
455+[11 22 33]
456+
457+> :*(11 22 33 44)
458+[11 22 33 44]
459+
460+> :*(11 22 33 44 55)
461+[11 22 33 44 55]
462+```
463+
464+We'll use `:*` to illustrate proper tall form running body style:
465+
466+```
467+> :* 11
468+ 22
469+ 33
470+ 44
471+ 55
472+ ==
473+[11 22 33 44 55]
474+```
475+
476+More generally:
477+
478+```
479+:* p
480+ q
481+ r
482+ s
483+ t
484+==
485+```
486+
487+#### Jogging
488+
489+A *jogging* body is an arbitrarily long series of subexpression pairs. Most jogging bodies are preceded by a fixed sequence of subexpressions. The first jogging pair is one line after the last fixed subexpression, and indented two spaces behind it. There are two jogging conventions: *flat* (each pair on one line) and *tall* (each pair split across lines). In either case the expression is terminated with a `==`.
490+
491+The `?-` rune is `1-fixed` followed by a jogging body. The fixed subexpression is evaluated and then compared against the left subexpression of each of the jogging pairs. When a match is found, the subexpression to the right of the match is evaluated.
492+
493+For example:
494+
495+```
496+> ?- `?(%2 %3 %4)`%2
497+ %2 %yes
498+ %3 %no
499+ %4 %no
500+ ==
501+%yes
502+```
503+
504+More generally, the *flat jogging* style (preceded by *1-fixed* `p`):
505+
506+```
507+?- p
508+ q r
509+ s t
510+ u v
511+==
512+```
513+
514+A *tall jogging* example (preceded by *1-fixed* `p`):
515+
516+```
517+?- p
518+ q
519+ r
520+ s
521+ t
522+ u
523+ v
524+==
525+```
526+
527+In flat form for *jogging* bodies, subexpression pairs are separated by commas:
528+
529+```
530+$(a +(a), b (dec b), c (add 2 c))
531+```
532+
533+#### Battery
534+
535+Certain runes are used to create a core. Cores with multiple arms have a special syntax for defining each of the arms in the battery. A core has no fixed limit on the number of arms contained in its battery, so you must terminate core expressions with the `--` rune. Each arm in the battery is defined with three things: (1) a rune in the `+` family (e.g., `++`, `+*`, and `+$`), (2) an arm name, and (3) a subexpression defining the content of that arm. Runes in the `+` family may only go in core subexpressions. Putting them anywhere else results in a syntax error.
536+
537+Here's an example of a *battery* body:
538+
539+```
540+|%
541+++ arm-1
542+ %p
543+++ arm-2
544+ %q
545+++ arm-3
546+ %r
547+--
548+```
549+
550+## Motivation
551+
552+There's no denying that Hoon's syntax is a bit strange, especially for those used to working in other programming languages. Hoon makes heavy use of ASCII characters, and this can be intimidating to newcomers. However, we believe that anyone who learns Hoon syntax will find that it has a number of advantages.
553+
554+Hoon's syntax is designed to address three serious problems in functional syntax design. These problems are: (1) *terminator piles*, (2) *indentation creep*, and (3) *feature/label confusion*.
555+
556+### Terminator piles
557+
558+A *terminator pile* is a series of termination characters required to end some expression in a language. Think of Lisp's stacks of right parentheses. For a trivial example, let's say you want to add 22 five times in Lisp using `+`:
559+
560+```
561+(+ 22 (+ 22 (+ 22 (+ 22 22))))
562+```
563+
564+In a sufficiently complicated expression it's tedious to keep track of all the parentheses in the terminator pile. You can write terminator piles in Hoon code if you really want to:
565+
566+```
567+> (add 22 (add 22 (add 22 (add 22 22))))
568+110
569+```
570+
571+...but you are never forced to do so. There is always a semantically equivalent alternative syntax without them:
572+
573+```
574+> %+ add 22
575+ %+ add 22
576+ %+ add 22
577+ %+ add 22 22
578+110
579+```
580+
581+### Indentation creep
582+
583+In some programming languages there is an indentation convention according to which an expression embedded within a parent expression is indented more to the right. In a sufficiently long and complicated function with many embedded subexpressions, the tendency is for the code to shift more and more to the right. This tendency is called *indentation creep*, and it can become an irritating problem when working with long functions. It's true that short functions are better, but long ones sometimes need to be written.
584+
585+Ordinary indentation conventions give long functions a _diagonal_ shape, which is a poor fit for most editor windows. Hoon is designed to be written with 'backstep' indentation (explained later in this lesson) so that the code flows _down_, not down and across.
586+
587+### Feature/label confusion
588+
589+A language lends itself to *feature/label confusion* (FLC) when it's difficult to distinguish general features of the language from labels in a particular program. This can be a serious problem other functional programming languages. In Lisp, for example, a user-defined macro has the same syntax as a function call.
590+
591+The worst-case result of FLC is "DSL cancer". Every source file with this malady is effectively written in its own domain-specific language (DSL). Learning to read such a file is like learning a language. One can also describe the result as "write-only code". User-level macros, operator overloading, and even excessive use of higher-order programming, can all lead quickly to the tragedy of write-only code.
592+
593+Hoon largely avoids FLC by its use of runes. Hoon has no user-level macros or operator overloading. It does support higher-order programming; write-only Hoon can certainly be (and has been) written. However, with a little discipline one can write Hoon without inventing a DSL.
docs/tutorials/hoon-ch2/hoon-ch2-3.umdnew file+895
@@ -0,0 +1,895 @@
1+:- :~ navhome/'/docs/'
2+ navuptwo/'true'
3+ next/'true'
4+ sort/'3'
5+ title/'Simple One-Gate Programs'
6+ ==
7+;>
8+
9+# Simple One-Gate Programs
10+
11+In this lesson we'll try to cover enough basic Hoon so that you can write (and understand!) your own simple programs. Each of the programs given in this lesson defines a gate. (Gates are one-armed cores of Hoon that can be used as functions -- this is covered in lesson 1.5 (link).)
12+
13+For each program we encourage you to: (1) write out the program yourself, (2) save it to the `/home/gen` directory of your urbit's pier, and (3) run it from the dojo. The best way to learn to program in Hoon is by getting your hands dirty.
14+
15+We will also continue to run one-line snippets of code in the dojo. We encourage you to enter these for yourself as well.
16+
17+## Intro to Writing Gates
18+
19+Let's look at a really simple gate: `|=(a=@ 15)`. This gate takes any atom as input and returns the value `15`.
20+
21+The `|=` rune takes two subexpressions. The first must indicate a type, and the second may evaluate to any value. The first defines the gate's sample type and possibly binds a face to it, and the second defines the output of the gate. In the example `|=(a=@ 15)` the `|=` subexpressions are `a=@` and `15`.
22+
23+The following characters represent basic Hoon types: `@` for atoms, `^` for cells, `?` for flags, and `*` for nouns. You should already know what atoms, cells, and nouns are. (See lesson 1.2 (link) if you need a reminder.) There are two values for the `?` type: `%.y` for yes, and `%.n` for no. In other words, `?` is for the [Boolean values](https://en.wikipedia.org/wiki/Boolean_data_type) of Hoon.
24+
25+You could have picked a different type for the first subexpression of `|=(a=@ 15)` and left off the face. To illustrate this let's call different versions of the gate with the `(gate arg)` function call syntax:
26+
27+```
28+> (|=(@ 15) 11)
29+15
30+
31+> (|=(@ 15) 22)
32+15
33+
34+> (|=(* 15) 11)
35+15
36+
37+> (|=(* 15) 22)
38+15
39+
40+> (|=(^ 15) 11)
41+nest-fail [crash message]
42+```
43+
44+The argument for each of these function calls is either `11` or `22`. These are atoms, `@`, and hence also nouns, `*`. So when you define the sample to be either `@` or `*` the evaluation works as desired.
45+
46+In the last function call, however, the gate's sample is defined to be a cell, `^`, and `11` isn't a cell. This is why, when that gate is called with `11`, the result is a `nest-fail` crash message. The call didn't work! For all function calls, Hoon's type system checks whether the type of the argument matches the type of the sample. If not, the the function will not be evaluated and you get the `nest-fail`.
47+
48+Ordinarily a face is included in the first subexpression after the `|=` rune. This makes it easier to refer to the sample in the second `|=` subexpression. Usually you'll want the gate product to depend on the arguments passed.
49+
50+```
51+> (|=(a=@ (add 2 a)) 12)
52+14
53+
54+> (|=(a=@ (add 2 a)) 14)
55+16
56+```
57+
58+### Checking the Gate's Output
59+
60+You are probably fallible. A fallible person will, at least occasionally, write code that produces output of the wrong type. Hoon's type system is designed to help you avoid this problem, but to take full advantage of this help you have to ask. You can do this with a 'cast' expression. It is good practice to include a cast in every gate expression you write in Hoon.
61+
62+A cast is a test that the value produced by an expression is provably of the desired type. When the code is compiled, the compiler does type inference on the expression in question. (We'll talk in more detail about how Hoon's type inference works later in the chapter.) If the inferred type 'nests' under the desired type then the cast succeeds and the program is compiled. Otherwise, the compile halts with a `nest-fail` crash. In the latter case the program -- at least potentially -- produces the wrong kind of value and needs to be debugged.
63+
64+There are different ways to cast, but for now we'll just use the `^-` rune. Consider the even number checker given in the last lesson:
65+
66+```
67+|= a=@ :: even number checker
68+^- ? :: output is a flag
69+=(0 (mod a 2)) :: if remainder=0 'yes'
70+```
71+
72+The first subexpression after `|=` is `a=@`, and the second is the rather more complex:
73+
74+```
75+^- ?
76+=(0 (mod a 2))
77+```
78+
79+This latter subexpression begins with the `^-` rune, which itself takes two subexpressions. The first `^-` subexpression must indicate a type, `?`, and the second is to be evaluated, `=(0 (mod a 2))`. The value of the second subexpression is the value produced by the whole `^-` expression.
80+
81+The inferred type of `=(0 (mod a 2))` is compared against `?`. If the former type fits under the latter, the type-check passes. Otherwise the program will fail to compile, `nest-fail`.
82+
83+Save the even number checker to the `/home/gen` directory of your pier as `even.hoon` and run it from the dojo:
84+
85+```
86+> +even 11
87+%.n
88+
89+> +even 22
90+%.y
91+```
92+
93+Now replace the `=(0 (mod a 2))` in the third line with just `15`. The result:
94+
95+```
96+|= a=@ :: even number checker
97+^- ? :: output is a flag
98+15 :: return 15
99+```
100+
101+Save this and try to run it from the dojo again:
102+
103+```
104+> +even 22
105+[stack trace]
106+nest-fail
107+```
108+
109+You changed the gate so that the output is `15`, which is an atom, `@`. But you're casting for a flag, `?` -- either `%.y` or `%.n`. Because `@` doesn't nest under `?` the program fails to compile.
110+
111+### Multiple Inputs and Outputs
112+
113+A gate is a one-armed core with a sample:
114+
115+```
116+ [gate]
117+ / \
118+ [$ arm] [payload]
119+ / \
120+ [sample] [context]
121+```
122+
123+When a function call to a gate occurs, the `$` arm is evaluated with the gate itself as the subject. But the gate's payload is usually modified. The modification in question is to the sample: the default gate sample is replaced with the argument(s) of the function call. This is how the `$` arm 'knows' what the argument(s) of the function are.
124+
125+The sample is just the noun in that slot of the gate, `+6`. The product of the arm evaluation is just another noun. Thus, gates always have a single noun for input and a single noun for output.
126+
127+But we would like to use functions that take multiple inputs as well as functions with multiple outputs. How? The obvious solution is to use cells.
128+
129+Let's write a program that checks two numbers at a time and tells us if each is even:
130+
131+```
132+::
133+:: even2.hoon
134+::
135+:: this gate takes a pair of atoms, tests whether each is even, and then
136+:: returns two flags.
137+::
138+|= [a=@ b=@] :: check two numbers
139+^- [? ?] :: output is two flags
140+:- =(0 (mod a 2)) :: :-(x y) makes [x y]
141+=(0 (mod b 2)) ::
142+```
143+
144+The first `|=` subexpression is now `[a=@ b=@]`. This indicates a complex type for the gate's sample. The gate takes a pair of atoms, labeling the first `a` and the second `b`.
145+
146+The second `|=` subexpression is:
147+
148+```
149+^- [? ?]
150+:- =(0 (mod a 2))
151+=(0 (mod b 2))
152+```
153+
154+The first of two `^-` subexpressions is `[? ?]`, indicating another complex type. The inferred type of the second `^-` subexpression must be a cell of two flags, or else the program will fail to compile. The second `^-` subexpression:
155+
156+```
157+:- =(0 (mod a 2))
158+=(0 (mod b 2))
159+```
160+
161+The `:-` rune takes two subexpressions and makes them into a cell. Each of these, `=(0 (mod a 2))` and `=(0 (mod b 2))`, evaluates to a flag value, `?`.
162+
163+Save the whole program in your pier as `even2.hoon` (or as something else if you like) and test it in the dojo. Remembering to pass the two arguments as a cell:
164+
165+```
166+> +even2 [2 2]
167+[%.y %.y]
168+
169+> +even2 [2 3]
170+[%.y %.n]
171+
172+> +even2 [3 3]
173+[%.n %.n]
174+
175+> +even2 [22 33]
176+[%.y %.n]
177+```
178+
179+A gate may take as input or produce as output arbitrarily complex cells. For example, one could write a gate that takes a cell of five different things:
180+
181+```
182+|= [a=* b=@ud c=^ d=? e=@sb]
183+...
184+```
185+
186+## Basic Tools
187+
188+### `.+` and `.=`
189+
190+The `.+` rune is for 'incrementing'; it takes an atom and adds `1` to it. That's it! Here it is in action:
191+
192+```
193+> .+ 22
194+23
195+
196+> .+(22)
197+23
198+
199+> .+(101)
200+102
201+```
202+
203+But it's nearly always used in its irregular form, which lacks the `.`:
204+
205+```
206+> +(22)
207+23
208+
209+> +(101)
210+102
211+```
212+
213+You've already used the `.=` rune in its irregular form, `=( )`. This rune takes two subexpressions, evaluates them, and then does a simple test of equality on the resulting values.
214+
215+```
216+> =(22 11)
217+%.n
218+
219+> =(22 (add 11 11))
220+%.y
221+```
222+
223+But there's one more quirk that you should know about: `.=(a b)` includes a type check. Of the inferred types of `a` and `b`, one must nest in the other or else the code won't compile:
224+
225+```
226+> =(12 [12 14])
227+nest-fail
228+```
229+
230+The inferred type of `12` is `@ud`, and the inferred type of `[12 14]` is `[@ud @ud]`. Neither type nests under the other, so the code fails to compile. There is a way to get around this type check, which we'll explain later in this chapter. The best policy is to avoid wiggling out of type safety checks, however.
231+
232+### Introduction to Conditionals: The `?` Rune Family
233+
234+We won't cover all the `?` runes here -- we'll save some for the upcoming lesson on types. But we'll cover enough to get you writing simple Hoon programs.
235+
236+#### `?:` if-then-else
237+
238+The `?:` rune indicates an 'if-then-else' expression and takes three subexpressions: (1) the condition, which must evaluate to a flag, (2) an expression to be evaluated if the condition evaluates to `%.y`, and (3) an expression to be evaluated if the condition evaluates to `%.n`.
239+
240+```
241+> ?:(%.y 11 22)
242+11
243+
244+> ?: %.y
245+ 11
246+ 22
247+11
248+
249+> ?:(%.n 11 22)
250+22
251+```
252+
253+#### `?.` ifnot-then-else
254+
255+The `?.` rune does precisely the same thing as `?:`, except reversed: if the condition evaluates to `%.n` then the second subexpression is evaluated, otherwise the third is evaluated.
256+
257+```
258+> ?.(%.y 11 22)
259+22
260+
261+> ?. %.y
262+ 11
263+ 22
264+22
265+
266+> ?.(%.n 11 22)
267+11
268+```
269+
270+The reasons for Hoon's having both `?:` and `?.` involve code neatness and clarity. Use whichever makes your code better.
271+
272+#### `?&` logical 'AND'
273+
274+The `?&` rune is for logical 'AND'. It takes two or more subexpressions, each of which must evaluate to a flag, `?`; and if all subhoons evaluate to `%.y` then the result of the `?&` hoon is `%.y`. Otherwise it's `%.n`. In tall form the expression is terminated with `==`.
275+
276+```
277+> ?& %.y %.y %.y ==
278+%.y
279+
280+> ?& & | & ==
281+%.n
282+
283+> ?&(%.y %.y %.y)
284+%.y
285+
286+> ?&(& =(1 2) &)
287+%.n
288+```
289+
290+You may be confused about the lone `&` and `|` characters in the second and fourth examples above. The `&` character (used by itself) is another alias for 'yes', and `|` (used by itself) is another alias for 'no':
291+
292+```
293+> &
294+%.y
295+
296+> |
297+%.n
298+```
299+
300+The irregular form of `?&` allows you to drop the `?` symbol:
301+
302+```
303+> &(& & &)
304+%.y
305+
306+> &(| & &)
307+%.n
308+
309+> &(& | &)
310+%.n
311+
312+> &(& & |)
313+%.n
314+```
315+
316+To be clear, in `&(blah-1 blah-2)` the `&()` is the irregular `?&` rune; and anywhere else in the code `&` by itself means 'yes', `%.y`.
317+
318+#### `?|` logical 'OR'
319+
320+The `?|` rune is for logical 'OR'. It takes two or more subexpressions, each of which must evaluate to a flag, `?`. If at least one evaluates to `%.y` then the whole `?|` expression evals to `%.y`; otherwise it's `%.n`:
321+
322+```
323+> ?| %.n %.n %.n ==
324+%.n
325+
326+> ?| | | & ==
327+%.y
328+
329+> ?|(=(12 12) | |)
330+%.y
331+```
332+
333+The irregular form drops the `?` symbol:
334+
335+```
336+> |(=(12 12) | |)
337+%.y
338+
339+> |(=(12 13) | |)
340+%.n
341+```
342+
343+#### `?!` logical 'NOT'
344+
345+The `?!` rune is for logical 'NOT'. It takes one subexpression that evaluates to a flag and returns the opposite value.
346+
347+```
348+> ?! &
349+%.n
350+
351+> ?!(|)
352+%.y
353+```
354+
355+The irregular form drops the `?` symbol and uses no parentheses:
356+
357+```
358+> !|
359+%.y
360+
361+> =(22 33)
362+%.n
363+
364+> !=(22 33)
365+%.y
366+```
367+
368+#### Are All Three Even?
369+
370+Let's write a program that takes three atoms, `@`, and returns `%.y` if they're all even, otherwise `%.n`.
371+
372+```
373+|= [a=@ b=@ c=@] :: check three @
374+^- ? :: output is a flag
375+?& =(0 (mod a 2)) :: `a` is even AND
376+ =(0 (mod b 2)) :: `b` is even AND
377+ =(0 (mod c 2)) :: `c` is even
378+==
379+```
380+
381+Save this in your urbit's pier as `even3.hoon` and run it from the dojo:
382+
383+```
384+> +even3 [12 13 14]
385+%.n
386+
387+> +even3 [12 16 14]
388+%.y
389+```
390+
391+#### If So, Multiply -- Otherwise Add
392+
393+Let's write a slightly more complicated program. The gate takes three atoms, `@`, and if all three are even it multiplies all of them together. Otherwise, it adds them all together.
394+
395+```
396+|= [a=@ b=@ c=@] :: take three @
397+^- @ :: output is an @
398+?: ?& =(0 (mod a 2)) :: if `a` is even AND
399+ =(0 (mod b 2)) :: `b` is even AND
400+ =(0 (mod c 2)) :: `c` is even
401+ ==
402+ (mul a (mul b c)) :: then multiply
403+(add a (add b c)) :: otherwise add
404+```
405+
406+Save this as `addmul.hoon` and try it from the dojo:
407+
408+```
409+> +addmul [2 2 2]
410+8
411+
412+> +addmul [2 2 3]
413+7
414+
415+> +addmul [4 4 4]
416+64
417+
418+> +addmul [4 4 5]
419+13
420+```
421+
422+### Subject Modification: The `=` Rune Family
423+
424+As with the `?` family, we won't explain all the runes of the `=` family -- just a few to get you started.
425+
426+#### `=>` Evaluate a Hoon Against a Subject
427+
428+The `=>` rune takes two subexpressions. The first is evaluated, with the result becoming the new subject; the second subexpression is evaluated against that subject.
429+
430+A few examples:
431+
432+```
433+> => [[a=12 b=14] [c=16 d=18]] +
434+[c=16 d=18]
435+
436+> => [[a=12 b=14] [c=16 d=18]] -
437+[a=12 b=14]
438+
439+> => [[a=12 b=14] [c=16 d=18]] +>
440+d=18
441+
442+> => [[a=12 b=14] [c=16 d=18]] a
443+12
444+
445+> => [[a=12 b=14] [c=16 d=18]] d
446+18
447+```
448+
449+#### `=<` Evaluate a Hoon Against a Subject, Reversed
450+
451+The `=<` rune is just like `=>` but reversed. The second subexpression is evaluated, with the result becoming the new subject; the first subexpression is evaluated against that subject.
452+
453+A few examples:
454+
455+```
456+> =< + [[a=12 b=14] [c=16 d=18]]
457+[c=16 d=18]
458+
459+> =< - [[a=12 b=14] [c=16 d=18]]
460+[a=12 b=14]
461+
462+> =< +> [[a=12 b=14] [c=16 d=18]]
463+d=18
464+
465+> =< a.- [[a=12 b=14] [c=16 d=18]]
466+12
467+
468+> =< d.+ [[a=12 b=14] [c=16 d=18]]
469+18
470+```
471+
472+The `=>` and `=<` runes should seem vaguely familiar, in spirit if not otherwise. You've already used the irregular version of `=<`, with the `:` character:
473+
474+```
475+> +:[[a=12 b=14] [c=16 d=18]]
476+[c=16 d=18]
477+
478+> -:[[a=12 b=14] [c=16 d=18]]
479+[a=12 b=14]
480+
481+> +>:[[a=12 b=14] [c=16 d=18]]
482+d=18
483+
484+> a:[[a=12 b=14] [c=16 d=18]]
485+12
486+
487+> d:[[a=12 b=14] [c=16 d=18]]
488+18
489+```
490+
491+#### `=+` 'Pin' a Noun to the Subject
492+
493+The `=+` rune takes two subexpressions. The first is evaluated and then the resulting value is 'pinned' to the head of the subject -- that is, the old subject becomes the tail of the new subject, and the value produced by the first `=+` subexpression becomes the head of the new subject. The second `=+` subexpression is evaluated against the new subject. Examples:
494+
495+```
496+> => [22 33 44] =+(101 -)
497+101
498+
499+> => [22 33 44] =+(101 +)
500+[22 33 44]
501+
502+> => [22 33 44] =+(101 +1)
503+[101 22 33 44]
504+
505+> => [b=22 c=33 d=44] a
506+-find.a
507+
508+> => [b=22 c=33 d=44] =+(a=101 a)
509+101
510+```
511+
512+#### `=/` Pin a Faced (and Possibly Typed) Noun To the Subject
513+
514+The `=/` rune is a more powerful variation of `=+`. `=/` takes three subexpressions: (1) the first is the face for the noun to be pinned (e.g., `a`), and possibly includes a type (e.g., `a=@`); (2) the second is the noun to be pinned; and (3) the third is the expression to be evaluated on the modified subject.
515+
516+Some examples:
517+
518+```
519+> =/(b=@ 22 [b b b])
520+[22 22 22]
521+
522+> =/(b=@ 22 (add b b))
523+44
524+```
525+
526+The `=/` rune is the closest thing Hoon has to an instruction for 'initializing a variable' while giving it an initial value. What actually occurs in Hoon is that the value is pinned to the head of the subject, and the indicated face is bound to that value.
527+
528+#### `=|` Pin a Faced, Typed Default Noun to the Subject
529+
530+The `=|` is a lot like the `=/` rune except that (1) you must include type information when you use it, and (2) the programmer doesn't set the initial value of the face -- it's a default value for the type in question, sometimes called a 'bunt' value. The `=|` rune takes two subexpressions. The first is a face names (e.g., `a`), followed by `=`, followed by a type (e.g., `@`). The second is to be evaluated against the modified subject.
531+
532+```
533+> =| a=@ a
534+0
535+
536+> =| a=^ a
537+[0 0]
538+
539+> =| a=? a
540+%.y
541+```
542+
543+The `=|` rune is a lot like 'initializing a variable' but for faces, without giving the face an interesting initial value (a default value for the type is used instead, i.e., the 'bunt' value).
544+
545+#### `=.` Change a Leg of the Subject
546+
547+The `=.` rune takes three subexpression. The first is a wing expression, indicating the leg of the subject whose value is to be changed. The second is the new value for the indicated leg. The third is the expression to be evaluated against the modified subject.
548+
549+```
550+> =/ a=@ 22 =.(a 99 a)
551+99
552+
553+> =/ a=@ 22 [a =.(a 99 a)]
554+[22 99]
555+
556+> => [12 14] =.(+2 22 .)
557+[22 14]
558+```
559+
560+This rune is often used for modifying the value of a face whose value was set beforehand.
561+
562+## Recursion
563+
564+How do we do loops in Hoon? Like other functional programming languages Hoon uses [recursion](https://en.wikipedia.org/wiki/Recursion_(computer_science)). In rough terms, a recursive function solves a problem in part by calling on itself to solve a slightly easier or smaller case of the same problem. The self-calling loop continues until the simplified problem is so simple that it has a trivial solution.
565+
566+Seeing an example will make this process easier to understand.
567+
568+### Addition
569+
570+Let's write a gate that takes a pair of atoms, `@`, and which returns the sum of these atoms. There is a cheap solution to this problem, of course. The Hoon standard library has `add` in it:
571+
572+```
573+> (add 22 33)
574+55
575+```
576+
577+But let's solve the problem without using `add` from the Hoon standard library. We have the `.+` rune for adding `1` and the `.=` rune for testing equality. We'll also use `dec` from the standard library and some recursion. That's it!
578+
579+What's `dec`? It takes some atom, `@`, and returns the decrement -- i.e., it takes some number `a` and returns `a - 1`:
580+
581+```
582+> (dec 101)
583+100
584+
585+> (dec 51)
586+50
587+
588+> (dec 11)
589+10
590+```
591+
592+For adding two atoms together, the algorithm we'll use is very simple. We start with two numbers, `a` and `b`. If `b` is `0`, then the answer is `a`. (This is the trivial case of addition for our algorithm, sometimes also called the 'base' case.) Otherwise, the answer is the sum of `a + 1` and `b - 1` -- now do *that* addition. (This is the *recursive* case.)
593+
594+Do you see how this process calls for a loop of sorts? If you want to sum `7` and `2`, check to see whether the second number is `0`. It isn't, so now figure out the sum of `8` and `1`. Is the second number `0`? No, so do the sum of `9` and `0`. Now the second number is `0` -- the answer is `9`.
595+
596+Here's the program:
597+
598+```
599+|= [a=@ b=@] :: take two @
600+^- @ :: output is one @
601+?: =(b 0) :: if b is 0
602+ a :: return a, else
603+$(a +(a), b (dec b)) :: add a+1 and b-1
604+```
605+
606+Save it as `add.hoon` in your urbit's pier and run it from the dojo:
607+
608+```
609+> +add [22 33]
610+55
611+
612+> +add [122 33]
613+155
614+```
615+
616+It works!
617+
618+Every line of `add.hoon` should be clear up to the last one. What's going on there? The `$( )` is used for recursive function calls. That is, it's a way for a function to call itself, but with certain values modified according to the instructions inside the parentheses. Two values are being modified for the call: `a` is modified to `+(a)`, and `b` is modified to `(dec b)`. A comma is used to separate the two modification instructions. (Of course, in programs that call for it, more than two modifications may be made here.)
619+
620+### `%=` Resolve to a Wing with Changes
621+
622+The `$( )` syntax is an irregular form of the the `%=` rune. We can rewrite that part of `add.hoon` in regular form:
623+
624+```
625+|= [a=@ b=@] :: take two @
626+^- @ :: output is one @
627+?: =(b 0) :: if b is 0
628+ a :: return a, else
629+%= $ :: resolve to $
630+ a +(a) :: but change a to +(a)
631+ b (dec b) :: and b to (dec b)
632+==
633+```
634+
635+This version is precisely equivalent to the old one. The first `%=` subexpression is for a wing. In the program above, this is just `$`. The other subexpressions of `%=` indicate the changes to be made upon resolution to the wing. You can make as many of these changes as desired when using `%=`, so the expression is ended with `==`.
636+
637+Remember from lessons 1.4-1.5 (links) that wing resolution works in two different ways. If the wing resolves to a leg, that fragment of the subject is returned. If the wing resolves to an arm, the arm is evaluated with its parent core as the subject. In lesson 1.5 (link) you learned that `$` is the special name of the arm of a gate. (Remember, a gate is a one-armed core with a sample.) Because we wrote `add.hoon` with `|=` it produces a gate. The `%=` expression above thus evaluates the `$` arm of the gate, but only after having made changes to the parent core: `a` is incremented, and `b` is decremented.
638+
639+### Decrement
640+
641+We've used `dec`, but now let's write our own version. That is, let's write a gate that takes some atom, `@`, and returns the 'decrement' of that value. There is a cheap solution to this problem too. The Hoon standard library has the `sub` function in it for subtraction:
642+
643+```
644+> (sub 100 50)
645+50
646+
647+> (sub 100 1)
648+99
649+```
650+
651+But let's solve the problem without using the Hoon standard library. We have the `.+` rune for adding `1`, the `.=` rune for testing equality, and various runes of the `=` family for manipulating the subject. And we'll again use recursion.
652+
653+How do we decrement using only those tools? The algorithm is pretty simple. We'll start by defining a counter value, `0`, and binding it to `c`.
654+
655+If `c + 1` equals the value to be decremented, then `c` is the answer. (This is the trivial case.) Otherwise, we increment `c` by `1` and try again. (This is the recursive case.)
656+
657+There's one quirk about this algorithm that makes it different from the addition algorithm. We didn't set any initial values in the addition program, and so calling the whole function at the end was an acceptable option. If we do the same thing with decrement -- call the whole function at the end -- we'll end up setting the same face, `c`, to the same initial value again, `0`. We don't want that. We want the counter to increase in value for each loop! There should be a recursion start point that comes after `c` is set initially. For that you can use the `|-` rune.
658+
659+Here's the program:
660+
661+```
662+|= a=@ :: take one @
663+=/ c=@ 0 :: set c to 0
664+|- :: recursion start
665+^- @ :: output is @
666+?: =(a +(c)) :: if a = c+1
667+ c :: return c, else
668+$(c +(c)) :: add 1 to c, recurse
669+ :: back to the |-
670+```
671+
672+Save it as `dec.hoon` and try it from the dojo:
673+
674+```
675+> +dec 101
676+100
677+
678+> +dec 97
679+96
680+
681+> +dec 11
682+10
683+```
684+
685+At an intuitive level this code should make sense. The `$( )` at the end effectively serves as a loop going back to the `|-` rune, with a modification to the value of `c`. But isn't `$` the name of the gate's single arm? What's going on? Let's take a moment to understand how `|-` works at a deeper level.
686+
687+### `|-` Make and Call a One-armed Core
688+
689+The `|-` rune makes a one-armed core whose arm has the name `$`, and then it calls `$`. The `|-` rune takes one subexpression, which determines what `$` does:
690+
691+```
692+> |- 2
693+2
694+
695+> |- (add 22 33)
696+55
697+```
698+
699+Let's look at the decrement program again, this time using the regular version of the `%=` rune.
700+
701+```
702+|= a=@ :: take one @
703+=/ c=@ 0 :: set c to 0
704+|- :: recursion start
705+^- @ :: output is @
706+?: =(a +(c)) :: if a = c+1
707+ c :: return c, else
708+%= $ :: resolve to $
709+ c +(c) :: add 1 to c
710+==
711+```
712+
713+Strictly speaking, when you use `$( )` or `%= $` you're asking for a resolution to `$` (with changes indicated in parentheses). And because `$` is an arm, that means evaluating it with its parent core as the subject.
714+
715+When we use `|-` in our decrement program, we're defining a _new_ core whose arm name is `$`, in addition to the one created by `|=`. So the subject ends up having two arms named `$` in it: one for the gate defined by `|=`, and one for the core defined by `|-`.
716+
717+When `$( )` or `%= $` is executed, the subject is searched for the `$` arm. The `|-` `$` arm is found first because it was defined later than the `|=` arm. You can skip the first name match for `$` by using `^`, if you like. That is, if you like, you can recurse all the way to the beginning of the function using `^$( )` or `%= ^$`.
718+
719+### Exercises
720+
721+You should know enough at this point to write some basic Hoon programs. Practice with some of these exercises. Solutions are provided at the bottom of the page.
722+
723+#### Exercise 2.3.1: Subtraction
724+
725+Write a program that takes two numbers and returns the difference. You may use `dec`, but don't use anything else from the Hoon standard library.
726+
727+#### Exercise 2.3.2: Factorial
728+
729+Write a program that takes a number `n` and returns the factorial of `n`, `n!`. `1!` is `1`, `2!` is `2 x 1`, `3!` is `3 x 2 x 1`, `4!` is `4 x 3 x 2 x 1`, and so on. You may use the Hoon standard library.
730+
731+#### Exercise 2.3.3: Prime Number Checker
732+
733+Write a program that takes a number `n` and returns `%.y` if it's prime, and `%.n` if it isn't. You may use the Hoon standard library.
734+
735+## Fizzbuzz
736+
737+Let's write a Hoon implementation of [FizzBuzz](https://en.wikipedia.org/wiki/Fizz_buzz). Fizzbuzz takes some number `n` and then makes a list of numbers from `1` to `n`, except that numbers evenly divisible by `3` are replaced with 'Fizz', numbers evenly divisible by `5` are replaced with 'Buzz', and numbers evenly divisible by both are replaced with 'FizzBuzz'.
738+
739+You already saw a program that produces a list of atoms from `1` to `n` in lesson 2.1 (link), `listnum.hoon`:
740+
741+```
742+|= end=@ :: 1
743+=/ count=@ 1 :: 2
744+|- :: 3
745+^- (list @) :: 4
746+?: =(end count) :: 5
747+ ~ :: 6
748+:- count :: 7
749+$(count (add 1 count)) :: 8
750+```
751+
752+The difference for FizzBuzz is that certain items of the product list must be replaced with strings: `"Fizz"`, `"Buzz"`, and `"FizzBuzz"`.
753+
754+Below is our implementation of FizzBuzz. Each line is commented with a number for convenient line reference:
755+
756+```
757+|= end=@ :: 1
758+=/ count=@ 1 :: 2
759+|- :: 3
760+^- (list tape) :: 4
761+?: =(end count) :: 5
762+ ~ :: 6
763+:- :: 7
764+ ?: =(0 (mod count 15)) :: 8
765+ "FizzBuzz" :: 9
766+ ?: =(0 (mod count 3)) :: 10
767+ "Fizz" :: 11
768+ ?: =(0 (mod count 5)) :: 12
769+ "Buzz" :: 13
770+ <count> :: 14
771+$(count (add 1 count)) :: 15
772+```
773+
774+Save this as 'fizzbuzz.hoon' in `/home/gen` of your urbit's pier. To run it enter `+fizzbuzz 25` in the dojo:
775+
776+```
777+> +fizzbuzz 25
778+<<
779+ "1"
780+ "2"
781+ "Fizz"
782+ "4"
783+ "Buzz"
784+ "Fizz"
785+ "7"
786+ "8"
787+ "Fizz"
788+ "Buzz"
789+ "11"
790+ "Fizz"
791+ "13"
792+ "14"
793+ "FizzBuzz"
794+ "16"
795+ "17"
796+ "Fizz"
797+ "19"
798+ "Buzz"
799+ "Fizz"
800+ "22"
801+ "23"
802+ "Fizz"
803+>>
804+```
805+
806+### Explaining Fizzbuzz
807+
808+```
809+|= end=@ :: 1
810+=/ count=@ 1 :: 2
811+|- :: 3
812+^- (list tape) :: 4
813+```
814+
815+This gate takes an atom, `end`, for its sample. The initial value of `count`, an atom, is `1`. Line `3` uses `|-` for a recursion (or loop) starting point, so that `count` is only set to `1` once.
816+
817+The gate output is cast to `(list tape)`, i.e., to a list of `tape`s. A `tape` is one of Hoon's two string types and is pretty-printed as a string in double quotes.
818+
819+```
820+> "This is a tape."
821+"This is a tape."
822+
823+> "So is this!"
824+"So is this!"
825+```
826+
827+Moving on:
828+
829+```
830+?: =(end count) :: 5
831+ ~ :: 6
832+```
833+
834+If `end` and `count` are the same value, then the list is finished. The null character, `~`, is returned. (Reminder: Hoon lists are null-terminated.)
835+
836+Otherwise...
837+
838+```
839+:- :: 7
840+ ?: =(0 (mod count 15)) :: 8
841+ "FizzBuzz" :: 9
842+ ?: =(0 (mod count 3)) :: 10
843+ "Fizz" :: 11
844+ ?: =(0 (mod count 5)) :: 12
845+ "Buzz" :: 13
846+ <count> :: 14
847+$(count (add 1 count)) :: 15
848+```
849+
850+If not, line 7 uses the rune `:-` to produce a cell. This cell is the FizzBuzz list, in which the head is the first list item and the tail is the rest of the list, itself another list.
851+
852+The head of this cell is produced by lines 8-14, and the tail by line 15.
853+
854+For value of the head there are two possibilities . First, the value is "FizzBuzz", or "Fizz", or "Buzz", if any of the respective conditional tests hit. For example, if `=(0 (mod count 15))` is true -- i.e., if `count` is evenly divisible by 15 -- then the value returned is "FizzBuzz". Second, if none of the three test conditions is true, then the value is the number in question, `count`. In the latter case, line 14 uses the `< >` syntax to convert `count` from an `@` to a `tape`. Remember that the cast is for a list of `tape`s, so each list item must be a `tape`.
855+
856+For the value of the cell's tail: the rest of the output list is produced by line 15. This line uses `$( )` to loop back to the `|-` in line 3, but only after modifying the value of `count`: `count` is increased in value by `1`.
857+
858+The product of the `$( )` call on line 15 is another list. Either the modified `count` equals `end`, in which case the null list, `~`, is returned on line 6; or a new cell is produced in which case the head is an item determined by lines 7-14 and the tail is determined by line 15. The process repeats until `count` equals `end`.
859+
860+## Exercise Answers
861+
862+There are many possible solutions so yours may look a bit different from the ones we have below. These solutions aren't optimized for performance. Instead, clarity and simplicity have been prioritized.
863+
864+#### Exercise 2.3.1 Solution: Subtraction
865+
866+```
867+|= [x=@ y=@]
868+^- @
869+?: =(y 0)
870+ x
871+$(x (dec x), y (dec y))
872+```
873+
874+#### Exercise 2.3.2 Solution: Factorial
875+
876+```
877+|= n=@
878+^- @
879+?: (lte n 1)
880+ 1
881+(mul n $(n (dec n)))
882+```
883+
884+#### Exercise 2.3.3 Solution: Prime
885+
886+```
887+|= a=@
888+?: (lth a 2) |
889+?: =(a 2) &
890+=/ c 2
891+|- ^- ?
892+?: =(0 (mod a c)) |
893+?: (gth (mul c 2) a) &
894+$(c +(c))
895+```
docs/tutorials/hoon-ch2/hoon-ch2-4.umdnew file+780

This diff is too big to show here.

docs/tutorials/hoon-ch2/hoon-ch2-5.umdnew file+708

This diff is too big to show here.

docs/tutorials/hoon-ch2/hoon-ch2-6.umdnew file+370

This diff is too big to show here.

docs/tutorials/hoon-ch2/hoon-ch2-7.umdnew file+394

This diff is too big to show here.

docs/tutorials/hoon-ch2/hoon-ch2-8.umdnew file+798

This diff is too big to show here.

docs/tutorials/hoon-ch2/hoon-ch2-9.umdnew file+389

This diff is too big to show here.

docs/arvo/internals.md → docs/tutorials/internals.umdrenamed+37−39

This diff is too big to show here.

docs/arvo/internals/ames.md → docs/tutorials/internals/ames.umdrenamed+9−7

This diff is too big to show here.

docs/arvo/internals/ames/commentary.md → docs/tutorials/internals/ames/commentary.umdrenamed+182−11

This diff is too big to show here.

docs/arvo/internals/behn.md → docs/tutorials/internals/behn.umdrenamed+9−7

This diff is too big to show here.

docs/arvo/internals/clay.md → docs/tutorials/internals/clay.umdrenamed+9−7

This diff is too big to show here.

docs/arvo/internals/clay/architecture.md → docs/tutorials/internals/clay/architecture.umdrenamed+12−8

This diff is too big to show here.

docs/arvo/internals/clay/commentary.md → docs/tutorials/internals/clay/commentary.umdrenamed+206−22

This diff is too big to show here.

docs/arvo/internals/dill.md → docs/tutorials/internals/dill.umdrenamed+9−7

This diff is too big to show here.

docs/arvo/internals/eyre.md → docs/tutorials/internals/eyre.umdrenamed+9−7

This diff is too big to show here.

docs/arvo/internals/eyre/commentary.md → docs/tutorials/internals/eyre/commentary.umdrenamed+13−16

This diff is too big to show here.

docs/arvo/internals/eyre/specification.md → docs/tutorials/internals/eyre/specification.umdrenamed+149−81

This diff is too big to show here.

docs/arvo/internals/ford.md → docs/tutorials/internals/ford.umdrenamed+10−10

This diff is too big to show here.

docs/arvo/internals/ford/runes.md → docs/tutorials/internals/ford/runes.umdrenamed+15−5

This diff is too big to show here.

docs/arvo/internals/gall.md → docs/tutorials/internals/gall.umdrenamed+8−9

This diff is too big to show here.

docs/tutorials/nock.umdnew file+12

This diff is too big to show here.

docs/nock/definition.md → docs/tutorials/nock/definition.umdrenamed+20−20

This diff is too big to show here.

docs/nock/example.md → docs/tutorials/nock/example.umdrenamed+8−7

This diff is too big to show here.

docs/nock/explanation.md → docs/tutorials/nock/explanation.umdrenamed+9−8

This diff is too big to show here.

docs/nock/implementations.md → docs/tutorials/nock/implementations.umdrenamed+8−7

This diff is too big to show here.

docs/nock/implementations/c.md → docs/tutorials/nock/implementations/c.umdrenamed

The content is the same.

docs/nock/implementations/clojure.md → docs/tutorials/nock/implementations/clojure.umdrenamed

The content is the same.

docs/nock/implementations/csharp.md → docs/tutorials/nock/implementations/csharp.umdrenamed

The content is the same.

docs/nock/implementations/groovy.md → docs/tutorials/nock/implementations/groovy.umdrenamed

The content is the same.

docs/nock/implementations/haskell.md → docs/tutorials/nock/implementations/haskell.umdrenamed

The content is the same.

docs/nock/implementations/hoon.md → docs/tutorials/nock/implementations/hoon.umdrenamed

The content is the same.

docs/nock/implementations/javascript.md → docs/tutorials/nock/implementations/javascript.umdrenamed

The content is the same.

docs/nock/implementations/python.md → docs/tutorials/nock/implementations/python.umdrenamed

The content is the same.

docs/nock/implementations/ruby.md → docs/tutorials/nock/implementations/ruby.umdrenamed

The content is the same.

docs/nock/implementations/scala.md → docs/tutorials/nock/implementations/scala.umdrenamed

The content is the same.

docs/nock/implementations/scheme.md → docs/tutorials/nock/implementations/scheme.umdrenamed

The content is the same.

docs/nock/implementations/swift.md → docs/tutorials/nock/implementations/swift.umdrenamed

The content is the same.

docs/urbyte.mddeleted−12

This diff is too big to show here.

docs/urbyte/0.mddeleted−284

This diff is too big to show here.

docs/urbyte/1.mddeleted−365

This diff is too big to show here.

docs/urbyte/2.mddeleted−504

This diff is too big to show here.

docs/using.md → docs/using.umdrenamed+7−7

This diff is too big to show here.

docs/using/admin.md → docs/using/admin.umdrenamed+16−14

This diff is too big to show here.

docs/using/filesystem.md → docs/using/filesystem.umdrenamed+80−63

This diff is too big to show here.

docs/using/install.md → docs/using/install.umdrenamed+53−57

This diff is too big to show here.

docs/using/layout.md → docs/using/layout.umdrenamed+10−11

This diff is too big to show here.

docs/using/messaging.md → docs/using/messaging.umdrenamed+194−113

This diff is too big to show here.

docs/using/setup.md → docs/using/setup.umdrenamed+11−13

This diff is too big to show here.

docs/using/shell.md → docs/using/shell.umdrenamed+153−88

This diff is too big to show here.

docs/using/web.md → docs/using/web.umdrenamed+74−60

This diff is too big to show here.

docs/using/web/blog.mddeleted−95

This diff is too big to show here.

docs/using/web/blog.umdnew file+99

This diff is too big to show here.

docs/using/web/comments.md → docs/using/web/comments.umdrenamed+25−19

This diff is too big to show here.

docs/using/web/static.mddeleted−127

This diff is too big to show here.

docs/using/web/static.umdnew file+137

This diff is too big to show here.

docs/vere.md → docs/vere.umdrenamed+9−9

This diff is too big to show here.

docs/vere/api.mddeleted−989

This diff is too big to show here.

docs/vere/c.mddeleted−111

This diff is too big to show here.

docs/vere/jetting.mddeleted−760

This diff is too big to show here.

docs/vere/nouns.mddeleted−458

This diff is too big to show here.

docs/vere/runtime.mddeleted−46

This diff is too big to show here.