on master help sign in
Merge pull request #205 from joshuareagan/patch-12
58b9f06Fang
docs/hoon/syntax.md+134−125
@@ -7,22 +7,19 @@ title: Syntax
7
7
8# Hoon syntax
8# Hoon syntax
9
9
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.
12
13
13# Motivation
14# Motivation
14
15
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
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*.
22
19
23## Terminator piles
20## Terminator piles
24
21
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.
27
24
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.
32
29
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.
37
35
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,38 +47,37 @@ shaped more or less like procedural programs.
49
47
50## Feature/label confusion
48## Feature/label confusion
51
49
52−*Feature/label confusion* is any syntax which makes it hard for
50+*Feature/label confusion* (FLC) is the result of any syntax that
53−the eye to tell whether a token on the screen is a feature of the
51+makes it hard for the eye to tell whether a token on the screen is
54−language, or a label in the program. For example, in Lisp a
52+a feature of the language, or a label in the program. For example,
55−special form has the same syntax as a function call.
53+in Lisp a special form has the same syntax as a function call.
56
54
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
59−read a new file is to learn a new language -- "write-only code."
57+read a new file is to learn a new language—"write-only code."
60
58
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
61+write-only code.
66
62
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.
71
66
72# Design
67# Design
73
68
74−Because each twig stem has its own bulb, each has its own parser
75−rule. We'll describe these grammars as we go through the stems.
76−
77−But Hoon has a general syntax design with common principles and
69+Hoon has a general syntax design with common principles and
78regularities. We'll cover those here.
70regularities. We'll cover those here.
79
71
80## Glyphs and characters
72## Glyphs and characters
81
73
74+Hoon source uses ASCII text. Hoon does not accept non-ASCII
75+text in source files, except UTF-8 in quoted strings. Hard
76+tab characters are illegal.
77+
82−Hoon is a heavy punctuation user. To make ASCII great again,
78+Hoon is a heavy punctuation user. Reading off code aloud
79+using the proper names of ASCII symbols is tedious, so we've
83−we've mapped each punctuation glyph to a syllable:
80+mapped each punctuation glyph to a syllable:
84
81
85```
82```
86ace [1 space] gal < pal (
83ace [1 space] gal < pal (
@@ -97,28 +94,59 @@ fas / pat @ wut ?
97zap !
94zap !
98```
95```
99
96
100−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.
101−is often vocalized or subvocalized. "pal" is easier to say,
98+Code is often vocalized or subvocalized. "pal" is easier to say,
102−aloud or silently, then "left paren."
99+aloud or silently, than "left paren".
103
100
104Note that the list includes two separate whitespace forms: `ace`
101Note that the list includes two separate whitespace forms: `ace`
105−for a single space, `gap` for 2+, comment or newline. In Hoon,
102+for a single space; `gap` is either 2+ spaces or a newline. In Hoon,
106the only significance in whitespace is the difference between
103the only significance in whitespace is the difference between
107−`ace` and `gap`.
104+`ace` and `gap`. Comments also count as `gap` whitespace&mdash;they
105+start with `::` and run to the end of the line.
106+
107+An 80-column right margin is strongly encouraged. Really
108+well-groomed Hoon uses a 55-column code margin and puts a standard
109+line comment at column 57.
108
110
109−Comments start with `::` and run to the end of the line. Hard
111+## Expressions and Runes
110−tab characters are illegal, and an 80-column right margin is
111−strongly encouraged. Really well-groomed Hoon uses a 55-column
112−code margin and puts a standard line comment at column 57.
113
112
114−Hoon does not accept non-ASCII text in source files, except UTF-8
113+Each regular Hoon expression begins with a
115−in quoted strings.
114+[rune](https://urbit.org/docs/about/glossary#rune). A rune is a pair
115+of ASCII punctuation marks (a digraph)&mdash;e.g., `:-`. The first
116+glyph in the rune indicates the category&mdash;e.g., `:` runes make
117+[cells](https://urbit.org/docs/about/glossary#cell) (i.e., ordered
118+pairs). We pronounce runes using their glyph names&mdash;for `:-`,
119+we say "colhep".
120+
121+Each rune is followed by one or more subexpressions. The number and
122+kind of subexpressions depend on the rune used.
123+
124+```
125+:- 25
126+3
127+```
128+
129+This twig uses `:-` to produce a cell: `[25 3]`. There are always two
130+subexpressions following the `:-` in syntactically correct Hoon code,
131+the first of which, when evaluated, becomes the *head* (i.e., the left)
132+and the second of which becomes the *tail* (i.e., the right).
133+
134+Hoon expressions are sometimes called
135+[twigs](https://urbit.org/docs/about/glossary#twig). You'll find that
136+Hoon code has a tree-like structure, so you can think of the various
137+expressions as twigs of the tree. The subexpressions following the
138+rune are sometimes called the *children* of that twig.
116
139
117## Tall and flat forms
140## Tall and flat forms
118
141
119There are two kinds of Hoon expression syntax: *tall* and *flat*.
142There are two kinds of Hoon expression syntax: *tall* and *flat*.
120−Most stems have both tall and flat forms. Tall twigs can contain
143+Most runes can be used in both tall and flat twigs. Tall twigs can
121−flat twigs, but not vice versa.
144+contain flat twigs, but not vice versa.
145+
146+The `:-` expression in the last subsection was in tall form. Here's
147+the flat equivalent:
148+
149+`:-(25 3)`
122
150
123Visually, a tall twig looks like a "statement" and a flat twig
151Visually, a tall twig looks like a "statement" and a flat twig
124like an "expression," preserving the attractive visual shape of
152like an "expression," preserving the attractive visual shape of
@@ -126,71 +154,53 @@ procedural code without the nasty side effects.
126
154
127## Regular and irregular forms
155## Regular and irregular forms
128
156
129−Most stems have *regular forms*, which share a common design.
157+Most runes have *regular forms*, which share a common design.
130−There is a regular flat form and a regular tall form; most stems
158+There is a regular flat form and a regular tall form; most runes
131−implement both. All tall forms are regular.
159+have both kinds of implementation. All tall forms are regular.
132
160
133−Some twigs also have *irregular forms*, which follow no
161+Some runes also have *irregular forms*, which follow no
134principles at all. All irregular forms are flat.
162principles at all. All irregular forms are flat.
135
163
136−Some twigs (simple leafy ones) have *only* irregular forms.
164+```
137−
165+.= 22
138−## Keywords versus runes
166+23
139−
167+```
140−A regular form starts with a *sigil*, which is either a
141−*keyword* or a *rune* -- at the programmer's choice.
142−
143−A *keyword* is `:` and then the stem label - e.g., `:cons`.
144−
145−A *rune* is a pair of ASCII punctuation marks (a digraph) - e.g.,
146−`:-`. The first glyph in the rune indicates the category - e.g.,
147−`:` runes make cells. Runes can be pronounced by their glyphs or
148−by their stem -- for `:-`, you can say either "colhep" or "cons".
149
168
150−Keywords may be less challenging for early learners. Rune style
169+The `.=` rune tests for equality the two subexpressions that
151−is less cluttered and distracting for experienced programmers;
170+follow, and returns a boolean. Above is the tall, regular form of
152−the system codebase is all in rune style. Beginners can start
171+`.=`. Below is the irregular form:
153−with keywords and move to runes; start with runes and stick
154−with runes; or start with keywords and stick with keywords.
155
172
156−Here's the FizzBuzz demo code, in idiomatic rune syntax. Compare
173+`=(22 23)`
157−with the [original](../demo).
158
174
159−```
175+Some twigs have *only* irregular forms.
160− |= end/atom
161− =/ count 1
162− |- ^- (list tape)
163− ?: =(end count) ~
164− :_ $(count (add 1 count))
165− ?: =(0 (mod count 15))
166− "FizzBuzz"
167− ?: =(0 (mod count 5))
168− "Fizz"
169− ?: =(0 (mod count 3))
170− "Buzz"
171− (pave !>(count))
172−```
173
176
174## Tall regular form
177## Tall regular form
175
178
176−Tall regular form starts with the sigil, followed by a `gap`
179+Tall regular forms start with a rune followed by a `gap`.
177−(any whitespace except `ace`), followed by a bulb whose twigs are
180+(Remember, a `gap` is any whitespace other than `ace`.) After
178−separated by `gap`.
181+that are the number and types of subexpressions appropriate for
182+that rune. Each subexpression is separated from its neighboring
183+subexpressions by a `gap`.
184+
185+Let's call everything in the twig after the initial rune the twig
186+*body*. There are four body subtypes: *fixed*, *running*, *jogging*,
187+and *[battery](https://urbit.org/docs/about/glossary#battery)*.
179
188
180−There are four body subtypes: *fixed*, *running*, *jogging*, and
181−*battery*. Stems with a *fixed* number of subexpressions
189+Runes with a *fixed* number of subexpressions self-terminate. For
182−self-terminate. For instance, `:if` has three subexpressions and
190+instance, the `:-` and `.=` runes each have two subexpressions
183−is self-terminating. Otherwise the twig is terminated by a
191+and are self-terminating. Otherwise the twig is terminated by both
184−`gap`, then either `==` (*running* or *jogging*, most twigs) or
192+a `gap`, then either `==` (*running* or *jogging*, most twigs) or
185`--` (*battery*).
193`--` (*battery*).
186
194
187−The *running* body is a list of twigs. The *jogging* body is a
195+The *running* body has a list of *children* (i.e., subexpressions).
196+The *jogging* body has a list of child pairs, where the members of
188−list of twig pairs, separated by a `gap`. The *battery* body is
197+each pair are separated by a `gap`. The *battery* body is
189−a list of symbol-twig pairs, separated by a gap, prefixed by `++`
198+a list of symbol-child pairs, separated by a gap, prefixed by `++`
190and then a gap.
199and then a gap.
191
200
192−This definition is enough to parse. But the proper shape of the
201+This definition is enough to write Hoon that will parse. But
193−whitespace gaps demands an informal convention.
202+writing code with optimal whitespace management requires some
203+additional informal conventions.
194
204
195Whitespace design in Hoon is an art, not a science. It involves
205Whitespace design in Hoon is an art, not a science. It involves
196both tall/flat mode switches and well-shaped gaps. (Hoon layout
206both tall/flat mode switches and well-shaped gaps. (Hoon layout
@@ -199,15 +209,15 @@ But it would at least take machine learning, not a rule engine.)
199
209
200There are only two real *rules* in Hoon whitespace design: don't
210There are only two real *rules* in Hoon whitespace design: don't
201go past 80 characters, and don't use (completely) blank lines.
211go past 80 characters, and don't use (completely) blank lines.
202−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
203−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
204until you know what you're doing. Here are the conventions:
214until you know what you're doing. Here are the conventions:
205
215
206### Conventions: *fixed*
216### Conventions: *fixed*
207
217
208−Bulbs with *fixed* fanout use "backstep" indentation, which slopes
218+Twig bodies with *fixed* fanout use "backstep" indentation, which
209−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
210−child is two spaces after the end of the sigil.
220+twig child is two spaces after the end of the rune.
211
221
212Some *1-fixed*, *2-fixed*, *3-fixed* and *4-fixed* examples:
222Some *1-fixed*, *2-fixed*, *3-fixed* and *4-fixed* examples:
213
223
@@ -228,15 +238,14 @@ r
228s
238s
229```
239```
230
240
231−The hope of backstep indentation is that the heaviest twigs are
241+In optimal usage of backstep indentation, the most complicated twigs
232−at the bottom, keeping code flow vertical rather than diagonal.
242+are at the bottom, keeping code flow vertical rather than diagonal.
233−
234
243
235### Conventions: *running*
244### Conventions: *running*
236
245
237−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
238−spaces after the end of the sigil, and the following children
247+spaces after the end of the rune, and the following children straight
239−straight down:
248+down:
240
249
241A *running* example:
250A *running* example:
242
251
@@ -251,10 +260,11 @@ A *running* example:
251
260
252### Conventions: *jogging*
261### Conventions: *jogging*
253
262
254−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
255−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
256−twigs start with a *fixed* sequence; the first jogging pair is
265+two spaces. Most jogging bodies start with a *fixed* sequence;
257−below and two steps backward from the last fixed child.
266+the first jogging pair is below and two steps backward from the
267+last fixed child.
258
268
259There are two jogging conventions: *flat* (pair on one line) and
269There are two jogging conventions: *flat* (pair on one line) and
260*tall* (pair split across lines).
270*tall* (pair split across lines).
@@ -284,8 +294,11 @@ A *tall jogging* example (preceded by *1-fixed* `p`):
284
294
285### Conventions: *battery*
295### Conventions: *battery*
286
296
287−A *battery* bulb is a list of symbol-twig pairs, for the battery
297+A *battery* body has a list of symbol-child pairs, for the
298+[battery](https://urbit.org/docs/about/glossary#battery)
299+of a
300+[core](https://urbit.org/docs/about/glossary#core). A
288−of a core. A conventional example:
301+conventional example:
289
302
290```
303```
291|%
304|%
@@ -300,24 +313,20 @@ of a core. A conventional example:
300
313
301## Flat regular form
314## Flat regular form
302
315
303−Flat regular form starts with the sigil, followed by `pal`
316+Flat regular form starts with the rune, followed by `pal`, `(`
304−(`(`, left parenthesis), followed by a bulb whose subexpressions
317+(left parenthesis), followed by a body whose subexpressions
305−are separated by `ace` (one space), followed by `par` (`)`, right
318+are separated by `ace` (one space), followed by `par`, `)` (right
306parenthesis).
319parenthesis).
307
320
308A 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}`:
309
322
310−```
311−:if(p q r)
312−
313−?:(p q r)
323+`?:(p q r)`
314−```
315
324
316The only exception is *jogging* bodies, in which subexpression
325The only exception is *jogging* bodies, in which subexpression
317pairs are separated by commas:
326pairs are separated by commas:
318
327
319```
328```
320−:make(foo bar 42, baz 55, moo 17)
329+foo(bar 42, baz 55, moo 17)
321```
330```
322
331
323There is no flat regular form for *battery* bodies. Be tall.
332There is no flat regular form for *battery* bodies. Be tall.
@@ -326,7 +335,7 @@ There is no flat regular form for *battery* bodies. Be tall.
326
335
327Hoon does not enforce any rule on symbols, except that capitals
336Hoon does not enforce any rule on symbols, except that capitals
328are not allowed (use kebab-case). However, a lot of system code
337are not allowed (use kebab-case). However, a lot of system code
329−is written in using "lapidary" conventions that need explanation.
338+is written using "lapidary" conventions that need explanation.
330
339
331Naming things is one of the hard problems in CS. Dodging this
340Naming things is one of the hard problems in CS. Dodging this
332problem is one of the reasons mathematicians use Greek letters,
341problem is one of the reasons mathematicians use Greek letters,
@@ -346,11 +355,11 @@ appropriate.
346
355
347In the *ultralapidary* naming style, labels are single letters,
356In the *ultralapidary* naming style, labels are single letters,
348starting 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
349−mold `p`. Hoon uses single-letter names for the same reason
359+uses single-letter names for the same reason Algol style
350−Algol style languages pass arguments by order, rather than
360+languages pass arguments by order, rather than keyword. Naming
351−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
352−more than three or four; five is stretching it; six is outright
362+four; five is stretching it; six is outright ridiculous.
353−ridiculous.
354
363
355For example, when defining `add`, we want to name the operands
364For example, when defining `add`, we want to name the operands
356`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