Puzzle circuits

A Puzzle Circuits NOT, AND, and XOR gate

As part of my residency at Culture at Work I'm working on alternate ways of thinking about computing that are more tactile, explorable and concrete. I want to try a bunch of different ideas, turn them into prototypes, and see what can best help me pull back the silicon curtain.

My first one is called Puzzle Circuits. This is designed to be a version of digital logic that's easy to play with and understand. Each logic gate, switch, or component is represented as a piece of a jigsaw puzzle. Inputs and outputs are on the edges of the piece and the jigsaw tabs make the connection, preventing you from mixing up outputs and inputs.

All the traces are illuminated with LEDs when active, so you can always see all the state in the system at once. Actual digital logic has some extra complexity that you could sweep under the rug, including how to get power to all the gates, pull-down resistors etc. The idea would be that you could just concentrate on the logic gate level of abstraction without worrying about the electrical engineering.

This would take two forms: a physical representation made of actual puzzle pieces cut from PCBs with logic gates soldered on to them, and a software representation that you can use in a web browser. The browser version would be easy to prototype with, so I'll start with that, but the goal is to have both.

Other than allowing people without the hardware the ability to play with the ideas, this would also serve an important purpose: making meta-pieces. You could assemble a bunch of virtual pieces on your computer, then write that logic into a programmable puzzle piece that you can use like any other.

Far from being a novelty, I think the ability to make pieces that are made of pieces, that themselves are made of pieces, is a fundamental part of what makes computation what it is. There is a kind of fractal self-similarity that lets you express information at any level of abstraction.

That said, the whole goal is that it can scale with your level of interest. You can get started just plug some buttons into some logic gates and a speaker and have fun bleeping and blooping, but when you're ready to do more complex things the idea can increase in complexity to match your ambitions. A Puzzle Circuits half-adder

Sleep-like

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.

Saturday

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.

Friday

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.

Tuesday

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).

Saturday

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.