September 26, 2019

A Plotter Quine

Recurse Center has this fantastic HP7440A plotter from the eighties.

a gif of the plotter drawing some letters

Using only a few simple commands — select pen, pen up, pen down, and move to position — we can draw very precise shapes with a pen. Yesterday, I wrote a utility in Rust that converts a font file and some text into plotter instructions.

A plotted printing that reads 'hello world'

Once I had that code linted, reviewed, and nicely formatted, I immediately inlined all functions, renamed most variables to be single letters, and removed all those pesky newlines. Forget about readability, we’re making a quine, a program that prints its own source code. The plotter could legibly render ~3000 characters on a page using Inconsolata, but since most quines list their source code twice (once for execution, once as a string) we needed to get the source code without the quine string to be under ~1500 characters to fit on the page.

The source code of the quine, printed by a plotter on an 8.5x11 sheet of paper and hung on a wall

The plotter driver terrifyingly crashed twice during printing, but after a few restarts, it managed to complete in two and a half hours.

Technicalities

This isn’t quite a proper quine, since the Rust executable outputs plotter code, not Rust. We have to run the resulting plotter code to produce the original Rust code. Wikipedia would classify this program as “quine-relay” or an “ouroboros program”.

A proper quine also can’t load files, but in our case, we load a font file and the rusttype library. That said, we don’t cheat by loading our main.rs from the filesystem! As mentioned above, the code is replicated twice in the quine, once as a string and once as proper code.

If you ever write your own quine in Rust, be sure to take a look at the format! macro — the {:?} debug representation of a string is conveniently a valid Rust string literal, so you don’t need to worry about inserting escape characters yourself.

The source code for this quine is available on GitHub.