on 52f2e0d help sign in
urbit.org/docs/hoon/basic.md
234 lines 8.3 kB history raw
1---
2navhome: /docs/
3sort: 15
4next: true
5title: Basic types
6---
8# Basic types
10A Hoon `type` is a set of nouns. There is no syntax for directly
11defining the data type of a Hoon expression. Instead, the compiler
12infers the type of a Hoon expression by calculating the range of
13possible values of that expression.
15Working with a type in Hoon normally requires the use of a `mold`.
16Each type is defined by a mold. To define a custom type, you must
17create a custom mold.
19## Molds
21A mathematical function is a mapping from one set (the domain) to
22another (the range). Pass an object from the domain to some
23function *f*, and *f* returns an object from the range. In Hoon we
24can think of a `gate` as a function, where the gate's `sample` is
25its argument.
27A `mold` is an idempotent function whose domain is the set of all
28nouns. (That is, it's an idempotent gate that takes any noun for its
29sample.) An idempotent function *f* is one such that, if *f(x)*
30terminates, *f(x) = f(f(x))*. The product range of a mold is the
31type defined by that mold. That is, each mold's type is the set of
32possible outputs of that mold.
34Essentially, molds are constructor functions. You can pass a mold
35any data you like, and the product is guaranteed be of the type
36defined by that mold. Molds are the perfect tool for validating
37untrusted foreign data. Just call the relevant mold with that data
38and check that the input equals the output. This is one reason why
39molds must be idempotent; if the untrusted data is of the correct
40type, passing it to the mold shouldn't change it. But this use case
41is unusual for beginners; in normal practice you shouldn't call
42molds directly.
44More frequently, molds are used when we want to `cast`. We use a
45cast when we want the Hoon compiler's type-checker to test whether
46a Hoon expression is guaranteed to evaluate to a product of the
47desired type. If it isn't, then the compiler will halt with a
48`nest-fail` crash. Proper Hoon code will include a cast for the
49product type of each gate.
51The `^` family of runes is for casting. In particular, `^-` allows
52us to cast with a mold. For example, we can cast for an `atom` using
53the `@` mold as follows:
55```
56^- @
5717
58```
60Evaluating the above in `dojo` should return 17, because 17 is of
61the type `atom`. On the other hand,
63```
64^- @
65[17 18]
66```
68...this should result in a `nest-fail`, because `[17 18]` is a cell,
69not an atom.
71See the documentation on the [`^` family](../rune/ket/) of runes
72for more information on casts. See the documentation on the
73[`$` family](../rune/buc/) of runes for building molds.
74(Also check out the irregular `,` operator.)
76## `type`: a set of types
78Below is the mold for `type`, which effectively defines all the types
79available in Hoon.
81Strictly speaking, this mold defines the tree data structure the Hoon
82compiler uses to represent type information. It has a label for each
83of the base types, and it's recursive, so a complex type is
84represented as a nested combination of base types and various other
85odds and ends.
87You haven't seen this syntax before, and we haven't explained it yet;
88just treat it as pseudocode.
90This is a slightly simplified version of `type`. We undo and
91explain the simplifications in the [advanced types](../advanced)
92section.
94```
95++ term @tas
96++ type
97 $@ $? %noun
98 %void
99 == $% [%atom p=term q=(unit atom)]
100 [%cell p=type q=type]
101 [%core p=type q=(map term hoon)]
102 [%face p=term q=type]
103 [%fork p=(set type)]
104 [%hold p=type q=hoon]
105 ==
106```
108If the `type`-tree is an atom, it's either a `%noun` or a `%void`; if
109the `type`-tree is a cell, it's a tuple with one of the heads `%atom`,
110`%cell`, `%core`, etc. We'll go through each of these cases below.
111these cases below.
113### `?(%noun %void)`
115`%noun` is the label for the set of all nouns. `%void` is the label
116for the empty set.
118(For now, don't worry too much about the switch from `$` to `%`.)
120### `[%cell p=type q=type]`
122`[%cell p=type q=type]` is for the set of all cells with head `p` and
123tail `q`.
125### `[%fork p=(set type)]`
127`[%fork p=(set type)]` is for the union of all types in the set `p`.
129### `[%hold p=type q=hoon]`
131A `%hold` type, with type `p` and hoon `q`, is a lazy reference
132to the type of `(mint p q)`. In English, it means: "the type of
133the product when we compile `q` against subject `p`."
135Note that this means we can have parsed Hoon AST data in the
136`type`-tree.
138### `[%face p=term q=type]`
140A `[%face p=term q=type]` wraps the label `p` around the type
141`q`. `p` is a `term` or `@tas`, an atomic ASCII string which
142obeys symbol rules: lowercase and digit only, infix hyphen,
143first character must be lowercase.
145See [`%limb`](../limb/limb/) for how labels are resolved. It's
146nontrivial.
148### `[%atom p=term q=(unit atom))]`
150`%atom` is for an atom, with two twists. `q` is a `unit`, Hoon's
151equivalent of a nullable pointer or a Haskell `Maybe`. If `q`
152is `~`, null, the type is *warm*; any atom is in the type.
153If `q` is `[~ x]`, where `x` is any atom, the type is *cold*;
154its only legal value is the constant `x`.
156`p` in the atom is a terminal used as an *aura*, or soft atom
157type. Auras are a lightweight, advisory representation of the
158units, semantics, and/or syntax of an atom. An aura is an atomic
159string; two auras are compatible if one is a prefix of the other.
161For instance, `@t` means UTF-8 text (LSB low), `@ta` means ASCII
162text, and `@tas` means an ASCII symbol. `@u` means an unsigned
163integer, `@ud` an unsigned decimal, `@ux` an unsigned
164hexadecimal. You can use a `@ud` atom as a `@u` or vice versa,
165but not as a `@tas`.
167Auras can also end with an optional, capitalized suffix, which
168defines the atom's bitwidth as a log starting from `A`. For
169example, `@udD` is an unsigned decimal byte; `@uxG` is an
170unsigned 64-bit hexadecimal.
172You can make up your own auras and are encouraged to do so, but
173here are some conventions bound to constant syntax:
175```
176@c UTF-32 codepoint
177@d date
178 @da absolute date
179 @dr relative date (ie, timespan)
180@n nil
181@p phonemic base (plot)
182@r IEEE floating-point
183 @rd double precision (64 bits)
184 @rh half precision (16 bits)
185 @rq quad precision (128 bits)
186 @rs single precision (32 bits)
187@s signed integer, sign bit low
188 @sb signed binary
189 @sd signed decimal
190 @sv signed base32
191 @sw signed base64
192 @sx signed hexadecimal
193@t UTF-8 text (cord)
194 @ta ASCII text (knot)
195 @tas ASCII text symbol (term)
196@u unsigned integer
197 @ub unsigned binary
198 @ud unsigned decimal
199 @uv unsigned base32
200 @uw unsigned base64
201 @ux unsigned hexadecimal
202```
204Auras are truly soft; you can turn any aura into any other,
205statically, by casting through the empty aura `@`. Hoon is not
206dependently typed and can't statically enforce data constraints
207(for example, it can't enforce that a `@tas` is really a symbol).
209### `[%core p=type q=(map term type)]`
211`%core` is for a code-data cell. The data (or *payload*) is the
212tail; the code (or *battery*) is the head. `p`, a type, is the
213type of the payload. `q`, a name-hoon table, is the source code
214for the battery.
216Each hoon in the battery source is compiled to a formula, with
217the core itself as the subject. The battery is a tree of these
218formulas, or *arms*. An arm is a computed attribute against its
219core.
221All code-data structures in normal languages (functions, objects,
222modules, etc) become cores in Hoon. A Hoon battery looks a bit
223like a method table, but not every arm is a "method" in the OO
224sense. An arm is a computed attribute. A method is an arm whose
225product is a Hoon function (or *gate*).
227A gate (function, lambda, etc) is a core with one arm, whose name
228is the empty symbol `$`, and a payload whose shape is `[sample
229context]`. The *context* is the subject in which the gate was
230defined; the *sample* is the argument.
232To call this function on an argument `x`, replace the sample (at
233tree address `6` in the core) with `x`, then compute the arm.
234(Of course, we don't mutate the noun, we make a mutant copy.)