In:verse has a simple premise: a poem that generates an image or animation.

It is a multicoding esolang, meaning its programs have double-readings: in this case, code as poetry. This is in the tradition of Piet (code as image) and Shakespeare (code as play). Unlike those languages, however, in:verse is not for general computing. By avoiding flow-control and recursion entirely, its creator Sukanya Aneja focused the language completely on creating compelling poetry and visuals in a way that both experienced and beginning programmers can engage with.

The simplicity of its command set is important because of in:verse's other unusual feature: its lexicon is unique to each program. In:verse has a static list of commands, but how those commands are called—their actual keywords—varies from program to program through an additional level of indirection. One poem might use the word "love" for tangent, while another poem will use the word "orange" in its place.

This approach is reminiscent of Esopo by Will Hicks; but where Hicks accomplished the variability of expression through many different languages, each finely-tuned for one mode of expression, in:verse leaves the naming to the designer of the individual piece, who essentially creates their own dialect of the larger language.

This is managed through a friendly interface that displays the wordtable (current list of keywords) and stack alongside the code and running program. Like a livecoding language, in:verse runs continuously, updating immediately when the program changes. This favors a trial-and-error approach, where one can take an existing program, alter the lexicon for the vocabulary that fits the coder's vision, extend verses or shorten them, and see the results. As a visual piece comes into focus, the programmer can alter the vocabulary to better relate the poem and generative visuals.

Aneja looked to earlier languages to build her language.

My research on esolangs drew me to Shakespeare and Chef particularly—languages that looked like natural languages—and I realized that most of these types of esolangs adopt a stack-based paradigm.

In:verse adopted both the stack, meaning the complexity of named variables can be avoided, and also the Forth-like reverse Polish notation. Each in:verse program has three inputs and three outputs: x and y (the coordinates of the pixel being evaluated) and t for time. The output are the red, green, and blue values for that pixel; the program runs continuously on each pixel in the square canvas. The stack is displayed as it is before evaluation. After evaluation, the (top) three elements remaining in the stack are read as the r, g, and b values. If there are not enough variables in the stack, or if a (preset) function doesn't have enough inputs, a random number is assigned.

[S]ince shaders only deal with floating point numbers and I wanted to embed some uncertainty in the language, I decided to return random numbers to avoid stack underflows. Where a programmer does not provide enough information, the language makes something up—ensuring that a program never crashes. I also embedded some randomness based on the number of words one puts in a line—so that identical programs written by me and you would still lead to slightly different output, based on the flavor of our writing.

For an example of how this works, take the piece "Untitled" by @maxbittker. By opening the developer console, we can see that the stack (viewable to the right of the canvas) translates to:

vec3(0.08990512765012681,cos(((0.8455037623643875 * degrees(atan((y / x)))) * tan(t))),y)

The stack begins with y and x. This comes from the first line, "tubes cruelly curved," where "tubes" corresponds to y in the wordtable, and "curved" to x. "Cruelly" is merely decorative here, in terms of the code's functionality. The second line, "separating boundary snow," adds /, atan, and degrees to the stack. / takes two parameters, so it applies to the y and x already on the stack, giving us:

(y / x)

The next two functions are both unary, so they apply to that output, giving us:

degrees(atan((y / x))

The tangent function brings in the t variable for time (in microseconds), turning the still image into a looping animation. Since cosine does not have enough parameters, a random number is applied (a static one based on the number of words, as Aneja describes above) and the same for the final three-part vector because the stack, after evaluation, has only two elements: this means that the red value will have a (random) constant across the piece.

The friendliness of the interface and the continual looping of the programs suggests its use for livecoding, but that was not initially planned:

What was probably the most unexpected response was a friend recording himself using in:verse—creating a performance of sorts. I had not thought about the performative aspect until this point. I presented this at Processing Community Hangouts, and someone who freestyles ended up using it in a similar fashion—almost on the other end of the spectrum, where the words seemed to be a far stronger driver than the visuals.

Aneja is continuing to refine the interface, with an emphasis on making it easy for non-programmers to experiment. The panel to the left provides the "!!!" button provides you with sample stacks. You still have to write the commands to get the sample stack to manifest, but it makes jumping into the project easier. By providing preset stacks, not the code to generate them, the beginner is forced to immediately think in terms of the language to get started. Creating a working piece is often a matter of adjusting the poem, adjusting the vocabulary, seeing the visual results, and then going back to the poem, until the code and its execution are both compelling.

In:verse was created as an ITP project. I learned of in:verse at the excellent monthly event WordHack in NYC (and for now everywhere, on Twitch!)