on f3ca521 help sign in
475 lines 13 kB history raw
1+++
2title = "Hoon Style Guide"
3weight = 100
4template = "doc.html"
5aliases = ["docs/learn/hoon/style/"]
6+++
7Welcome to the Hoon style guide. It's important to familiarize yourself with our way of writing Hoon code.
9## Layout
11Hoon's position on layout is: so long as your code is (a) correctly commented,
12(b) free from blank or overlong lines, (c) parses, and (d) looks good, it's good
13layout.
15When a layout standard or other fundamental coding convention is
16not perfectly rigid, code can develop some individual flavor.
17But Hoon's layout rules, though not rigid, are still strict. The
18flavor should never overwhelm the content.
20### General outline of Hoon syntax
22There are two forms of syntax in Hoon: wide and tall. Wide forms
23fit on a single line, use single spaces to separate syntax, and
24generally use enclosing terminators (like parentheses to close an
25expression). Tall forms can use multiple lines, separate syntax
26with two spaces at minimum and arbitrary whitespace at maximum,
27and avoid terminators when the content has a fixed structure.
29For example, the wide form `=+(a b)` could be written in tall form
30as
32```hoon
33 =+ a
34 b
35```
37or
39```hoon
40 =+ a b
41```
43These are regular forms -- every rune can be written this way.
44Hoon also has a variety of wide [irregular forms](@/docs/hoon/hoon-expressions/irregular.md). All tall
45forms are regular. All code within a wide form is wide.
46Almost all code has both wide and tall forms, the exception
47being named cores.
49The goal of wide/tall forms is to resemble the look of
50procedural code, with its statement/expression distinction,
51in a purely functional language. In particular, complex code in
52functional languages tends to develop a diagonal shape, since
53child nodes in the syntax tree are indented right.
55### Tall layout conventions
57In wide form, the parser allows no freedom of layout (and no
58comments, either). In tall form, there is too much freedom, and so we need
59conventions. These conventions aren't absolute, but
60you shouldn't defy them unless you have a good reason to do so.
62Syntactically, there are three kinds of runes: fixed sequences,
63variable sequences, and cores/engines. Let's talk about each.
65#### Fixed sequences and backstep indentation
67A fixed sequence is a rune with a fixed number of children. Most
68runes are fixed sequences. In wide mode we terminate a fixed
69sequence with a right-parenthesis (rit). In tall mode there is
70no terminator.
72With a fixed sequence, we typically use "backstep indentation."
73The goal of a backstep is for the largest child node of the rune
74to end up on the same left margin as the rune itself. This
75design ensures that the body of the code flows down the page, not
76across the page.
78With one child:
80```hoon
81 !:
82 a
83```
85With two:
87```hoon
88 =+ a
89 b
90```
92With three:
94```hoon
95 ?: a
96 b
97 c
98```
100With four (the maximum rune fanout):
102```hoon
103 :^ a
104 b
105 c
106 d
107```
109It is sometimes acceptable to not backstep -- especially in tuple
110runes: `:-,` `:_`, `:+` and `+^`. But you should have a specific reason:
111for example: emphasizing symmetry in a tuple.
113#### Variable sequences
115Variable sequences can have an arbitrary number of elements, so
116they can't self-terminate. They are terminated by a `==` marker.
117The sequence, or its variable part, is indented and vertical:
119```hoon
120 :* a
121 b
122 c
123 ==
124```
126Another representation wastes a line, but saves an indent. Use
127this only for very long sequences:
129```hoon
130 :*
131 a
132 b
133 c
134 ==
135```
137Some variable sequences are sequences of pairs; some of these
138start with fixed sequences of nodes. Pair sequences are in
139either "kingside" or "queenside" convention, depending on what
140looks better for this particular code.
142Kingside format:
144```hoon
145 ?+ x default
146 %foo 99
147 %foobar ?: y
148 42
149 (add 2 2)
150 37 36
151 ==
152```
154Queenside format:
156```hoon
157 ?+ x
158 default
159 ::
160 %foo
161 99
162 ::
163 %foobar
164 ?: y
165 42
166 (add 2 2)
167 ==
168```
170The queenside format is more useful when the tails are bigger.
171It is also usually hard to read without linebreak comments,
172as demonstrated above.
174We sometimes end up with multiple terminators on separate lines,
175two or more spaces apart. These lines can be collapsed:
177```hoon
178 ?+ x default
179 %foo 99
180 37 36
181 %foobar ?- y
182 %moo 9
183 %bar 10
184 == ==
185```
187## General naming style
189Modern Hoon naming is **verbose**.
191**Never**: abbreviate a label; pack characters (try to reduce the
192length of labels, or make lengths match up between parallel
193labels); use intentionally vague and meaningless words; or use
194nonsense text that isn't a word.
196It can't be repeated too often: **do not abbreviate words, unless
197you would use the same abbreviations in written English**. To
198save a trivial, one-time amount of work in typing, you are adding
199a nontrivial amount of work and ambiguity in reading.
201### Comments and unparsed bytes
203Hoon comments are 8-column lines which contain whitespace, then
204`::`, then optional text.
206Blank lines are lines containing no characters, or only whitespace.
207There must never be blank lines in a Hoon file.
209Empty lines are lines containing `::` only. There must never be
210two empty lines in a row in a Hoon file.
212Whitespace is semi-significant. The difference between a
213space and a gap (more than one space) is significant. But two or
214more spaces, newlines, or comments are one gap.
216#### Comment conventions
218Hoon suggests "breathing comments." There should always be an
219empty comment line between a comment and the line **below** it:
221```hoon
222 :: look, code
223 ::
224 this.is.code
225 :: we are going to need more code
226 ::
227 this.is.more.code
228```
230Sometimes dense code does need air on both sides. Also
231legitimate:
233```hoon
234 :: look, code
235 ::
236 this.is.code
237 ::
238 :: we are going to need more code
239 ::
240 this.is.more.code
241```
243But air on both sides is needed less often than you may think.
245Crowded comments are comments on lines which also contain code.
246Older code has a lot of these, especially the "column 56"
247standard.
249Crowded comments are considered harmful -- don't use them. Hoon,
250like any higher-order functional language, can be very dense and
251powerful. We almost never want it to be **more** dense.
253#### Megalithic comments
255In older code you'll also see attempts to produce large, visually
256salient geometries as separators, like:
258```
259 ::
260 ::::
261 ::
262```
264or
266```
267 ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
268```
270Please don't do this in new code. Normal conventions should be
271legible. Use more deeply qualified positions if your code is
272hard to navigate.
274### Structure of all comments, formal and informal
276If any comment cannot be parsed as a formal comment, we treat it
277as an informal comment and ignore it.
279There are four types of formal comments: feature comments (which
280annotate named features), product comments (which describe what
281the expression below makes), flow comments (which describe the
282computation flow), and development comments (which describe the
283development process).
285All kinds of formal comments have the same structure: simple or
286complex.
288A simple formal comment is a one-line headline. A headline is
289optional whitespace; then `::`; then two spaces; then a parsed
290line of **lowercase** ASCII whose syntax depends on the comment
291type. Like this:
293```hoon
294 :: $foo: the definition of a foo
295```
297A complex formal comment is the headline; then an empty line;
298then an udon body with paragraphs broken by empty lines, indented
299four spaces, in ASCII mixed case:
301```hoon
302 :: $foo: the definition of a foo
303 ::
304 :: The source of the word "foo" is lost in history. Some
305 :: think it comes from the WWII military term "FUBAR,"
306 :: in which "UBAR" stands for "up beyond all retrieval."
307 ::
308 :: Somehow "FUBAR" became "foobar." The rest is history.
309 ::
310```
312The point is: sometimes we want to see a deep explanation;
313sometimes we just want a summary. So we require you to either
314(a) provide a line-length explanation, or (b) a long screed
315but with a line-length summary/headline.
317### Feature comments
319A feature headline is `::`, then two spaces, then a qualified
320location, then `:`, then a freeform string. Like:
322```hoon
323 :: $foo: a the definition of a foo
324 ::
325 +$ foo [head=@ tail=^]
326```
328We find the feature `$foo` relative to the current location and
329move the comment there, as described above. In most cases it
330becomes a product comment. For a `|chapter` (which does not
331resolve to any data value) it becomes the chapter description.
333### Product comments
335Product comments describe the product of the expression below.
336The headline is a string in parentheses:
338```hoon
339 :: (a very strange $foo indeed)
340 ::
341 make:a:strange:foo
342```
344### Flow comments and legends
346Flow comments use a new commenting concept called **legends**.
348#### Legends
350One of the problems with Hoon as a language is that it takes some
351time to learn to look at a tree of runes and "see the function."
352Seeing the function is beautiful and pleasant. But until the new
353Hoon student has put in a lot of practice, this experience is
354inaccessible. And tracing runes with a manual is hard.
356Canonical flow comments are one way to ease this burden.
357them, we first need to write descriptive names (not necessarily
358unique) for every leg of every rune case. Then, we introduce a
359narration of the code with these descriptions.
361For example, let's fix `[%wtcl p=hoon q=hoon r=hoon]`. Let's
362make it... `[%wtcl if=hoon then=hoon else=hoon]`. Then we
363could write flow comments as follows:
365```hoon
366 ?: :: if, it's it winter
367 ::
368 is-winter
369 :: then, why not rome?
370 ::
371 visit-italy
372 :: else, amsterdam is nice in the summer
373 ::
374 visit-holland
375```
377The headline of a flow comment uses a **legend**: the name of
378this leg in the parent rune, then a message,
380For someone who doesn't know Hoon, these pseudo-keywords are
381a lifesaver. For someone who does, they are not too annoying
382and may still be helpful.
384Of course, to use this we need to write useful "leg ends" for all
385appropriate legs of all appropriate runes. But that will
386probably help us document them, anyway.
388#### Flow promotion
390Sometimes, just for cosmetic reasons, we like to raise the
391comment on the first leg of a rune up above the parent:
393```hoon
394 :: if, it's it winter
395 ::
396 ?: is-winter
397 :: then, why not rome?
398 ::
399 visit-italy
400 :: else, amsterdam is nice in the summer
401 ::
402 visit-holland
403```
405This can make flow comments collide, as in "else, if," below:
407```hoon
408 :: if, it's winter
409 ::
410 ?: is-winter
411 :: then, why not rome?
412 ::
413 visit-italy
414 :: else, if, sprechen sie deutsch?
415 ::
416 ?: speak-german
417 :: then, maybe berlin?
418 ::
419 visit-berlin
420 :: else, everyone in amsterdam speaks english
421 ::
422 visit-holland
423```
425#### Flow comments, traces, and interpolation
427Flow comments, because they describe what your code is doing, are
428embedded in the stack trace, using the same hint mechanism as
429`~|`. A trace is an explanation of everything your code was
430doing when it crashed.
432And data interpolation, in `{}`, also works in flow comments.
433Your flow comments just describe what your code is doing, in
434English, including data.
436## Grading
438How do we define the superficial quality of Hoon code? (Setting
439aside, of course, the question of whether the code is computing
440the right thing in the right way.)
442There are five grades of Hoon: incomplete (F), compiling (D),
443correct (C), complete (B), and annotated (A).
445Any file that looks like code and opens in an editor gets an F.
446If it compiles, and it is Hoon, it gets a D.
448A Hoon file that follows the layout, structure, and naming
449conventions in this document has earned a C. Weird indents,
450cryptic or abbreviated names, etc, etc, preclude an A or B
451grade -- regardless of documentation.
453A Hoon file gets a B if and only if **every symbol in the file is
454defined, where introduced, by a formal comment**. You do not get
455to make up a name without writing a one-line definition.
457For an A, there are two criteria.
459One: every symbol that needs an explanation (a multiline comment
460after the definition) has an explanation. This is obviously a
461judgment call, as a grade of A should always be. If a definition
462doesn't call for any explanation, it must be dead obvious.
464Two: every `%constant` we use must be defined where it is used,
465not just where it's declared.
467The advantage of a `%constant` over a classic `typedef`: there is no
468need to search formally for a symbol. The disadvantage: there is
469no trivial way to find out what the symbol actually means. So
470when I send some `%foobar` move, I should define what I think
471`%foobar` means. Just copy and paste the original definition.
473Code shouldn't even try for an A until it is quite stable. The worst
474thing in the world is code that changes without updating the documentation.
475Any **incorrect** comment in a file drops it all the way back to a D.