-
Notifications
You must be signed in to change notification settings - Fork 0
/
deco.hoon
178 lines (177 loc) · 6.33 KB
/
deco.hoon
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
::
:: 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)]
=> :: # %arch
::
:: structures for our imaginary hello, world generator.
::
:: 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 {+|}).
|%
:: # %model
::
:: models (molds) are functions that normalize nouns.
::
:: arms producing molds are introduced with {+$}. the
:: compiler will copy the arm decoration onto its product
:: +|
+$ spot [p=@ q=@] :: a coordinate
+$ tops :: also a coordinate
[p=@ q=@]
+$ goof :: a simple tuple
$: foo=@ :: something mysterious
bar=@ :: go here for drink
moo=(binary-tree juice) :: cows do this
==
+$ juice :: fruity beverage
$% [%plum p=@] :: fresh prune
[%pear p=@ q=@] :: good for cider
[%acai p=@] :: aztec superfood
==
:: #
:: # %pattern
:: #
::
:: patterns are functions that build models.
::
:: other languages might call these "type constructors"
:: or "higher-kinded types".
:: +|
++ binary-tree :: tree pattern
|* a=$-(* *)
$@(~ [n=a l=(binary-tree a) r=(binary-tree a)])
:: #
:: # %constant
:: #
:: if you have constants, put them in their own chapter.
:: +|
++ answer :: answer to everything
42
--
:: #
:: # %work
:: #
:: engines for our imaginary hello, world app.
::
|%
++ say-hello :: say hi to someone
:: friendly welcome message
::
|= :: txt: friend to say hi to
::
txt=term
^- tape
"hello, {(rip 3 txt)}"
:: ++say-goodbye: say a really proper goodbye
::
:: 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 {(scow %ud moo)}, {(rip 3 txt)}"
::
++ say-minimum :: minimal decoration
|= txt=term
"nothing to say to {(rip 3 txt)}"
--