I don't program my computer
March 18, 2022
I am 31 years old and have been programming computers in some form for 17 years. I majored in Computer Science at Cornell for four of them and have worked at Facebook (now Meta) for the last ten. I don't program my computer. What do I mean by that? I write computer programs all the time, but I don't program? The programs I write are for other users, run on some other computer, as part of a service, or a CLI utility, or a plugin to a data collection system, and so I don't program my own computer. I've got it set up pretty nicely. I know how to use my tools, but on my computer, I'm just that: a user. Not a programmer. In that simple fact, lies a horrible contradiction. I'm supposed to be able to automate mundane tasks, create abstractions, build tools, reuse my past efforts ever more efficiently, and yet I barely do any of that at all for myself.
Why?
The tools are pretty darn good
bash, screen, vim, awk, ssh, git, libc, dd, tar, atop, sqlite, nginx, systemd, docker, python, LaTeX, the C++ STL, Chrome, Powerpoint, gmail. These aren't bad tools and I use most of them. Some of them I even love. I just thought of a bunch off the top off my head, but there are hundreds and thousands of others. Spending a few minutes (or even years) learning how to use and configure them is good enough: I can be productive without programming anything at all for myself. This is generally a good thing, as someone worked hard to make these tools well so I should use them, and use them well.
I might break it
In college, I used to use emacs, a system that insists you really must program it. I really wanted to see some LaTeX I was writing for a math assignment in its final rendered form alongside the marked up text as I worked. I coded that up in emacs lisp and excitedly fired it up. My laptop's fan came on, as my battery started dropping from 80 to 65 faster than the indicator could update. Clearly I didn't do a good job, so did I buckle down and work on this, like I would on any programming task that meant a lot to me? No, I just switched to vim, and a tiling window manager, and added a really short shortcut for re-rendering the document. I've been a vim user and a non-programming programmer roughly ever since.
Mismatched interfaces
I vividly remember first learning Java in high school and memorizing the cryptic
public static void main(String[] args) {
System.out.println("Hello world!");
}that it took to start a project. My good friend was better at programming than me, and he remembered how to start a C++ program that drew some triangles in DirectX. This boilerplate stops me, not because I can't recite it, but because it isn't really matched to what I'm doing. When I run into some problem, I can either open an editor and try to write some Python that can flexibly consume arguments, transform data, handle errors, give useful output, or I can stay put and start crafting a shell pipeline. This is like the famous apocryphal example of McIlroy vs. Knuth. I never open the editor because it feels completely unreasonable to type
files = subprocess.check_output("ls")when just ls will do. Or when I go to write a shell script, which I do far more often, I find myself chafing at the unusual programming environment where if statements are commands, functions can't affect their calling scope, there's not a portable hash table in easy reach and so on. This impedance between the typical Unixy interfaces of files, streams, fork, environment variables and the typical proper programming interfaces of functions, classes, data structures, collections, scopes, etc. drives a wedge between me and my computer.
Reusability is hard
The essence of automating work by programming is that you do the work upfront once, and get to reuse it forever. Blessed with a filesystem, we never manage the bytes and blocks of a disk directly. So if I am to program my computer, those programs have to go somewhere to be found and reused. As I see it, the options for this are convention, installation, and dotfiles. By convention, I mean remembering where I keep little programs I have written, like a git repo of scripts. By installation, I mean placing the program somewhere my system can automatically find it when I run it. And by dotfiles I mean in something like .bashrc or .vimrc or .emacs depending on what's appropriate. Rightly fearing that I will misplace the scripts I install globally on my system, and wanting to reuse them beyond just shell sessions, I have generally settled on convention. I do my best to keep this little travelling repo up to date between computers, but inevitably it ends up with different names, and different contents everywhere. It just barely works but would never pass muster for deploying real software.
Ok, so what?
The focus of this essay has been observing this fact about my own patterns. However, it clearly contains an implication that the alternative is somehow better, that I ought to be programming my own computer. While the basic analysis of Steve Jobs when he said that the computer is the bicycle of the mind does not imply that there needs to be a recursive process of tool-empowered tool building, other examples from industrial history surely hint that way. I feel in my gut that I am missing out on a step function of productivity by not creating tailor-made tools for a task, as I do it.
I am envisioning a computer system that removes the barriers I outlined above, to encourage me towards meta-programming. I think it could start quite simply: by using my same existing systems, but hardening some informal conventions of discoverability (e.g. PATH), templating (e.g. generating boilerplate), and reuse (e.g. git and install scripts), I could reap quick local improvements. I believe that a still greater prize lies in improving debuggability and mismatched interfaces. That feels like it requires rethinking or augmenting existing interfaces and languages, though I have only made rudimentary attempts to think along those lines, so the ideas have not taken concrete shape.