Est. 1998 Advanced

Malbolge

An esoteric programming language deliberately designed to be nearly impossible to program in, named after the eighth circle of Hell in Dante's Inferno.

Created by Ben Olmstead

Paradigm Esoteric, Machine Language
Typing None (operates on ternary memory cells)
First Appeared 1998
Latest Version N/A (specification unchanged since creation)

Malbolge is widely considered one of the most difficult programming languages ever created. Designed in 1998 by Ben Olmstead specifically to be nearly impossible to use, it is named after Malebolge, the eighth circle of Hell in Dante Alighieri’s Inferno — a fitting name for a language that punishes anyone who attempts to program in it.

History & Origins

In 1998, Ben Olmstead, inspired by the esoteric programming language community, set out to create a language that would be as difficult as possible to program in. According to the original specification, Malbolge “borrows from machine, BrainF***, and tri-INTERCAL, but put together in a unique way.” Befunge is also commonly cited as an influence. Olmstead succeeded so thoroughly that he himself has never written a complete Malbolge program. The entire language was designed and implemented in a single afternoon.

It took approximately two years before anyone managed to produce a working Malbolge program — and even then, it wasn’t written by a human. Around 2000, Andrew Cooke used a beam search algorithm implemented in Lisp to generate the first functional Malbolge program. That program reportedly output “HEllO WORld” with non-standard capitalization, far from a conventional “Hello, World!”.

Why “Malbolge”?

The name comes from Malebolge (Italian: “evil ditches”), the eighth circle of Hell in Dante’s Divine Comedy. In the poem, the Malebolge is a large funnel-shaped cavern divided into ten concentric trenches where fraudsters and deceivers are punished.

The name is entirely appropriate — programming in Malbolge is a hellish experience by design.

How Malbolge Works

Malbolge is a machine language for a ternary (base-3) virtual machine with specific design choices intended to maximize difficulty:

The Virtual Machine

  • Memory: 59,049 (3^10) memory locations, each holding a value from 0 to 59,048
  • Registers: Three registers — Code pointer (C), Data pointer (D), and Accumulator (A)
  • Architecture: Von Neumann (code and data share the same memory)
  • Number system: Ternary (base-3) with 10-trit values

What Makes It So Difficult

  1. Self-altering code: Every instruction modifies itself after execution, making programs nearly impossible to trace mentally
  2. The “crazy operation”: A custom tritwise operation on ternary digits that is deliberately counter-intuitive and has no standard mathematical name
  3. Ternary arithmetic: Base-3 operations are inherently less intuitive than binary or decimal
  4. Instruction encryption: Valid instructions must pass through an encryption table, and the program is validated before execution
  5. No human-readable syntax: Programs look like random strings of printable ASCII characters

The Eight Operations

InstructionOperation
j (4)Set data pointer to value at current data pointer
i (5)Set code pointer to value at current data pointer
* (23)Rotate the value at data pointer right one trit, store in accumulator
p (39)Perform “crazy operation” on accumulator and data pointer value
< (40)Read one character from stdin
/ (62)Write accumulator value as ASCII to stdout
v (81)Stop execution
o (others)No operation

Note: The actual instruction executed depends on the memory value at the code pointer after decryption — the numbers in parentheses are the decrypted operation codes. There is a well-known discrepancy between the original specification and the reference interpreter: the input (<) and output (/) operations are reversed in the specification. Olmstead has stated the interpreter is correct and the specification contains the bug. The table above follows the reference interpreter’s behavior.

Not Turing-Complete (By Default)

An important theoretical property: standard Malbolge is not Turing-complete. Its fixed memory of 59,049 cells makes it a bounded-storage machine — more powerful than a linear bounded automaton but unable to compute everything a Turing machine can.

In 2007, Orjan Johansen created Malbolge Unshackled, which removes the memory limit and achieves full Turing completeness.

Programming Approaches

Since hand-writing Malbolge programs is essentially impossible for anything non-trivial, several approaches have emerged:

Automated Search (Most Common)

The most successful approach treats Malbolge as a search problem. Programs like John Markus Bjorndalen’s generator recursively search through possible execution paths to find programs that produce desired output.

Cryptanalysis

Lou Scheffer’s breakthrough insight was treating Malbolge as a cryptography problem: “The correct way to think about Malbolge… is as a cryptographer and not a programmer.”

Code Generators

Several code generators exist that can produce Malbolge programs for arbitrary output strings, effectively making the language usable — if you consider using a generator “using” the language.

File Extensions

Malbolge source files typically use:

  • .mb — Most common in the community
  • .mal — Alternative extension

Running Malbolge

Several interpreters exist:

  • esolang-box — Standardized Docker images for esoteric languages
  • Various C implementations — Based on Olmstead’s original interpreter
  • Online interpreters — Available for quick experimentation

For this tutorial, we use a Docker-based interpreter for consistent cross-platform execution.

A Language Designed to Be Impossible

Malbolge represents the extreme end of esoteric language design. Where Brainfuck challenges with minimalism, Malbolge challenges with active hostility. Every design decision was made to frustrate the programmer:

  • The creator never wrote a program in it
  • The first program took two years to produce and was machine-generated
  • Programs cannot be meaningfully read or understood by humans
  • Writing programs by hand is practically impossible for anything beyond trivial output

Yet people continue to push the boundaries. In 2020, Kamila Szewczyk created MalbolgeLISP — a working Lisp interpreter written in Malbolge Unshackled — demonstrating that with enough determination (and automated tools), even the most hostile language can be tamed.

Continue to the Hello World tutorial to run your first Malbolge program.

Timeline

1998
Ben Olmstead creates Malbolge, designing it in a single afternoon
~2000
Andrew Cooke generates the first Malbolge program using a beam search algorithm in Lisp, approximately two years after the language's creation
~2005
Lou Scheffer publishes a cryptanalysis of Malbolge, treating it as a cryptographic problem (exact publication date uncertain)
2006
John Markus Bjorndalen creates a Malbolge code generator that produces working programs (per the author's own documentation)
2007
Orjan Johansen creates Malbolge Unshackled, a Turing-complete variant
2020
Kamila Szewczyk creates MalbolgeLISP, a Lisp interpreter in Malbolge Unshackled

Notable Uses & Legacy

Cryptanalysis Research

Lou Scheffer demonstrated that Malbolge is best approached as a cryptographic problem rather than a programming one.

Automated Program Generation

Malbolge programs are typically generated by search algorithms rather than written by hand.

Computational Theory

Standard Malbolge is a bounded-storage machine (not Turing-complete due to fixed memory), while Malbolge Unshackled achieves Turing completeness.

Esolang Community Challenges

Used in programming challenges and CTF competitions as an extreme difficulty test.

Language Influence

Influenced By

Brainfuck tri-INTERCAL Befunge

Influenced

Dis Malbolge Unshackled

Running Today

Run examples using the official Docker image:

docker pull esolang/malbolge:latest

Example usage:

docker run --rm -v $(pwd):/code esolang/malbolge malbolge /code/hello.mb

Topics Covered

Last updated: