What Conway's Game of Life Teaches About Pure Functions
Conway's Game of Life is barely a game in the usual sense. You set up a grid of living and dead cells, press start, and watch it evolve under four tiny rules with no further input from you.

Conway's Game of Life is barely a game in the usual sense. You set up a grid of living and dead cells, press start, and watch it evolve under four tiny rules with no further input from you. Online versions run it in a browser tab with a single click. I keep coming back to it when teaching functional programming, because beneath the hypnotic patterns sits one of the cleanest demonstrations of a pure function and immutable state that I have ever found. The whole universe of Life is a single function applied over and over, and seeing that makes an abstract idea click.
One function, applied forever
Every generation in Life is produced by applying the same rule to the current grid to get the next grid. There is no hidden memory, no accumulated side effect, no state squirreled away between steps. Give the function a grid and it returns a new grid, and the same grid in always yields the same grid out. That is the textbook definition of a pure function, running in front of you at thirty frames a second. The entire evolving spectacle is nothing more than one honest transformation, repeated, and naming that out loud turns a screensaver into a lesson.
The next grid is new, not edited
A beginner reaching for Life usually mutates the grid in place, flipping cells as they go, and promptly gets wrong answers. The reason is that each cell's fate depends on its neighbours in the current generation, so changing a cell before you have read all of its neighbours corrupts the calculation. The correct approach builds a brand new grid from the old one and never touches the original mid-pass. That is immutability enforced by the problem itself. Life refuses to work unless you treat the current state as read-only, which is the exact discipline functional code asks of you everywhere.
Four rules with no exceptions
The transition rules are total: every cell, in every situation, has a defined outcome based solely on its live neighbour count. There is no undefined case, no special exception, no cell that behaves differently because of history. A pure function aspires to the same completeness, handling every input without reaching outside itself for an answer. Life models that cleanly because the rules cover the whole space of possibilities with four short clauses. Writing the transition as a single expression over neighbour count, rather than a tangle of special cases, is where the functional style and the game meet most obviously.
Referential transparency you can watch
Because the step function is pure, you can replace any generation with a cached copy and the future unfolds identically. Run the same starting pattern twice and you get the same sequence every time, down to the last cell. That property, that an expression can be swapped for its value with no change in behaviour, is referential transparency, and Life lets you see it rather than merely trust it. The determinism is not a coincidence of the game, it is a direct consequence of the step being a pure function, and the two ideas illuminate each other beautifully.
Separating the rule from the clock
A clean Life implementation splits the pure transition from the impure business of looping, drawing, and reading the clock. The function that computes the next grid knows nothing about time or the screen. Something outside it handles the ticking and the rendering. That separation, a pure core wrapped in a thin shell of effects, is the shape of almost every well-structured functional program. Life makes the division concrete: the rule is pure and testable, the animation loop is where the messy outside world lives, and keeping them apart is what keeps the core honest.
Testing a world without running it
Because the step is a pure function, you can test it exhaustively without ever animating anything. Feed it a known pattern, assert the exact next grid, and you have verified the whole engine. A glider should move one step diagonally after four generations, and a pure function lets you check that as a plain equality, no screen required. This is the payoff of purity that beginners underestimate. The hardest-looking part of the program, the evolving universe, becomes the easiest to test, precisely because it is a function from grid to grid and nothing more.
Why I keep teaching with it
Conway's Game of Life earns its place in a functional programming lesson because it makes the central ideas visible. A pure step, immutable generations, total rules, determinism you can watch, a pure core split from an effectful shell, and exhaustive tests that need no animation. Students who struggle with these ideas in the abstract grasp them in an afternoon of watching gliders. The game is old, tiny, and endlessly instructive, and an online version is one click away, which makes it the most convenient teacher of pure functions I know.
Frequently asked questions
Is Conway's Game of Life actually a game? Not in the interactive sense, since you only set the initial cells and then watch. It is a cellular automaton, a system that evolves on its own under fixed rules. The name stuck because of the lifelike patterns that emerge, and online versions let you place cells and run it, which is close enough to play for the comparison to hold.
Why must I build a new grid instead of editing the old one? Because each cell's next state depends on its neighbours in the current generation. If you flip a cell in place, the neighbouring cells you read afterward see the changed value and compute the wrong result. Building a fresh grid from the untouched original preserves correctness, which is immutability enforced by the problem rather than by a language rule.
How does purity make the engine easier to test? A pure step function depends only on its input grid, so you can feed it a known pattern and assert the exact output without animating or involving the screen. Determinism guarantees the same result every time, which means a single equality check verifies the whole transition. The part that looks hardest to test becomes the easiest, precisely because it has no hidden state.
A universe in one function
Conway's Game of Life is a living lesson in pure functions and immutable state. Each generation is one honest transformation of a read-only grid, the rules are total, the outcome is deterministic, and the pure core sits cleanly apart from the drawing loop. Run it online, watch a glider, and the ideas that resist explanation in prose simply become obvious on screen.
More in Games
Games
How Online Game Platforms Reveal Their Inner Systems to Developers
To most players an online game platform is a black box, but to a developer it is a system that leaves evidence everywhere, in...
Games
How an Online Chess Engine Uses Immutable Game State
Watch an online chess engine think and it looks like magic: in a second it considers millions of positions, picks a move, and...
Games
Roguelike Field of View With Shadowcasting in Haskell
Most hobby roguelikes I review on weekends have the same visible flaw within the first room.