Kartik Agaram


My home on the old web.

I'm a programmer. I work on ways to write software that make it easier for newcomers to understand rather than for insiders to maintain.

It seems to me that modern computers trap people in a vicious cycle. Compatibility guarantees breed complexity over time as the world changes. This complexity is managed by introducing layers of abstraction. Abstractions introduce new compatibility guarantees. Over the decades this vicious cycle leads to even professional programmers understanding only a tiny fraction of the software infrastructure that runs their computers. As a result, our world is increasingly captured by software that is unaccountable to people.

For several years now I've had a vision for a computer that allows anyone to audit its inner workings, where any operation can be decomposed strictly into a parsimonious combination of simpler operations, terminating without cyclic dependencies or circular reasoning at some ground level. Ideally it would do this in a way that rewards curiosity, leading to a virtuous cycle where an order of magnitude more people grow to understand how their computer works as they use it.

Nowhere in this picture are compatibility guarantees, version numbers or forced upgrades. At any point your computer should be internally consistent and free of known historical accidents. Even if this means upgrades are more work and so more infrequent, and that our computers must be slower. Or do less. That seems like a worthwhile trade for a more sustainable world.

Mu, my attempt at making software more auditable, down to the finest details.

Rather than start from some syntax and introduce layers of translation to implement it, Mu starts from the processor's instruction set and tries to get to some safe and clear syntax with as few layers of translation as possible. The emphasis is on internal consistency at any point in time rather than compatibility with the past.

Try it out on a computer with Linux and Qemu:

git clone https://github.com/akkartik/mu
cd mu
./translate life.mu      # generates code.img
qemu-system-i386 code.img

(Other OSs also work. See the Readme above.)

I believe a prerequisite for understanding software is building it, and so all software should be easy to build. Mu is only distributed in source form.

Beyond the initial build, you shouldn't have to poke inside the sources to use Mu. However, if you choose to do so, Mu emphasizes lots of guardrails and good error messages to give you rapid feedback. My goal is for every desire I have tried to satisfy in Mu to have a test or other check. If something doesn't make sense, try changing it and rebuilding Mu, see what errors you get. Any breaking change should cause a well-defined error message somewhere.

Tests are a key mechanism for providing good error messages. In Mu any manual test should be easy to turn into a reproducible automated test. Mu has some unconventional methods for providing this guarantee. It exposes testable interfaces for hardware using dependency injection so that tests can run on -- and make assertions against -- fake hardware. It also performs automated white-box testing which enables robust tests for performance, concurrency, fault-tolerance, etc.

The Mu stack consists of:

- the Mu type-safe and memory-safe language;

- SubX, an unsafe notation for a subset of x86 machine code; and

- bare SubX, a more rudimentary form of SubX without certain syntax sugar.

All Mu programs get translated through these layers into tiny zero-dependency binaries that run natively. The translators for most levels are built out of lower levels. The translator from Mu to SubX is written in SubX, and the translator from SubX to bare SubX is built in bare SubX. There is also an emulator for Mu's supported subset of x86, that's useful for debugging SubX programs.

There's also a prototyping environment in progress that uses a Lisp-based high-level language.

./translate shell/*.mu
qemu-system-i386 code.img


Some 2-minute videos about Mu and other projects.


2021-06-09: A live-coding session (http; video; 6 minutes)

2021-05-31: Sandboxing computations in the Mu computer

2021-05-15: Printing out the call stack when the Mu computer crashes

2021-05-05: Noodling on sandboxing models

2021-04-22: Prototyping on the Mu computer

2021-04-10: Distinguishing a program's return value from its side effects (2-minute video)

2021-04-09: Beginnings of a UI for the Mu computer's high-level language





the Future of Coding community on Slack