Structures

The $ family of runes is used for defining custom types. Strictly speaking, these runes are used to produce 'structures'. A structure is a compile-time value that at runtime can be converted to either an example value (sometimes called a 'bunt' value) for its corresponding type, or to a 'factory' (sometimes called a 'mold'). An example value is used as a placeholder for sample values, among other things. A factory/mold is used as a data validator.

Overview

A correct mold is a normalizer: an idempotent function across all nouns. If the sample of a gate has type %noun, and its body obeys the constraint that for any x, =((mold x) (mold (mold x))), it's a normalizer and can be used as a mold.

(Hoon is not dependently typed and so can't check idempotence statically, so we can't actually tell if a mold matches this definition perfectly. This is not actually a problem.)

Validation, though very important, is a rare use case. Except for direct raw input, it's generally a faux pas to rectify nouns at runtime -- or even in userspace.

In any case, since molds are just functions, we can use functional programming to assemble interesting molds. For instance, (map foo bar) is a table from mold foo to mold bar. map is not a mold; it's a function that makes a mold. Molds and mold builders are generally described together.

Base Structures

[%base p=$@(?(%noun %cell %bean %null) [%atom p=aura])]: trivial structures (types).

Produces

A structure is a noun produced, usually at compile-time, for use in tracking types. In most cases, structures don't exist in the runtime semantics.

A structure for the base in p. %noun is any noun; %atom is any atom; %cell is a cell of nouns; %flag is a loobean, ?(`@f`0 `@f`1). %null is zero with aura @n.

Syntax

Irregular: * makes %noun, ^ makes %cell, ? makes %bean, ~ makes %null, @aura makes atom aura.

Runes

$_ "buccab"

[%bscb p=hoon]: structure that normalizes to an example.

Expands to
|=(* p)
Syntax

Regular: 1-fixed.

Irregular: _foo is $_(foo).

Discussion

$_ discards the sample it's supposedly normalizing and produces its example instead.

Examples
~zod:dojo> =foo $_([%foobaz %moobaz])

~zod:dojo> (foo %foo %baz)
[%foobaz %moobaz]

~zod:dojo> `foo`[%foobaz %moobaz]
[%foobaz %moobaz]

~zod:dojo $:foo
[%foobaz %moobaz]

$% "buccen"

[%bscn p=(list spec)]: structure which recognizes a union tagged by head atom.

Defaults to

The default of the last item i in p. Crashes if p is empty.

Syntax

Regular form: 2-running.

Discussion

A $% is a tagged union, a common data model.

Make sure the first item in your $% terminates, or the default will be an infinite loop!

Examples
~zod:dojo> =foo $%([%foo p=@ud q=@ud] [%baz p=@ud])

~zod:dojo> (foo [%baz 37])
[%baz p=37]

~zod:dojo> $:foo
[%foo p=0 q=0]~

"buccol"

[%bscl p=(list spec)]: form a cell type.

Normalizes

The tuple the length of p, normalizing each item.

Defaults to

The tuple the length of p.

Syntax

Regular: running.

Irregular (noun mode): ,[a b c] is $:(a b c). Irregular (structure mode): [a b c] is $:(a b c).

Examples
~zod:dojo> =foo $:(p=@ud q=@tas)

~zod:dojo> (foo 33 %foo)
[p=33 q=%foo]

~zod:dojo> `foo`[33 %foo]
[p=33 q=%foo]

~zod:dojo> $:foo
[p=0 q=%$]

$- "buchep"

[%bshp p=spec q=spec]: structure that normalizes to an example gate.

Expands to
$_  ^|
|=(p $:q)
Syntax

Regular: 2-fixed.

Discussion

Since a $- reduces to a $_, it is not useful for normalizing, just for typechecking. In particular, the existence of $-s does not let us send gates or other cores over the network!

Examples
~zod:dojo> =foo $-(%foo %baz)

~zod:dojo> ($:foo %foo)
%baz

$^ "bucket"

[%bskt p=spec q=spec]: structure which normalizes a union tagged by head depth (cell).

Normalizes to

Default, if the sample is an atom; p, if the head of the sample is an atom; q otherwise.

Defaults to

The default of p.

Syntax

Regular: 2-fixed.

Examples
~zod:dojo> =a $%([%foo p=@ud q=@ud] [%baz p=@ud])

~zod:dojo> =b $^([a a] a)

~zod:dojo> (b [[%baz 33] [%foo 19 22]])
[[%baz p=33] [%foo p=19 q=22]]

~zod:dojo> (b [%foo 19 22])
[%foo p=19 q=22]

~zod:dojo> $:b
[%baz p=0]

$~ "bucsig"

[%bssg p=hoon q=spec]: define a custom type default value

Product

Creates a structure (custom type) just like q, except its default value is p.

Defaults to

The product of p.

Syntax

Regular: 2-fixed.

$~  p=hoon  q=spec

p defines the default value, and q defines everything else about the structure.

Discussion

You should make sure that the product type of p nests under q. You can check the default value of some structure (custom type) r with *r. (See the ^* rune.)

Do not confuse the $~ rune with the constant type for null, $~. (The latter uses older Hoon syntax that is still accepted. Preferably it would be %~.)

Examples

First, let's define a type without using $~:

> =b $@(@tas $%([%two *] [%three *]))

> `b`%hello
%hello

> `b`[%two %hello]
[%two 478.560.413.032]

> *b
%$

> *@tas
%$

Using $~:

> =c $~(%default-value $@(@tas $%([%two *] [%three *])))

> `c`%hello
%hello

> `c`[%two %hello]
[%two 478.560.413.032]

> *c
%default-value

$@ "bucvat"

[%bsvt p=spec q=spec]: structure which normalizes a union tagged by head depth (atom).

Normalizes to

Default, if the sample is an atom; p, if the head of the sample is an atom; q otherwise.

Defaults to

The default of p.

Syntax

Regular: 2-fixed.

Product: a structure which applies p if its sample is an atom, q if its sample is a cell.

Regular form: 2-fixed.

Example:

~zod:dojo> =a $@(%foo $:(p=%baz q=@ud))

~zod:dojo> (a %foo)
%foo

~zod:dojo> `a`[%baz 99]
[p=%baz q=99]

~zod:dojo> $:a
[%foo p=0 q=0]

$= "buctis"

[%bsts p=skin q=spec]: structure which wraps a face around another structure.

Expands to
|=  *
^=(p %-(q +6))
Syntax

Regular: 2-fixed.

Irregular (structure mode): foo=baz is $=(foo baz).

Discussion

Note that the Hoon compiler is at least slightly clever about compiling structures, and almost never has to actually put in a gate layer (as seen in the expansion above) to apply a $=.

Examples
~zod:dojo> =a $=(p %foo)

~zod:dojo> (a %foo)
p=%foo

~zod:dojo> (a %baz)
p=%foo

$? "bucwut"

[%bswt p=(list spec)]: form a type from a union of other types.

Normalizes to

The first item in p which normalizes the sample to itself.

Void, if p is empty.

Defaults to

The first item in p.

Syntax

Regular: running.

Irregular: ?(%foo %baz) is $?(%foo %baz).

Discussion

For a union of atoms, a $? is fine. For more complex nouns, always try to use a $%, $@ or $^, at least if you expect your structure to be used as a normalizer.

Examples
~zod:dojo> =a ?(%foo %baz %baz)

~zod:dojo> (a %baz)
%baz

~zod:dojo> (a [37 45])
%baz

~zod:dojo> $:a
%baz