on c1e415f help sign in
urbit.org/docs/hoon/basic.md
232 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 of runes for more information
72on casts. See the documentation on the `$` family of runes for
73building molds. (Also check out the irregular `,` operator.)
75## `type`: a set of types
77Below is the mold for `type`, which effectively defines all the types
78available in Hoon.
80Strictly speaking, this mold defines the tree data structure the Hoon
81compiler uses to represent type information. It has a label for each
82of the base types, and it's recursive, so a complex type is
83represented as a nested combination of base types and various other
84odds and ends.
86You haven't seen this syntax before, and we haven't explained it yet;
87just treat it as pseudocode.
89This is a slightly simplified version of `type`. We undo and
90explain the simplifications in the [advanced types](../advanced)
91section.
93```
94++ term @tas
95++ type
96 $@ $? $noun
97 $void
98 == $% {$atom p/term q/(unit atom)}
99 {$cell p/type q/type}
100 {$core p/type q/(map term hoon)}
101 {$face p/term q/type}
102 {$fork p/(set type)}
103 {$hold p/type q/hoon}
104 ==
105```
107If the `type`-tree is an atom, it's either a `%noun` or a `%void`; if
108the `type`-tree is a cell, it's a tuple with one of the heads `%atom`,
109`%cell`, `%core`, etc. We'll go through each of these cases below.
111### `?($noun $void)`
113`%noun` is the label for the set of all nouns. `%void` is the label
114for the empty set.
116(For now, don't worry too much about the switch from `$` to `%`.)
118### `{$cell p/type q/type}`
120`[%cell p/type q/type]` is for the set of all cells with head `p` and
121tail `q`.
123### `{$fork p/(set type)}`
125`[%fork p/(set type)]` is for the union of all types in the set `p`.
127### `{$hold p/type q/hoon}`
129A `%hold` type, with type `p` and hoon `q`, is a lazy reference
130to the type of `(mint p q)`. In English, it means: "the type of
131the product when we compile `q` against subject `p`."
133Note that this means we can have parsed Hoon AST data in the
134`type`-tree.
136### `{$face p/term q/type}`
138A `[%face p/term q/type]` wraps the label `p` around the type
139`q`. `p` is a `term` or `@tas`, an atomic ASCII string which
140obeys symbol rules: lowercase and digit only, infix hyphen,
141first character must be lowercase.
143See [`:limb`](../twig/limb/limb) for how labels are resolved. It's
144nontrivial.
146### `{%atom p/term q/(unit atom))}`
148`%atom` is for an atom, with two twists. `q` is a `unit`, Hoon's
149equivalent of a nullable pointer or a Haskell `Maybe`. If `q`
150is `~`, null, the type is *warm*; any atom is in the type.
151If `q` is `[~ x]`, where `x` is any atom, the type is *cold*;
152its only legal value is the constant `x`.
154`p` in the atom is a terminal used as an *aura*, or soft atom
155type. Auras are a lightweight, advisory representation of the
156units, semantics, and/or syntax of an atom. An aura is an atomic
157string; two auras are compatible if one is a prefix of the other.
159For instance, `@t` means UTF-8 text (LSB low), `@ta` means ASCII
160text, and `@tas` means an ASCII symbol. `@u` means an unsigned
161integer, `@ud` an unsigned decimal, `@ux` an unsigned
162hexadecimal. You can use a `@ud` atom as a `@u` or vice versa,
163but not as a `@tas`.
165Auras can also end with an optional, capitalized suffix, which
166defines the atom's bitwidth as a log starting from `A`. For
167example, `@udD` is an unsigned decimal byte; `@uxG` is an
168unsigned 64-bit hexadecimal.
170You can make up your own auras and are encouraged to do so, but
171here are some conventions bound to constant syntax:
173```
174@c UTF-32 codepoint
175@d date
176 @da absolute date
177 @dr relative date (ie, timespan)
178@n nil
179@p phonemic base (plot)
180@r IEEE floating-point
181 @rd double precision (64 bits)
182 @rh half precision (16 bits)
183 @rq quad precision (128 bits)
184 @rs single precision (32 bits)
185@s signed integer, sign bit low
186 @sb signed binary
187 @sd signed decimal
188 @sv signed base32
189 @sw signed base64
190 @sx signed hexadecimal
191@t UTF-8 text (cord)
192 @ta ASCII text (span)
193 @tas ASCII symbol (term)
194@u unsigned integer
195 @ub unsigned binary
196 @ud unsigned decimal
197 @uv unsigned base32
198 @uw unsigned base64
199 @ux unsigned hexadecimal
200```
202Auras are truly soft; you can turn any aura into any other,
203statically, by casting through the empty aura `@`. Hoon is not
204dependently typed and can't statically enforce data constraints
205(for example, it can't enforce that a `@tas` is really a symbol).
207### `{$core p/type q/(map term type)}`
209`%core` is for a code-data cell. The data (or *payload*) is the
210tail; the code (or *battery*) is the head. `p`, a type, is the
211type of the payload. `q`, a name-hoon table, is the source code
212for the battery.
214Each hoon in the battery source is compiled to a formula, with
215the core itself as the subject. The battery is a tree of these
216formulas, or *arms*. An arm is a computed attribute against its
217core.
219All code-data structures in normal languages (functions, objects,
220modules, etc) become cores in Hoon. A Hoon battery looks a bit
221like a method table, but not every arm is a "method" in the OO
222sense. An arm is a computed attribute. A method is an arm whose
223product is a Hoon function (or *gate*).
225A gate (function, lambda, etc) is a core with one arm, whose name
226is the empty symbol `$`, and a payload whose shape is `{sample
227context}`. The *context* is the subject in which the gate was
228defined; the *sample* is the argument.
230To call this function on an argument `x`, replace the sample (at
231tree address `6` in the core) with `x`, then compute the arm.
232(Of course, we don't mutate the noun, we make a mutant copy.)