← All writing

Reversing three cards illustrates how recursive programs work

A recursive program solves a problem by applying the same operation to a smaller instance of it. In a programming languages course, the aim is to understand why those repeated steps produce the intended answer. Reversing a short list gives us a manageable example: start with 1, 2, 3 and finish with 3, 2, 1.

I am a teaching assistant for Programming Languages at UCSB this winter, after serving as a TA for the same course in winter 2024 and 2025. List reversal offers a chance to slow down and ask what each recursive call preserves. A correct line of code leaves several decisions hidden inside it.

Imagine three numbered cards in a row: 1, 2, 3. Take the leftmost card and place it in a new row. Now put each next card at the front of that new row. It grows from 1, to 2, 1, to 3, 2, 1. When the original row is empty, you are done.

Cards leftNew row
1, 2, 3empty
2, 31
32, 1
empty3, 2, 1
Move the next card to the front of the new row. Each step reverses a little more of the original order.

The new row is what programmers call an accumulator. Here, it holds the cards already moved, in reverse order. Giving it that meaning answers several questions at once. It starts empty because we have moved nothing. Each new card goes at the front because it came after the cards we already moved. We return the new row when there are no cards left in the old one.

That description is an invariant: a claim that remains true as the state changes. Hoare (1969) gives a foundational account of reasoning about programs through assertions about their states. The card example introduces the same habit in a small setting: state what is true before a step, then explain why the step preserves it.

That is the explanation I want alongside the code. Someone who understands it can also tell what happens if the next card goes at the back: the order stays 1, 2, 3. They can follow the change without memorizing another solution.

There is room to keep going, into recursion and proofs and the cost of moving things around. But first, try the exercise with four cards. Pause halfway through and describe what each row contains. The same explanation should still work with two cards waiting to move.

References

  1. C. A. R. Hoare (1969). An Axiomatic Basis for Computer Programming. Communications of the ACM 12(10), pp. 576–580, 583.
Further links