A language you can run backward

Stepwise is a tiny programming language with one trick: after your program runs, you can step backward through it. This page is the long answer to “why would anyone want that?” If you would rather just try it, the app is one tab over.

Use the app →

What it is

A small language for people learning to code. It has whole numbers, true and false, variables, if, while, functions and recursion, and that is about it. That is on purpose: it is small enough to learn in an afternoon, and small enough that the debugger can show you absolutely everything your program did.

What it does

You write a program and press Run. Stepwise records every step while it runs: every line, every value a variable ever held, every call and every return. Then it hands the run back to you like a video you can scrub.

  • Step backward from a wrong answer to the line where it went wrong, one step at a time or by dragging.
  • Ask where a value came from click a variable and Stepwise jumps to the step that set it, even deep inside a recursion.
  • See every call at once the whole run as a map of calls, the call galaxy. Hover one for its values, click to go there.
  • Read it in English every step comes with a sentence saying what just happened and what changed.
  • Share it a program fits in a link, so a TA can send you the exact run they are talking about.

How it works

The short version: there is a whole compiler running in this tab.

  • A real compiler, in the tab what you type is read, type-checked and turned into a WebAssembly program by a compiler written in Rust. The compiler is itself WebAssembly, 88 KB of it, so it runs right here in the page.
  • Your program takes notes while compiling, Stepwise quietly adds a note after everything your program does: “line 5”, “total was 3, now 6”, “called factorial(4)”. Eight kinds of note in all, and they are the whole recording.
  • It runs off to the side the program runs in a background thread with a watchdog, so an infinite loop cannot freeze the page. The recording holds up to a million events.
  • Backward is just forward again undoing things one by one is fiddly and easy to get wrong, so Stepwise does not. It saves a full snapshot every 1,000 steps, and to reach any step it loads the snapshot before it and replays forward, never more than a thousand. Forward and backward are the same operation, which is why they cannot disagree. Stepping back 5,000 times takes under a second; doing it the naive way took two minutes.
  • No server nothing is sent anywhere. Your code never leaves the page.

The long, technical version

Why it exists

When you are learning to program, the hard part is not typing the code. It is seeing what the code does. A loop runs twenty times in a blink. A recursive function calls itself, hands back an answer that is just wrong, and there is no way to tell which of the forty calls broke it. Most debuggers only go forward, so if you step past the moment that mattered, you start over. So beginners sprinkle print statements and guess.

Stepwise flips the order. You run first and look around after. The mistake has already happened and it is sitting in the recording; you just go back and find it.

What it can’t do (yet)

  • Only whole numbers and true or false. Text and lists are next.
  • It records a run and then lets you explore it. You cannot change a variable halfway and carry on.
  • Numbers are 32-bit, and one too big wraps around instead of complaining.
  • It is for learning. Nobody should build real software in it, and it would be a little alarmed if you tried.

How it is checked

248 tests. The one that matters most: every step has to look exactly the same whether you reached it going forward, going backward or jumping around at random. On top of that, 23 sample programs run in two different WebAssembly engines and have to agree, and the compiler gets fed random junk and must never crash on it.