on f3ca521 help sign in
329 lines 16 kB history raw
1+++
2title = "1.3 Hoon Syntax"
3weight = 4
4template = "doc.html"
5aliases = ["/docs/learn/hoon/hoon-tutorial/hoon-syntax/"]
6+++
8The study of Hoon can be divided into two parts: syntax and semantics.
10The [syntax](https://en.wikipedia.org/wiki/Syntax_%28programming_languages%29 ) of a programming language is the set of rules that determine what counts as admissible code in that language. It determines which characters may be used in the source, and also how these characters may be assembled to constitute a program. Attempting to run a program that doesn't follow these rules will result in a syntax error.
12The [semantics](https://en.wikipedia.org/wiki/Semantics_%28computer_science%29 ) of a programming language concerns the meaning of the various parts of that language's code.
14In this lesson we will give a general overview of Hoon's syntax. By the end of it, you should be familiar with all the basic elements of Hoon code.
16## Hoon Characters
18Hoon source files are composed almost entirely of the [printable ASCII characters](https://en.wikipedia.org/wiki/ASCII%23Printable_characters). Hoon does not accept any other characters in source files except for [UTF-8](https://en.wikipedia.org/wiki/UTF-8) in quoted strings. Hard tab characters are illegal; use two spaces instead.
20```
21> "You can put ½ in quotes, but not elsewhere!"
22"You can put ½ in quotes, but not elsewhere!"
24> 'You can put ½ in single quotes too.'
25'You can put ½ in single quotes too.'
27> "Some UTF-8: ἄλφα"
28"Some UTF-8: ἄλφα"
29```
31### Reading Hoon Aloud
33Hoon code makes heavy use of non-alphanumeric symbols. Reading off code aloud using the proper names of ASCII symbols is tedious, so we've mapped syllables to symbols:
35```
36ace [1 space] gap [>1 space, nl] pat @
37bar | gar > sel [
38bas \ hax # ser ]
39buc $ hep - sig ~
40cab _ kel { soq '
41cen % ker } tar *
42col : ket ^ tic `
43com , lus + tis =
44doq " mic ; wut ?
45dot . pal ( zap !
46fas / pam &
47gal < par )
48```
50Learning and using these names of non-alphanumeric symbols is entirely optional; you can become an expert Hoon programmer without them. Many Hoon programmers find them helpful, however, particularly when talking to someone else who knows them.
52Note that the list includes two separate whitespace forms: `ace` for a single space; `gap` is either 2+ spaces or a newline. In Hoon, the only whitespace significance is the distinction between `ace` and `gap` -- i.e., the distinction between one space and more than one.
54## Expressions of Hoon
56An [expression](https://en.wikipedia.org/wiki/Expression_%28computer_science%29 ) is a combination of characters that the language interprets and evaluates as producing a value. Hoon programs are made up entirely of expressions.
58Hoon expressions can be either basic or complex. Basic expressions of Hoon are fundamental, meaning that they can't be broken down into smaller expressions. Complex expressions are made up of smaller expressions (which are called **subexpressions**).
60There are many categories of Hoon expressions: noun literals, wing expressions, type expressions, and rune expressions. Let's go over each.
62### Noun Literals
64A noun is either an atom or a cell. An atom is an unsigned integer and a cell is a pair of nouns.
66There are [literal](https://en.wikipedia.org/wiki/Literal_%28computer_programming%29 ) expressions for each kind of noun. A noun literal is just a notation for representing a fixed noun value.
68We start with atom literals. Each of these is a basic expression of Hoon that evaluates to itself. Examples:
70```
71> 1
74> 123
75123
77> 123.456
78123.456
80> 'hello'
81'hello'
83> ~zod
84~zod
85```
87Recall from [lesson 1.2](@/docs/hoon/hoon-tutorial/nouns.md) that even though atoms are unsigned integers, they can be pretty-printed in different ways. The way an atom is to be represented depends on its aura. The literal syntax for each of the hard-coded auras will be explained further in [lesson 2.4](@/docs/hoon/hoon-tutorial/atoms-auras-and-simple-cell-types.md).
89Cell literals can be written in Hoon using `[ ]`. Cell literals are complex, because other expressions are put inside the square brackets. Examples:
91```
92> [6 7]
93[6 7]
95> [[12 14] [654 123.456 980]]
96[[12 14] 654 123.456 980]
98> ['hello' 0xdad]
99['hello' 0xdad]
101> [123 [~zod ~ten] .1.2837]
102[123 [~zod ~ten] .1.2837]
103```
105You can also put complex expressions inside square brackets to make a cell. These are valid expressions but they aren't cell literals, naturally:
107```
108> [(add 22 33) (mul 22 33)]
109[55 726]
110```
112### Wings
114A wing expression is a series of limb expressions separated by `.`. A deeper explanation can be found on the [wing](@/docs/hoon/hoon-expressions/limb/wing.md) and [limb](@/docs/hoon/hoon-expressions/limb/limb.md) reference pages.
116Let's start with the base case: a single limb. A limb expression is a trivial wing expression -- there is only one limb in the series. Some one-limb wings:
118- `+2`
119- `-`
120- `+>`
121- `&4`
122- `a`
123- `b`
124- `add`
125- `mul`
127As a special limb we also have `$`. This is the name of the arm in special one-armed cores called "gates". (We'll cover the role of `$` in [lesson 1.5](@/docs/hoon/hoon-tutorial/gates.md).)
129Wing expressions with multiple limbs are complex expressions. Examples:
131- `+2.+3.+4`
132- `-.+.+`
133- `resolution.path.into.subject`
134- `+>.$`
135- `a.b.c`
136- `-.b.+2`
137- `-.add`
140### Type Expressions
142Hoon is a statically typed language. You'll learn more about the type system later in the chapter. For now, just know that Hoon's type system uses special symbols to indicate certain fundamental types: `~` (null), `*` (noun), `@` (atom), `^` (cell), and `?` (flag). Each of these symbols can be used as a stand-alone expression of Hoon. In the case of `@` there may be a series of letters following it, to indicate an atom aura; e.g., `@s`, `@rs`, `@tas`, and `@tD`.
144They may also be put in brackets to indicate compound types, e.g., `[@ ^]`, `[@ud @sb]`, `[[? *] ^]`. (Technically these expressions don't _always_ indicate compound types. In certain contexts they're interpreted in a different way. We'll address this variation of meaning in [lesson 2.6](@/docs/hoon/hoon-tutorial/structures-and-complex-types.md).)
146### Rune Expressions
148A **rune** is just a pair of ASCII characters (a digraph). You've already seen some runes in Chapter 1: `|=`,`|%`, and `|_`. We usually pronounce runes by combining their characters' names, e.g.: 'ket-hep' for `^-`, 'bar-tis' for `|=`, and 'bar-cen' for `|%`. As stated previously, these names are entirely optional.
150Expressions with a rune at the beginning are rune expressions. Most runes are used at the beginning of a complex expression, but there are exceptions. For example, the runes `--` and `==` are used at the end of certain expressions.
152Runes are classified by family (with the exceptions of `--` and `==`). The first of the two symbols indicates the family -- e.g., the `^-` rune is in the `^` family of runes, and the `|=` and `|%` runes are in the `|` family. The runes of particular family usually have related meanings. Two simple examples: the runes in the `|` family are all used to create cores, and the runes in the `:` family are all used to create cells.
154Rune expressions are usually complex, which means they usually have one or more subexpressions. The appropriate syntax varies from rune to rune; after all, they're used for different purposes. To see the syntax rules for a particular rune, consult the [rune reference](@/docs/hoon/hoon-expressions/rune/_index.md). Nevertheless, there are some general principles that hold of all rune expressions.
156Runes generally do not need to be closed. In other languages you'll see an abundance of terminators, such as opening and closing parentheses, and this way of doing this is largely absent from Urbit. That's because all runes take a fixed number of children. Children can themselves be runes (with more children), and Hoon programs work by chaining through these series of children until a value -- not another rune -- is arrived at. This makes Hoon code nice and neat to look at.
158#### Tall and Flat Forms
160There are two rune syntax forms: **tall** and **flat**. Tall form is usually used for multi-line expressions, and flat form is used for one-line expressions. Most runes can be used in either of tall or flat forms. Tall form expressions may contain flat form subexpressions, but flat form expressions may not contain tall form.
162The spacing rules differ in the two forms. In tall form, each rune and subexpression must be separated from the others by a `gap` -- that is, by two or more spaces, or a line break. In flat form the rune is immediately followed by parentheses `( )`, and the various subexpressions inside the parentheses must be separated from the others by an `ace` -- that is, by a single space.
164Seeing an example will help you understand the difference. The `:-` rune is used to produce a cell. Accordingly, it is followed by two subexpressions: the first defines the head of the cell, and the second defines the tail. Here are three different ways to write a `:-` expression in tall form:
166```
167> :- 11 22
168[11 22]
170> :- 11
171 22
172[11 22]
174> :-
175 11
176 22
177[11 22]
178```
180These all do the same thing. The first example shows that, if you want to, you can write 'tall' form code on a single line. Notice that there are two spaces between the `:-` rune and `11`, and also between `11` and `22`. This is the minimum spacing necessary between the various parts of a tall form expression -- any fewer will result in a syntax error.
182Usually one or more line breaks are used to break up a tall form expression. This is especially useful when the subexpressions are themselves long stretches of code. The same `:-` expression in flat-form is:
184```
185> :-(11 22)
186[11 22]
187```
189This is the preferred way to write an expression on a single line. The rune itself is followed by a set of parentheses, and the subexpressions inside are separated by a single space. Any more spacing than that results in a syntax error.
191Nearly all rune expressions can be written in either form, but there are exceptions. `|%` and `|_` expressions, for example, can only be written in tall form. (Those are a bit too complicated to fit comfortably on one line anyway.)
193#### Irregular Forms
195Some runes are used so frequently that they have irregular counterparts that are easier to write and which mean precisely the same thing. Irregular rune syntax is hence a form of [syntactic sugar](https://en.wikipedia.org/wiki/Syntactic_sugar). All irregular rune syntax is flat. (It follows from this that all tall form expressions are regular.)
197Let's look at another example. The `.=` rune takes two subexpressions, evaluates them, and tests the results for equality. If they're equal it produces `%.y` for 'yes'; otherwise `%.n` for 'no'. In tall form:
199```
200> .= 22 11
201%.n
203> .= 22
204 (add 11 11)
205%.y
206```
208And in flat form:
210```
211> .=(22 11)
212%.n
214> .=(22 (add 11 11))
215%.y
216```
218The irregular form of the `.=` rune is just `=( )`:
220```
221> =(22 11)
222%.n
224> =(22 (add 11 11))
225%.y
226```
228The examples above have another irregular form: `(add 11 11)`. This is the irregular form of `%+`, which calls a gate (i.e., a Hoon function) with two arguments for the sample.
230```
231> %+ add 11 11
23222
234> %+(add 11 11)
23522
236```
238The irregular `( )` gate-calling syntax is versatile -- it is also a shortcut for calling a gate with one argument, which is what the `%-` rune is for:
240```
241> (dec 11)
24210
244> %- dec 11
24510
247> %-(dec 11)
24810
249```
251The `( )` gate-calling syntax can be used for gates with any number of arguments.
253You can find other irregular forms in the irregular expression [reference document](@/docs/hoon/hoon-expressions/irregular.md).
255### Expressions That Are Only Irregular
257There are certain irregular expressions that aren't syntactic sugar for regular form equivalents -- they're solely irregular. There isn't much in general that can be said about these because they're all different, but we can look at some examples.
259Below we use the `` ` `` symbol to create a cell whose head is null, `~`.
261```
262> `12
263[~ 12]
265> `[[12 14] 16]
266[~ [12 14] 16]
267```
269Putting `,.` in front of a wing expression removes a face, if there is one.
271```
272> -:[a=[12 14] b=[16 18]]
273a=[12 14]
275> ,.-:[a=[12 14] b=[16 18]]
276[12 14]
278> ,.-:[[12 14] b=[16 18]]
279[12 14]
281> +:[a=[12 14] b=[16 18]]
282b=[16 18]
284> ,.+:[a=[12 14] b=[16 18]]
285[16 18]
286```
288To see other irregular expressions, check the irregular expression [reference document](@/docs/hoon/hoon-expressions/irregular.md).
291## The Standard Library
293The Hoon standard library is a compilation of generally useful Hoon gates (functions). You've seen these already: in expressions like `(add 11 11)`, `add` is a function from the standard library.
295It's important to know about standard library functions, because they make certain tasks much easier, and spare you from having to write the code itself. If you did not use the `add` library function, for example, you would have to write out code like this every time you wanted to find the sum of two numbers:
297```hoon
298++ add
299 ~/ %add
300 |= [a=@ b=@]
301 ^- @
302 ?: =(0 a) b
303 $(a (dec a), b +(b))
304```
306Standard library functions are often built with other standard library functions, but ultimately those functions used are only built with runes. Notice how in the code above `add` is built with the `dec` function, which decrements a value by `1`.
308## Reference Materials
310The Hoon syntax can be intimidating for the uninitiated, so it's good to remember where you can look up expressions can be found. The [reference section](/docs/reference/) itself is a good place to find the reference materials that you need. These children sections are likely to be useful:
312- The [Runes](/docs/hoon/hoon-expressions/) page will show you how to use any Hoon rune.
313- The [Cheat sheet](/docs/reference/cheat-sheet/) is a more compact place to look up rune expressions.
314- The [Standard library](/docs/reference/library/) section has its sub-pages arranged by category. So arithmetic functions, for example, are all found on the same page.
315- The [Hoon Style Guide](/docs/hoon/style/) will show you how to write your Hoon code so that it's idiomatic and easily understood by others.
317### Debugging
319When you have an error in your Hoon code, one of two things can happen. Either the code does not run at all and you get an error (such as `nest-fail`), or your code _does_ run but produces the wrong results. The [Troubleshooting](/docs/reference/troubleshooting/) page is a good resource for figuring out how to debug your code.
321There are a couple useful runes associated with debugging:
323`!:` (zapcol), if written at the top of a Hoon file, turns on a full debugging stack-trace. It's good practice to use whenever you're learning.
325`~&` (sigpam) is used to print its argument every time that argument executes. So, if you wanted to see how many times your program executed `foo`, you would write `foo bar`. Then, when your program runs, it will print `foo` on a new line of output every time the program comes across it by recursion.
327But there are more. Check out the aforementioned [troubleshooting](/docs/reference/troubleshooting/) page to see other handy debugging runes and how to use them.
329### [Next Up: Walkthrough -- Conditionals](../conditionals)