on master help sign in
Check Core Hoon into docs.
f35d42eC. Guy Yarvin
docs/system/hoon/core.mdnew file+24
@@ -0,0 +1,24 @@
1+---
2+sort: 1
3+---
4+
5+# Core Hoon
6+
7+Hoon is strict, typed functional programming without math.
8+
9+Hoon is named after a Wallace Stevens poem. Coincidentally, it
10+means "hooligan" in Australian. Practically, "Hoon" is a short
11+punchy name which search engines handle well.
12+
13+This manual defines a practical Hoon subset we call Core Hoon.
14+(Some of the internal structures we present are simplified to
15+reflect the Core subset.)
16+
17+To read it for the first time, read these links in order:
18+
19+<list>
20+</list>
21+
22+Once you've been through all this material, you can try some
23+[exercises]() if you feel you're ready, or read [Deep Hoon]() for
24+a more narrative introduction.
docs/system/hoon/core/demo.mdnew file+56
@@ -0,0 +1,56 @@
1+---
2+sort: 1
3+---
4+
5+# Demo
6+
7+Here's everyone's favorite whiteboard example, FizzBuzz. Each
8+line is commented with its number:
9+
10+```
11+:gate end/atom :: 1
12+:var count 1 :: 2
13+:loop :: 3
14+:if =(end count) :: 4
15+ ~ :: 5
16+:cons :: 6
17+ :if =(0 (mod count 15)) :: 7
18+ "FizzBuzz" :: 8
19+ :if =(0 (mod count 5)) :: 9
20+ "Fizz" :: 10
21+ :if =(0 (mod count 3)) :: 11
22+ "Buzz" :: 12
23+ (text :wrap(count)) :: 13
24+:moar(count (add 1 count)) :: 14
25+```
26+
27+Can you understand this code by just looking at it? Hopefully,
28+but let's explain it anyway.
29+
30+Hoon is a functional language. FizzBuzz is usually defined as a
31+side effect, but Hoon has no side effects. This code will
32+*make* a list of strings, not *print* a list of strings.
33+
34+Line 1 defines a function of one argument, `end`, an unsigned
35+integer.
36+
37+Line 2 declares a variable, `count`, with initial value `1`.
38+
39+Line 3 begins a loop.
40+
41+Line 4 checks if `count` equals `end`. If so, line 5 (and the
42+whole loop) produces the value `~`, null. If not, line 6 begins
43+an ordered pair.
44+
45+The head of the pair is "FizzBuzz", or "Fizz", or "Buzz", if the
46+respective tests hit. If not, line 13 wraps a runtime type
47+around `count`, then prints the type-value pair to a string (like
48+C `sprintf()`). This string is the first item in the output list.
49+
50+The tail of the pair is line 14, which repeats the loop (like
51+Clojure `recur`), with `count` incremented. This list of strings
52+is the rest of the output list.
53+
54+You can test this code by typing it into `home/gen/fizzbuzz.hoon`
55+in your Urbit mount directory, then typing `+fizzbuzz 100` in the
56+Urbit dojo (shell).
docs/system/hoon/core/examples.mdnew file+453
@@ -0,0 +1,453 @@
1+---
2+sort: 9
3+---
4+
5+# Examples
6+
7+Now we know enough to write two quick examples: the Sieve of
8+Eratosthenes (a naive prime sieve) and a tictactoe engine.
9+
10+(Note that these are not examples of perfect Hoon code; they are
11+meant for teaching. They err, more than usual for Hoon, on the
12+side of simple manual construction over high-octane FP.)
13+
14+## `sieve`: code in basic style
15+
16+A function that produces the list of primes less than or equal to
17+than its argument, an atom:
18+```
19+:gate thru/atom :: 1
20+:cast (list atom) :: 2
21+:var field/(set atom) (silt (gulf 2 thru)) :: 3
22+:rap abet:main :: 4
23+:core :: 5
24+++ abet :: 6
25+ (sort (~(tap in field) ~) lth) :: 7
26+:: :: 8
27+++ main :: 9
28+ :var factor/atom 2 :: 10
29+ :loop :like ..main :: 11
30+ :if (gth (mul factor factor) thru) :: 12
31+ ..main :: 13
32+ :moar(factor +(factor), ..main (reap factor)) :: 14
33+:: :: 15
34+++ reap :: 16
35+ :gate factor/atom :: 17
36+ :var count/atom (mul 2 factor) :: 18
37+ :loop :like ..reap :: 19
38+ :if (gth count thru) :: 20
39+ ..reap :: 21
40+ :moar :: 22
41+ count (add count factor) :: 23
42+ field (~(del in field) count) :: 24
43+ == :: 25
44+-- :: 26
45+```
46+
47+## `sieve`: explanation
48+
49+Line `1`: we are building a gate (function) whose sample
50+(argument) is `thru`, an atom.
51+
52+Line `2`: the product of this gate is a list of atoms.
53+
54+Line `3`: we introduce a variable `field`, whose type is a set of
55+atoms. The `silt` function converts a list to a set. The `gulf`
56+function creates the range `2` through `thru` inclusive, as a
57+list of atoms.
58+
59+Line `4`: below, we introduce a core which does our work. With
60+reverse flow, we compute `main` on this core, then `abet` on the
61+product of `main`. (`abet:main` means `:rap(abet main)`.)
62+
63+The core is a state machine; `main` produces the core itself,
64+with the computation completed. `abet` then extracts the result.
65+
66+Line `5`: we wrap a core around our existing subject. The
67+`field` and `thru` atoms are within the payload and of course
68+remain accessible.
69+
70+Lines `6` and `7`: the `abet` arm, which produces the field as a
71+sorted list. `in` is the set core; `tap` is an arm which
72+produces a gate that exports the set as a list, prepending it to
73+a tail which is nil in this case (and most cases). We sort this
74+list in ascending order with `lth` (less-than).
75+
76+Line `9`: the `main` arm, which performs the main calculation.
77+
78+Line `10`: we declare a counter, `factor`, which will iterate
79+up through the factors we're removing.
80+
81+Line `11`: we start a loop. The product of the loop is cast to
82+`..main`, which is the core we're in (`+1.main`).
83+
84+Lines `12` and `13`: we terminate the loop, returning `..main`,
85+if the square of the counter exceeds the range.
86+
87+Line `14`: repeats the loop, incrementing the counter, and
88+replacing the core with a version sieved by `reap`.
89+
90+Lines `16` and `17`: the `reap` arm, which produces a gate that
91+removes multiples of a factor from the field (set of possible
92+primes). The sample of this gate is the factor to remove.
93+
94+Line `18`: we declare a variable `count`, an atom, with the
95+initial value `(mul 2 factor)`.
96+
97+Line `19`: we enter a loop. This loop produces the core itself.
98+
99+Lines `20` and `21`: we are done if the counter is out of range.
100+
101+Lines `22` to `25`: repeat the loop, stepping `count` to the next
102+multiple of `factor`, and deleting it from `field`.
103+
104+## `sieve`: code in kernel style
105+
106+Finally, the same code transliterated into runes (and in a more
107+concise "kernel" style).
108+
109+```
110+|= top/@
111+^- (list @)
112+=+ fed=(silt (gulf 2 top))
113+=< abet:main
114+|%
115+++ abet (sort (~(tap in fed)) lth)
116+++ main
117+ =+ fac=2
118+ |- ^+ ..main
119+ ?: (gth (mul fac fac) top)
120+ ..main
121+ $(fac +(fac), ..main (reap fac))
122+::
123+++ reap
124+ |= fac/atom
125+ =+ cot=(mul 2 fac)
126+ |- ^+ ..reap
127+ ?: (gth cot top)
128+ ..reap
129+ $(cot (add cot fac), fed (~(del in fed) cot))
130+--
131+```
132+
133+### `toe`: tictactoe engine
134+
135+The `toe` tictactoe engine applies a list of events to a game
136+state, producing a list of game actions. Events are tictactoe
137+moves (`move)`; actions are tictactoe results (`fact`).
138+
139+```
140+:rap :gate feed/(list move) :: 1
141+ :new game/game :: 2
142+ :loop :cast (list fact) :: 3
143+ :ifno feed ~ :: 4
144+ :sip this/(unit fact) :: 5
145+ game :: 6
146+ (~(do go game) i.feed) :: 7
147+ :var rest/(list fact) :moar(feed t.feed) :: 8
148+ :ifno(this rest [u.this rest]) :: 9
149+:: :: 10
150+:per :core :: 11
151+ ++ side atom :: 12
152+ ++ spot {x/atom y/atom} :: 13
153+ ++ fact :book {$tie $~} :: 14
154+ {$win p/cord} :: 15
155+ == :: 16
156+ ++ move :book {$x p/spot} :: 17
157+ {$o p/spot} :: 18
158+ {$z $~} :: 19
159+ == :: 20
160+ ++ game :bank w/? :: 21
161+ a/side :: 22
162+ z/side :: 23
163+ == :: 24
164+ -- :: 25
165+:core :: 26
166+++ bo :: 27
167+ :door half/side :: 28
168+ ++ bit :gate(a/atom =(1 (cut 0 [a 1] half))) :: 29
169+ ++ off :gate(a/spot (add x.a (mul 3 y.a))) :: 30
170+ ++ get :gate(a/spot (bit (off a))) :: 31
171+ ++ set :gate(a/spot (con half (bex (off a)))) :: 32
172+ ++ win :calt lien :: 33
173+ (rip 4 0wl04h0.4A0Aw.4A00s.0e070) :: 34
174+ :gate(a/atom =(a (dis a half))) :: 35
175+ -- :: 36
176+++ go :: 37
177+ :door game/game :: 38
178+ ++ do :: 39
179+ :gate act/move :: 40
180+ :cast {(unit fact) ^game} :: 41
181+ :case act :: 42
182+ {$x *} :sure(w.game ~(mo on p.act)) :: 43
183+ {$o *} :deny(w.game ~(mo on p.act)) :: 44
184+ {$z *} [~ nu] :: 45
185+ == :: 46
186+ :: :: 47
187+ ++ nu :like(game [& 0 0]) :: 48
188+ ++ on :: 49
189+ :door here/spot :: 50
190+ ++ is :or (~(get bo a.game) here) :: 51
191+ (~(get bo z.game) here) :: 52
192+ == :: 53
193+ ++ mo :cast {(unit fact) ^game} :: 54
194+ :deny is :: 55
195+ :var next/side (~(set bo a.game) here) :: 56
196+ :if ~(win bo next) :: 57
197+ [[~ %win ?:(w.game %x %o)] nu] :: 58
198+ [~ game(w !w.game, a z.game, z next)] :: 59
199+ -- :: 60
200+ -- :: 62
201+-- :: 63
202+```
203+
204+### `toe`: explanation
205+
206+Line `1` wraps a conclusion around a stack of cores. The cores
207+at `11` and `26` are the data structures and functions of the
208+engine; the conclusion is the interface and top-level logic. It
209+produces a gate whose sample is `feed`, a list of `move`.
210+
211+Line `2` declares a blank new variable named `game`, whose type
212+is the `game` mold (tictactoe game state) defined on line `21`.
213+Under line `2`, `game` pulls the variable and `^game` the mold.
214+
215+Line `3` enters a loop producing a list of game events, `fact`.
216+
217+Line `4` produces nil, `~`, if `feed` is empty.
218+
219+Lines `5` through `7` apply the move. We open a `go` core on the
220+current game state, produce a `do` gate, and call that gate on
221+the move. The product of the `do` gate is a pair; the head is
222+`(unit fact)`, either `~` or `[~ fact]`; the tail is a new
223+`game`. The `:sip` twig declares the head as a new variable,
224+`this`; it modifies the subject by setting `game` to the tail.
225+
226+Line `8` declares a new variable, `rest`, which is all the facts
227+generated by the moves in `t.feed`, the tail of the move list.
228+(Yes, this is gratuitous head recursion.) Line `9` produces
229+`rest` if the `i.feed` move produced no fact; otherwise it
230+prepends the new fact to `rest`.
231+
232+Line `11` wraps a library core around a data structure core, a
233+common pattern. (You could put the molds and the gates in the
234+same core, but the compiler couldn't constant-fold gate samples
235+that use these molds, an efficiency cost.)
236+
237+Line `12` defines the `side` mold, an alias for `atom` (`@`).
238+A side is a half of the board, as a marked/unmarked bitfield.
239+
240+Line `13` defines the `spot` mold, a 2D coordinate.
241+
242+Lines `14` to `16` define the `fact` mold, a game event (ie,
243+output action), as a book (tagged union). There are two forms of
244+`fact`: `[%tie ~]` (reporting a tie), and `[%win cord]`
245+(reporting that `'X'` or `'O'` won a game.
246+
247+Lines `17` to `20` define the `move` mold, a game move. This is
248+either `[%x spot]`, `[%o spot]`, or `[%z ~]` to reset the board.
249+
250+Lines `21` to `23` define the `game` mold, the game state. This
251+is an `a` side, the next side to move; a `z` side, the other
252+side; and `w`, which is `&` (yes) if `a` is X and `b` is O; `|`
253+otherwise. (Obviously, we swap `a` and `z` on every move.)
254+
255+Line `26` introduces the library core, which contains the doors
256+`bo` (for `side` bitfields) and `go` (for game state).
257+
258+Lines `27` to `28` begin the `bo` core, a door around `half`, a
259+board side.
260+
261+Line `29` is the `bit` gate, which tests a bit in `half`.
262+
263+Line `30` is the `off` gate, which maps from a `spot` (coordinate)
264+to a bit index.
265+
266+Line `31` is the `get` gate, which produces the bit at a `spot`.
267+
268+Line `32` is the `set` gate, which produces a new side with the
269+bit at a `spot` set. It works by ORing (`con`) `half` with the
270+binary exponent (`bex`) of the offset (`off`) of the spot.
271+
272+Lines `33` to `35` are a victory test. It calls the
273+standard `lien` function, which iterates a boolean gate over a
274+list and produces `&` (yes) if any item tests as true, against a
275+list of magic bitfields (expanded from a base64 constant), each
276+of which must equal itself when ANDed (`dis`) with `half`.
277+
278+Lines `37` to `38` begin the `go` core, a door around a `game`.
279+Again we name the sample `game`. (This is a legitimate style,
280+but not used much.)
281+
282+Lines `40` to `42` begin the `do` gate, whose sample is `act`, a
283+move. The product is cast to a pair of `(unit fact)` and a new
284+game state, written `^game` to skip to the second binding.
285+
286+Lines `42` through `46` switch on the form of `act`. If it's an
287+`%x` or `%o` move, we assert that it's the right turn, then use
288+the `mo` door to apply the move. If it's a `%z` move, we clear
289+the board.
290+
291+Line `48` is the `nu` arm, which produces a blank game state.
292+
293+Lines `49` to `50` begin the `on` door, a door around `here`, a
294+`spot`. Just as we have multiple computed attributes against the
295+game state, we have multiple computed attributes (`is` and `mo`)
296+against the combination of game state and coordinate.
297+
298+Lines `51` to `53` define the `is` arm, which is `&` (yes) iff
299+either `a` or `z` has played `here`.
300+
301+Line `54` begins the `mo` arm, which produces (with a
302+nonessential cast) a pair of `(unit fact)` and game state.
303+Again we see `^game` to pull the mold, since `game` is the
304+current game state in the `go` core.
305+
306+Line `55` asserts that no one has yet played `here`.
307+
308+Line `56` declares a variable `next`, as game side `a` with
309+`here` played in it.
310+
311+Lines `57` and `58` test if `a` has won with this move. If so,
312+we produce the win fact and a blank game state.
313+
314+Line `59` produces no fact (since nothing has happened), but
315+inverts the `w` turn indicator, replaces side `a` with the other
316+side `z`, and replaces `z` with `next`.
317+
318+### `toe`: code, kernel style
319+
320+```
321+=< |= fed/(list move)
322+ =| mag/game
323+ |- ^- (list fact)
324+ ?~ fed ~
325+ =^ did/(unit fact) mag (~(do go mag) i.fed)
326+ =+ res=$(fed t.fed)
327+ ?~(did res [u.did res])
328+=> |%
329+ ++ side @
330+ ++ spot {x/@ y/@}
331+ ++ fact $% {$tie $~}
332+ {$win p/cord}
333+ ==
334+ ++ move $% {$x p/spot}
335+ {$o p/spot}
336+ {$z $~}
337+ ==
338+ ++ game $: w/?
339+ a/side
340+ z/side
341+ ==
342+ --
343+|%
344+++ bo
345+ |_ haf/side
346+ ++ bit |=(a/atom =(1 (cut 0 [a 1] haf)))
347+ ++ get |=(a/spot (bit (off a)))
348+ ++ off |=(a/spot (add x.a (mul 3 y.a)))
349+ ++ set |=(a/spot (con haf (bex (off a))))
350+ ++ win %+ lien
351+ (rip 4 0wl04h0.4A0Aw.4A00s.0e070)
352+ |=(a/atom =(a (dis a haf)))
353+ --
354+++ go
355+ |_ mag/game
356+ ++ do
357+ |= act/move
358+ ^- {(unit fact) game}
359+ ?- act
360+ {$x *} ?>(w.mag ~(mo on p.act))
361+ {$o *} ?<(w.mag ~(mo on p.act))
362+ {$z *} [~ nu]
363+ ==
364+ ::
365+ ++ nu `game`[& 0 0]
366+ ++ on
367+ =| her/spot
368+ |%
369+ ++ is ?| (~(get bo a.mag) her)
370+ (~(get bo z.mag) her)
371+ ==
372+ ++ mo ^- {(unit fact) game}
373+ ?< is
374+ =+ next=(~(set bo a.mag) her)
375+ ?: ~(win bo next)
376+ [[~ %win ?:(w.mag %x %o)] nu]
377+ [~ mag(w !w.mag, a z.mag, z next)]
378+ --
379+ --
380+--
381+```
382+
383+## Basic molds
384+```
385+++ atom @ :: just an atom
386+++ axis @ :: tree address
387+++ bean ? :: 0=&=yes, 1=|=no
388+++ bloq @ :: blockclass
389+++ char @tD :: UTF-8 byte
390+++ cord @t :: text atom (UTF-8)
391+++ gate $-(* *) :: general gate
392+++ knot @ta :: ASCII text
393+++ noun * :: any noun
394+++ null $~ :: null, nil, etc
395+++ time @da :: galactic time
396+++ path (list knot) :: eg, fs location
397+++ tang (list tank) :: error trace
398+++ tank ::
399+ $% {$leaf p/tape} :: printing formats
400+ $: $palm :: backstep list
401+ p/{p/tape q/tape r/tape s/tape} ::
402+ q/(list tank) ::
403+ == ::
404+ $: $rose :: flat list
405+ p/{p/tape q/tape r/tape} :: mid open close
406+ q/(list tank) ::
407+ == ::
408+ == ::
409+++ tanq :: future tank
410+ $? {$~ p/(list tanq)} :: list of printables
411+ {$~ $~ p/tape} :: simple string
412+ (pair @tas tanq) :: captioned
413+ == ::
414+++ tape (list char) :: string as list
415+++ term @tas :: ascii symbol
416+++ wall (list tape) :: text lines (no \n)
417+++ wain (list cord) :: text lines (no \n)
418+
419+::::
420+::::
421+
422+++ tree |* a/gate :: binary tree
423+ $@($~ {n/a l/(tree a) r/(tree a)}) ::
424+++ trap |*(a/_* _|?(*a)) :: makes perfect sense
425+++ trel |* {a/gate b/gate c/gate} :: just a triple
426+ {p/a q/b r/c} ::
427+++ each |* {a/gate b/gate} :: either a or b
428+ $%({$& p/a} {$| p/b}) :: a default
429+
430+++ qual |* {a/gate b/gate c/gate d/gate} :: just a quadruple
431+ {p/a q/b r/c s/d} ::
432+++ pair |*({a/gate b/gate} {p/a q/b}) :: just a pair
433+++ quid |*({a/gate b/*} {a _b}) :: for =^
434+++ quip |*({a/gate b/*} {(list a) _b}) :: for =^
435+++ unit |* a/gate :: maybe
436+ $@($~ {$~ u/a}) ::
437+++ list |* a/gate :: null-term list
438+ $@($~ {i/a t/(list a)}) ::
439+++ lone |*(a/gate p/a) :: just one thing
440+
441+::::
442+::::
443+++ map |* {a/gate b/gate} :: associative tree
444+ $@($~ {n/{p/a q/b} l/(map a b) r/(map a b)}) ::
445+++ qeu |* a/gate :: queue
446+ $@($~ {n/a l/(qeu a) r/(qeu a)}) ::
447+++ set |* a/gate :: set
448+ $@($~ {n/a l/(set a) r/(set a)}) ::
449+++ jar |*({a/gate b/gate} (map a (list b))) :: map of lists
450+++ jug |*({a/gate b/gate} (map a (set b))) :: map of sets
451+```
452+
453+### Basic libraries
docs/system/hoon/core/jargon.mdnew file+83
@@ -0,0 +1,83 @@
1+---
2+sort: 3
3+---
4+
5+# Terminology
6+
7+Usually, a new language is an improvement on one you already
8+know. If it isn't, it probably at least shares concepts with a
9+large family of relatives. These concepts come with words, like
10+*type* or *function*, that map cleanly onto its semantics.
11+
12+In Hoon we throw away almost all these words and invent new
13+ones, which mean almost the same things. But wait, wat?
14+
15+## Motivation
16+
17+Hoon has no close relatives, and the normal jargon of programming
18+maps poorly onto its semantics. For example, although Hoon is a
19+typed language, the term *type* is not formally defined in Hoon.
20+It's a great word, but Hoon has three quite separate concepts
21+which could comfortably claim it. We say *type* all the time;
22+we mean `span`, or `mold`, or `mark`, or possibly all three.
23+Sometimes this is ok and sometimes it isn't.
24+
25+Other common programming concepts used only informally in Hoon
26+are "function," "object," "event," "expression," "variable,"
27+"label," "closure", "environment," "stack," and probably a few
28+more. We can get away with any of these conventional words --
29+and we do. But when we do, we're making an analogy that relies
30+on context for precision.
31+
32+## Notation
33+
34+Any `word` in code font is a `limb` (label) in the Hoon kernel.
35+Any jargon that isn't a limb is in *italics*.
36+
37+## Enumeration
38+
39+Top-level Hoon concepts: `noun` (data), `nock` (interpreter),
40+`mint` (compiler), `span` (type), `twig` (expression).
41+
42+## Execution
43+
44+### `noun` (data)
45+
46+A value in Hoon is called a [`noun`](noun). A noun is either a
47+unsigned integer of any size (`atom`), or an ordered pair of any
48+two nouns (`cell`). Nouns are like Lisp S-expressions, but
49+simpler (Lisp atoms effectively have dynamic type bits).
50+
51+### `nock` (interpreter)
52+
53+Hoon compiles itself to the [Nock](nock) VM, a "functional assembly
54+language" whose spec fits on a T-shirt. You don't need to know
55+Nock to use Urbit, but it helps. Nock is an interpreter function
56+that maps a pair `{data nock}` to a *product* noun, where `data`
57+is the *subject* (input) and `nock` is the *formula* (program).
58+
59+## Compilation
60+
61+### `mint` (compiler)
62+
63+[`mint`](mint) is the Hoon compiler. It maps a cell `{span twig}` to a
64+cell `{span nock}`, where a `span` is a type, a `twig` is a compiled
65+expression (AST), and a `nock` is a Nock formula. `mint` accepts
66+a subject type and a source expression; it produces a product type
67+and an executable formula.
68+
69+### `span` (type, as range)
70+
71+A [`span`](span) is a Hoon type. It defines a set (finite or
72+infinite) of nouns and ascribes some semantics to it. There is
73+no syntax for spans; they are always defined by inference (ie, by
74+`mint`), usually using a constructor (`mold`).
75+### `twig` (expression)
76+
77+A [`twig`](twig) is a Hoon AST node, the result of parsing a
78+source expression. In general, a twig is a tagged union of the
79+form `{stem bulb}`, where `stem` is a symbolic atom which
80+controls the type of `bulb`. The regular form is a Hoon keyword
81+`:stem` and a *rune*, or digraph keyword, made of two ASCII
82+punctuation marks. The rune prefix character defines a twig
83+category, like `:`
docs/system/hoon/core/mint.mdnew file+25
@@ -0,0 +1,25 @@
1+---
2+sort: 6
3+---
4+
5+# Compiler: `mint`
6+
7+`mint` is the Hoon compiler. It maps a cell `{subject/span
8+source/twig}` to a cell `{product/span formula/nock}`, where
9+`span` is a type, `twig` is a compiled expression, and `nock` is
10+a Nock formula.
11+
12+Calculating the output type from the input type and the source
13+code is called "type inference." If you've used another typed
14+functional language, like Haskell, Hoon's type inference does the
15+same job but with less intelligence.
16+
17+Haskell infers backward and forward; Hoon only infers forward.
18+Hoon can't figure out the type of a noun from how you use it,
19+only from how you make it. Hoon can infer tail recursion, but
20+not head recursion.
21+
22+Low-powered type inference means you need more type annotations,
23+which makes your program more readable anyway. (Also, the dumber
24+the compiler, the easier it is for a dumb human to understand
25+what the compiler is thinking.)
docs/system/hoon/core/nock.mdnew file+160
@@ -0,0 +1,160 @@
1+---
2+sort: 5
3+---
4+
5+# Interpreter: `nock`
6+
7+The Nock VM is a Turing-complete function that maps a cell
8+`{subject formula}` to a noun `product`, where `subject` is the
9+data, `formula` is the code, and `product` is the result.
10+
11+To program in Hoon, this is all you need to know about Nock.
12+It's probably at least worth skimming this definition, though.
13+
14+(Also, the Hoon programmer should know that (a) tail call
15+elimination in Nock is straightforward; and (b) tail calls in
16+Hoon always become tail calls in Nock.)
17+
18+## Rules
19+
20+Nock is a combinator interpreter defined by the spec below.
21+
22+This pseudocode (any system of axioms is properly defined in
23+pseudocode) is a system of problem reduction rules. Variables
24+match any noun; the first rule from the top matches.
25+
26+A problem that reduces to itself is an infinite loop, hence a
27+crash ("bottom" in formal logic). Obviously a real interpreter
28+can detect this crash and produce an out-of-band value instead.
29+
30+```
31+?[a b] 0
32+?a 1
33++[a b] +[a b]
34++a 1 + a
35+=[a a] 0
36+=[a b] 1
37+=a =a
38+
39+/[1 a] a
40+/[2 a b] a
41+/[3 a b] b
42+/[(a + a) b] /[2 /[a b]]
43+/[(a + a + 1) b] /[3 /[a b]]
44+/a /a
45+
46+*[a [b c] d] [*[a b c] *[a d]]
47+
48+*[a 0 b] /[b a]
49+*[a 1 b] b
50+*[a 2 b c] *[*[a b] *[a c]]
51+*[a 3 b] ?*[a b]
52+*[a 4 b] +*[a b]
53+*[a 5 b] =*[a b]
54+
55+*[a 6 b c d] *[a 2 [0 1] 2 [1 c d] [1 0]
56+ 2 [1 2 3] [1 0] 4 4 b]
57+*[a 7 b c] *[a 2 b 1 c]
58+*[a 8 b c] *[a 7 [[7 [0 1] b] 0 1] c]
59+*[a 9 b c] *[a 7 c 2 [0 1] 0 b]
60+*[a 10 [b c] d] *[a 8 c 7 [0 3] d]
61+*[a 10 b c] *[a c]
62+
63+*a *a
64+```
65+
66+## Operators
67+
68+The pseudocode notation defines five prefix operators: `?`, `+`,
69+`=`, `/`, and `*`.
70+
71+`?[x]` produces `0` if `x` is a cell, `1` if an atom.
72+
73+`+[x]` produces the atom `x` plus `1`.
74+
75+`=[x y]` produces `0` if `x` and `y` are the same noun, `1`
76+otherwise.
77+
78+`/` is a tree addressing operator. The root of the tree is `1`;
79+the left child of any node `n` is `2n`; the right child is
80+`2n+1`. `/[x y]` is the subtree of `y` at address `x`.
81+
82+(For instance, `/[1 [531 25 99]]` is `[531 25 99]`; `/[2 [531 25
83+99]]` is `531`; `/[3 [531 25 99]]` is `[25 99]`; `/[6 [531 25
84+99]]` is `25`; `/[12 [531 25 99]]` crashes.)
85+
86+`*[x y]` is the Nock interpreter function. `x` is the subject,
87+`y` is the formula.
88+
89+An invalid use of any operator (eg, incrementing a cell) crashes.
90+This is specified as an infinite loop, but it's not actually an
91+infinite loop.
92+
93+## Instructions
94+
95+A valid formula is always a cell. If the head of the formula is a
96+cell, Nock treats both head and tail as formulas, resolves each
97+against the subject, and produces the cell of their products. In
98+other words, the Lisp program `(cons x y)` becomes the Nock
99+formula `[x y]`.
100+
101+If the head of the formula is an atom, it's an instruction from
102+`0` to `10`.
103+
104+A formula `[0 b]` produces the noun at tree address `b`
105+in the subject.
106+
107+A formula `[1 b]` produces the constant noun `b`.
108+
109+A formula `[2 b c]` treats `b` and `c` is formulas, resolves each
110+against the subject, then computes Nock again with the product of
111+`b` as the subject, `c` as the formula.
112+
113+In formulas `[3 b]`, `[4 b]`, and `[5 b]`, `b` is another
114+formula, whose product against the subject becomes the input to
115+an axiomatic operator. `3` is `?`, `4` is `+`, `5` is `=`.
116+
117+Instructions `6` through `10` are macros; deleting them
118+from Nock would decrease compactness, but not expressiveness.
119+
120+`[6 b c d]` is *if* `b`, *then* `c`, *else* `d`. Each of `b`,
121+`c`, `d` is a formula against the subject. Remember that `0` is
122+true and `1` is false.
123+
124+`[7 b c]` composes the formulas `b` and `c`.
125+
126+`[8 b c]` produces the product of formula `c`, against
127+a subject whose head is the product of formula `b` with the
128+original subject, and whose tail is the original subject. (Think
129+of `8` as a ``variable declaration'' or ``stack push.'')
130+
131+`[9 b c]` computes the product of formula `c` with the
132+current subject; from that product `d` it extracts a formula
133+`e` at tree address `b`, then computes `*[d e]`.
134+(Think, very roughly, of `d` as an object and `e` as a
135+method.)
136+
137+`[10 b c]` is a *hint* semantically equivalent to the formula
138+`c`. If `b` is an atom, it's a *static hint*, which is just
139+discarded. If `b` is a cell, it's a *dynamic* hint; the head of
140+`b` is discarded, and the tail of `b` is executed as a formula
141+against the current subject; the product of this is discarded.
142+
143+A practical interpreter can do anything with discarded data, so
144+long as the result it computes complies with the semantics of
145+Nock. For example, the simplest use of hints is the ordinary
146+"debug printf." It is erroneous for an interpreter to skip
147+computing dynamic hints; they might crash.
148+
149+## Implementation
150+
151+The reader might wonder how an interpreter whose only arithmetic
152+operation is increment can ever be practical.
153+
154+The short answer is that a Nock interpreter doesn't have to use
155+the algorithm above; it just has to get the same result as the
156+algorithm above.
157+
158+The algorithm for decrementing an atom is to count up to it, an
159+O(n) operation. But if we know we are running a decrement
160+formula,
docs/system/hoon/core/noun.mdnew file+33
@@ -0,0 +1,33 @@
1+---
2+sort: 4
3+---
4+
5+# Data model: `noun`
6+
7+A value in Hoon is called a `noun`. A noun is either a unsigned
8+integer of any size (`atom`), or an ordered pair of any two
9+nouns (`cell`). In other words, a noun is a binary tree whose
10+leaves are unsigned integers.
11+
12+Nouns are a Nock concept; there is no Nock syntax; so there is no
13+general noun syntax. But nouns are usually written with square
14+brackets associating right; `[a b c]` means `[a [b c]]`. In Hoon
15+we also see `{a b c}`, a constructor (`mold`) for `[a b c]`.
16+
17+Nouns are almost like Lisp's S-expressions, but S-expressions
18+have dynamic type tags in atoms. Nouns can lose this feature
19+because they're designed to sit under a static type system. For
20+the same reason, nouns tend to be tuple-centric where Lisp is
21+list-centric. Lisp `(a b c)` as a noun is `[a b c 0]`; Nock `[a
22+b c]` is Lisp `(a . b . c)`.
23+
24+Nouns are immutable and acyclic. A naive implementation uses
25+reference counting and needs no tracing GC. There is no test for
26+pointer equality as in Lisp. But indirect nouns have a lazily
27+computed short hash, so nonduplicates have O(1) comparison cost.
28+
29+All kinds of atomic values can be and are stored as atoms:
30+unsigned integers, signed integers (with sign bit low), dates,
31+floats, UTF-8 strings (LSB first), even whole files. Again,
32+a static type system is essential; an atom is not usable or even
33+printable if we don't know what it means.
docs/system/hoon/core/philosophy.mdnew file+41
@@ -0,0 +1,41 @@
1+---
2+sort: 2
3+---
4+
5+# Philosophy
6+
7+Hoon is a strict, typed functional language which compiles itself
8+to the Nock VM (whose spec fits on a T-shirt).
9+
10+Hoon's design goal is to support higher-order typed functional
11+programming without category theory, formal logic, or other
12+interesting math. The reasoning: (a) a programming language is a
13+user interface for programmers; (b) most programmers are not very
14+good at math. Hoon is not quite as expressive as Haskell, though
15+fairly close.
16+
17+Good Hoon style varies from good Haskell style. Hoon encourages
18+coders to use higher-order programming as little as possible --
19+again, simply for UI reasons. For example, multiple arguments
20+are curried by default in Haskell and tupled by default in Hoon.
21+The house style has been described as "procedural programming in
22+a functional language." The power of Haskell, or close, is there
23+when we really need it. But we try not to swat flies with it.
24+
25+Hoon is objectively simple: its complexity is bounded by the size
26+of the compiler, about 3000 lines of Hoon. This is split about
27+halfway half between frontend (parsing and macro expansion) and
28+backend (code generation and type inference).
29+
30+This parser-heavy ratio reflects the belief that our brains are
31+better than everyone thinks at learning languages (symbols and/or
32+grammars), and worse at learning abstractions (proofs and/or
33+algorithms). At first glance, Hoon may look gnarly (though its
34+squiggles are more structured than most ASCII-heavy languages).
35+But there's surprisingly little under the hood.
36+
37+Keeping the Hoon-to-Nock mapping straightforward is a priority.
38+Very roughly, Hoon is to Haskell as C is to Pascal. Pascal tries
39+to conceal its implementation beneath a layer of abstract
40+concepts; C, an "advanced macro assembler," tries to provide a
41+similar user experience with few abstract ideas as possible.
docs/system/hoon/core/span.mdnew file+118
@@ -0,0 +1,118 @@
1+---
2+sort: 7
3+---
4+
5+# Type: `span`
6+
7+A `span` is a type as most languages define it: a set of values
8+and a semantic interpretation of these values.
9+
10+## `mold`: type (as constructor)
11+
12+Why isn't `span` called "type"? Because Hoon also has a `mold`,
13+a completely different concept that could also be called a "type."
14+Hoon has no syntax for declaring spans. Spans are always created
15+by `mint`, using type inference.
16+
17+But we do want to define data structures with regular shapes. A
18+*mold* is an idempotent function (`gate`), accepting any noun.
19+The span of our structure is the result set of this function.
20+
21+In theory, either molds or spans could be called "types." In
22+practice, they're both called "types." The T-word has to stay
23+informal: it can't be banned, and it's already confusing enough.
24+
25+## `span`: definition
26+
27+This twig defines a mold named `span`, whose icon is the set of
28+all spans. Don't worry about the syntax yet:
29+
30+```
31+++ span
32+ $@ $? $noun
33+ $void
34+ == $% {$atom p/term q/(unit atom)}
35+ {$cell p/span q/span}
36+ {$core p/span q/(map term span)}
37+ {$face p/term q/span}
38+ {$fork p/(set span)}
39+ {$hold p/span q/twig}
40+ ==
41+```
42+
43+## `$noun` and `$void`
44+
45+`$noun` is the set of all nouns. `$void` is the set of
46+no nouns.
47+
48+## `{$cell p/span q/span}`
49+
50+`{$cell p/span q/span}` is the set of all cells with head `p` and
51+tail `q`.
52+
53+## `{$fork p/(set span)}
54+
55+`{$fork p/(set span)}` is the union of all spans in the set `p`.
56+
57+## `{$hold p/span q/twig}`
58+
59+A `$hold` span, with span `p` and twig `q`, is a lazy reference
60+to the span of `(mint p q)`. In English it means: "the type of
61+the product when we compile `q` with the subject `p`. (Hoon is
62+a strict language and the Hoon compiler is written in Hoon, so
63+laziness has to be implemented manually.)
64+
65+## `{$face p/term q/span}
66+
67+A `{$face p/term q/span}` wraps the label `p` around the span
68+`q`. See the twig section for how labels are resolved.
69+
70+## `{%atom p/term q/(unit atom))}
71+
72+An `$atom` is an atom, with two twists. `q` is a `unit`, Hoon's
73+equivalent of `Maybe` in Haskell or a nullable in Rust. If `q`
74+is `~`, null, the span is *warm*; any atom is in the span.
75+If `q` is `[~ x]`, where `x` is any atom, the span is *cold*;
76+its only legal value is the constnat `x`.
77+
78+`p` in the atom is a terminal used as an *aura*, or soft atom
79+type. Auras are a lightweight, advisory representation of the
80+units, semantics, and/or syntax of an atom. Two auras are
81+compatible if one is a prefix of the other.
82+
83+For instance, `@t` means UTF-8 text (LSB low), `@ta` means ASCII
84+text, and `@tas` means an ASCII symbol. `@u` means an unsigned
85+integer, `@ud` an unsigned decimal, `@ux` an unsigned
86+hexadecimal. You can use a `@ud` atom as a `@u` or vice versa,
87+but not as a `@tas`.
88+
89+Auras are truly soft; you can turn any aura into any other,
90+statically, by casting through the empty aura `@`. Hoon is not
91+dependently typed and can't enforce data constraints.
92+
93+## `{$core p/span q/(map term span)}
94+
95+A `$core` is a code-data cell. The data (or *payload*) is the
96+tail; the code (or *battery*) is the head. `p`, a span, is the
97+span of the payload. `q`, a name-twig table, is the source code
98+for the battery.
99+
100+Each twig in the battery source is compiled to a formula, with
101+the core itself as the subject. The battery is a tree of these
102+formulas, or *arms*. An arm is a computed attribute against its
103+core.
104+
105+All code-data structures in normal languages (functions, objects,
106+modules, etc) become cores in Hoon. A Hoon battery looks a bit
107+like a method table, but not every arm is a "method" in the OO
108+sense. An arm is a computed attribute. A method is an arm whose
109+product is a Hoon function (or *gate*).
110+
111+A gate is a core with one arm, whose name is the empty symbol
112+`$`, and a payload whose shape is `{sample context}`. The
113+*context* is the subject in which the gate was defined; the
114+*sample* is the argument.
115+
116+To call this function on an argument `x`, replace the sample (at
117+tree address `6` in the core) with `x`, then compute the arm.
118+(Of course, we don't mutate the noun, we make a mutant copy.)
docs/system/hoon/core/twig.mdnew file+48
@@ -0,0 +1,48 @@
1+---
2+sort: 8
3+---
4+
5+# Expression: `twig`
6+
7+A `twig` is an AST node: the noun that the Hoon compiler makes
8+when it parses a source expression.
9+
10+The definition of `twig` is the definition of Hoon. So let's
11+define the syntax and semantics of Hoon, a twig at a time. But
12+first, basic twig anatomy.
13+
14+## Twig anatomy
15+
16+A twig is a tagged union (`book`) with the form `{stem bulb}`,
17+where the `stem` is an atomic symbol. The bulb for each stem has
18+its own type, which varies by stem. (Compare with Lisp, where
19+every AST node is a tag and a list of child nodes.)
20+
21+There are no user-level macros. All stems are built into Hoon.
22+Most stems are implemented as internal macros, however.
23+
24+The bulb is usually a tuple, sometimes a list or map. An element
25+of this structure is a *subexpression*.
26+
27+Usually a subexpression is itself a `twig`; sometimes it's an
28+`@tas` (symbol) or a `wing` (reference path). Solely for
29+clarity, we use the type alias `moss` for twigs meant to produce
30+molds. A `moss` is just a twig, both in syntax and semantics.
31+
32+## Twig categories
33+
34+Fortunately, the twigs fit neatly into clear categories which
35+match their rune prefix. Read forward by category:
36+
37+<div><list/></div>
38+
39+## Structures
40+
41+The whole Crash twig system, as a
42+
43+```
44+|%
45+++
46+--
47+```
48+
docs/system/hoon/core/twig/atom.mdnew file+107
@@ -0,0 +1,107 @@
1+---
2+sort: 2
3+---
4+
5+# Constants and interpolations
6+
7+A constant is a twig whose product does not depend on the
8+subject. If you know Nock, the formula produced is always
9+is always `[1 constant]`.
10+
11+(Some of the "constant" syntax below can interpolate dynamic
12+twigs. When it does, it obviously isn't constant at all.)
13+
14+## Twigs
15+
16+```
17+|%
18+++ twig
19+ {$rock p/@tas q/@}
20+ {$sand p/@tas q/@}
21+ {$knit p/(list $@(@ {$~ p/twig}))}
22+ {$path p/(list (each @tas twig))
23+--
24+```
25+
26+## Syntax
27+
28+All Hoon constants are irregular; they have no rune form. The
29+stems described below are `$rock` (cold / constant), `$sand`
30+(warm / open), `$knit` (iterative string), and `$path` (Unix
31+style path).
32+
33+### Atoms
34+
35+Recall the `$atom` span, `{$atom p/aura q/(unit @)}`.
36+
37+Each atom constant syntax implies an aura. Note that the aura is
38+used indiscriminately to convey units, interpretations, parsing
39+syntax, and/or printing syntax.
40+
41+### Hardcoded auras
42+
43+### Cold or warm, single or arbitrary
44+
45+A span is a set of nouns; an `$atom` span contains either one
46+atom (*cold*) or all atoms (a *warm*).
47+
48+In general, the `%` prefix is added to indicate coldness. `42`
49+is warm and `%42` is cold. `@tas` symbols (which start with `%`
50+already, see below) are always cold.
51+
52+### Unsigned integer: `@ud`, `@ux`, `@uw`.
53+
54+Unsigned integers are broken into groups of 3 for decimals, and 4
55+for non-decimals, separated German style by `.`; `420` plus `999`
56+is `1.419`, a `@ud`.
57+
58+A hex (`@ux`) favorite is `0xcafe.babe`.
59+
60+`0w` is base64: `0-9`, `a-z` + 10, `A-Z` + 36, `-` and `~`. For
61+giant numbers, you can put whitespace/newlines after the `.`.
62+
63+### Boolean and null: `@f`, `@n`.
64+
65+Booleans in Hoon (`@f`) are `&` for yes (`@f`) and `|` for no.
66+Remember that `&` is `0` and `|` is `1` (which is why we say
67+"yes" and "no" rather than "true" and "false").
68+
69+Nil (aura `@n`) is `~` (with the value `0`).
70+
71+### Atomic string
72+
73+`'text'` in single quotes, `@t`, is a UTF-8 string LSB first.
74+
75+`%symbol`, `@tas`, containing only `a-z`, `0-9` and `-`, starting
76+with `a-z`, and ending with `a-z0-9`, is a valid symbolic name.
77+
78+`%$` is an empty `@tas`, ie, `0` with span `@tas`.
79+
80+### Signed integer: `@sd`
81+
82+Signed integers (`@sd`) are encoded with sign bit *low*. This
83+means we need a special syntax for positive signed integers,
84+since their atomic value can't be their unsigned value. For
85+example, `-3` is the atom `7`, whereas `--3` encodes to `6`.
86+
87+### Iterative string
88+
89+Hoon also has list-shaped strings (less compact, more editable).
90+Use double quotes: `"hello, world"`. The mold is `tape` or
91+`(list char)`, where `char` is a UTF-8 byte.
92+
93+Within a quoted string, interpolate with `{}`: `"hello, {(weld
94+"wo" "rld")}"`. It's also worth noting that `<`, `gar`, and `>`,
95+`gal` (angle brackets) stringify any twig: `"hello, {<mul 6
96+7>}"`. (Obviously, an interpolated string is not a constant.)
97+
98+### Path
99+
100+The path `/foo/bar/baz` is the constant `[%foo %bar %baz ~]`.
101+A path can be dynamically interpolated with `[]`:
102+
103+```
104+/foo/[:(if & %bar %rab)]/baz`
105+```
106+
107+equals `/foo/bar/baz`.
docs/system/hoon/core/twig/call.mdnew file+121
@@ -0,0 +1,121 @@
1+---
2+sort: 7
3+---
4+
5+# Full make (`%` runes)
6+
7+We've already covered the irregular-only twigs `$wing` and
8+`$limb`. These are simple forms of the *invocation* family of
9+twigs, `%`, whose general form is `$make`, `%=`.
10+
11+## Regular forms
12+
13+The rune prefix is `%`. Suffixes: `=` for `:make`, `~` for
14+`:open`, `-` for `:call`, `+` for `:calt`, `^` for `:calq`, `*`
15+for `:calp`.
16+
17+### `:make`, `%=`, "centis", `{$make p/wing q/(list (pair wing twig))}`
18+
19+Syntax: *1-fixed*, then *jogging*.
20+
21+The product: `p`, modified by the change list `q`.
22+
23+If `p` resolves to a leg, `q` is a list of changes to that leg.
24+If `p` resolves to an arm, `q` is a list of changes to the core
25+containing that arm. We compute the arm on the modified core.
26+
27+### `:open`, `%~`, "censig", `{$open p/wing q/twig r/twig}`
28+
29+Syntax: *3-fixed*.
30+
31+Expands to:
32+
33+```
34+ :pin q
35+ :make(p.+2 +6 :per(+3 r))
36+```
37+
38+We pin `q`, making our subject `[q subject]`. We make arm `p` on
39+`q`, changing leg `6` to `r` (per the original subject).
40+
41+Wut? Why? `$open` is a general case of `$call`; see below.
42+
43+### `:call`, `%-`, "cenhep", `{$call p/twig q/twig}`/
44+
45+Syntax: *2-fixed*.
46+
47+Expands to: `:open($ p q)`.
48+
49+`$call` is a function call; `p` is the function (`gate`), `q` the
50+argument. `$call` is a special case of `$open`, and a gate is a
51+special case of a `door` (see the [core](../core) twigs).
52+
53+In a gate, the modified core has only one anonymous arm; in a
54+door it gets a full battery. Intuitively, a gate defines one
55+algorithm it can compute upon its sample, `+6`. A door defines
56+many such algorithms.
57+
58+In classical languages, doors correspond to groups of functions
59+with the same argument list, or at least sharing a prefix. In
60+Hoon, this shared sample is likely to be pulled into a door.
61+
62+### `:calt`, `%+`, "cenlus", `{$calt p/twig q/twig r/twig}`
63+
64+Syntax: *3-fixed*.
65+
66+Expands to: `:(call p [q r])`.
67+
68+### `:calq`, `%^`, "cenket", `{$cnkt p/twig q/twig r/twig s/twig}`
69+
70+Syntax: *4-fixed*.
71+
72+Expands to: `:(call p [q r s])`.
73+
74+### `:calp`, `%*`, "centar", `{$cntr p/twig q/(list twig)}`
75+
76+Syntax: *4-fixed*.
77+
78+Expands to: `:(call p [q])`.
79+
80+## Irregular forms
81+
82+### Classic call, `(p q r s)`
83+
84+Translation:
85+
86+```
87+(p) :per(p $)
88+(p q) :call(p q)
89+(p q r s) :call(p [q r s])
90+```
91+
92+### Modified wing, `p.q(r s, t u, v w)`
93+
94+Translation:
95+
96+```
97+p.q(r s, t u, v w) :make(p.q r s, t u, v w)
98+```
99+
100+### Anonymous recursion, `:moar*`.
101+
102+Translation:
103+
104+```
105+:moar $
106+:moar(a b, c d, e f) $(a b, c d, e f)
107+:moarr ^$
108+:moarrrr ^^^$
109+```
110+
111+`:moar` has tall and wide form like a regular stem, though it has
112+no rune and is not a regular stem.
113+
114+`$` is a label like any other. But loops, gates, and traps all
115+hardcode this label. `$` thus implies recursing back to the
116+nearest `:loop` (`|-)`, `:gate` (`|=`), or `:trap` (`|.`). (Or
117+`^$` for the second nearest, `^^$` for the third, etc.
118+
119+`$` *seems* like a language primitive (eg, Clojure's `recur`), so
120+we made it look like one. Keyword enthusiasts and cats who love
121+cheeseburgers will appreciate `:moar`. Others can use `$`.
docs/system/hoon/core/twig/cast.mdnew file+53
@@ -0,0 +1,53 @@
1+---
2+sort: 10
3+---
4+
5+# Type manipulation (`^` runes).
6+
7+`$cast`, `$like`, and `$name` let us adjust spans without
8+violating type constraints.
9+
10+The `nest` algorithm which tests span subtyping is conservative;
11+it never allows invalid nests, it sometimes rejects valid nests.
12+
13+## Regular forms
14+
15+### `:like`, `^+`, "ketlus", `{$like p/twig q/twig}`
16+
17+Syntax: *2-fixed*.
18+
19+The product is the formula of `q` with the span of `p`, provided
20+nouns within the span of `q` can be shown to nest within the span
21+of `p`.
22+
23+### `:cast`, `^-`, "ketlus", `{$like p/moss q/twig}`
24+
25+Syntax: *2-fixed*.
26+
27+Expands to: `:like($.p q)`.
28+
29+`$like` is a typecheck by example; `$cast` is a typecheck by
30+mold.
31+
32+### `:name`, `^=`, "kettis", `{$name p/@tas q/twig}
33+
34+Syntax: *2-fixed*.
35+
36+The product: the formula of `q`, with the span of `q` labeled by
37+symbol `p`.
38+
39+### Irregular forms
40+
41+### Backtick cast: `\`foo\`bar`
42+
43+Translation:
44+```
45+`foo`bar ^-(foo bar)
46+```
47+
48+### Infix name: `foo=bar`
49+
50+Translation:
51+```
52+foo=bar ^=(foo bar)
53+```
docs/system/hoon/core/twig/cell.mdnew file+81
@@ -0,0 +1,81 @@
1+---
2+sort: 4
3+---
4+
5+# Cell construction (`:` runes)
6+
7+The cell twigs, `$cons` and friends, are simple and regular.
8+All `:` twigs expand to `$cons`.
9+
10+## Twigs
11+
12+```
13+|%
14+++ twig
15+ {$scon p/twig q/twig}
16+ {$conq p/twig q/twig r/twig s/twig}
17+ {$cons p/twig q/twig}
18+ {$cont p/twig q/twig r/twig}
19+ {$conl p/(list twig)}
20+ {$conp p/(list twig)}
21+--
22+```
23+
24+All construction stems expand to one natural stem, `$cons`, the
25+pair constructor, named for the Lisp special form.
26+
27+Synthetic stems change the last letter to indicate the bulb type:
28+`$cont` for triple, `$conq` for quad, `$conp` for tuple, `$conl`
29+for list. `$scon` is the reverse.
30+
31+## Regular forms
32+
33+The rune prefix is `:`. Suffixes: `-` for pair, `+` for triple,
34+`^` for quad, `*` for tuple, `~` for list, `_` for reverse.
35+
36+### `:cons`, `:-`, "colhep", `{$cons p/twig q/twig}`, "construct"
37+
38+Syntax: *2-fixed*.
39+
40+The product: the cell of `p` and `q`, each compiled against
41+the subject.
42+
43+### `:cont`, `:+`, "collus", `{$cont p/twig q/twig r/twig}`, "cons-3"
44+
45+Syntax: *3-fixed*.
46+
47+Expands to: `:cons(p :cons(q r))`.
48+
49+### `:conq`, `:^`, "colket", `{$cont p/twig q/twig r/twig s/twig}`, "cons-4"
50+
51+Syntax: *4-fixed*.
52+
53+Expands to: `:cons(p :cont(q r s))`.
54+
55+### `:conp`, `:*`, "coltar", `{$conp p/(list twig)}`, "construct tuple"
56+
57+Syntax: *running*.
58+
59+Expands by: `|-(?~(p ~ ?~(t.p i.p [%cons i.p $(p t.p)])))`.
60+
61+### `:conl`, `:~`, "colsig", `{$conl p/(list twig)}`, "construct list"
62+
63+Syntax: *running*.
64+
65+Expands by: `|-(?~(p [%rock %n ~] [%cons i.p $(p t.p)]))`.
66+
67+### `:scon`, `:_`, "colcab", `{$scon p/twig q/twig}`, "construct backward"
68+
69+Syntax: *running*.
70+
71+Expands to: `[%cons q p]`.
72+
73+## Irregular forms
74+
75+### Bracket tuple, `[p q r s]`
76+
77+Translation:
78+
79+```
80+[p q r s] :conp(p q r s)
81+```
docs/system/hoon/core/twig/core.mdnew file+90
@@ -0,0 +1,90 @@
1+---
2+sort: 6
3+---
4+
5+# Cores (`|` runes)
6+
7+Core twigs are flow twigs. The compiler essentially pins a Nock
8+formula, or battery of formulas, to the subject.
9+
10+All `|` twigs are macros around `$core`. (See the `$core`
11+section in [`span`](../span) above.) `$core` uses the subject as
12+the payload of a battery, whose arms are compiled with the core
13+itself as the subject.
14+
15+## Regular forms
16+
17+The rune prefix is `|`. Suffixes: `%` for `:core`, `=` for
18+`:gate`, `-` for `:loop`, `.` for `:trap`, `_` for `:door`.
19+
20+### `:core`, `|%`, "barcen", `{$core p/(map term twig)}`
21+
22+Syntax: *battery*
23+
24+The product: a core with battery `p`. Payload is the subject.
25+
26+### `:gate`, `|=`, "bartis", `{$gate p/moss q/twig}
27+
28+Syntax: *2-fixed*.
29+
30+Expands to:
31+
32+```
33+:new p
34+:core
35+++ $
36+ q
37+--
38+```
39+
40+A `$gate` produces a function from `p` to `q`. `p` is the
41+*sample*, or argument. The core has one formula, named `$` (the
42+empty name). The payload is of the form `{sample context}`,
43+where `context` is the subject of the gate.
44+
45+### `:loop`, `|-`, "barhep", `{$loop p/twig}`
46+
47+Syntax: *1-fixed*.
48+
49+Expands to:
50+
51+```
52+ :rap $
53+ :core
54+ ++ $
55+ p
56+ --
57+```
58+
59+A `$loop` makes a core with one anonymous arm `p`, then takes
60+that arm.
61+
62+### `:trap`, `|.`, "bardot", `{$trap p/twig}`
63+
64+Syntax: *1-fixed*.
65+
66+Expands to:
67+
68+```
69+ :core
70+ ++ $ p
71+ --
72+```
73+
74+A `$trap` is a deferred value.
75+
76+### `:door`, `|_`, "barcab", `{$door p/moss q/(map term twig)}`
77+
78+Syntax: *1-fixed*, then *battery*.
79+
80+Expands to:
81+
82+```
83+ :new p
84+ :core
85+ q
86+ ==
87+```
88+
89+A `gate` is a function; a `door` is the general case of a
90+function. Wut? We'll look at this again from the caller's side.
docs/system/hoon/core/twig/flow.mdnew file+143
@@ -0,0 +1,143 @@
1+---
2+sort: 5
3+---
4+
5+# Subject flow (`=` runes)
6+
7+Flow twigs change the subject. (Or more precisely, a flow twig
8+compiles at least one of its subtwigs with a different subject.)
9+All non-flow twigs (except cores) pass the subject down unchanged.
10+
11+## Overview
12+
13+The simplest way to change the subject is to compose two twigs,
14+`p` and `q`. Let `x` be `(mint subject p)`, with product span
15+`p.x` and nock formula `q.x`. Let `y` be `(mint p.x q)`. Then
16+their composition is `[p.y [7 q.x q.y]]`.
17+
18+This composition is the `$per` twig. A close relative is `$pin`,
19+which is `$per` over `[p .]`. The new subject is a cell of `p`
20+and the old subject. `$pin` is the simplest Hoon equivalent of
21+"declaring a variable" (introducing new data into the subject).
22+
23+Another way to change the subject is to mutate it. With the
24+`$set` twig, given a wing that resolves to a leg, we can write
25+instead of reading, *installing* a new value at that leg. Of
26+course, we are creating a copy, not modifying the original.
27+
28+## Structures
29+
30+### `taco`: name with optional filling
31+
32+A `taco` is either a symbol or a symbol-mold cell. The mold is a
33+typecheck and cast. For instance, when "initializing a variable"
34+with `:var`, we can cast the inferred type of the initial value
35+to match an explicit `taco` mold, or just state the symbol and
36+use the inferred type.
37+
38+The `taco` syntax is `foo` for the symbol foo, or `foo/bar` for
39+symbol `foo` and mold `bar`.
40+
41+## Definitions
42+
43+The rune prefix is `=`. Suffixes: `>` for `:per`, `<` for
44+`:rap`, `+` for `:pin`, `-` for `:nip`, `|` for `:new`, `/` for
45+`:var`, `;` for `:rev`, `.` for `:set`, and `^` for `:sip`.
46+
47+### `:per`, `=>`, "tisgar", `{$per p/twig q/twig}`, "compose"
48+
49+The product: `q`, compiled against the product of `p`.
50+
51+Intuitively: uses `p` as the subject of `q`.
52+
53+### `:rap`, `=<`, "tisgal", `{$rap p/twig q/twig}`, "reverse compose"
54+
55+Expands to: `:per(q p)`
56+
57+Intuitively: reverse of `:per`.
58+
59+### `:pin`, `=+`, "tislus", `{$pin p/twig q/twig}`, "work with"
60+
61+Expands to: `:per(:cons(p .) q)`
62+
63+Intuitively: uses `[p subject]` as the subject of `q`.
64+
65+### `:nip`, `=-`, "tishep", `{$nip p/twig q/twig}`, "work over"
66+
67+Expands to: `:pin(q p)`
68+
69+Intuitively: reverse of `:pin`.
70+
71+### `:var`, `=/`, "tisfas", `{$var p/taco q/twig r/twig}, "with variable"
72+
73+Expands to: `?@(p :pin(:name(p q) r) :pin(:cast(:(coat p) q) r)`
74+
75+Intuitively: uses `[p=q subject]` as the subject of `r`. If `p`
76+contains a mold, cast `q` to that mold.
77+
78+### `:rev`, `=;`, "tissem", `{$var p/taco q/twig r/twig}, "over variable"
79+
80+Expands to: `:var(p r q)`
81+
82+Intuitively: reverse of `:var`.
83+
84+### `:new`, `=|`, "tisbar", `{$new p/moss q/twig}`, "with blank"
85+
86+Expands to: `:pin(:per($ p) q)`
87+
88+Intuitively: pin the default value of `p`.
89+
90+### `:set`, `=.`, "tisdot", `{$set p/wing q/twig r/twig}`, "mutate"
91+
92+The product: `r`, compiled against a version of the subject
93+with wing `p` modified to the product of `q`.
94+
95+Intuitively: `r` with `p` set to `q`. Almost an assignment.
96+
97+### `:sip`, `=^`, "tisket", `{$sip p/taco q/wing r/twig s/twig}`, "advance"
98+
99+The product is `s`, compiled against a version of the subject
100+in which the head of `r` is bound to variable `p`, and the tail
101+of `r` is assigned into the wing `q`.
102+
103+Intuitively: `r` produces a cell; we pin the head and install the
104+tail.
105+
106+Whyuppose we have a state machine with a function that
107+produces a cell, whose head is a result and whose tail is a new
108+state. We want to use the head as a new variable, and stuff the
109+tail back into wherever we stored the old state. This may also
110+remind you of Haskell's State monad.
111+
112+## Irregular forms
113+
114+### Infix colon, p:q
115+
116+Not to be confused with the wing `p.q`. Translation:
117+```
118+p:q:r :rap(p :rap(q r))
119+```
120+
121+## Structures
122+
123+Using a mold syntax we haven't learned yet:
124+
125+```
126+|%
127+++ taco
128+ ?@(term {term moss})
129+::
130+++ twig
131+ {$per p/twig q/twig}
132+ {$rap p/twig q/twig}
133+
134+ {$pin p/twig q/twig}
135+ {$nip p/twig q/twig}
136+
137+ {$new p/moss q/twig}
138+ {$var p/taco q/twig r/twig}
139+ {$rev p/taco q/twig r/twig}
140+ {$set p/wing q/twig r/twig}
141+ {$sip p/taco q/wing r/twig s/twig}
142+--
143+```
docs/system/hoon/core/twig/limb.mdnew file+103
@@ -0,0 +1,103 @@
1+---
2+sort: 3
3+---
4+
5+# Limbs and wings
6+
7+One feature Hoon lacks: a context that isn't a first-class value.
8+Hoon has no concept of scope, environment, etc. A twig has one
9+data source, the *subject*, a noun like any other.
10+
11+In most languages "variable" and "attribute" are different
12+things. They are both symbols, but a variable is in "the
13+environment" and a attribute is on "an object." In Hoon, "the
14+environment" is "an object" -- the subject.
15+
16+`$limb` and `$wing` are two basic twig stems that extract
17+information from the subject. A `limb` is an attribute; a `wing`
18+is an attribute path, ie, a list of limbs.
19+
20+## Twigs
21+
22+Using a mold
23+```
24+++ limb
25+ $% {$& p/@ud}
26+ {$| p/@ud q/@tas}
27+ ==
28+++ twig
29+ $% {$limb p/limb}
30+ {$wing p/wing}
31+ ==
32+++ wing (list limb)
33+```
34+
35+The basic reference twigs are `$limb` and `$wing`. `$limb`
36+is a single reference step into the subject. `$wing` is a path
37+of reference steps.
38+
39+## Limbs and wings
40+
41+A `limb` is either *geometric*, `{$& p/@ud}`, or *symbolic*,
42+`{$| p/@ud q/@tas}`.
43+
44+The result of compiling a limb is either an *arm* or a *leg*. A
45+leg is a subtree of the subject. An arm is a computed attribute
46+on a core which is a subtree of the subject. (See `$core` in
47+[span](../span).)
48+
49+A geometric limb always compiles to a leg. A symbolic limb may
50+compile to an arm or a leg, depending on the subject.
51+
52+### Geometric limb, `{$& p/@ud}`
53+
54+`p` is a Nock tree address in the subject. If you don't know
55+Nock, tree addresses are a way of designating a subtree of a noun
56+with an atom. The root is `1`, the left child of any node `n` is
57+`(mul 2 n)`, the right child is `(add 1 (mul 2 n))`.
58+
59+### Symbolic limb
60+
61+A symbolic limb has a name `q` and a *skip count* `p`.
62+
63+To resolve the limb to arm or leg, we search the subject
64+headfirst and depth-first. If we descend to a `$face` span whose
65+label matches the limb symbol, the descent address is a leg; the
66+span is the span beneath the label. But if the `$face` label
67+differs, the search ignores this leg.
68+
69+If we descend into a `$core` span in which the limb symbol is an
70+arm, we produce that arm. If the limb symbol is not bound, we
71+descend into the payload (data) of the core.
72+
73+If the skip count `p` is nonzero, we pretend our first `p`
74+matches are actually mismatches. This lets the programmer "look
75+through" an overriding label. No label anywhere is inaccessible.
76+
77+### Wing
78+
79+A `wing` is a symbolic reference path, `(list limb)`. Taking a
80+wing is not quite the same as composing each of these limbs,
81+though; the product of a wing is still either an arm or a leg.
82+
83+This is trivial if each step in the wing is a leg. If an
84+intermediate step in a wing compiles to an arm, this arm is
85+rewritten; it becomes a leg to the arm's core.
86+
87+### Syntax
88+
89+All limb references are irregular.
90+
91+A geometric limb `x` is `+x`. `.` means `+1`.
92+
93+A symbolic limb `foo` is `foo`; the symbol is naked. To set a
94+nonzero skip count, use a unary `^` prefix; thus `^foo` skips one
95+match, and `^^^foo` skips three.
96+
97+The empty name `$` is the label whose value is 0. By convention,
98+`$` is always an arm, usually on a one-armed core (such as a
99+function or loop).
100+
101+A wing is written outside-in with `.` as a separator. So
102+`foo.bar.baz` is "foo, in bar, in baz." Yes, this is the
103+opposite of what you're used to.
docs/system/hoon/core/twig/mold.mdnew file+136
@@ -0,0 +1,136 @@
1+---
2+sort: 8
3+---
4+
5+# Molds (`$` runes).
6+
7+A *mold* is a `gate` (function) that helps us build simple and
8+rigorous data structures. (In fact, since "mold" sounds nasty,
9+molds are often called "structures.")
10+
11+## Overview
12+
13+While Hoon can't check this property statically, any true mold
14+is a *rectifier*: an idempotent function across all nouns. If
15+the sample of a gate has span `%noun`, and its body obeys the
16+constraint that for any x, `=((mold x) (mold (mold x)))`, it's a
17+rectifier and can be used as a mold.
18+
19+Twigs in the `$` family are macros designed for making molds.
20+But any Hoon twig may produce a mold. (This is why `moss` is a
21+synonym for `twig`).
22+
23+Many macros *bunt* a mold, producing `:per(mold $)`. This value,
24+simply the result of executing the gate on the default sample,
25+is a constant by definition and normally can be compiled as such.
26+The range of a mold (the span of its bunt) is called its *icon*.
27+
28+Molds have two uses: defining simple and rigorous structures, and
29+validating untrusted input data. Validation, though very
30+important, is a rare use case. Except for direct raw input,
31+it's generally a faux pas to rectify nouns at runtime -- or even
32+in userspace.
33+
34+As a structure definition, a mold has three common uses. One,
35+its bunt is a default value (such as the sample in a gate.) Two,
36+the product of some computation is cast to its icon, both
37+checking the type and regularizing it. Three, it's used as a
38+building block in other molds.
39+
40+## Regular forms
41+
42+The rune prefix is `$`. Suffixes:
43+
44+### `:bank`, `$:`, "buccol", `{$bank p/(list moss)}`
45+
46+Syntax: *running*.
47+
48+The product: a rectifier gate producing the tuple `p`.
49+
50+Where `a`, `b` and `c` produce molds, `:bank(a b c)` produces a
51+mold whose icon is the span `[$.a $.b $.c]`.
52+
53+### `:coat`, `$=`, "buctis", `{$coat p/@tas q/moss}`
54+
55+Syntax: *2-fixed*.
56+
57+The product: a rectifier gate producing mold `q` under label `p`.
58+
59+Where `q` produces a mold, `:coat(p q)` produces a mold whose
60+icon matches the span of `:name(p $.q)`.
61+
62+### `:pick`, `$?`, "bucwut", `{$pick p/(list moss)}`
63+
64+Syntax: *running*.
65+
66+The product: a rectifier gate producing the union of the molds in
67+`p`.
68+
69+Where `a`, `b`, and `c` produce molds, `:pick(a b c)` produces a
70+mold whose icon matches the span of `?:(& $.a ?:(& $.b $.c))`.
71+
72+The default mold is the first item in `p`. To avoid an infinite
73+loop, it has to be a termination case (such as a constant).
74+
75+### `:book`, `$%`, "buccen", `{$book p/(list moss)}`
76+
77+Syntax: *running*.
78+
79+The product: a rectifier gate producing the tagged union of the
80+molds in `p`, all of which must be of the form `:bank(stem
81+bulb)`, where `stem` is an atomic mold.
82+
83+`$book` has the same icon as `$pick`, but rectifies better.
84+
85+The default mold is the first item in `p`. To avoid an infinite
86+loop, it has to be a termination case (such as a constant).
87+
88+### `:shoe`, `$_`, "buccab", "{$shoe p/twig}"
89+
90+Syntax: *1-fixed*.
91+
92+Expands to: `:gate(* p)`.
93+
94+A `$shoe` is not useful for rectification; it ignores its input.
95+It is only useful for defaults and typechecks. Sometimes we have
96+no choice but to describe by example.
97+
98+### `:lamb`, `$-`, `"buchep"`, `{$lamb p/moss q/moss}`
99+
100+Syntax: *1-fixed*.
101+
102+Expands to: `:shoe(:gate(p $.q))`.
103+
104+`$lamb` is a lambda. We shoe a trivial function from `p` to `q`.
105+Like any `$shoe`, a `$lamb` is not useful for rectification (eg,
106+you can't use it to typecheck cores sent over the network).
107+
108+## Irregular forms
109+
110+### Primitives
111+
112+`*` means any noun; `@` with an aura means an atom, such as `@ud`
113+for unsigned decimal, or just `@` for a generic noun; `?` for
114+boolean; `^` for a cell (of `*`).
115+
116+### Constants
117+
118+For a mold producing a cold atom, replace the `%` of the constant
119+syntax with `$`. `%42` is the constant number `42`; `$42` is a
120+function that, passed 42 or any other argument, produces `%42`.
121+
122+Similarly, `%foo` is the number `7.303.014` or `0x6f.6f66`;
123+`$foo` is a function that produces `%foo`.
124+
125+`$~` produces `~`.
126+
127+### Miscellaneous
128+
129+Translation:
130+
131+```
132+{a b c}` :bank(a b c)
133+a/b :coat(a b)
134+?(a b c) :pick(a b c)
135+_a :shoe(a)
136+```
docs/system/hoon/core/twig/nock.mdnew file+36
@@ -0,0 +1,36 @@
1+---
2+sort: 11
3+---
4+
5+# Intrinsics (`.` runes)
6+
7+Anything Nock can do, Hoon can do.
8+
9+## Regular forms
10+
11+### `:bump`, `.+`, "dotlus", `{$bump p/twig}`
12+
13+Syntax: *1-fixed*
14+
15+The product: the product of `p`, which must be an atom, plus 1.
16+
17+### `:same`, `.=`, "dottis", `{$same p/twig q/twig}`
18+
19+Syntax: *2-fixed*.
20+
21+The product: yes iff `p` and `q` produce the same value. The span
22+of `p` must nest within the span of `q`, or vice versa.
23+
24+### `:nock`, `.*`, "dottar", `{$nock p/twig q/twig}`
25+
26+The product: Nock of the formula produced by `q`, with the
27+subject produced by `p`. Typeless.
28+
29+### `:wish`, `.^`, "dotket", `{$wish p/moss q/twig}`
30+
31+The product: the noun `q` dereferenced in the Urbit global
32+namespace. The product must nest within the icon of `p`.
33+
34+Only available in user-level code. Not blocking except in
35+dojo-level code (blocks for a generator, fails if it would block
36+for an app).
docs/system/hoon/core/twig/syntax.mdnew file+20
@@ -0,0 +1,20 @@
1+---
2+sort: 1
3+---
4+
5+# Hoon syntax
6+
7+Hoon's semantics are simple, but unusual. Hoon's syntax is
8+complex, and unusual. Sorry.
9+
10+An excuse: the normal human brain doesn't have hardware support
11+for math, but it does have hardware support for syntax. Learning
12+math is harder than it looks. Learning syntax is easier.
13+
14+An explanation: the Hoon syntax is trying to solve three serious
15+problems in functional syntax design.
16+
17+Read the [motivation](motivation) if you care; or go straight to
18+the actual [design](design).
19+
20+<list></list>
docs/system/hoon/core/twig/syntax/design.mdnew file+297
@@ -0,0 +1,297 @@
1+# Design
2+
3+Because each twig stem has its own bulb, each has its own parser
4+rule. We'll describe these grammars as we go through the stems.
5+
6+But Hoon has a general syntax design with common principles and
7+regularities. We'll cover those here.
8+
9+## Glyphs and characters
10+
11+Hoon is a heavy punctuation user. To make ASCII great again,
12+we've mapped each punctuation glyph to a syllable:
13+
14+```
15+ ace [1 space] gal < pal (
16+ bar | gap [>1 space, nl] par )
17+ bas \ gar > sel [
18+ buc $ hax # sem ;
19+ cab _ hep - ser ]
20+ cen % kel { sig ~
21+ col : ker } soq '
22+ com , ket ^ tar *
23+ doq " lus + tec `
24+ dot . pam & tis =
25+ fas / pat @ wut ?
26+ zap !
27+```
28+
29+You don't need to memorize these glyph names, but it helps. Code
30+is often vocalized or subvocalized. "pal" is easier to say,
31+aloud or silently, then "left paren."
32+
33+Note that the list includes two separate whitespace forms: `ace`
34+for a single space, `gap` for 2+, comment or newline. Hoon
35+Besides `ace` versus `gap`, whitespace is not significant.
36+
37+Comments start with `::` and run to the end of the line. Hard
38+tab characters are illegal, and an 80-column right margin is
39+strongly encouraged. Really well-groomed Hoon uses a 55-column
40+code margin and puts a standard line comment at column 57.
41+
42+Hoon does not accept non-ASCII text in source files, except UTF-8
43+in quoted strings.
44+
45+## Tall and flat forms
46+
47+There are two kinds of Hoon expression syntax: *tall* and *flat*.
48+Most stems have both tall and flat forms. Tall twigs can contain
49+flat twigs, but not vice versa.
50+
51+Visually, a tall twig looks like a "statement" and a flat twig
52+like an "expression," preserving the attractive visual shape of
53+procedural code without the nasty side effects.
54+
55+## Regular and irregular forms
56+
57+Most stems have *regular forms*, which share a common design.
58+There is a regular flat form and a regular tall form; most stems
59+implement both. All tall forms are regular.
60+
61+Some twigs also have *irregular forms*, which follow no
62+principles at all. All irregular forms are flat.
63+
64+Some twigs (simple leafy ones) have *only* irregular forms.
65+
66+## Keywords versus runes
67+
68+A regular form starts with a *sigil*, which is either a
69+*keyword* or a *rune* -- at the programmer's choice.
70+
71+A *keyword* is `:` and then the stem label - eg, `:cons`.
72+
73+A *rune* is a pair of ASCII punctuation marks (a digraph) - eg,
74+`:-`. The first glyph in the rune indicates the category - eg,
75+`:` runes make cells. Runes can be pronounced by their glyphs or
76+by their stem -- for `:-`, you can say either "colhep" or "cons".
77+
78+Keywords may be less challenging for early learners. Rune style
79+is less cluttered and distracting for experienced programmers;
80+the system codebase is all in rune style. Beginners can start
81+with keywords and move to runes; start with runes and stick
82+with runes; or start with keywords and stick with keywords.
83+
84+Here's the FizzBuzz demo code, in idiomatic rune syntax. Compare
85+with the [original](../../demo).
86+
87+```
88+ |= end/atom
89+ =/ count 1
90+ |- ^- (list tape)
91+ ?: =(100 count) ~
92+ :_ $(count (add 1 count))
93+ ?: =(0 (mod count 15))
94+ "FizzBuzz"
95+ ?: =(0 (mod count 5))
96+ "Fizz"
97+ ?: =(0 (mod count 3))
98+ "Buzz"
99+ (text !>(count))
100+```
101+
102+## Tall regular form
103+
104+Tall regular form starts with the sigil, followed by a `gap`
105+(any whitespace except `ace`), followed by a bulb whose twigs are
106+separated by `gap`.
107+
108+There are four body subtypes: *fixed*, *running*, *jogging*, and
109+*battery*. Stems with a *fixed* number of subexpressions
110+self-terminate. For instance, `:if` has three subexpressions and
111+is self-terminating. Otherwise the twig is terminated by a
112+`gap`, then either `==` (*running* or *jogging*, most twigs) or
113+`--` (*battery*).
114+
115+The *running* body is a list of twigs. The *jogging* body is a
116+list of twig pairs, separated by a `gap`. The *battery* body is
117+a list of symbol-twig pairs, separated by a gap, prefixed by `++`
118+and then a gap.
119+
120+This definition is enough to parse. But the proper shape of the
121+whitespace gaps demands an informal convention.
122+
123+Whitespace design in Hoon is an art, not a science. It involves
124+both tall/flat mode switches and well-shaped gaps. (Hoon layout
125+could probably be done automatically with reasonable quality.
126+But it would at least take machine learning, not a rule engine.)
127+
128+There only two real *rules* in Hoon whitespace design: don't
129+go past 80 characters, and don't use (completely) blank lines.
130+Otherwise, if it looks good and is easy to read, it's good. But
131+the best way to learn the art is to do everything by convention
132+until you know what you're doing. Here are the conventions:
133+
134+### Conventions: *fixed*
135+
136+Bulbs with *fixed* fanout use "backstep" indentation, which slopes
137+backward and to the right by two spaces per line. The first
138+child is two spaces after the end of the sigil.
139+
140+Some *1-fixed*, *2-fixed*, *3-fixed* and *4-fixed* examples:
141+
142+```
143+|.
144+p
145+
146+=| p
147+q
148+
149+?: p
150+ q
151+r
152+
153+%^ p
154+ q
155+ r
156+s
157+```
158+
159+The hope of backstep indentation is that the heaviest twigs are
160+at the bottom, keeping code flow vertical rather than diagonal.
161+Alternate, reversing
162+
163+### Conventions: *running*
164+
165+A *running* bulb (a simple child list) puts the first child two
166+spaces after the end of the sigil, and the following children
167+straight down:
168+
169+A *running* example:
170+
171+```
172+:* p
173+ q
174+ r
175+ s
176+ t
177+==
178+```
179+
180+### Conventions: *jogging*
181+
182+A *jogging* bulb (a list of child pairs) is like a running bulb,
183+but backsteps the head of the pair above the tail. Most jogging
184+twigs start with a *fixed* sequence; the first jogging pair is
185+below and two steps backward from the last fixed child.
186+
187+There are two jogging conventions: *flat* (pair on one line) and
188+*tall* (pair split across lines).
189+
190+A *flat jogging* example (preceded by *1-fixed* `p`)
191+
192+```
193+?- p
194+ q r
195+ s t
196+ u v
197+==
198+```
199+
200+A *tall jogging* example (preceded by *1-fixed* `p`):
201+
202+```
203+?- p
204+ q
205+ r
206+ s
207+ t
208+ u
209+ v
210+==
211+```
212+
213+### Conventions: *battery*
214+
215+A *battery* bulb is a list of symbol-twig pairs, for the battery
216+of a core. A conventional example:
217+
218+```
219+|%
220+++ foo
221+ p
222+++ bar
223+ q
224+--
225+```
226+
227+## Flat regular form
228+
229+Flat regular form starts with the sigil, followed by `pal`
230+(`(`, left parenthesis), followed by a bulb whose subexpressions
231+are separated by `ace` (one space), followed by `par` (`)`, right
232+parenthesis).
233+
234+A twig in flat form, `:if`, `?:`, `{$if p/twig q/twig r/twig}`:
235+
236+```
237+:if(p q r)
238+
239+?:(p q r)
240+```
241+
242+The only exception is *jogging* bodies, in which subexpression
243+pairs are separated by commas:
244+
245+```
246+:make(foo bar 42, baz 55, moo 17)
247+```
248+
249+There is no flat regular form for *battery* bodies. Be tall.
250+
251+## Naming conventions
252+
253+Hoon does not enforce any rule on symbols, except that capitals
254+are not allowed (use kebab-case). However, a lot of system code
255+is written in using "lapidary" conventions that need explanation.
256+
257+Naming things is one of the hard problems in CS. Dodging this
258+problem is one of the reasons mathematicians use Greek letters,
259+not variable names. Meaningful names also interpose a verbal
260+interpretation, distracting at best and confusing at worst, on
261+the formula or algorithm. Greek letters are not *meaningful*,
262+but they are *memorable*. And their interpretation is defined by
263+the formula and nothing else.
264+
265+### Lapidary and ultralapidary
266+
267+In the *lapidary* naming style, labels are pronounceable
268+three-letter strings, usually CVC (consonant-vowel-consonant).
269+Sometimes they encode a mnemonic, but usually they are just
270+memorable. Labels are reused wherever the analogy seems
271+appropriate.
272+
273+In the *ultralapidary* naming style, labels are single letters,
274+starting in order of construction from `a`, or within a tuple
275+mold `p`. Hoon uses single-letter names for the same reason
276+Algol style languages pass arguments by order, rather than
277+keyword. Naming items by order makes sense when there are no
278+more than three or four; five is stretching it; six is too many.
279+
280+For example, when defining `add`, we want to name the operands
281+`a` and `b`. It's silly to call them `foo` and `bar`, let alone
282+`left-operand` and `right-operand`. The smaller the scale of an
283+algorithm, the simpler its names should be.
284+
285+### When in doubt, don't be lapidary
286+
287+This works in the other direction: namelessness doesn't scale.
288+Most normal code shouldn't use lapidary naming at all. (There is
289+too much lapidary Hoon in Urbit.)
290+
291+Lapidary naming is only for *inherently simple code*: code that
292+both aspires to high elegance and clarity, and *is solving a
293+simple and elegant problem*.
294+
295+Given an ugly or complex problem, lapidary naming is a liability,
296+no matter the excellence of the programmer. When in doubt, use
297+long names and/or kebab-case.
docs/system/hoon/core/twig/syntax/motivation.mdnew file+56
@@ -0,0 +1,56 @@
1+# Motivation
2+
3+The three problems are *terminator piles*, *indentation creep*,
4+and *feature/label confusion*.
5+
6+## Terminator piles
7+
8+*Terminator piles* are like Lisp's stacks of right parens. If a
9+syntax uses matching glyphs besides `)`, they get truly ugly.
10+Significant whitespace solves this problem but introduces others.
11+
12+Hoon has no terminator piles. Except for a 1-space / more-space
13+distinction, it has no significant whitespace.
14+
15+## Indentation creep
16+
17+*Indentation creep* is a problem caused by indentation conventions
18+where the indentation point is a function of expression tree
19+depth. It's true that short functions are better than long ones,
20+but long ones sometimes need to be written.
21+
22+A procedural block has a backbone of statements which flows
23+straight down. Most expressions are flat and of limited depth.
24+With some bulging, a long function flows *down* the page.
25+
26+A functional language lacks the expression/statement distinction.
27+So a long function means a deep tree. Given normal indentation
28+conventions, a long function wants to flow *down and across*.
29+This *diagonal* shape fits poorly into most editor windows.
30+
31+Thanks to backstep indentation (see below), Hoon programs are
32+shaped more or less like procedural programs.
33+
34+## Feature/label confusion
35+
36+*Feature/label confusion* is any syntax which makes it hard for
37+the eye to tell whether a token on the screen is a feature of the
38+language, or a label in the program. For example, in Lisp a
39+special form has the same syntax as a function call.
40+
41+The worst-case result of FLC is "DSL cancer". Every source file
42+is effectively written in its own domain-specific language. To
43+read a new file is to learn a new language -- "write-only code."
44+
45+A fixed reserved-word set, especially with syntax highlighting,
46+and especially with orthogonal grammar (in C, you don't write
47+`for(a b c)`), may not be too bad. User-level macros, operator
48+overloading, even excessive use of higher-order programming,
49+can all lead quickly to the tragedy of write-only code.
50+
51+Hoon has very weak FLC in keyword style, none in rune style.
52+It has no user-level macros or overloading. It does support
53+higher-order programming; write-only Hoon can certainly be
54+(and has been) written. But good Hoon style is to avoid it.
55+
56+
docs/system/hoon/core/twig/test.mdnew file+143
@@ -0,0 +1,143 @@
1+---
2+sort: 9
3+---
4+
5+# Tests (`?` runes)
6+
7+Hoon has the usual branches and logical tests. For pattern
8+matching, it also has a `$fits` twig that tests whether a value
9+matches the icon of a mold. And it has branch inference,
10+learning from `$fits` tests in the condition of `:if` twigs.
11+
12+## Overview
13+
14+All `?` runes expand to `$if` (`?:`) and/or `$fits` (`?=`).
15+
16+If the condition of an `$if` is a `$fits`, *and* the `$fits` is
17+testing a leg of the subject, the compile specializes the subject
18+span for the branches of the `$if`. Branch inference also works
19+for twigs which expand to `$if`.
20+
21+The test does not have to be a single `$fits`; the compiler can
22+analyze arbitrary boolean logic (`$and`, `$or`, `$not`) with full
23+short-circuiting. Equality tests (`=`) are *not* analyzed.
24+
25+If the compiler detects that the branch is degenerate (only one
26+side is taken), it fails with an error.
27+
28+## Regular forms
29+
30+The rune prefix is `?`. Suffixes: `=` for `:fits`, `:` for
31+`:if`, `.` for `:lest`, `-` for `:case`, `+` for `:deft`, `|` for
32+`:or`, `&` for `:and`, `!` for `:not`, `>` for `$sure`, `<` for
33+`$deny`, `^` for `:ifcl`, `@` for `:ifat`, `~` for `:ifno`.
34+
35+### `:fits`, `?=`, "wuttis", `{$fits p/moss q/twig}`
36+
37+Syntax: *2-fixed*.
38+
39+The product: `&` if the product of `q` is in the icon of `p`,
40+`|` otherwise.
41+
42+The icon of `p` must be finite / nonrecursive. In general,
43+always match one layer of a data structure at a time.
44+
45+### `:if`, `?:`, "wutcol", `{$if p/twig q/twig r/twig}`
46+
47+Syntax: *3-fixed*.
48+
49+The product: `q` if `p` has the value `&` (0), `r` for `|` (1).
50+`p` must be statically boolean.
51+
52+### `:lest`, `?.`, "wutdot", `{$lest p/twig q/twig r/twig}`
53+
54+Syntax: *3-fixed*.
55+
56+Expands to: `:if(p r q)`.
57+
58+### `:case`, `?-`, "wuthep", `{$case p/twig q/(list (pair moss twig))}`
59+
60+Syntax: *1-fixed*, then *jogging*.
61+
62+Expands by:
63+
64+```
65+|-(?~(q [%lost p] [%if [%fits p.i.q p] q.i.q $(q t.q)]))
66+```
67+
68+A pattern-matching switch. Fails to compile if the pattern is
69+incomplete or irrelevant.
70+
71+### `:deft`, `?+`, "wutlus", `{$case p/twig q/twig r/(list (pair moss twig))}`
72+
73+Syntax: *1-fixed*, then *jogging*.
74+
75+Expands by: `[%case p (weld r [[%base %noun] q])]`
76+
77+A pattern-matching switch, with default.
78+
79+### `:or`, `?|`, "wutbar", `{$or p/(list twig)}`
80+
81+Syntax: *running*.
82+
83+Expands by: `|-(?~(p [%rock %f |] [%if i.p [%rock %f &]] $(p t.p)))`
84+
85+Logical or (`&` (`0`) is yes, `|` (`1`) is no).
86+
87+### `:and`, `?&`, "wutpam", `{$and p/(list twig)}`
88+
89+Syntax: *running*.
90+
91+Expands by: `|-(?~(p [%rock %f &] [%if i.p $(p t.p) [%rock %f |]]))`
92+
93+Logical and (`&` (`0`) is yes, `|` (`1`) is no).
94+
95+### `:not`, `?!`, "wutzap", `{$not p/twig}`
96+
97+Syntax: *1-fixed*.
98+
99+Expands to: `:if(p %| %&)`.
100+
101+Logical not (`&` (`0`) is yes, `|` (`1`) is no).
102+
103+### `:sure`, `?>`, "wutgar", `{$sure p/twig q/twig}`
104+
105+Expands to: `:if(p q !!)`.
106+
107+An assertion.
108+
109+### `:deny`, `?<`, "wutgal", `{$deny p/twig q/twig}`
110+
111+Expands to: `:if(p !! q)`.
112+
113+A negative assertion.
114+
115+### `:ifno`, `?~`, "wutsig", `{$ifno p/twig q/twig r/twig}`
116+
117+Expands to: `:if(:fits($~ p) q r)`.
118+
119+Branches on whether `p` is null.
120+
121+### `:ifat`, `?@`, "wutpat", `{$ifat p/twig q/twig r/twig}`
122+
123+Expands to: `:if(:fits(@ p) q r)`.
124+
125+Branches on whether `p` is atomic.
126+
127+### `:ifcl`, `?^`, "wutket", `{$ifat p/twig q/twig r/twig}`
128+
129+Expands to: `:if(:fits(^ p) q r)`.
130+
131+Branches on whether `p` is cellular.
132+
133+## Irregular forms
134+
135+### Light logic
136+
137+Translations:
138+
139+```
140+&(a b c) ?&(a b c)
141+|(a b c) ?|(a b c)
142+!a ?!(a)
143+```