Graph is a simple, declarative abstraction to express compositional structure.
Declarative means that we should explicitly list a system’s components and dependencies in a way that is accessible to our tooling. This solves the issues of the previous section, enabling abstractions over a system’s components as well as reasoning about the composition as a whole. Of course, this idea is not new; for example, it is the basis of graph computation frameworks like Pregel, Dryad, and Storm, and existing libraries for system composition such as react.
Our primary objective in Graph is to distill this idea to its simplest, most idiomatic expression in Clojure, our language of choice. Concretely, a Graph is just a Clojure map of functions that can depend on the outputs of other functions. Because Graphs are just ordinary data, we can manipulate them for free using our favorite existing tools, making Graphs trivially easy to create, modify, run, reason about, test, and build upon. Put simply, Graph is an [FCA][swe] for composition.
It is better to have 100 functions operate on one data structure than 10
functions on 10 data structures.
-- Alan Perlis
As a first attempt in this direction, we could rewrite our stats example as a Clojure map, turning let variables into keywords and wrapping each of the corresponding value expressions in anonymous functions.
This gets us 90% of the way there. The individual components of the computation are now explicit, but the dependency information is still missing. For instance, there’s no way for our tools to know that the m in the arguments to the :v function refers to the mean computed in the second step of the graph – after compilation, it’s just the first argument to an anonymous function.
- GitHub - plumatic/plumbing: Prismatic's Clojure(Script) utility belt · GitHub
- Plumbing 0.4.0 API documentation

In a previous article, we established that content is sovereign, which means the site generator needs to gather content from various repositories and branches. In order for the generator to identify, aggregate, and catalog content partitioned in this way, the repositories must present a consistent structure. Otherwise, the generator isn’t going to know which files represent pages or which pages should be grouped together.
![]()