Funge-98 in Depth

Funge-98 Features in Depth

A tour of what Funge-98 adds beyond the original Befunge: extra instructions, multiple pointers, a stack of stacks, file access, extensions and more.

On this page
  1. The starting point
  2. A freer playfield
  3. More control over the pointer
  4. Concurrency
  5. Smarter stacks
  6. Talking to the outside world
  7. Extensions
  8. Unknown instructions and portability
  9. Other small additions
  10. How to read the rest of this section

The starting point

The original Befunge is a small language: a grid of characters, an instruction pointer that moves in one of four directions, and a single stack. Funge-98 keeps that model but treats it as a base to build on. The new features fall into a few groups: a bigger and more flexible space, more ways to steer the pointer, richer data handling, ways to talk to the outside world, and room for optional extensions.

This page is a map. Each group below points at the idea behind it, and the other articles in this section take the larger features one at a time. Details can differ between interpreters, so treat the descriptions here as the general picture and check the documentation of the interpreter you use.

A freer playfield

The older language fixes the program area at a small rectangle, and its limits are part of what made it easy to implement. Funge-98 drops that fixed size. The space is conceptually unbounded, and programs can read and write cells well away from where the source text was loaded. Cells are also typically wider than a single byte, so a cell can hold a much larger number than a printable character.

Funge-98 also generalizes the number of dimensions. The same ideas apply to a single line, a flat grid or a three-dimensional space, which is how the family gets its one-, two- and three-dimensional members. A few instructions exist specifically for the third dimension, such as ones that move the pointer up or down through layers.

More control over the pointer

In the original language the pointer turns to one of four compass directions and otherwise runs straight. Funge-98 adds finer tools:

  • Quarter turns to the left or right, rather than only absolute directions.
  • A reverse instruction that sends the pointer back the way it came.
  • An instruction that sets an arbitrary movement vector, so the pointer can step diagonally or skip several cells at a time. This is the subject of the article on delta vectors.
  • A jump instruction that moves the pointer a given number of cells, and an instruction that skips code between a pair of marker characters.
  • A repeat prefix that runs the next instruction several times.

Most of these exist to make code shorter and layouts tidier. They also change how you think about a path: instead of a flow of turns, the pointer can follow a slanted line through the grid. Basic ideas such as pointer direction and the way wrapping works at the edges of a toroidal playfield still apply, but the edges are less central once the space is large.

Concurrency

Funge-98 allows more than one instruction pointer to exist at once. A single instruction splits the current pointer in two, and each copy continues independently. The pointers share the same grid, so one can write cells that another reads, which makes careful design important. The interleaving is taken up in the article on running several pointers.

Smarter stacks

The program stack is still the main place for temporary values, but Funge-98 turns it into a stack of stacks. Blocks of code can open a fresh stack, receive some values from the old one, and later return results. That makes grid subroutines far less error prone, because a routine cannot accidentally disturb values beneath its own stack.

Closely related is a storage offset. Instead of always addressing the grid from its origin, the get and put instructions can work relative to a movable point. Combined with the stack of stacks, this lets one block of code run in several places, and it also makes grid variables easier to manage. There is more detail in the articles on the stack of stacks and the storage offset.

Talking to the outside world

Where the original language mostly reads from the keyboard and writes to the screen, Funge-98 provides instructions for other tasks:

  • Reading a file into the grid and writing a region of the grid to a file.
  • Asking the interpreter for facts about itself and the environment, such as the number of dimensions, the size of a cell or the current position. This is covered in the article on system information.
  • Running a command through the host system, which many interpreters either disable or restrict for good reason.

These instructions are where portability and safety become real concerns. A program that works on one machine may behave differently on another, and a program from an unknown source should not be given broad access to files or commands.

Extensions

Funge-98 defines a mechanism for loading optional extensions. A program supplies an identifier, and the interpreter either makes a set of new capabilities available or declines. Those capabilities are mapped onto the otherwise unused capital letters. This is what Funge fingerprints are for, and it is the reason a program can request something such as extra math or text routines without the core language growing. The article on loading extensions safely covers how to ask for them politely and what to do when they are missing.

Unknown instructions and portability

A subtle but important Funge-98 rule is that an instruction the interpreter does not recognize generally acts as a reflection: it turns the pointer around rather than crashing. This is a design choice that makes programs fail in a visible and manageable way, and it is why checking for support before relying on a feature matters. The article on reflect behavior discusses the consequences.

Other small additions

A few smaller instructions are worth knowing by name:

  • Hexadecimal digit instructions that push the values ten to fifteen, which saves a lot of arithmetic.
  • A fetch-character instruction that pushes the character in the next cell, and a store-character instruction that writes one.
  • A comparison instruction that turns left, right or straight depending on how two values compare.
  • A clear-stack instruction and a no-operation instruction.
  • A quit instruction that ends the whole program with an exit code, distinct from the instruction that stops only one pointer.

How to read the rest of this section

If you are comparing the two languages, the Funge-98 specification and the Befunge-93 limits are the natural background. If you are writing your own interpreter, many of these features affect the playfield data structure you choose, because an unbounded space cannot be a simple fixed array. And if you are exploring Funge variants, you will find that the same ideas return in different shapes.

A sensible way to learn is to try one feature at a time in a small program, trace it by hand, and only then combine it with others. Features such as repeating, splitting and offsets each change the rules just enough that unexpected results are common at first, and the habit of tracing by hand pays off quickly.

Keep exploring

Guides from other topics

All topics →

What Is Befunge?

A plain introduction to Befunge, the esoteric language where code lives on a two-dimensional grid and an instruction pointer moves in four directions.

Befunge Basics 5 min read