this is a sample file designed to set conventions for high-quality conventional hoon.
all lines must be under 80 characters. no blank lines. any line longer than 60 characters is probably too long. uppercase or non-ascii letters are strongly discouraged.
informal comments (lines with ::
) should be used only for
meta-discussion about the code.
whenever possible, use formal decorations. :>
decorates
the next expression; :<
decorates the previous one.
there are two places to put decorations: in line with the code, and on the right margin.
in comments and decorations, use phrase for emphasis
and braces
to surround code literals. (documentation will
eventually be automatically generated from formal comments.)
%literal, ++literal, ~ship need no braces. for a valid
hoon expression, `exp.
there are three conventions for naming: ultralapidary, lapidary, and natural. this file is mostly natural.
when in doubt, use the natural naming convention. for
both arms and faces, natural naming means long, legible,
english-language phrases, in hyphen-separated kebab-case
.
lapidary conventions should be used only for small, simple, self-contained systems. lapidary mode means three-letter faces ("variable names") and four-letter arms ("methods").
ultralapidary conventions use single-letter names starting
with a
. use this convention only for one-liners, etc.
the file below is a medium-sized generator, built around
a typical two-core structure. the cores are labeled %arch
(structures) and %work
(productions). this is canonical.
this code is written to display the variety of formatting options the parser allows. a specific convention should pick one of these styles and stick to it.
a forward decoration block :>
is either a document block or
a definition block.
a document block has two parts, each of which is optional: the title and the body,
the title is a ++term preceded by :> || %
. only cores
and core chapters (preceded by +|
) can use titles. titles
are optionally surrounded by blank or semi-blank decorations,
:>
or :> ||
.
the body is either short or long. a short body is a single line
preceded by :>
- ie, not indented. a long body starts with
a single line indented by two extra spaces, :>
, then a
blank line, then a series of paragraphs.
a definition block is a list of name definitions. the twig below the block is traversed for bindings on these names.
a name definition can be short or long. a short definition is
a single line of the form :> name: value
.
a long definition is a short definition, followed by a blank
decoration :>
, followed by a series of paragraphs each
indented by an extra two spaces.
a paragraph is a series of lines, not indented for text,
indented by four extra spaces, :>
, for code.
a backward decoration :<
is only one line, always parsed
as a short body.
:- %say
|= *
=< [%noun (say-hello %world)]
=>
nothing forces us to put structures in a separate core. but compile-time evaluation doesn't work in the current core; we often want to statically evaluate structures.
there are three kinds of structures: models (normalizing functions), patterns (functions that build models), and constants (static data).
most code will not need its own patterns. but put them
in a separate chapter (separated by +|
).
|%
arms producing molds are introduced with +=
. for molds,
we decorate the mold rather than the arm. the compiler
will copy the mold decoration onto the arm.
+|
+= spot {p/@ q/@}a coordinate
+= topsalso a coordinate
{p/@ q/@}
+= goofa simple tuple
$: foo/@something mysterious
bar/@go here for drink
moo/(binary-tree juice)cows do this
==
+= juicefruity beverage
$% {$plum p/@}fresh prune
{$pear p/@ q/@}good for cider
{$acai p/@}aztec superfood
==
other languages might call these "type constructors" or "higher-kinded types".
+|
++ binary-treetree pattern
|* a/$-(* *)
$@($~ {n/a l/(binary-tree a) r/(binary-tree a)})
+|
++ answeranswer to everything
42
--
note that ++say-goodbye is the correct notation, even though
it's a +-
arm.
|%
++ say-hellosay hi to someone
friendly welcome message
|=
txt
: friend to say hi to
txt/term
^- tape
"hello, {(rip 3 txt)}"
some paragraphs about the goodbye algorithm, possibly including code indented by four extra spaces:
?: =(%hello %world) %hello %world
+- say-goodbye
describe product of function
|=
txt
: departing friend
num
: number of friends
$: txt/term
num/@
==
^- tape
foo
: four
bar
: forty-two
=/ foo (add 2 2)
=/ bar (add (mul num foo) 2)
=/ moo (mul num bar)for all the cows
"goodbye and {(scot %ud moo)}, {(rip 3 txt)}"
++ say-minimumminimal decoration
|= txt/term
"nothing to say to {(rip 3 txt)}"
--