Funge-98 in Depth

What Happens When an Instruction Is Unknown

Funge-98 treats unsupported or unassigned instructions as a reflection that turns the pointer around. Learn why, how it shows up, and what it means for portability.

On this page
  1. The rule in one sentence
  2. Why reflect
  3. What it looks like in practice
  4. Reflection and the capital letters
  5. Portability consequences
  6. Notes for interpreter authors
  7. A debugging habit

The rule in one sentence

In Funge-98, when the pointer meets an instruction that the interpreter does not implement, or that currently has no meaning, the pointer reflects: it reverses its direction and heads back the way it came. The reversal is the same action as the reverse instruction r. Nothing is added to the stack, and no error message is required.

This applies to several situations. A character the language never defined, a capital letter with no extension loaded, an optional instruction the interpreter has chosen not to support, and an instruction that cannot work in the current situation (for example, a block-end with no matching block) can all behave this way. The details of each case belong to the specification and to the interpreter, but the common thread is a reflection.

Why reflect

The designers needed some answer, and there are only a few choices. The program could crash, the instruction could be silently ignored, or the pointer could turn around.

  • Crashing is clear, but it makes optional features awkward. Every program would have to know in advance what its interpreter supports.
  • Ignoring is convenient for comments and padding, but it allows the program to continue as if the instruction had worked, and the results are quietly wrong.
  • Reflecting is a middle path. It keeps the program running, and it usually produces visible and often dramatic misbehavior. It also lets programs build checks: if a feature is missing, the pointer comes back along the route it took, and the code can handle that.

The choice follows from the language’s spatial nature. A pointer that reverses retraces its steps, so what it just did is undone in terms of position, which is a natural way to say “that did not work.”

What it looks like in practice

A typical symptom is a program that seems to run backwards or loops between two cells. For example, suppose a row runs east with an unsupported instruction in the middle. The pointer reaches it, turns around and runs back west through the cells it just executed, in reverse order. If those cells include operations that changed the stack, the reverse pass applies them again, in the opposite order, and the stack ends up in a mess. Often the pointer returns to the start of the row, hits a wrapping edge and starts again, giving an endless loop.

This is why an apparently minor typo can produce wild behavior. A mistyped character, a digit mistaken for a letter or a stray capital letter may not announce itself. It simply sends the pointer back.

Reflection and the capital letters

The capital letters A to Z are a special case. They are reserved for extensions. Until an extension assigns a letter, using it reflects. After a load, the same letter does something else. This gives a program a way to detect support: attempt the load, and if the pointer comes back, the extension is not there.

It also means that capital letters in code cells are risky. A letter you meant as a harmless label may do something after an extension is loaded. Keep labels and comments out of the code path, and use capital letters in the code only intentionally. The article on Funge fingerprints explains the loading itself, and the one on loading extensions safely covers the habits that make this reliable.

Portability consequences

Because unknown instructions reflect rather than stop, a program written for a feature-rich interpreter can run on a smaller one and fail in confusing ways rather than clearly. To keep programs portable:

  1. Check for support first. Use the information query to read the flags and the dimension count before relying on a feature.
  2. Isolate optional features. Put them in one area with a visible fallback.
  3. Avoid relying on reflection by accident. Some programmers use an unused character deliberately as a reverse, which saves nothing and breaks as soon as an interpreter assigns it a meaning. Use the real reverse instruction.
  4. Write down requirements. A comment-style note outside the code stating “needs two dimensions, file input and one extension” saves a reader a lot of time.

It also matters when moving between languages. Programs from the older language can include characters that were harmless there but have meaning in Funge-98, or the reverse. The Befunge-93 limits and the differences between the versions are worth reading about before porting code, since the same character may mean something new.

Notes for interpreter authors

If you are building interpreters, the default case of your instruction dispatch should be a reflection, not an error. Beyond that:

  • Make sure instructions that reflect on failure do so cleanly, without half-completed side effects such as a partly popped stack.
  • Decide how to treat the instructions you do not support, such as file access or command execution, and document it. Reflecting is the standard-conforming choice.
  • Add a debug option that reports each reflection, because silent reversals are the hardest thing for users to find. A message such as “unknown instruction at position X” costs little and saves hours.
  • Include tests that use unassigned characters, letters with no extension and mismatched block instructions, as part of your interpreter testing.

A debugging habit

When a Funge-98 program behaves strangely, ask first: “where could the pointer have reflected?” Trace the path and look for any cell you are not certain is an instruction on this interpreter. Replacing suspect cells with a no-operation instruction or a space, one at a time, quickly shows which one matters. It is a small habit, but it turns the most puzzling class of grid debugging problems into a short checklist.

The complete guide to funge-98 in depth

Funge-98 Features in Depth
Read the guide

Keep exploring

Guides from other topics

All topics →