Hello World in Befunge
Your first Befunge program - the classic Hello World example with Docker setup
Writing “Hello, World!” in Befunge gives you a taste of two-dimensional programming. The code exists on a grid, and execution flows through it in multiple directions.
The Code
Create a file named hello.bf:
"!dlroW ,olleH">:#,_@
Yes, that’s it! Just 22 characters arranged in a single line.
Understanding the Code
Let’s break down how this works by tracing the execution:
String Mode and Reversal
"!dlroW ,olleH"
The " character toggles “string mode.” While in string mode, each character’s ASCII value is pushed onto the stack instead of being executed as a command.
Notice the text is reversed: !dlroW ,olleH instead of Hello, World!. This is because the stack is LIFO (Last In, First Out). When we push characters and then pop them to print, they come out in reverse order.
So after this string section, our stack (bottom to top) contains:
33 100 108 114 111 87 32 44 111 108 108 101 72
! d l r o W , o l l e H
The Print Loop
>:#,_@
This is where it gets interesting. Let’s trace each character:
| Char | Function |
|---|---|
> | Set direction to right (we’re already going right, but this is explicit) |
: | Duplicate the top of stack |
# | Bridge - skip the next instruction |
, | Print top of stack as ASCII character |
_ | Horizontal if: go right if top is 0, left if non-zero |
@ | End program |
Tracing Execution
First iteration: Stack has
H(72) on top:duplicates: stack now has72, 72, ...#skips,and goes to__pops 72, it’s non-zero, so we go left- Going left, we hit
,which prints 72 as ‘H’ - Continue left to
#, which skips:and wraps to> >sends us right again
Loop continues: Each iteration prints one character
- The
:duplicates so we can both test (at_) and print (at,) - When the stack is empty,
:duplicates 0 _sees 0 and goes right to@@ends the program
- The
Visual Trace
Here’s the execution path:
"!dlroW ,olleH">:#,_@
^ |
| v (when 0)
<------+--+
|
+-------->
The program essentially bounces back and forth through the print loop until the stack is empty.
Running with Docker
The easiest way to run Befunge without installing an interpreter locally:
| |
Expected Output
Hello, World!
Alternative Version
Here’s a more visual, multi-line version that’s easier to follow:
v
>92*"!dlroW ,olleH"v
v
@,+*52_,#!:<
This version:
vsends us down immediately>sends us right92*pushes 9*2=18 (not used here, but demonstrates math)- The string gets pushed onto the stack
vat the end sends us down- Another
vsends us down again - We enter the print loop going left
Even Simpler Version
For absolute clarity, here’s a version with explicit direction markers:
> v
v"Hello, World!"<
>:v
,|
^_@
This spreads the logic across multiple lines:
- Line 1: Go right, then down at the
v - Line 2: Go left pushing the string (note: NOT reversed because we’re going left!)
- Lines 3-5: A vertical print loop
Common Patterns
Pushing Numbers
To push a two-digit number, use multiplication:
79* Push 63 (7 * 9)
Numbers 0-9 can be pushed directly. For larger numbers, calculate them.
Output a Newline
52*, Push 10 (5*2), print as ASCII (newline)
Conditional Direction
_ Horizontal: right if 0, left if non-zero
| Vertical: down if 0, up if non-zero
Skip Next Instruction
# Bridge: always skip the next cell
Debugging Tips
- Trace on paper: Draw the grid and trace the IP’s path
- Watch the stack: Keep track of what’s on the stack at each step
- Direction matters: Know which way you’re going at all times
- String reversal: Remember that strings come out backwards unless you push them while going left
- Empty stack: Popping from an empty stack gives 0
Why This Works
Befunge’s design makes simple tasks interesting puzzles:
- Linear text in 2D space: We have to think about how to lay out our code
- Stack reversal: We push “Hello, World!” backwards, or push while going left
- Control flow: The
_instruction creates a loop by sending us different directions based on the stack
Historical Note
Chris Pressey created Befunge in 1993 specifically to be difficult to compile. The self-modifying capabilities (not used in this simple example) and two-dimensional nature make static analysis extremely challenging.
The fact that we can run this same language 30+ years later in a Docker container demonstrates that even the most unusual languages can be preserved and executed on modern systems.
Next Steps
Try these modifications:
- Change the message to print your name
- Add a newline at the end using
52*, - Create a multi-line version that’s easier to trace
- Experiment with the
pcommand to modify the program during execution