Definition
A type-theoretic feature and family of systems in which types may depend on values (terms), enabling types to express precise specifications, relate data and proofs, and internalize propositions as types.

Principle

Principle
Types-as-predicates: a type can be parameterized by a value (e.g., Vector n A) so that typing enforces value-level invariants; the correspondence between propositions and types (Curry–Howard) is realized at greater expressiveness.

Demonstration

Demonstration
Defining a type of lists with length n as List A n and writing a function append : ∀n m. List A n → List A m → List A (n + m); the type ensures at compile time that the result's length equals the sum of input lengths.

Misapplication

Misapplication
Encoding undecidable or heavyweight properties directly in types (e.g., using arbitrary search in typechecking) without care, which can make type checking nonterminating or programs impractical to write and maintain.

Consequence

Consequence
Allows embedding rich specifications in types so that many correctness properties are checked by the type checker, enabling program extraction from constructive proofs and high-assurance software when well-engineered.

Reversal

Reversal
Simple type systems where types are independent of runtime values (e.g., simply typed systems), which forgo expressive specifications in favor of decidable and efficient type checking.

Boundary

Boundary
Applies where the type-checking discipline supports value-level computation and termination checks; dependent types do not magically decide arbitrary semantic properties and often require totality/termination constraints and proof obligations.

Semantic Tension

Semantic Tension
Tension between expressive dependent types that can state strong invariants and the desire for decidable, efficient type checking and automation; also between using dependent types for proofs versus pragmatic programming ergonomics.

Synthesis

Synthesis
Dependent types extend the type system so that types can talk about values, turning types into precise specifications and enabling proofs about program behavior to live alongside code; they trade added expressiveness and verification power against increased complexity in type checking and development.