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
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
- Self-altering code: Every instruction modifies itself after execution, making programs nearly impossible to trace mentally
- The “crazy operation”: A custom tritwise operation on ternary digits that is deliberately counter-intuitive and has no standard mathematical name
- Ternary arithmetic: Base-3 operations are inherently less intuitive than binary or decimal
- Instruction encryption: Valid instructions must pass through an encryption table, and the program is validated before execution
- No human-readable syntax: Programs look like random strings of printable ASCII characters
The Eight Operations
| Instruction | Operation |
|---|---|
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
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
Influenced
Running Today
Run examples using the official Docker image:
docker pull esolang/malbolge:latestExample usage:
docker run --rm -v $(pwd):/code esolang/malbolge malbolge /code/hello.mb