What “two-dimensional” means here
Most programming languages are one-dimensional in a quiet way. The source is a sequence of characters, and the interpreter reads it from the first to the last, with line breaks and indentation serving mainly the human reader. A two-dimensional language changes that rule: where a symbol sits on a plane is part of what the program says. Moving a character one cell to the left or up can change what the program does, even if the character itself is untouched.
That idea covers a surprisingly varied group of languages. Some read text on a grid, some read pictures, and some use shapes such as hexagons. They are mostly hobby projects and experiments, and they sit in the wider world of esoteric programming languages, though a few of the underlying ideas also appear in mainstream tools.
Three ways position can matter
It helps to separate the ways a language can use a plane.
Layout as control flow. The program is a grid of characters, and an instruction pointer travels across it. Certain cells change the direction of travel. The path the pointer takes is the program’s control flow, so you can often see loops and branches as shapes.
Color or geometry as the instruction. The program is a picture, or a shape in some other sense. Which operation runs depends on colors, on how areas border one another, or on the shape of the region the pointer is in.
Spatial relationships between parts. Here the program is a set of pieces and the connections between them, as in many block and wire diagram tools. Position on the screen is often cosmetic, and what matters is which piece is connected to which.
The first two are what this site mostly means by two-dimensional. The third is usually called visual programming, which is a related but different tradition.
Where Funge fits
The Befunge language is the best-known text-based example. A program is a rectangular grid of characters, the instruction pointer starts at the top left heading right, and arrow characters turn it. The standard Befunge-93 grid has fixed dimensions, while the Funge-98 specification relaxes that and generalizes the idea. Funge-98 also reaches beyond the plane, as the notes on Trefunge dimensions show, with a version in three dimensions and another in one.
Three features define the family and recur in the other languages below:
- A pointer moves in a direction, and the program can change that direction. This is the core of grid-based flow.
- The grid has a defined edge behavior. In Befunge, the pointer that leaves one side re-enters on the opposite side, which makes the space behave like a toroidal playfield.
- The program’s data lives on a stack, and the grid itself can also be read or modified while the program runs.
Each of these has counterparts elsewhere in the survey.
A tour of neighbors
Fish. The language usually written as ><> keeps the idea of a moving pointer on a wrapping grid, but steers it differently. Besides arrows it uses mirror characters that reflect the pointer. The details are in the article on Fish and other mirror-based languages. Its basic relationship to Funge is close: it is a sibling, not a different species.
Piet. Here the source is an image. The program is made of connected blocks of color, and the pointer moves between blocks. The operation to perform comes from the change in hue and lightness when the pointer crosses from one block to the next. Piet is named after the painter Piet Mondrian, and good programs can look like abstract art. The full details are in the article on Piet and its colors.
Hexagony. This language lays its code out on a hexagonal grid, with six directions instead of four. The article on programming on a hexagonal grid looks at what that changes, including how neighbors, turns and edges behave.
Cellular automata. A system such as the Game of Life has no instruction pointer at all. A grid of cells updates by a local rule, and a “program” is an arrangement of cells. This is a very different style of computation, but position still carries all the meaning. Related one-dimensional examples exist too, and the topic of cellular automata has its own place on this site.
ASCII art as source. Some programs are written so that the source text itself forms a picture. Sometimes the shape is just decoration; sometimes it is the structure of the program. The article on ASCII art programs covers the difference.
What about Whitespace?
A common point of confusion is the Whitespace language, which uses only spaces, tabs and line breaks. The program looks like blank paper, but it is still read as a one-dimensional sequence. Layout does not mean position on a plane there. It is an esoteric language about visibility rather than geometry, so it belongs in a different group.
Trade-offs of working on a plane
Two-dimensional languages tend to be fun for exactly the reasons that make them awkward.
Control flow becomes visible. In a good case you can trace the path of the pointer with a finger, and a loop looks like a loop. In a bad case, paths cross and overlap, and a single cell may be visited from several directions with different meanings.
Editing is delicate. Inserting a line or a column can shift the whole program. Text editors are built for one-dimensional text, so tools that show the grid, highlight the pointer or provide a trace visualizer are much more useful here than for ordinary code.
Readability is a design choice. The rules say nothing about how tidy you should be, so a reader may find a small program as hard to follow as dense obfuscated code. The reasons are partly structural and partly about habits of layout.
Interpreters are small. Because the rules are few, writing an interpreter for a grid language is a manageable weekend project, which is one reason hobbyists keep inventing new ones.
How to explore
A reasonable path is to start with a language whose rules fit in your head, and the Funge family is a good choice. Once you can follow a Befunge program by eye, ><> will feel familiar within an hour or so. Piet is a nice change of pace because you can use any image editor and think in blocks. Hexagony is the strongest test of spatial intuition, and it is better saved for last.
In each case, the useful question is the same: what does the language let position decide, and what does it leave to something else? Answering that for each language is the quickest way to understand how they differ.