@@ -4,38 +4,51 @@ weight = 12
4template = "doc.html"
4template = "doc.html"
5aliases = ["docs/reference/hoon-expressions/rune/buc/"]
5aliases = ["docs/reference/hoon-expressions/rune/buc/"]
7The `$` family of runes is used for defining custom types. Strictly speaking,
8The `$` family of runes is used for defining custom types. Strictly speaking,
8−these runes are used to produce 'structures'. A structure is a compile-time
9+these runes are used to produce `spec`s, which we call 'structures'.
9−value that at runtime can be converted to either an example value (sometimes
10−called a 'bunt' value) for its corresponding type, or to a 'mold'. An example
11−value is used as a placeholder for sample values, among other things. A
12−mold is an idempotent function used as a data validator.
14## Overview
11## Overview
13+Structures are abstract syntax trees for `type`s (see the documentation on
14+[basic](@/docs/reference/hoon-expressions/basic.md) and
15+[advanced](@/docs/reference/hoon-expressions/advanced.md) types for the
16+precise definition of `type`). Structures are compile-time values of `type` which
17+at runtime may be used to produce a 'mold'.
19+A mold is a function from nouns to nouns used to validate values of the type to
20+which the structure defines. A mold can do two things at runtime. First, it may
21+'clam' a noun, which validates the shape of the noun to be one that fits the
22+abstract syntax tree given by the `spec` that produced the mold. Failing this
23+validation results in a crash. Secondly, a mold may also be used to produce an
24+example value of the type to which is corresponds, called the 'bunt value'. The
25+bunt value is used as a placeholder for sample values that may be passed to a
26+gate that accepts the corresponding type.
16−A correct mold is a **normalizer**: an idempotent function across
28+A correct mold is a **normalizer**: an idempotent function across all nouns. If
17−all nouns. If the sample of a gate has type `%noun`, and its
29+the sample of a gate has type `%noun`, and its body obeys the constraint that
18−body obeys the constraint that for any x, `=((mold x) (mold (mold
19−x)))`, it's a normalizer and can be used as a mold.
30+for any x, `=((mold x) (mold (mold x)))`, it's a normalizer and can be used as a
21−(Hoon is not dependently typed and so can't check idempotence
31+mold. Hoon is not dependently typed and so can't check idempotence statically,
22−statically, so we can't actually tell if a mold matches this
32+so we can't actually tell if a mold matches this definition perfectly. This is
23−definition perfectly. This is not actually a problem.)
33+not actually a problem.
25−Validation, though very
26−important, is a rare use case. Except for direct raw input,
27−it's generally a faux pas to rectify nouns at runtime -- or even
30−In any case, since molds are just functions, we can use
35+In any case, since molds are just functions, we can use functional programming
31−functional programming to assemble interesting molds. For
32−instance, `(map foo bar)` is a table from mold `foo` to mold
36+to assemble interesting molds. For instance, `(map foo bar)` is a table from
33−`bar`. `map` is not a mold; it's a function that makes a mold.
37+mold `foo` to mold `bar`. `map` is not a mold; it's a function that makes a
34−Molds and mold builders are generally described together.
38+mold. Molds and mold builders are generally described together.
40+`spec`s contain more information and draw finer distinctions than `type`s,
41+which is to say that a given type may have more than one valid `spec` defining
42+it, and thus downconversion from `spec` to `type` is lossy. Thus structure
43+validation (done with [`$|`](#bucbar), which is a more restrictive validation
44+than that performed by molds, is a rare use case. Except for direct raw input,
45+it's generally a faux pas to validate structure at runtime -- or even in userspace.
46+Nonetheless they are sometimes utilized for types that will be more performant
47+if they satisfy some validating gate.
36## Base Structures
49## Base Structures
38−`[%base p=$@(?(%noun %cell %bean %null) [%atom p=aura])]`: trivial structures (types).
51+`[%base p=$@(?(%noun %cell %flag %null %void) [%atom p=aura])]`: trivial structures (types).
40##### Produces
53##### Produces
@@ -43,15 +56,87 @@ A structure is a noun produced, usually at compile-time, for use in tracking typ
44A structure for the base in `p`. `%noun` is any noun; `%atom` is any
57A structure for the base in `p`. `%noun` is any noun; `%atom` is any
45atom; `%cell` is a cell of nouns; `%flag` is a loobean, ``?(`@f`0
58atom; `%cell` is a cell of nouns; `%flag` is a loobean, ``?(`@f`0
46−`@f`1)``. `%null` is zero with aura `@n`.
59+`@f`1)``. `%null` is zero with aura `@n`, `%void` is the empty set.
48##### Syntax
61##### Syntax
50Irregular: `*` makes `%noun`, `^` makes `%cell`, `?` makes
63Irregular: `*` makes `%noun`, `^` makes `%cell`, `?` makes
51`%bean`, `~` makes `%null`, `@aura` makes atom `aura`.
64`%bean`, `~` makes `%null`, `@aura` makes atom `aura`.
71+`[%bsbr p=spec q=hoon]`: structure that satisfies a validator.
79+`$|` is used for validation of values at a finer level than that of types.
80+Recall that a given value of `type` can be equivalently defined by more than one
81+`spec`. For performance reasons, it may be beneficial to restrict oneself to
82+values of a given type that adhere to an abstract syntax tree specified by some
83+subset of those `spec`s that may be used to define a given type.
85+`$|` takes two arguments: a structure `a` and a gate `b` that produces a `flag`
86+that is used to validate values produced by the mold generated by `a` at
87+runtime. `$|(a b)` is a gate that takes in a noun `x` and first pins the product
88+of clamming `a` with `x`, call this `foo`. Then it calls `b` on `foo`. It
89+asserts that the product of `(b foo)` is `&`, and then produces `foo`. This is
90+equivalent to the following (which is not how `$|` is actually defined but has
100+For example, the elements of a `set` are treated as being unordered, but the
101+values will necessarily possess an order by where they are in the memory. Thus
102+if every `set` is stored using the same order scheme then faster algorithms
103+involving `set`s may be written. Furthermore, if you just place elements in the
104+`set` randomly, it may be mistreated by algorithms already in place that are
105+expecting a certain order. This is not the same thing as casting - it is forcing
106+a type to have a more specific set of values than its mold would suggest. This
107+rune should rarely be used, but it is extremely important when it is.
112+~zod:dojo> =foo $| (list @)
113+ |=(a=(list) (lth (lent a) 4))
115+This creates a structure `foo` whose values are `list`s with length less than 4.
120+ford: %ride failed to execute:
124+The definition of `+set` in `hoon.hoon` is the following:
129+ |=(a=(tree) ~(apt in a))
131+Here [`|$`](@/docs/reference/hoon-expressions/rune/bar.md#barbuc) is used to
132+define a mold builder that takes in a mold (given the face `item`) and creates a
133+structure consisting of a `tree` of `item`s with `$|` that is validated with the
134+gate `|=(a=(tree) ~(apt in a))`. `in` is a door in `hoon.hoon` with functions
135+for handling `set`s, and `apt` is an arm in that door that checks that the
136+values in the `tree` are arranged in the particular way that `set`s are arranged
137+in Hoon, namely 'ascending `+mug` hash order'.
55### `$_` "buccab"
140### `$_` "buccab"
57`[%bscb p=hoon]`: structure that normalizes to an example.
142`[%bscb p=hoon]`: structure that normalizes to an example.