Show HN: Makefiles, Metalanguages, and Matrioshka Automata
by robot-wrangler | 2025-11-21 17:12:06+00:00
This project is a strange labor of love, practically guaranteed to inspire horror and delight. It's also tough to summarize. Partly it's practical and involves familiar tools, but part of it is also a new programming language with esolang roots. I'll start with the practical and move towards the peculiar.

The one-sentence summary: compose.mk brings docker-fluency, polyglots, and a capable standard library to Makefiles. A more in-depth elevator pitch from the main landing page is below, and some related links at the end in footnotes 1-5.

> Meet compose.mk, a tool / library / framework for Makefile-based automation, scripting, and lightweight orchestration. Native support for docker, docker-compose, workflow primitives, JSON IO, TUI elements, and more, all provided by a single file with no dependencies beyond what's already in your development environment. Typical use-cases include general project automation, especially decoupling your CI/CD from different kinds of platform lock-in. Other superpowers include the ability to quickly incorporate foreign tools and foreign code as first-class objects, which provides unique and powerful capabilities for quickly assembling console applications, systems prototyping, and component-oriented design experiments in general. Definitely not the Makefiles of your ancestors.

Here's where it starts to get more weird and fun. Building the ideal environment for zero-dependency automation and pesky "glue code" moves in a certain direction. So it happens that compose.mk moonlights as an interpreter / compiler / packaging tool for a new kind of programming language. CMK-lang (or just CMK) is multiparadigm with diverse influences, from functional to concatenative, ultimately specializing in things like extensibility, interoperability, DAGs, and dispatch. CMK is a superset of Makefile that can be transpiled to vanilla Makefile. And it is what is known as a matrioshka language. Paraphrasing the definition from esolangs-wiki:

> A matrioshka language is formed by bundling one or more meta-languages with one or more language descriptions. They can be identified by their program forms, which have multiple, distinct 'phases' with different syntactic and semantic rules. There are often two phases; the first gives a set of rules, and the second provides objects on which those rules are to be applied.

In CMK-lang, matrioshka "objects" are things like container-runtimes or foreign interpreters, and "rules" are DAGs in the form of tasks, task-groups, or foreign code. For those interested in matrioshkas and topics in PLT, I suggest the alternate landing pages at footnotes 6-9.

Love it or hate it, I think you'll agree that compose.mk is easily the biggest, baddest, most highly powered mutant Makefile the world has ever seen. If it helps you can think of CMK-lang as a PoC that's waiting for another back-end implementation ;) Playing around with it has convinced me though that the gap is real, and the world needs containers-first matrioshka languages that work locally and aren't tightly coupled to bulky remote platforms or infrastructure. It also needs languages that are capable of aggressively reusing and recombining existing code and existing tools.

[1]: https://robot-wranglers.github.io/compose.mk/standard-lib [2]: https://robot-wranglers.github.io/compose.mk/bridge [3]: https://robot-wranglers.github.io/compose.mk/container-dispa... [4]: https://robot-wranglers.github.io/compose.mk/demos/polyglots [5]: https://robot-wranglers.github.io/compose.mk/json [6]: https://robot-wranglers.github.io/compose.mk/matrioshka [7]: https://robot-wranglers.github.io/compose.mk/language [8]: https://robot-wranglers.github.io/compose.mk/compiler [9]: https://robot-wranglers.github.io/compose.mk/demos/packaging