on 65352d4 help sign in
urbit.org/tutorials/hoon/conditionals.md
104 lines 5.1 kB history raw
1+++
2title = "1.3.1 Walkthrough: Conditionals"
3weight = 5
4template = "doc.html"
5aliases = ["/docs/learn/hoon/hoon-tutorial/conditionals/"]
6+++
8In this lesson, we will write a generator that takes an integer and checks if it is an even number between `1` and `100`. This will help demonstrate how boolean (`true` or `false`) conditional expressions work in Hoon.
10```hoon
11:- %say
12|= [* [n=@ud ~] ~]
13:- %noun
14^- ?
15?& (gte n 1)
16 (lte n 100)
17 =(0 (mod n 2))
18==
19```
21On the very first line, with `:- %say` we are beginning to create a generator of the `%say` variety. The result of a `%say` generator is a cell with a head of `%say` and tail that is a [gate](/docs/glossary/gate/), itself producing a `cask`, a pair of a `mark` and some data. It's not important for understanding conditionals; this is just template code. For more information about `%say` generators, see the [Generators](@/docs/tutorials/hoon/generators.md) documentation.
23```hoon
24|= [* [n=@ud ~] ~]
25```
27The code above builds a gate. The gate's first argument is a cell provided by Dojo that contains some system information we're not going to use, so we use `*` to indicate "any [noun](/docs/glossary/noun/)". The next cell is our arguments provided to the generator upon invocation at the Dojo. Here we only want one `@ud` with the face `n`.
29```hoon
30:- %noun
31```
33This code is the third line of the `%say` "boilerplate", and it produces a `cask` with the head of `%noun`. We could use any `mark` here, but `%noun` is the most generic type, able to fit any data.
35```hoon
36^- ?
37```
39This line casts the output as a `flag`, which is a type whose values are `%.y` and `%.n` representing "yes" and "no". These behave as boolean values (`true` or `false`).
41Let's look at the conditional:
43```hoon
44?& (gte n 1)
45```
47`?&` (pronounced "wut-pam") takes in a list of Hoon expressions, terminated by `==`, that evaluate to a `flag` and returns the logical "AND" of these flags. Most runes take a fixed number of children, but the handful that do not (such as `?&`) end their list of children with a terminating rune. In our context, that means that if the product of each of the children of `?&` is `%.y`, then the product of the entire `?&` expression is `%.y` as well. Otherwise, the product of the conditional `?&` is `%.n`.
49The first child of `?&` is `(gte n 1)`. It is good practice to put the first boolean test of a conditional on the same line as the conditional, as we have done here. This utilizes the standard library function `gte` which stands for "greater than or equal to". `(gte a b)` returns `%.y` if `a` is greater than or equal to `b`, and `%.n` otherwise.
51Next we have:
53```hoon
54 (lte n 100)
55```
57`lte` is the standard library function for "less than or equal to". `(lte a b)` returns `%.y` if `a` is less than `b`, and `%.n` otherwise.
59The last boolean test we have is:
61```hoon
62 =(0 (mod n 2))
63```
65This checks to see if `0` is equal to `(mod n 2)` -- in other words, checking if `n` is even. It produces `%.y` if `n` is even and `%.n` if `n` is odd.
67It is good practice in Hoon to put "lighter" lines at the top and "heavier" lines at the bottom, which is why we have put `=(0 (mod n 2))` last in the list of conditionals.
69Finally we have a terminator:
71```hoon
72==
73```
75This marks the end of the list of children of `?&`.
77### Other Runes
79We only utilized one "wut" rune in our walkthrough, but there are many others. Here are a few more examples:
81- `?:` (pronounced "wut-col") is the simplest "wut" rune. It takes three children, also called subexpressions. The first child is a boolean test, so it looks for a `%.y` or a `%.n`. The second child is a yes-branch, which is what we arrive at if the aforementioned boolean test evaluates to `%.y`. The third child is a no-branch, which we arrive at if the boolean test evaluates to `%.n`. These branches can contain any sort of Hoon expression, including further conditional expressions. Instead of the `?&` expression in our `%say` generator above, we could have written:
83```hoon
84?: ?& (gte n 1)
85 (lte n 100)
86 =(0 (mod n 2))
87 ==
88 %.y
89%.n
90```
92Of course, doing so would be needlessly obfuscating -- we mention this only to illustrate that these two Hoon expressions have the same product.
94- `?!` ("wut-zap") is the logical "NOT" operator, which inverts the truth value of its single child. Instead of `(lte n 100)` in our `%say` generator above, we could have written `?! (gth n 100)`. Again, this would be bad practice, we only present this as an example.
96- `?@` takes three children. It branches on whether its first child is an [atom](/docs/glossary/atom/).
98- `?^` takes three children. It branches on whether its first child is a cell.
100- `?~` takes three children. It branches on whether its first child is null.
102- `?|` takes an indefinite number of children. It's the logical "or" operator. It checks if at least one of its children is true.
104To see an exhaustive list of "wut" runes, check out the [reference documentation on conditionals](@/docs/reference/hoon-expressions/rune/wut.md).