@@ -0,0 +1,367 @@
1+---
2+sort: 4
3+next: true
4+title: Syntax
5+---
6+
7+# Hoon syntax
8+
9+Hoon's semantics are simple, but unusual. Hoon's syntax is
10+complex, and unusual. Sorry.
11+
12+## Motivation
13+
14+An excuse: the normal human brain doesn't have hardware support
15+for math, but it does have hardware support for syntax. Learning
16+math is harder than it looks. Learning syntax is easier.
17+
18+An explanation: the Hoon syntax is trying to solve three serious
19+problems in functional syntax design. These are *terminator
20+piles*, *indentation creep*, and *feature/label confusion*.
21+
22+## Terminator piles
23+
24+*Terminator piles* are like Lisp's stacks of right parenthesess.
25+Significant whitespace solves this problem and creates others.
26+
27+Hoon has no terminator piles. Except for a 1-space / more-space
28+distinction, it has no significant whitespace.
29+
30+## Indentation creep
31+
32+*Indentation creep* is a problem caused by indentation conventions
33+where the indentation point is a function of expression tree
34+depth. It's true that short functions are better than long ones,
35+but long ones sometimes need to be written.
36+
37+A procedural block has a backbone of statements which flows
38+straight down. Most expressions are flat and of limited depth.
39+With some bulging, a long function flows *down* the page.
40+
41+A functional language lacks the expression/statement distinction.
42+So a long function means a deep tree. Given normal indentation
43+conventions, a long function wants to flow *down and across*.
44+This *diagonal* shape fits poorly into most editor windows.
45+
46+Thanks to backstep indentation (see below), Hoon programs are
47+shaped more or less like procedural programs.
48+
49+## Feature/label confusion
50+
51+*Feature/label confusion* is any syntax which makes it hard for
52+the eye to tell whether a token on the screen is a feature of the
53+language, or a label in the program. For example, in Lisp a
54+special form has the same syntax as a function call.
55+
56+The worst-case result of FLC is "DSL cancer". Every source file
57+is effectively written in its own domain-specific language. To
58+read a new file is to learn a new language -- "write-only code."
59+
60+A fixed reserved-word set, especially with syntax highlighting,
61+and especially with orthogonal grammar (in C, you don't write
62+`for(a b c)`), may not be too bad. User-level macros, operator
63+overloading, even excessive use of higher-order programming,
64+can all lead quickly to the tragedy of write-only code.
65+
66+Hoon has very weak FLC in keyword style, none in rune style.
67+It has no user-level macros or overloading. It does support
68+higher-order programming; write-only Hoon can certainly be
69+(and has been) written. But good Hoon style is to avoid it.
70+
71+# Design
72+
73+Because each twig stem has its own bulb, each has its own parser
74+rule. We'll describe these grammars as we go through the stems.
75+
76+But Hoon has a general syntax design with common principles and
77+regularities. We'll cover those here.
78+
79+## Glyphs and characters
80+
81+Hoon is a heavy punctuation user. To make ASCII great again,
82+we've mapped each punctuation glyph to a syllable:
83+
84+```
85+ace [1 space] gal < pal (
86+bar | gap [>1 space, nl] par )
87+bas \ gar > sel [
88+buc $ hax # sem ;
89+cab _ hep - ser ]
90+cen % kel { sig ~
91+col : ker } soq '
92+com , ket ^ tar *
93+doq " lus + tec `
94+dot . pam & tis =
95+fas / pat @ wut ?
96+zap !
97+```
98+
99+You don't need to memorize these glyph names, but it helps. Code
100+is often vocalized or subvocalized. "pal" is easier to say,
101+aloud or silently, then "left paren."
102+
103+Note that the list includes two separate whitespace forms: `ace`
104+for a single space, `gap` for 2+, comment or newline. Hoon
105+Besides `ace` versus `gap`, whitespace is not significant.
106+
107+Comments start with `::` and run to the end of the line. Hard
108+tab characters are illegal, and an 80-column right margin is
109+strongly encouraged. Really well-groomed Hoon uses a 55-column
110+code margin and puts a standard line comment at column 57.
111+
112+Hoon does not accept non-ASCII text in source files, except UTF-8
113+in quoted strings.
114+
115+## Tall and flat forms
116+
117+There are two kinds of Hoon expression syntax: *tall* and *flat*.
118+Most stems have both tall and flat forms. Tall twigs can contain
119+flat twigs, but not vice versa.
120+
121+Visually, a tall twig looks like a "statement" and a flat twig
122+like an "expression," preserving the attractive visual shape of
123+procedural code without the nasty side effects.
124+
125+## Regular and irregular forms
126+
127+Most stems have *regular forms*, which share a common design.
128+There is a regular flat form and a regular tall form; most stems
129+implement both. All tall forms are regular.
130+
131+Some twigs also have *irregular forms*, which follow no
132+principles at all. All irregular forms are flat.
133+
134+Some twigs (simple leafy ones) have *only* irregular forms.
135+
136+## Keywords versus runes
137+
138+A regular form starts with a *sigil*, which is either a
139+*keyword* or a *rune* -- at the programmer's choice.
140+
141+A *keyword* is `:` and then the stem label - eg, `:cons`.
142+
143+A *rune* is a pair of ASCII punctuation marks (a digraph) - eg,
144+`:-`. The first glyph in the rune indicates the category - eg,
145+`:` runes make cells. Runes can be pronounced by their glyphs or
146+by their stem -- for `:-`, you can say either "colhep" or "cons".
147+
148+Keywords may be less challenging for early learners. Rune style
149+is less cluttered and distracting for experienced programmers;
150+the system codebase is all in rune style. Beginners can start
151+with keywords and move to runes; start with runes and stick
152+with runes; or start with keywords and stick with keywords.
153+
154+Here's the FizzBuzz demo code, in idiomatic rune syntax. Compare
155+with the [original](../../demo).
156+
157+```
158+ |= end/atom
159+ =/ count 1
160+ |- ^- (list tape)
161+ ?: =(100 count) ~
162+ :_ $(count (add 1 count))
163+ ?: =(0 (mod count 15))
164+ "FizzBuzz"
165+ ?: =(0 (mod count 5))
166+ "Fizz"
167+ ?: =(0 (mod count 3))
168+ "Buzz"
169+ (text !>(count))
170+```
171+
172+## Tall regular form
173+
174+Tall regular form starts with the sigil, followed by a `gap`
175+(any whitespace except `ace`), followed by a bulb whose twigs are
176+separated by `gap`.
177+
178+There are four body subtypes: *fixed*, *running*, *jogging*, and
179+*battery*. Stems with a *fixed* number of subexpressions
180+self-terminate. For instance, `:if` has three subexpressions and
181+is self-terminating. Otherwise the twig is terminated by a
182+`gap`, then either `==` (*running* or *jogging*, most twigs) or
183+`--` (*battery*).
184+
185+The *running* body is a list of twigs. The *jogging* body is a
186+list of twig pairs, separated by a `gap`. The *battery* body is
187+a list of symbol-twig pairs, separated by a gap, prefixed by `++`
188+and then a gap.
189+
190+This definition is enough to parse. But the proper shape of the
191+whitespace gaps demands an informal convention.
192+
193+Whitespace design in Hoon is an art, not a science. It involves
194+both tall/flat mode switches and well-shaped gaps. (Hoon layout
195+could probably be done automatically with reasonable quality.
196+But it would at least take machine learning, not a rule engine.)
197+
198+There only two real *rules* in Hoon whitespace design: don't
199+go past 80 characters, and don't use (completely) blank lines.
200+Otherwise, if it looks good and is easy to read, it's good. But
201+the best way to learn the art is to do everything by convention
202+until you know what you're doing. Here are the conventions:
203+
204+### Conventions: *fixed*
205+
206+Bulbs with *fixed* fanout use "backstep" indentation, which slopes
207+backward and to the right by two spaces per line. The first
208+child is two spaces after the end of the sigil.
209+
210+Some *1-fixed*, *2-fixed*, *3-fixed* and *4-fixed* examples:
211+
212+```
213+|.
214+p
215+
216+=| p
217+q
218+
219+?: p
220+ q
221+r
222+
223+%^ p
224+ q
225+ r
226+s
227+```
228+
229+The hope of backstep indentation is that the heaviest twigs are
230+at the bottom, keeping code flow vertical rather than diagonal.
231+Alternate, reversing
232+
233+### Conventions: *running*
234+
235+A *running* bulb (a simple child list) puts the first child two
236+spaces after the end of the sigil, and the following children
237+straight down:
238+
239+A *running* example:
240+
241+```
242+:* p
243+ q
244+ r
245+ s
246+ t
247+==
248+```
249+
250+### Conventions: *jogging*
251+
252+A *jogging* bulb (a list of child pairs) is like a running bulb,
253+but backsteps the head of the pair above the tail. Most jogging
254+twigs start with a *fixed* sequence; the first jogging pair is
255+below and two steps backward from the last fixed child.
256+
257+There are two jogging conventions: *flat* (pair on one line) and
258+*tall* (pair split across lines).
259+
260+A *flat jogging* example (preceded by *1-fixed* `p`)
261+
262+```
263+?- p
264+ q r
265+ s t
266+ u v
267+==
268+```
269+
270+A *tall jogging* example (preceded by *1-fixed* `p`):
271+
272+```
273+?- p
274+ q
275+ r
276+ s
277+ t
278+ u
279+ v
280+==
281+```
282+
283+### Conventions: *battery*
284+
285+A *battery* bulb is a list of symbol-twig pairs, for the battery
286+of a core. A conventional example:
287+
288+```
289+|%
290+++ foo
291+ p
292+++ bar
293+ q
294+--
295+```
296+
297+## Flat regular form
298+
299+Flat regular form starts with the sigil, followed by `pal`
300+(`(`, left parenthesis), followed by a bulb whose subexpressions
301+are separated by `ace` (one space), followed by `par` (`)`, right
302+parenthesis).
303+
304+A twig in flat form, `:if`, `?:`, `{$if p/twig q/twig r/twig}`:
305+
306+```
307+:if(p q r)
308+
309+?:(p q r)
310+```
311+
312+The only exception is *jogging* bodies, in which subexpression
313+pairs are separated by commas:
314+
315+```
316+:make(foo bar 42, baz 55, moo 17)
317+```
318+
319+There is no flat regular form for *battery* bodies. Be tall.
320+
321+## Naming conventions
322+
323+Hoon does not enforce any rule on symbols, except that capitals
324+are not allowed (use kebab-case). However, a lot of system code
325+is written in using "lapidary" conventions that need explanation.
326+
327+Naming things is one of the hard problems in CS. Dodging this
328+problem is one of the reasons mathematicians use Greek letters,
329+not variable names. Meaningful names also interpose a verbal
330+interpretation, distracting at best and confusing at worst, on
331+the formula or algorithm. Greek letters are not *meaningful*,
332+but they are *memorable*. And their interpretation is defined by
333+the formula and nothing else.
334+
335+### Lapidary and ultralapidary
336+
337+In the *lapidary* naming style, labels are pronounceable
338+three-letter strings, usually CVC (consonant-vowel-consonant).
339+Sometimes they encode a mnemonic, but usually they are just
340+memorable. Labels are reused wherever the analogy seems
341+appropriate.
342+
343+In the *ultralapidary* naming style, labels are single letters,
344+starting in order of construction from `a`, or within a tuple
345+mold `p`. Hoon uses single-letter names for the same reason
346+Algol style languages pass arguments by order, rather than
347+keyword. Naming items by order makes sense when there are no
348+more than three or four; five is stretching it; six is too many.
349+
350+For example, when defining `add`, we want to name the operands
351+`a` and `b`. It's silly to call them `foo` and `bar`, let alone
352+`left-operand` and `right-operand`. The smaller the scale of an
353+algorithm, the simpler its names should be.
354+
355+### When in doubt, don't be lapidary
356+
357+This works in the other direction: namelessness doesn't scale.
358+Most normal code shouldn't use lapidary naming at all. (Everyone
359+agrees: there is *way* too much lapidary Hoon in Urbit.)
360+
361+Lapidary naming is only for *inherently simple code*: code that
362+both aspires to high elegance and clarity, and *is solving a
363+simple and elegant problem*.
364+
365+Given an ugly or complex problem, lapidary naming is a liability,
366+no matter the excellence of the programmer. When in doubt, use
367+long names and/or kebab-case.