on f3ca521 help sign in
483 lines 15 kB history raw
1+++
2title = "1.2 Nouns"
3weight = 3
4template = "doc.html"
5aliases = ["/docs/learn/hoon/hoon-tutorial/nouns/"]
6+++
8In Urbit, every piece of data is a noun. In order to understand Hoon, one must first understand nouns.
10## Noun Definition
12A **noun** is either an atom or a cell. An **atom** is a natural number ("unsigned integer" in computer lingo) of any size, including zero. A **cell** is an [ordered pair](https://en.wikipedia.org/wiki/Ordered_pair) of nouns, usually indicated with square brackets around the nouns in question; i.e., `[a b]`, where `a` and `b` are nouns.
14Here are some atoms:
16- `0`
17- `87`
18- `325`
20Here are some cells:
22- `[12 13]`
23- `[12 [487 325]]`
24- `[[12 13] [87 65]]`
25- `[[83 [1 17]] [[23 [32 64]] 90]]`
27All of the above are nouns.
29### Nouns as Binary Trees
31A [binary tree](https://en.wikipedia.org/wiki/Binary_tree) has a single base node, and each node of the tree may have up to two child nodes (but it need not have any). A node without children is a 'leaf'. You can think of a noun as a binary tree whose leaves are atoms, i.e., unsigned integers. All non-leaf nodes are cells. To visualize this, consider the following representation of the noun: `[12 [17 45]]`:
33```
34[12 [17 45]]
35 .
36 / \
37 12 .
38 / \
39 17 45
40```
42Each number is an atom; each dot is a cell. Let's look at another example, this time of `[[7 13] [87 65]]`, with the cell nodes shown explicitly:
44```
45 [[7 13] [87 65]]
46 .
47 / \
48 [7 13] [87 65]
49 . .
50 / \ / \
51 7 13 87 65
52```
54An atom is a trivial tree of just one node; e.g., `17`.
56## Atoms
58Atoms are unsigned integers. These are often represented by the dojo as unsigned integers in decimal notation, e.g., `17`.
60To be sure we understand Hoon's atom notation, let's enter some atoms into the dojo:
62```
63> 3
65```
67Seems straightforward.
69```
70> 32
7132
72```
74Why not try it again to make sure?
76```
77> 320
78320
79```
81Can we add another zero?
83```
84> 320
85```
87It didn't work! When you tried to type that next zero and turn `320` into `3200`, the dojo actually _deleted the `0` and beeped at you_.
89Isn't an atom an unsigned integer of any size? It is. But the way to represent the four-digit number `3200` is actually `3.200`:
91```
92> 3.200
933.200
95> (mul 32 100)
963.200
97```
99Just think of it as "3,200", written the German way with a dot.
101Why? Long numbers are difficult to read. We know this, so we group digits in threes. For some reason most programming languages don't use this marvelous innovation. Hoon does.
103English notation for decimals is more common than German notation. Unfortunately, dots are URL-safe and commas aren't. For reasons to be discussed in a later lesson, it's nice to have a regular syntax for atoms that's URL-safe.
105As for why the dojo deleted your zero: it parses the command line as you type, and rejects any characters after the parser stops. This prevents you from entering commands or expressions that aren't well-formed.
107### Atom Auras
109Atoms are nothing more than unsigned integers -- natural numbers -- but it's often useful to represent an atom in a different way. This is done with an **aura**. The aura of an atom is type meta-data used by Hoon to determine how to interpret that atom. It answers the question: What type of information is this atom?
111We use auras because data isn't always represented as a positive decimal number. Sometimes we want to represent data as binary, as text, or as a negative number. Auras allow us to to use such types of data _without changing the underlying atom_.
113We won't fully explain auras and their various uses yet. Auras will be covered more comprehensively in a later lesson. For now let's just look at the various kinds of [literal syntax](https://en.wikipedia.org/wiki/Literal_%28computer_programming%29) associated with a few atom auras.
115In computer science, a 'literal' is an expression that represents and evaluates to a fixed value. The default syntax of an atom literal is the German-style decimal notation, as seen above. Let's look at some other atom literal syntaxes: unsigned binary, unsigned hexadecimal, signed decimal, signed binary and hexadecimal.
117```
118> 0b1001
1190b1001
121> 0b1001.1101
1220b1001.1101
124> 0x9d
1250x9d
127> 0xdead.beef
1280xdead.beef
130> --9
131--9
133> -79
134-79
136> --0b1001
137--0b1001
139> -0x9d
140-0x9d
141```
143All of the above are atoms. The underlying noun of each is just an unsigned integer, but each is written in a special syntax indicating to Hoon that the atom is to be represented in a different way. To see their values in the default atom notation, you can tell Hoon to throw away the aura information. Do this by preceding each expression above with `` `@` ``.
145```
146> `@`0b1001
149> `@`0b1001.1101
150157
152> `@`0x9d
153157
155> `@`0xdead.beef
1563.735.928.559
158> `@`--9
15918
161> `@`-79
162157
164> `@`--0b1001
16518
167> `@`-0x9d
168313
169```
171The `` `@` `` syntax is used to 'cast' a value to a raw atom, i.e., an atom without an aura. Don't worry about exactly what `` `@` `` means just yet. Casts will be explained in more detail in a later lesson. For now all you need to know is that a cast doesn't change the underlying value of the noun; it's used here only to change how the value is printed in the dojo output.
173#### Identities, Cords, and Terms
175Urbit identities such as `~zod` and `~sorreg-namtyv` are also atoms, but of the aura `@p`:
177```
178> ~zod
179~zod
181> ~sorreg-namtyv
182~sorreg-namtyv
184> `@`~zod
187> `@p`0
188~zod
190> `@`~sorreg-namtyv
1915.702.400
193> `@p`5.702.400
194~sorreg-namtyv
195```
197Hoon permits the use of atoms as strings. Strings that are encoded as atoms are called **cords**. Cords are of the aura `@t`. The literal syntax of a cord is text inside a pair of single-quotes, e.g., `'Hello world!'`.
199```
200> 'Howdy!'
201'Howdy!'
203> `@`'Howdy!'
20436.805.260.308.296
206> 'Hello world!'
207'Hello world!'
209> `@`'Hello world!'
21010.334.410.032.606.748.633.331.426.632
211```
213Hoon also has **terms**, of the aura `@tas`. Terms are constant values that are used to tag data using the type system. These are strings preceded with a `%` and made up of lower-case letters, numbers, and hyphens, i.e., 'kebab case'. The first character after the `%` must be a letter. For example, `%a`, `%hello`, `%this-is-kebab-case123`.
215```
216> %howdy
217%howdy
219> %this-is-kebab-case123
220%this-is-kebab-case123
222> `@`%howdy
223521.376.591.720
225> `@`'howdy'
226521.376.591.720
228> `@`%this-is-kebab-case123
22974.823.134.616.534.770.182.309.416.397.866.674.543.716.995.786.868
230```
232#### List of Auras
234Here's a non-exhaustive list of auras, along with examples of corresponding literal syntax:
236```
237Aura Meaning Example of Literal Syntax
238-------------------------------------------------------------------------
239@d date
240 @da absolute date ~2018.5.14..22.31.46..1435
241 @dr relative date (ie, timespan) ~h5.m30.s12
242@n nil ~
243@p phonemic base (urbit name) ~sorreg-namtyv
244@r IEEE floating-point
245 @rd double precision (64 bits) .~6.02214085774e23
246 @rh half precision (16 bits) .~~3.14
247 @rq quad precision (128 bits) .~~~6.02214085774e23
248 @rs single precision (32 bits) .6.022141e23
249@s signed integer, sign bit low
250 @sb signed binary --0b11.1000
251 @sd signed decimal --1.000.056
252 @sv signed base32 -0v1df64.49beg
253 @sw signed base64 --0wbnC.8haTg
254 @sx signed hexadecimal -0x5f5.e138
255@t UTF-8 text (cord) 'howdy'
256 @ta ASCII text (knot) ~.howdy
257 @tas ASCII text symbol (term) %howdy
258@u unsigned integer
259 @ub unsigned binary 0b11.1000
260 @ud unsigned decimal 1.000.056
261 @uv unsigned base32 0v1df64.49beg
262 @uw unsigned base64 0wbnC.8haTg
263 @ux unsigned hexadecimal 0x5f5.e138
264```
266#### Casting to Other Auras
268You can force Hoon to interpret an atom differently by using the aura symbols in the chart above; e.g., `` `@ux` `` for unsigned hexadecimal, `` `@ub` `` for unsigned binary, etc.:
270```
271> `@ux`157
2720x9d
274> `@ub`157
2750b1001.1101
277> `@ub`0x9d
2780b1001.1101
280> `@ux`0b1001.1101
2810x9d
282```
284The atoms in the examples above are all exactly the same value. Only they're interpreted and printed differently, depending on the aura.
286You'll learn more about atoms and auras in [lesson 2.4](../atoms-auras-and-simple-cell-types.md).
288## Cells
290There's not much mystery about cells. The left of a cell is called the **head**, and the right is called the **tail**. Cells are typically represented in Hoon with square brackets around a pair of nouns.
292```
293> [32 320]
294[32 320]
295```
297In this cell `32` is the head and `320` is the tail. Cells can contain cells, and atoms of other auras as well:
299```
300> [%hello 'world!']
301[%hello 'world!']
303> [[%in 0xa] 'cell']
304[[%in 0xa] 'cell']
305```
307I said there isn't _much_ mystery about cells, but there is a little. So far whenever we've entered a cell into the dojo, it not only returned the same cell; the cell was printed in the same way it was entered. This doesn't always happen. The dojo is obligated to evaluate the input and return the correct answer, but it doesn't have to show the result in exactly the same way:
309```
310> [6 [62 620]]
311[6 62 620]
313> [6 62 620]
314[6 62 620]
316> [[6 62] 620]
317[[6 62] 620]
318```
320In the first example, the inner pair of square brackets is dropped. Why did this happen? Why is `[6 62 620]` accepted as a cell despite apparently having more than two atoms in it?
322In fact, `[6 [62 620]]` and `[6 62 620]` are considered equivalent in Hoon. A cell _must_ be a pair, which means there are always exactly two nouns in it. Whenever cell brackets are omitted so that visually there appears to be more than two child nouns, it is implicitly understood that the right-most nouns constitute a cell. That is, the tail of the whole cell is assumed to be a cell of the right-most nouns.
324This is why `[6 [62 620]]` and `[6 62 620]` are equivalent. `[6 [62 620]]` and `[[6 62] 620]`, on the other hand, are not equivalent. If you look at them as binary trees you can see the difference:
326```
327 [6 [62 620]] [[6 62] 620]
328 . .
329 / \ / \
330 6 . . 620
331 / \ / \
332 62 620 6 62
333```
335When the dojo pretty-prints a cell it always removes superfluous cell brackets:
337```
338> [[12 13] [[14 15] [16 17]]]
339[[12 13] [14 15] 16 17]
340```
342However, you should always remember that though cells can be presented as lists of more than two nouns, they're always just pairs.
344### Exercise 1.2a
346Without using the dojo, assess whether each of the following pairs of nouns is equivalent. (Answers are at the bottom of the page.)
348```
3491. [[1 3] [6 2]] [1 3 [6 2]]
3502. [[[17 18] 20] 19 21] [[[17 18] 20] [19 21]]
3513. [[[[[12 13] 14] 15] 16] 17] [12 13 14 15 16 17]
3524. [12 [13 [14 [15 [16 17]]]]] [12 13 14 15 16 17]
3535. [37 [99 17] 83] [37 [[99 17] 83]]
354```
356## Noun Addresses
358Nouns have a regular structure that can be exploited to give a unique **address** to each of its 'sub-nouns'. A sub-noun is a part of a noun that is itself a noun; e.g., `[6 2]` is a sub-noun of `[[1 3] [6 2]]`. We can also call these 'noun fragments'.
360What if you want to refer to a noun fragment, and not the whole thing? For example, what if you want to refer to the `[6 2]` part of `[[1 3] [6 2]]`? One way is to use the unique address of that noun fragment.
362To define noun addresses we'll use recursion. The base case is trivial: address `1` of a noun is the entire noun. The generating case: if the noun at address `n` is a cell, then its head is at address `2n` and its tail is at address `2n + 1`. For example, if address `5` of some noun is a cell, then its head is at address `10` and its tail address `11`.
364Address 1 of the noun `[[1 3] [6 2]]` is the whole noun: `[[1 3] [6 2]]`. The head of the noun at address `1`, `[1 3]`, is at address `2 x 1`, i.e., `2`. The tail of the noun at address `1`, `[6 2]`, is at address `(2 x 1) + 1`, i.e., `3`.
366If the way this works isn't immediately clear, remember that each noun can be understood as a binary tree. The following diagram shows the address of several nodes of the tree:
368```
369 1
370 / \
371 2 3
372 / \ / \
373 4 5 6 7
374 / \
375 14 15
376```
378Let's do some examples in the dojo. We're going to use the `slot` operator, `+`, to return fragments of a noun. For any unsigned integer `n`, `+n` evaluates to the fragment at address `n`.
380```
381> +1:[22 [33 44]]
382[22 33 44]
384> +2:[22 [33 44]]
38522
387> +3:[22 [33 44]]
388[33 44]
390> +6:[22 [33 44]]
39133
393> +7:[22 [33 44]]
39444
395```
397You'll notice that we use the `:` symbol between the slot syntax and the noun. Don't worry about what this means yet; we'll explain it in another lesson. For now you can read it as the word "of": `+7:[22 [33 44]]` is "slot `7` of `[22 [33 44]]`".
399What happens if you ask for a fragment that doesn't exist?
401```
402> +4:[22 [33 44]]
403ford: %ride failed to execute:
404```
406Let's do a few more examples:
408```
409> +2:[['apple' %pie] [0b1101 0xdad]]
410['apple' %pie]
412> +5:[['apple' %pie] [0b1101 0xdad]]
413%pie
415> +2:[[%one %two] [%three %four] [%five %six]]
416[%one %two]
418> +3:[[%one %two] [%three %four] [%five %six]]
419[[%three %four] %five %six]
421> +15:[[%one %two] [%three %four] [%five %six]]
422%six
423```
425For those who prefer to think in terms of binary numbers and binary trees, there is another (equivalent) way to understand noun addressing. When the noun address is expressed as a binary number, you can think of the the number as indicating a tree path from the top node.
427As before, the root of the binary tree (i.e., the whole noun) is at address `1`. For the node of a tree at any address `b`, where `b` is a binary number, you get the address of its head by concatenating a `0` to the end of `b`; and to get its tail, concatenate a `1` to the end. For example, the head of the node at binary address `111` is at `1110`, and the tail is at `1111`.
429Address `1110` indicates "the head of the tail of the tail of the noun".
431### Exercise 1.2b
433Without using the dojo, evaluate the following expressions. (Answers are at the bottom of the page.)
435```
4361. +6:[[34 54] [86 48]]
4372. +3:[13 [[[65 35] 54] 77]]
4383. +12:[13 [[[65 35] 54] 77]]
4394. +7:[13 [[[65 35] 54] 77]]
4405. +10:[[[2 4 5] [3 6]] 11]
441```
443### Exercise 1.2c
445Without using the dojo, for each fragment below provide the address relative to the noun `[51 52 53 54 55]`. (Answers are at the bottom of the page.)
447```
4481. 51
4492. 52
4503. 53
4514. [54 55]
4525. 55
453```
455That's it for our basic introduction to nouns. Hit `ctrl-d` to exit your ship, or else move on to the next lesson.
457## Exercise Answers
459### 1.2a
461+ No
462+ Yes
463+ No
464+ Yes
465+ Yes
467### 1.2b
469+ 86
470+ [[[65 35] 54] 77]
471+ [65 35]
472+ 77
473+ 3
475### 1.2c
477+ +2
478+ +6
479+ +14
480+ +15
481+ +31
483### [Next Up: Reading -- Hoon Syntax](../hoon-syntax)