Deep vs. Shallow Subtyping
- Deep vs. Shallow Subtyping is a concept distinguishing recursive type validation (deep) from surface-level checks (shallow) in type systems.
- Type inference methods vary in complexity, as deep subtyping increases constraint recursion while η-expansion and normalization can simplify verification.
- Its practical implications span object-oriented and modular DSL design, influencing trade-offs between expressiveness, safety, and engineering feasibility.
The distinction between deep and shallow subtyping is fundamental in the design and implementation of type systems, with ramifications in type inference, program semantics, language feature expressiveness, and the engineering of both compilers and interpreters. At its core, the difference turns on whether subtyping relationships must be recursively validated throughout all type constructors (deep subtyping), or only at the top-level of type expressions (shallow subtyping). The trade-offs, expressive boundaries, and algorithmic techniques arising from this distinction are sharply illustrated in type inference algorithms, effect systems, models of object-oriented programming, and the metatheory of type systems. The following sections survey the major principles, methods, and consequences of deep versus shallow subtyping, drawing on rigorous developments across several computational paradigms.
1. Definitions and Fundamental Distinctions
Deep subtyping recursively inspects and compares the internal structure of compound types. In a canonical example from function types, a deep subtyping rule is:
This formulation enforces contravariance in argument position and covariance in result, requiring recursive decomposition for compound type constructors (as in intersection, product, or recursive types) (Dunfield, 26 Dec 2024).
Shallow subtyping, in contrast, operates only at the surface level (the "head" constructor) of a type, not descending into the structure beneath. For example, a shallow system may consist of only the rules:
where no recursive examination of sub-components occurs; subtyping is decided entirely by top-level type information (Dunfield, 26 Dec 2024).
The expressiveness of deep subtyping allows for richer reasoning about the compatibility of data structures and functions, but increases the logical and operational complexity of type-checking.
2. Type Inference and Constraint Handling
Constraint-based type inference algorithms have historically confronted the tension between expressiveness and tractability in subtyping (Gottlieb, 2011). Deep subtyping, as directly integrated into inference rules, can generate complex, recursively intertwined constraints of the form:
where includes deep subtyping relationships. However, this approach tends to aggravate both undecidability (through similarity to the semi-unification problem) and inference incompleteness.
Termination and completeness are achievable by minimizing subtyping intervention during inference—factoring out, simplifying, or eliminating subtyping constraints via normalization. Seminal algorithms assign ranges within a lattice to type variables, generate a minimal set of inequalities, solve the core unification, and then reintroduce only those minimal subtyping "adjustments" required for correctness. As a result, explicit subtyping constraints are eliminated from the principal types, and deep subtyping is effectively reduced to a shallow or flattened set of constraints that neither impede decidability nor inject proof obligations into the output types (Gottlieb, 2011).
3. Deep Subtyping and η-Expansion
A substantial reduction in the complexity of type systems employing deep subtyping can be achieved by η-expansion of terms (Dunfield, 26 Dec 2024). Early work by Barendregt, Coppo, and Dezani-Ciancaglini established that the role of deep subtyping in systems with rich compound types (notably intersection types) could be replaced by introducing η-expansion at the term level:
- Function types: replacing , where and , with such that is typable at using only shallow rules.
- Product types: repackaging projections to produce a pair that will pass "shallow" subtyping tests.
Formally, the key lemma (completeness) asserts that every term typable using deep subtyping can, via η-expansion, be rewritten as a term typable in a shallow system:
This provides a systematic means to flatten subtyping hierarchies, sidestepping deep recursion during type-checking by transferring the complexity into program structure (Dunfield, 26 Dec 2024).
4. Object-Oriented Subtyping: Nominal vs Structural and Depth
In object-oriented programming (OOP), subtyping's depth is entwined with the language's adoption of nominal or structural typing (AbdelGawad, 2016). Nominal typing enforces deep subtyping: subtypes must not only surface-match but inherit and fulfill deep behavioral contracts, as encoded in class names and inheritance hierarchies—for example, by ensuring that and for a subtype of .
Structural typing often facilitates shallow subtyping: subtypes are determined by the external record of methods and fields, regardless of contracts, supporting "after-the-fact" compatibility but risking spurious or missing subsumption.
This distinction has profound implications:
- Nominal/deep subtyping provides robust enforcement of semantic contracts (e.g., the Liskov Substitution Principle).
- Structural/shallow subtyping can create semantic mismatches, undermining invariants, and allow or disallow substitution in ways contrary to developer intentions (AbdelGawad, 2016).
5. Practical Applications: Modular Design and Rule Learning
In modular DSL and EDSL design, especially in languages supporting object-oriented constructs (e.g., Scala), shallow subtyping—leveraging inheritance and type refinement—enables greater modularity, reuse, and expressiveness compared to deep subtyping approaches such as explicit AST tagging in deep embeddings (Zhang et al., 2019). The ability to incrementally extend base traits (e.g., extending Circuit1 with Circuit2 and Circuit3 to add new operations or properties) supports modular addition of features and interpretations without code base rewrites.
In machine learning, analogous structural distinctions arise in deep versus shallow rule learning (Beck et al., 2021) and deep versus shallow neural network architectures (Mhaskar et al., 2016). Deep networks and deep rule theories introduce intermediate subtypes or concepts, capturing and reusing compositional structure to achieve superior accuracy and parameter efficiency—directly paralleling the advantages and costs of deep subtyping in programs and type systems.
Approach | Expressiveness | Type System Complexity | Reusability/Modularity |
---|---|---|---|
Deep Subtyping | High | High | Lower (without flattening) |
Shallow Subtyping | Lower | Lower | Higher (with η-expansion) |
6. Theoretical Foundations and Mechanized Models
Deep subtyping is often critical for the theoretical soundness of systems with recursive or effectful types, as in logical accounts of subtyping for session types (Horne et al., 2023), structural treatments in polarized subtyping with equirecursive types (Lakhani et al., 2022), and categorical models for dependent type theory (Coraglia et al., 2023). In these settings, deep subtyping enables correct handling of variance, unfolds recursive types, and interacts nontrivially with substitution, weakening, and term formation.
However, several works demonstrate that desirable proof-theoretic and semantic properties—such as the subformula conjunction property (Siek, 2019) or compositionality—can be maintained in systems engineered to be "shallower" by construction, by limiting intermediate types in derivations to be subformulas (or intersections of subformulas) of the original types being compared.
In categorical models (generalized categories with families), deep subtyping is encoded structurally as vertical maps (coercions) within the fiber category attached to each context. This is contrasted with coercive subtyping, where coercions are function terms; in categorical settings, subtyping relations exhibit functoriality and compose in alignment with the semantics of type constructors (Coraglia et al., 2023).
7. Implementation and Future Directions
Contemporary language design often seeks to balance the expressiveness and safety of deep subtyping with the tractability of shallow systems. Transformative approaches such as constraint normalization, η-expansion, and modular object-oriented embeddings illustrate multiple paths for implementing expressive type systems with manageable complexity (Gottlieb, 2011, Dunfield, 26 Dec 2024, Zhang et al., 2019).
Formalisms in session types, effect systems, and recursive types demonstrate the need for deep subtyping to achieve properties beyond basic safety—such as termination and liveness (Horne et al., 2023). Conversely, for practical engineering, eliminating or flattening deep subtyping (via well-founded η-expansion or modular type constructors) can make implementation and mechanized reasoning feasible, while preserving essential facets of system correctness and expressiveness.
These findings delineate the boundary between theoretical necessity and engineering pragmatism and suggest hybrid approaches as fertile ground for future type system development.