# 1.8 Doors

It's useful to have cores whose arms evaluate to make gates. The use of such cores is common in Hoon; that's how the functions of the Hoon standard library are stored in the subject. Learning about such cores will also deepen the reader's understanding of Hoon semantics, and for that reason alone is worthwhile.

In this lesson you'll also learn about a new kind of core, called a 'door'.

## Two Kinds of Function Calls

There are two ways of making a function call in Hoon. First, you can call a gate in the subject by name. This is what you did with `inc` in the last lesson; you bound `inc` to a gate that adds `1` to an input:

```> =inc |=(a=@ (add 1 a))

> (inc 10)
11

> =inc
```

The second way of making a function call involves an expression that produces a gate:

```> (|=(a=@ (add 1 a)) 123)
124

> (|=(a=@ (mul 2 a)) 123)
246
```

The difference is that `inc` is an already-created gate in the subject when we called it. The latter calls involve producing a gate that doesn't exist anywhere in the subject, and then calling it.

Are calls to `add` and `mul` of the Hoon standard library of the first kind, or the second?

```> (add 12 23)
35

> (mul 12 23)
276
```

They're of the second kind. Neither `add` nor `mul` resolves to a gate directly; they're each arms that produce gates.

Often the difference doesn't matter much. Either way you can do a function call using the `(gate arg)` syntax.

It's important to learn the difference, however, because for certain use cases you'll want the extra flexibility that comes with having an already produced core in the subject.

## A Gate-Building Core

Let's make a core with arms that build gates of various kinds. As we did in a previous lesson, we'll use the `|%` rune. Feel free to cut and paste the following into the dojo:

```> =c |%
++  inc  |=(a=@ (add 1 a))
++  add-two  |=(a=@ (inc (inc a)))
++  double  |=(a=@ (mul 2 a))
++  triple  |=(a=@ (mul 3 a))
--
```

Let's try out these arms, using them for function calls:

```> (inc:c 10)
11

12

> (double:c 10)
20

> (triple:c 10)
30
```

Notice that each arm in core `c` is able to call the other arms of `c` -- `add-two` uses the `inc` arm to increment a number twice. As a reminder, each arm is evaluated with its parent core as the subject. In the case of `add-two` the parent core is `c`, which has `inc` in it.

### Mutating a Gate

Let's say you want to modify the default sample of the gate for `double`. We can infer the default sample by calling `double` with no argument:

```> (double:c)
0
```

Given that `a x 2 = 0`, `a` must be `0`. (Remember that `a` is the face for the `double` sample, as defined in the core we bound to `c` above.)

Let's say we want to mutate the `double` gate so that the default sample is `25`. There is only one problem: `double` isn't a gate!

```> double.c(a 25)
-tack.a
-find.a
```

It's an arm that produces a gate, and `a` cannot be found in `double` until the gate is created. Furthermore, every time the gate is created, it has the default sample, `0`. If you want to mutate the gate produced by `double`, you'll first have to put a copy of that gate into the subject:

```> =double-copy double:c

> (double-copy 123)
246
```

Now let's mutate the sample to `25`, and check that it worked with `+6`:

```> +6:double-copy(a 25)
a=25
```

Good. Let's call it with no argument and see if it returns double the value of the modified sample.

```> (double-copy(a 25))
50
```

It does indeed. Unbind `c` and `double-copy`:

```> =c

> =double-copy
```

Contrast this with the behavior of `add`. We can look at the sample of the gate for `add` with `+6:add`:

```> +6:add
[a=0 b=0]
```

If you try to mutate the default sample of `add`, it won't work:

```> add(a 3)
-tack.a
-find.a
```

As before with `double`, Hoon can't find an `a` to modify in a gate that doesn't exist yet.

## Other Functions in the Hoon Standard Library

Let's look once more at the parent core of the `add` arm in the Hoon standard library:

```> ..add
<74.dbd 1.qct \$141>
```

The battery of this core contains 74 arms, each of which evaluates to a gate in the standard library. This 'library' is nothing more than a core containing useful basic functions that Hoon often makes available as part of the subject. You can see the Hoon code defining these arms near the beginning of hoon.hoon, starting with `++ add`. (Yes, the Hoon standard library is written in Hoon.)

Here are some of the other gates that can be generated from this core in the Hoon standard library. It should be fairly obvious what they do:

```> (dec 18)
17

> (dec 17)
16

> (gth 11 7)
%.y

> (gth 7 11)
%.n

> (gth 11 11)
%.n

> (lth 11 7)
%.n

> (lth 7 11)
%.y

> (lth 11 11)
%.n

> (max 12 14)
14

> (max 14 14)
14

> (max 14 432)
432

> (mod 11 7)
4

> (mod 22 7)
1

> (mod 33 7)
5

> (sub 234 123)
111
```

## Doors

A brief review: A core is a cell of battery and payload: `[battery payload]`. The battery is code and the payload is data. The battery contains a series of arms, and the payload contains all the data necessary to run those arms correctly.

New material: A door is a core with a sample. That is, a door is a core whose payload is a cell of sample and context: `[sample context]`.

```        Door
/    \
Battery      .
/ \
Sample   Context
```

It follows from this definition that a gate is a special case of a door. A gate is a door with exactly one arm, named `\$`.

Gates are useful for defining functions. But there are many-armed doors as well. How are they used? Doors are quite useful data structures. In Chapter 2 of the Hoon tutorial series you'll learn how to use doors to implement state machines, where the sample stores the relevant state data. For now let's talk about how to use doors for simpler purposes.

### An Example Door

Let's write an example door in order to illustrate its features. Each of the arms in the door will define a simple gate. Let's bind the door to `c` as we did with the last core. To make a door we use the `|_` rune:

```> =c |_  b=@
++  plus  |=(a=@ (add a b))
++  times  |=(a=@ (mul a b))
++  greater  |=(a=@ (gth a b))
--
```

If you type this into the dojo manually, make sure you attend carefully to the spacing. Feel free to cut and paste the code, if desired.

Before getting into what these arms do, let's cover how the `|_` rune works in general.

#### The `|_` Rune

The `|_` rune for making a door works exactly like the `|%` rune for making a core, except it takes one additional subexpression.

The first subexpression after the `|_` rune defines the door's sample. (This is the subexpression the `|%` rune lacks.) Following that are a series of `++` runes, each of which defines an arm of the door. Finally, the expression is terminated with a `--` rune.

#### Back to the Example

For the door defined above, `c`, the sample is defined as an atom, `@`, and given the face `b`. The `plus` arm defines a gate that takes a single atom as its argument, `a`, and which returns the sum of `a` and `b`. The `times` arm defines a gate that takes a single atom, `a`, and returns `a` times `b`. The `greater` arm defines a gate that takes a single atom, `a`, and if `a` is greater than `b` returns `%.y`; otherwise `%.n`.

Let's try out the arms of `c` with ordinary function calls:

```> (plus:c 10)
10

> (times:c 10)
0

> (greater:c 10)
%.y
```

This works, but the results are not exciting. Passing `10` to the `plus` gate returns `10`, so it must be that the value of `b` is `0` (the bunt value of `@`). The products of the other function calls reinforce that assessment. Let's look directly at `+6` of `c`:

```> +6:c
b=0
```

Having confirmed that `b` is `0`, let's mutate the `c` sample and then call its arms:

```> (plus:c(b 7) 10)
17

> (times:c(b 7) 10)
70

> (greater:c(b 7) 10)
%.y

> (greater:c(b 17) 10)
%.n
```

Doing the same mutation repeatedly can be tedious, so let's bind `c` to the modified version of the door, where `b` is `7`:

```> =c c(b 7)

> (plus:c 10)
17

> (times:c 10)
70

> (greater:c 10)
%.y
```

There's a more direct way of passing arguments for both the door sample and the gate sample simultaneously. We may use the `~(arm door arg)` syntax. This generates the `arm` product after modifying the `door`'s sample to be `arg`.

```> (~(plus c 7) 10)
17

> (~(times c 7) 10)
70

> (~(greater c 7) 10)
%.y

> (~(greater c 17) 10)
%.n
```

Readers with some mathematical background may notice that `~( )` expressions allow us to curry. For each of the arms above, the `~( )` expression is used to create different versions of the same gate:

```> ~(plus c 7)
< 1.gxk
{ a/@
< 3.iba
{ b/@
{our/@p now/@da eny/@uvJ}
< 19.anu
24.tmo
6.ipz
38.ard
119.spd
241.plj
51.zox
93.pqh
74.dbd
1.qct
\$141
>
}
>
}
>

> b:~(plus c 7)
7

> b:~(plus c 17)
17
```

Thus, you may think of the `c` door as a function for making functions. Use the `~(arm c arg)` syntax -- `arm` defines which kind of gate is produced (i.e., which arm of the door is used to create the gate), and `arg` defines the value of `b` in that gate, which in turn affects the product value of the gate produced.

The standard library provides currying functionality outside of the context of doors - see `+curr` and `+cury`.

#### Creating Doors with a Modified Sample

In the above example we created a door `c` with sample `b=@` and found that the initial value of `b` was `0`, the bunt value of `@`. We then created new door from `c` by modifying the value of `b`. But what if we wish to define a door with a chosen sample value directly? We make use of the `\$_` rune, whose irregular form is simply `_`. To create the door `c` with the sample `b=@` set to have the value `7` in the dojo, we would write

```> =c |_  b=_7
++  plus  |=(a=@ (add a b))
++  times  |=(a=@ (mul a b))
++  greater  |=(a=@ (gth a b))
--
```

Here the type of `b` is inferred to be `@` based on the example value `7`, similar to how we've seen casting done by example. You will learn more about how types are inferred in Lesson 2.2.

### Doors in the Hoon Standard Library

Back in lesson 1.2 you were introduced to atom auras, which are metadata used by Hoon that defines how that atom is interpreted and pretty-printed. Atoms are unsigned integers, but sometimes programmers want to work with fractions and decimal points. Accordingly, there are auras for floating point numbers. Let's work with the aura for doing single-precision floating point arithmetic: `@rs`.

The `@rs` has its own literal syntax. These atoms are represented as a `.` followed by digits, and possibly another `.` (for the decimal point) and more digits. For example, the float 3.14159 can be represented as a single-precision (32 bit) float with the literal expression `.3.14159`.

You can't use the ordinary `add` function to get the correct sum of two `@rs` atoms:

```> (add .3.14159 .2.22222)
2.153.203.882
```

That's because the `add` gate is designed for use with raw atoms, not floating point values. You can add two `@rs` atoms as follows:

```> (add:rs .3.14159 .2.22222)
.5.36381
```

It turns out that the `rs` in `add:rs` is a Hoon standard library arm that produces a door. Let's take a closer look:

```> rs
<21|fan {r/?(\$n \$u \$d \$z) <51.zox 93.pqh 74.dbd 1.qct \$141>}>
```

The battery of this core, pretty-printed as `21|fan`, has 21 arms that define functions specifically for `@rs` atoms. One of these arms is named `add`; it's a different `add` from the standard one we've been using for vanilla atoms. So when you invoke `add:rs` instead of just `add` in a function call, (1) the `rs` door is produced, and then (2) the name search for `add` resolves to the special `add` arm in `rs`. This produces the gate for adding `@rs` atoms:

```> add:rs
< 1.hsu
{{a/@rs b/@rs} <21.fan {r/?(\$n \$u \$d \$z) <51.zox 93.pqh 74.dbd 1.qct \$141>}>}
>
```

What about the sample of the `rs` door? The pretty-printer shows `r/?(\$n \$u \$d \$z)`. What does this mean? Without yet explaining this notation fully, we'll simply say that the `rs` sample can take one of four values: `%n`, `%u`, `%d`, and `%z`. These argument values represent four options for how to round `@rs` numbers:

```%n -- round to the nearest value
%u -- round up
%d -- round down
%z -- round to zero
```

The default value is `%z` -- round to zero. When we invoke `add:rs` to call the addition function, there is no way to modify the `rs` door sample, so the default rounding option is used. How do we change it? We use the `~( )` notation: `~(arm door arg)`.

Let's evaluate the `add` arm of `rs`, also modifying the door sample to `%u` for 'round up':

```> ~(add rs %u)
< 1.hsu
{{a/@rs b/@rs} <21.fan {r/?(\$n \$u \$d \$z) <51.zox 93.pqh 74.dbd 1.qct \$141>}>}
>
```

This is the gate produced by `add`, and you can see that its sample is a pair of `@rs` atoms. But if you look in the context you'll see the `rs` door. Let's look in the sample of that core to make sure that it changed to `%u`. We'll use the wing `+6.+7` to look at the sample of the gate's context:

```> +6.+7:~(add rs %u)
r=%u
```

It did indeed change. We also see that the door sample uses the face `r`, so let's use that instead of the unwieldy `+6.+7`:

```> r:~(add rs %u)
%u
```

We can do the same thing for rounding down, `%d`:

```> r:~(add rs %d)
%d
```

Let's see the rounding differences in action. Because `~(add rs %u)` produces a gate, we can call it like we would any other gate:

```> (~(add rs %u) .3.14159265 .1.11111111)
.4.252704

> (~(add rs %d) .3.14159265 .1.11111111)
.4.2527037
```

This difference between rounding up and rounding down might seem strange at first. There is a difference of 0.0000003 between the two answers. Why does this gap exist? Single-precision floats are 32-bit and there's only so many distinctions that can be made in floats before you run out of bits.

Just as there is a door for `@rs` functions, there is a Hoon standard library door for `@rd` functions (double-precision 64 bit floats), another for `@rq` functions (quad-precision 128 bit floats), and more.

### Mutating the `rs` Door

Can we mutate the `rs` door so that its sample is `%u`? Let's try it:

```> rs(r %u)
-tack.r
-find.r
```

Oops! Why didn't this work? Remember, `rs` isn't itself a door; it's an arm that produces a door. The `rs` in `rs(r %u)` resolves to the nameless parent core of `rs`, and the search for `r` commences there. But that face can't be found in that parent core -- it's not where we want to look.

It's better simply to use the `~(arm rs arg)` syntax to replace the value of the `rs` door sample with `arg`.