Reproducible Literate Programming: A Correct and Efficient Design

I’ve been very frustrated recently by quarto; rebuilding the algebraicjulia site takes forever because we have to run latex a bajillion times for all of the tikzcd diagrams.

Fortunately, we don’t have to run julia a bunch of times for all of the code, because we jankily save the previous results. But really, we shouldn’t have to do any of this. I want the following.

A “literate programming document” should be compiled by first extracting all of the code blocks to a file, and then building a nix derivation for that file whose output consists of the output for each of the code blocks. The advantage of this is that it only depends on the code blocks, so that when you make changes to the surrounding prose, nothing needs to change, and the code block stuff can be pulled from cache. Moreover, because the code blocks are run by nix, you have absolute certainty that you can reproduce their results at a later date; you don’t have to worry about what libraries you have installed, or whatever. And finally, it should be easy to define new runners; you just have to write something that takes a directory with a bunch of code blocks, and and produces a directory with markdown snippets and images that should be spliced into the file/copied into the same directory as the file. This would make writing, say, something that compiled tikz, something like a 5 line bash script, rather than what it stands as now (you would have to write a whole Jupyter kernel for tikz).

Best of all, the actual document processing can be totally oblivious to how any of the code blocks are compiled; its job is just to extract them and pass them to a user-defined nix builder.

Of course, a better solution would be along the lines of How notebooks should work, but I feel like this approach to literate programming should be possible to write with, like, a 500 line Rust program that wraps some existing Rust markdown library, and shells out to nix. Or alternatively, maybe this could be built into a fork of zola. This is what I want for Christmas.


Mentioning noweb, as I rarely see it mentioned in discussions on literate programming but it’s been around awhile.