on f3ca521 help sign in
113 lines 3.2 kB history raw
1+++
2title = "Digits"
3weight = 4
4template = "doc.html"
5aliases = ["docs/learn/hoon/workbook/digits/"]
6+++
7Let's write a generator that takes a `@ud` (unsigned decimal) and returns a list
8of its digits.
10```hoon
11!:
12:- %say
13|= [* [n=@ud ~] ~]
14:- %noun
15=| lis=(list @ud)
16|- ^+ lis
17?: (lte n 0)
18 lis
19%= $
20 n (div n 10)
21 lis (mod n 10)^lis
22==
23```
25We're creating a [`%say` generator](@/docs/hoon/hoon-tutorial/generators.md). That means we
26need some "boilerplate" code in the format of `[%say [%noun "data"]]`:
28```hoon
29:- %say
30|= [* [n=@ud ~] ~]
31:- %noun
32```
34The head of this cell is the literal `%say`.
36In the tail is the gate and its sample: `|= [* [n=@ud ~] ~]`. This is
37where we describe any arguments we are expecting to be passed in when the
38generator is called. We are expecting data of type `@ud`. We give the data the
39face `n` so that we can easily reference it later.
41Also in the tail is another `cell`, its head indicating to the `dojo` how to
42print the value we are creating. In this case, we use the generic `%noun`.
44The tail of our second cell is the product of the rest of the program.
46```hoon
47=| lis=(list @ud)
48```
50We use the above code to construct a `list` of `@ud` by cutting up the `@ud` we
51got passed and so we add a face onto that type. This list is empty until we
52manipulate it further.
54```hoon
55|- ^+ lis
56?: (lte n 0)
57 lis
58```
60`|-` creates a gate that functions as a recursion point.
62We are actually able to reuse `lis` for the type of output that we are going
63to produce. A sibling of the `^-` rune, `^+` is distinct because it is for
64casting _by example_. It takes type information from an _instance_ of that type.
65It's useful when using a complicated type.
67```hoon
68?: (lte n 0)
69 lis
70```
72`?:` checks if the statement that follows is true or false. In our case, if it's
73true that `n` is less than or equal to `0`, we simply return `lis`. Otherwise,
74we branch to the following operations:
76```hoon
77%= $
78 n (div n 10)
79 lis (mod n 10)^lis
80==
81```
83`%=` is the rune that takes a wing with any number changes, in the
84form of a list. Our list has two elements that represent such changes, contained
85in a `$` expression to perform recursion. This is the tall form of an equivalent
86syntax that you may be more familiar with:
87`$(n (div n 10), lis (mod n 10)^lis)`.
89The first change divides `n` by `10`, rounding down without a remainder, and
90assigning that product as the new value for `n`.
92The second change prepends the remainder of `n` divided `10` to `lis` (`x^y` is
93an alternative syntax for `[x y]`). `mod` performs the modulo operation.
95Together, these operations will pull each digit out of `n` and put it into a
96`list`. That's because dividing `n` by 10 will knock off one decimal place from
97the value, and `mod` will store the actual discarded digit. To visualize this
98complementarity, let's run some operations in the dojo:
100```hoon
101> (div 146 10)
10214
104> (mod 146 10)
106```
108* TODO What if we do this with vases? Can we accept a vase, map it to whatever
109the correct value would be to extract each digit of the number in whatever base
110we are interpreting it in?
112* TODO from Rob: we need a few exercises here. Maybe asking the reader to
113make one that accepts a vase could be one?