Towards Composable Concurrency Abstractions
One of the big questions that came up during my PhD was: ok, now you got your fancy ownership-based metaobject protocol, and you can implement actors, agents, communicating sequential processes, software transactional memory, and many others, but now what? How are you going to use all of these in concert in one application? Finding a satisfying answer is unfortunately far from trivial.
Since I am far from the first person thinking about these problems, we, that is Tom, Joeri, and most notably Janwillem put out heads together to figure out what the main issues are, and what the solutions are others have come up with. Janwillem took the lead and started to write down our first preliminary findings in a paper for the PLACES workshop, co-located with ETAPS in April.
Below, you can find the preprint and abstract of the paper. It is only a first small step, but I hope it won’t be the last one because in the end, the OMOP is only going to be useful if we actually can figure out how to combine the various concurrent programming models it enables in a safe and efficient manner.
In the past decades, many different programming models for managing concurrency in applications have been proposed, such as the actor model, Communicating Sequential Processes, and Software Transactional Memory. The ubiquity of multi-core processors has made harnessing concurrency even more important. We observe that modern languages, such as Scala, Clojure, or F#, provide not one, but multiple concurrency models that help developers manage concurrency. Large end-user applications are rarely built using just a single concurrency model. Programmers need to manage a responsive UI, deal with file or network I/O, asynchronous workflows, and shared resources. Different concurrency models facilitate different requirements. This raises the issue of how these concurrency models interact, and whether they are composable. After all, combining different concurrency models may lead to subtle bugs or inconsistencies.
In this paper, we perform an in-depth study of the concurrency abstractions provided by the Clojure language. We study all pairwise combinations of the abstractions, noting which ones compose without issues, and which do not. We make an attempt to abstract from the specifics of Clojure, identifying the general properties of concurrency models that facilitate or hinder composition.