2title = "Hoon Style Guide"
5aliases = ["docs/learn/hoon/style/"]
8Welcome to the Hoon style guide. It’s important to familiarize yourself with our way of writing Hoon code.
12Hoon’s position on layout is: so long as your code is (a) correctly commented,
13(b) free from blank or overlong lines, (c) parses, and (d) looks good, it’s good
16When a layout standard or other fundamental coding convention is
17not perfectly rigid, code can develop some individual flavor.
18But Hoon’s layout rules, though not rigid, are still strict. The
19flavor should never overwhelm the content.
21### General outline of Hoon syntax
23There are two forms of syntax in Hoon: wide and tall. Wide forms
24fit on a single line, use single spaces to separate syntax, and
25generally use enclosing terminators (like parentheses to close an
26expression). Tall forms can use multiple lines, separate syntax
27with two spaces at minimum and arbitrary whitespace at maximum,
28and avoid terminators when the content has a fixed structure.
30For example, the wide form `=+(a b)` could be written in tall form
44These are regular forms -- every rune can be written this way.
45Hoon also has a variety of wide [irregular forms](/docs/hoon/reference/irregular). All tall
46forms are regular. All code within a wide form is wide.
47Almost all code has both wide and tall forms, the exception
48being named [cores](/docs/glossary/core/).
50The goal of wide/tall forms is to resemble the look of
51procedural code, with its statement/expression distinction,
52in a purely functional language. In particular, complex code in
53functional languages tends to develop a diagonal shape, since
54child nodes in the syntax tree are indented right.
56### Tall layout conventions
58In wide form, the parser allows no freedom of layout (and no
59comments, either). In tall form, there is too much freedom, and so we need
60conventions. These conventions aren’t absolute, but
61you shouldn’t defy them unless you have a good reason to do so.
63Syntactically, there are three kinds of runes: fixed sequences,
64variable sequences, and cores/engines. Let’s talk about each.
66#### Fixed sequences and backstep indentation
68A fixed sequence is a rune with a fixed number of children. Most
69runes are fixed sequences. In wide mode we terminate a fixed
70sequence with a right-parenthesis (“rit”). In tall mode there is
73With a fixed sequence, we typically use “backstep indentation.”
74The goal of a backstep is for the largest child node of the rune
75to end up on the same left margin as the rune itself. This
76design ensures that the body of the code flows down the page, not
101With four (the maximum rune fanout):
110It is sometimes acceptable to not backstep -- especially in tuple
111runes: `:-`, `:_`, `:+` and `+^`. But you should have a specific reason:
112for example: emphasizing symmetry in a tuple.
114#### Variable sequences
116Variable sequences can have an arbitrary number of elements, so
117they can’t self-terminate. They are terminated by a `==` marker.
118The sequence, or its variable part, is indented and vertical:
127Another representation wastes a line, but saves an indent. Use
128this only for very long sequences:
138Some variable sequences are sequences of pairs; some of these
139start with fixed sequences of nodes. Pair sequences are in
140either “kingside” or “queenside” convention, depending on what
141looks better for this particular code.
171The queenside format is more useful when the tails are bigger.
172It is also usually hard to read without linebreak comments,
173as demonstrated above.
175We sometimes end up with multiple terminators on separate lines,
176two or more spaces apart. These lines can be collapsed:
188## General naming style
190Modern Hoon naming is **verbose**.
192**Never**: abbreviate a label; pack characters (try to reduce the
193length of labels, or make lengths match up between parallel
194labels); use intentionally vague and meaningless words; or use
195nonsense text that isn’t a word.
197It can’t be repeated too often: **do not abbreviate words, unless
198you would use the same abbreviations in written English**. To
199save a trivial, one-time amount of work in typing, you are adding
200a nontrivial amount of work and ambiguity in reading.
202### Comments and unparsed bytes
204Hoon comments are 8-column lines which contain whitespace, then
205`::`, then optional text.
207Blank lines are lines containing no characters, or only whitespace.
208There must never be blank lines in a Hoon file.
210Empty lines are lines containing `::` only. There must never be
211two empty lines in a row in a Hoon file.
213Whitespace is semi-significant. The difference between a
214space and a gap (more than one space) is significant. But two or
215more spaces, newlines, or comments are one gap.
217#### Comment conventions
219Hoon suggests “breathing comments.” There should always be an
220empty comment line between a comment and the line **below** it:
226:: we are going to need more code
231Sometimes dense code does need air on both sides. Also
239:: we are going to need more code
244But air on both sides is needed less often than you may think.
246Crowded comments are comments on lines which also contain code.
247Older code has a lot of these, especially the “column 56”
250Crowded comments are considered harmful -- don’t use them. Hoon,
251like any higher-order functional language, can be very dense and
252powerful. We almost never want it to be **more** dense.
254#### Megalithic comments
256In older code you’ll also see attempts to produce large, visually
257salient geometries as separators, like:
268::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
271Please don’t do this in new code. Normal conventions should be
272legible. Use more deeply qualified positions if your code is
275### Structure of all comments, formal and informal
277If any comment cannot be parsed as a formal comment, we treat it
278as an informal comment and ignore it.
280There are four types of formal comments: feature comments (which
281annotate named features), product comments (which describe what
282the expression below makes), flow comments (which describe the
283computation flow), and development comments (which describe the
286All kinds of formal comments have the same structure: simple or
289A simple formal comment is a one-line headline. A headline is
290optional whitespace; then `::`; then two spaces; then a parsed
291line of **lowercase** ASCII whose syntax depends on the comment
295 :: $foo: the definition of a foo
298A complex formal comment is the headline; then an empty line;
299then an udon body with paragraphs broken by empty lines, indented
300four spaces, in ASCII mixed case:
303:: $foo: the definition of a foo
305:: The source of the word “foo” is lost in history. Some
306:: think it comes from the WWII military term “FUBAR,”
307:: in which “UBAR” stands for “up beyond all retrieval.”
309:: Somehow “FUBAR” became “foobar.” The rest is history.
313The point is: sometimes we want to see a deep explanation;
314sometimes we just want a summary. So we require you to either
315(a) provide a line-length explanation, or (b) a long screed
316but with a line-length summary/headline.
320A feature headline is `::`, then two spaces, then a qualified
321location, then `:`, then a freeform string. Like:
324:: $foo: a the definition of a foo
326+$ foo [head=@ tail=^]
329We find the feature `$foo` relative to the current location and
330move the comment there, as described above. In most cases it
331becomes a product comment. For a `|chapter` (which does not
332resolve to any data value) it becomes the chapter description.
336Product comments describe the product of the expression below.
337The headline is a string in parentheses:
340:: (a very strange $foo indeed)
345### Flow comments and legends
347Flow comments use a new commenting concept called **legends**.
351One of the problems with Hoon as a language is that it takes some
352time to learn to look at a tree of runes and “see the function.”
353Seeing the function is beautiful and pleasant. But until the new
354Hoon student has put in a lot of practice, this experience is
355inaccessible. And tracing runes with a manual is hard.
357Canonical flow comments are one way to ease this burden.
358We first need to write descriptive names (not necessarily
359unique) for every leg of every rune case. Then, we introduce a
360narration of the code with these descriptions.
362For example, let’s fix `[%wtcl p=hoon q=hoon r=hoon]`. Let’s
363make it … `[%wtcl if=hoon then=hoon else=hoon]`. Then we
364could write flow comments as follows:
367?: :: if, it is winter
370 :: then, why not rome?
373:: else, amsterdam is nice in the summer
378The headline of a flow comment uses a **legend**: the name of
379this leg in the parent rune, then a message,
381For someone who doesn’t know Hoon, these pseudo-keywords are
382a lifesaver. For someone who does, they are not too annoying
383and may still be helpful.
385Of course, to use this we need to write useful “leg ends” for all
386appropriate legs of all appropriate runes. But that will
387probably help us document them, anyway.
391Sometimes, just for cosmetic reasons, we like to raise the
392comment on the first leg of a rune up above the parent:
398 :: then, why not rome?
401:: else, amsterdam is nice in the summer
406This can make flow comments collide, as in “else, if,” below:
412 :: then, why not rome?
415:: else, if, sprechen sie deutsch?
418 :: then, maybe berlin?
421:: else, everyone in amsterdam speaks english
426#### Flow comments, traces, and interpolation
428Flow comments, because they describe what your code is doing, are
429embedded in the stack trace, using the same hint mechanism as
430`~|`. A trace is an explanation of everything your code was
431doing when it crashed.
433And data interpolation, in `{}`, also works in flow comments.
434Your flow comments just describe what your code is doing, in
435English, including data.
439How do we define the superficial quality of Hoon code? (Setting
440aside, of course, the question of whether the code is computing
441the right thing in the right way.)
443There are five grades of Hoon: incomplete (F), compiling (D),
444correct (C), complete (B), and annotated (A).
446Any file that looks like code and opens in an editor gets an F.
447If it compiles, and it is Hoon, it gets a D.
449A Hoon file that follows the layout, structure, and naming
450conventions in this document has earned a C. Weird indents,
451cryptic or abbreviated names, etc, etc, preclude an A or B
452grade -- regardless of documentation.
454A Hoon file gets a B if and only if **every symbol in the file is
455defined, where introduced, by a formal comment**. You do not get
456to make up a name without writing a one-line definition.
458For an A, there are two criteria.
460One: every symbol that needs an explanation (a multiline comment
461after the definition) has an explanation. This is obviously a
462judgment call, as a grade of A should always be. If a definition
463doesn’t call for any explanation, it must be dead obvious.
465Two: every `%constant` we use must be defined where it is used,
466not just where it’s declared.
468The advantage of a `%constant` over a classic `typedef`: there is no
469need to search formally for a symbol. The disadvantage: there is
470no trivial way to find out what the symbol actually means. So
471when I send some `%foobar` move, I should define what I think
472`%foobar` means. Just copy and paste the original definition.
474Code shouldn’t even try for an A until it is quite stable. The worst
475thing in the world is code that changes without updating the documentation.
476Any **incorrect** comment in a file drops it all the way back to a D.
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list