Opacity is often the goal
Hard-to-read code in an ordinary language is usually an accident. In an esoteric language it is often intentional, or at least an accepted side effect of the design. Knowing the specific causes is useful, because each one is the opposite of a habit that makes everyday code easier to maintain.
Cause 1: no meaningful names
Practical languages let you name variables, functions and types. A name like total_price tells a reader what a value is for. Many esolangs have no names at all. In Brainfuck, data lives in anonymous cells and the program is a stream of punctuation. You must track in your head which cell holds what, because the code does not say.
Lesson: names carry intent. When code cannot express intent, readers must reconstruct it, which is slow and error prone.
Cause 2: tiny instruction sets
With only a handful of commands, even a simple operation takes many steps. Adding two numbers may need a loop, a pointer move and a decrement. The reader sees mechanics rather than purpose, the way a long list of arithmetic steps hides the idea of “total.”
Lesson: abstraction compresses meaning. Functions and higher-level constructs let a reader skip detail they do not need.
Cause 3: hidden state
In tape and stack languages, the current state of the machine is not visible in the program text. You have to simulate it. Where is the pointer? What is on the stack right now? Nothing in the source answers these questions, so understanding a program means executing it mentally. This is why tracing by hand is such a common technique.
Lesson: code that depends on invisible state is hard to review. Making state explicit, through clear variables or small functions, helps readers a great deal.
Cause 4: unusual control flow
In a grid language such as Befunge, the instruction pointer can turn in any direction, so the path of execution does not follow the reading order of the text. A single cell can be passed in more than one direction. The reader must trace the path rather than read it. Conditional branching is expressed as a fork in the path, and loops appear as shapes.
Lesson: when execution order differs from reading order, readers get lost. Mainstream languages keep the two close on purpose.
Cause 5: the wrong visual channel
Some languages move meaning into places readers do not normally look. Whitespace hides code in blank characters. Others encode instructions in color, and others use text that reads like prose but follows hidden rules. Each of these breaks the link between how code looks and what it does.
Lesson: layout and appearance are part of a program’s communication, not decoration.
Cause 6: tricks and density
Experienced users of odd languages often write compact, clever code. Reusing a cell for two purposes or placing instructions so that they serve double duty saves space but makes the program harder to follow. In a language that allows self-modifying programs, the code a reader sees may not even be the code that runs.
Lesson: cleverness has a cost. Code is read far more often than it is written.
What helps readers anyway
Even in these languages, people have developed ways to cope:
- Comments, or in Brainfuck any ignored characters, placed next to code
- Layout conventions that line up related instructions, which is the whole idea behind careful code layout in Befunge
- Small, tested building blocks reused across programs
- Tools that visualize execution, such as a step-through trace
- Writing the program first in a friendlier notation and then translating it
These are the same remedies that improve readability everywhere: structure, documentation and tooling.
The bigger takeaway
Esoteric languages work almost like a controlled experiment. Remove names, remove structure, hide state, or scramble layout, and readability collapses. That shows which features of ordinary languages are doing quiet work. When you next choose a descriptive name, split a long function or add a comment, you are replacing something an esolang deliberately leaves out.
None of this means esolangs are poorly designed. A language can be successful at being puzzling, and the difficulty is part of the fun. The useful lesson is only that readability must be designed for, and it does not happen by default.