statement: Are avant-garde practices still important to you?
I see esolangs as an avant-garde of computer science, challenging the norms of programming practice and computational culture. Some go further, obliterating the definitions of programming language, code, and computer. In the machine, no data has inherent meaning; this makes the rigidity of computational thinking ripe for challenge and re-evaluation.
It was accepted mostly as a clever joke when Edwin Brady and Chris Morris chose April Fool’s Day to announce a programming language written solely in tabs, spaces, and returns. But such a thing was possible: a language that can express any algorithm programmable in C++, written only with white space characters. Whatever their feeling about the language’s legacy (Brady’s current twitter bio disowns the language completely), their creation Whitespace (2003) embodied and expanded on the most challenging ideas in esoteric programming. The three languages I present here are my languages inspired by Whitespace, continuing provocations it raised – intentionally or not.
Tab, space, and return are thought of as contentless: the spaces between words. They are interchangeable in many languages – those in the legacy of C, for instance, may have conventions about when to use tab or space, but are compilable with a tab where a return might be ordinarily used; the language does not favor one over the other. Whitespace flips this, making these characters the ONLY ones with meaning; now any letter or word or punctuation can separate a space from tab, or none at all. All that matters is the order of white space characters. The language dramatizes the arbitrariness of signification. It also means that a Whitespace program can be hidden in the gaps of a C program, using just the spaces.
This arbitrariness is at the center of experimental language design. Theorist Wendy Chun calls the computer a metaphor machine, an ontological medium where nothing has intrinsic meaning and anything can be mapped to anything else. Artistic practices like glitch use sound to manipulate visual data. Malware has been hidden in just about every form of digital content, including the opacity of pixels in advertising images. Data that “means” one thing is granted a second or third meaning.
In designing programming languages, we build a metaphoric system, a plane of immanence (to borrow from Deleuze and Guattari) in which the ideas of the language find coherence. Like a natural language, a programming language has a worldview: it is just a very tiny one, required only to convey the behaviors and capabilities of a computer, and the expectations of its programmers. Whitespace reflects this arbitrariness boldly in its choice to use what is normally discarded. Brady and Morris ask, Why treat these spaces like nothing? Cruelly discarded by other programming languages, in Whitespace, they are rehabilitated, given significance.
In its annihilation of visual inscription, Whitespace poetically mirrors the dematerialization of programming languages themselves. A language, after all, is not necessarily contained in a compiler or interpreter; it may just be a set of rules about what code looks like and how it functions. The nature of programming languages is open-ended, to be explored by programmers writing code in it. Whitespace perhaps unwittingly connects to the history of “uninscribed” experimental literary and artistic works, like those in Craig Dworkin’s “No Medium,” which challenge their media by refusing to express something specific in them. Whitespace makes the case for programming languages to serve both as media themselves and pieces within the medium of computation.
Each of the three languages in this piece attempt to build on this promise, responding to the prompts Whitespace puts forward: how to put the dematerialization of computing at the center of a language, how to build semantics around “empty” signifiers, how to reduce a language to its minimal form, and how to truly empty out a language.
The Folders language considers not only visible text, but even white space excessive. It does not use text at all. It even does away with program files, the ordinary containers for text or other data.
The lexicon of Folders is only the existence of folders and their containment of other folders. A program is a folder. So is a command or an expression. Each is defined by navigating the labyrinth of its subdirectories; if there is folder inside, and that first folder has four subdirectories, we can identify it as a print command.
Folders date back to the first Mac, where they appeared as the graphical symbol for the directory, the organizational structure for files (the directory itself dates back to the Xerox PARC era). Folders are only meant to organize content, they are not considered content themselves. They are structural, a place to store files. The empty folder is perhaps the universal symbol of emptiness on a computer; if a folder has no content, it appears unkempt, something to be deleted.
In the Hello World program, the root folder holds all the other folders. The commands of the program are on the first level. Every command has at least one subfolder, and the number of folders in that first subfolder determine the command type. Data is stored as bits: Each folder with a subfolder is a 1; each folder without a subfolder is a 0. So folders are not just commands but also a form of raw data. [The specifics of Folders is here. https://danieltemkin.com/Esolangs/Folders]
Abstract away a program’s lexical elements, and programs have a tree structure that mirrors the tree structure folders already have in the file system. A folder has files or folders inside of it – its children – and can also sit inside of another folder, its parent. In the file system, all parents are single parents. Likewise, in a program, a command has children, either expressions or other commands, given the recursive nature of most programming languages.
Programs in the Folders language are 0 bytes. No Folders program takes up any space at all. This means that, should you write all your code in Folders, you will have infinite storage for it.
This is because Folders was created for Windows, where folders are considered to take up no room. This is not the case on, say, a Mac, where as we can see 430 empty folders take up a whopping 18k of space.
Extending the Folders language to store other kinds of data, we now have a file system, the Folders FS, where we can store as much data as we want. We have to store text in the folders file names, which runs counter to Folders’s elimination of text, but it gains us unbounded storage. These parallel file and programmatic systems can run alongside Windows, a parasitic system that only meets Windows in execution.
If you fully commit to Folders, and your folder count gets into the billions, you might notice your hard drive slowly shrinking. This is just a coincidence! For reassurance, you can always get info and see that, in fact, no space was used.
In Time Out, the activity of the program happens entirely in the space between the lines of code.
Each line is executed, but in the typical Time Out program, it does nothing. When the line is complete, a Time Out command fires. What that command does is entirely determined by how long the previous line of code took to complete.
In the background, an interpreter cycles through each possible Time Out command, like a big clock hand clicking to point to each possible activity. If a line of code completes, it executes the command it’s pointing to at that moment.
A Time Out program can be written entirely with Sleep commands, a common command that specifies waiting for a set period of time. In Time Out, the Sleep command tells the executor to wait the right amount of time – to not fire until it points at the right place, where the intended command will be initiated. This is definitely the easiest way to get Time Out commands correct. It is ordinarily written as Sleep(x) or TimeOut.Set(x), where x is a length of time in clock units (typically of 30 milliseconds each).
As one can imagine, Time Out is not a fast language. It gets you where you need to go, but it takes its time about it. The “speed” of the language is configurable, but as we’ll see below, setting it too fast can cause other problems. Luckily, there is nothing in the definition of Turing Completeness (i.e. the ability to express all the algorithms runnable in a language like C++) that considers speed. Time Out can be set to run one command each million years, and it will still be a valid language, even if the computer that executes it is unlikely to make it to the end of the program.
The approach of Time Out divorces what the line of code says from its effects; they are like two different programs. In Time Out, it’s not the line of code that tells the interpreter what to do, it’s the performance of that line of code that serves as the language’s vocabulary.
In fact, the command does not need to be sleep, this is arbitrary. Each line of Time Out could simply be a command in another language, executed in any interpreted language. A Python program, running a very different program, yet executing lines in the right staccato rhythm, can be executed simultaneously as Time Out, taking on a second meaning in a single run. Like Whitespace, this code can hide entirely in a program written in another language. This only works, however, if you can predict or control how quickly the lines of code execute.
These examples show how much depends on 30ms. An impatient programmer with a fast computer might configure Time Out to run quicker. Set it too fast and it will “miss” and you’ll have a non-functional program. For a fast computer, 30ms is just about the fastest it can run successfully.
One “ends” a Time Out program by requesting a time out for ever; it will simply sit and wait, cycling through all the possibilities, never again to fire any of them.
This description was the first sentence of the Wikipedia entry for Programming Language in 2014.
It is also the name of a programming language designed in dubious honor of this sentence. Additionally, it’s the text of the language’s only possible program, and the output when that program is run. It is what’s known as a quine program, one that prints its own source code.
This language, which we can call Programming Language for short (APL is already taken!), does not allow for any other programming. It is not concerned with algorithms; only one algorithm is possible here, which can be seen as reiteration (of the input phrase) or erasure (of anything else put into it). It is like a sieve that takes out anything apart from that sentence. Programming Language consists solely of what the famed compiler book known as the Dragon Book calls a “recognizer.” It affirms that a text is valid within a system, and takes out anything that is not.
This language lives in defiance of its own definition. When the first sentence on Wikipedia changes, the name of the language changes and so does the text within it. Currently, it is called “A programming language is a formal language comprising a set of instructions that produce various kinds of output.” It will continue to change each time Wikipedia is updated, almost certainly by people who do not know of this language, and make their decisions with no regard for how this language will be affected or the thousands of programs currently valid in it.
Where the old definition had much that was wrong, the new one is vague to the point of saying almost nothing at all. However, it does include one thing that Programming Language absolutely refuses to do: offer “various kinds of output.” If a sentence that adequately expresses programming language ever begins the Wikipedia page, this language will cease to exist.
There are currently around 4400 valid programs in this language. The earlier definition had more than 5000. Most programs appear with a sense of defeated resignation. No one uses the Wikipedia definition with enthusiasm. Forbes goes so far to say the definition is “in true encyclopedia form also mostly unhelpful.” Yet they included it just the same, which makes that Forbes article a program in this language.
This is not a language focused on Wikipedia oddities or malfeasance. So while “MIKE RULES!!!!” and “some people believe that computers have a written language like 00100110010 as soon as this happens you see a baby fucking another baby” were temporarily valid programs, Wikipedia’s vigilant upkeep invalidated these in seconds. For an instant, all the web pages with “MIKE RULES!!!!” were valid programs (so long as they had at least four exclamation points); now they are obsolete.
Programming Language builds on Whitespace’s redefinition of what a programming language can look like. Where Whitespace has programs that appear empty, the emptiness of Programming Language is in its capacity as a language, its lexicon, essentially everything that makes it a programming language. Unlike Time Out and Folders, Programming Language can not be used to code even simple programs. You can write a web browser in Folders with enough patience, even if it would be extremely impractical. But you can’t even write “Hello, World!” in Programming Language. So in what sense is Programming Language a programming language?
There is a long-running debate about the over-emphasis on algorithms in computer science, and the favoring of the Turing Machine (which describes its algorithmic possibilities) over what we might call the Interaction Machine, covering interaction with users and other systems. Programming Language is purely Interactive. In terms of algorithmic complexity, it is the simplest automaton, the equivalent of a push button. It does nothing at all except print the same thing, when called upon to do so. In a sense, Programming Language is a programming language simply because it’s presented as such. It can be described in the same EBNF notation that many languages are defined in. It can be processed by a computer even if it never will be. It has programs that, when interpreted within the language, have a predictable effect. However, it works much better purely as idea.
Endlessly repeating the same ineffectual definition, this language encourages reflection on computation and the problems defining it outside the closed circle of language, computer, and code. It might seem unfair to pick the Wikipedia definition, which is of course the worst one. I recommend the definitions presented in the book Programming Languages: History and Fundamentals (1969) or Programming Language Pragmatics by Michael L. Scott, which both focus specifically on high-level languages, avoiding some of the pitfalls. But truly no definition will be enough. For every definition of language, a new esolang (an experimental “esoteric” language) will appear that sits on its border, if there isn’t one there already.
Whitespace, Folders, Time Out and Programming Language all fall into this classification of “esoteric” programming languages or esolangs, in that they are designed, not for practical coding, but to expand the ideas of what programming is. There are at least a thousand such languages. Since 2011, I have been documenting their history on the blog esoteric.codes.
Some esolangs focus on the material of communication – using images, music, cooking recipes or punctuation as code, to name a few examples. The esolangs discussed here do the same, but by weaving in ideas of erasure found in experimental literature and art, in order to further Whitespace’s provocation of dematerialization. Folders eschews text and files entirely. Time Out uses not even data, but the performance of other code, as its lexicon, entirely divorcing performance from text. Programming Language takes this gesture of erasure into computation itself, hollowing out what a language ordinarily does, making it perhaps the purest form of obliteration.
Whitespace for me was a jumping-off point for a new type of language. My hope is that others will find inspiration in these and so many other esolangs that challenge the conventions of code.