on 3c19574 help sign in
urbit.org/docs/hoon/concepts.md
260 lines 10 kB history raw
1---
2navhome: /docs/
3sort: 14
4next: true
5title: Concepts
6---
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_variable_ or _function_, that map cleanly onto its semantics.
15In Hoon we throw away many of these words and invent new
16ones, which mean almost the same things. But why?
18## Motivation
20Hoon has no close relatives. The normal jargon of programming
21maps poorly onto its semantics. Some of the common concepts used
22only informally in Hoon include "function," "object," "event,"
23"variable," "label," "closure", "environment," "scope," and probably
24a few more. We do use these words informally, but we're always
25making an analogy whose precision depends on context.
27Hoon has concepts *like* all these abstractions, but they remain
28*false cognates*. The closer an inexact cognate, the more
29unsettling it feels when the abstractions don't match. Learning
30a few new words is a small price for avoiding this pain point.
32## Concepts
34A few major Hoon concepts: `noun` (data), `nock` (interpreter),
35[`hoon`](#-hoon) (AST node), [`mint`](#-mint) (compiler), [`type`](#-type) (type),
36`gate` (function), `mold` (constructor), `core` (object), `mark`
37(protocol).
39### <a name="-noun">`noun`</a> (data value)
41A value in Hoon is called a `noun`. A noun is either a
42unsigned integer of any size (`atom`), or an ordered pair of any
43two nouns (`cell`). Nouns are like Lisp S-expressions, but
44simpler (Lisp atoms effectively have dynamic type bits).
46The simplest noun syntax uses brackets, like `[a b]` for the cell
47of `a` and `b`. Brackets nest right; `[a b c d]` is `[a [b [c
48d]]]`.
50A noun list, by convention, goes from left to right and is
51null-terminated. That said, Hoon uses tuples (improper nouns) more
52freely than Lisp; only genuinely iterative structures are
53null-terminated lists.
55When an atom is used as a string (a `cord`), the bytes are always UTF-8
56in LSB first order. When you see `'foo'` and `%foo`, this refers to the
57integer `0x6f.6f66`, aka `7.303.014`. (Hoon syntax uses `.` to break
58integer atoms in the German style, because `.`'s are URL-safe and `,`'s
59aren't.)
61One common operation on nouns is `slot`, a tree addressing
62scheme which maps an atom to a subtree. The whole noun is slot
63`1`; the left child of `n` is `2n`, the right child `2n+1`.
65Nothing in Nock, Hoon, or Urbit can create cycles in a noun or
66detect pointer equivalence. Nouns are generally implemented
67with reference counting, and have a lazy short Merkle hash to
68help with equality testing and associative containers.
70### <a name="-nock">`nock`</a> (interpreter)
72Hoon compiles itself to the [Nock](../../nock) VM. Nock is a
73Turing-complete, non-lambda combinator function. The function
74takes a cell `{subject formula}`, and produces a noun `product`.
76To program in Hoon, this is all you need to know about Nock. But
77it's still fun and useful to [learn more](../../nock).
79## Compilation concepts
81### <a name="-hoon">`hoon`</a> (AST node)
83A [`hoon`](../reference) is the result of parsing a Hoon source
84expression into an AST node. These AST nodes are nouns, like all
85other Hoon data. Because every Hoon program is, in its entirety, a
86single expression of Hoon, the result of parsing the whole thing
87into an AST is a single `hoon`.
89A hoon is a tagged union of the form `[%tag data]`, where the tag
90is a constant such as `%brts` (from the source `|=`, i.e. "bartis"),
91and is matched up with the appropriate type of data (often more
92`hoon`s, from source subexpressions). For example, the expression
93`:-(2 17)`, once parsed into an AST, becomes the following:
95```
96[%clhp p=[%sand p=%ud q=2] q=[%sand p=%ud q=17]]
97```
99The `%clhp` is produced from the rune `:-` (i.e. "colhep"). The 2 and
10017 have each been parsed as `%sand`-tagged hoons, which represent
101atoms (in this case each with an aura of `%ud`, i.e. unsigned
102decimal).
104To parse Hoon source into a hoon AST, use `ream` on a `cord`
105containing Hoon source. Try the following in `dojo`:
107```
108(ream ':+(12 7 %a)')
109```
111The result should be:
113```
114[%clls p=[%sand p=%ud q=12] q=[%sand p=%ud q=7] r=[%rock p=%tas q=97]]
115```
117### <a name="-mint">`mint`</a> (compiler)
119[`mint`](#-mint) is the Hoon compiler. It maps a cell `[type hoon]`
120to a cell `[type nock]`, where a [`type`](#-type) is type
121information, a [`hoon`](#-hoon) is a parsed expression (AST), and a
122`nock` is a Nock formula. `mint` takes as input the subject type
123and a parsed source expression; it produces a product type and an
124executable formula.
126Calculating the output type from the input `hoon` and subject type
127is called "type inference". If you've used another typed functional
128language, like Haskell, the Hoon compiler's type inference does the
129same job but with less intelligence.
131Haskell infers backward and forward; Hoon only infers forward.
132Hoon can't figure out the type of a noun from how you use it,
133only from how you make it. Hoon can infer tail recursion, but
134not head recursion.
136Low-powered type inference means you need more type annotations,
137which makes your program more readable anyway. Also, the dumber
138the compiler, the easier it is for a dumb human to understand
139what the compiler is thinking.
141The `mint` gate is inside the core `++ ut`, so call it using the
142following syntax:
144```
145(~(<gate> <core> <arg 1>) <arg 2> <arg 3>)
146```
148The `<gate>` is mint, the `<core>` is `ut`, `<arg 1>` is the subject
149type, and `<arg 3>` is the parsed Hoon AST (i.e., a `hoon` from the
150last section). What's `<arg 2>`? It's another piece of type
151information. As part of the type-checking process, mint checks that
152the output type "nests" within the input type, i.e. that the output
153type is a subset of the input type. If not, mint halts with a
154`nest-fail` crash.
156Let's compile an example `hoon` from the last subsection into Nock.
157Try the following in Dojo:
159(~(mint ut %noun) %noun [%clhp p=[%sand p=%ud q=2] q=[%sand p=%ud q=17]])
161### <a name="-type">`type`</a> (type, as range)
163A `type` defines a set (finite or infinite) of nouns and ascribes
164some semantics to it. There is no direct syntax for defining
165types; they are always defined by inference (i.e., by
166[`mint`](#-mint)), usually using a constructor (`mold`).
168All types are assembled out of base types defined in `++type`.
169(Look up `++ type` in hoon.hoon for examples.) When the compiler
170does type-inference on a program, it assembles complex types out
171of the simpler built-in types.
173### <a name="-gate">`gate`</a> (function)
175A `gate` is a Hoon function (lambda or closure). Other
176constructs in Urbit are functions in the mathematical sense -- for
177instance, a Nock formula is also a function. But a gate is not a
178formula. The gate's argument is its *sample*; the result is its
179*product*.
181### <a name="-core">`core`</a> (object)
183A `core` has no exact equivalent in conventional languages, but
184the closest equivalent is an object. An object has methods; a
185core has functionally computed attributes (*arms*). An arm that
186produces a gate is the Hoon equivalent of a conventional method;
187think of it as a computed attribute whose value is a lambda.
189A gate is a special case of a core: a core with one arm, whose
190name is the empty string. The shape of a core is `[battery
191payload]`, where *battery* is a tree of Nock formulas
193### <a name="-mold">`mold`</a> (constructor)
195A `mold` is a constructor function (`gate`). Its sample is any
196noun; its product is a structured noun. A mold is idempotent;
197`(mold (mold x))` always equals `(mold x)`.
199Because there's no such thing as a [`type`](#-type) declaration,
200we use molds to define useful types by example; we also use them
201to validate untrusted network data.
203### <a name="-face">`face`</a> (named variable)
205In a conventional language, we have a scope, environment or
206symbol table. Declaring a variable, like e.g. `int foo = 3`,
207adds the name `foo` to the table with type `int`.
209The Hoon analogue is `=/(foo atom 3 ...)`, where `foo` is a `face`
210and `atom` is the type. But Hoon has a homoiconic heap; there is no
211inscrutable scope or environment. There is just the subject, which
212is one noun. To "declare a variable" is to make a cell
213`[variable old-subject]`, and use that as the subject of the next
214expression.
216The label `foo` isn't a key in a symbol table; it's stored as a kind
217of metadata, in the type ([`type`](#-type)) of the new value. It's not
218a variable named `foo`, whose value is of type `atom`; it's a subtree
219of type `foo:atom`.
221### <a name="-limb">`limb`</a> (attribute or variable reference)
223A [`limb`](../limb/limb/), like `foo`, is Hoon's equivalent of a variable
224reference. A limb is a [`hoon`](#-hoon); given a subject [`type`](#-type),
225[`mint`](#-mint) resolves it to a Nock formula and a product [`type`](#-type).
227To resolve limb `foo`, [`mint`](#-mint) searches the subject depth-first,
228head-first for either a `face` named `foo`, or a `core` with the
229arm `foo`. If it finds a face, the product is a *leg*, or
230subtree of the subject. If it finds a core, it computes the arm
231formula with that core as the subject. A limb can also be a slot
232(direct tree address), like `+15`.
234The hoon compiler always resolves a limb to a tree axis lookup,
235regardless of the kind of limb.
237`boo:[foo=12 baz=23 boo=34]` evaluates to `34`.
238`+6:[foo=12 baz=23 boo=34]` evaluates to `baz=23`.
240### <a name="-wing">`wing`</a> ([`limb`](#-limb) path)
242A [wing](../limb/wing/) is a list of limbs. Like attribute
243references in a conventional language, it uses the syntax `a.b.c`,
244but inside out: Hoon `a.b.c` means "a within b within c", the equivalent
245of `c.b.a` in any other language. All limbs but the last, here `a`,
246must be legs.
248### <a name="-mark">`mark`</a> (type, as protocol name)
250A `mark` (really an Arvo concept, not a Hoon concept) is Urbit's
251version of a MIME type, if a MIME type was an executable
252specification. The mark is just a label that's used as a path to
253a local source file in the Arvo filesystem. This source file
254defines a core that can mold untrusted data, diff and patch,
255convert to other marks, etc.
257If this sounds like magic, it isn't quite magic. There's no way
258for different urbits to make sure they mean the same thing by the
259same mark. However, when incompatibility happens, marks ensure
260that we at least handle the situation in a predictable way.