I was trying to think of a good way to explain to a friend recently why programming and meetings are so incompatible. The canonical reference for this is Paul Graham's Maker's Schedule, Manager's Schedule. Basically, programming needs big blocks of uninterrupted time, but managers tend to operate on small blocks. For managers, meetings are just another small block, but for programmers their whole big block is interrupted. That seems about right, but what it doesn't explain is why.

I'd like to propose another metaphor: programming is sleep-like. Sleep is a fairly odd phenomenon compared most of our behaviour. First, we have to engage in a certain degree of ritual to even get it going. We lie down somewhere dark and quiet, remove all external stimulation, empty our minds, and wait. Even when it comes, sleep is easily interrupted, and many short blocks of sleep don't work as well as fewer long blocks, no matter what the Ubermenschen will tell you.

Sleep comes in stages. The first is an essentially transitional light sleep, the second is a medium sleep that makes up the majority of the duration, the third is the deepest, so called slow-wave sleep (SWS). Finally, the much-hyped REM sleep, which is actually closest to light sleep in terms of brain activity. It used to be thought that REM was the most important stage, and then SWS, but presently the consensus is that they both work together.

Interestingly, programming also seems to involve stages. In my experience, the early stages involve acclimatising yourself to the code, getting all the different parts in your head, and generally setting up. With that done, you can then start thinking deeply about the problem. Once the solution occurs to you, you write the code for it, which looks like the hardest part but is actually the easiest.

Now, this is just a metaphor; there's no similarity at a neurological level between sleep and programming. That said, there are functional similarities. Being interrupted in the light stages is not so bad, but being interrupted in the deep stages means basically starting over. A certain amount of time is required to get through all the stages, and it has to be in one continuous block.

Most significantly, I feel like the main quality both sleep and programming share is that they thrive in a vacuum. To sleep effectively you have to get rid of everything that isn't sleep, and so too with programming. The main predictor of both good code and good sleep is long stretches of uninterrupted time.

Of course, programming isn't the only thing with this quality. Really, I that that any focused application of your mind would have similar characteristics, be that programming, writing, studying or something else. I suspect it's some unifying property of the way our brains work best; associations build on themselves, so you need to keep the spurious ones quiet and give the relevant ones time to build up.

40 Covers of Skrillex

In the spirit of better late than never, I'm releasing a project I did back in 2012, but haven't published until now: 40 Covers of Skrillex.

This originally started as an idea vaguely inspired by Kutiman's Thru-you. At the time, Skrillex covers were really popular on YouTube, especially Scary Monsters and Nice Sprites. After hearing a few I started thinking, what if you could remix all those covers together to make a whole new version of the song?

I spent the better part of a day just listening to and downloading as many covers as I could find, which ended up being about 50. I took a bunch of notes on which instruments were in the cover, sections that I thought sounded particularly good, etc. I started vaguely thinking about how they might fit together, but didn't really anything concrete in mind.

After that, I started loading stuff into Reaper. Originally I was thinking I'd do the audio editing there and then figure out the video afterwards, but actually Reaper's video editing was powerful enough for my modest needs. I put in the original track as a reference and just started playing around to see what worked.

The following two days or so just consisted of repeatedly adding new covers, figuring out where they'd fit, listening to the sound of different parts together, getting ideas for what might work well next and then starting the process again. A lot of the best ideas came from just trying something silly to see how it would sound; a particular favourite was the floppy disk + guitar solo.

I'm not entirely sure why I didn't release the video at the time. I definitely wanted to get to 50 covers, but I'm not really sure how I was going to get them or where they would have gone. I was also a little unhappy with the audio; I had to lay a pretty fat compressor over everything because there was such a varied amount of sound, and I thought it sounded kinda muddy in the loud sections.

I've had this project in the back of my head for the last five years. Every now and again I would think "oh, yeah, I should finally get around to fixing whatever's wrong with that and finish it". Funny thing is, when I listened to it, it seemed totally fine. What I ended up uploading was completely unchanged from the version I wasn't ready to release five years ago.

Prototype wrapup #41

Last time I did a prototype wrapup it was mainly home automation stuff. Since then I've fallen out of prototypes habit a bit but, especially with my recent integration push, I'm starting to pick up on them a little and use them for bigger projects.


I've had a little Arduino-on-a-breadboard kit for a while, but I never actually set it up properly. I thought it would let me program the bootloader (ie that it would work as an ISP), but actually it just connected to the serial pins by default. However, by using the broken out FT232 pins in bitbang mode and a few jumper wires it was possible to do it. Even though the functionality was all there it took a totally unreasonable amount of time to figure out how to do it, so I thought I'd capture my newfound knowledge in a shell script for posterity.


I'm working on an interesting project for Prismatik Labs that involved some Javascript AST mangling, so I thought I'd try to get comfortable with the Typescript API. It was actually pretty easy once I figured it out, but a lot of it is undocumented, so this is a little demo transformer that adds comments around function calls and function definitions.


This was a bit of a tale of woe. I was setting up user groups on a Linux machine and running into that annoying problem where you add yourself to a new group, but for it to take effect you have to quit and log back in. I carefully put together the Linux syscall magic necessary to load the group list and update the current groups, before realising that what I was trying to do was fundamentally impossible under Linux's security model (a process can only relinquish privileges, not gain them, and an extra group counts as gaining privileges). Still, here's some code that would work if it was somehow injected into your shell and your shell was running as root anyway (or had CAP_SETGID, which is pretty close).


On the other hand, this worked great. I'm doing some new brain things and I needed to convert the raw data format used by my code to something that research-grade tools could understand. So I wrote the unimaginatively named txt2edf to do it. I tested it out using a BDF file and BrainVision Analyzer and, although random markers showed up for no reason, the data itself seemed to import cleanly.

Future forgiveness

I've been thinking a little about forgiveness and its curious intersection with the present. Although I'm a profound believer in going easy on yourself and forgiving your own mistakes, I think that can sometimes go badly wrong when it turns into forgiving yourself in advance.

The whole point of forgiveness is to recognise that, well, it's in the past, there's nothing you can do about it now. Trying to figure out who should have done better or feeling bad about decisions that are already past is a waste of time and effort that could go into improving the future. There are plenty of mistakes yet to make, and those you can actually influence.

But for some reason it seems very easy to mix up forgiving yourself for past mistakes with forgiving yourself in advance for future ones. "Well, if I don't do the right thing here, it's understandable. I'm only human after all." "I want to be productive, but I've had a tough day and nobody would blame me for just putting my feet up instead."

These are things it only really makes sense to say in retrospect. It's fine to look back and forgive a mistake, but if you're looking forward to forgiving a mistake that's entirely different. The crucial "nothing I can do about it now" isn't there. It's not recognising the futility of trying to change the past, it's creating futility about the future. It's an excuse not to try. And if you're forgiving yourself for a decision while you're making it, that means your forgiveness forms part of the calculation. You're not forgiving yourself, you're figuring out what you can get away with.

That said, the best thing to do with a future mistake is actually the same as the best thing to do with a past mistake: learn from it. The difference is that with a future mistake, if you learn from it quickly enough, you don't need to make it at all.

Doing nothing

I've written before about the perils of leisure-like activities, those things that kind of seem like fun but really aren't that fun. Of course, most of us recognise that social news sites and other timewasting dopamine farms aren't great ways to spend your time, but we do it anyway. So why is this and how do we fix it?

Of course, entertainment as analgesia is probably familiar to anyone who, faced with an stray unpleasant memory, has found themselves typing "facebo-" into their web browser before they even realise what they're doing. But I think there's a more general principle that you can get from a two-axis analysis: timewasting is not very positive, but it's also not very negative. It's a reliable feeling of just enough reward to be worth it.

That might not seem particularly great, but "not very negative" can sometimes be quite a compelling proposition. If you're stressed, tired, or upset, you know you can quite quickly lose yourself in something that's reliably neutral. Neutral beats negative any day. Unfortunately, that easy escape from negativity can stop you from addressing its source. Worse still, sometimes important stuff is uncomfortable, and discomfort doesn't stack up well against neutrality.

But although the neutrality gets you in the door, I ultimately think it's timewasting's small, safe positivity that makes it really dangerous. Why take a risk on an uncertain positive outcome when you have a certain one right here, right in front of you, just a click away? To do something else, you don't just have to accept the negatives of the thing you could have, you also have to give up the positive thing you have already. That's a brutal combination.

Unfortunately, the time when you most need the awareness to avoid timewasting is the time you're least likely to have it. Everyone gets tired sometimes, or needs a break from thinking. Escapism can be healty when it gives you the distance to deal with something better. And who doesn't occasionally feel that just doing nothing might be the most attractive idea in the world right now?

I think there is an answer to be found in recognising that the "not negative" and "slightly positive" aspects of timewasting are separable. You can have not negative without the seductive safety of slightly positive. You can have a break without putting anything fun in that break to sweeten the deal, which robs the break of its compulsivity. Then the break only sticks around for long enough to you to feel the pull of something positive again.

In other words, perhaps the solution to doing nothing is, in fact, to do nothing. Actually nothing. Not staring at a screen, chatting to a friend or playing a game. Just embrace the lack of anything and see how it feels. At first, probably, relieving. Then, hopefully, boring. It's dangerous for nothing to be interesting.