Funge-98 in Depth

Loading Extensions Safely

How a Funge-98 program asks its interpreter to load optional extensions, what can go wrong, and habits that keep programs predictable and safe to run.

On this page
  1. The idea behind extensions
  2. How the request works
  3. Habit one: expect refusal
  4. Habit two: do not assume which letters you get
  5. Habit three: be careful about what an extension can do
  6. Habit four: keep portability in view
  7. A short mental model

The idea behind extensions

Funge-98 keeps its core instruction set small. To add more without changing the language itself, it reserves the capital letters A to Z. In a fresh program those letters do nothing useful. A program can ask the interpreter to attach a set of new meanings to them, and the interpreter either agrees or declines. A set of such meanings is an extension, and the identifier a program uses to ask for one is a fingerprint.

The mechanism is explained in more depth in the article on Funge fingerprints. Here the focus is narrower: how to use the request responsibly, so that a program behaves sensibly whether the extension is there or not.

How the request works

Two instructions are involved. The load instruction, written (, pops a count and then that many values, which together form the identifier. If the interpreter knows the extension, it assigns the extension’s behavior to some of the capital letters, pushes the identifier back, and then pushes a 1 to signal success. The unload instruction, written ), takes a similar request and removes the extension’s behavior from those letters.

If the interpreter does not know the identifier, the load instruction reflects. The pointer turns around and nothing is loaded. As with any unknown instruction, the pointer just goes back where it came from, so the program must be arranged to notice.

The fine details, including how the identifier is formed from the cell values, are in the specification. Check your interpreter’s documentation for the extensions it supports, because the list varies a lot.

Habit one: expect refusal

The most important safe habit is to assume the request can fail. A program that loads an extension and then uses its letters without checking is at the mercy of the interpreter. If the extension is missing, each of its instructions reflects, and the pointer will wander in ways that are hard to understand.

A reasonable pattern is to:

  1. Make the request on a path where a reflection leads somewhere harmless, such as a message that says what was missing and then a clean stop.
  2. Continue only on the success path.
  3. Keep the extension-dependent code in one region, so there is a single place to read when something goes wrong.

Because a failed load reverses the pointer, many programmers lay out the code so the reversed pointer runs into a small error handler on the way back. Tracing that path by hand is worth doing once, since the code in front of the load is traversed in the opposite direction.

Habit two: do not assume which letters you get

When an extension loads, it takes over particular letters. Different extensions use different letters, and loading a second one can reassign a letter that the first one used. The most recently loaded meaning usually wins, and unloading brings back the previous one. This is a stack-like behavior per letter.

Practical consequences:

  • Load the extensions you need at the start, in a fixed order, and avoid loading and unloading in the middle of a loop.
  • Do not write code that depends on a letter being unused. A letter you treated as a no-op might be live.
  • If you use more than one extension, document which letters each one owns. A short table on paper is enough.
  • Remember that capital letters in your data, such as inside quote mode, are harmless, but capital letters sitting in code cells may suddenly do something after a load.

Habit three: be careful about what an extension can do

Extensions can be harmless or powerful. Some might add math functions. Others might touch files, the network or the host system. A program that loads an unfamiliar extension should be treated like any program with extra privileges.

  • Only load extensions you understand, and prefer ones documented by the interpreter you use.
  • Do not run programs from unknown sources with every extension enabled. Many interpreters let you disable categories of extensions, file access and command execution in particular.
  • Be careful with the command-execution instruction, which is part of the core language rather than an extension but raises similar concerns. A program that can run commands can do whatever the user can.
  • Do not paste in a program that loads something obscure just because it works. Read the load sequence first and ask what that identifier means.

Habit four: keep portability in view

An extension is not guaranteed to exist anywhere other than the interpreter that provides it. If you share a program, say in a short note which extensions it needs. A program that quietly depends on one extension only works for readers who have it.

Where possible, write the core logic with the base language and use an extension only to speed up or tidy a small portion. Then, if the extension is missing, you can fall back to a slower routine written out by hand. This is more work, but it makes the program robust, and it is a good exercise in separating what is essential from what is convenient.

Interpreter authors have a matching duty. If you are building interpreters, treat an unknown identifier as a clean refusal, never as a crash, and document which identifiers you accept. Testing both known and unknown requests is an easy way to catch mistakes, and it fits naturally with interpreter testing.

A short mental model

Think of the load instruction as a polite question, not a command. The interpreter answers yes or no. Your job is to be ready for either answer, to know exactly what a yes gives you, and to avoid asking for more power than the task needs. Programs written this way are easier to trace, easier to share and much less likely to behave unexpectedly on a different interpreter.

The complete guide to funge-98 in depth

Funge-98 Features in Depth
Read the guide

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