Fact-checked by Grok 2 weeks ago

Bottom type

In , the bottom type—also known as the empty type or zero type—is the type that contains no values and serves as a subtype of every other type in a given , representing the least element in the subtype relation. This property ensures that values of the bottom type can be safely used wherever any other type is expected, though no such values exist, making it uninhabited and useful for modeling impossibility or contradictions. The corresponds to the object in the of types under , analogous to the in or the falsity constant in , where it inhabits no terms but allows type systems to remain closed under operations like intersections or products. In formal semantics, it often denotes divergent computations or non-terminating programs, distinguishing it from type (which has exactly one value) by its complete lack of inhabitants. In programming languages with advanced type systems, the bottom type facilitates features like exhaustive , , and modeling functions that never return, such as error handlers or infinite loops. For instance, TypeScript's never type represents values that never occur, acting as a subtype of all types to refine analysis and prevent . Similarly, Rust's ! (never) type denotes computations that do not produce a value, coercible to any type for use in error propagation or panics. These implementations highlight the bottom type's role in enhancing and expressiveness without introducing runtime overhead.

Definition and Properties

Formal Definition

In , the bottom type, often denoted as \bot, is defined as the least element in the of types under the relation, making it a subtype of every other type in the system. It is represented as an uninhabited type, meaning it contains no values or terms, in contrast to inhabited types that admit at least one . Logically, under the Curry-Howard correspondence, the bottom type aligns with falsehood, such that the implication \bot \to A holds for any type A, as there are no terms of type \bot to falsify the implication (ex falso quodlibet). This notion traces its origins to in , developed by in the 1970s to model and fixed points, where the bottom element denotes undefined or non-terminating behavior.

Key Properties

The bottom type, often denoted ⊥, embodies the absurdity principle in : assuming the existence of a term inhabiting ⊥ leads to a logical , enabling the derivation of any proposition or type through the ex falso quodlibet rule, which is foundational for in constructive settings. This property arises because ⊥ has no introduction rules or constructors, making any purported inhabitant impossible to construct without violating the type system's consistency. A key structural property of the bottom type is its universality in relations: as the least element in the , ⊥ is a subtype of every other type in the system, allowing values (or rather, the absence thereof) of bottom to be safely coerced to any expected type without errors. This universality facilitates flexible type checking and , particularly in polymorphic contexts where bottom serves as a "catch-all" subtype, though its uninhabited nature ensures it never introduces actual values. The non-constructibility of the type underscores its emptiness: unlike inhabited types, ⊥ admits no terms, constructors, or values, rendering it computationally irrelevant and preventing any meaningful computation from proceeding on its instances. This property distinguishes from other empty-like constructs and ensures that functions expecting inputs are , as they need not handle any cases. In , which provides for typed calculi, the type corresponds to the least element ⊥ of a domain, representing undefined or partial computations and serving as the initial element in the least fixed-point construction for recursive type definitions. This role is essential for modeling recursive functions and data types, where iterations begin from and approximate towards fixed points through directed complete partial orders (dcpos).

Relations to Other Types

Empty Type

In many type systems, the bottom type coincides with the empty type, often denoted ∅ or ⊥, as both represent uninhabited types containing no values. This equivalence arises because the bottom type serves as the least element in the type lattice, mirroring the empty set's role as the initial object in categorical models of . Consequently, expressions typed as bottom or empty can be safely coerced to any other type via , as no actual values exist to violate type invariants. In more advanced systems, particularly those with non-strict evaluation semantics, distinctions emerge: the bottom type may model or non-termination (e.g., infinite loops), while the empty type strictly captures impossible or absent values. For instance, in call-by-need languages, assigning the bottom type to diverging computations prevents unsound equivalences, such as treating a pair of a diverging expression and an integer as interchangeable with a pair involving a , whereas the empty type maintains a pure interpretation as the without incorporating computational effects like non-termination. In logical contexts, such as under the Curry-Howard correspondence, the empty type embodies falsehood (⊥), where the absence of terms proves a , directly paralleling the bottom type's uninhabited nature in . A term inhabiting the empty type would derive any via ex falso quodlibet, reinforcing its foundational role in constructive proofs. This overlap supports by enabling the empty or bottom type to statically model errors or unreachable states, allowing functions that "never return" (due to impossibility or divergence) to integrate seamlessly without requiring runtime or checks. By leveraging the bottom type's universality as a subtype of all types, systems can eliminate dynamic error propagation in these cases, ensuring compile-time guarantees of correctness.

Top Type

The top type, denoted \top, serves as the universal supertype in , meaning that every type is a subtype of \top. Unlike the bottom type \bot, which is uninhabited and thus contains no values, the top type is inhabited by any possible value, allowing it to act as a catch-all or most general type in hierarchical structures. This positions \top as the greatest element in the partial order of types under . Note that the top type should not be confused with the , which is a distinct type often corresponding to the object in categorical semantics. In the context of bounded lattices formed by types ordered by , the top type exhibits a clear duality with the bottom type: while \bot functions as the infimum or least element (subtype of all types), \top acts as the supremum or greatest element (supertype of all types). This symmetry underscores their complementary roles in type hierarchies, where the is bounded above by \top and below by \bot. Such duality ensures that type systems can model complete partial orders effectively, facilitating proofs and constructions in theoretical foundations. During type unification processes, the top type often plays the role of a wildcard or universal type, representing a placeholder that can match any specific type in inference algorithms, thereby enabling flexible generalization without overconstraining solutions. This usage highlights \top's utility in deriving principal types or most general unifiers. In category theory, the bottom type aligns with the initial object, from which there is exactly one morphism to any other object. Dually, the unit type corresponds to the terminal object, an object $1 such that there is exactly one morphism from any object to $1. The top type in subtyping lattices, while the greatest element, does not directly correspond to the terminal object but complements the bottom in the subtype poset, emphasizing their symmetric extremes in categorical semantics of types.

Theoretical Applications

Subtyping and Lattices

In , the bottom type \bot functions as the minimal element in the relation, serving as a subtype of every other type in the system. This is formalized by the rule \forall A.\ \bot <: A, which guarantees that \bot can safely substitute for any type A without violating , thereby enabling covariant subtyping in constructs like function types where the argument position requires a supertype. Such positioning of \bot as the least element ensures that subtyping forms a partial order with a bottom, preventing inconsistencies in type hierarchies and supporting the propagation of type information downward in the lattice. The types in a system equipped with a bottom type form a under , where \bot represents the infimum (greatest lower bound) of the entire type set, and the top type \top serves as the supremum (least upper bound). In this structure, the meet operation \sqcap (glb) computes the greatest lower bound between two types, akin to , while the join operation \sqcup (lub) computes the least upper bound, akin to ; for instance, in algebraic systems, the meet of two function types \tau_1 \to \tau_2 and \tau'_1 \to \tau'_2 is (\tau_1 \sqcup \tau'_1) \to (\tau_2 \sqcap \tau'_2). This framework, often distributive to facilitate algorithmic decisions, allows for the existence of meets and joins for arbitrary subsets of types, ensuring totality in the sense that every pair of types has a well-defined glb and lub relative to \bot. The bottom type's role as the meet of the further solidifies the 's completeness, enabling proofs of properties like and reflexivity in derivations. In certain models of non-structural with both \bot and \top, the subtyping relation is total, as all types between \bot and \top, ensuring comparability within those lattices. This property simplifies type checking and inference by avoiding incomparable types, as demonstrated in logics where \bot encodes the empty type to resolve undecidability in structural variants. In applications to , \bot is employed as the implicit lower bound for generics and wildcards, permitting the widest possible without restricting to a specific supertype. For example, in wildcard-based systems, an unbounded wildcard like Java's ? is modeled with \bot as the lower bound, equivalent to \super \bot, which allows with any type while preserving in producer positions. This usage in lower-bounded type variables, such as \forall (\alpha \succsim \bot).\ \tau, facilitates flexible polymorphism by treating \bot as the neutral element for lower constraints, enhancing expressiveness in languages supporting impredicative .

Polymorphism and Inference

In , the bottom type enables polymorphic functions to operate uniformly across type instances, including the uninhabited bottom type, without necessitating specialized implementations. As the least element in the , the bottom type is a subtype of every other type, allowing a universally quantified like ∀α. α → α to accept a bottom value as an argument of any type α while preserving the function's parametric generality. This integration avoids representational overhead, as the can simplify quantified types involving monotonic positions of the bottom type, replacing them with equivalent forms that maintain semantic equivalence. For instance, a type such as ∀α:∀β:α → β simplifies to top → bottom under constraints, reflecting the bottom type's role in bounding polymorphic outputs to uninhabitable cases. The bottom type enhances in systems supporting polymorphism, such as the Hindley-Milner framework, by resolving ambiguities during unification. In unification algorithms, type variables facing conflicting constraints—such as needing to subtype multiple incompatible types—can be bound to the bottom type, which unifies seamlessly with any type due to its universal . This mechanism yields the most general unifier without over-specializing, facilitating efficient inference for expressions involving potential non-values. By treating the bottom type as a canonical solution for underconstrained variables, inference algorithms maintain completeness and decidability, avoiding unification failures in polymorphic contexts. The bottom type models non-terminating or divergent computations within polymorphic settings, representing the domain-theoretic least element that inhabits no values yet subtypes all types. A non-terminating function can thus be assigned the bottom type, enabling its use in polymorphic positions—such as arguments to higher-order functions—without requiring the caller to specialize for termination guarantees. This approach leverages polymorphism's uniformity to handle divergence generically; for example, inferred types from polymorphic programs can detect non-termination by propagating bottom constraints through recursive or higher-order calls, ensuring type safety without explicit termination checks. Such modeling aligns with subtyping lattices where the bottom type anchors incomplete computations, briefly relating to totality proofs by excluding divergent paths from well-typed behaviors. In advanced dependent type systems, the bottom type supports proofs of totality by explicitly excluding impossible or contradictory cases during type checking. When index constraints in dependent types derive an unsatisfiable equivalent to the bottom type (denoted ⊥), it signals that no closed value can inhabit the type, allowing the system to prune unreachable branches and verify exhaustive coverage. For , if constraints entail ⊥ for a , the matcher confirms no input can reach it, aiding totality by ensuring functions handle all valid cases without gaps or errors. This use of the bottom type integrates with dependent quantification to enforce invariants, proving correctness in contexts like recursive definitions or effectful computations.

Practical Implementations

In Functional Languages

In languages like , the bottom type, denoted as ⊥, represents computations that fail to produce a value, encompassing both non-termination (such as infinite loops) and explicit errors. This concept is integral to 's semantics, where ⊥ is included in every type, allowing any expression to potentially diverge without violating . The module provides undefined :: a as a inhabitant of ⊥ for any type a, enabling programmers to stub out incomplete implementations that raise a runtime error when evaluated. Haskell's lazy evaluation strategy leverages ⊥ through unevaluated thunks, which are suspensions of computations that delay execution until their results are demanded. If a thunk's computation yields ⊥, the bottom value propagates without forcing immediate evaluation, preserving referential transparency in pure functions. This mechanism facilitates short-circuiting in control structures; for instance, the logical operators && and || avoid evaluating the second argument if the first determines the outcome, as the remaining thunk remains unevaluated and ⊥-infused if applicable. Semantically, ⊥ is included in every type due to Haskell's non-strict evaluation, and polymorphic functions like undefined have the type forall a. a, allowing their use in any context to represent impossible or erroneous cases. This supports error handling and modeling without subtyping in Haskell's Hindley-Milner type system. In practice, Haskell's pattern matching exhaustiveness checks, implemented in GHC since the early 2000s, utilize bottom for handling impossible branches to avoid runtime failures. When patterns are non-exhaustive, GHC issues warnings, and developers often complete matches with a catch-all clause returning undefined or error, ensuring the function is total while signaling impossibility at runtime. For example, in a function processing a sum type like data Color = Red | Green | Blue, an exhaustive match might include:
processColor Red = "red"
processColor Green = "green"
processColor Blue = "blue"
processColor _ = undefined  -- Bottom for any impossible extension
This approach, supported by GHC extensions like PatternGuards (introduced around 2003), allows flexible matching while relying on ⊥ to model unreachable cases without altering the function's type.

In Object-Oriented Languages

In object-oriented languages, the bottom type is typically adapted to handle scenarios where no valid value can be produced, such as in exception propagation or implementations that cannot be fulfilled. This adaptation contrasts with functional paradigms by emphasizing mutable state and runtime errors over pure non-termination, enabling polymorphic dispatch in inheritance-based systems. Java lacks an explicit bottom type but approximates it through void for non-returning methods and null for absent references. Unchecked exceptions, subclasses of RuntimeException, model bottom-like behavior by allowing abrupt termination without compile-time declaration, effectively permitting a method to "return" no value while remaining type-compatible with any caller expectation. For instance, a method declared to return String but always throwing a RuntimeException behaves as if it has a bottom subtype, avoiding type errors in polymorphic contexts. Scala, as a hybrid object-oriented and functional language, provides an explicit bottom type called Nothing, which is a subtype of every other type and has no instances. Nothing is commonly used for empty collections, such as List.empty, which has type List[Nothing] and can be safely upcast to List[T] for any T due to subtyping. It also serves as the return type for methods that never complete normally, like those throwing exceptions: def fail(msg: String): Nothing = throw new RuntimeException(msg). This enables polymorphic usage, such as returning Nothing from case statements to satisfy exhaustiveness without providing a value. In object-oriented inheritance hierarchies, the integrates with exception classes to support polymorphic handling. Exception hierarchies typically root at a top type like Throwable in or Exception in other languages, but the represents the uninhabited of all exception subtypes, allowing catch blocks to polymorphically handle any possible as a supertype. This design ensures that functions returning (e.g., via guaranteed exceptions) are subtypes of all types, facilitating safe substitution in overridden methods or implementations. C++ templates exhibit bottom-like behavior through SFINAE (Substitution Failure Is Not an Error), introduced prominently in C++11, which discards invalid template specializations at without error. This simulates an uninhabited type when substitution fails, enabling conditional compilation akin to selecting from a bottom type in a type . For example, trait detection using std::enable_if relies on SFINAE to provide a valid overload only if a type satisfies criteria, otherwise falling back to no implementation—mirroring the absence of values in a bottom type.

References

  1. [1]
    Types and Programming Languages - MIT Press
    This text provides a comprehensive introduction both to type systems in computer science and to the basic theory of programming languages.
  2. [2]
    bottom in nLab
    Jul 3, 2018 · In a poset P P , a bottom is a least element: an element ⊥ \bot of P P such that ⊥ ≤ a \bot \leq a for every element a a . Such a bottom may not ...
  3. [3]
    never - Rust
    The `!` type, or 'never', represents computations that never resolve to any value, like `exit`, `break`, `continue`, and `return`. It can be assigned to a ...and generics · Infallible errors · and traits · Never type fallback
  4. [4]
    Handbook - Basic Types - TypeScript
    The never type is a subtype of, and assignable to, every type; however, no type is a subtype of, or assignable to, never (except never itself). Even any isn't ...String · Unknown · Any · Null and Undefined
  5. [5]
    Subtype Polymorphism - CS@Cornell
    We can also introduce a bottom type 0 that is a universal subtype. This type can be accepted by any context in lieu of any other type: i.e., \(\forall τ, ~0≤τ\ ...
  6. [6]
    [PDF] Type Systems for Programming Languages
    Mar 22, 2021 · The study of type systems for programming languages has emerged over the past decade as one of the most active areas of computer science ...
  7. [7]
    [PDF] Type Theory & Functional Programming - Kent Academic Repository
    The fact that ⊥means contradiction or absurdity suggests that there is no ... implication ('implies') operations over the boolean type. 4.17. Define the ...<|separator|>
  8. [8]
    [PDF] OUTLINE OF A MATHEMATICAL THEORY OF COMPUTATION
    Dana Scott. Princeton University. The motivation for trying to formulate a mathematical theory of computation is to give mathematical semantics for high-level.
  9. [9]
    Type Theory - Stanford Encyclopedia of Philosophy
    Feb 8, 2006 · The topic of type theory is fundamental both in logic and computer science. We limit ourselves here to sketch some aspects that are important in logic.Simple Type Theory and the... · Type Theory/Category Theory
  10. [10]
    domain theory in nLab
    ### Summary of Bottom Element in Domain Theory
  11. [11]
  12. [12]
    [PDF] Semantic subtyping for non-strict languages
    Current semantic subtyping systems are unsound for non-strict semantics because of the way they deal with the bottom type 0, which corresponds to the empty set ...
  13. [13]
    falsehood in nLab
    Sep 6, 2024 · In intuitionistic logic, false is the bottom element in the poset of truth values. Intuitionistic logic is still two-valued in the sense that ...
  14. [14]
    top in nLab
    ### Summary of "Top" from nLab
  15. [15]
    unit type in nLab
    Jul 3, 2025 · In type theory the unit type is the type with a unique term. It is the special case of a product type with no factors.
  16. [16]
    [PDF] Type Systems
    A type system is that component of a typed language that keeps track of the types of variables and, in general, of the types of all expressions in a program.
  17. [17]
    [PDF] First-Order Theory of Subtyping Constraints
    We first describe the subtype logic that we use. We consider any subtype language with at least a bottom element ⊥ and a binary type constructor. We show that ...
  18. [18]
    [PDF] Algebraic Subtyping
    The addition of these two types causes the partial order of types to form a lattice (for the usual definitions of function and record subtyping).
  19. [19]
    [PDF] Subtyping constraints in quasi-lattices - HAL Inria
    May 23, 2006 · However, in a lattice, the bottom element ⊥ denotes the empty type, hence a function typed by ⊥ → τ cannot be applied to any argument.<|control11|><|separator|>
  20. [20]
    [PDF] A Model for Java with Wildcards - SciSpace
    The bottom type, ⊥, is used only as a lower bound and is used to model the situation in Java where a lower bound is omitted. Substitution in TameFJ is ...
  21. [21]
    [PDF] Greedy Implicit Bounded Quantification - HKU
    Since we include bottom types, the subtyping relation is not antisymmetric like the original F≤, e.g., a type variable with a bottom bound and the bottom type ...
  22. [22]
    [PDF] Optimal Representations of Polymorphic Types with Subtyping
    Parametric polymorphism allows a parameterized type inferred for a program fragment to take on a di erent instance in every context where it is used.Missing: bottom | Show results with:bottom
  23. [23]
    [PDF] On Variance-Based Subtyping for Parametric Types
    ... bottom type, which is a subtype of any type (even of unknown abstract type) ... Parametric polymorphism in Java: an efficient implementation for parametric methods ...
  24. [24]
    [PDF] Optimal Representations of Polymorphic Types with Subtyping ...
    There is a published account illustrating how types inferred from ML programs (which have polymorphism but no subtyping) can be used to detect non-terminating ...Missing: bottom | Show results with:bottom
  25. [25]
    [PDF] Dependent Types in Practical Programming
    Dec 6, 1998 · This is crucial to proving the type preservation theorem for ML0 ... because this declaration assigns Bottom the type ∀α.α → bottom, which clearly ...
  26. [26]
    Chapter 3 Expressions - Haskell.org
    3.1 Errors. Errors during expression evaluation, denoted by ⊥ (“bottom”), are indistinguishable by a Haskell program from non-termination. Since ...
  27. [27]
  28. [28]
  29. [29]
    [PDF] A Static Checker for Safe Pattern Matching in Haskell - Neil Mitchell
    This paper describes a static checker that allows non-exhaustive pat- terns to exist, yet ensures that a pattern-match error does not occur. It describes a.
  30. [30]
    Nothing - The Scala Programming Language
    Null - at the bottom of Scala's type hierarchy. Nothing is a subtype of every other type (including scala.Null); there exist no instances of this type.
  31. [31]
    Unified Types | Tour of Scala
    Nothing is a subtype of all types, also called the bottom type. There is no value that has type Nothing . A common use is to signal non-termination such as a ...