LearnReferenceThe language

The language, precisely

A brainfuck program works on a row of numbered cells with a pointer on one of them. Eight commands move the pointer, change the cell under it, read and print one character, and repeat a piece of program while that cell is not zero. Every other character in a program is a comment. The whole original definition is one table and three sentences [1]; what it leaves open is on the page Where implementations differ.

The machine

The program below is +++>++: six commands. Under it is a row of six cells that all hold 0, and a mark on the cell the pointer is on. Press Play, or drag Step forwards and backwards, and watch the marked command and the marked cell:

Three steps added one to cell 0, three times. The fourth moved the pointer to cell 1. The last two added one to cell 1. Nothing else happened, and nothing else can: a command either moves the pointer by one cell or works on the cell under it. The marked command is one place in the program, the marked cell is one place on the row, and nothing else is remembered. I'm showing six cells; the original has 30,000.

The parts have names:

Tape
The memory: one row of cells. The original has 30,000 of them [1]. Other implementations have more.
Cell
One place on the tape. It holds a whole number and starts at 0. In most implementations it holds 0 to 255, one byte.
Pointer
The mark that says which cell is the current one. It starts on the first cell. On these pages the first cell is cell 0.
Program
A text. The machine reads it from left to right, one command at a time, and stops after the last one.

The program had only two kinds of command. What can the other kinds do?

The eight commands

Choose a command below. The program is that command with a > in front of it, which puts the pointer on cell 1; cell 1 holds 5, except for ., where it holds 72 so that there is a letter to print; for , the input is the letter A. Press Play, or drag Step, and watch what the command changes:

Notice what each one touched. + and - changed the cell under the pointer by one. > and < changed nothing on the tape, only the place of the pointer. . sent a cell to the output and , took a letter from the input. The pair [ and ] asked whether the cell was 0, and repeated what stands between them until it was. Here are the eight commands in a table, with the wording of the 1993 README and its translation into C:

The eight commands. The third column is the wording of the 1993 README, the fourth its translation into C [1]. (The README has the misprint "Decrases".)
CommandWhat it doesThe README saysIn C
+Adds one to the current cellIncreases element under pointerarray[p]++;
-Takes one off the current cellDecrases element under pointerarray[p]--;
>Moves the pointer one cell to the rightIncreases pointerp++;
<Moves the pointer one cell to the leftDecreases pointerp--;
[If the current cell is 0, jumps forward to just after the matching ]. Otherwise goes onStarts loop, counter under pointerwhile(array[p]) {
]If the current cell is not 0, jumps back to just after the matching [. Otherwise goes onIndicates end of loop}
.Prints the current cell as one characterOutputs ASCII code under pointerputchar(array[p]);
,Reads one character and puts its code in the current cellReads char and stores ASCII under ptrarray[p]=getchar();

The commands come in four pairs. The two in each pair undo or complete each other: the first two pairs change the machine, the third makes a loop, the last speaks to the outside world.

Four commands change the machine: two move the pointer, two change a number. Two speak to the outside world. Two make a loop. There are no names, no numbers written out, no "if", no functions. Whatever a program needs, it builds from these.

The C column is the most exact part of the definition. It shows that a loop is a plain "while": test the cell, run the body, test again.

A loop repeats. What exactly decides when it stops?

Loops

The program below puts a number in cell 0, then runs a loop that takes 1 off cell 0 and adds 2 to cell 1, until cell 0 is empty. Press Play, or drag Step, and change the two sliders:

With the sliders as they were, cell 0 counted down from 3 to 0, and every round added 2 to cell 1. When cell 0 reached 0 the loop ended. Three times two is six: this loop multiplies. The part between [ and ] is the body of the loop. Slide the left cell to 0 and play again: the whole body is skipped.

Exactly:

"The current cell" is wherever the pointer is at that moment. The body may move the pointer, so the test at ] can look at a different cell than the test at [. The tape below starts with some cells that hold 1, followed by a 0, and the program is only [>]. Slide the number of 1s and press Play:

The pointer walked right, one cell for every round, and stopped on the first cell that held 0. Whatever the number of 1s, the program is the same. That is what [>] is for: it finds the next empty cell.

Brackets pair up like brackets in arithmetic, and loops can sit inside loops. In the program below the outer loop counts down cell 0. Each round it puts the number of the lower slider in cell 1, and the inner loop moves that number to cell 2. Choose both numbers:

Cell 2 ends at the product of the two numbers. Each ] belongs to the nearest [ before it that has no partner yet, so the inner loop ran to its end once for every round of the outer one. Cells 0 and 1 are empty afterwards: a loop reads a cell by counting it down.

Some implementations make ] jump back to the [ without looking, and let the [ do the test. The result is always the same. Only the number of steps differs.

A loop is also the only way to decide something. "If the cell is not 0, do this once" is a loop whose body ends by making the cell 0. The pattern If non-zero shows this, and the patterns section has many more.

So far the cells only held numbers. How does a number become a letter on the screen?

Output and input

The program below makes 64 with a loop (eight times eight), adds the number of plus signs you choose, and prints cell 1. Press Play and watch the line "Printed". Then slide the last number until it prints B:

With one plus sign the cell held 65, and 65 is the code of the letter A; with two it held 66, and B came out. The machine knows no letters, only numbers. The command . sends the number in the current cell to the output, and the screen shows the character with that code. The codes are those of the ASCII table: 65 is A, 97 is a, 48 is the digit 0, 32 is a space and 10 is a new line.

Now the other way. The program is ,+.: read a character, add one, print it. Type a letter in the box and press Play:

The command , took the next character of the input and stored its code, so the cell held the code of your letter before the +. Each , takes one character; a second , takes the next one. A digit you type arrives as its code too: the key 7 gives 55, not 7. A program that wants to calculate with it takes 48 off first.

Input and output are single streams of characters. A brainfuck program cannot open a file, draw on the screen or ask the time. It reads characters and prints characters. What happens when the input has run out is not defined by the original and differs between implementations: see the end of the input.

What a program is

A program is any text. The machine looks only at the eight command characters. The README: "All other characters are ignored." [1] So letters, spaces and line breaks can be used freely to lay a program out and to explain it.

++++++++        eight in cell 0
[ > ++++++++ < - ]   times eight into cell 1
> + .           one more makes 65 and prints A

This is the program of the printing figure with comments. Two things go wrong often:

A common trick uses the first rule of Loops: a loop can run zero times. The first cell is 0 when a program starts, so a loop at the very beginning never runs. Text inside it is safe, punctuation and all, as long as its own brackets match:

[ This program prints A. Nothing in here runs, not even this: +++ . ]
++++++++[>++++++++<-]>+.

Programs are usually kept in files that end in .b (as in the original distribution [1]) or .bf.

What the original defines

The whole definition in the 1993 distribution is the table of commands (the table above gives its wording) and these three sentences [1]:

"All other characters are ignored. The 30000 array elements and p are being initialized to zero at the beginning. Now while this seems to be a pretty useless language, it can be proven that it can compute every solvable mathematical problem (if we ignore the array size limit and the executable size limit)."

Urban Müller, README of brainfuck-2.lha, June 1993 [1].

So the original fixes these things:

Elsewhere the README adds that the compiler of this version "operates on a byte array": a cell is one byte [1]. It says nothing about what happens when a cell goes past its largest value, when the pointer leaves the tape, or when the input ends. Those gaps are the reason two correct implementations can disagree. The next page of this reference, Where implementations differ, takes them one by one.

There is no later official definition. The author has said so himself: the language has no formal standard, and people disagree about the size of a cell and about the end of the input [2]. What exists are careful descriptions by others [3] [4] [5].

Limits

Read next

Notes and sources

Where a source is a community wiki or the author's own account, the entry or the text says so.

  1. Urban Müller, brainfuck-2.lha, Aminet, dev/lang, dated 9 June 1993: the package page on Aminet. We read the files in the archive: README, bfc.asm (the compiler), bfi.c (the interpreter) and the six example programs. Sizes and dates are those of the archive listing. Opened 11 October 2026.
  2. Urban Müller, talk at Tamedia TX, 2017, read as the community transcript on the Esolang wiki: Tamedia TX 2017 transcript. The transcript says its last page is missing. Wikipedia gives the title as "Brainfuck, or how I learned to change the problem" and the date as 13 June 2017; we did not watch the recording. Opened 11 October 2026.
  3. Daniel B Cristofani, "Yet another brainfuck reference": the reference on brainfuck.org. Opened 11 October 2026.
  4. Brian Raiter, "Portable Brainfuck": the portability page on muppetlabs.com. Opened 11 October 2026.
  5. Esolang wiki, "Brainfuck": the wiki article on brainfuck. A community wiki; we use it for conventions and for its list of results, and name it where it is our only source. Opened 11 October 2026.