Why patterns matter here
With only eight Brainfuck commands and no named variables, almost every task is built from the same few moves. Experienced programmers think in terms of those moves rather than individual symbols, much as people who write other languages think in loops and function calls. Learning the idioms turns an unreadable wall of punctuation into something with structure.
In the examples below, cells are written as c0, c1, c2 and so on, and the pointer is assumed to start at c0. All starting values are hypothetical and chosen to make the arithmetic easy to check. Each pattern assumes cells that are not mentioned start at zero.
Clearing a cell
[-]
This loops while the current cell is nonzero and subtracts 1 each time, so it always ends with zero. It is the closest thing the language has to an assignment of zero. On a cell that wraps around, the loop is still safe because it counts down until it reaches 0. On a very large cell it can take a long time, since it runs once per unit of value.
Setting a value
To place a particular number, you can repeat plus signs, or use a small loop. To get 65 (the code for the letter A):
++++++++[>++++++++<-]>+.
The first eight plus signs set c0 to 8. The loop adds 8 to c1 eight times, giving 64, and c0 returns to 0. The final >+ moves to c1 and makes it 65, and the dot prints it. The pattern is a counter times a step, plus a remainder.
Moving a value
[->+<]
This moves the content of the current cell into the next one. Each pass takes 1 from c0 and adds 1 to c1, and the pointer finishes back on c0, which is now zero. If c1 started at 5 and c0 at 3, c1 ends at 8, so this pattern is also an addition. Move left by swapping the arrows: [-<+>].
Copying a value
A destructive move cannot copy, since the original is consumed. Copying needs a scratch cell:
[->+>+<<]>>[-<<+>>]
Starting with c0 holding a value and c1 and c2 at zero, the first loop empties c0 into both c1 and c2. Then the pointer moves to c2 and the second loop pours c2 back into c0. The result is that c0 and c1 both hold the original value, c2 is zero, and the pointer rests on c2. The second half is just the move pattern again, aimed in the opposite direction.
Looping over a counter
A loop that runs a fixed number of times keeps the count in one cell and the work in others. For example, to print the letter A five times:
+++++>++++++++[>++++++++<-]>+<<[>>.<<-]
The first five plus signs put 5 in c0, the counter. The next part builds 65 in c2 using c1 as a helper, exactly as in the previous pattern. Then << returns to c0, and the final loop moves to c2, prints, moves back and subtracts 1 from the counter. It runs five times and prints AAAAA. Keeping the counter and the data in separate cells, and making each loop body end on the cell where it began, is the most important habit in the language. Otherwise the closing bracket tests the wrong cell.
Multiplication
[->[->+>+<<]>>[-<<+>>]<<<]
With c0 as a, c1 as b, and c2 and c3 empty, this leaves a times b in c2. The outer loop runs a times; each time, the inner part adds b into c2 while also copying it into c3, and then c3 is poured back into c1 so b is restored. If a is 3 and b is 4, c2 ends at 12 and c0 is 0. It is the copy pattern nested inside a counting loop.
Conditionals
There is no if statement, but a loop that runs at most once behaves like one. Set a flag cell, run [ body [-]], and the body executes only if the flag is nonzero. The trick is to clear the flag at the end, so the loop does not repeat. If-else needs a second flag that holds the opposite value.
Habits that keep programs readable
- Keep a note of which cell is which; many programmers write a comment-style line using characters that are not commands.
- Reserve a block of scratch cells and leave them at zero afterward.
- Let every loop body end on the cell where it began.
- Test a pattern in isolation before combining it.
Because the language ignores any character that is not a command, comments are easy, but be careful: punctuation such as a period or a comma in a note is read as an instruction. These habits address the code readability problem that is built into the language. Small patterns are also exactly what you need when working under size limits or competing in code golf, where every symbol counts, and they are easy to verify by tracing by hand with a short table of cell values.