Tutorial: Counter Application

2 The Set Up

Define Our Module

Naturally we need a module so lets sort that out first.

(defmodule counter
  (export (new 0)
          (incr 1)
          (count 1)
          (counter 0)))

Define Our Functions

Now we can start to define the functionality that will make up our module. Lets start with new.. Keeping to Erlang and LFE design principles we want to keep our counters in their own processes, so when this is called just spin up a new counter and hand back the pid to the caller.

(defun new ()
  "For creating a new counter."
  (spawn 'counter 'counter '()))

Now of course having the pid to a process that does nothing but spawn itself isn't terribly useful so how about we implement the incr function to bump our counter up by 1.

(defun incr (counter)
  "Increments our counter value."
  (! counter (tuple 'incr)))

Notice that for the increment function we simply forward our request for an increment to occur and then end the function. Since our counter is designed to be a background process that will manage the counter it is holding and report back when asked. The increment step is an asynchronous action.

Tracking Counter State

Having a running process that we can send an increment instruction to is all well and good, but in this case it's a bit useless if we can't ask for the current value of the counter. Or the value of the counter at the time it was requested, if you want to be picky, so lets implement our count function to request the current value of the count.

(defun count (counter)
  "Retrieves the value of the given counter."
  (! counter (tuple 'count (self)))
  (receive
    ((tuple 'count count)
     count)))

This function takes care of the steps required to talk to our running counter process and the provide a message back to the caller. First we send a message to the given counter process, asking for it's current count value, and then we wait for a response before responding with the result.