172 research outputs found
Language integrated relational lenses
Relational databases are ubiquitous. Such monolithic databases accumulate large
amounts of data, yet applications typically only work on small portions of the data
at a time. A subset of the database defined as a computation on the underlying
tables is called a view. Querying views is helpful, but it is also desirable to update
them and have these changes be applied to the underlying database. This view
update problem has been the subject of much previous work before, but support
by database servers is limited and only rarely available.
Lenses are a popular approach to bidirectional transformations, a generalization
of the view update problem in databases to arbitrary data. However, perhaps surprisingly, lenses have seldom actually been used to implement updatable views in
databases. Bohannon, Pierce and Vaughan propose an approach to updatable views called relational lenses. However, to the best of our knowledge this
proposal has not been implemented or evaluated prior to the work reported in
this thesis.
This thesis proposes programming language support for relational lenses. Language integrated relational lenses support expressive and efficient view updates,
without relying on updatable view support from the database server. By integrating relational lenses into the programming language, application development
becomes easier and less error-prone, avoiding the impedance mismatch of having
two programming languages. Integrating relational lenses into the language poses
additional challenges. As defined by Bohannon et al. relational lenses completely
recompute the database, making them inefficient as the database scales. The
other challenge is that some parts of the well-formedness conditions are too general for implementation. Bohannon et al. specify predicates using possibly infinite
abstract sets and define the type checking rules using relational algebra.
Incremental relational lenses equip relational lenses with change-propagating semantics that map small changes to the view into (potentially) small changes
to the source tables. We prove that our incremental semantics are functionally
equivalent to the non-incremental semantics, and our experimental results show
orders of magnitude improvement over the non-incremental approach. This thesis introduces a concrete predicate syntax and shows how the required checks
are performed on these predicates and show that they satisfy the abstract predicate specifications. We discuss trade-offs between static predicates that are fully
known at compile time vs dynamic predicates that are only known during execution and introduce hybrid predicates taking inspiration from both approaches.
This thesis adapts the typing rules for relational lenses from sequential composition to a functional style of sub-expressions. We prove that any well-typed
functional relational lens expression can derive a well-typed sequential lens.
We use these additions to relational lenses as the foundation for two practical implementations: an extension of the Links functional language and a library written
in Haskell. The second implementation demonstrates how type-level computation can be used to implement relational lenses without changes to the compiler.
These two implementations attest to the possibility of turning relational lenses
into a practical language feature
Focusing on Refinement Typing
We present a logically principled foundation for systematizing, in a way that
works with any computational effect and evaluation order, SMT constraint
generation seen in refinement type systems for functional programming
languages. By carefully combining a focalized variant of call-by-push-value,
bidirectional typing, and our novel technique of value-determined indexes, our
system generates solvable SMT constraints without existential (unification)
variables. We design a polarized subtyping relation allowing us to prove our
logically focused typing algorithm is sound, complete, and decidable. We prove
type soundness of our declarative system with respect to an elementary
domain-theoretic denotational semantics. Type soundness implies, relatively
simply, the total correctness and logical consistency of our system. The
relative ease with which we obtain both algorithmic and semantic results
ultimately stems from the proof-theoretic technique of focalization.Comment: 61 pages + appendix with proofs, Just Accepted version of paper (with
new title) at ACM Transactions on Programming Languages and System
Generic Programming with Extensible Data Types; Or, Making Ad Hoc Extensible Data Types Less Ad Hoc
We present a novel approach to generic programming over extensible data
types. Row types capture the structure of records and variants, and can be used
to express record and variant subtyping, record extension, and modular
composition of case branches. We extend row typing to capture generic
programming over rows themselves, capturing patterns including lifting
operations to records and variations from their component types, and the
duality between cases blocks over variants and records of labeled functions,
without placing specific requirements on the fields or constructors present in
the records and variants. We formalize our approach in System R{\omega}, an
extension of F{\omega} with row types, and give a denotational semantics for
(stratified) R{\omega} in Agda.Comment: To appear at: International Conference on Functional Programming 2023
Corrected citations from previous versio
No Unification Variable Left Behind: Fully Grounding Type Inference for the HDM System
The Hindley-Damas-Milner (HDM) system provides polymorphism, a key feature of functional programming languages such as Haskell and OCaml. It does so through a type inference algorithm, whose soundness and completeness have been well-studied and proven both manually (on paper) and mechanically (in a proof assistant). Earlier research has focused on the problem of inferring the type of a top-level expression. Yet, in practice, we also may wish to infer the type of subexpressions, either for the sake of elaboration into an explicitly-typed target language, or for reporting those types back to the programmer. One key difference between these two problems is the treatment of underconstrained types: in the former, unification variables that do not affect the overall type need not be instantiated. However, in the latter, instantiating all unification variables is essential, because unification variables are internal to the algorithm and should not leak into the output.
We present an algorithm for the HDM system that explicitly tracks the scope of all unification variables. In addition to solving the subexpression type reconstruction problem described above, it can be used as a basis for elaboration algorithms, including those that implement elaboration-based features such as type classes. The algorithm implements input and output contexts, as well as the novel concept of full contexts, which significantly simplifies the state-passing of traditional algorithms. The algorithm has been formalised and proven sound and complete using the Coq proof assistant
Restrictable Variants: A Simple and Practical Alternative to Extensible Variants
We propose restrictable variants as a simple and practical alternative to extensible variants. Restrictable variants combine nominal and structural typing: a restrictable variant is an algebraic data type indexed by a type-level set formula that captures its set of active labels. We introduce new pattern-matching constructs that allows programmers to write functions that only match on a subset of variants, i.e., pattern-matches may be non-exhaustive. We then present a type system for restrictable variants which ensures that such non-exhaustive matches cannot get stuck at runtime.
An essential feature of restrictable variants is that the type system can capture structure-preserving transformations: specifically the introduction and elimination of variants. This property is important for writing reusable functions, yet many row-based extensible variant systems lack it.
In this paper, we present a calculus with restrictable variants, two partial pattern-matching constructs, and a type system that ensures progress and preservation. The type system extends Hindley-Milner with restrictable variants and supports type inference with an extension of Algorithm W with Boolean unification. We implement restrictable variants as an extension of the Flix programming language and conduct a few case studies to illustrate their practical usefulness
How Functorial Are (Deep) GADTs?
It is well-known that GADTs do not admit standard map functions of the kind supported by ADTs and nested types. In addition, standard map functions are insufficient to distribute their data-changing argument functions over all of the structure present in elements of deep GADTs, even just deep ADTs or nested types. This paper develops an algorithm for detecting exactly which functions are mappable over data whose types are (deep) GADTs. The algorithm takes as input a term t whose type is an instance of a deep GADT D and a function f to be mapped over t. It detects a minimal possible shape of t as an element of D, and returns a minimal set of constraints f must satisfy to be mappable over t. The crux of the algorithm is its ability to separate t's essential structure as an element of D -- i.e., the part of t that is essential for it to have the shape of an element of D -- from its incidental structure as an element of D -- i.e., the part of t that is simply data in the positions of this shape. The algorithm ensures that the constraints on f come only from t's essential structure. This work is part of an ongoing effort to define initial algebra semantics for GADTs that properly generalizes the usual semantics for ADTs and nested types as least fix points of higher-order endofunctors
Software Engineering with Incomplete Information
Information may be the common currency of the universe, the stuff of creation. As the physicist John Wheeler claimed, we get ``it from bit''. Measuring information, however, is a hard problem. Knowing the meaning of information is a hard problem. Directing the movement of information is a hard problem. This hardness comes when our information about information is incomplete. Yet we need to offer decision making guidance, to the computer or developer, when facing this incompleteness. This work addresses this insufficiency within the universe of software engineering.
This thesis addresses the first problem by demonstrating that obtaining the relative magnitude of information flow is computationally less expensive than an exact measurement. We propose ranked information flow, or RIF, where different flows are ordered according to their FlowForward, a new measure designed for ease of ordering. To demonstrate the utility of FlowForward, we introduce information contour maps: heatmapped callgraphs of information flow within software. These maps serve multiple engineering uses, such as security and refactoring.
By mixing a type system with RIF, we address the problem of meaning. Information security is a common concern in software engineering. We present OaST, the world's first gradual security type system that replaces dynamic monitoring with information theoretic risk assessment. OaST now contextualises FlowForward within a formally verified framework: secure program components communicate over insecure channels ranked by how much information flows through them. This context helps the developer interpret the flows and enables security policy discovery, adaptation and refactoring.
Finally, we introduce safestrings, a type-based system for controlling how the information embedded within a string moves through a program. This takes a structural approach, whereby a string subtype is a more precise, information limited, subset of string, ie a string that contains an email address, rather than anything else
(Deep) Induction Rules For GADTs
Deep data types are those that are constructed from other data types, including, possibly, themselves. In this case, they are said to be truly nested. Deep induction is an extension of structural induction that traverses all of the structure in a deep data type, propagating predicates on its primitive data throughout the entire structure. Deep induction can be used to prove properties of nested types, including truly nested types, that cannot be proved via structural induction. In this paper we show how to extend deep induction to GADTs that are not truly nested GADTs. This opens the way to incorporating automatic generation of (deep) induction rules for them into proof assistants. We also show that the techniques developed in this paper do not suffice for extending deep induction to truly nested GADTs, so more sophisticated techniques are needed to derive deep induction rules for them
33Úmes Journées Francophones des Langages Applicatifs
International audienceLes 33Ăšmes JournĂ©es Francophones des Langages Applicatifs (JFLA) se sont tenues Ă Saint-MĂ©dard-d'Excideuil, plus prĂ©cisĂ©ment Domaine d'EssendiĂ©ras (PĂ©rigord), du mardi 28 juin 2022 au vendredi 1er juillet 2022.Les JFLA rĂ©unissent concepteurs, utilisateurs et thĂ©oriciens ; elles ont pour ambition de couvrir les domaines des langages applicatifs, de la preuve formelle, de la vĂ©rification de programmes, et des objets mathĂ©matiques qui sous-tendent ces outils. Ces domaines doivent ĂȘtre pris au sens large : nous souhaitons promouvoir les ponts entre les diffĂ©rentes thĂ©matiques.- Langages fonctionnels et applicatifs : sĂ©mantique, compilation, optimisation, typage, mesures, extensions par d'autres paradigmes.- Assistants de preuve : implĂ©mentation, nouvelles tactiques, dĂ©veloppements prĂ©sentant un intĂ©rĂȘt technique ou mĂ©thodologique.- Logique, correspondance de Curry-Howard, rĂ©alisabilitĂ©, extraction de programmes, modĂšles.- SpĂ©cification, prototypage, dĂ©veloppements formels d'algorithmes.- VĂ©rification de programmes ou de modĂšles, mĂ©thode dĂ©ductive, interprĂ©tation abstraite, raffinement.- Utilisation industrielle des langages fonctionnels et applicatifs, ou des mĂ©thodes issues des preuves formelles, outils pour le web.Les articles soumis aux JFLA sont relus par au moins deux personnes s'ils sont acceptĂ©s, trois personnes s'ils sont rejetĂ©s. Les critiques des relecteurs sont toujours bienveillantes et la plupart du temps encourageantes et constructives, mĂȘme en cas de rejet
- âŠ