Static vs Dynamic Typing

That static typing prevents runtime errors. A static type system proves the properties it models and says nothing about the rest: null dereferences, index-out-of-range, division by zero, protocol violations and wrong answers all survive a clean type check unless the type system was designed to model them.

Static typing

When the codebase is large or long-lived, when refactoring must be mechanical, and when the properties you care about are ones a type system can model.

Dynamic typing

When shapes are genuinely heterogeneous or not known until run time, and when the cost of describing them exceeds the cost of testing them.

AspectStatic typingDynamic typing
When the check happensBefore running, on all paths, including ones no test exercises.At the operation, on the path actually taken.
What it provesExactly the properties encoded in the types — no more.Nothing in advance; every guarantee is a test or a run-time check.
Effect on the compilerTypes drive layout, dispatch and specialization.Operations dispatch on the values, which is what costs at run time.
RefactoringThe checker enumerates the call sites you broke.You find them by running the code or by grep.
Cost of expressivenessPrograms the type system cannot express are rejected even when correct.Programs the reader cannot understand are accepted until they run.
Middle groundLocal inference reduces annotation cost without weakening the proof.Gradual typing adds annotations incrementally, with run-time checks at the boundary.