Articles

The Hacker Aesthetic of Minimalist Code

Ask most programmers about minimalist programming and they invoke the word elegance, yet working with extreme code minimalism often means exposing the chaotic underside of our engagement with logic.

Page 11 from Allison Parrish’s “Compasses” (screenshot image by the author)

This article is part of Sunday Edition: “Minimalisms”.
––––––

Each of Allison Parrish‘s poems in her series  “Compasses” (2019) is composed of a diamond arrangement of what she calls a “well-known quartet” of words. The space between each word-pairing is occupied by a word that sits phonetically halfway between the two. A ninth, in the center, averages all four, often resulting in a word no one would expect but that resonates in a peculiar way with the others. At the center of “earth,” “air,” “fire,” and “water,” for instance, is “hair.”

Parrish’s poems are minimalist; they are short enough that they can be understood as text-based art rather than poetry, the cross-over of which is explored in Paul Stephens’ book absence of clutter. Using the Pincelate machine learning model she wrote, Parrish vectorizes the phonemes of each word so they can be added, subtracted, or, in the above case, averaged. It is trained on the CMU Pronunciation Dictionary of 134,000 words, and relies on Parrish’s earlier models, including her “Articulations” project.

It might seem odd to open a discussion of code minimalism with a work of minimalist poetry produced by code, but it is a reminder that code is never one thing. Code is defined by its entanglements — between the text of code and its performance or output when executed, the programming language in which it’s interpreted, and interactions with other systems, datasets, or users. Codes that are minimal in one dimension (e.g. a very short program) might be maximal in another. Some minimalist codes break down this multivalence of code to question how code is defined.

Ask most programmers about minimalist programming and they invoke the word elegance, a clarity of expression in the language design or the written code. This idea, as expressed in Donald Knuth’s multi-volume tome The Art of Computer Programming amounts to an almost mythical ability to capture logical complexity in concise abstractions that ease human understanding of the machinic process. Yet as we will see, working with extreme code minimalism often means breaking from elegance to expose the chaotic underside of our engagement with logic.

Maximal Minimalisms

In 1993, a young programmer named Urban Müller shared his new language called brainfuck to an Amiga mailing list. Brainfuck was intended to function as a full-fledged language with the smallest possible compiler (the program that converts programs in that language into the ones and zeros of machine code). It has only eight commands, each represented by a single punctuation mark. Its compiler is 256 bytes, or a quarter of 1k. A typical program in brainfuck (properly spelled lower-case) is anything but minimal, appearing to the uninitiated as an absurdly long mass of undifferentiated punctuation marks, a dense and chaotic concrete poem.

Brainfuck is an example of a minimalist programming language with maximalist programs; see how numbers are written in brainfuck for an idea of what basic math looks like. It maintains algorithmic expansiveness by pushing complexity from the language to the programs written in it. It helped establish esolangs (short for “esoteric programming languages”) where extreme experimentation is the norm. It inspired works like the similarly minimal JSFuck (2012), a dialect of JavaScript designed by Martin Kleppe, based on an accidental and long-undiscovered feature always lurking in JS, that any expression in JS can be written with only punctuation.

Where brainfuck often engenders maximal programs, we can contrast minimalist forkbombs, short programs that are maximal in their performance, designed to overwhelm and shut down the machine. They set in motion a single process that splits — forks — into two, each of which fork into two more, expanding exponentially. Jaromil’s “ASCII Shell Forkbomb” (2012) is a minimalist piece that happens to be one of the most recognizable pieces of code. It is also the most-tattooed.

:(){ :|:& };:

The choice to name the function :() instead of something more conventional like f() means it is perhaps the shortest program that could be considered obfuscated, intentionally unclear, and the very opposite of “elegant code.” This mass of punctuation, like the punctuation-only programs of brainfuck and JSFuck, makes code alienating, and emphasizes the machinic nature of code. In contrast, Pall Thayer’s “Subverting time-based media: Frozen in time” (2009) is a minimalist forkbomb written in the friendly, English-like syntax that Perl aspires to. (Note: Perl is not always so friendly.) It forks with the command “fork” and prints a lyrical message about the human experience of time’s malleability while running the program to manipulate the experiential time of the computer’s tasks, eventually bringing it to a standstill:

#!/usr/bin/perl

fork && print “Time has fallen asleep in the afternoon sunshine.\n” while 1;

Minimalist Constraints 

Coding tiny programs traces back to the early days of computing, when programmers had to work with limited resources. It was honed as a competitive skill in the demoscene era of the 1980s and ’90s, when dense, nearly unreadable programs became a part of the hacker aesthetic. In modern competitions called code golf, programs that produce the same output are scored by the number of characters used. The yearly contest js1k and micro-blogging site dwitter.net celebrate technical mastery in JavaScript pieces given strict character limits. They are open source, encouraging the sharing of code and the reuse of discoveries made in earlier work.

The literary journal Taper, created at MIT’s Trope Tank, publishes tiny programs with similar size limits, but with a curatorial approach favoring thoughtful engagement over flashy graphics. Editor Sebastian Bartlett’s piece for issue three, “Triangles of Mind,” is a carefully crafted visual work packing a surprising amount of variation in a tiny program. It uses every character of the 3k limit, employing the same variable in multiple ways, dense, and unreadable.

Expertise in JavaScript or code obfuscation is not necessary to make work that follows these strict size limits. Lillian-Yvonne Bertram, an accomplished poet with a Ph.D. in Literature and Creative Writing, used clearly-written CSS to give her work “Weights and Measures” frenetic activity on the screen. This slows our intake of the phrases, which draw on American wealth and slavery, as embodied in the cotton content of each dollar bill. Bertram chose bold colors “that would be hard to look at and that also seemed reminiscent of low-budget and lo-fi television or internet ads. It’s intended to be hard to look at, as the topic itself is hard to stomach,” as she explained by email.

The extreme size limit can force code poets and artists to boil down their work to its essential elements. Leo Flores, in issues two and three of Taper, made text-generative works about Puerto Rico and Hurricane Maria. For issue two, which had a theme of duality, he combined his twitterbots, Little Protests (protest-related emoji with English phrases) and Protestitas (the same in Spanish), themselves works of minimal coding, into a continuous, bilingual flow. For issue three, he revisited this with a triptych representing Puerto Rico before, during, and after Maria. True to the hacker approach, he borrowed coding tricks he picked up from viewing the source of works in earlier issues, and also credits editor Angela Chang who helped him shape the code and bring it down to size.

Dematerializing Code

Nick Montfort, who heads the Trope Tank, is known for his own code-minimalist poetry, some collected in his book #!. His paper “No Code” (2013) takes a step further, examining the behavior of an entirely empty program.

Expanding on the idea of the “uninscribed work” examined in Craig Dworkin’s No Medium, Montfort explains, “Art can be considered, analyzed, and discussed even if it has no content, because of important aspects of presentation, reception, and other sorts of context … I aim to show that the same is true when it comes to computation.”

But what counts as no content in computer programming? The smallest valid programs in each language are usually larger than zero bytes, as shown in this list. And yet empty programs, whether or not they are considered valid, invoke activity when run, as seen in the attempt to run an empty file in Python described in the 2020 Critical Code Studies Working Group post “What Python Does When It’s Doing Nothing”: When the runtime is started, libraries are loaded, resulting in 234 different files opened or read, in the service of a program with no commands.

Montfort recounts the debate among the judges of the best-known obfuscated code contest, the IOCCC, on whether an empty file is a valid program in the C language. The submission was a quine, a program that prints its own code to the screen. It just happened to have no code at all to print. In the end, the judges, despite some added complexity in getting it to run, accepted it as a winning submission (in the “Worst Abuse of the Rules” category), which prevents anyone from entering an empty program in the contest again, since it could then be disqualified as plagiarism.

The empty program is not the smallest program one can run. The programming language Unnecessary (2005) by Keymaker, has only one valid program: a program that doesn’t exist. For Unnecessary, even an empty program is too verbose. Only a program that can’t be found is accepted. Like the empty C program, it prints its own (lack of) source code to the screen (does nothing). Utterly useless for practical coding, Unnecessary has only what the classic Dragon compiler book calls a “recognizer;” it divides texts into those that belong to the language and those that don’t. Languages like Unnecessary challenge conventional ideas about what a programming language is. And it is far from the only language that plays with dematerializing code; there are other languages that make code invisible or remove usability to challenge conventional definitions of language or code.

This deconstruction of code and language emphasizes the multiple meanings and contexts code holds — the way code still exists, even when its text doesn’t. Like the minimalist and constraint-based programming described above, they affirm that code is never one thing, but always a system of text, language, and performance.

comments (0)