@@ -7,22 +7,19 @@ title: Syntax
8# Hoon syntax
8# Hoon syntax
10−Hoon's semantics are simple, but unusual. Hoon's syntax is
10+Hoon's syntax is unusual, and to beginners it can look a lot more
11−complex, and unusual. Sorry.
11+complex than it really is. However, we believe that anyone who
12+learns Hoon syntax will find that it has a number of advantages.
13# Motivation
14# Motivation
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.
19−An explanation: the Hoon syntax is trying to solve three serious
16+Hoon syntax is trying to solve three serious
20problems in functional syntax design. These are *terminator
17problems in functional syntax design. These are *terminator
21piles*, *indentation creep*, and *feature/label confusion*.
18piles*, *indentation creep*, and *feature/label confusion*.
23## Terminator piles
20## Terminator piles
25−*Terminator piles* are like Lisp's stacks of right parentheses.
22+*Terminator piles* are like Lisp's stacks of right parentheses.
26Significant whitespace solves this problem and creates others.
23Significant whitespace solves this problem and creates others.
28Hoon has no terminator piles. Except for a 1-space / more-space
25Hoon has no terminator piles. Except for a 1-space / more-space
@@ -32,8 +29,9 @@ distinction, it has no significant whitespace.
33*Indentation creep* is a problem caused by indentation conventions
30*Indentation creep* is a problem caused by indentation conventions
34where the indentation point is a function of expression tree
31where the indentation point is a function of expression tree
32+depth. This problem is especially irritating when working with
35−depth. It's true that short functions are better than long ones,
33+long functions. It's true that short functions are better, but
36−but long ones sometimes need to be written.
34+long ones sometimes need to be written.
38A procedural block has a backbone of statements which flows
36A procedural block has a backbone of statements which flows
39straight down. Most expressions are flat and of limited depth.
37straight down. Most expressions are flat and of limited depth.
@@ -49,53 +47,37 @@ shaped more or less like procedural programs.
50## Feature/label confusion
48## Feature/label confusion
52−*Feature/label confusion* is any syntax which makes it hard for
50+*Feature/label confusion* (FLC) is any syntax which makes it hard
53−the eye to tell whether a token on the screen is a feature of the
51+for the eye to tell whether a token on the screen is a feature of
54−language, or a label in the program. For example, in Lisp a
52+the language, or a label in the program. For example, in Lisp a
55special form has the same syntax as a function call.
53special form has the same syntax as a function call.
57The worst-case result of FLC is "DSL cancer." Every source file
55The worst-case result of FLC is "DSL cancer." Every source file
58is effectively written in its own domain-specific language. To
56is effectively written in its own domain-specific language. To
59read a new file is to learn a new language—"write-only code."
57read a new file is to learn a new language—"write-only code."
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,
59+User-level macros, operator overloading, even excessive use of
65−can all lead quickly to the tragedy of write-only code.
60+higher-order programming, can all lead quickly to the tragedy of
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
63+Hoon has no FLC, user-level macros, or overloading. It does
69−higher-order programming; write-only Hoon can certainly be
64+support higher-order programming; write-only Hoon can certainly be
70(and has been) written. But good Hoon style is to avoid it.
65(and has been) written. But good Hoon style is to avoid it.
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.:
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.
92Hoon has a general syntax design with common principles and
69Hoon has a general syntax design with common principles and
93regularities. We'll cover those here.
70regularities. We'll cover those here.
95## Glyphs and characters
72## Glyphs and characters
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.
97−Hoon is a heavy punctuation user. To aid pronunciation,
78+Hoon is a heavy punctuation user. Reading off code aloud
79+using the proper names of ASCII symbols is tedious, so we've
98−we've mapped each punctuation glyph to a syllable:
80+mapped each punctuation glyph to a syllable:
101ace [1 space] gal < pal (
83ace [1 space] gal < pal (
@@ -112,28 +94,60 @@ fas / pat @ wut ?
115−You don't need to memorize these glyph names, but it helps. Code
97+You don't need to memorize these glyph names, but it might help.
116−is often vocalized or subvocalized. "pal" is easier to say,
98+Code is often vocalized or subvocalized. "pal" is easier to say,
117−aloud or silently, then "left paren."
99+aloud or silently, than "left paren".
119Note that the list includes two separate whitespace forms: `ace`
101Note 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,
121the only significance in whitespace is the difference between
103the 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
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.
111+## Expressions and Runes
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 `:-`,
121+Each rune is followed by one or more subexpressions. The number and
122+kind of subexpressions depend on the rune.
124−Comments start with `::` and run to the end of the line. Hard
130+This twig uses `:-` to produce a cell: `[25 3]`. There are always two
125−tab characters are illegal, and an 80-column right margin is
131+subexpressions following the `:-` in syntactically correct Hoon code,
126−strongly encouraged. Really well-groomed Hoon uses a 55-column
132+the first of which, when evaluated, becomes the *head* (i.e., the left)
127−code margin and puts a standard line comment at column 57.
133+and the second of which becomes the *tail* (i.e., the right).
129−Hoon does not accept non-ASCII text in source files, except UTF-8
135+Hoon expressions are sometimes called
130−in quoted strings.
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.
132## Tall and flat forms
141## Tall and flat forms
134There are two kinds of Hoon expression syntax: *tall* and *flat*.
143There are two kinds of Hoon expression syntax: *tall* and *flat*.
135−Most stems have both tall and flat forms. Tall twigs can contain
144+Most runes can be used in both tall and flat twigs. Tall twigs can
136−flat twigs, but not vice versa.
145+contain flat twigs, but not vice versa.
147+The `:-` expression in the last subsection was in tall form. Here's
138Visually, a tall twig looks like a "statement" and a flat twig
152Visually, a tall twig looks like a "statement" and a flat twig
139like an "expression," preserving the attractive visual shape of
153like an "expression," preserving the attractive visual shape of
@@ -141,47 +155,52 @@ procedural code without the nasty side effects.
142## Regular and irregular forms
156## Regular and irregular forms
144−Most stems have *regular forms*, which share a common design.
158+Most runes have *regular forms*, which share a common design.
145−There is a regular flat form and a regular tall form; most stems
159+There is a regular flat form and a regular tall form; most runes
146−implement both. All tall forms are regular.
160+have both kinds of implementation. All tall forms are regular.
148−Some twigs also have *irregular forms*, which follow no
162+Some runes also have *irregular forms*, which follow no
149principles at all. All irregular forms are flat.
163principles at all. All irregular forms are flat.
151−Some twigs have *only* irregular forms.
165+```
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:
155−As mentioned earlier, a regular form starts with a
175+`=(22 23)`
156−[rune](https://urbit.org/docs/about/glossary#rune).
158−A *rune* is a pair of ASCII punctuation marks (a digraph)—e.g.,
177+Some twigs have *only* irregular forms.
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".
163## Tall regular form
179## Tall regular form
165−Tall regular form starts with the rune, followed by a `gap`
181+Tall regular form starts with the rune, followed by a `gap`.
166−(any whitespace except `ace`). After this is a
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`.
187+Let's call everything in the twig after the initial rune the twig
188+*body*. There are four body subtypes: *fixed*, *running*, *jogging*,
167−*[bulb](https://urbit.org/docs/about/glossary#bulb)*—which
189+and *[battery](https://urbit.org/docs/about/glossary#battery)*.
168−defines the types of content the twig can have—whose own twigs
169−are separated by `gap`.
171−There are four body subtypes: *fixed*, *running*, *jogging*, and
172−*battery*. Stems with a *fixed* number of subexpressions
190+Runes with a *fixed* number of subexpressions self-terminate.
173−self-terminate. For instance, `?:` has three subexpressions and
191+For instance, the `:-` and `.=` runes each have two subexpressions
174−is self-terminating. Otherwise the twig is terminated by a
192+and are self-terminating. Otherwise the twig is terminated by both
175−`gap`, then either `==` (*running* or *jogging*, most twigs) or
193+a `gap`, then either `==` (*running* or *jogging*, most twigs) or
176`--` (*battery*).
194`--` (*battery*).
178−The *running* body is a list of twigs. The *jogging* body is a
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
179−list of twig pairs, separated by a `gap`. The *battery* body is
198+each pair is separated by a `gap`. The *battery* body is
180−a list of symbol-twig pairs, separated by a gap, prefixed by `++`
199+a list of symbol-child pairs, separated by a gap, prefixed by `++`
181and then a gap.
200and then a gap.
183−This definition is enough to parse. But the proper shape of the
202+This definition is enough to write Hoon that will parse. But the
184−whitespace gaps demands an informal convention.
203+proper shape of the whitespace gaps rquiress an informal convention.
186Whitespace design in Hoon is an art, not a science. It involves
205Whitespace design in Hoon is an art, not a science. It involves
187both tall/flat mode switches and well-shaped gaps. (Hoon layout
206both 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.)
191There are only two real *rules* in Hoon whitespace design: don't
210There are only two real *rules* in Hoon whitespace design: don't
192go past 80 characters, and don't use (completely) blank lines.
211go 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
212+Otherwise, if it looks good and is easy to read, it's good. The
194−the best way to learn the art is to do everything by convention
213+best way to learn the art is to do everything by convention
195until you know what you're doing. Here are the conventions:
214until you know what you're doing. Here are the conventions:
197### Conventions: *fixed*
216### Conventions: *fixed*
199−Bulbs with *fixed* fanout use "backstep" indentation, which slopes
218+Twig bodies with *fixed* fanout use "backstep" indentation, which
200−backward and to the right by two spaces per line. The first
219+slopes backward and to the right by two spaces per line. The first
201−child is two spaces after the end of the sigil.
220+twig child is two spaces after the end of the rune.
203Some *1-fixed*, *2-fixed*, *3-fixed* and *4-fixed* examples:
222Some *1-fixed*, *2-fixed*, *3-fixed* and *4-fixed* examples:
@@ -219,15 +238,14 @@ r
222−The hope of backstep indentation is that the heaviest twigs are
241+In optimal usage of backstep indentation, the most complicated twigs
223−at the bottom, keeping code flow vertical rather than diagonal.
242+are at the bottom, keeping code flow vertical rather than diagonal.
226### Conventions: *running*
244### Conventions: *running*
228−A *running* bulb (a simple child list) puts the first child two
246+A *running* twig body (a simple child list) puts the first child two
229−spaces after the end of the sigil, and the following children
247+spaces after the end of the rune, and the following children straight
230−straight down:
248+down:
232A *running* example:
250A *running* example:
@@ -242,10 +260,11 @@ A *running* example:
243### Conventions: *jogging*
261### Conventions: *jogging*
245−A *jogging* bulb (a list of child pairs) is like a running bulb,
263+A *jogging* twig body (a list of child pairs) is like a running
246−but backsteps the head of the pair above the tail. Most jogging
264+body, but with a pair of children on each line, separated by
247−twigs start with a *fixed* sequence; the first jogging pair is
265+two spaces. Most jogging bodies start with a *fixed* sequence;
248−below and two steps backward from the last fixed child.
266+the first jogging pair is below and two steps backward from the
250There are two jogging conventions: *flat* (pair on one line) and
269There are two jogging conventions: *flat* (pair on one line) and
251*tall* (pair split across lines).
270*tall* (pair split across lines).
@@ -275,7 +294,7 @@ A *tall jogging* example (preceded by *1-fixed* `p`):
276### Conventions: *battery*
295### Conventions: *battery*
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
279*[battery](https://urbit.org/docs/about/glossary#battery)*
298*[battery](https://urbit.org/docs/about/glossary#battery)*
281*[core](https://urbit.org/docs/about/glossary#core)*. A
300*[core](https://urbit.org/docs/about/glossary#core)*. A
@@ -294,24 +313,20 @@ conventional example:
295## Flat regular form
314## Flat regular form
297−Flat regular form starts with the rune, followed by `pal`
316+Flat regular form starts with the rune, followed by `pal`, `(`
298−(`(`, left parenthesis), followed by a bulb whose subexpressions
317+(left parenthesis), followed by a body whose subexpressions
299−are separated by `ace` (one space), followed by `par` (`)`, right
318+are separated by `ace` (one space), followed by `par`, `)` (right
300parenthesis).
319parenthesis).
302A twig in flat form, `:if`, `?:`, `{$if p/twig q/twig r/twig}`:
321A twig in flat form, `:if`, `?:`, `{$if p/twig q/twig r/twig}`:
307−?:(p q r)
323+`?:(p q r)`
310The only exception is *jogging* bodies, in which subexpression
325The only exception is *jogging* bodies, in which subexpression
311pairs are separated by commas:
326pairs are separated by commas:
314−:make(foo bar 42, baz 55, moo 17)
329+foo(bar 42, baz 55, moo 17)
317There is no flat regular form for *battery* bodies. Be tall.
332There is no flat regular form for *battery* bodies. Be tall.
@@ -340,11 +355,11 @@ appropriate.
341In the *ultralapidary* naming style, labels are single letters,
356In the *ultralapidary* naming style, labels are single letters,
342starting in order of construction from `a`, or within a tuple
357starting in order of construction from `a`, or within a tuple
358+[mold](https://urbit.org/docs/about/glossary#mold) `p`. Hoon
343−mold `p`. Hoon uses single-letter names for the same reason
359+uses single-letter names for the same reason Algol style
344−Algol style languages pass arguments by order, rather than
360+languages pass arguments by order, rather than keyword. Naming
345−keyword. Naming items by order makes sense when there are no
361+items by order makes sense when there are no more than three or
346−more than three or four; five is stretching it; six is outright
362+four; five is stretching it; six is outright ridiculous.
349For example, when defining `add`, we want to name the operands
364For example, when defining `add`, we want to name the operands
350`a` and `b`. It's silly to call them `foo` and `bar`, let alone
365`a` and `b`. It's silly to call them `foo` and `bar`, let alone