— Ian Malcolm, “Jurassic Park”
— Christopher Alexander, “A Timeless Way of Building”
Lately I tend to program in a certain unconventional manner. A series of design choices, each seemingly reasonable in isolation, take me pretty far from conventional wisdom.
- Axiomatically, I care as much about the experience of reading my code as that of running my programs.
- Programs are easier to grok when you can run them, so I try to keep my programs super easy to build.
- Dependencies add moving parts when building from source, so I try to minimize them.
- All languages tend to directly or indirectly depend on C, so I try to cut out the middle men and program directly in C (unless I'm prototyping).
- Describing dependencies explicitly tends to make C projects (header files and so on) hard to reorganize, so I rely on small codebase size and automatically generated headers to keep my code supple.
- Grokking strange new codebases is hard, so I organize my projects in layers that can be ignored in the beginning to focus on a tiny subset of code that still builds and runs.
- Determining if a code change is good can be harder than making the change itself, so I try to provide lots of automated tests as guardrails for newcomers.
- And finally, this list is already pretty long so I give up on almost everything else, making a virtue of a rough, low-polish aesthetic in hopes of minimizing my area of concern and so controlling complexity over time. Sometimes people are forced to go in and modify my codebase. So be it!
Applied together, these concerns make my projects look fairly unfamiliar at first glance, with strange directives mixed into what seems like a C program, files auto-generated by the build system, strange looking tests and so on. To help newcomers gain an initial orientation, here is a series of four example repos that gradually introduce my idioms:
- basic-build: a zero-dependency build system in 30 lines of code. All it needs is /bin/sh.
- basic-test: a bare-bones test harness for C in 45 lines of code.
- basic-whitebox-test: a sandbox for my white-box tests that enable more comprehensive testing, more radical code reorganizations, and more scalable “debug by print”.
- basic-layers: a sandbox for my non-modular, abstraction-busting approach to organizing large-ish projects.
My hope is that these repos act like foundational “meta layers” that help peel back some of the complexity in my larger Mu project, and so make it more accessible to others. They aren't really intended to be read in a browser, so git clone them (Mac or *nix) and try following the Readme. Comments and feedback most appreciated, particularly if you're moved to try building something using them.
(Update 2019-08-14: Remo Dentato has a project developing basic-build further.)
Comments gratefully appreciated. Please send them to me by any method of your choice and I'll include them here.