8# Concepts and terminology
10Usually, a new language is an improvement on one you already
11know. If it isn't, it probably at least shares concepts with a
12large family of relatives. These concepts come with words, like
13*type* or *function*, that map cleanly onto its semantics.
15In Hoon we throw away almost all these words and invent new
16ones, which mean almost the same things. But why?
20Hoon has no close relatives. The normal jargon of programming
21maps poorly onto its semantics. For example, although Hoon is a
22typed language, the term "type" is not formally defined in Hoon.
23"Type" is a great word, but Hoon has three separate concepts
24which could comfortably claim it. We say "type" all the time; we
25mean `span`, or `mold`, or `mark`, or possibly all three.
27Other common programming concepts used only informally in Hoon
28are "function," "object," "event," "expression," "variable,"
29"label," "closure", "environment," "scope," and probably a few
30more. We do use these words informally, but we're always making
31an analogy whose precision depends on context.
33Hoon has concepts *like* all these abstractions, but they remain
34*false cognates*. The closer an inexact cognate, the more
35unsettling it feels when the abstractions don't match. Learning
36a few new words is a small price for avoiding this pain point.
40A few major Hoon concepts: `noun` (data), `nock` (interpreter),
41`mint` (compiler), `span` (type), `twig` (expression), `gate`
42(function), `mold` (constructor), `core` (object), `mark`
45### `noun` (data value)
47A value in Hoon is called a `noun`. A noun is either a
48unsigned integer of any size (`atom`), or an ordered pair of any
49two nouns (`cell`). Nouns are like Lisp S-expressions, but
50simpler (Lisp atoms effectively have dynamic type bits).
52The simplest noun syntax uses brackets, like `[a b]` for the cell
53of `a` and `b`. Brackets nest right; `[a b c d]` is `[a [b [c
54d]]]`. You'll also see braces: `{a b c d}`.
56A noun list, by convention, points right and is zero-terminated.
57Hoon uses tuples (improper nouns) more freely than Lisp; only
58genuinely iterative structures are null-terminated lists.
60When an atom is used as a string (a `cord`), the bytes are always
61UTF-8 in LSB first order. When you see `foo`, `$foo`, `%foo`,
62etc, this refers to the integer `0x6f.6f66`, aka `7.303.014`.
63(Hoon syntax breaks integer atoms in the German style.)
65One common operation on nouns is `slot`, a tree addressing
66scheme which maps an atom to a subtree. The whole noun is slot
67`1`; the left child of `n` is `2n`, the right child `2n+1`.
69Nothing in Nock, Hoon or Urbit can create cycles in a noun or
70detect pointer equivalence. Nouns are generally implemented
71with reference counting, and have a lazy short Merkle hash to
72help with equality testing and associative containers.
74### `nock` (interpreter)
76Hoon compiles itself to the [Nock](../../nock) VM. Nock is a
77Turing-complete, non-lambda combinator function. The function
78takes a cell `{subject formula}`, and produces a noun `product`.
80To program in Hoon, this is all you need to know about Nock. But
81it's still bfun and useful to [learn more](../../nock).
83## Compilation concepts
87[`mint`](mint) is the Hoon compiler. It maps a cell `{span twig}` to a
88cell `{span nock}`, where a `span` is a type, a `twig` is a compiled
89expression (AST), and a `nock` is a Nock formula. `mint` accepts
90a subject type and a source expression; it produces a product type
91and an executable formula.
93Calculating the output type from the input type and the source
94code is called "type inference." If you've used another typed
95functional language, like Haskell, Hoon's type inference does the
96same job but with less intelligence.
98Haskell infers backward and forward; Hoon only infers forward.
99Hoon can't figure out the type of a noun from how you use it,
100only from how you make it. Hoon can infer tail recursion, but
103Low-powered type inference means you need more type annotations,
104which makes your program more readable anyway. Also, the dumber
105the compiler, the easier it is for a dumb human to understand
106what the compiler is thinking.
108### `twig` (expression)
110A [`twig`](twig) is a Hoon AST node, the result of parsing a
111source expression. A Hoon source file encodes one twig.
113As the noun that the parser produces, a twig is a tagged union of
114the form `{stem bulb}`, where `stem` (the tag) is a `cord` which
115controls the type of `bulb` (the data).
117As text, each twig has both regular and irregular syntax forms.
118Regular syntax can be either *tall* or *flat*: multiline or
119single-line. Irregular syntax is always flat. Tall twigs can
120contain flat twigs, but not vice versa.
122Regular forms always start with a *sigil*, which is either a
123*keyword* or a *rune* at the programmer's choice. A keyword is
126For most stems, tall regular form has no delimiter or terminator,
127eliminating the `)))))` problem common in functional languages.
128Hoon also uses an unusual "backstep" indentation pattern to
129control left-margin drift.
131Hoon is mildly whitespace-sensitive. It knows the difference
132between no whitespace, one-space, and more-space. But all cases
133of more-space mean the same thing. Flat syntax uses one-space,
134tall syntax more-space.
136As an example, the regular flat keyword syntax `:call(a b)` means
137the same thing as the flat rune syntax `%-(a b)`, the tall
144or the tall rune syntax (here on one line, with double spaces):
149### `span` (type, as range)
151A [`span`](span) is a Hoon type. It defines a set (finite or
152infinite) of nouns and ascribes some semantics to it. There is
153no syntax for spans; they are always defined by inference (ie, by
154`mint`), usually using a constructor (`mold`).
158A `gate` is a Hoon function (lambda or closure). Other
159constructs Urbit are functions in the mathematical sense -- for
160instance, a Nock formula is also a function. But a gate is not a
161formula. The gate's argument is its *sample*; the result is its
166A `core` has no exact equivalent in conventional languages, but
167the closest equivalent is an object. An object has methods; a
168core has functionally computed attributes (*arms*). An arm that
169produces a gate is the Hoon equivalent of a conventional method;
170think of it as a computed attribute whose value is a lambda.
172A gate is a special case of a core: a core with one arm, whose
173name is the empty string. The shape of a core is `[battery
174payload]`, where *battery* is a tree of Nock formulas
176### `mold` (type, as constructor)
178A `mold` is a constructor function (`gate`). Its sample is any
179noun; its product is a structured noun. A mold is idempotent;
180`(mold (mold x))` always equals `(mold x)`.
182Since there's no such thing as a span declaration, we use molds
183to define useful spans by example; we also use them to validate
184untrusted network input.
186### `face` (named variable)
188In a conventional language, we have a scope, environment or
189symbol table. Declaring a variable, like `var foo: atom`, adds
190the name `foo` to the table with type `atom`.
192The Hoon equivalent is `:var foo atom`. But Hoon has a
193homoiconic heap; there is no inscrutable scope or environment.
194There is just the subject, which is one noun. To "declare a
195variable" is to make a cell `[variable old-subject]`, and use it
196as the subject of the twig below.
198So the label `foo` isn't a key in a symbol table; it's in the
199type (`span`) of the new value. It's not a variable named `foo`,
200whose value is of type `atom`; it's a subtree of type `foo:atom`.
202### `limb` (attribute or variable reference)
204A [`limb`](limb), like `foo`, is Hoon's equivalent of a variable
205reference. A limb is a twig; given a subject span, `mint`
206resolves it to a Nock formula and a product span.
208To resolve limb `foo`, `mint` searches the subject depth-first,
209head-first for either a `face` named `foo`, or a `core` with the
210arm `foo`. If it finds a face, the product is a *leg*, or
211subtree of the subject. If it finds a core, it computes the arm
212formula with that core as the subject.
214A limb can also be a slot (direct tree address), like `+15`.
216### `wing` (limb path)
218A wing is a list of limbs. Like attribute references in a
219conventional language, it uses the syntax `a.b.c`, but inside
220out: Hoon `a.b.c` means "a within b within c", the equivalent of
221`c.b.a` in any other language. All limbs but the last, here `a`,
224### `mark` (type, as protocol name)
226A `mark` (really an Arvo concept, not a Hoon concept) is Urbit's
227version of a MIME type, if a MIME type was an executable
228specification. The mark is just a label that's used as a path to
229a local source file in the Arvo filesystem. This source file
230defines a core that can mold untrusted data, diff and patch,
231convert to other marks, etc.
233If this sounds like magic, it isn't quite magic. There's no way
234for different urbits to make sure they mean the same thing by the
235same mark. However, when incompatibility happens, marks ensure
236that we at least handle the situation in a predictable way.
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list