To Be a Better Programmer, Write Little Proofs in Your Head
A practical technique: mentally sketch simple proofs as you code to reason more clearly, reduce errors, and design code with intrinsic verifiability.
- Think like a proof-writer: As you implement tricky logic, mentally walk through a simple proof that your code will do what you intend. This "online" reasoning, once habitual, often leads to code working correctly on the first try.
- Monotonicity and Immutability: Identify parts of your code that only move in one direction—like checkpointing—or values that don’t change. These properties help eliminate many possible failure modes by reasoning they can’t regress.
- Pre- and Post-Conditions: Articulate what must be true before a function runs, and what must hold afterward. Using these as mental contracts helps clarify correctness—and they double as useful test or assertion candidates.
- Invariants: Determine conditions that should always hold true—before, during, and after execution. Break your logic into small atomic steps, each preserving the invariant, to prove overall consistency. Think of double-entry bookkeeping as a classic example: if debits equal credits before, they remain balanced after each transaction.
- Isolation (Blast Radius): Consider how changes propagate. Ideally, only related code changes—unaffected paths remain stable. This mental separation aids in ensuring you don’t inadvertently break unrelated behavior.
- Inductive Reasoning for Recursion: For recursive logic, prove correctness by assuming it works for subparts (the inductive hypothesis)—then show it holds when building toward the whole, starting from a base case. A concrete example sketches simplification of an AST by contracting nodes recursively.
- Proof-Affinity as Design Lens: You can also design your code to invite proofs: favor immutable structures, clear pre/post conditions, well-defined invariants, strong isolation boundaries, and simple recursion. Code that’s easy to "prove in your head" is likely to be well-structured.
- Practice Makes Proofing Second-Nature: Sharpening this mental skill takes repetition. Writing actual mathematical proofs—or doing algorithmic challenges with proof-focused reasoning—builds fluency. Educational resources like Stanford’s algorithms MOOC or even non-timed Leetcode problems (focused on correctness) can help.
The full post is available here.