NexusCS

Brainfuck

Esoteric Languages
Brainfuck is a minimalist esoteric programming language created by Urban Müller in 1993. With only 8 commands, it's Turing-complete yet intentionally difficult to use—perfect for understanding computational fundamentals.
brainfuck
esoteric
programming
minimalism

Getting started

Introduction

Brainfuck operates on a tape of 30,000 cells (each 8-bit) with a movable pointer. Only 8 commands exist, making it one of the most minimal programming languages.

Created in 1993 by Urban Müller to challenge the notion of what makes a programming language.

The 8 Commands

Command Description
> Move pointer right
< Move pointer left
+ Increment cell
- Decrement cell
. Output cell as ASCII
, Input ASCII to cell
[ Jump past ] if cell is 0
] Jump back to [ if cell is non-zero

All other characters are comments.

Hello World

++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>
---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.

This outputs: Hello World!

Memory Model

The Tape

Cell:    [0] [0] [0] [0] [0] ...
Index:    0   1   2   3   4
          ^
        pointer
  • 30,000 cells (minimum, implementation-dependent)
  • 8-bit values (0-255)
  • Wrapping: 255 + 1 = 0, 0 - 1 = 255
  • Pointer starts at cell 0

Moving the Pointer

>>>     # Move right 3 cells
<<      # Move left 2 cells

Going beyond tape bounds is undefined behavior (often wraps or crashes).

Modifying Cells

+++     # Cell value: 0  3
--      # Cell value: 3  1

Values wrap:

  • 255 + 1 = 0
  • 0 - 1 = 255

Loop Mechanics

Basic Loop Structure

[commands]
  • [ checks if current cell is 0
    • If 0: jump past matching ]
    • If non-zero: enter loop
  • ] jumps back to matching [

Loops continue while cell is non-zero.

Loop Example

+++[>+<-]
  1. Set cell 0 to 3
  2. Loop while cell 0 ≠ 0:
    • Move right, increment
    • Move left, decrement

Result: Moves value 3 from cell 0 to cell 1

Nested Loops

++[>+++[>+<-]<-]
  • Outer loop runs 2 times
  • Inner loop runs 3 times per outer iteration
  • Result: Cell 2 = 2 × 3 = 6

Common Patterns

Clear Cell

[-]     # Set current cell to 0

Loop decrements until zero. Works regardless of initial value.

Set Value

[-]+++++     # Set cell to 5

Clear first, then increment desired times.

Move Value

[>+<-]

Moves value from current cell to next cell (source becomes 0).

Copy Value

[>+>+<<-]>>     # Copy to two cells
[<<+>>-]        # Move one copy back

Pattern: Copy cell 0 → cells 1 & 2, then restore cell 0

Add Two Cells

[>+<-]     # Add cell 0 to cell 1

Cell 0 becomes 0, cell 1 = original cell 0 + cell 1

Multiply by Constant

[>+++<-]   # Multiply by 3

For each decrement of cell 0, increment cell 1 three times.

Input/Output

Output (.)

+++++++++.     # Output ASCII 9 (tab)
  • Outputs current cell as ASCII character
  • Cell value unchanged after output

ASCII Values

++++++++++[>+++++++>++++++++++>+++<<<-]>++.>+.+++++++..
+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.

Common ASCII:

  • 65-90: A-Z
  • 97-122: a-z
  • 48-57: 0-9
  • 32: space
  • 10: newline

Input (,)

,>,>,<     # Read 3 characters
  • Reads one ASCII character
  • Stores in current cell
  • EOF behavior varies by implementation

EOF Handling

Implementation EOF behavior
0 Set cell to 0
-1 Set cell to 255 (wrapping)
Unchanged Leave cell as-is

Most common: set to 0

Example Programs

Cat Program

,[.,]
  1. Read character
  2. Loop while input exists:
    • Output character
    • Read next character

Copies input to output until EOF.

Truth Machine

,----------[+++++++++++++++++++++++++++++++++++++++++++.[-]]+++++++++++++++++++++++++++++++++++++++++++++++.
  • Input 0: prints 0 once and exits
  • Input 1: prints 1 forever

ROT13 Cipher

-,+[                         Read first character and start outer character reading loop
    -[                       Skip forward if character is 0
        >>++++[>++++++++<-]  Set up divisor (32) for division loop
           <+<-[             Set up dividend (x minus 1) and enter division loop
            >+>+>-[>>>]      Increase copy and remainder / reduce divisor / Normal case: skip forward
            <[[>+<-]>>+>]    Special case: move remainder back to divisor and increase copy
            <<<<<-           Decrement dividend
        ]                    End division loop
    ]>>>[-]+                 End skip loop; zero former divisor and reuse space for a flag
    >--[-[<->+++[-]]]<[         Zero that flag unless quotient was 2 or 3; zero quotient; check flag
        ++++++++++++<[       If flag then set up divisor (13) for second division loop
            >-[>+>>]         Reduce divisor; Normal case: increase remainder
            >[+[<+>-]>+>>]   Special case: increase remainder / move it back to divisor / increase quotient
            <<<<<-           Decrease dividend
        ]                    End division loop
        >>[<+>-]             Add remainder back to divisor to get a useful 13
        >[                   Skip forward if quotient was 0
            -[               Decrement quotient and skip forward if quotient was 1
                -<<[-]>>     Zero quotient and divisor if quotient was 2
            ]<<[<<->>-]>>    Zero divisor and subtract 13 from copy if quotient was 1
        ]<<[<<+>>-]          Zero divisor and add 13 to copy if quotient was 0
    ]                        End outer skip loop (jump to here if ((character minus 1)/32) was not 2 or 3)
    <[-]                     Clear remainder from first division if second division was skipped
    <.[-]                    Output ROT13ed character from copy and clear it
    <-,+                     Read next character
]                            End character reading loop

Implements ROT13 cipher (rotates A-Z and a-z by 13 positions).

Fibonacci Sequence

+++++++++++>+>>>>++++++++++++++++++++++++++++++++++++++++++++
>++++++++++++++++++++++++++++++++<<<<<<[>[>>>>>>+>+<<<<<<<-]>>
>>>>>[<<<<<<<+>>>>>>>-]<[>++++++++++[-<-[>>+>+<<<-]>>>[<<<+>>>
-]+<[>[-]<[-]]>[<<[>>>+<<<-]>>[-]]<<]>>>[>>+>+<<<-]>>>[<<<+>>>
-]+<[>[-]<[-]]>[<<+>>[-]]<<<<<<<]>>>>>[++++++++++++++++++++++
++++++++++++++++++++++++++++.[-]]++++++++++<[->-<]>++++++++++++
+++++++++++++++++++++++++++++++++++++++++++.[-]<<<<<<<<<<<<[>>>
>+<<<<-]>>>>.

Prints first 10 Fibonacci numbers as ASCII characters.

Advanced Patterns

If-Then-Else

# If cell 0 is non-zero
[
  [-]        # Clear cell 0 (consume flag)
  >++++++    # Then: cell 1 = 6
<]

# If cell 0 is zero
>[-]<       # Ensure cell 0 is 0
[code]      # (skipped)
>[-]        # Clear work cell

# Else
<[->code<]  # Only runs if cell 0 was 0

Conditional execution based on cell value.

Comparison

# Is cell 0 == cell 1?
>[-]>[-]<<     # Clear work cells
[->+>+<<]      # Copy cell 0 to cells 1 and 2
>>[<<+>>-]<<   # Move cell 2 back to cell 0
>[<->-]<       # Subtract cell 1 from cell 0

Result: cell 0 = 0 if equal, non-zero if different

Division

# Divide cell 0 by cell 1, result in cell 2
>>[-]<<           # Clear quotient
[->-[>+>>]        # Subtract divisor
  >[+[-<+>]>+>>]  # Shift remainder
  <<<<<-]         # Decrement dividend
>>>[-]            # Clear remainder

Complex but demonstrates computational power.

Debugging Strategies

Memory Dumping

# Output first 10 cells as numbers
++++++++++[>++++++++++<-]>  # Cell 1 = 100 (visual separator)
<<<<<[>.>.>.>.>.>.>.>.>.>.>>>>>>-]

Print cell values to visualize memory state.

Step-by-Step Tracing

  1. Run small snippets: Test patterns in isolation
  2. Use comments: Mark cell purposes
    # Cell 0: counter
    # Cell 1: accumulator
    
  3. Track pointer: Note position after each operation
  4. Print markers: Insert . to verify execution path

Online Interpreters

Use these for interactive debugging:

  • copy.sh/brainfuck - Visual cell display
  • sange.fi/esoteric/brainfuck - Step-by-step execution
  • dcode.fr/brainfuck-language - With memory viewer

Educational Value

Why Brainfuck Matters

Concept Learning Value
Turing Completeness Minimal requirements for computation
Memory Management Direct manipulation of data structures
Loops Building complex control flow from basics
Optimization Every instruction counts

Skills Developed

  • Low-level thinking: Understanding memory and pointers
  • Algorithm design: Implementing logic with constraints
  • Problem decomposition: Breaking tasks into primitives
  • Patience: Debugging intentionally obscure code 😄

Historical Context

Created as a challenge to make the smallest compiler. The original compiler was 296 bytes on Amiga OS.

Inspired by:

  • P′′ (P double-prime) - Corrado Böhm's minimal language
  • FALSE - Another minimalist language

Gotchas

Unbalanced Brackets

[>+<-    # WRONG: Missing ]

Error: Syntax error, program won't run.

Fix: Always match [ with ]

Pointer Out of Bounds

<<<<<<<<<<    # Moving left from cell 0

Issue: Undefined behavior (crash or wrap).

Fix: Track pointer position carefully.

Infinite Loops

+[>+<]    # WRONG: Cell 0 never becomes 0

Issue: Loop never exits.

Fix: Ensure loop condition changes

+[>+<-]   # CORRECT: Decrements cell 0

Off-by-One Errors

+++[>+<-]    # Expect 3 in cell 1
>>.          # But pointer at cell 2!

Issue: Wrong cell accessed.

Fix: Track pointer position after operations.

EOF Inconsistency

,            # What happens at EOF?

Issue: Behavior varies (0, -1, unchanged).

Fix: Test on target interpreter or assume 0 (most common).

Integer Overflow

++++[>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<-]

Issue: 4 × 64 = 256, wraps to 0.

Fix: Account for 8-bit wrapping (use 255 max).

Implementations

Popular Interpreters

Interpreter Platform Features
bfi Linux/Unix Fast, standard-compliant
beef Cross-platform Optimizing compiler
Brainfuck Visualizer Web Step-by-step debugging
copy.sh Web Interactive, cell display

Compile to C

Many implementations transpile to C for performance:

// +++
*ptr += 3;

// [>+<-]
while (*ptr) {
    ++ptr;
    ++*ptr;
    --ptr;
    --*ptr;
}

Optimizations can make Brainfuck surprisingly fast!

Variations & Extensions

Brainfuck Derivatives

Language Changes
Boolfuck 1-bit cells instead of 8-bit
Smallfuck No I/O commands
Binaryfuck Binary encoding of commands
Ook! Syntax using "Ook.", "Ook?", "Ook!"
TrivialBrainfuckSubstitution Different symbols, same semantics

Extended Brainfuck

Some implementations add:

  • # - Debug output (print cell value as number)
  • ! - Breakpoint
  • @ - Terminate program

Optimization Techniques

Instruction Combining

Before:

+++++

After (internally):

*ptr += 5;  // Single operation

Modern interpreters combine consecutive +, -, >, <.

Clear Loop Optimization

Before:

[-]    # Loop to clear

After:

*ptr = 0;  // Direct assignment

Pattern recognized and optimized by compilers.

Copy Loop Unrolling

Before:

[>+++<-]   # Loop-based multiply

After (conceptually):

*(ptr+1) += *ptr * 3;
*ptr = 0;

Advanced compilers detect and optimize patterns.

Resources & Tools

Online Interpreters

Code Generators

Learning Resources

Also see