Advanced

Hello World in Whitespace

Your first Whitespace program - the classic Hello World example with Docker setup

Writing “Hello, World!” in Whitespace gives you a taste of programming with invisible characters. The code you’ll write consists entirely of spaces, tabs, and linefeeds—nothing else matters.

The Code

Create a file named hello.ws:

   	  	   
	
     		  	 	
	
     		 		  
	
     		 		  
	
     		 				
	
     	 		  
	
     	     
	
     	 	 			
	
     		 				
	
     			  	 
	
     		 		  
	
     		  	  
	
     	    	
	
  

Yes, that’s the actual program! It looks blank (or nearly blank) because it consists only of whitespace characters. The file is 195 bytes of spaces, tabs, and linefeeds.

Understanding the Code

Since whitespace is invisible, we need an annotated version to understand what’s happening. Here’s the same program with S (Space), T (Tab), and L (Linefeed) notation:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
S S S S T S S T S S S L   ; Push 72 ('H')
T L S S                   ; Output character
S S S S T T S S T S T L   ; Push 101 ('e')
T L S S                   ; Output character
S S S S T T S T T S S L   ; Push 108 ('l')
T L S S                   ; Output character
S S S S T T S T T S S L   ; Push 108 ('l')
T L S S                   ; Output character
S S S S T T S T T T T L   ; Push 111 ('o')
T L S S                   ; Output character
S S S S T S T T S S L     ; Push 44 (',')
T L S S                   ; Output character
S S S S T S S S S S L     ; Push 32 (' ')
T L S S                   ; Output character
S S S S T S T S T T T L   ; Push 87 ('W')
T L S S                   ; Output character
S S S S T T S T T T T L   ; Push 111 ('o')
T L S S                   ; Output character
S S S S T T T S S T S L   ; Push 114 ('r')
T L S S                   ; Output character
S S S S T T S T T S S L   ; Push 108 ('l')
T L S S                   ; Output character
S S S S T T S S T S S L   ; Push 100 ('d')
T L S S                   ; Output character
S S S S T S S S S T L     ; Push 33 ('!')
T L S S                   ; Output character
L L L                     ; End program

Breaking It Down

Each character in “Hello, World!” requires two operations:

  1. Push the ASCII value onto the stack
  2. Output it as a character

The Push Instruction

1
2
3
4
S S S S T S S T S S S L
│ │ │ │ └─────────────┴─ Number: sign + binary + terminator
│ │ └─┴─ Command: Space = Push
└─┴─ IMP: Space = Stack Manipulation

The number encoding:

  • First character is the sign: Space = positive, Tab = negative
  • Following characters are binary digits: Space = 0, Tab = 1
  • Linefeed terminates the number

For ‘H’ (ASCII 72 = binary 1001000):

  • Sign: S (positive)
  • Binary: T S S T S S S (1001000)
  • Terminator: L

The Output Instruction

1
2
3
T L S S
│ │ └─┴─ Command: Space Space = Output Character
└─┴─ IMP: Tab Linefeed = I/O

This pops the top of the stack and outputs it as an ASCII character.

The End Instruction

1
2
3
L L L
│ └─┴─ Command: Linefeed Linefeed = End Program
└─ IMP: Linefeed = Flow Control

ASCII Values Reference

CharacterDecimalBinaryWhitespace (S=0, T=1)
H721001000TSSTSSS
e1011100101TTSSTS T
l1081101100TTSTTSS
o1111101111TTSTTTT
,44101100TSTTSS
(space)32100000TSSSSS
W871010111TSTSTTT
r1141110010TTTSSTS
d1001100100TTSSTS S
!33100001TSSSST

Creating the File

The tricky part is creating a file with exact whitespace characters. Here are several methods:

Method 1: Download from Repository

The easiest approach is to copy an existing hello.ws file from a Whitespace examples repository.

Method 2: Use a Script

Create the file programmatically with Python:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
def number_to_ws(n):
    sign = ' ' if n >= 0 else '\t'
    binary = ''
    while n > 0:
        binary = (' ' if n % 2 == 0 else '\t') + binary
        n //= 2
    return sign + (binary or ' ') + '\n'

def push(n): return '  ' + number_to_ws(n)
def output_char(): return '\t\n  '
def end(): return '\n\n\n'

message = "Hello, World!"
program = ''.join(push(ord(c)) + output_char() for c in message) + end()

with open('hello.ws', 'w') as f:
    f.write(program)

Method 3: Hex Editor

Create a file with these exact bytes:

  • 20 = Space
  • 09 = Tab
  • 0A = Linefeed

Running with Docker

The easiest way to run Whitespace without installing an interpreter locally:

1
2
3
4
5
# Pull the Whitespace interpreter image
docker pull esolang/whitespace

# Run the program
docker run --rm -v $(pwd):/code:ro esolang/whitespace whitespace /code/hello.ws

Expected Output

Hello, World!

Viewing the Actual Code

Since the code is invisible, you can verify it with various tools:

Show whitespace characters (Unix/macOS)

1
2
3
4
5
6
7
8
# Show tabs as ^I, mark line endings with $
cat -A hello.ws

# Show as hex dump
xxd hello.ws | head -20

# Count characters
wc -c hello.ws  # Should show 195 bytes

Validate the structure

Each character in the output requires approximately 15 bytes of whitespace:

  • 2 bytes for push IMP + command
  • ~8-9 bytes for the number encoding
  • 4 bytes for output command

Plus 3 bytes for the end instruction.

Why Whitespace Is Interesting

Steganography

Because non-whitespace characters are ignored, you can hide a Whitespace program inside any text file. For example, you could write a Python program with carefully placed spaces and tabs that also runs as a Whitespace program!

Polyglot Programs

A file can be valid in multiple languages:

  • The visible characters could be valid Python
  • The invisible whitespace could be valid Whitespace
  • Both programs would run correctly in their respective interpreters

Editor Challenges

Most text editors:

  • Trim trailing whitespace automatically
  • Convert tabs to spaces (or vice versa)
  • Normalize line endings

All of these will break a Whitespace program. You need an editor configured to preserve exact whitespace.

Common Pitfalls

  1. Editor “helpful” features: Disable auto-formatting, trailing whitespace removal, and tab-to-space conversion

  2. Line ending normalization: Different systems use different line endings (LF vs CRLF). Whitespace specifically uses LF (ASCII 10).

  3. Copy/paste corruption: Copying from web pages often mangles whitespace characters

  4. File encoding: Ensure UTF-8 or ASCII encoding without BOM

Historical Note

Edwin Brady and Chris Morris created Whitespace in 2003 at the University of Durham. They released it on April 1st, leading most people to assume it was an April Fool’s joke. It wasn’t—it’s a fully functional, Turing-complete programming language that continues to be implemented and used for programming challenges and steganography experiments.

Brady later went on to create Idris, a sophisticated dependently-typed programming language—quite a contrast from Whitespace’s invisible simplicity.

Next Steps

Try these modifications:

  • Change the message to print your name
  • Add a newline at the end (push 10, output character)
  • Create a program that takes input and echoes it back
  • Try embedding a Whitespace program inside another language’s source code

Running Today

All examples can be run using Docker:

docker pull esolang/whitespace
Last updated: