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