— 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
- 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.
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 projects like SubX or Mu, and so make them 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.