on ecaaf93 help sign in
urbit.org/docs/hoon/basic.md
185 lines 6.5 kB history raw
1---
2sort: 5
3next: true
4title: Basic types
5---
7# Basic types
9A `span` is a set of nouns and an interpretation of these nouns.
10Officially, we don't use the word "type" in Hoon. But if we had
11to say "type," it would mean `span`.
13## Type, span and mold
15There is no Hoon syntax for a span. The programmer never defines
16a span explicitly. It is always produced as the inferred range
17of an expression (`twig`).
19But we still need simple, well-formed expressions that produce
20regular and well-shaped ranges, for three reasons.
22First: in most cases, this trivial generator should be much
23simpler than the computation itself. Casting the actual result
24to its ideal shape makes sure we know what we're building.
26Second: we can define a standard form for such generators, and
27the standard form is useful. The standard form is a constructor
28function, or *mold*.
30A mold is an idempotent function (`gate`), accepting any noun.
31(An idempotent function is one such that *f(f(x))* equals *f(x)*
32if *f(x)* terminates.) The product range of the function is the
33span, or *icon*, of the mold.
35Usually we use molds purely in the first sense: as an abstract
36definition of a noun. Don't actually call a mold unless you're
37actually validating untrusted foreign data. As a beginner,
38hopefully you aren't!
40## `span`: a set of nouns
42Below is the mold for `span`. You haven't seen this syntax before,
43and we haven't explained it yet; just treat it as pseudocode.
45This is a slightly simplified version of `span`. We undo and explain the
46simplifications in the [advanced types](../advanced) section.
48```
49++ term @tas
50++ span
51 $@ $? $noun
52 $void
53 == $% {$atom p/term q/(unit atom)}
54 {$cell p/span q/span}
55 {$core p/span q/(map term twig)}
56 {$face p/term q/span}
57 {$fork p/(set span)}
58 {$hold p/span q/twig}
59 ==
60```
62If a span is an atom, it's either the atomic string `noun` or
63`void`; if a cell, it's a tuple with one of the heads `atom`,
64`cell`, `core`, etc. We'll go through each of these cases below.
66### `?($noun $void)`
68`$noun` is the set of all nouns. `$void` is the set of no nouns.
70### `{$cell p/span q/span}`
72`{$cell p/span q/span}` is the set of all cells with head `p` and
73tail `q`.
75### `{$fork p/(set span)}`
77`{$fork p/(set span)}` is the union of all spans in the set `p`.
79### `{$hold p/span q/twig}`
81A `$hold` span, with span `p` and twig `q`, is a lazy reference
82to the span of `(mint p q)`. In English it means: "the type of
83the product when we compile `q` against subject `p`.
85This is "manual laziness." Hoon is a strict language, so we have
86to express
88### `{$face p/term q/span}`
90A `{$face p/term q/span}` wraps the label `p` around the span
91`q`. `p` is a `term` or `@tas`, an atomic ASCII string which
92obeys symbol rules: lowercase and digit only, infix hyphen,
93first character must be lowercase.
95See [`:limb`](../twig/limb/limb) for how labels are resolved. It's
96nontrivial.
98### `{%atom p/term q/(unit atom))}`
100An `$atom` is an atom, with two twists. `q` is a `unit`, Hoon's
101equivalent of a nullable pointer or a Haskell `Maybe`. If `q`
102is `~`, null, the span is *warm*; any atom is in the span.
103If `q` is `[~ x]`, where `x` is any atom, the span is *cold*;
104its only legal value is the constant `x`.
106`p` in the atom is a terminal used as an *aura*, or soft atom
107type. Auras are a lightweight, advisory representation of the
108units, semantics, and/or syntax of an atom. An aura is an atomic
109string; two auras are compatible if one is a prefix of the other.
111For instance, `@t` means UTF-8 text (LSB low), `@ta` means ASCII
112text, and `@tas` means an ASCII symbol. `@u` means an unsigned
113integer, `@ud` an unsigned decimal, `@ux` an unsigned
114hexadecimal. You can use a `@ud` atom as a `@u` or vice versa,
115but not as a `@tas`.
117Auras can also end with an optional, capitalized suffix, which
118defines the atom's bitwidth as a log starting from `A`. For
119example, `@udD` is an unsigned decimal byte; `@uxG` is an
120unsigned 64-bit hexadecimal.
122You can make up your own auras and are encouraged to do so, but
123here are some conventions bound to constant syntax:
125```
126@c UTF-32 codepoint
127@d date
128 @da absolute date
129 @dr relative date (ie, timespan)
130@f yes or no (inverse boolean)
131@n nil
132@p phonemic base (plot)
133@r IEEE floating-point
134 @rd double precision (64 bits)
135 @rh half precision (16 bits)
136 @rq quad precision (128 bits)
137 @rs single precision (32 bits)
138@s signed integer, sign bit low
139 @sb signed binary
140 @sd signed decimal
141 @sv signed base32
142 @sw signed base64
143 @sx signed hexadecimal
144@t UTF-8 text (cord)
145 @ta ASCII text (span)
146 @tas ASCII symbol (term)
147@u unsigned integer
148 @ub unsigned binary
149 @ud unsigned decimal
150 @uv unsigned base32
151 @uw unsigned base64
152 @ux unsigned hexadecimal
153```
155Auras are truly soft; you can turn any aura into any other,
156statically, by casting through the empty aura `@`. Hoon is not
157dependently typed and can't statically enforce data constraints
158(for example, it can't enforce that a `@tas` is really a symbol).
160### `{$core p/span q/(map term span)}`
162A `$core` is a code-data cell. The data (or *payload*) is the
163tail; the code (or *battery*) is the head. `p`, a span, is the
164span of the payload. `q`, a name-twig table, is the source code
165for the battery.
167Each twig in the battery source is compiled to a formula, with
168the core itself as the subject. The battery is a tree of these
169formulas, or *arms*. An arm is a computed attribute against its
170core.
172All code-data structures in normal languages (functions, objects,
173modules, etc) become cores in Hoon. A Hoon battery looks a bit
174like a method table, but not every arm is a "method" in the OO
175sense. An arm is a computed attribute. A method is an arm whose
176product is a Hoon function (or *gate*).
178A gate (function, lambda, etc) is a core with one arm, whose name
179is the empty symbol `$`, and a payload whose shape is `{sample
180context}`. The *context* is the subject in which the gate was
181defined; the *sample* is the argument.
183To call this function on an argument `x`, replace the sample (at
184tree address `6` in the core) with `x`, then compute the arm.
185(Of course, we don't mutate the noun, we make a mutant copy.)