We are currently working on new rules for what content should and shouldn't be allowed on this website, and are looking for feedback! See Esolang:2026 topicality proposal to view and give feedback on the current draft.
Offset
Offset is an esoteric programming language created by User:Rainwave in January 2026, though it wasn't published to the esolang wiki until August 2026. It was Rainwave's first esolang that he felt was worth publishing. His goal was to create a minimalistic language that has no explicit branching. To perform any computation, the program has to rewrite its own instructions as it runs.
Language semantics
Offset is a self-modifying language, meaning there's no distinction between data and a piece of code that operates on that data. The language operates on a bidirectionally-unbounded tape, where each cell stores one symbol. Unlike the standard tape memory model, the tape head can jump to and read/write arbitrarily far cells relative to its current position. Initially each cell stores a blank symbol (a space), which behaves like a NOP. There are also two registers: symbol register () and offset accumulator (), which are initialized to blank and 0 respectively.
At the start of the execution, the program's source code is loaded into an array of contiguous cells in memory. A pointer () is then set to point to the first character of the source code.
The pointer reads one symbol at each step and determines an action to be performed. The language recognizes a few special symbols (commands), listed as follows
| Command | Description |
|---|---|
d (0-9) |
Append a single digit d to . This is equivalent to .
|
> |
Jump cells right. |
< |
Jump cells left. |
$ |
Load the symbol at into . |
= |
Store the current symbol in into the cell at . |
. |
Output the symbol at to the standard output. |
& |
Terminate the execution. |
At each step, after executing the command (except > and <), the pointer naturally advances to the next cell. If the command was not a digit, will be reset to 0. Other symbols that are not listed above are ignored, effectively behaving like a NOP.
Examples
Hello World!
34.32.30.28.26.24.22.20.18.16.14.12.Hello World!&
Truth Machine
40$41=38> TRY CHANGING THIS TO A 1 --> [0] x1>1.0& 1.10<
Looping Counter
This following code prints the integers from 0 to 9. In general, it is possible to create a looping counter up to any given finite value, though dealing with multi-digit numbers can be tricky.
15> 22$2=2x$14=1= 7.20< [0] 123456789&
Computational class
Offset is Turing complete as it can simulate a Universal Turing machine. The original proof sketch was developed with help from User:Olus2000 and Uni on Discord. However, an explicit construction remains very difficult to write due to the nature of the language itself, so it is not provided here. Rainwave hopes to find an intermediate representation that can make an explicit construction easier to write. In the meantime, here's a general overview of the original sketch.
The idea is that two or more looping counters can be chained together such that each counter contributes one digit to a load/store offset, making the range they cover grow exponentially with respect to the total number of cells occupied by the counters. We can then map each UTM cell into a constant-length Offset block, separated by a constant distance from one another. Each block stores a "copier" which is a piece of code that can copy the next block into a new block right after it. This is what allows us to simulate an unbounded UTM tape.
Apart from the copier, each block should also store the UTM cell value, a copy of the transition table, the current state of the machine, as well as other mechanisms to simulate the transition logic, such as moving the pointer between blocks, setting the value of the block, detecting whether the copier should be triggered, and so on. All of these should fit inside a constant-length block, which means there's only a constant number of looping counters required to implement the copier as the exponentially growing copy range will eventually surpass the block length, no matter how large it might be.
Implementations
Python
from collections import defaultdict
code = input()
tape = defaultdict(lambda: ' ')
for i, c in enumerate(code):
tape[i] = c
p, a, r = 0, 0, ' '
while True:
if tape[p] == '$':
r = tape[p + a]
elif tape[p] == '=':
tape[p + a] = r
elif tape[p] == '.':
print(tape[p + a], end="")
elif tape[p] == '&':
break
if tape[p].isdigit():
a = 10 * a + int(tape[p])
p += 1
elif tape[p] in '><':
p = p + a if tape[p] == '>' else p - a
a = 0
else:
a = 0
p += 1