What does a type system actually guarantee? Type soundness: “well-typed programs do not go wrong” (Milner). Wright & Felleisen made proving it a recipe of two lemmas. Progress: a well-typed term is either a value or can take a step — it never gets stuck (no 1 + true with nowhere to go). Preservation (subject reduction): if a well-typed term steps, the result is well-typed at the same type. Together, by induction: a well-typed program steps and steps, always typed, never stuck — it runs to a value or forever, but never to nonsense. This is the theorem a type system exists to earn.
A well-typed arithmetic term reduced step by step. The demo shows the type is preserved at every step and the term makes progress to a value: live demo
“A type checker just catches typos.” — it earns a theorem: every program it accepts is guaranteed never to reach a meaningless state. Progress and preservation are the proof that “well-typed” means “won't go wrong,” not just “looks tidy.” cited
Progress says it can move; preservation says it stays typed while moving. Chain them by induction and “well-typed” becomes a promise about the entire run, not a single moment. Wright-Felleisen 1994
On the canonical compiler, the well-typed term (1+2)+3 reduces to 6, staying type Int at every step (preservation) and never stuck (progress):