@@ -10,41 +10,62 @@ title: State
1010In the last section we built a few small apps that sent moves. These apps were
1111entirely stateless, however. Most useful apps require some amount of state.
1212Let's build a trivial stateful app. It'll keep a running the sum of all the
13−atoms we poke it with. Here's `app/examples/sum.hoon`:
14−
15− /? 314
13+atoms we poke it with. Here's `examples/app/sum.hoon`:
14+
15+ :: Keeps track of the sum of all the atoms it has been
16+ :: poked with and prints the sum out
17+ ::
18+ :::: /===/app/sum/hoon
19+ ::
1620 !:
17− |_ {bowl state/@}
18− ++ poke-atom
19− |= arg/@
20− ^- {(list) _+>.$}
21− ~& [%so-far (add state arg)]
22− [~ +>.$(state (add state arg))]
21+ |%
22+ ++ move {bone card}
23+ ++ card $% $~
24+ ==
25+ --
26+ |_ {bow/bowl sum/@}
27+ ::
28+ ++ poke-atom
29+ |= tom/@
30+ ^- {(list move) _+>.$}
31+ ~& sum+(add sum tom)
32+ [~ +>.$(sum (add sum tom))]
33+ ::
34+ ++ coup
35+ |= {wir/wire err/(unit tang)}
36+ ^- {(list move) _+>.$}
37+ ?~ err
38+ ~& sum+success+'Poke succeeded!'
39+ [~ +>.$]
40+ ~& sum+error+'Poke failed. Error:'
41+ ~& sum+error+err
42+ [~ +>.$]
43+ ::
2344 --
2445
25−We can start it with `|start %examples-sum`, and then run it:
46+We can start it with `|start %sum`, and then run it:
2647
27− ~fintud-macrep:dojo> :examples-sum &atom 5
28− [%so-far 5]
48+ ~fintud-macrep:dojo> :sum &atom 5
49+ [%sum 5]
2950 >=
30− ~fintud-macrep:dojo> :examples-sum &atom 2
31− [%so-far 7]
51+ ~fintud-macrep:dojo> :sum &atom 2
52+ [%sum 7]
3253 >=
33− ~fintud-macrep:dojo> :examples-sum &atom 15
34− [%so-far 22]
54+ ~fintud-macrep:dojo> :sum &atom 15
55+ [%sum 22]
3556 >=
3657
3758We can see that app state is being saved, but when, where, and how?
3859
3960The state is stored as the second thing in the `|_` line. In our case, it's
40−simply an atom named `state`. We change it by producing our state not with
41−`+>.$` (as before), but with `+>.$(state (add state arg))`. We've seen all these
61+simply an atom named `sum`. We change it by producing our state not with
62+`+>.$` (as before), but with `+>.$(sum (add sum tom))`. We've seen all these
4263parts before, but you might not recognize them.
4364
4465Recall in the first chapter that we recursed with the expression
4566`$(b (add 3 b))`. This meant "produce `$` with `b` changed to `(add 3 b)`.
46−Similarly, `+>.$(state (add state arg))` means "produce `+>.$` (i.e. our
47−context, which contains our state) with `state` changed to `(add state arg)`.
67+Similarly, `+>.$(sum (add sum tom))` means "produce `+>.$` (i.e. our
68+context, which contains our state) with `sum` changed to `(add sum tom)`.
4869
4970At a high level, then, when we handle state, we do it explicitly. It's passed in
5071and produced explicitly. In Unix systems, application state is just a block of
@@ -52,8 +73,8 @@ memory, which you need to serialize to disk if you want to keep it around for
5273very long.
5374
5475In Urbit, app state is a single (usually complex) value. In our example, we have
55−very simple state, so we defined `state/@`, meaning that our state is an atom.
56−Of course, `state` is just a name, and you're free to name your state whatever
76+very simple state, so we defined `sum/@`, meaning that our state is an atom.
77+Of course, `sum` is just a name, and you're free to name your state whatever
5778you like. But let's clarify a couple other things before we continue.
5879
5980First, `bowl` is a set of general global states. This set is managed by the
@@ -81,22 +102,22 @@ Unix filesystem, you can, but it's not needed for persistence. Urbit has
81102transactional events, which makes it an [ACID operating
82103system](https://en.wikipedia.org/wiki/ACID). Thus, you don't have to worry about
83104persistence when programming in Urbit, or ever go through the hassle of having
84−to set up and write to a database.
105+to set up and write to a database.
85106
86107**Exercises**:
87108
88−- Modify `:examples-sum` to reset the counter when you poke it with 0.
109+- Modify `:sum` to reset the counter when you poke it with 0.
89110
90−- Write an app that prints out the previous value you poked it with. Sample
91− output:
111+- Write an app called `last` that prints out the previous value you poked it with.
112+ Sample output:
92113
93114<!-- -->
94115
95− ~fintud-macrep:dojo> :examples-last 7
116+ ~fintud-macrep:dojo> :last 7
96117 [%last 0]
97118 >=
98− ~fintud-macrep:dojo> :examples-last [1 2 3]
119+ ~fintud-macrep:dojo> :last [1 2 3]
99120 [%last 7]
100121 >=
101− ~fintud-macrep:dojo> :examples-last 'howdy'
122+ ~fintud-macrep:dojo> :last 'howdy'
102123 [%last [1 2 3]]