An annotated Busy Beaver program in Turing Paint

One doesn't so much write a Turing Paint program as scribble it, preferably in MSPaint.

Think of it as Piet meets the Turing Machine. Where Piet uses colors to indicate commands, it also essentially a Funge, where the instruction pointer is sent left or right, up or down via a command (indicated with a relative change in color). In Turing Paint, those directions are determined by paths marked in black, similar to the lines of an AsciiDots program.

However, the real charm of Turing Paint is in the crudeness of its programs' visual design, where programs can be quickly scribbled doodles, so long as the logic is correct. In fact, the more basic the editing tool, the better: anti-aliasing, on by default in most imaging programs, causes interpreter issues. Turing Paint creator Byron Knoll, a software engineer at Google, suggests writing programs in JSPaint, which simulates MSPaint in the browser.

The language is a simulated Turing Machine with a tiny set of instructions, fewer than brainfuck. A green spot marks the beginning of the program flow. The first spot encountered after start or an intersection writes 1 if red or 0 if blue. It is followed by another spot, which moves the pointer in memory to the right if red, left if blue. If red and blue spots are mashed together, this indicates a branch. If the value currently pointed to is 0, it will follow the path extending from the blue spot, otherwise the red for 1. Yellow spots let the paths cross over other paths without interacting. Black regions (the paths) never split on their own, always at one of these red/blue branches. A loop can be formed by drawing a black line back onto itself. That is all it takes for Turing Completeness.

I asked Knoll how the black lines know which direction to go when a branch joins it.

The implementation for this case is actually very simple. It just follows the edge of the black region until a "branch" (intersection between black+blue+red) is encountered. This works because black regions can only join each other before a branch. In practice, this means that the program will sometimes go the wrong way where the black regions join, but it will backtrack when no branch is encountered.

Knoll's first design represented circuits with logic gates, but felt too complex. The idea took several years to coalesce from there.

Even with the Turing machine model I had several iterations of redesigns, making different tradeoffs between making the language simpler (e.g. using fewer colors), making it easier to learn for new users, and making the language more powerful (i.e. how difficult it is to perform some common programming tasks). Turing Paint could have been designed using fewer than six colors, but those extra colors help make it easier to learn and use. I also designed the language so that it would be easy for me to implement, so the actual JavaScript coding was pretty quick.

The code for the Turing Paint interpreter is open-source and released under the public domain, but you won't find it in Github; view source and it is there, all inline, in vanilla JavaScript. As a brand new language, there is just the one example program for the moment; but with the fun of scribbling out programs and the working JS interpreter to test them, we will see what body of work emerges for it.