Lesson 1 — A cell is a whole program
A cell holds its contract (face), its storage (memory) and its handlers (on). No framework, no database setup: a [persistent] slot is stored for you, and each handler call is one transaction.
counter.cell
cell Counter {
face {
signal bump(name: String) -> Int
signal top(n: Int) -> List
}
memory { hits: Map<String, Int> [persistent] }
on bump(name: String) {
let n = (hits.get(name) ?? 0) + 1 // `??`: a default for a missing key
hits.set(name, n)
return n
}
on top(n: Int) {
return entries(hits) |> sort_by(e => 0 - e.value) |> top(n) |> map(e => e.key)
}
}$ soma check counter.cell
✓ All checks passed.
$ soma run counter.cell bump ada
1
$ soma run counter.cell bump ada
2
$ soma run counter.cell bump alan
1
$ soma run counter.cell top 1
["ada"]The slot kept its values between runs (in .soma_data/ beside the file). soma serve counter.cell would answer the same handlers over HTTP: POST /bump/ada.