Skip to content

An actor that remembers

An actor is a small, independent part of a program, with its own state, that you talk to by sending it messages. In Blue, actors are also durable: their state is kept, and outlives the program.

Save this as account.blue:

type AccountMsg =
| Deposit Int
| Balance (Reply Int)
actor Account (id: String) receives AccountMsg
state balance = 0
on Deposit amount =
become { balance = balance + amount }
on Balance replyTo =
send replyTo balance
fn main () =
let acct = Account "acc-42"
print "balance at start: {ask acct Balance}"
send acct (Deposit 100)
print "balance now: {ask acct Balance}"
balance at start: 0
balance now: 100

Reading it from the top:

  • AccountMsg lists the messages an account understands. Balance carries a Reply Int: whoever asks gets an Int back.
  • actor Account (id: String) declares a kind of actor. Each id is a separate account: Account "acc-42" and Account "acc-7" have their own balances.
  • state balance = 0 is the state a new account starts with. on clauses say what to do with each message, and become gives the actor its new state.
  • send delivers a message and carries on; ask sends one and waits for the reply.
Terminal window
blue run account.blue
blue run account.blue

The second run starts where the first left off:

balance at start: 100
balance now: 200

There is no save call and no database code. blue run keeps the program’s actors in account.db, beside the file, and each message is committed as a whole: the new state, the messages it sent, and a journal entry, together or not at all. Stop the program at any moment, even with kill -9, and nothing is half-done. To start again from nothing, delete account.db.

The REPL can open the same store and show an actor’s state and every message it has handled:

$ blue repl --store account.db
blue> :load account.blue
loaded account.blue: 2 names (Account, main); run it with main ()
blue> :state Account "acc-42"
balance = 200
after 6 messages
blue> :journal Account "acc-42"
1 Balance (<reply>)
2 Deposit 100
3 Balance (<reply>)
4 Balance (<reply>)
5 Deposit 100
6 Balance (<reply>)

The journal is what makes the rest of Blue possible: blue replay account.blue runs every actor’s history again and checks it comes out the same, and the simulator uses it to test what happens when things fail.

Next: watch it in a browser.