mirror of
https://github.com/urbit/developers.urbit.org.git
synced 2024-09-11 13:55:59 +03:00
Change to old-style anchor links.
This commit is contained in:
parent
373460788f
commit
3a064d530b
@ -399,7 +399,7 @@ it returns the following letter `b` as the result.
|
||||
|
||||
Building complex parsers from simpler parsers is accomplished in Hoon with the
|
||||
use of two tools: the monadic applicator rune
|
||||
[`;~`](/reference/hoon/rune/mic/#micsig) and [parsing
|
||||
[`;~`](/reference/hoon/rune/mic/#-micsig) and [parsing
|
||||
combinators](/reference/hoon/stdlib/4e). First we introduce a few
|
||||
combinators, then we examine more closely how `;~` is used to chain them together.
|
||||
|
||||
@ -412,7 +412,7 @@ The syntax to combine `rule`s is
|
||||
The `rule`s are composed together using the combinator as an
|
||||
intermediate function, which takes the product of a `rule` (an `edge`) and a `rule` and turns
|
||||
it into a sample (a `nail`) for the next `rule` to handle. We elaborate on this
|
||||
behavior [below](#micsig).
|
||||
behavior [below](#-micsig).
|
||||
|
||||
### [`+plug`](/reference/hoon/stdlib/4e/#plug)
|
||||
|
||||
@ -451,7 +451,7 @@ syntax error
|
||||
['a' 'b' 'a']
|
||||
```
|
||||
|
||||
### [`;~`](/reference/hoon/rune/mic/#micsig) {% #micsig %}
|
||||
### [`;~`](/reference/hoon/rune/mic/#-micsig) {% #-micsig %}
|
||||
|
||||
Understanding the rune `;~` is essential to building parsers with Hoon. Let's
|
||||
take this opportunity to think about it carefully.
|
||||
|
@ -334,7 +334,7 @@ And then your style tag might look like:
|
||||
```
|
||||
|
||||
A cord is used rather than a tape so you don't need to escape braces. The
|
||||
[ketsig](/reference/hoon/rune/ket#ketsig) (`^~`) rune means `++trip` will
|
||||
[ketsig](/reference/hoon/rune/ket#-ketsig) (`^~`) rune means `++trip` will
|
||||
be run at compile time rather than call time.
|
||||
|
||||
## Types and marks
|
||||
@ -440,7 +440,7 @@ runes:
|
||||
|
||||
### `;+` Miclus
|
||||
|
||||
The [miclus rune](/reference/hoon/rune/mic#miclus) makes a `$marl` from a
|
||||
The [miclus rune](/reference/hoon/rune/mic#-miclus) makes a `$marl` from a
|
||||
complex hoon expression that produces a single `$manx`. Its main use is nesting
|
||||
tall-form hoon logic in another Sail element. For example:
|
||||
|
||||
@ -467,7 +467,7 @@ Produces one of these depending on the value of `number`:
|
||||
|
||||
### `;*` Mictar
|
||||
|
||||
The [mictar rune](/reference/hoon/rune/mic#mictar) makes a `$marl` (a list
|
||||
The [mictar rune](/reference/hoon/rune/mic#-mictar) makes a `$marl` (a list
|
||||
of XML nodes) from a complex hoon expression. This rune lets you add many
|
||||
elements inside another Sail element. For example:
|
||||
|
||||
@ -501,7 +501,7 @@ elements inside another Sail element. For example:
|
||||
|
||||
### `;=` Mictis
|
||||
|
||||
The [mictis rune](/reference/hoon/rune/mic#mictis) makes a `$marl` (a list
|
||||
The [mictis rune](/reference/hoon/rune/mic#-mictis) makes a `$marl` (a list
|
||||
of XML nodes) from a series of `$manx`es. This is mostly useful if you want to
|
||||
make the list outside of an element and then be able to insert it afterwards.
|
||||
For example:
|
||||
@ -534,7 +534,7 @@ For example:
|
||||
|
||||
### `;/` Micfas
|
||||
|
||||
The [micfas rune](/reference/hoon/rune/mic#micfas) turns an ordinary tape
|
||||
The [micfas rune](/reference/hoon/rune/mic#-micfas) turns an ordinary tape
|
||||
into a `$manx`. For example:
|
||||
|
||||
```
|
||||
|
@ -237,7 +237,7 @@ handle incoming poke `$action`s and outgoing facts or scry result `$update`s.
|
||||
```
|
||||
|
||||
The first thing we do is use the [`=,`
|
||||
rune](/reference/hoon/rune/tis#tiscom) to expose the `++dejs:format`
|
||||
rune](/reference/hoon/rune/tis#-tiscom) to expose the `++dejs:format`
|
||||
namespace. This allows us to reference `ot`, `ni`, etc rather than having to
|
||||
write `ot:dejs:format` every time. Note that you should be careful using `=,`
|
||||
generally as the exposed wings can shadow previous wings if they have the same
|
||||
|
@ -6,7 +6,7 @@ weight = 50
|
||||
In this lesson we'll look at scrying agents, as well as how agents handle such
|
||||
scries. If you're not at all familiar with performing scries in general, have a
|
||||
read through the [Scry Guide](/reference/arvo/concepts/scry), as well as the [dotket
|
||||
rune documentation](/reference/hoon/rune/dot#dotket).
|
||||
rune documentation](/reference/hoon/rune/dot#-dotket).
|
||||
|
||||
## Scrying
|
||||
|
||||
@ -19,7 +19,7 @@ Most of the time, scry requests are handled by Arvo, which routes the request to
|
||||
the appropriate vane. When you scry a Gall agent you actually scry Gall itself.
|
||||
Gall interprets the request, runs it on the specified agent, and then returns
|
||||
the result. Scries are performed with the
|
||||
[dotket](/reference/hoon/rune/dot#dotket) (`.^`) rune. Here's a summary of
|
||||
[dotket](/reference/hoon/rune/dot#-dotket) (`.^`) rune. Here's a summary of
|
||||
their format:
|
||||
|
||||
![scry summary diagram](https://media.urbit.orgreference/arvo/scry-diagram-v2.svg)
|
||||
@ -353,7 +353,7 @@ crash!
|
||||
|
||||
- Have a read through the [Scry Guide](/reference/arvo/concepts/scry).
|
||||
- Have a read through the [dotket rune
|
||||
documentation](/reference/hoon/rune/dot#dotket).
|
||||
documentation](/reference/hoon/rune/dot#-dotket).
|
||||
- Run through the [Example](#example) yourself if you've not done so already.
|
||||
- Try adding another scry endpoint to the `peeker.hoon` agent, which uses a
|
||||
[`wyt:by`](/reference/hoon/stdlib/2i#wytby) map function to produce the
|
||||
|
@ -89,7 +89,7 @@ Recall that the build system will implicitly compose any discrete expressions.
|
||||
If we simply added the helper core below the agent core, the agent core would be
|
||||
composed into the subject of the helper core, which is the opposite of what we
|
||||
want. Instead, we must inversely compose the two cores with a
|
||||
[tisgal](/reference/hoon/rune/tis#tisgal) (`=<`) rune. We add the tisgal
|
||||
[tisgal](/reference/hoon/rune/tis#-tisgal) (`=<`) rune. We add the tisgal
|
||||
rune directly above the agent core like:
|
||||
|
||||
```hoon
|
||||
@ -124,7 +124,7 @@ hc ~(. +> bowl)
|
||||
```
|
||||
|
||||
To get to the helper core we composed from within the door, we use a
|
||||
[censig](/reference/hoon/rune/cen#censig) expression to call `+>` of the
|
||||
[censig](/reference/hoon/rune/cen#-censig) expression to call `+>` of the
|
||||
subject (`.`) with the `bowl` as its sample. After that, any agent arms can make
|
||||
use of helper core functions by calling them like `(some-function:hc ....)`.
|
||||
|
||||
|
@ -9,7 +9,7 @@ A Gall agent is a [door](/reference/glossary/door) with exactly ten [arms](/refe
|
||||
handling certain kinds of events that Gall feeds in to the agent. A door is
|
||||
just a [core](/reference/glossary/core) with a sample - it's made with the
|
||||
[barcab](/reference/hoon/rune/bar#_-barcab) rune (`|_`) instead of the
|
||||
usual [barcen](/reference/hoon/rune/bar#barcen) rune (`|%`).
|
||||
usual [barcen](/reference/hoon/rune/bar#-barcen) rune (`|%`).
|
||||
|
||||
## The ten arms
|
||||
|
||||
|
@ -28,8 +28,8 @@ terminal, and in others it succeeds but does nothing. It has two primary uses:
|
||||
function in `default-agent`, rather than having to manually handle events on
|
||||
those arms.
|
||||
- A common pattern in an agent is to switch on the input of an arm with
|
||||
[wutlus](/reference/hoon/rune/wut#wutlus) (`?+`) runes or maybe
|
||||
[wutcol](/reference/hoon/rune/wut#wutcol) (`?:`) runes. For any
|
||||
[wutlus](/reference/hoon/rune/wut#-wutlus) (`?+`) runes or maybe
|
||||
[wutcol](/reference/hoon/rune/wut#-wutcol) (`?:`) runes. For any
|
||||
unexpected input, you can just pass it to the relevant arm of `default-agent`
|
||||
rather than handling it manually.
|
||||
|
||||
@ -100,11 +100,11 @@ later.
|
||||
An agent core must have exactly ten arms. However, there's a special kind of
|
||||
"virtual arm" that can be added without actually increasing the core's arm
|
||||
count, since it really just adds code to the other arms in the core. A virtual arm is created with the
|
||||
[lustar](/reference/hoon/rune/lus#lustar) (`+*`) rune, and its purpose is
|
||||
[lustar](/reference/hoon/rune/lus#-lustar) (`+*`) rune, and its purpose is
|
||||
to define _deferred expressions_. It takes a list of pairs of names and Hoon
|
||||
expressions. When compiled, the deferred expressions defined in the virtual arm are
|
||||
implicitly inserted at the beginning of every other arm of the core, so they all
|
||||
have access to them. Each time a name in a `+*` is called, the associated Hoon is evaluated in its place, similar to lazy evaluation except it is re-evaluated whenever needed. See the [tistar](/reference/hoon/rune/tis#tistar) reference for more information on deferred expressions.
|
||||
have access to them. Each time a name in a `+*` is called, the associated Hoon is evaluated in its place, similar to lazy evaluation except it is re-evaluated whenever needed. See the [tistar](/reference/hoon/rune/tis#-tistar) reference for more information on deferred expressions.
|
||||
|
||||
A virtual arm in an agent often looks something like this:
|
||||
|
||||
@ -141,9 +141,9 @@ additional cores by composing them into the subject of the agent core itself.
|
||||
The contents of these cores will then be available to arms of the agent core.
|
||||
|
||||
Usually to compose cores in this way, you'd have to do something like insert
|
||||
[tisgar](/reference/hoon/rune/tis#tisgar) (`=>`) runes in between them.
|
||||
[tisgar](/reference/hoon/rune/tis#-tisgar) (`=>`) runes in between them.
|
||||
However, Clay's build system implicitly composes everything in a file by
|
||||
wrapping it in a [tissig](/reference/hoon/rune/tis#tissig) (`=~`)
|
||||
wrapping it in a [tissig](/reference/hoon/rune/tis#-tissig) (`=~`)
|
||||
expression, which means you can just butt separate cores up against one another
|
||||
and they'll all still get composed.
|
||||
|
||||
@ -260,7 +260,7 @@ The key takeaways are:
|
||||
- `dbug` is a library that lets you inspect the state and `bowl` of an agent
|
||||
from the dojo, with the `+dbug` generator.
|
||||
- Convenient deferred expressions for Hoon expressions can be defined in a virtual arm with
|
||||
the [lustar](/reference/hoon/rune/lus#lustar) (`+*`) rune.
|
||||
the [lustar](/reference/hoon/rune/lus#-lustar) (`+*`) rune.
|
||||
- `this` is a conventional deferred expression name for the agent core itself.
|
||||
- `def` is a conventional deferred expression name for accessing arms in the `default-agent`
|
||||
library.
|
||||
|
@ -38,9 +38,9 @@ so you commit a modified version of the file to Clay. When the commit completes,
|
||||
|
||||
A `vase` is just a cell of `[type-of-the-noun the-noun]`. Most data an agent
|
||||
sends or receives will be encapsulated in a vase. A vase is made with the
|
||||
[zapgar](/reference/hoon/rune/zap#zapgar) (`!>`) rune like
|
||||
[zapgar](/reference/hoon/rune/zap#-zapgar) (`!>`) rune like
|
||||
`!>(some-data)`, and unpacked with the
|
||||
[zapgal](/reference/hoon/rune/zap#zapgal) (`!<`) rune like
|
||||
[zapgal](/reference/hoon/rune/zap#-zapgal) (`!<`) rune like
|
||||
`!<(type-to-extract vase)`. Have a read through the [`vase` section of the type
|
||||
reference for details](/guides/core/app-school/types#vase).
|
||||
|
||||
@ -90,7 +90,7 @@ In addition to each of those individual state versions, you'd also define a
|
||||
structure called `versioned-state`, which just contains a union of all the
|
||||
possible states. This way, the vase `on-load` receives can be unpacked to a
|
||||
`versioned-state` type, and then a
|
||||
[wuthep](/reference/hoon/rune/wut#wuthep) (`?-`) expression can switch on
|
||||
[wuthep](/reference/hoon/rune/wut#-wuthep) (`?-`) expression can switch on
|
||||
the head (`%0`, `%1`, `%2`, etc) and process each one appropriately.
|
||||
|
||||
For example, your state definition core might initially look like:
|
||||
@ -134,7 +134,7 @@ it to the subject of the core. The conventional way to do this is by adding the
|
||||
|
||||
The first line bunts (produces the default value) of the state type we defined
|
||||
in the previous core, and adds it to the head of the subject _without a face_.
|
||||
The next line uses [tistar](/reference/hoon/rune/tis#tistar) to give it
|
||||
The next line uses [tistar](/reference/hoon/rune/tis#-tistar) to give it
|
||||
the name of `state`. You might wonder why we don't just give it a face when we
|
||||
bunt it and skip the tistar part. If we did that, we'd have to refer to `tasks`
|
||||
as `tasks.state`. With tistar, we can just reference `tasks` while also being
|
||||
@ -184,7 +184,7 @@ suspended or an app is uninstalled, so that the state can be restored when it's
|
||||
resumed or reinstalled.
|
||||
|
||||
The state is packed in a vase with the
|
||||
[zapgar](/reference/hoon/rune/zap#zapgar) (`!>`) rune, like `!>(state)`.
|
||||
[zapgar](/reference/hoon/rune/zap#-zapgar) (`!>`) rune, like `!>(state)`.
|
||||
|
||||
### `on-load`
|
||||
|
||||
@ -196,8 +196,8 @@ from an old version to the new version if necessary, and load it into the
|
||||
`state` wing of the subject.
|
||||
|
||||
The vase would be unpacked with a
|
||||
[zapgal](/reference/hoon/rune/zap#zapgal) (`!<`) rune, and then typically
|
||||
you'd test its version with a [wuthep](/reference/hoon/rune/wut#wuthep)
|
||||
[zapgal](/reference/hoon/rune/zap#-zapgal) (`!<`) rune, and then typically
|
||||
you'd test its version with a [wuthep](/reference/hoon/rune/wut#-wuthep)
|
||||
(`?-`) expression.
|
||||
|
||||
## Example
|
||||
@ -276,7 +276,7 @@ After that core, we have the usual `agent:dbug` call, and then we have this:
|
||||
|
||||
We've just bunted the `state-0` type, which will produce `[%0 val=0]`, pinning
|
||||
it to the head of the subject. Then, we've use
|
||||
[tistar](/reference/hoon/rune/tis#tistar) (`=*`) to give it a name of
|
||||
[tistar](/reference/hoon/rune/tis#-tistar) (`=*`) to give it a name of
|
||||
`state`.
|
||||
|
||||
Inside our agent core, we have `on-init`:
|
||||
@ -288,7 +288,7 @@ Inside our agent core, we have `on-init`:
|
||||
```
|
||||
|
||||
The `a(b c)` syntax is the irregular form of the
|
||||
[centis](/reference/hoon/rune/cen#centis) (`%=`) rune. You'll likely be
|
||||
[centis](/reference/hoon/rune/cen#-centis) (`%=`) rune. You'll likely be
|
||||
familiar with this from recursive functions, where you'll typically call the buc
|
||||
arm of a trap like `$(a b, c d, ...)`. It's the same concept here - we're saying
|
||||
`this` (our agent core) with `val` replaced by `42`. Since `on-init` is only
|
||||
|
@ -25,7 +25,7 @@ The sample of the gate is usually specified as a cell of `mark` and `vase`
|
||||
rather than just `cage`, simply because it's easier to work with.
|
||||
|
||||
Typically, you'd first test the `mark` with something like a
|
||||
[wutlus](/reference/hoon/rune/wut#wutlus) `?+` expression, passing
|
||||
[wutlus](/reference/hoon/rune/wut#-wutlus) `?+` expression, passing
|
||||
unexpected `mark`s to `default-agent`, which just crashes. We'll look at custom
|
||||
`mark`s in a subsequent lesson, but the basic patten looks like:
|
||||
|
||||
|
@ -150,7 +150,7 @@ manner:
|
||||
```
|
||||
|
||||
Let's break this down a bit. Firstly, our `on-poke` arm includes a
|
||||
[barket](/reference/hoon/rune/bar#barket) (`|^`) rune. Barket creates a
|
||||
[barket](/reference/hoon/rune/bar#-barket) (`|^`) rune. Barket creates a
|
||||
core with a `$` arm that's computed immediately. We extract the `vase` to the
|
||||
`action:todo` type and immediately pass it to the `handle-poke` arm of the core
|
||||
created with the barket. This `handle-poke` arm tests what kind of `action` it's
|
||||
@ -168,7 +168,7 @@ expression:
|
||||
[cards this]
|
||||
```
|
||||
|
||||
The [tisket](/reference/hoon/rune/tis#tisket) (`=^`) expression takes two
|
||||
The [tisket](/reference/hoon/rune/tis#-tisket) (`=^`) expression takes two
|
||||
arguments: A new named noun to pin to the subject (`cards` in this case), and an
|
||||
existing wing of the subject to modify (`state` in this case). Since
|
||||
`handle-poke` produces `(quip card _state)`, we're saving the `card`s it
|
||||
@ -319,8 +319,8 @@ specified in the `src` field of the `bowl` can be trusted to be correct, which
|
||||
makes checking permissions very simple.
|
||||
|
||||
You're free to use whatever logic you want for this, but the most common way is
|
||||
to use [wutgar](/reference/hoon/rune/wut#wutgar) (`?>`) and
|
||||
[wutgal](/reference/hoon/rune/wut#wutgal) (`?<`) runes, which are
|
||||
to use [wutgar](/reference/hoon/rune/wut#-wutgar) (`?>`) and
|
||||
[wutgal](/reference/hoon/rune/wut#-wutgal) (`?<`) runes, which are
|
||||
respectively True and False assertions that crash if they don't evaluate to the
|
||||
expected truth value. To only allow messages from the local ship, you can just
|
||||
do the following in the relevant agent arm:
|
||||
@ -401,7 +401,7 @@ Permissions:
|
||||
## Exercises
|
||||
|
||||
- Have a quick look at the [tisket
|
||||
documentation](/reference/hoon/rune/tis#tisket).
|
||||
documentation](/reference/hoon/rune/tis#-tisket).
|
||||
- Try writing a mark file for the `update:todo` type, in a similar fashion to
|
||||
the `action:todo` one in the [mark file section](#mark-files). You can compare
|
||||
yours to the one we'll use in the next lesson.
|
||||
|
@ -39,7 +39,7 @@ of these next.
|
||||
|
||||
### Create a `vase`
|
||||
|
||||
The [zapgar](/reference/hoon/rune/zap#zapgar) rune (`!>`)
|
||||
The [zapgar](/reference/hoon/rune/zap#-zapgar) rune (`!>`)
|
||||
takes a single argument of any noun, and wraps it in a vase. For example, in the
|
||||
dojo:
|
||||
|
||||
@ -62,7 +62,7 @@ constructing a `card` like a poke or a `%fact` `gift` to be sent off.
|
||||
|
||||
### Extract data from `vase`
|
||||
|
||||
The [zapgal](/reference/hoon/rune/zap#zapgal) rune (`!<`)
|
||||
The [zapgal](/reference/hoon/rune/zap#-zapgal) rune (`!<`)
|
||||
takes two arguments: A mold specifying the type to try and extract the data as,
|
||||
and the vase to be extracted.
|
||||
|
||||
|
@ -93,7 +93,7 @@ Hearkening back to our discussion of interchangeable representations in Lesson -
|
||||
|
||||
There's a special value that recurs in many contexts in Hoon: `~` sig is the null or zero value.
|
||||
|
||||
The [`^-` kethep](/reference/hoon/rune/ket#kethep) rune is useful for ensuring that everything in the second child matches the type (aura) of the first, e.g.
|
||||
The [`^-` kethep](/reference/hoon/rune/ket#-kethep) rune is useful for ensuring that everything in the second child matches the type (aura) of the first, e.g.
|
||||
|
||||
```
|
||||
^- @ux 0x1ab4
|
||||
@ -121,7 +121,7 @@ A cell is a pair of two nouns. Cells are traditionally written using square bra
|
||||
[[1 2] [3 4]]
|
||||
```
|
||||
|
||||
This is actually a shorthand for a rune as well, [`:-` colhep](/reference/hoon/rune/col#colhep):
|
||||
This is actually a shorthand for a rune as well, [`:-` colhep](/reference/hoon/rune/col#-colhep):
|
||||
|
||||
```
|
||||
:- 1 2
|
||||
@ -151,7 +151,7 @@ The backbone of any Hoon expression is a scaffolding of _runes_, which are essen
|
||||
|
||||
A rune is just a pair of ASCII characters (a digraph). We usually pronounce runes by combining their characters’ names, e.g.: “kethep” for `^-`, “bartis” for `|=`, and “barcen” for `|%`.
|
||||
|
||||
For instance, when we called a function earlier (in Hoon parlance, we _slammed a gate_), we needed to provide the [`%-` cenhep](/reference/hoon/rune/cen#cenhep) rune with two bits of information, a function name and the values to associate with it:
|
||||
For instance, when we called a function earlier (in Hoon parlance, we _slammed a gate_), we needed to provide the [`%-` cenhep](/reference/hoon/rune/cen#-cenhep) rune with two bits of information, a function name and the values to associate with it:
|
||||
|
||||
```hoon
|
||||
%-
|
||||
@ -231,9 +231,9 @@ Here is a snippet of Hoon code:
|
||||
==
|
||||
```
|
||||
|
||||
Without looking it up first, what does the [`==` tistis](/reference/hoon/rune/terminators#tistis) do for the [`:~` colsig](/reference/hoon/rune/col#colsig) rune? Hint: some runes can take any number of arguments.
|
||||
Without looking it up first, what does the [`==` tistis](/reference/hoon/rune/terminators#-tistis) do for the [`:~` colsig](/reference/hoon/rune/col#-colsig) rune? Hint: some runes can take any number of arguments.
|
||||
|
||||
> Most runes are used at the beginning of a complex expression, but there are exceptions. For example, the runes [`--` hephep](/reference/hoon/rune/terminators#hephep) and [`==` tistis](/reference/hoon/rune/terminators#tistis) are used at the end of certain expressions.
|
||||
> Most runes are used at the beginning of a complex expression, but there are exceptions. For example, the runes [`--` hephep](/reference/hoon/rune/terminators#-hephep) and [`==` tistis](/reference/hoon/rune/terminators#-tistis) are used at the end of certain expressions.
|
||||
|
||||
#### Aside: Writing Incorrect Code
|
||||
|
||||
|
@ -13,7 +13,7 @@ _This module will teach you how to produce deferred computations for later use,
|
||||
|
||||
Until this point in Hoon School, we have rigorously adhered to the regular syntax of runes so that you could get used to using them. In fact, the only two irregular forms we used were these:
|
||||
|
||||
- Cell definition `[a b]` which represents the [`:-` colhep](/reference/hoon/rune/col#colhep) rune, `:- a b`.
|
||||
- Cell definition `[a b]` which represents the [`:-` colhep](/reference/hoon/rune/col#-colhep) rune, `:- a b`.
|
||||
|
||||
That is, these expressions are all the same for Hoon:
|
||||
|
||||
@ -30,7 +30,7 @@ Until this point in Hoon School, we have rigorously adhered to the regular synta
|
||||
[1 2]
|
||||
```
|
||||
|
||||
- Aura application ``@ux`500`` which represents a double [`^-` kethep](/reference/hoon/rune/ket#kethep), `^- @ux ^- @ 500`.
|
||||
- Aura application ``@ux`500`` which represents a double [`^-` kethep](/reference/hoon/rune/ket#-kethep), `^- @ux ^- @ 500`.
|
||||
|
||||
These are equivalent in Hoon:
|
||||
|
||||
@ -44,7 +44,7 @@ Until this point in Hoon School, we have rigorously adhered to the regular synta
|
||||
|
||||
(Why two `^-`s? We have to clear the type information in general to be able to apply new type information.)
|
||||
|
||||
Hoon developers often employ irregular forms, sometimes called “sugar syntax”. Besides the `:-` colhep and `^-` kethep forms, we will commonly use a new form for [`%-` cenhep](/reference/hoon/rune/cen#cenhep) “function calls”:
|
||||
Hoon developers often employ irregular forms, sometimes called “sugar syntax”. Besides the `:-` colhep and `^-` kethep forms, we will commonly use a new form for [`%-` cenhep](/reference/hoon/rune/cen#-cenhep) “function calls”:
|
||||
|
||||
```hoon
|
||||
> %- add [1 2]
|
||||
@ -86,7 +86,7 @@ So far, every time we have calculated something, we have had to build it from sc
|
||||
|
||||
This has no flexibility: if we want to change `a` we have to rewrite the whole thing every time!
|
||||
|
||||
(Note also our introduction of the [`::` colcol](/reference/hoon/rune/col#colcol) digraph in the above code block. This marks anything following it as a _comment_, meaning that it is meant for the developer and reader, and ignored by the computer.)
|
||||
(Note also our introduction of the [`::` colcol](/reference/hoon/rune/col#-colcol) digraph in the above code block. This marks anything following it as a _comment_, meaning that it is meant for the developer and reader, and ignored by the computer.)
|
||||
|
||||
Hoon uses _gates_ as deferred computations. What this means is that we can build a Hoon expression now and use it at need later on, perhaps many times. More than that, we can also use it on different data values. A gate is the Hoon analogue of a [function or subroutine](https://en.wikipedia.org/wiki/Subroutine) in other programming languages.
|
||||
|
||||
@ -98,7 +98,7 @@ Functions are implemented in Hoon with a special kind of [core](/reference/gloss
|
||||
|
||||
### Building a Gate
|
||||
|
||||
Syntactically, a gate is a [`|=` bartis](/reference/hoon/rune/bar#bartis) rune with two children: a [`spec`](/reference/hoon/stdlib/4o#spec) (specification of input) and a [`hoon`](/reference/hoon/stdlib/4o#hoon) (body). Think of just replacing the `=/` tisfas with the `|=` bartis:
|
||||
Syntactically, a gate is a [`|=` bartis](/reference/hoon/rune/bar#-bartis) rune with two children: a [`spec`](/reference/hoon/stdlib/4o#spec) (specification of input) and a [`hoon`](/reference/hoon/stdlib/4o#hoon) (body). Think of just replacing the `=/` tisfas with the `|=` bartis:
|
||||
|
||||
```hoon
|
||||
:: Confirm whether a value is greater than one.
|
||||
@ -116,7 +116,7 @@ Beyond those, what is the purpose of each line?
|
||||
|
||||
The [`spec`](/reference/hoon/stdlib/4o#spec) gives the type as a mold and attaches a face to it for use in the gate.
|
||||
|
||||
The [`hoon`](/reference/hoon/stdlib/4o#hoon) body expression evaluates and yields a result, ultimately sent back to the call site. Frequently it is wise to explicitly require a particular type for the return value using the [`^-` kethep](/reference/hoon/rune/ket#kethep) rune:
|
||||
The [`hoon`](/reference/hoon/stdlib/4o#hoon) body expression evaluates and yields a result, ultimately sent back to the call site. Frequently it is wise to explicitly require a particular type for the return value using the [`^-` kethep](/reference/hoon/rune/ket#-kethep) rune:
|
||||
|
||||
```hoon
|
||||
:: Confirm whether a value is greater than one.
|
||||
@ -361,7 +361,7 @@ Hoon source files are composed almost entirely of the printable ASCII characters
|
||||
|
||||
### Coding Piecemeal
|
||||
|
||||
If you need to test code without completing it, you can stub out as-yet-undefined arms with the [`!!` zapzap](/reference/hoon/rune/zap#zapzap) crash rune. `!!` is the only rune which has no children, and it's helpful when you need something to satisfy Hoon syntax but aren't ready to flesh out the program yet.
|
||||
If you need to test code without completing it, you can stub out as-yet-undefined arms with the [`!!` zapzap](/reference/hoon/rune/zap#-zapzap) crash rune. `!!` is the only rune which has no children, and it's helpful when you need something to satisfy Hoon syntax but aren't ready to flesh out the program yet.
|
||||
|
||||
### Building Code Generally
|
||||
|
||||
|
@ -337,7 +337,7 @@ We commonly need to do one of two things with a mold:
|
||||
|
||||
We often use bunts to clam; for example ``@ud` implicitly uses the `@ud` default value (`0`) as the type specimen which the computation must match.
|
||||
|
||||
To _actually_ get the bunt value, use the [`^*` kettar](/reference/hoon/rune/ket#kettar) rune, almost always used in its irregular form `*` tar:
|
||||
To _actually_ get the bunt value, use the [`^*` kettar](/reference/hoon/rune/ket#-kettar) rune, almost always used in its irregular form `*` tar:
|
||||
|
||||
```hoon
|
||||
> ^* @ud
|
||||
@ -353,7 +353,7 @@ To _actually_ get the bunt value, use the [`^*` kettar](/reference/hoon/rune/ket
|
||||
[0 0x0 0b0]
|
||||
```
|
||||
|
||||
One more way to validate against type is to use an example instead of the extracted mold. This uses the [`^+` ketlus](/reference/hoon/rune/ket#ketlus) rune similarly to how we used `^-` ketlus previously:
|
||||
One more way to validate against type is to use an example instead of the extracted mold. This uses the [`^+` ketlus](/reference/hoon/rune/ket#-ketlus) rune similarly to how we used `^-` ketlus previously:
|
||||
|
||||
```hoon
|
||||
^+(1.000 100)
|
||||
@ -392,7 +392,7 @@ Most of the time, we will define such complex types using specific runes and “
|
||||
|
||||
### Identifying Molds
|
||||
|
||||
Besides `?` (which is a Dojo-specific tool), the programmatic way to figure out which mold the Hoon compiler thinks something is to use the [`!>` zapgar](/reference/hoon/rune/zap#zapgar) rune.
|
||||
Besides `?` (which is a Dojo-specific tool), the programmatic way to figure out which mold the Hoon compiler thinks something is to use the [`!>` zapgar](/reference/hoon/rune/zap#-zapgar) rune.
|
||||
|
||||
```
|
||||
> !>(0xace2.bead)
|
||||
@ -408,7 +408,7 @@ For reasons which will be elaborated in Trees, this is often employed as the so-
|
||||
|
||||
### Type Unions
|
||||
|
||||
[`$?` bucwut](/reference/hoon/rune/buc#bucwut) forms a type union.
|
||||
[`$?` bucwut](/reference/hoon/rune/buc#-bucwut) forms a type union.
|
||||
|
||||
For instance, if you wanted a gate to return one of an unsigned aura type, but no other type, you could define a type union thus:
|
||||
|
||||
|
@ -22,7 +22,7 @@ Computers were built and designed to carry out tasks which were too dainty and t
|
||||
|
||||
In programming, we call this behavior a “loop”. A loop describes the situation in which we set up some condition, and repeat a process over and over until something we do meets that condition. _Most_ of the time, this means counting once for each item in a collection, like a list.
|
||||
|
||||
Hoon effects the concept of a loop using recursion, return to a particular point in an expression (presumably with some different values). One way to do this is using the [`|-` barhep](/reference/hoon/rune/bar#barhep) rune, which creates a structure called a _trap_. (Think of the “trap” in the bottom of your sink.) It means a point to which you can return again, perhaps with some key values (like a counter) changed. Then you can repeat the calculation inside the trap again. This continues until some single value, some noun, results, thereby handing a value back out of the expression. (Remember that every Hoon expression results in a value.)
|
||||
Hoon effects the concept of a loop using recursion, return to a particular point in an expression (presumably with some different values). One way to do this is using the [`|-` barhep](/reference/hoon/rune/bar#-barhep) rune, which creates a structure called a _trap_. (Think of the “trap” in the bottom of your sink.) It means a point to which you can return again, perhaps with some key values (like a counter) changed. Then you can repeat the calculation inside the trap again. This continues until some single value, some noun, results, thereby handing a value back out of the expression. (Remember that every Hoon expression results in a value.)
|
||||
|
||||
This program adds 1+2+3+4+5 and returns the sum:
|
||||
|
||||
@ -120,9 +120,9 @@ You can do even better using _interpolation_:
|
||||
==
|
||||
```
|
||||
|
||||
- We are using the `=` irregular syntax for the [`.=` dottis](/reference/hoon/rune/dot#dottis) rune, which tests for the equality of two expressions.
|
||||
- We are using the `=` irregular syntax for the [`.=` dottis](/reference/hoon/rune/dot#-dottis) rune, which tests for the equality of two expressions.
|
||||
|
||||
- We are using the `+` irregular syntax for the [`.+` dotlus](/reference/hoon/rune/dot#dotlus) rune, which increments a value (adds one).
|
||||
- We are using the `+` irregular syntax for the [`.+` dotlus](/reference/hoon/rune/dot#-dotlus) rune, which increments a value (adds one).
|
||||
|
||||
```hoon
|
||||
> +factorial 5
|
||||
@ -176,7 +176,7 @@ As we write more complicated programs, it is helpful to learn to read the runes
|
||||
|
||||
Recall that the `::` digraph tells the compiler to ignore the rest of the text on the line. Such text is referred to as a "comment" because, instead of performing a computation, it exists to explain things to human readers of the source code. Here, we have also explicitly marked the expansion of the irregular forms.
|
||||
|
||||
We will revert to the irregular form more and more. If you would like to see exactly how an expression is structured, you can use the [`!,` zapcom](/reference/hoon/rune/zap#zapcom) rune. `!,` zapcom produces an annotated _abstract syntax tree_ (AST) which labels every value and expands any irregular syntax into the regular runic form.
|
||||
We will revert to the irregular form more and more. If you would like to see exactly how an expression is structured, you can use the [`!,` zapcom](/reference/hoon/rune/zap#-zapcom) rune. `!,` zapcom produces an annotated _abstract syntax tree_ (AST) which labels every value and expands any irregular syntax into the regular runic form.
|
||||
|
||||
```hoon
|
||||
> !, *hoon (add 5 6)
|
||||
@ -298,7 +298,7 @@ Every expression of Hoon is evaluated relative to a subject. An [_arm_](/refere
|
||||
|
||||
#### Arms for Gates
|
||||
|
||||
Within a core, we label arms as Hoon expressions (frequently `|=` bartis gates) using the [`++` luslus](/reference/hoon/rune/lus#luslus) digraph. (`++` isn't formally a rune because it doesn't actually change the structure of a Hoon expression, it simply marks a name for an expression or value. The `--` hephep limiter digraph is used because `|%` barcen can have any number of arms attached. Like `++`, it is not formally a rune.)
|
||||
Within a core, we label arms as Hoon expressions (frequently `|=` bartis gates) using the [`++` luslus](/reference/hoon/rune/lus#-luslus) digraph. (`++` isn't formally a rune because it doesn't actually change the structure of a Hoon expression, it simply marks a name for an expression or value. The `--` hephep limiter digraph is used because `|%` barcen can have any number of arms attached. Like `++`, it is not formally a rune.)
|
||||
|
||||
```hoon
|
||||
|%
|
||||
@ -331,7 +331,7 @@ Notice here that we read the arm resolution from right-to-left. This isn't the
|
||||
|
||||
#### Arms for Types
|
||||
|
||||
We can define custom types for a core using [`+$` lusbuc](/reference/hoon/rune/lus#lusbuc) digraphs. We won't do much with these yet but they will come in handy for custom types later on.
|
||||
We can define custom types for a core using [`+$` lusbuc](/reference/hoon/rune/lus#-lusbuc) digraphs. We won't do much with these yet but they will come in handy for custom types later on.
|
||||
|
||||
This core defines a set of types intended to work with playing cards:
|
||||
|
||||
@ -469,7 +469,7 @@ n
|
||||
==
|
||||
```
|
||||
|
||||
Even more compactly, `(add counter 1)` can be replaced by the Nock increment rune, [`.+` dotlus](/reference/hoon/rune/dot#dotlus), for the equivalent version:
|
||||
Even more compactly, `(add counter 1)` can be replaced by the Nock increment rune, [`.+` dotlus](/reference/hoon/rune/dot#-dotlus), for the equivalent version:
|
||||
|
||||
```hoon
|
||||
|= n=@ud
|
||||
|
@ -506,7 +506,7 @@ n
|
||||
$(n (dec n))
|
||||
```
|
||||
|
||||
The `$()` syntax is the commonly-used irregular form of the [`%=` centis](/reference/hoon/rune/cen#centis) rune.
|
||||
The `$()` syntax is the commonly-used irregular form of the [`%=` centis](/reference/hoon/rune/cen#-centis) rune.
|
||||
|
||||
Now, we noted that `$` buc is the default arm for the trap. It turns out that `$` is also the default arm for some other structures, like the gate! That means we can cut out the trap, in the factorial example, and write something more compact like this:
|
||||
|
||||
@ -591,7 +591,7 @@ A further tweak maps to `@t` ASCII characters instead of the digits.
|
||||
|
||||
(Notice that we apply `@t` as a mold gate rather than using the tic notation. This is because `^` ket is a rare case where the order of evaluation of operators would cause the intuitive writing to fail.)
|
||||
|
||||
- Extend the above generator so that it accepts a cell of type and value (a `vase` as produced by the [`!>` zapgar](/reference/hoon/rune/zap#zapgar) rune). Use the type to determine which number base the digit string should be constructed from; e.g. `+num2dig !>(0xdead.beef)` should yield `~['d' 'e' 'a' 'd' 'b' 'e' 'e' 'f']`.
|
||||
- Extend the above generator so that it accepts a cell of type and value (a `vase` as produced by the [`!>` zapgar](/reference/hoon/rune/zap#-zapgar) rune). Use the type to determine which number base the digit string should be constructed from; e.g. `+num2dig !>(0xdead.beef)` should yield `~['d' 'e' 'a' 'd' 'b' 'e' 'e' 'f']`.
|
||||
|
||||
#### Exercise: Resolving Wings
|
||||
|
||||
|
@ -63,14 +63,14 @@ For simplicity, everything we do will take place on the `%base` desk for now. W
|
||||
|
||||
Another common design pattern besides creating a library is to sequester core-specific behavior in a helper core, which sits next to the interface operations. Two runes are used to compose expressions together so that the subject has everything it needs to carry out the desired calculations.
|
||||
|
||||
- [`=>` tisgar](/reference/hoon/rune/tis#tisgar) composes two expressions so that the first is included in the second's subject (and thus can see it).
|
||||
- [`=<` tisgal](/reference/hoon/rune/tis#tisgal) inverts the order of composition, allowing heavier helper cores to be composed after the core's logic but still be available for use.
|
||||
- [`=>` tisgar](/reference/hoon/rune/tis#-tisgar) composes two expressions so that the first is included in the second's subject (and thus can see it).
|
||||
- [`=<` tisgal](/reference/hoon/rune/tis#-tisgal) inverts the order of composition, allowing heavier helper cores to be composed after the core's logic but still be available for use.
|
||||
|
||||
Watch for these being used in generators and libraries over the next few modules.
|
||||
|
||||
#### Exercise: A Playing Card Library
|
||||
|
||||
In this exercise, we examine a library that can be used to represent a deck of 52 playing cards. The core below builds such a library, and can be accessed by programs. You should recognize most of the things this program does aside from the `++shuffle-deck` arm which uses a [door](./K-doors.md) to produce [randomness](./O-subject.md). This is fairly idiomatic Hoon and it relies a lot on the convention that heavier code should be lower in the expression. This means that instead of `?:` wutcol you may see [`?.` wutdot](/reference/hoon/rune/wut#wutdot), which inverts the order of the true/false arms, as well as other new constructions.
|
||||
In this exercise, we examine a library that can be used to represent a deck of 52 playing cards. The core below builds such a library, and can be accessed by programs. You should recognize most of the things this program does aside from the `++shuffle-deck` arm which uses a [door](./K-doors.md) to produce [randomness](./O-subject.md). This is fairly idiomatic Hoon and it relies a lot on the convention that heavier code should be lower in the expression. This means that instead of `?:` wutcol you may see [`?.` wutdot](/reference/hoon/rune/wut#-wutdot), which inverts the order of the true/false arms, as well as other new constructions.
|
||||
|
||||
```hoon
|
||||
|%
|
||||
@ -149,7 +149,7 @@ One way to get a feel for how a library works is to skim the `++` luslus arm-nam
|
||||
==
|
||||
```
|
||||
|
||||
`++num-to-suit` defines a gate which takes a single `@ud` unsigned decimal integer and produces a `suit`. The [`?+` wutlus](/reference/hoon/rune/wut#wutlus) rune creates a structure to switch against a value with a default in case there are no matches. (Here the default is to crash with [`!!` zapzap](/reference/hoon/rune/zap#zapzap).) We then have options 1–4 which each resulting in a different suit.
|
||||
`++num-to-suit` defines a gate which takes a single `@ud` unsigned decimal integer and produces a `suit`. The [`?+` wutlus](/reference/hoon/rune/wut#-wutlus) rune creates a structure to switch against a value with a default in case there are no matches. (Here the default is to crash with [`!!` zapzap](/reference/hoon/rune/zap#-zapzap).) We then have options 1–4 which each resulting in a different suit.
|
||||
|
||||
```hoon
|
||||
++ make-deck
|
||||
@ -171,7 +171,7 @@ One way to get a feel for how a library works is to skim the `++` luslus arm-nam
|
||||
|
||||
`++make-deck` assembles a deck of 52 cards by cycling through every possible suit and number and combining them. It uses `++num-to-suit` and a couple of loops to go through the counters. It has an interesting `^$` loop skip where when `j` is greater than 14 it jumps instead to the outer loop, incrementing `i`.
|
||||
|
||||
[`?.` wutdot](/reference/hoon/rune/wut#wutdot) may be an unfamiliar rune; it is simply the inverted version of `?:` wutcol, so the first branch is actually the if-false branch and the second is the if-true branch. This is done to keep the “heaviest” branch at the bottom, which makes for more idiomatic and readable Hoon code.
|
||||
[`?.` wutdot](/reference/hoon/rune/wut#-wutdot) may be an unfamiliar rune; it is simply the inverted version of `?:` wutcol, so the first branch is actually the if-false branch and the second is the if-true branch. This is done to keep the “heaviest” branch at the bottom, which makes for more idiomatic and readable Hoon code.
|
||||
|
||||
```hoon
|
||||
++ draw
|
||||
@ -204,13 +204,13 @@ One way to get a feel for how a library works is to skim the `++` luslus arm-nam
|
||||
|
||||
Finally we come to `++shuffle-deck`. This gate takes two arguments: a `deck`, and a `@` as a bit of `entropy` to seed the `og` random-number core. It will produce a `deck`.
|
||||
|
||||
We add a bunted `deck`, then encounter a very interesting statement that you haven't run into yet. This is the irregular form of [`%~` censig](/reference/hoon/rune/cen#censig), which “evaluates an arm in a door.” For our purposes now, you can see it as a way of creating a random-value arm that we'll use later on with `++rads:random`.
|
||||
We add a bunted `deck`, then encounter a very interesting statement that you haven't run into yet. This is the irregular form of [`%~` censig](/reference/hoon/rune/cen#-censig), which “evaluates an arm in a door.” For our purposes now, you can see it as a way of creating a random-value arm that we'll use later on with `++rads:random`.
|
||||
|
||||
With `=/ remaining (lent unshuffled)`, we get the length of the unshuffled deck with [`++lent`](/reference/hoon/stdlib/2b#lent).
|
||||
|
||||
`?: =(remaining 1)` checks if we have only one card remaining. If that's true, we produce a cell of `shuffled` and the one card left in `unshuffled`. We use the [`:_` colcab](/reference/hoon/rune/col#colcab) rune here, so that the “heavier” expression is at the bottom.
|
||||
`?: =(remaining 1)` checks if we have only one card remaining. If that's true, we produce a cell of `shuffled` and the one card left in `unshuffled`. We use the [`:_` colcab](/reference/hoon/rune/col#-colcab) rune here, so that the “heavier” expression is at the bottom.
|
||||
|
||||
If the above conditional evaluates to `%.n` false, we need to do a little work. [`=^` tisket](/reference/hoon/rune/tis#tisket) is a rune that pins the head of a pair and changes a leg in the subject with the tail. It's useful for interacting with the `og` core arms, as many of them produce a pair of a random numbers and the next state of the core. We're going to put the random number in the subject with the face `index` and change `random` to be the next core.
|
||||
If the above conditional evaluates to `%.n` false, we need to do a little work. [`=^` tisket](/reference/hoon/rune/tis#-tisket) is a rune that pins the head of a pair and changes a leg in the subject with the tail. It's useful for interacting with the `og` core arms, as many of them produce a pair of a random numbers and the next state of the core. We're going to put the random number in the subject with the face `index` and change `random` to be the next core.
|
||||
|
||||
With that completed, we use `%=` centis to call `$` buc to recurse back up to `|-` barhep with a few changes:
|
||||
|
||||
|
@ -146,7 +146,7 @@ In `/lib/test.hoon` we find a core with a few gates: `++expect`, `++expect-eq`,
|
||||
result
|
||||
```
|
||||
|
||||
Test code deals in `vase`s, which are produced by [`!>` zapgar](/reference/hoon/rune/zap#zapgar) as a cell of the type of a value and the value.
|
||||
Test code deals in `vase`s, which are produced by [`!>` zapgar](/reference/hoon/rune/zap#-zapgar) as a cell of the type of a value and the value.
|
||||
|
||||
`++expect-fail` by contrast take a `|.` bardot trap (a trap that has the `$` buc arm but hasn't been called yet) and verifies that the code within fails.
|
||||
|
||||
@ -176,8 +176,8 @@ Formal error messages in Urbit are built of tanks.
|
||||
|
||||
As your code evaluates, the Arvo runtime maintains a _stack trace_, or list of the evaluations and expressions that got the program to its notional point of computation. When the code fails, any error hints currently on the stack are dumped to the terminal for you to see what has gone wrong.
|
||||
|
||||
- The [`~_` sigcab](/reference/hoon/rune/sig/#sigcab) rune, described as a “user-formatted tracing printf”, can include an error message for you, requiring you to explicitly build the `tank`. (`printf` is a reference to [C's I/O library](https://en.wikipedia.org/wiki/Printf_format_string).)
|
||||
- The [`~|` sigbar](/reference/hoon/rune/sig/#sigbar) rune, a “tracing printf”, can include an error message from a simple `@t` cord.
|
||||
- The [`~_` sigcab](/reference/hoon/rune/sig/#-sigcab) rune, described as a “user-formatted tracing printf”, can include an error message for you, requiring you to explicitly build the `tank`. (`printf` is a reference to [C's I/O library](https://en.wikipedia.org/wiki/Printf_format_string).)
|
||||
- The [`~|` sigbar](/reference/hoon/rune/sig/#-sigbar) rune, a “tracing printf”, can include an error message from a simple `@t` cord.
|
||||
|
||||
What this means is that these print to the stack trace if something fails, so you can use either rune to contribute to the error description:
|
||||
|
||||
@ -187,7 +187,7 @@ As your code evaluates, the Arvo runtime maintains a _stack trace_, or list of t
|
||||
!!
|
||||
```
|
||||
|
||||
- The [`!:` zapcol`](/reference/hoon/rune/zap/#zapcol) rune turns on line-by-line stack tracing, which is extremely helpful when debugging programs. Drop it in on the first Hoon line (after `/` fas imports) of a generator or library while developing.
|
||||
- The [`!:` zapcol`](/reference/hoon/rune/zap/#-zapcol) rune turns on line-by-line stack tracing, which is extremely helpful when debugging programs. Drop it in on the first Hoon line (after `/` fas imports) of a generator or library while developing.
|
||||
|
||||
```hoon
|
||||
> (sub 0 1)
|
||||
|
@ -262,7 +262,7 @@ Applicable `list` operations—some of which you've seen before—include:
|
||||
|
||||
- There is a built-in `++lent` function that counts the number of characters in a `tape`. Build your own `tape`-length character counting function without using `++lent`.
|
||||
|
||||
You may find the [`?~` wutsig](/reference/hoon/rune/wut#wutsig) rune to be helpful. It tells you whether a value is `~` or not. (How would you do this with a regular `?:` wutcol?)
|
||||
You may find the [`?~` wutsig](/reference/hoon/rune/wut#-wutsig) rune to be helpful. It tells you whether a value is `~` or not. (How would you do this with a regular `?:` wutcol?)
|
||||
|
||||
The foregoing are `list` operations. The following, in contrast, are `tape`-specific operations:
|
||||
|
||||
|
@ -154,7 +154,7 @@ As before with `++double`, Hoon can't find an `a` to modify in a gate that doesn
|
||||
|
||||
### Slamming a Gate
|
||||
|
||||
If you check the docs on our now-familiar [`%-` cenhep](/reference/hoon/rune/cen#cenhep), you'll find that it is actually sugar syntax for another rune:
|
||||
If you check the docs on our now-familiar [`%-` cenhep](/reference/hoon/rune/cen#-cenhep), you'll find that it is actually sugar syntax for another rune:
|
||||
|
||||
> This rune is for evaluating the `$` arm of a gate, i.e., calling a gate as a function. `a` is the gate, and `b` is the desired sample value (i.e., input value) for the gate.
|
||||
>
|
||||
@ -162,9 +162,9 @@ If you check the docs on our now-familiar [`%-` cenhep](/reference/hoon/rune/cen
|
||||
> %~($ a b)
|
||||
> ```
|
||||
|
||||
So all gate calls actually pass back through [`%~` censig](/reference/hoon/rune/cen#censig). What's the difference?
|
||||
So all gate calls actually pass back through [`%~` censig](/reference/hoon/rune/cen#-censig). What's the difference?
|
||||
|
||||
The [`%~` censig](/reference/hoon/rune/cen#censig) rune accepts three children, a wing which resolves to an arm in a _door_; the aforesaid door; and a `sample` for the door.
|
||||
The [`%~` censig](/reference/hoon/rune/cen#-censig) rune accepts three children, a wing which resolves to an arm in a _door_; the aforesaid door; and a `sample` for the door.
|
||||
|
||||
Basically, whenever you use `%-` cenhep, it actually looks up a wing in a door using `%~` censig, which is a more general type of core than a gate. Whatever that wing resolves to is then provided a `sample`. The resulting Hoon expression is evaluated and the value is returned.
|
||||
|
||||
@ -227,7 +227,7 @@ If we built this as a door instead, we could push the parameters out to a differ
|
||||
|
||||
This will be used in two steps: a gate-building step then a gate usage step.
|
||||
|
||||
We produce a gate from a door's arm using the [`%~` censig](/reference/hoon/rune/cen#censig) rune, almost always used in its irregular form, `~()`. Here we prime the door with `[5 4 3]`, which yields a gate:
|
||||
We produce a gate from a door's arm using the [`%~` censig](/reference/hoon/rune/cen#-censig) rune, almost always used in its irregular form, `~()`. Here we prime the door with `[5 4 3]`, which yields a gate:
|
||||
|
||||
```hoon
|
||||
~(quad poly [5 4 3])
|
||||
@ -807,7 +807,7 @@ If the two `tape`s are of the same length, we continue on to create a trap. `|-`
|
||||
|
||||
`?: |(?=(~ key-position) ?=(~ value-result))` checks if either `tape` is empty. If this is true, the `map-maker` arm is finished and can return `chart`, the `map` that we have been creating.
|
||||
|
||||
If the above test finds that the `tape`s are not empty, we trigger a recursion that constructs our `map`: `$(chart (~(put by chart) i.a i.b), a t.a, b t.b)`. This code recursively adds an entry in our `map` where the head of the `tape` `a` maps to the value of the head of `tape` `b` with `~(put by chart)`, our calling of the `put` arm of the `by` map-engine core (note that `~(<wing> <door> <sample>`) is a shorthand for `%~ <wing> <door> <sample>` (see the [Calls % ('cen')](/reference/hoon/rune/cen#censig) documentation for more information). The recursion also "consumes" those heads with every iteration by changing `a` and `b` to their tails using `a t.a, b t.b`.
|
||||
If the above test finds that the `tape`s are not empty, we trigger a recursion that constructs our `map`: `$(chart (~(put by chart) i.a i.b), a t.a, b t.b)`. This code recursively adds an entry in our `map` where the head of the `tape` `a` maps to the value of the head of `tape` `b` with `~(put by chart)`, our calling of the `put` arm of the `by` map-engine core (note that `~(<wing> <door> <sample>`) is a shorthand for `%~ <wing> <door> <sample>` (see the [Calls % ('cen')](/reference/hoon/rune/cen#-censig) documentation for more information). The recursion also "consumes" those heads with every iteration by changing `a` and `b` to their tails using `a t.a, b t.b`.
|
||||
|
||||
We have three related arms to look at next, `++decoder`, `++encoder`, and `++space-adder`. `++space-adder` is required for the other two, so we'll look at it first.
|
||||
|
||||
@ -904,7 +904,7 @@ Now, to decode, we can put either of our ciphers in with the appropriate key and
|
||||
|
||||
## A Bit More on Cores
|
||||
|
||||
The [`|^` barket](/reference/hoon/rune/bar#barket) rune is an example of what we can call a _convenience rune_, similar to the idea of sugar syntax (irregular syntax to make writing certain things out in a more expressive manner). `|^` barket produces a core with _at least_ a `$` buc arm and computes it immediately, called a _cork_. (So a cork is like a trap in the regard of computing immediately, but it has more arms than just `$` buc.)
|
||||
The [`|^` barket](/reference/hoon/rune/bar#-barket) rune is an example of what we can call a _convenience rune_, similar to the idea of sugar syntax (irregular syntax to make writing certain things out in a more expressive manner). `|^` barket produces a core with _at least_ a `$` buc arm and computes it immediately, called a _cork_. (So a cork is like a trap in the regard of computing immediately, but it has more arms than just `$` buc.)
|
||||
|
||||
This code calculates the volume of a cylinder, _A=πr²h_.
|
||||
|
||||
@ -921,7 +921,7 @@ This code calculates the volume of a cylinder, _A=πr²h_.
|
||||
|
||||
Since all of the values either have to be pinned ahead of time or made available as arms, a `|^` barket would probably be used inside of a gate. Of course, since it is a core with a `$` buc arm, one could also use it recursively to calculate values like the factorial.
|
||||
|
||||
If you read the docs, you'll find that a [`|-` barhep](/reference/hoon/rune/bar#barhep) rune “produces a trap (a core with one arm `$`) and evaluates it.” So a trap actually evaluates to a `|%` barcen core with an arm `$`:
|
||||
If you read the docs, you'll find that a [`|-` barhep](/reference/hoon/rune/bar#-barhep) rune “produces a trap (a core with one arm `$`) and evaluates it.” So a trap actually evaluates to a `|%` barcen core with an arm `$`:
|
||||
|
||||
```hoon
|
||||
:: count to five
|
||||
@ -946,7 +946,7 @@ actually translates to
|
||||
--
|
||||
```
|
||||
|
||||
You can also create a trap for later use with the [`|.` bardot](/reference/hoon/rune/bar#bardot) rune. It's quite similar, but without the `=<($...` part then it doesn't get evaluated immediately.
|
||||
You can also create a trap for later use with the [`|.` bardot](/reference/hoon/rune/bar#-bardot) rune. It's quite similar, but without the `=<($...` part then it doesn't get evaluated immediately.
|
||||
|
||||
```hoon
|
||||
> =forty-two |.(42)
|
||||
@ -958,4 +958,4 @@ You can also create a trap for later use with the [`|.` bardot](/reference/hoon/
|
||||
|
||||
What is a gate? It is a door with only one arm `$` buc, and whenever you invoke it then that default arm's expression is referred to and evaluated.
|
||||
|
||||
A _gate_ and a _trap_ are actually very similar: a [gate](/reference/hoon/rune/bar#bartis) simply has a sample (and can actively change when evaluated or via a `%=` cenhep), whereas a trap does not (and can _only_ be passively changed via something like `%=` cenhep).
|
||||
A _gate_ and a _trap_ are actually very similar: a [gate](/reference/hoon/rune/bar#-bartis) simply has a sample (and can actively change when evaluated or via a `%=` cenhep), whereas a trap does not (and can _only_ be passively changed via something like `%=` cenhep).
|
||||
|
@ -339,13 +339,13 @@ For our earlier example with `++roll`, if we wanted to set the default sample to
|
||||
|
||||
### Named Tuples
|
||||
|
||||
A named tuple is a structured collection of values with faces. The [`$:` buccol](/reference/hoon/rune/buc#buccol) rune forms a named tuple. We use these implicitly in an irregular form when we specify the sample of a gate, as `|=([a=@ b=@] (add a b))` expands to a `$:` buccol expression for `[a=@ b=@]`. Otherwise, we only need these if we are building a special type like a vector (e.g. with two components like an _x_ and a _y_).
|
||||
A named tuple is a structured collection of values with faces. The [`$:` buccol](/reference/hoon/rune/buc#-buccol) rune forms a named tuple. We use these implicitly in an irregular form when we specify the sample of a gate, as `|=([a=@ b=@] (add a b))` expands to a `$:` buccol expression for `[a=@ b=@]`. Otherwise, we only need these if we are building a special type like a vector (e.g. with two components like an _x_ and a _y_).
|
||||
|
||||
### Structure Mode
|
||||
|
||||
Most Hoon expressions evaluate normally (that's what “normal” means), what we'll call _noun mode_ (or _normal mode_). However, sample definitions and `+$` lusbuc mold specification arms evaluate in what is called _structure mode_. (You may occasionally see this the older term “spec mode”.) Structure mode expressions use a similar syntax to regular Hoon expressions but create structure definitions instead.
|
||||
|
||||
For instance, in eval mode if you use the irregular form `p=1` this is an irregular form of the [`^=` kettis](/reference/hoon/rune/ket#kettis) rune. This is one way to define a variable using a [`=+` tislus](/reference/hoon/rune/tis#tislus); these are equivalent statements:
|
||||
For instance, in eval mode if you use the irregular form `p=1` this is an irregular form of the [`^=` kettis](/reference/hoon/rune/ket#-kettis) rune. This is one way to define a variable using a [`=+` tislus](/reference/hoon/rune/tis#-tislus); these are equivalent statements:
|
||||
|
||||
```hoon
|
||||
> =+(hello=1 hello)
|
||||
@ -355,7 +355,7 @@ For instance, in eval mode if you use the irregular form `p=1` this is an irregu
|
||||
1
|
||||
```
|
||||
|
||||
(Normally we have preferred [`=/` tisfas](/reference/hoon/rune/tis#tisfas) in the Hoon School docs, but that is just for consistency.)
|
||||
(Normally we have preferred [`=/` tisfas](/reference/hoon/rune/tis#-tisfas) in the Hoon School docs, but that is just for consistency.)
|
||||
|
||||
In a sample definition, such as in a gate, the statement is evaluated in structure mode; these are equivalent statements:
|
||||
|
||||
|
@ -94,7 +94,7 @@ The most obvious case is when there is a casting `^` ket rune in your code. The
|
||||
|
||||
#### `^-` kethep Cast with a Type
|
||||
|
||||
You've already seen one rune that calls for a type check: [`^-` kethep](/reference/hoon/rune/ket#kethep):
|
||||
You've already seen one rune that calls for a type check: [`^-` kethep](/reference/hoon/rune/ket#-kethep):
|
||||
|
||||
```hoon
|
||||
> ^-(@ 12)
|
||||
@ -124,7 +124,7 @@ nest-fail
|
||||
|
||||
#### `^+` ketlus Cast with an Example Value
|
||||
|
||||
The rune [`^+` ketlus](/reference/hoon/rune/ket#ketlus) is like `^-` kethep, except that instead of using a type name for the cast, it uses an example value of the type in question. E.g.:
|
||||
The rune [`^+` ketlus](/reference/hoon/rune/ket#-ketlus) is like `^-` kethep, except that instead of using a type name for the cast, it uses an example value of the type in question. E.g.:
|
||||
|
||||
```hoon
|
||||
> ^+(7 12)
|
||||
@ -156,7 +156,7 @@ nest-fail
|
||||
|
||||
### Nock Checks (`.` dot Runes)
|
||||
|
||||
You saw earlier how a type check is performed when [`.=` dottis](/reference/hoon/rune/dot#dottis)—or more commonly its irregular variant `=( )`—is used. For any expression of the form `=(a b)`, either the type of `a` must be a subset of the type of `b` or the type of `b` must be a subset of the type of `a`. Otherwise, the type check fails and you'll get a `nest-fail`.
|
||||
You saw earlier how a type check is performed when [`.=` dottis](/reference/hoon/rune/dot#-dottis)—or more commonly its irregular variant `=( )`—is used. For any expression of the form `=(a b)`, either the type of `a` must be a subset of the type of `b` or the type of `b` must be a subset of the type of `a`. Otherwise, the type check fails and you'll get a `nest-fail`.
|
||||
|
||||
```hoon
|
||||
> =(12 [33 44])
|
||||
@ -175,7 +175,7 @@ You can evade the `.=` dottis type-check by casting one of its subexpressions to
|
||||
|
||||
(It isn't recommended that you evade the rules in this way, however!)
|
||||
|
||||
The [`.+` dotlus](/reference/hoon/rune/dot#dotlus) increment rune—including its `+( )` irregular form—does a type check to ensure that its subexpression must evaluate to an atom.
|
||||
The [`.+` dotlus](/reference/hoon/rune/dot#-dotlus) increment rune—including its `+( )` irregular form—does a type check to ensure that its subexpression must evaluate to an atom.
|
||||
|
||||
```hoon
|
||||
> +(12)
|
||||
@ -210,7 +210,7 @@ nest-fail
|
||||
|
||||
We'll talk in more detail about the various kinds of type-checking that can occur at arm evaluation [when we discuss type polymorphism](./R-metals.md).
|
||||
|
||||
This isn't a comprehensive list of the type checks in Hoon: for instance, some other runes that include a type check are [`=.`](/reference/hoon/rune/tis#tisdot) and [`%_` cencab](/reference/hoon/rune/cen#_-cencab).
|
||||
This isn't a comprehensive list of the type checks in Hoon: for instance, some other runes that include a type check are [`=.`](/reference/hoon/rune/tis#-tisdot) and [`%_` cencab](/reference/hoon/rune/cen#_-cencab).
|
||||
|
||||
|
||||
## Type Inference
|
||||
@ -283,13 +283,13 @@ If you try to call this gate with the wrong kind of argument, you get a `nest-fa
|
||||
|
||||
#### Using Conditionals for Inference by Branch
|
||||
|
||||
You have learned about a few conditional runes (e.g., `?:` wutcol and `?.` wutdot), but other runes of the `?` family are used for branch-specialized type inference. The [`?@` wutpat](/reference/hoon/rune/wut#wutpat), [`?^` wutket](/reference/hoon/rune/wut#wutket), and [`?~` wutsig](/reference/hoon/rune/wut#wutket) conditionals each take three subexpressions, which play the same basic role as the corresponding subexpressions of `?:` wutcol—the first is the test condition, which evaluates to a flag `?`. If the test condition is true, the second subexpression is evaluated; otherwise the third. These second and third subexpressions are the ‘branches’ of the conditional.
|
||||
You have learned about a few conditional runes (e.g., `?:` wutcol and `?.` wutdot), but other runes of the `?` family are used for branch-specialized type inference. The [`?@` wutpat](/reference/hoon/rune/wut#-wutpat), [`?^` wutket](/reference/hoon/rune/wut#-wutket), and [`?~` wutsig](/reference/hoon/rune/wut#-wutket) conditionals each take three subexpressions, which play the same basic role as the corresponding subexpressions of `?:` wutcol—the first is the test condition, which evaluates to a flag `?`. If the test condition is true, the second subexpression is evaluated; otherwise the third. These second and third subexpressions are the ‘branches’ of the conditional.
|
||||
|
||||
There is also a [`?=` wuttis](/reference/hoon/rune/wut#wuttis) rune for pattern-matching expressions by type, returning `%.y` for a match and `%.n` otherwise.
|
||||
There is also a [`?=` wuttis](/reference/hoon/rune/wut#-wuttis) rune for pattern-matching expressions by type, returning `%.y` for a match and `%.n` otherwise.
|
||||
|
||||
##### `?=` wuttis Non-recursive Type Match Test
|
||||
|
||||
The [`?=` wuttis](/reference/hoon/rune/wut#wuttis) rune takes two subexpressions. The first subexpression should be a type. The second subexpression is evaluated and the resulting value is compared to the first type. If the value is an instance of the type, `%.y` is produced. Otherwise, `%.n`. Examples:
|
||||
The [`?=` wuttis](/reference/hoon/rune/wut#-wuttis) rune takes two subexpressions. The first subexpression should be a type. The second subexpression is evaluated and the resulting value is compared to the first type. If the value is an instance of the type, `%.y` is produced. Otherwise, `%.n`. Examples:
|
||||
|
||||
```hoon
|
||||
> ?=(@ 12)
|
||||
@ -365,7 +365,7 @@ You can't see it here either, but the inferred type of `b` in `[| b]` is `^`. T
|
||||
|
||||
##### The Type Spear
|
||||
|
||||
What if you want to see the inferred type of `b` for yourself for each conditional branch? One way to do this is with the _type spear_. The [`!>` zapgar](/reference/hoon/rune/zap#zapgar) rune takes one subexpression and constructs a cell from it. The subexpression is evaluated and becomes the tail of the product cell, with a `q` face attached. The head of the product cell is the inferred type of the subexpression.
|
||||
What if you want to see the inferred type of `b` for yourself for each conditional branch? One way to do this is with the _type spear_. The [`!>` zapgar](/reference/hoon/rune/zap#-zapgar) rune takes one subexpression and constructs a cell from it. The subexpression is evaluated and becomes the tail of the product cell, with a `q` face attached. The head of the product cell is the inferred type of the subexpression.
|
||||
|
||||
```hoon
|
||||
> !>(15)
|
||||
@ -427,7 +427,7 @@ In the first case it's already known that `b` is an atom. In the second case it
|
||||
|
||||
#### `?@` wutpat Atom Match Tests
|
||||
|
||||
The [`?@` wutpat](/reference/hoon/rune/wut#wutpat) rune takes three subexpressions. The first is evaluated, and if its value is an instance of `@`, the second subexpression is evaluated. Otherwise, the third subexpression is evaluated.
|
||||
The [`?@` wutpat](/reference/hoon/rune/wut#-wutpat) rune takes three subexpressions. The first is evaluated, and if its value is an instance of `@`, the second subexpression is evaluated. Otherwise, the third subexpression is evaluated.
|
||||
|
||||
```hoon
|
||||
> =/(b=* 12 ?@(b %atom %cell))
|
||||
@ -467,7 +467,7 @@ mint-vain
|
||||
|
||||
#### `?^` wutket Cell Match Tests
|
||||
|
||||
The [`?^` wutket](/reference/hoon/rune/wut#wutket) rune is just like `?@` wutpat except it tests for a cell match instead of for an atom match. The first subexpression is evaluated, and if the resulting value is an instance of `^` the second subexpression is evaluated. Otherwise, the third is run.
|
||||
The [`?^` wutket](/reference/hoon/rune/wut#-wutket) rune is just like `?@` wutpat except it tests for a cell match instead of for an atom match. The first subexpression is evaluated, and if the resulting value is an instance of `^` the second subexpression is evaluated. Otherwise, the third is run.
|
||||
|
||||
```hoon
|
||||
> =/(b=* 12 ?^(b %cell %atom))
|
||||
@ -631,7 +631,7 @@ We called this program `gulf.hoon` because it replicates the `gulf` function in
|
||||
|
||||
#### `?~` wutsig Null Match Test
|
||||
|
||||
The [`?~` wutsig](/reference/hoon/rune/wut#wutsig) rune is a lot like `?@` wutpat and `?^` wutket. It takes three subexpressions, the first of which is evaluated to see whether the result is `~` null. If so, the second subexpression is evaluated. Otherwise, the third one is evaluated.
|
||||
The [`?~` wutsig](/reference/hoon/rune/wut#-wutsig) rune is a lot like `?@` wutpat and `?^` wutket. It takes three subexpressions, the first of which is evaluated to see whether the result is `~` null. If so, the second subexpression is evaluated. Otherwise, the third one is evaluated.
|
||||
|
||||
```hoon
|
||||
> =/(b=* ~ ?~(b %null %not-null))
|
||||
@ -721,9 +721,9 @@ So far you've learned about four kinds of type inference:
|
||||
3. gate sample definitions
|
||||
4. branch specialization using runes in the `?` family
|
||||
|
||||
There are several other ways that Hoon infers type. Any rune expression that evaluates to a `?` flag, e.g., `.=` dottis, will be inferred from accordingly. The `.+` dotlus rune always evaluates to an `@`, and Hoon knows that too. The cell constructor runes, [`:-` colhep](/reference/hoon/rune/col#colhep), [`:+` collus](/reference/hoon/rune/col#collus), [`:^` colket](/reference/hoon/rune/col#colket), and [`:*` coltar](/reference/hoon/rune/col#coltar) are all known to produce cells.
|
||||
There are several other ways that Hoon infers type. Any rune expression that evaluates to a `?` flag, e.g., `.=` dottis, will be inferred from accordingly. The `.+` dotlus rune always evaluates to an `@`, and Hoon knows that too. The cell constructor runes, [`:-` colhep](/reference/hoon/rune/col#-colhep), [`:+` collus](/reference/hoon/rune/col#-collus), [`:^` colket](/reference/hoon/rune/col#-colket), and [`:*` coltar](/reference/hoon/rune/col#-coltar) are all known to produce cells.
|
||||
|
||||
More subtly, the [`=+` tislus](/reference/hoon/rune/tis#tislus), [`=/` tisfas](/reference/hoon/rune/tis#tisfas), and [`=|` tisbar](/reference/hoon/rune/tis#tisbar) runes modify the subject by pinning values to the head. Hoon infers from this that the subject has a new type: a cell whose head is the type of the pinned value and whose tail is the type of the (old) subject.
|
||||
More subtly, the [`=+` tislus](/reference/hoon/rune/tis#-tislus), [`=/` tisfas](/reference/hoon/rune/tis#-tisfas), and [`=|` tisbar](/reference/hoon/rune/tis#-tisbar) runes modify the subject by pinning values to the head. Hoon infers from this that the subject has a new type: a cell whose head is the type of the pinned value and whose tail is the type of the (old) subject.
|
||||
|
||||
In general, anything that modifies the subject modifies the type of the subject. Type inference can work in subtle ways for various expressions. However, we have covered enough that it should be relatively clear how to anticipate how type inference works for the vast majority of ordinary use cases.
|
||||
|
||||
@ -843,14 +843,14 @@ You can cast `b` back to `(list)` to work around this:
|
||||
|
||||
To summarize, as values get passed around and checked at various points, the Hoon compiler tracks what the possible data structure or mold looks like. The following runes are particularly helpful when inducing the compiler to infer what it needs to know:
|
||||
|
||||
- [`?~` wutsig](/reference/hoon/rune/wut#wutsig) asserts non-null.
|
||||
- [`?^` wutket](/reference/hoon/rune/wut#wutket) asserts cell.
|
||||
- [`?@` wutpat](/reference/hoon/rune/wut#wutpat) asserts atom.
|
||||
- [`?=` wuttis](/reference/hoon/rune/wut#wuttis) tests for a pattern match in type.
|
||||
- [`?~` wutsig](/reference/hoon/rune/wut#-wutsig) asserts non-null.
|
||||
- [`?^` wutket](/reference/hoon/rune/wut#-wutket) asserts cell.
|
||||
- [`?@` wutpat](/reference/hoon/rune/wut#-wutpat) asserts atom.
|
||||
- [`?=` wuttis](/reference/hoon/rune/wut#-wuttis) tests for a pattern match in type.
|
||||
|
||||
There are two additional assertions which can be used with the type system:
|
||||
|
||||
- [`?>` wutgar](/reference/hoon/rune/wut#wutgar) is a positive assertion (`%.y%` or crash).
|
||||
- [`?<` wutgal](/reference/hoon/rune/wut#wutgal) is a negative assertion (`%.n` or crash).
|
||||
- [`?>` wutgar](/reference/hoon/rune/wut#-wutgar) is a positive assertion (`%.y%` or crash).
|
||||
- [`?<` wutgal](/reference/hoon/rune/wut#-wutgal) is a negative assertion (`%.n` or crash).
|
||||
|
||||
If you are running into `find-fork` errors in more complicated data structures (like marks or JSONs), consider using these assertions to guide the typechecker.
|
||||
|
@ -37,13 +37,13 @@ Essentially, we have to be able to decide whether or not some value or expressio
|
||||
- [`++lth`](/reference/hoon/stdlib/1a#lth) (less than `<`)
|
||||
- [`++gte`](/reference/hoon/stdlib/1a#gte) (greater than or equal to `≥`)
|
||||
- [`++lte`](/reference/hoon/stdlib/1a#lte) (less than or equal to `≤`)
|
||||
- [`.=` dottis](/reference/hoon/rune/dot#dottis), irregularly `=()` (check for equality)
|
||||
- [`.=` dottis](/reference/hoon/rune/dot#-dottis), irregularly `=()` (check for equality)
|
||||
|
||||
The key conditional decision-making rune is [`?:` wutcol](/reference/hoon/rune/wut#wutcol), which lets you branch between an `expression-if-true` and an `expression-if-false`. [`?.` wutdot](/reference/hoon/rune/wut#wutdot) inverts the order of `?:`. Good Hoon style prescribes that the heavier branch of a logical expression should be lower in the file.
|
||||
The key conditional decision-making rune is [`?:` wutcol](/reference/hoon/rune/wut#-wutcol), which lets you branch between an `expression-if-true` and an `expression-if-false`. [`?.` wutdot](/reference/hoon/rune/wut#-wutdot) inverts the order of `?:`. Good Hoon style prescribes that the heavier branch of a logical expression should be lower in the file.
|
||||
|
||||
There are also two long-form decision-making runes, which we will call [_switch statements_](https://en.wikipedia.org/wiki/Switch_statement) by analogy with languages like C.
|
||||
|
||||
- [`?-` wuthep](/reference/hoon/rune/wut#wuthep) lets you choose between several possibilities, as with a type union. Every case must be handled and no case can be unreachable.
|
||||
- [`?-` wuthep](/reference/hoon/rune/wut#-wuthep) lets you choose between several possibilities, as with a type union. Every case must be handled and no case can be unreachable.
|
||||
|
||||
Since `@tas` terms are constants first, and not `@tas` unless marked as such, `?-` wuthep switches over term unions can make it look like the expression is branching on the value. It's actually branching on the _type_. These are almost exclusively used with term type unions.
|
||||
|
||||
@ -56,7 +56,7 @@ There are also two long-form decision-making runes, which we will call [_switch
|
||||
==
|
||||
```
|
||||
|
||||
- [`?+` wutlus](/reference/hoon/rune/wut#wutlus) is similar to `?-` but allows a default value in case no branch is taken. Otherwise these are similar to `?-` wuthep switch statements.
|
||||
- [`?+` wutlus](/reference/hoon/rune/wut#-wutlus) is similar to `?-` but allows a default value in case no branch is taken. Otherwise these are similar to `?-` wuthep switch statements.
|
||||
|
||||
```hoon
|
||||
|= p=?(%0 %1 %2 %3 %4)
|
||||
@ -84,7 +84,7 @@ Mathematical logic allows the collocation of propositions to determine other pro
|
||||
%.y
|
||||
```
|
||||
|
||||
- [`?|` wutbar](/reference/hoon/rune/wut#wutbar), irregularly `|()`, is a logical `OR` _p_ ∨ _q_ over loobean values, e.g. either term may be true.
|
||||
- [`?|` wutbar](/reference/hoon/rune/wut#-wutbar), irregularly `|()`, is a logical `OR` _p_ ∨ _q_ over loobean values, e.g. either term may be true.
|
||||
|
||||
| `OR` | `%.y` | `%.n` |
|
||||
|-------|-------|-------|
|
||||
@ -97,7 +97,7 @@ Mathematical logic allows the collocation of propositions to determine other pro
|
||||
%.y
|
||||
```
|
||||
|
||||
- [`?!` wutzap](/reference/hoon/rune/wut#wutzap), irregularly `!`, is a logical `NOT` ¬_p_. Sometimes it can be difficult to parse code including `!` because it operates without parentheses.
|
||||
- [`?!` wutzap](/reference/hoon/rune/wut#-wutzap), irregularly `!`, is a logical `NOT` ¬_p_. Sometimes it can be difficult to parse code including `!` because it operates without parentheses.
|
||||
|
||||
| | `NOT` |
|
||||
|-------|-------|
|
||||
|
@ -33,7 +33,7 @@ Different kinds of cores can expose or conceal functionality (such as their samp
|
||||
|
||||
Usually the subject of a Hoon expression isn't shown explicitly. In fact, only when using `:`/`.` wing lookup expressions have we made the subject explicit.
|
||||
|
||||
An arm is always evaluated with its parent core as its subject. We've briefly mentioned that one can use helper cores (e.g. for generators) by composing the cores side-by-side using [`=<` tisgal](/reference/hoon/rune/tis#tisgal) and [`=>` tisgar](/reference/hoon/rune/tis#tisgar). This way we can make sure that the arms fall within each other's subject horizon.
|
||||
An arm is always evaluated with its parent core as its subject. We've briefly mentioned that one can use helper cores (e.g. for generators) by composing the cores side-by-side using [`=<` tisgal](/reference/hoon/rune/tis#-tisgal) and [`=>` tisgar](/reference/hoon/rune/tis#-tisgar). This way we can make sure that the arms fall within each other's subject horizon.
|
||||
|
||||
Why must an arm have its parent core as the subject, when it's computed? As stated previously, the payload of a core contains all the data needed for computing the arms of that core. Arms can only access data in the subject. By requiring that the parent core be the subject we guarantee that each arm has the appropriate data available to it. The tail of its subject contains the `payload` and thus all the values therein. The head of the subject is the `battery`, which allows for making reference to sibling arms of that same core.
|
||||
|
||||
@ -259,8 +259,8 @@ We will use `%say` generators as a bridge concept. We will produce some short a
|
||||
|
||||
Here are a couple of new runes for modifying the subject and chaining computations together, aside from `%=` cenhep which you've already seen:
|
||||
|
||||
- [`=.` tisdot](/reference/hoon/rune/tis#tisdot) is used to change a leg in the subject.
|
||||
- [`=~` tissig](/reference/hoon/rune/tis#tissig) composes many expressions together serially.
|
||||
- [`=.` tisdot](/reference/hoon/rune/tis#-tisdot) is used to change a leg in the subject.
|
||||
- [`=~` tissig](/reference/hoon/rune/tis#-tissig) composes many expressions together serially.
|
||||
|
||||
#### Tutorial: Bank Account
|
||||
|
||||
@ -310,7 +310,7 @@ In the above code chunk, we're creating a cell. The head of this cell is `%say`
|
||||
|
||||
In this code above, we're going to compose two runes using `=<`, which has inverted arguments. We use this rune to keep the heaviest twig to the bottom of the code.
|
||||
|
||||
The [`=~` tissig](/reference/hoon/rune/tis#tissig) rune composes multiple expressions together; we use it here to make the code more readable. We take `new-account` and use that as the subject for the call to `deposit`. `deposit` and `withdraw` both produce a new version of the door that's used in subsequent calls, which is why we are able to chain them in this fashion. The final reference is to `balance`, which is the account balance contained in the [core](/reference/glossary/core/) that we examine below.
|
||||
The [`=~` tissig](/reference/hoon/rune/tis#-tissig) rune composes multiple expressions together; we use it here to make the code more readable. We take `new-account` and use that as the subject for the call to `deposit`. `deposit` and `withdraw` both produce a new version of the door that's used in subsequent calls, which is why we are able to chain them in this fashion. The final reference is to `balance`, which is the account balance contained in the [core](/reference/glossary/core/) that we examine below.
|
||||
|
||||
```hoon
|
||||
|%
|
||||
@ -350,10 +350,10 @@ For instance, a network service call may take a while or may fail. How should t
|
||||
|
||||
We have some more tools available for managing deferred or chained computations, in addition to `=~` tissig and `=*` tistar:
|
||||
|
||||
- [`=^` tisket](/reference/hoon/rune/tis#tisket) is used to change a leg in the tail of the subject then evaluate against it. This is commonly used for events that need to be ordered in their resolution e.g. with a `%=` cenhep. (Used in Gall agents frequently.)
|
||||
- [`=*` tistar](/reference/hoon/rune/tis#tistar) defers an expression (rather like a macro).
|
||||
- [`;<` micgal](/reference/hoon/rune/mic#micgal) sequences two computations, particularly for an asynchronous event like a remote system call. (Used in [threads](/guides/additional/threads/overview).)
|
||||
- [`;~` micsig](/reference/hoon/rune/mic#micsig) produces a pipeline, a way of piping the output of one gate into another in a chain. (This is particularly helpful when parsing text.)
|
||||
- [`=^` tisket](/reference/hoon/rune/tis#-tisket) is used to change a leg in the tail of the subject then evaluate against it. This is commonly used for events that need to be ordered in their resolution e.g. with a `%=` cenhep. (Used in Gall agents frequently.)
|
||||
- [`=*` tistar](/reference/hoon/rune/tis#-tistar) defers an expression (rather like a macro).
|
||||
- [`;<` micgal](/reference/hoon/rune/mic#-micgal) sequences two computations, particularly for an asynchronous event like a remote system call. (Used in [threads](/guides/additional/threads/overview).)
|
||||
- [`;~` micsig](/reference/hoon/rune/mic#-micsig) produces a pipeline, a way of piping the output of one gate into another in a chain. (This is particularly helpful when parsing text.)
|
||||
|
||||
### `++og` Randomness
|
||||
|
||||
@ -478,7 +478,7 @@ We get a different value from the same generator between runs, something that is
|
||||
|
||||
## Scrying (In Brief)
|
||||
|
||||
A _peek_ or a _scry_ is a request to Arvo to tell you something about the state of part of the Urbit OS. Scries are used to determine the state of an agent or a vane. The [`.^` dotket](/reference/hoon/rune/dot#dotket) rune sends the scry request to a particular vane with a certain _care_ or type of scry. The request is then routed to a particular path in that vane. Scries are discused in detail in [App School](/guides/core/app-school/10-scry). We will only briefly introduce them here as we can use them later to find out about Arvo's system state, such as file contents and agent state.
|
||||
A _peek_ or a _scry_ is a request to Arvo to tell you something about the state of part of the Urbit OS. Scries are used to determine the state of an agent or a vane. The [`.^` dotket](/reference/hoon/rune/dot#-dotket) rune sends the scry request to a particular vane with a certain _care_ or type of scry. The request is then routed to a particular path in that vane. Scries are discused in detail in [App School](/guides/core/app-school/10-scry). We will only briefly introduce them here as we can use them later to find out about Arvo's system state, such as file contents and agent state.
|
||||
|
||||
### `%c` Clay
|
||||
|
||||
|
@ -157,7 +157,7 @@ This generator requires a path argument in its sample and optionally accepts a v
|
||||
=+ lon=.^(arch (cat 3 vane %y) arg)
|
||||
```
|
||||
|
||||
We saw [`.^` dotket](/reference/hoon/rune/dot#dotket) for the first time in [the previous module](./O-subject.md), where we learned that it performs a _peek_ or _scry_ into the state of an Arvo vane. Most of the time this functionality is used to ask `%c` Clay or `%g` Gall for information about a path, desk, agent, etc. In this case, `(cat 3 %c %y)` is a fancy way of collocating the two `@tas` terms into `%cy`, a Clay file or directory lookup. The type of this lookup is `+$arch`, and the location of the file or directory is given by `arg` from the sample.
|
||||
We saw [`.^` dotket](/reference/hoon/rune/dot#-dotket) for the first time in [the previous module](./O-subject.md), where we learned that it performs a _peek_ or _scry_ into the state of an Arvo vane. Most of the time this functionality is used to ask `%c` Clay or `%g` Gall for information about a path, desk, agent, etc. In this case, `(cat 3 %c %y)` is a fancy way of collocating the two `@tas` terms into `%cy`, a Clay file or directory lookup. The type of this lookup is `+$arch`, and the location of the file or directory is given by `arg` from the sample.
|
||||
|
||||
```hoon
|
||||
tang+[?~(dir.lon leaf+"~" (show-dir vane arg dir.lon))]~
|
||||
@ -209,9 +209,9 @@ For instance, how does `+cat` work? Let's look at the structure of `/gen/cat/ho
|
||||
|
||||
- Some points of interest include:
|
||||
- `/?` faswut pins the expected Arvo kelvin version; right now it doesn't do anything.
|
||||
- [`.^` dotket](/reference/hoon/rune/dot#dotket) loads a value from Arvo (called a “scry”).
|
||||
- [`.^` dotket](/reference/hoon/rune/dot#-dotket) loads a value from Arvo (called a “scry”).
|
||||
- [`++smyt`](/reference/hoon/stdlib/4m#smyt) pretty-prints a path.
|
||||
- [`=-` tishep](/reference/hoon/rune/tis#tishep) combines a faced noun with the subject, inverted relative to `=+` tislus/`=/` tisfas.
|
||||
- [`=-` tishep](/reference/hoon/rune/tis#-tishep) combines a faced noun with the subject, inverted relative to `=+` tislus/`=/` tisfas.
|
||||
|
||||
You can see how much of the generator is concerned with formatting the content of the file into a formatted text `tank` by prepending `%rose` tags and so forth.
|
||||
|
||||
@ -221,7 +221,7 @@ You can see how much of the generator is concerned with formatting the content o
|
||||
|
||||
Formal error messages in Urbit are built of tanks. “A `tang` is a list of `tank`s, and a `tank` is a structure for printing data. There are three types of `tank`: `leaf`, `palm`, and `rose`. A `leaf` is for printing a single noun, a `rose` is for printing rows of data, and a `palm` is for printing backstep-indented lists.”
|
||||
|
||||
One way to include an error message in your code is the [`~_` sigcab](/reference/hoon/rune/sig/#sigcab) rune, described as a “user-formatted tracing printf”, or the [`~|` sigbar](/reference/hoon/rune/sig/#sigbar) rune, a “tracing printf”. What this means is that these print to the stack trace if something fails, so you can use either rune to contribute to the error description:
|
||||
One way to include an error message in your code is the [`~_` sigcab](/reference/hoon/rune/sig/#-sigcab) rune, described as a “user-formatted tracing printf”, or the [`~|` sigbar](/reference/hoon/rune/sig/#-sigbar) rune, a “tracing printf”. What this means is that these print to the stack trace if something fails, so you can use either rune to contribute to the error description:
|
||||
|
||||
```hoon
|
||||
|= [a=@ud]
|
||||
|
@ -16,7 +16,7 @@ Functional programming, as a paradigm, tends to prefer rather mathematical expre
|
||||
|
||||
## Changing Arity
|
||||
|
||||
If a gate accepts only two values in its sample, for instance, you can chain together multiple calls automatically using the [`;:` miccol](/reference/hoon/rune/mic#miccol) rune.
|
||||
If a gate accepts only two values in its sample, for instance, you can chain together multiple calls automatically using the [`;:` miccol](/reference/hoon/rune/mic#-miccol) rune.
|
||||
|
||||
```hoon
|
||||
> (add 3 (add 4 5))
|
||||
@ -269,7 +269,7 @@ How do we parse multiple characters in order to break things up sensibly?
|
||||
['a' 'b' 'a']
|
||||
```
|
||||
|
||||
- The [`;~` micsig](/reference/hoon/rune/mic/#micsig) will create `;~(combinator (list rule))` to use multiple `rule`s.
|
||||
- The [`;~` micsig](/reference/hoon/rune/mic/#-micsig) will create `;~(combinator (list rule))` to use multiple `rule`s.
|
||||
|
||||
```hoon
|
||||
> (scan "after the" ;~((glue ace) (star (shim 'a' 'z')) (star (shim 'a' 'z'))))
|
||||
|
@ -44,7 +44,7 @@ When you pass arguments to a wet gate, their types are preserved and type analys
|
||||
|
||||
Consider a function like `++turn` which transforms each element of a list. To use `++turn`, we install a list and a transformation function in a generic core. The type of the list we produce depends on the type of the list and the type of the transformation function. But the Nock formulas for transforming each element of the list will work on any function and any list, so long as the function's argument is the list item.
|
||||
|
||||
A wet gate is defined by a [`|*` bartar](/reference/hoon/rune/bar#bartar) rune rather than a `|=` bartis. More generally, cores that contain wet arms **must** be defined using [`|@` barpat](/reference/hoon/rune/bar#barpat) instead of `|%` barcen (`|*` expands to a `|@` core with `$` buc arm). There is also [`|$` barbuc](/reference/hoon/rune/bar#barbuc) which defines the wet gate mold builder (remember, we like gates that build gates).
|
||||
A wet gate is defined by a [`|*` bartar](/reference/hoon/rune/bar#-bartar) rune rather than a `|=` bartis. More generally, cores that contain wet arms **must** be defined using [`|@` barpat](/reference/hoon/rune/bar#-barpat) instead of `|%` barcen (`|*` expands to a `|@` core with `$` buc arm). There is also [`|$` barbuc](/reference/hoon/rune/bar#-barbuc) which defines the wet gate mold builder (remember, we like gates that build gates).
|
||||
|
||||
In a nutshell, compare these two gates:
|
||||
|
||||
@ -120,7 +120,7 @@ This declares a wet gate which accepts a `unit`.
|
||||
?~ a ~<(%mean.'need' !!)
|
||||
```
|
||||
|
||||
If `a` is empty, `~`, then the `unit` cannot be unwrapped. Crash with [`!!` zapzap](/reference/hoon/rune/zap#zapzap), but use [`~<` siggal](/reference/hoon/rune/sig#siggal) to hint to the runtime interpreter how to handle the crash.
|
||||
If `a` is empty, `~`, then the `unit` cannot be unwrapped. Crash with [`!!` zapzap](/reference/hoon/rune/zap#-zapzap), but use [`~<` siggal](/reference/hoon/rune/sig#-siggal) to hint to the runtime interpreter how to handle the crash.
|
||||
|
||||
```hoon
|
||||
u.a
|
||||
@ -242,7 +242,7 @@ Informally, a function fits an interface if the function has a more specific res
|
||||
|
||||
For instance, the archetypal Gall agents in `/sys/lull.hoon` are composed using iron gates since they will be used as examples for building actual agent cores. The `++rs` and sister gates in `/sys/hoon.hoon` are built using iron doors with specified rounding behavior so when you actually use the core (like `++add:rs`) the core you are using has been built as an example.
|
||||
|
||||
The [`|~` barsig](/reference/hoon/rune/bar#barsig) rune produces an iron gate. The [`^|` ketbar](/reference/hoon/rune/ket#ketbar) rune converts a `%gold` invariant core to an iron core.
|
||||
The [`|~` barsig](/reference/hoon/rune/bar#-barsig) rune produces an iron gate. The [`^|` ketbar](/reference/hoon/rune/ket#-ketbar) rune converts a `%gold` invariant core to an iron core.
|
||||
|
||||
### `%lead` Bivariance
|
||||
|
||||
@ -258,7 +258,7 @@ Informally, a more specific generator can be used as a less specific generator.
|
||||
|
||||
For instance, several archetypal cores in `/sys/lull.hoon` which define operational data structures for Arvo are composed using lead gates.
|
||||
|
||||
The [`|?` barwut](/reference/hoon/rune/bar#barwut) rune produces a lead trap. The [`^?` ketwut](/reference/hoon/rune/ket#ketwut) rune converts any core to a `%lead` bivariant core.
|
||||
The [`|?` barwut](/reference/hoon/rune/bar#-barwut) rune produces a lead trap. The [`^?` ketwut](/reference/hoon/rune/ket#-ketwut) rune converts any core to a `%lead` bivariant core.
|
||||
|
||||
### `%gold` Invariance
|
||||
|
||||
@ -337,7 +337,7 @@ This generator is rather simple except for the first line. The sample is define
|
||||
50
|
||||
```
|
||||
|
||||
But we still haven't fully explained the first line of the code. What does `_^|(|=(@ 15))` mean? The inside portion is clear enough: `|=(@ 15)` produces a normal (i.e., `%gold`) gate that takes an atom and returns `15`. The [`^|` ketbar](/reference/hoon/rune/ket#ketbar) rune is used to turn `%gold` gates to `%iron`. (Reverse alchemy!) And the `_` character turns that `%iron` gate value into a structure, i.e. a type. So the whole subexpression means, roughly: “the same type as an iron gate whose sample is an atom, `@`, and whose product is another atom, `@`”. The context isn't checked at all. This is good, because that allows us to accept gates defined and produced in drastically different environments. Let's try passing a gate with a different context:
|
||||
But we still haven't fully explained the first line of the code. What does `_^|(|=(@ 15))` mean? The inside portion is clear enough: `|=(@ 15)` produces a normal (i.e., `%gold`) gate that takes an atom and returns `15`. The [`^|` ketbar](/reference/hoon/rune/ket#-ketbar) rune is used to turn `%gold` gates to `%iron`. (Reverse alchemy!) And the `_` character turns that `%iron` gate value into a structure, i.e. a type. So the whole subexpression means, roughly: “the same type as an iron gate whose sample is an atom, `@`, and whose product is another atom, `@`”. The context isn't checked at all. This is good, because that allows us to accept gates defined and produced in drastically different environments. Let's try passing a gate with a different context:
|
||||
|
||||
```hoon
|
||||
> +gatepass =>([22 33] |=(a=@ +(a)))
|
||||
@ -355,7 +355,7 @@ There's a simpler way to define an iron sample. Revise the first line of `/gen/g
|
||||
(add b 20)
|
||||
```
|
||||
|
||||
If you test it, you'll find that the generator behaves the same as it did before the edits. The [`$-` buchep](/reference/hoon/rune/buc#buchep) rune is used to create an `%iron` gate structure, i.e., an `%iron` gate type. The first expression defines the desired sample type, and the second subexpression defines the gate's desired output type.
|
||||
If you test it, you'll find that the generator behaves the same as it did before the edits. The [`$-` buchep](/reference/hoon/rune/buc#-buchep) rune is used to create an `%iron` gate structure, i.e., an `%iron` gate type. The first expression defines the desired sample type, and the second subexpression defines the gate's desired output type.
|
||||
|
||||
The sample type of an `%iron` gate is contravariant. This means that, when doing a cast with some `%iron` gate, the desired gate must have either the same sample type or a superset.
|
||||
|
||||
|
@ -254,8 +254,8 @@ The `++equ:rs` arm checks for complete equality of two values. The downside of
|
||||
This program shows several interesting aspects, which we've covered before but highlight here:
|
||||
|
||||
- Meters form the standard unit of length.
|
||||
- [`~|` sigbar](/reference/hoon/rune/sig#sigbar) produces an error message in case of a bad input.
|
||||
- [`+$` lusbuc](/reference/hoon/rune/lus#lusbuc) is a type constructor arm, here for a type union over units of length.
|
||||
- [`~|` sigbar](/reference/hoon/rune/sig#-sigbar) produces an error message in case of a bad input.
|
||||
- [`+$` lusbuc](/reference/hoon/rune/lus#-lusbuc) is a type constructor arm, here for a type union over units of length.
|
||||
|
||||
#### Exercise: Measurement Converter
|
||||
|
||||
|
@ -17,7 +17,7 @@ The subject available in something like a Gall agent or thread contains a great
|
||||
|
||||
Scries are performed exclusively with the dotket rune: `.^`
|
||||
|
||||
For details of its usage, see the [dotket](/reference/hoon/rune/dot#dotket) section of the Nock rune documentation. In addition to the dotket documentation, below is a colour-coded diagram breaking down the structure of a dotket scry expression with some additional notes.
|
||||
For details of its usage, see the [dotket](/reference/hoon/rune/dot#-dotket) section of the Nock rune documentation. In addition to the dotket documentation, below is a colour-coded diagram breaking down the structure of a dotket scry expression with some additional notes.
|
||||
|
||||
![Scry diagram](https://media.urbit.orgreference/arvo/scry-diagram-v2.svg)
|
||||
|
||||
@ -67,7 +67,7 @@ The webserver vane Eyre has a system which allows clients like web browsers to p
|
||||
|
||||
### Further reading
|
||||
|
||||
[dotket](/reference/hoon/rune/dot#dotket) - Documentation of the `.^` rune which performs scries.
|
||||
[dotket](/reference/hoon/rune/dot#-dotket) - Documentation of the `.^` rune which performs scries.
|
||||
|
||||
[Arvo](/reference/arvo/overview) - Each vane has a Scry Reference section with details of their endpoints as well as examples.
|
||||
|
||||
|
@ -22,7 +22,7 @@ a correct Hoon file. These values are always correct.
|
||||
Usually, the line and column tell you everything you need to
|
||||
know. But the worst-case scenario for a syntax error is that,
|
||||
somewhere above, you've confused Hoon's tall form by using the
|
||||
wrong fanout for a rune. For example, `%+` ([**cenlus**](/reference/hoon/rune/cen#cenlus),
|
||||
wrong fanout for a rune. For example, `%+` ([**cenlus**](/reference/hoon/rune/cen#-cenlus),
|
||||
a function call whose sample is a cell) has three subhoons:
|
||||
|
||||
```hoon
|
||||
@ -106,7 +106,7 @@ means you tried to pound a square peg into a round hole.
|
||||
What was the peg and what was the hole? Hoon doesn't tell you by
|
||||
default, because moral fiber, and also because in too many cases
|
||||
trivial errors lead to large intimidating dumps. However, you
|
||||
can use the `~!` rune ([**sigzap**](/reference/hoon/rune/sig#sigzap)) to print the type of any hoon in your stack trace.
|
||||
can use the `~!` rune ([**sigzap**](/reference/hoon/rune/sig#-sigzap)) to print the type of any hoon in your stack trace.
|
||||
|
||||
For instance, you wrote `(foo bar)` and got a `nest-fail`. Change
|
||||
your code to be:
|
||||
@ -134,7 +134,7 @@ function.
|
||||
### `mint-vain` and `mint-lost`
|
||||
|
||||
These are errors caused by type inference in pattern matching.
|
||||
`mint-vain` means this hoon is never executed. `mint-lost` means there's a case in a `?-` ([**wuthep**](/reference/hoon/rune/wut#wuthep)) that isn't handled.
|
||||
`mint-vain` means this hoon is never executed. `mint-lost` means there's a case in a `?-` ([**wuthep**](/reference/hoon/rune/wut#-wuthep)) that isn't handled.
|
||||
|
||||
## Runtime crashes
|
||||
|
||||
@ -148,7 +148,7 @@ infinite loop will time out either too slowly or too fast). The
|
||||
stack trace will show what your code was doing when interrupted.
|
||||
|
||||
The counterpart of `~!` for runtime crashes is `~|`
|
||||
([**sigbar**](/reference/hoon/rune/sig#sigbar)):
|
||||
([**sigbar**](/reference/hoon/rune/sig#-sigbar)):
|
||||
|
||||
```hoon
|
||||
~| foo
|
||||
@ -173,7 +173,7 @@ This pretty-prints its argument:
|
||||
```
|
||||
|
||||
will always print `foo` every time it executes. A variant is
|
||||
`~?` ([**sigwut**](/reference/hoon/rune/sig#sigwut)), which prints only if a condition is
|
||||
`~?` ([**sigwut**](/reference/hoon/rune/sig#-sigwut)), which prints only if a condition is
|
||||
true:
|
||||
|
||||
```hoon
|
||||
|
@ -7,25 +7,25 @@ weight = 20
|
||||
|
||||
| Form | Regular Form |
|
||||
| ---- | ------------ |
|
||||
| `_foo` | [`$_`](/reference/hoon/rune/buc#buccab), normalizes to an example |
|
||||
| `foo=bar` | [`$=`](/reference/hoon/rune/buc#buctis), wraps a face around a value |
|
||||
| `?(%foo %bar %baz)` | [`$?`](/reference/hoon/rune/buc#bucwut), forms a type union |
|
||||
| `(fun a b c)` | [`%:`](/reference/hoon/rune/cen#cencol), calls a gate with n arguments |
|
||||
| `~(arm core arg)` | [`%~`](/reference/hoon/rune/cen#censig), pulls an arm in a door |
|
||||
| `foo(x 1, y 2, z 3)` | [`%=`](/reference/hoon/rune/cen#centis), resolve a wing with changes |
|
||||
| `[a b c]` | [`:*`](/reference/hoon/rune/col#coltar) or [`$:`](/reference/hoon/rune/buc#buccol), constructs _n_-tuple in normal mode or its structure in structure mode |
|
||||
| `~[a b c]` | [`:~`](/reference/hoon/rune/col#colsig), constructs null-terminated list |
|
||||
| `+(42)` | [`.+`](/reference/hoon/rune/dot#dotlus), increments with Nock 4 |
|
||||
| `=(a b)` | [`.=`](/reference/hoon/rune/dot#dottis), tests for equality wiht Nock 5 |
|
||||
| ``foo`bar` | [`^-`](/reference/hoon/rune/ket#kethep), typecasts by explicit type label |
|
||||
| `foo=bar` | [`^=`](/reference/hoon/rune/ket#kettis), binds name to value |
|
||||
| `*foo` | [`^*`](/reference/hoon/rune/ket#kettar), bunts (produces default mold value) |
|
||||
| `,foo` | [`^:`](/reference/hoon/rune/ket#ketcol), produces “factory” gate for type |
|
||||
| `:(fun a b c d)` | [`;:`](/reference/hoon/rune/mic#miccol), calls binary function as _n_-ary function |
|
||||
| `foo:bar` | [`=<`](/reference/hoon/rune/tis#tisgal), composes two expressions, inverted |
|
||||
| `|(foo bar baz)` | [`?|`](/reference/hoon/rune/wut#wutbar), logical OR (loobean) |
|
||||
| `_foo` | [`$_`](/reference/hoon/rune/buc#-buccab), normalizes to an example |
|
||||
| `foo=bar` | [`$=`](/reference/hoon/rune/buc#-buctis), wraps a face around a value |
|
||||
| `?(%foo %bar %baz)` | [`$?`](/reference/hoon/rune/buc#-bucwut), forms a type union |
|
||||
| `(fun a b c)` | [`%:`](/reference/hoon/rune/cen#-cencol), calls a gate with n arguments |
|
||||
| `~(arm core arg)` | [`%~`](/reference/hoon/rune/cen#-censig), pulls an arm in a door |
|
||||
| `foo(x 1, y 2, z 3)` | [`%=`](/reference/hoon/rune/cen#-centis), resolve a wing with changes |
|
||||
| `[a b c]` | [`:*`](/reference/hoon/rune/col#-coltar) or [`$:`](/reference/hoon/rune/buc#-buccol), constructs _n_-tuple in normal mode or its structure in structure mode |
|
||||
| `~[a b c]` | [`:~`](/reference/hoon/rune/col#-colsig), constructs null-terminated list |
|
||||
| `+(42)` | [`.+`](/reference/hoon/rune/dot#-dotlus), increments with Nock 4 |
|
||||
| `=(a b)` | [`.=`](/reference/hoon/rune/dot#-dottis), tests for equality wiht Nock 5 |
|
||||
| ``foo`bar` | [`^-`](/reference/hoon/rune/ket#-kethep), typecasts by explicit type label |
|
||||
| `foo=bar` | [`^=`](/reference/hoon/rune/ket#-kettis), binds name to value |
|
||||
| `*foo` | [`^*`](/reference/hoon/rune/ket#-kettar), bunts (produces default mold value) |
|
||||
| `,foo` | [`^:`](/reference/hoon/rune/ket#-ketcol), produces “factory” gate for type |
|
||||
| `:(fun a b c d)` | [`;:`](/reference/hoon/rune/mic#-miccol), calls binary function as _n_-ary function |
|
||||
| `foo:bar` | [`=<`](/reference/hoon/rune/tis#-tisgal), composes two expressions, inverted |
|
||||
| `|(foo bar baz)` | [`?|`](/reference/hoon/rune/wut#-wutbar), logical OR (loobean) |
|
||||
| `&(foo bar baz)` | [`?&`](/reference/hoon/rune/wut#wutpam), logical AND (loobean) |
|
||||
| `!foo` | [`?!`](/reference/hoon/rune/wut#wutzap), logical NOT (loobean) |
|
||||
| `!foo` | [`?!`](/reference/hoon/rune/wut#-wutzap), logical NOT (loobean) |
|
||||
|
||||
##### Reading guide
|
||||
|
||||
@ -40,7 +40,7 @@ Anything Nock can do, Hoon can do also.
|
||||
|
||||
### `.+` dotlus
|
||||
|
||||
[docs](/reference/hoon/rune/dot#dotlus) \\+
|
||||
[docs](/reference/hoon/rune/dot#-dotlus) \\+
|
||||
|
||||
`[%dtls p=atom]`: increment an atom with Nock 4.
|
||||
|
||||
@ -50,7 +50,7 @@ Irregular: `+(p)`
|
||||
|
||||
### `.=` dottis
|
||||
|
||||
[docs](/reference/hoon/rune/dot#dottis) \\=
|
||||
[docs](/reference/hoon/rune/dot#-dottis) \\=
|
||||
|
||||
`[%dtts p=hoon q=hoon]`: test for equality with Nock 5.
|
||||
|
||||
@ -64,7 +64,7 @@ Miscellaneous useful macros.
|
||||
|
||||
### `;:` miccol
|
||||
|
||||
[docs](/reference/hoon/rune/mic#miccol) \\:
|
||||
[docs](/reference/hoon/rune/mic#-miccol) \\:
|
||||
|
||||
`[%mccl p=hoon q=(list hoon)]`: call a binary function as an n-ary function.
|
||||
|
||||
@ -78,7 +78,7 @@ The cell runes.
|
||||
|
||||
### `:-` colhep
|
||||
|
||||
[docs](/reference/hoon/rune/col#colhep) \\[\\]\\^\\+\\\`\\~
|
||||
[docs](/reference/hoon/rune/col#-colhep) \\[\\]\\^\\+\\\`\\~
|
||||
|
||||
`[%clhp p=hoon q=hoon]`: construct a cell (2-tuple).
|
||||
|
||||
@ -103,7 +103,7 @@ Flow hoons change the subject. All non-flow hoons (except cores) pass the subjec
|
||||
|
||||
### `=<` tisgal
|
||||
|
||||
[docs](/reference/hoon/rune/tis#tisgal) \\:
|
||||
[docs](/reference/hoon/rune/tis#-tisgal) \\:
|
||||
|
||||
`[%tsgl p=hoon q=hoon]`: compose two hoons, inverted.
|
||||
|
||||
@ -132,7 +132,7 @@ The invocation family of runes.
|
||||
|
||||
### `%=` centis
|
||||
|
||||
[docs](/reference/hoon/rune/cen#centis) \\(\\)
|
||||
[docs](/reference/hoon/rune/cen#-centis) \\(\\)
|
||||
|
||||
`[%cnts p=wing q=(list (pair wing hoon))]`: take a wing with changes.
|
||||
|
||||
@ -142,7 +142,7 @@ Irregular: `p(a 1)`
|
||||
|
||||
### `%~` censig
|
||||
|
||||
[docs](/reference/hoon/rune/cen#censig) \\~
|
||||
[docs](/reference/hoon/rune/cen#-censig) \\~
|
||||
|
||||
`[%cnsg p=wing q=hoon r=hoon]`: call with multi-armed door.
|
||||
|
||||
@ -152,7 +152,7 @@ Irregular: `~(p q r)`
|
||||
|
||||
### `%-` cenhep
|
||||
|
||||
[docs](/reference/hoon/rune/cen#cenhep) \\(\\)
|
||||
[docs](/reference/hoon/rune/cen#-cenhep) \\(\\)
|
||||
|
||||
`[%cnhp p=hoon q=hoon]`: call a gate (function).
|
||||
|
||||
@ -168,7 +168,7 @@ A mold is a gate (function) that helps us build simple and rigorous data structu
|
||||
|
||||
### `$?` bucwut
|
||||
|
||||
[docs](/reference/hoon/rune/buc#bucwut) \\?
|
||||
[docs](/reference/hoon/rune/buc#-bucwut) \\?
|
||||
|
||||
`[%bcwt p=(list model)]`: mold which normalizes a general union.
|
||||
|
||||
@ -178,7 +178,7 @@ Irregular: `?(p)`
|
||||
|
||||
### `$_` buccab
|
||||
|
||||
[docs](/reference/hoon/rune/buc#buccab) \\\_
|
||||
[docs](/reference/hoon/rune/buc#-buccab) \\\_
|
||||
|
||||
`[%bccb p=value]`: mold which normalizes to an example.
|
||||
|
||||
@ -192,7 +192,7 @@ Hoon has the usual branches and logical tests.
|
||||
|
||||
### `?!` wutzap
|
||||
|
||||
[docs](/reference/hoon/rune/wut#wutzap) \\!
|
||||
[docs](/reference/hoon/rune/wut#-wutzap) \\!
|
||||
|
||||
`[%wtzp p=hoon]`: logical not.
|
||||
|
||||
@ -212,7 +212,7 @@ Irregular: `&(p)`
|
||||
|
||||
### `?|` wutbar
|
||||
|
||||
[docs](/reference/hoon/rune/wut#wutbar) \\|
|
||||
[docs](/reference/hoon/rune/wut#-wutbar) \\|
|
||||
|
||||
`[%wtbr p=(list hoon)]`: logical or.
|
||||
|
||||
@ -226,7 +226,7 @@ Lets us adjust types without violating type constraints.
|
||||
|
||||
### `^:` ketcol
|
||||
|
||||
[docs](/reference/hoon/rune/ket#ketcol) \\,
|
||||
[docs](/reference/hoon/rune/ket#-ketcol) \\,
|
||||
|
||||
`[%ktcl p=spec]`: mold gate for type `p`.
|
||||
|
||||
@ -236,7 +236,7 @@ Irregular: `,p`
|
||||
|
||||
### `^-` kethep
|
||||
|
||||
[docs](/reference/hoon/rune/ket#kethep) \\\`
|
||||
[docs](/reference/hoon/rune/ket#-kethep) \\\`
|
||||
|
||||
`[%kthp p=model q=value]`: typecast by mold.
|
||||
|
||||
@ -246,7 +246,7 @@ Irregular: `` `p`q ``
|
||||
|
||||
### `^*` kettar
|
||||
|
||||
[docs](/reference/hoon/rune/ket#kettar) \\\*
|
||||
[docs](/reference/hoon/rune/ket#-kettar) \\\*
|
||||
|
||||
`[%kttr p=spec]`: produce bunt value of mold.
|
||||
|
||||
@ -256,7 +256,7 @@ Irregular: `*p`
|
||||
|
||||
### `^=` kettis
|
||||
|
||||
[docs](/reference/hoon/rune/ket#kettis) \\=
|
||||
[docs](/reference/hoon/rune/ket#-kettis) \\=
|
||||
|
||||
`[%ktts p=toga q=value]`: name a value.
|
||||
|
||||
|
@ -85,7 +85,7 @@ is a hint that `|$` is closely related to buc runes, and thus `|$` should be
|
||||
used to make mold builders, while `|*` should be used for any other sort of wet
|
||||
gate. Unlike `|*`, the body of `|$` is parsed in pattern mode to a `$spec`.
|
||||
Thus, the second argument of `|$` is frequently a buc rune. For further
|
||||
discussion of wet gates, see the entry for [`|*`](#bartar).
|
||||
discussion of wet gates, see the entry for [`|*`](#-bartar).
|
||||
|
||||
Like other single-arm cores, the arm for `|$` is named `$` and this can be used to
|
||||
define recursive structures. Note however that Hoon is evaluated eagerly, and so
|
||||
@ -192,7 +192,7 @@ contains some arm `arm`, and you want to pass some argument (i.e., input value
|
||||
Because gates are also doors, you can call them the same way. To call the gate
|
||||
`foo` as a door, instead of `(foo baz)` we would write `~($ foo baz)`. This is
|
||||
an irregular form for `%~($ foo baz)`,
|
||||
[%~](/reference/hoon/rune/cen#censig).
|
||||
[%~](/reference/hoon/rune/cen#-censig).
|
||||
|
||||
#### Examples
|
||||
|
||||
@ -286,7 +286,7 @@ Two arguments, fixed.
|
||||
#### Discussion
|
||||
|
||||
Pick your own default value for the sample. Note that `a` is an ordinary
|
||||
expression, not a type; `|:` doesn't bunt a sample as [`|=`](#bartis) does.
|
||||
expression, not a type; `|:` doesn't bunt a sample as [`|=`](#-bartis) does.
|
||||
|
||||
This is useful if you want a gate to have a sample of a particular type, but you don't want the default value of the gate to be the default value of that type.
|
||||
|
||||
@ -487,7 +487,7 @@ A more interesting trap:
|
||||
Note that we can use `$()` to recurse back into the
|
||||
trap, since it's a core with an `$` arm.
|
||||
|
||||
> `$(...)` expands to `%=($ ...)` (["centis"](/reference/hoon/rune/cen#centis)).
|
||||
> `$(...)` expands to `%=($ ...)` (["centis"](/reference/hoon/rune/cen#-centis)).
|
||||
|
||||
---
|
||||
|
||||
@ -630,10 +630,10 @@ evaluates `$`. `a` is a Hoon expression that determines what `$` evaluates to.
|
||||
#### Discussion
|
||||
|
||||
The `|-` rune can be thought of as a 'recursion point' or a 'loop starting
|
||||
point'. Since `|-` makes a `|.` (["bardot"](#bardot), a core with one arm named
|
||||
point'. Since `|-` makes a `|.` (["bardot"](#-bardot), a core with one arm named
|
||||
`$`, we can recurse back into it with `$()`.
|
||||
|
||||
> `$(...)` expands to `%=($ ...)` (["centis"](/reference/hoon/rune/cen#centis)).
|
||||
> `$(...)` expands to `%=($ ...)` (["centis"](/reference/hoon/rune/cen#-centis)).
|
||||
|
||||
#### Examples
|
||||
|
||||
@ -788,10 +788,10 @@ is still only one copy of the code, however).
|
||||
Genericity is a powerful and dangerous tool. Use wet gates only if
|
||||
you know what you're doing.
|
||||
|
||||
Just as with a [gate](#bartis), we can recurse back into a wet gate
|
||||
Just as with a [gate](#-bartis), we can recurse back into a wet gate
|
||||
with `$()`.
|
||||
|
||||
> `$(...)` expands to `%=($ ...)` (["centis"](/reference/hoon/rune/cen#centis)).
|
||||
> `$(...)` expands to `%=($ ...)` (["centis"](/reference/hoon/rune/cen#-centis)).
|
||||
|
||||
`|*` can be used to make wet gates that produce structures, but this usage is
|
||||
discouraged in favor of `|$`.
|
||||
@ -879,7 +879,7 @@ Dry gates are used for the vast majority of ordinary functions in Hoon.
|
||||
|
||||
A gate is a core with one arm named `$`, so we can recurse back into it with `$()`.
|
||||
|
||||
> `$(...)` expands to `%=($ ...)` (["centis"](/reference/hoon/rune/cen#centis)).
|
||||
> `$(...)` expands to `%=($ ...)` (["centis"](/reference/hoon/rune/cen#-centis)).
|
||||
|
||||
#### Examples
|
||||
|
||||
|
@ -38,7 +38,7 @@ mold. Molds and mold builders are generally described together.
|
||||
`spec`s contain more information and draw finer distinctions than `type`s,
|
||||
which is to say that a given type may have more than one valid `spec` defining
|
||||
it, and thus downconversion from `spec` to `type` is lossy. Thus structure
|
||||
validation (done with [`$|`](#bucbar), which is a more restrictive validation
|
||||
validation (done with [`$|`](#-bucbar), which is a more restrictive validation
|
||||
than that performed by molds, is a rare use case. Except for direct raw input,
|
||||
it's generally a faux pas to validate structure at runtime -- or even in userspace.
|
||||
Nonetheless they are sometimes utilized for types that will be more performant
|
||||
@ -144,7 +144,7 @@ The definition of `+set` in `hoon.hoon` is the following:
|
||||
|=(a=(tree) ?:(=(~ a) & ~(apt in a)))
|
||||
```
|
||||
|
||||
Here [`|$`](/reference/hoon/rune/bar#barbuc) is used to define a mold
|
||||
Here [`|$`](/reference/hoon/rune/bar#-barbuc) is used to define a mold
|
||||
builder that takes in a mold (given the face `item`) and creates a structure
|
||||
consisting of a `tree` of `item`s with `$|` that is validated with the gate
|
||||
`|=(a=(tree) ?:(=(~ a) & ~(apt in a)))`. `in` is a door in `hoon.hoon` with
|
||||
@ -573,7 +573,7 @@ Two arguments, fixed.
|
||||
|
||||
#### Discussion
|
||||
|
||||
Since a `$-` reduces to a [`$_`](#buccab), 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!
|
||||
Since a `$-` reduces to a [`$_`](#-buccab), 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
|
||||
|
||||
@ -785,7 +785,7 @@ The product of `p`.
|
||||
|
||||
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](/reference/hoon/rune/ket#kettar).)
|
||||
rune](/reference/hoon/rune/ket#-kettar).)
|
||||
|
||||
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 `%~`.)
|
||||
@ -1025,7 +1025,7 @@ The last item in `p`.
|
||||
#### Discussion
|
||||
|
||||
For a union of atoms, a `$?` is fine. For more complex nouns, always try to use
|
||||
a [`$%`](#buccen), [`$@`](#bucpat) or [`$^`](#bucket), at least if you expect
|
||||
a [`$%`](#-buccen), [`$@`](#-bucpat) or [`$^`](#-bucket), at least if you expect
|
||||
your structure to be used as a normalizer.
|
||||
|
||||
#### Examples
|
||||
|
@ -261,7 +261,7 @@ first, and then the gate.
|
||||
|
||||
---
|
||||
|
||||
## `%-` "cenhep" {% #cenhep %}
|
||||
## `%-` "cenhep" {% #-cenhep %}
|
||||
|
||||
Call a gate (function).
|
||||
|
||||
@ -316,9 +316,9 @@ value) for the gate.
|
||||
#### Discussion
|
||||
|
||||
`%-` is used to call a function; `a` is the function
|
||||
([`gate`](/reference/hoon/rune/bar#bartis), `q` the argument. `%-` is a
|
||||
special case of [`%~` ("censig")](#censig), and a gate is a special case of a
|
||||
[door](/reference/hoon/rune/bar#barcab).
|
||||
([`gate`](/reference/hoon/rune/bar#-bartis), `q` the argument. `%-` is a
|
||||
special case of [`%~` ("censig")](#-censig), and a gate is a special case of a
|
||||
[door](/reference/hoon/rune/bar#-barcab).
|
||||
|
||||
#### Examples
|
||||
|
||||
@ -509,7 +509,7 @@ door itself. `c` is the sample of the door.
|
||||
|
||||
`%~` is the general case of a function call, `%-`. In both, we replace the sample (`+6`) of a core. In `%-` the core is a gate and the `$` arm is evaluated. In `%~` the core is a door and any arm may be evaluated. You must identify the arm to be run: `%~(arm door arg)`.
|
||||
|
||||
See also [`|_`](/reference/hoon/rune/bar#barcab).
|
||||
See also [`|_`](/reference/hoon/rune/bar#-barcab).
|
||||
|
||||
#### Examples
|
||||
|
||||
|
@ -263,7 +263,7 @@ therefore possible to use Hoon as a typeless language.
|
||||
|
||||
---
|
||||
|
||||
## `.=` "dottis" {% #dottis %}
|
||||
## `.=` "dottis" {% #-dottis %}
|
||||
|
||||
Test for equality with Nock `5`.
|
||||
|
||||
|
@ -3,8 +3,8 @@ title = "Casts ^ ('ket')"
|
||||
weight = 11
|
||||
+++
|
||||
|
||||
[`^-` ("kethep")](#kethep), [`^+` ("ketlus")](#ketlus), and [`^=`
|
||||
("kettis")](#kettis) let us adjust types without violating type constraints.
|
||||
[`^-` ("kethep")](#-kethep), [`^+` ("ketlus")](#-ketlus), and [`^=`
|
||||
("kettis")](#-kettis) let us adjust types without violating type constraints.
|
||||
|
||||
The `nest` algorithm which tests subtyping is conservative; it never allows
|
||||
invalid nests, it sometimes rejects valid nests.
|
||||
|
@ -262,7 +262,7 @@ and thus are also called "virtual arms", which can be important for things like
|
||||
Gall agent cores that require a fixed number of arms.
|
||||
|
||||
Under the hood, `+*` gets compiled as
|
||||
[`=*`'s](/reference/hoon/rune/tis#tistar) (see here for more discussion on
|
||||
[`=*`'s](/reference/hoon/rune/tis#-tistar) (see here for more discussion on
|
||||
deferred expressions). `+* foo bar` rewrites each `++` arm beneath it in the
|
||||
core to include `=* foo bar`. For example, the interpreter sees the Nock
|
||||
compiled from this Hoon expression
|
||||
|
@ -156,7 +156,7 @@ like to run such that each past the first depends on the output of the previous
|
||||
one. The output of the previous one may not be of the correct type to use as an
|
||||
input to the next one, and so an adapter such as `+biff` is needed.
|
||||
|
||||
`;<` differs from [`;~`](#micsig) in that it takes a gate which takes a mold
|
||||
`;<` differs from [`;~`](#-micsig) in that it takes a gate which takes a mold
|
||||
that produces an implementation of monadic bind, rather than taking an
|
||||
implementation of monadic bind directly.
|
||||
|
||||
@ -619,7 +619,7 @@ If you need a complex Hoon expression to produce a `marl`, use the `;*` rune.
|
||||
Often this rune is used with an expression, `p`, that includes one or more `;=`
|
||||
subexpressions.
|
||||
|
||||
(See also [`;=`](#mictis).)
|
||||
(See also [`;=`](#-mictis).)
|
||||
|
||||
#### Examples
|
||||
|
||||
@ -711,7 +711,7 @@ can be produced in the following way:
|
||||
Sometimes what is needed is a `marl`, i.e., a list of `manx`. To convert a
|
||||
series of `manx` nodes to a `marl`, use the `;=` rune.
|
||||
|
||||
(See also [`;*`](#mictar).)
|
||||
(See also [`;*`](#-mictar).)
|
||||
|
||||
#### Examples
|
||||
|
||||
|
@ -459,7 +459,7 @@ may optionally be written as `%foo.some-hoon`.
|
||||
|
||||
#### Discussion
|
||||
|
||||
`~<` is only used for jet hints ([`~/`](#sigfas) and [`~%`](#sigcen)) at the
|
||||
`~<` is only used for jet hints ([`~/`](#-sigfas) and [`~%`](#-sigcen)) at the
|
||||
moment; we are not telling the interpreter something about the computation we're
|
||||
about to perform, but rather about its product.
|
||||
|
||||
|
@ -357,7 +357,7 @@ Three arguments, fixed.
|
||||
|
||||
Technically the `=.` rune doesn't change the subject. It creates a new subject
|
||||
just like the old one except for a changed value at `p`. Note that the mutation
|
||||
uses [`%_` ("cencab")](/reference/hoon/rune/cen#cencab), so the type at `p`
|
||||
uses [`%_` ("cencab")](/reference/hoon/rune/cen#-cencab), so the type at `p`
|
||||
doesn't change. Trying to change the value type results in a `nest-fail`.
|
||||
|
||||
#### Examples
|
||||
@ -903,7 +903,7 @@ The product of the chain composition.
|
||||
|
||||
---
|
||||
|
||||
## `=*` "tistar" {% #tistar %}
|
||||
## `=*` "tistar" {% #-tistar %}
|
||||
|
||||
Define a deferred expression.
|
||||
|
||||
|
@ -6,7 +6,7 @@ weight = 6
|
||||
Hoon has the usual program control branches. It also has the usual logical
|
||||
operators: AND `?&`, OR `?|`, and NOT `?!`. It also has a `?=` rune that tests
|
||||
whether a value matches a given type. In the course of type inference, Hoon
|
||||
learns from `?=` tests in the test condition of [`?:` ("wutcol")](#wutcol)
|
||||
learns from `?=` tests in the test condition of [`?:` ("wutcol")](#-wutcol)
|
||||
expressions.
|
||||
|
||||
## Overview
|
||||
@ -20,8 +20,8 @@ for expressions which expand to `?:`.
|
||||
|
||||
The test does not have to be a single `?=`; the compiler can
|
||||
analyze arbitrary boolean logic ([`?&` ("wutpam")](#wutpam),
|
||||
[`?|` ("wutbar")](#wutbar), [`?!` ("wutzap")](#wutzap)) with full
|
||||
short-circuiting. Equality tests ([`.=` ("dottis")](/reference/hoon/rune/dot#dottis)) are **not**
|
||||
[`?|` ("wutbar")](#-wutbar), [`?!` ("wutzap")](#-wutzap)) with full
|
||||
short-circuiting. Equality tests ([`.=` ("dottis")](/reference/hoon/rune/dot#-dottis)) are **not**
|
||||
analyzed.
|
||||
|
||||
If the compiler detects that the branch is degenerate (only one
|
||||
@ -226,7 +226,7 @@ A missing case will throw the `mint-lost` error. An extra case will throw
|
||||
|
||||
---
|
||||
|
||||
## `?:` "wutcol" {% #wutcol %}
|
||||
## `?:` "wutcol" {% #-wutcol %}
|
||||
|
||||
Branch on a boolean test.
|
||||
|
||||
|
@ -236,7 +236,7 @@ Two arguments, fixed.
|
||||
#### Discussion
|
||||
|
||||
This wraps the product of `q` in its inferred type. It's a raw version of
|
||||
[`!>`](#zapgar). Unlike zapgar, `q` is not given a `p` face and its type
|
||||
[`!>`](#-zapgar). Unlike zapgar, `q` is not given a `p` face and its type
|
||||
information is not stripped to a raw noun.
|
||||
|
||||
The first field, `p`, must be an example of the
|
||||
@ -244,7 +244,7 @@ The first field, `p`, must be an example of the
|
||||
bunt of `$type`). The `p` argument is just so transitions can be handled if the
|
||||
`$type` type changes.
|
||||
|
||||
It's unlikely you'd use this rune directly; [`!>`](#zapgar) is much more
|
||||
It's unlikely you'd use this rune directly; [`!>`](#-zapgar) is much more
|
||||
typical.
|
||||
|
||||
#### Examples
|
||||
|
@ -126,7 +126,7 @@ or in a more compact form (omitting the parent core and chapter label)
|
||||
$(a (dec a), b +(b))
|
||||
```
|
||||
|
||||
The jet hint `%add` allows Hoon to hint to the runtime that a jet _may_ exist. By convention, the jet hint name matches the gate label. Jets must be registered elsewhere in the runtime source code for the Vere binary to know where to connect the hint; we elide that discussion until we take a look at jet implementation below. We will expand on the jet registration runes [`~/` sigfas](/reference/hoon/sig#sigfas) and [`~%` sigcen](/reference/hoon/sig#sigcen) later.
|
||||
The jet hint `%add` allows Hoon to hint to the runtime that a jet _may_ exist. By convention, the jet hint name matches the gate label. Jets must be registered elsewhere in the runtime source code for the Vere binary to know where to connect the hint; we elide that discussion until we take a look at jet implementation below. We will expand on the jet registration runes [`~/` sigfas](/reference/hoon/sig#-sigfas) and [`~%` sigcen](/reference/hoon/sig#-sigcen) later.
|
||||
|
||||
The following C code implements `++add` as a significantly faster operation including handling of >31-bit atoms. It may be found in `urbit/pkg/urbit/jets/a/add.c`:
|
||||
|
||||
@ -942,8 +942,8 @@ Hoon jets are compiled into the Vere binary for distribution with the Urbit runt
|
||||
|
||||
Jets are registered with the runtime so that Vere knows to check whether a particular jet exists when it encounters a marked Hoon arm.
|
||||
|
||||
- [`~/` sigfas](/reference/hoon/sig#sigfas) registers a jet simply (using defaults).
|
||||
- [`~%` sigcen](/reference/hoon/sig#sigcen) registers a jet with all arguments specified.
|
||||
- [`~/` sigfas](/reference/hoon/sig#-sigfas) registers a jet simply (using defaults).
|
||||
- [`~%` sigcen](/reference/hoon/sig#-sigcen) registers a jet with all arguments specified.
|
||||
|
||||
Typically we use `~/` sigfas to register jets within a core under the umbrella of a `~%` sigcen registration. For instance, `++add` is registered under the Kelvin tag of `hoon.hoon`:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user