Concurrency the other way around

Clojure is built around concurrency and it clearly shows in the abstractions the language makes available. I would say that concurrency is pervasive in the language. The good thing about that it that it’s a bit harder to shoot yourself in the foot when doing programming with multiple threads. But the bad side is that it adds quite a bit of mental overhead in situations where concurrency is undesirable.

As an example in mucomp, there is a certain part of the code that deals with the audio player. This is inherently a resource that should only be handled by one thread at a time. Clojure comes with a very good abstraction for exactly this problem, agents. An agent is simply some state, that is manipulated by only thread. Using an agent is done by through sending a function to the agent that will take the old state and return a new state. So with that one gets everything that is needed to write an audio player: serialized access and safely mutable state.

The only bad thing about agents is that if one forgets to return something from a function that run on the agent, then the new state of the agent will be nil. After being bit by this two times I decided that enough was enough. One of the very nice things about languages in the lisp family, is that one can mold your own abstractions to make code better (easier to read and with less bugs in this case).

The following macro creates a new way to define functions. Functions defined in this way will check for nil on return, and return the old state instead. The only change that is needed in code is to use defa instead of defn 🙂

One thought on “Concurrency the other way around”

Comments are closed.