on master help sign in
Merge pull request #205 from joshuareagan/patch-12

Partial Rewrite of Hoon Syntax doc

commit58b9f062d064fd4306212c294a241dabf65cd52f authorFang <Fang-@users.noreply.github.com> dateFri 6 Oct 2017, 21:57 (9 years ago) parent489a77a5e6a713
1 file changed+134−125
docs/hoon/syntax.md+134−125
docs/hoon/syntax.md+134−125
@@ -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,38 +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
55−special form has the same syntax as a function call.
50+*Feature/label confusion* (FLC) is the result of any syntax that
51+makes it hard for the eye to tell whether a token on the screen is
52+a feature of the language, or a label in the program. For example,
53+in Lisp a special form has the same syntax as a function call.
5654
5755The worst-case result of FLC is "DSL cancer." Every source file
5856is 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&mdash;"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−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
7870regularities. We'll cover those here.
7971
8072## Glyphs and characters
8173
82−Hoon is a heavy punctuation user. To make ASCII great again,
83−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:
8481
8582```
8683ace [1 space] gal < pal (
@@ -97,28 +94,59 @@ fas / pat @ wut ?
9794zap !
9895```
9996
100−You don't need to memorize these glyph names, but it helps. Code
101−is often vocalized or subvocalized. "pal" is easier to say,
102−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".
103100
104101Note 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,
106103the 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.
108110
109−Comments start with `::` and run to the end of the line. Hard
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.
111+## Expressions and Runes
113112
114−Hoon does not accept non-ASCII text in source files, except UTF-8
115−in quoted strings.
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)&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.
116139
117140## Tall and flat forms
118141
119142There are two kinds of Hoon expression syntax: *tall* and *flat*.
120−Most stems have both tall and flat forms. Tall twigs can contain
121−flat twigs, but not vice versa.
143+Most runes can be used in both tall and flat twigs. Tall twigs can
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)`
122150
123151Visually, a tall twig looks like a "statement" and a flat twig
124152like an "expression," preserving the attractive visual shape of
@@ -126,71 +154,53 @@ procedural code without the nasty side effects.
126154
127155## Regular and irregular forms
128156
129−Most stems have *regular forms*, which share a common design.
130−There is a regular flat form and a regular tall form; most stems
131−implement both. All tall forms are regular.
157+Most runes have *regular forms*, which share a common design.
158+There is a regular flat form and a regular tall form; most runes
159+have both kinds of implementation. All tall forms are regular.
132160
133−Some twigs also have *irregular forms*, which follow no
161+Some runes also have *irregular forms*, which follow no
134162principles at all. All irregular forms are flat.
135163
136−Some twigs (simple leafy ones) have *only* irregular forms.
137−
138−## Keywords versus runes
139−
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".
164+```
165+.= 22
166+23
167+```
149168
150−Keywords may be less challenging for early learners. Rune style
151−is less cluttered and distracting for experienced programmers;
152−the system codebase is all in rune style. Beginners can start
153−with keywords and move to runes; start with runes and stick
154−with runes; or start with keywords and stick with keywords.
169+The `.=` rune tests for equality the two subexpressions that
170+follow, and returns a boolean. Above is the tall, regular form of
171+`.=`. Below is the irregular form:
155172
156−Here's the FizzBuzz demo code, in idiomatic rune syntax. Compare
157−with the [original](../demo).
173+`=(22 23)`
158174
159−```
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−```
175+Some twigs have *only* irregular forms.
173176
174177## Tall regular form
175178
176−Tall regular form starts with the sigil, followed by a `gap`
177−(any whitespace except `ace`), followed by a bulb whose twigs are
178−separated by `gap`.
179+Tall regular forms start with a rune followed by a `gap`.
180+(Remember, a `gap` is any whitespace other than `ace`.) After
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)*.
179188
180−There are four body subtypes: *fixed*, *running*, *jogging*, and
181−*battery*. Stems with a *fixed* number of subexpressions
182−self-terminate. For instance, `:if` has three subexpressions and
183−is self-terminating. Otherwise the twig is terminated by a
184−`gap`, then either `==` (*running* or *jogging*, most twigs) or
189+Runes with a *fixed* number of subexpressions self-terminate. For
190+instance, the `:-` and `.=` runes each have two subexpressions
191+and are self-terminating. Otherwise the twig is terminated by both
192+a `gap`, then either `==` (*running* or *jogging*, most twigs) or
185193`--` (*battery*).
186194
187−The *running* body is a list of twigs. The *jogging* body is a
188−list of twig pairs, separated by a `gap`. The *battery* body is
189−a list of symbol-twig pairs, separated by a gap, prefixed by `++`
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
197+each pair are separated by a `gap`. The *battery* body is
198+a list of symbol-child pairs, separated by a gap, prefixed by `++`
190199and then a gap.
191200
192−This definition is enough to parse. But the proper shape of the
193−whitespace gaps demands an informal convention.
201+This definition is enough to write Hoon that will parse. But
202+writing code with optimal whitespace management requires some
203+additional informal conventions.
194204
195205Whitespace design in Hoon is an art, not a science. It involves
196206both 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.)
199209
200210There are only two real *rules* in Hoon whitespace design: don't
201211go 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
203−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
204214until you know what you're doing. Here are the conventions:
205215
206216### Conventions: *fixed*
207217
208−Bulbs with *fixed* fanout use "backstep" indentation, which slopes
209−backward and to the right by two spaces per line. The first
210−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.
211221
212222Some *1-fixed*, *2-fixed*, *3-fixed* and *4-fixed* examples:
213223
@@ -228,15 +238,14 @@ r
228238s
229239```
230240
231−The hope of backstep indentation is that the heaviest twigs are
232−at the bottom, keeping code flow vertical rather than diagonal.
233−
241+In optimal usage of backstep indentation, the most complicated twigs
242+are at the bottom, keeping code flow vertical rather than diagonal.
234243
235244### Conventions: *running*
236245
237−A *running* bulb (a simple child list) puts the first child two
238−spaces after the end of the sigil, and the following children
239−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:
240249
241250A *running* example:
242251
@@ -251,10 +260,11 @@ A *running* example:
251260
252261### Conventions: *jogging*
253262
254−A *jogging* bulb (a list of child pairs) is like a running bulb,
255−but backsteps the head of the pair above the tail. Most jogging
256−twigs start with a *fixed* sequence; the first jogging pair is
257−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.
258268
259269There are two jogging conventions: *flat* (pair on one line) and
260270*tall* (pair split across lines).
@@ -284,8 +294,11 @@ A *tall jogging* example (preceded by *1-fixed* `p`):
284294
285295### Conventions: *battery*
286296
287−A *battery* bulb is a list of symbol-twig pairs, for the battery
288−of a core. A conventional example:
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
301+conventional example:
289302
290303```
291304|%
@@ -300,24 +313,20 @@ of a core. A conventional example:
300313
301314## Flat regular form
302315
303−Flat regular form starts with the sigil, followed by `pal`
304−(`(`, left parenthesis), followed by a bulb whose subexpressions
305−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
306319parenthesis).
307320
308321A twig in flat form, `:if`, `?:`, `{$if p/twig q/twig r/twig}`:
309322
310−```
311−:if(p q r)
312−
313−?:(p q r)
314−```
323+`?:(p q r)`
315324
316325The only exception is *jogging* bodies, in which subexpression
317326pairs are separated by commas:
318327
319328```
320−:make(foo bar 42, baz 55, moo 17)
329+foo(bar 42, baz 55, moo 17)
321330```
322331
323332There 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.
326335
327336Hoon does not enforce any rule on symbols, except that capitals
328337are 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.
330339
331340Naming things is one of the hard problems in CS. Dodging this
332341problem is one of the reasons mathematicians use Greek letters,
@@ -346,11 +355,11 @@ appropriate.
346355
347356In the *ultralapidary* naming style, labels are single letters,
348357starting in order of construction from `a`, or within a tuple
349−mold `p`. Hoon uses single-letter names for the same reason
350−Algol style languages pass arguments by order, rather than
351−keyword. Naming items by order makes sense when there are no
352−more than three or four; five is stretching it; six is outright
353−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.
354363
355364For example, when defining `add`, we want to name the operands
356365`a` and `b`. It's silly to call them `foo` and `bar`, let alone