8 research outputs found
Approximate Normalization for Gradual Dependent Types
Dependent types help programmers write highly reliable code. However, this
reliability comes at a cost: it can be challenging to write new prototypes in
(or migrate old code to) dependently-typed programming languages. Gradual
typing makes static type disciplines more flexible, so an appropriate notion of
gradual dependent types could fruitfully lower this cost. However, dependent
types raise unique challenges for gradual typing. Dependent typechecking
involves the execution of program code, but gradually-typed code can signal
runtime type errors or diverge. These runtime errors threaten the soundness
guarantees that make dependent types so attractive, while divergence spoils the
type-driven programming experience.
This paper presents GDTL, a gradual dependently-typed language that
emphasizes pragmatic dependently-typed programming. GDTL fully embeds both an
untyped and dependently-typed language, and allows for smooth transitions
between the two. In addition to gradual types we introduce gradual terms ,
which allow the user to be imprecise in type indices and to omit proof terms;
runtime checks ensure type safety . To account for nontermination and failure,
we distinguish between compile-time normalization and run-time execution:
compile-time normalization is approximate but total, while runtime execution is
exact , but may fail or diverge. We prove that GDTL has decidable typechecking
and satisfies all the expected properties of gradual languages. In particular,
GDTL satisfies the static and dynamic gradual guarantees: reducing type
precision preserves typedness, and altering type precision does not change
program behavior outside of dynamic type failures. To prove these properties,
we were led to establish a novel normalization gradual guarantee that captures
the monotonicity of approximate normalization with respect to imprecision
On the design of a gradual dependently typed language for programming
Dependently typed programming languages provide a way to write programs, specifications, and correctness proofs using a single language. If a dependent type checker accepts a program, the programmer can be assured that it behaves according to the specification given in its types. However, dependently typed programming languages can be hard to use.
Gradual types provide a way to mix dynamically and statically typed code in a single language. Under this paradigm, programs may have imprecise types, causing certain type checks to be deferred to run time.
We build the theoretical foundations for combining gradual and dependent types in a programming language, with the aim of making dependent types easier to use. The differences between these two paradigms lead to inherent tensions when choosing the properties such a language should satisfy. Gradual typing's effectful nature conflicts with the compile-time reductions of dependent type checking. Gradual run-time type comparisons clash with dependent types containing terms that bind variables. This dissertation identifies such tensions and proposes a design that finds balance between the conflicting goals.
Our contribution has three parts:
First, we present a foundational calculus for gradual dependent types, with functions, function types and universes. To ensure that type checking terminates, we reduce compile-time terms with approximate normalization, producing imprecise results when the available type information cannot guarantee termination. We use hereditary substitution to show that approximate normalization always terminates.
Second, we present a notion of propositional equality for gradual dependent types. We devise a method of tracking run-time consistency information between imprecise equated terms, and introduce a composition operator in the language itself.
Third, we show that the first and second contributions can be combined, giving a language with approximate normalization that supports inductive types and propositional equality with dynamic consistency tracking. Since hereditary substitution does not scale to inductive types, we use a syntactic model to establish termination. The same technique is used to model non-terminating run-time semantics using guarded type theory, paving the road for mechanizing the metatheory of gradual dependent types.Science, Faculty ofComputer Science, Department ofGraduat
Propositional Equality for Gradual Dependently Typed Programming
Gradual dependent types can help with the incremental adoption of dependently
typed code by providing a principled semantics for imprecise types and proofs,
where some parts have been omitted. Current theories of gradual dependent
types, though, lack a central feature of type theory: propositional equality.
Lennon-Bertrand et al. show that, when the reflexive proof is
the only closed value of an equality type, a gradual extension of CIC with
propositional equality violates static observational equivalences.
Extensionally-equal functions should be indistinguishable at run time, but the
combination of equality and type imprecision allows for contexts that
distinguish extensionally-equal but syntactically-different functions.
This work presents a gradually typed language that supports propositional
equality. We avoid the above issues by devising an equality type where
is not the only closed inhabitant. Instead, each equality proof
carries a term that is at least as precise as the equated terms, acting as a
witness of their plausible equality. These witnesses track partial type
information as a program runs, raising errors when that information shows that
two equated terms are undeniably inconsistent. Composition of type information
is internalized as a construct of the language, and is deferred for function
bodies whose evaluation is blocked by variables. By deferring, we ensure that
extensionally equal functions compose without error, thereby preventing
contexts from distinguishing them. We describe the challenges of designing
consistency and precision relations for this system, along with solutions to
these challenges. Finally, we prove important metatheory: type-safety,
conservative embedding of CIC, canonicity, and the gradual guarantees of Siek
et al.Comment: Under submission to ICFP 202
A framework for improving error messages in dependently-typed languages
Dependently-typed programming languages provide a powerful tool for establishing code correctness. However, it can be hard for newcomers to learn how to employ the advanced type system of such languages effectively. For simply-typed languages, several techniques have been devised to generate helpful error messages and suggestions for the programmer. We adapt these techniques to dependently-typed languages, to facilitate their more widespread adoption. In particular, we modify a higher-order unification algorithm that is used to resolve and type-check implicit arguments. We augment this algorithm with replay graphs, allowing for a global heuristic analysis of a unification problem-set, error-tolerant typing, which allows type-checking to continue after errors are found, and counter-factual unification, which makes error messages less affected by the order in which types are checked. A formalization of our algorithm is presented with an outline of its correctness. We implement replay graphs, and compare the generated error messages to those from existing languages, highlighting the improvements we achieved