@@ -7,22 +7,19 @@ title: Syntax
77
88# Hoon syntax
99
10−Hoon's semantics are simple, but unusual. Hoon's syntax is
11−complex, and unusual. Sorry.
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.
1213
1314# Motivation
1415
15−An excuse: the normal human brain doesn't have hardware support
16−for math, but it does have hardware support for syntax. Learning
17−math is harder than it looks. Learning syntax is easier.
18−
19−An explanation: the Hoon syntax is trying to solve three serious
16+Hoon syntax is trying to solve three serious
2017problems in functional syntax design. These are *terminator
2118piles*, *indentation creep*, and *feature/label confusion*.
2219
2320## Terminator piles
2421
25−*Terminator piles* are like Lisp's stacks of right parentheses.
22+*Terminator piles* are like Lisp's stacks of right parentheses.
2623Significant whitespace solves this problem and creates others.
2724
2825Hoon has no terminator piles. Except for a 1-space / more-space
@@ -32,8 +29,9 @@ distinction, it has no significant whitespace.
3229
3330*Indentation creep* is a problem caused by indentation conventions
3431where the indentation point is a function of expression tree
35−depth. It's true that short functions are better than long ones,
36−but long ones sometimes need to be written.
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.
3735
3836A procedural block has a backbone of statements which flows
3937straight down. Most expressions are flat and of limited depth.
@@ -49,53 +47,37 @@ shaped more or less like procedural programs.
4947
5048## Feature/label confusion
5149
52−*Feature/label confusion* is any syntax which makes it hard for
53−the eye to tell whether a token on the screen is a feature of the
54−language, or a label in the program. For example, in Lisp a
50+*Feature/label confusion* (FLC) is any syntax which makes it hard
51+for the eye to tell whether a token on the screen is a feature of
52+the language, or a label in the program. For example, in Lisp a
5553special form has the same syntax as a function call.
5654
5755The worst-case result of FLC is "DSL cancer." Every source file
5856is effectively written in its own domain-specific language. To
5957read a new file is to learn a new language—"write-only code."
6058
61−A fixed reserved-word set, especially with syntax highlighting,
62−and especially with orthogonal grammar (in C, you don't write
63−`for(a b c)`), may not be too bad. User-level macros, operator
64−overloading, even excessive use of higher-order programming,
65−can all lead quickly to the tragedy of write-only code.
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.
6662
67−Hoon has very weak FLC in keyword style, none in rune style.
68−It has no user-level macros or overloading. It does support
69−higher-order programming; write-only Hoon can certainly be
63+Hoon has no FLC, user-level macros, or overloading. It does
64+support higher-order programming; write-only Hoon can certainly be
7065(and has been) written. But good Hoon style is to avoid it.
7166
7267# Design
7368
74−Hoon expressions are called
75−*[twigs](https://urbit.org/docs/about/glossary#twig)*, and at the
76−beginning of each twig is a
77−*[rune](https://urbit.org/docs/about/glossary#rune)*. Each rune
78−type has a name, called a
79−*[stem](https://urbit.org/docs/about/glossary#stem)*. Finally,
80−each stem has its own structure, e.g.:
81−
82−```
83− :-
84− (add 12 13)
85− (sub 10 7)
86−```
87−
88−This twig uses the rune `:-` (stem: `%clhp`) to produce an ordered
89−pair: `[25 3]`. There are two subexpressions following the `:-`,
90−corresponding to the two parts of the `%clhp` structure.
91−
9269Hoon has a general syntax design with common principles and
9370regularities. We'll cover those here.
9471
9572## Glyphs and characters
9673
97−Hoon is a heavy punctuation user. To aid pronunciation,
98−we've mapped each punctuation glyph to a syllable:
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:
9981
10082```
10183ace [1 space] gal < pal (
@@ -112,28 +94,60 @@ fas / pat @ wut ?
11294zap !
11395```
11496
115−You don't need to memorize these glyph names, but it helps. Code
116−is often vocalized or subvocalized. "pal" is easier to say,
117−aloud or silently, then "left paren."
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".
118100
119101Note that the list includes two separate whitespace forms: `ace`
120−for a single space, `gap` for 2+, comment or newline. In Hoon,
102+for a single space, `gap` for 2+, comment, and newline. In Hoon,
121103the only significance in whitespace is the difference between
122−`ace` and `gap`.
104+`ace` and `gap`. Comments start with `::` and run to the end of
105+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](https://urbit.org/docs/about/glossary#rune). A rune is a pair
115+of ASCII punctuation marks (a digraph)—e.g., `:-`. The first
116+glyph in the rune indicates the category—e.g., `:` runes make
117+[cells](https://urbit.org/docs/about/glossary#cell) (i.e., ordered
118+pairs). We pronounce runes using their glyph names—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.
123+
124+```
125+:-
126+ 25
127+3
128+```
123129
124−Comments start with `::` and run to the end of the line. Hard
125−tab characters are illegal, and an 80-column right margin is
126−strongly encouraged. Really well-groomed Hoon uses a 55-column
127−code margin and puts a standard line comment at column 57.
130+This twig uses `:-` to produce a cell: `[25 3]`. There are always two
131+subexpressions following the `:-` in syntactically correct Hoon code,
132+the first of which, when evaluated, becomes the *head* (i.e., the left)
133+and the second of which becomes the *tail* (i.e., the right).
128134
129−Hoon does not accept non-ASCII text in source files, except UTF-8
130−in quoted strings.
135+Hoon expressions are sometimes called
136+[twigs](https://urbit.org/docs/about/glossary#twig). You'll find that
137+Hoon code has a tree-like structure, so you can think of the various
138+expressions as twigs of this tree. The subexpressions following the
139+rune are sometimes called the *children* of that twig.
131140
132141## Tall and flat forms
133142
134143There are two kinds of Hoon expression syntax: *tall* and *flat*.
135−Most stems have both tall and flat forms. Tall twigs can contain
136−flat twigs, but not vice versa.
144+Most runes can be used in both tall and flat twigs. Tall twigs can
145+contain flat twigs, 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)`
137151
138152Visually, a tall twig looks like a "statement" and a flat twig
139153like an "expression," preserving the attractive visual shape of
@@ -141,47 +155,52 @@ procedural code without the nasty side effects.
141155
142156## Regular and irregular forms
143157
144−Most stems have *regular forms*, which share a common design.
145−There is a regular flat form and a regular tall form; most stems
146−implement both. All tall forms are regular.
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.
147161
148−Some twigs also have *irregular forms*, which follow no
162+Some runes also have *irregular forms*, which follow no
149163principles at all. All irregular forms are flat.
150164
151−Some twigs have *only* irregular forms.
165+```
166+.=
167+ 22
168+23
169+```
152170
153−## Runes
171+The `.=` rune tests for equality the two subexpressions that
172+follow, and returns a boolean. Above is the tall, regular form of
173+`.=`. Below is the irregular form:
154174
155−As mentioned earlier, a regular form starts with a
156−[rune](https://urbit.org/docs/about/glossary#rune).
175+`=(22 23)`
157176
158−A *rune* is a pair of ASCII punctuation marks (a digraph)—e.g.,
159−`:-`. The first glyph in the rune indicates the category—e.g.,
160−`:` runes make cells. Runes can be pronounced by their glyphs—
161−for `:-`, you say "colhep".
177+Some twigs have *only* irregular forms.
162178
163179## Tall regular form
164180
165−Tall regular form starts with the rune, followed by a `gap`
166−(any whitespace except `ace`). After this is a
167−*[bulb](https://urbit.org/docs/about/glossary#bulb)*—which
168−defines the types of content the twig can have—whose own twigs
169−are separated by `gap`.
170−
171−There are four body subtypes: *fixed*, *running*, *jogging*, and
172−*battery*. Stems with a *fixed* number of subexpressions
173−self-terminate. For instance, `?:` has three subexpressions and
174−is self-terminating. Otherwise the twig is terminated by a
175−`gap`, then either `==` (*running* or *jogging*, most twigs) or
181+Tall regular form starts with the rune, followed by a `gap`.
182+(Remember, a `gap` is any whitespace except `ace`, including
183+either comments or line breaks.). After that are the number and
184+types of subexpressions appropriate for that rune. Each
185+subexpression is separated from the others by a `gap`.
186+
187+Let's call everything in the twig after the initial rune the twig
188+*body*. There are four body subtypes: *fixed*, *running*, *jogging*,
189+and *[battery](https://urbit.org/docs/about/glossary#battery)*.
190+Runes with a *fixed* number of subexpressions self-terminate.
191+For instance, the `:-` and `.=` runes each have two subexpressions
192+and are self-terminating. Otherwise the twig is terminated by both
193+a `gap`, then either `==` (*running* or *jogging*, most twigs) or
176194`--` (*battery*).
177195
178−The *running* body is a list of twigs. The *jogging* body is a
179−list of twig pairs, separated by a `gap`. The *battery* body is
180−a list of symbol-twig pairs, separated by a gap, prefixed by `++`
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 is separated by a `gap`. The *battery* body is
199+a list of symbol-child pairs, separated by a gap, prefixed by `++`
181200and then a gap.
182201
183−This definition is enough to parse. But the proper shape of the
184−whitespace gaps demands an informal convention.
202+This definition is enough to write Hoon that will parse. But the
203+proper shape of the whitespace gaps rquiress an informal convention.
185204
186205Whitespace design in Hoon is an art, not a science. It involves
187206both tall/flat mode switches and well-shaped gaps. (Hoon layout
@@ -190,15 +209,15 @@ But it would at least take machine learning, not a rule engine.)
190209
191210There are only two real *rules* in Hoon whitespace design: don't
192211go past 80 characters, and don't use (completely) blank lines.
193−Otherwise, if it looks good and is easy to read, it's good. But
194−the best way to learn the art is to do everything by convention
212+Otherwise, if it looks good and is easy to read, it's good. The
213+best way to learn the art is to do everything by convention
195214until you know what you're doing. Here are the conventions:
196215
197216### Conventions: *fixed*
198217
199−Bulbs with *fixed* fanout use "backstep" indentation, which slopes
200−backward and to the right by two spaces per line. The first
201−child is two spaces after the end of the sigil.
218+Twig bodies with *fixed* fanout use "backstep" indentation, which
219+slopes backward and to the right by two spaces per line. The first
220+twig child is two spaces after the end of the rune.
202221
203222Some *1-fixed*, *2-fixed*, *3-fixed* and *4-fixed* examples:
204223
@@ -219,15 +238,14 @@ r
219238s
220239```
221240
222−The hope of backstep indentation is that the heaviest twigs are
223−at the bottom, keeping code flow vertical rather than diagonal.
224−
241+In optimal usage of backstep indentation, the most complicated twigs
242+are at the bottom, keeping code flow vertical rather than diagonal.
225243
226244### Conventions: *running*
227245
228−A *running* bulb (a simple child list) puts the first child two
229−spaces after the end of the sigil, and the following children
230−straight down:
246+A *running* twig body (a simple child list) puts the first child two
247+spaces after the end of the rune, and the following children straight
248+down:
231249
232250A *running* example:
233251
@@ -242,10 +260,11 @@ A *running* example:
242260
243261### Conventions: *jogging*
244262
245−A *jogging* bulb (a list of child pairs) is like a running bulb,
246−but backsteps the head of the pair above the tail. Most jogging
247−twigs start with a *fixed* sequence; the first jogging pair is
248−below and two steps backward from the last fixed child.
263+A *jogging* twig body (a list of child pairs) is like a running
264+body, but with a pair of children on each line, separated by
265+two spaces. Most jogging bodies start with a *fixed* sequence;
266+the first jogging pair is below and two steps backward from the
267+last fixed child.
249268
250269There are two jogging conventions: *flat* (pair on one line) and
251270*tall* (pair split across lines).
@@ -275,7 +294,7 @@ A *tall jogging* example (preceded by *1-fixed* `p`):
275294
276295### Conventions: *battery*
277296
278−A *battery* bulb is a list of symbol-twig pairs, for the
297+A *battery* body has a list of symbol-child pairs, for the
279298*[battery](https://urbit.org/docs/about/glossary#battery)*
280299of a
281300*[core](https://urbit.org/docs/about/glossary#core)*. A
@@ -294,24 +313,20 @@ conventional example:
294313
295314## Flat regular form
296315
297−Flat regular form starts with the rune, followed by `pal`
298−(`(`, left parenthesis), followed by a bulb whose subexpressions
299−are separated by `ace` (one space), followed by `par` (`)`, right
316+Flat regular form starts with the rune, followed by `pal`, `(`
317+(left parenthesis), followed by a body whose subexpressions
318+are separated by `ace` (one space), followed by `par`, `)` (right
300319parenthesis).
301320
302321A twig in flat form, `:if`, `?:`, `{$if p/twig q/twig r/twig}`:
303322
304−```
305−:if(p q r)
306−
307−?:(p q r)
308−```
323+`?:(p q r)`
309324
310325The only exception is *jogging* bodies, in which subexpression
311326pairs are separated by commas:
312327
313328```
314−:make(foo bar 42, baz 55, moo 17)
329+foo(bar 42, baz 55, moo 17)
315330```
316331
317332There is no flat regular form for *battery* bodies. Be tall.
@@ -340,11 +355,11 @@ appropriate.
340355
341356In the *ultralapidary* naming style, labels are single letters,
342357starting in order of construction from `a`, or within a tuple
343−mold `p`. Hoon uses single-letter names for the same reason
344−Algol style languages pass arguments by order, rather than
345−keyword. Naming items by order makes sense when there are no
346−more than three or four; five is stretching it; six is outright
347−ridiculous.
358+[mold](https://urbit.org/docs/about/glossary#mold) `p`. Hoon
359+uses single-letter names for the same reason Algol style
360+languages pass arguments by order, rather than keyword. Naming
361+items by order makes sense when there are no more than three or
362+four; five is stretching it; six is outright ridiculous.
348363
349364For example, when defining `add`, we want to name the operands
350365`a` and `b`. It's silly to call them `foo` and `bar`, let alone