- The paper introduces Hippogriff, a programming language that unifies ML-style modules with dependent types while maintaining decidable type checking and general recursion.
- Type equality in Hippogriff is both decidable and maintains safe recursion by confining problematic constructs to small types under a closed modality.
- The language incorporates the type-theoretic framework of SOGATs with a synthetic phase distinction for a comprehensive metatheory of unification.
Hippogriff is a programming language and accompanying type-theoretic framework that unifies ML-style modules with dependent types while retaining decidable type checking, general recursion, and a direct semantics in System F. The paper by Lynch and Staton makes two contributions: a working implementation of the language, and a mathematical metatheory—SOGATs equipped with a synthetic phase distinction—that justifies the design. The central claim is that features commonly held to be incompatible (decidable dependent typing and general recursion) can coexist when problematic term-level constructs are confined to small types under a closed modality.
The language
Hippogriff presents a single, unified syntax in which types are ordinary values: there is a universe Type of small types, itself large, and large record types (theory declarations) play the role of module signatures. Elements of signatures such as Monoid or Eq are passed as ordinary function arguments, which subsumes functors, first-class modules, and features that other languages only recently adopted—for instance, passing an Ord dictionary as a run-time argument to sort, which the authors note was only added to OCaml 5.5.
Several design points carry most of the technical weight:
- No non-constant functions into large types. Pattern matching may not eliminate from a sum type into
Type. Consequently, every writable function a→Type for small a is constant. This invariant is what makes type equality decidable despite general recursion.
- Recursion via guarded fixpoints. Every top-level definition is implicitly wrapped in a guarded fixpoint $\mathsf{gfix}_A : (\tri A \to A) \to A$, following Nakano's modality and Atkey–McBride's productive coprogramming. Recursive invocation is permitted only inside
sum ... end blocks or inside rec (...), the latter restricted to small types so it evaluates to an opaque value at typechecking time.
- Specialization via static extent. The constructor
Monoid ~ [ .t := t ] is a variant of singleton types integrated into the record type former, in the tradition of Sterling–Harper's synthetic phase distinction.
- Nominal types via behaviors, adapted from Narya's kinetic/potential distinction: each top-level binding introduces a fresh variable equipped with a behavior, unfolded on demand during normalization-by-evaluation.
The implementation uses bidirectional elaboration rather than Hindley–Milner unification, with mutually recursive synthesis and checking modes. Check-only notation such as 'just x allows overlapping tags across sum types without ambiguity.
Implementation strategy
Type equality is decided by Coquand's normalization by evaluation, modified with an opaque value ■ representing an arbitrary element of a small type. Constructs like rec and abandon evaluate to ■; equality checks involving ■ succeed immediately because both sides are known to inhabit a small type. This is an overapproximation of object-level equality, in contrast to Kovács's staged two-level type theory, which omits beta-normalization for object code and thus underapproximates. The elaborator never round-trips through readback, so diagnostics are explained entirely in the user's source syntax—a deliberate contrast with 1ML, where type errors must be understood through the translation to System F. A separate interpreter erases types and evaluates fixpoints for actual execution.
The authors note a consequential degree of freedom: making function-type levels depend only on the codomain yields impredicativity (the current choice, matching System F), whereas taking the maximum of domain and codomain sizes yields a predicative system that could conceivably be fully monomorphized; making all function types large would resemble Rust's treatment of functions as non-first-class. These alternatives are conjectural.
Mathematical framework
The second half develops the semantics. The judgment structure of System F is classically a split-context theory: Harper–Mitchell–Moggi present it via a SCwF-indexed SCwF (following Moggi's indexed-category account of SML modules). Writing rules in split-context style is verbose, and SOGATs (Uemura; Kaposi–Xie) remove the clutter but lose control over dependency structure in general models.
The paper's resolution is to extend SOGATs with a synthetic phase distinction: a representable proposition § ("it is currently typechecking time") with associated open modality $\Op A = \phi \to A$ and closed modality given by quotient-induction (a pushout construction). Working internally to presheaves over the extended total space $\mc{C}^\bullet$ of the fibration, the open-modal objects recover constant (context-independent) judgments and the closed-modal objects recover fiber judgments. The key synthetic lemma: since elements of a closed-modal type become equal under ϕ, any function a0 with a1 open-modal must be constant—so dependent function types collapse to simple ones exactly as required for System F.
Module signatures a2 are then defined internally as pairs of base and fiber data, and the theorem that they admit dependent function types whenever the base has a3, the fiber has simple function types, and the pair has universal quantification reproduces precisely HMM's signature for dependent module functors—but derived compositionally rather than written out "in agonizing detail" in two-context style. Problematic features (general recursion, abandonment) are added under the closed modality, where their equality behavior is irrelevant to type checking.
Limitations and open questions
The paper is candid about gaps. The definition of SOGATs with phase distinction is labeled "conjectural": significant technical work remains, related work in greater generality is in progress elsewhere, and the proof that indexed models of the split-context signature correspond to CwF-indexed SCwFs is omitted as long and technical. There is no termination proof for the type-equality decision procedure beyond "proof by implementation"; proving normalization would require extending Bocquet's relative induction both to modalities and to guarded recursion, presupposing a theory of "modal SOGATs" that does not yet exist. Ergonomically, Hippogriff lacks unification-based implicit argument inference and any subtyping between module signatures. A full comparison of its recursive modules against OCaml/SML recursive modules has not been made. Finally, combining this phase distinction with a refinement-type phase distinction (where propositions are erased at runtime) appears to break the opaque-value approach, since proposition checking requires finer-grained equality; how general recursion would work there remains open.
Conclusion
Hippogriff demonstrates that the synthetic machinery of Logical Relations as Types—the phase distinction used for logical relations, normalization proofs, and cost-aware logical frameworks—can be repurposed to build a practical language whose unified syntax elaborates directly to System F semantics without sacrificing error-message fidelity. The price is a genuine restriction (no non-constant functions into large types) and several unproven metatheoretic claims; the main outstanding questions concern formalizing termination of type checking and developing the theory of modal SOGATs that the construction implicitly requires.