-
Qualifying System F-sub
Authors:
Edward Lee,
Yaoyu Zhao,
James You,
Kavin Satheeskumar,
Ondřej Lhoták,
Jonathan Brachthäuser
Abstract:
Type qualifiers offer a lightweight mechanism for enriching existing type systems to enforce additional, desirable, program invariants. They do so by offering a restricted but effective form of subtyping. While the theory of type qualifiers is well understood and present in many programming languages today, polymorphism over type qualifiers is an area that is less examined. We explore how such a p…
▽ More
Type qualifiers offer a lightweight mechanism for enriching existing type systems to enforce additional, desirable, program invariants. They do so by offering a restricted but effective form of subtyping. While the theory of type qualifiers is well understood and present in many programming languages today, polymorphism over type qualifiers is an area that is less examined. We explore how such a polymorphic system could arise by constructing a calculus System F<:Q which combines the higher-rank bounded polymorphism of System F<: with the theory of type qualifiers. We explore how the ideas used to construct System F<:Q can be reused in situations where type qualifiers naturally arise -- in reference immutability, function colouring, and capture checking. Finally, we re-examine other qualifier systems in the literature in light of the observations presented while developing System F<:Q.
△ Less
Submitted 13 November, 2023;
originally announced November 2023.
-
Simple Reference Immutability for System F-sub
Authors:
Edward Lee,
Ondřej Lhoták
Abstract:
Reference immutability is a type based technique for taming mutation that has long been studied in the context of object-oriented languages, like Java. Recently, though, languages like Scala have blurred the lines between functional programming languages and object oriented programming languages. We explore how reference immutability interacts with features commonly found in these hybrid languages…
▽ More
Reference immutability is a type based technique for taming mutation that has long been studied in the context of object-oriented languages, like Java. Recently, though, languages like Scala have blurred the lines between functional programming languages and object oriented programming languages. We explore how reference immutability interacts with features commonly found in these hybrid languages, in particular with higher-order functions -- polymorphism -- and subtyping. We construct a calculus System F-sub-M which encodes a reference immutability system as a simple extension of F-sub and prove that it satisfies the standard soundness and immutability safety properties.
△ Less
Submitted 10 July, 2023;
originally announced July 2023.
-
Scoped Capabilities for Polymorphic Effects
Authors:
Martin Odersky,
Aleksander Boruch-Gruszecki,
Edward Lee,
Jonathan Brachthäuser,
Ondřej Lhoták
Abstract:
Type systems usually characterize the shape of values but not their free variables. However, many desirable safety properties could be guaranteed if one knew the free variables captured by values. We describe CCsubBox, a calculus where such captured variables are succinctly represented in types, and show it can be used to safely implement effects and effect polymorphism via scoped capabilities. We…
▽ More
Type systems usually characterize the shape of values but not their free variables. However, many desirable safety properties could be guaranteed if one knew the free variables captured by values. We describe CCsubBox, a calculus where such captured variables are succinctly represented in types, and show it can be used to safely implement effects and effect polymorphism via scoped capabilities. We discuss how the decision to track captured variables guides key aspects of the calculus, and show that CCsubBox admits simple and intuitive types for common data structures and their typical usage patterns. We demonstrate how these ideas can be used to guide the implementation of capture checking in a practical programming language.
△ Less
Submitted 22 July, 2022; v1 submitted 7 July, 2022;
originally announced July 2022.
-
Tracking Captured Variables in Types
Authors:
Aleksander Boruch-Gruszecki,
Jonathan Immanuel Brachthäuser,
Edward Lee,
Ondřej Lhoták,
Martin Odersky
Abstract:
Type systems usually characterize the shape of values but not their free variables. However, there are many desirable safety properties one could guarantee if one could track how references can escape. For example, one may implement algebraic effect handlers using capabilities -- a value which permits one to perform the effect -- safely if one can guarantee that the capability itself does not esca…
▽ More
Type systems usually characterize the shape of values but not their free variables. However, there are many desirable safety properties one could guarantee if one could track how references can escape. For example, one may implement algebraic effect handlers using capabilities -- a value which permits one to perform the effect -- safely if one can guarantee that the capability itself does not escape the scope bound by the effect handler. To this end, we study the $\textrm{CF}_{<:}$ calculus, a conservative and lightweight extension of $\textrm{System F}_{<:}$, to track how values and their references can be captured and escape. We show that existing terms in $\textrm{System F}_{<:}$ embed naturally in our calculus, and that many natural problems can be expressed in a system that tracks variable references like we do in $\textrm{CF}_{<:}$. We also give mechanized proofs of the soundness properties of $\textrm{CF}_{<:}$ in Coq. The type system presented in $\textrm{CF}_{<:}$ is powerful enough to reason about safety in the context of many natural extensions of $\textrm{CF}_{<:}$ such as region-based memory-management, non-local returns, and effect handlers.
△ Less
Submitted 25 May, 2021;
originally announced May 2021.
-
Precise Dataflow Analysis of Event-Driven Applications
Authors:
Ming-Ho Yee,
Ayaz Badouraly,
Ondřej Lhoták,
Frank Tip,
Jan Vitek
Abstract:
Event-driven programming is widely used for implementing user interfaces, web applications, and non-blocking I/O. An event-driven program is organized as a collection of event handlers whose execution is triggered by events. Traditional static analysis techniques are unable to reason precisely about event-driven code because they conservatively assume that event handlers may execute in any order.…
▽ More
Event-driven programming is widely used for implementing user interfaces, web applications, and non-blocking I/O. An event-driven program is organized as a collection of event handlers whose execution is triggered by events. Traditional static analysis techniques are unable to reason precisely about event-driven code because they conservatively assume that event handlers may execute in any order. This paper proposes an automatic transformation from Interprocedural Finite Distributive Subset (IFDS) problems to Interprocedural Distributed Environment (IDE) problems as a general solution to obtain precise static analysis of event-driven applications; problems in both forms can be solved by existing implementations. Our contribution is to show how to improve analysis precision by automatically enriching the former with information about the state of event handlers to filter out infeasible paths. We prove the correctness of our transformation and report on experiments with a proof-of-concept implementation for a subset of JavaScript.
△ Less
Submitted 28 October, 2019;
originally announced October 2019.
-
Undecidability of $D_{<:}$ and Its Decidable Fragments
Authors:
Jason Hu,
Ondřej Lhoták
Abstract:
Dependent Object Types (DOT) is a calculus with path dependent types, intersection types, and object self-references, which serves as the core calculus of Scala 3. Although the calculus has been proven sound, it remains open whether type checking in DOT is decidable. In this paper, we establish undecidability proofs of type checking and subtyping of $D_{<:}$, a syntactic subset of DOT. It turns ou…
▽ More
Dependent Object Types (DOT) is a calculus with path dependent types, intersection types, and object self-references, which serves as the core calculus of Scala 3. Although the calculus has been proven sound, it remains open whether type checking in DOT is decidable. In this paper, we establish undecidability proofs of type checking and subtyping of $D_{<:}$, a syntactic subset of DOT. It turns out that even for $D_{<:}$, undecidability is surprisingly difficult to show, as evidenced by counterexamples for past attempts. To prove undecidability, we discover an equivalent definition of the $D_{<:}$ subtyping rules in normal form. Besides being easier to reason about, this definition makes the phenomenon of bad bounds explicit as a single inference rule. After removing this rule, we discover two decidable fragments of $D_{<:}$ subtyping and identify algorithms to decide them. We prove soundness and completeness of the algorithms with respect to the fragments, and we prove that the algorithms terminate. Our proofs are mechanized in a combination of Coq and Agda.
△ Less
Submitted 14 August, 2019;
originally announced August 2019.
-
A Path To DOT: Formalizing Fully Path-Dependent Types
Authors:
Marianna Rapoport,
Ondřej Lhoták
Abstract:
The Dependent Object Types (DOT) calculus aims to formalize the Scala programming language with a focus on path-dependent types $-$ types such as $x.a_1\dots a_n.T$ that depend on the runtime value of a path $x.a_1\dots a_n$ to an object. Unfortunately, existing formulations of DOT can model only types of the form $x.A$ which depend on variables rather than general paths. This restriction makes it…
▽ More
The Dependent Object Types (DOT) calculus aims to formalize the Scala programming language with a focus on path-dependent types $-$ types such as $x.a_1\dots a_n.T$ that depend on the runtime value of a path $x.a_1\dots a_n$ to an object. Unfortunately, existing formulations of DOT can model only types of the form $x.A$ which depend on variables rather than general paths. This restriction makes it impossible to model nested module dependencies. Nesting small components inside larger ones is a necessary ingredient of a modular, scalable language. DOT's variable restriction thus undermines its ability to fully formalize a variety of programming-language features including Scala's module system, family polymorphism, and covariant specialization.
This paper presents the pDOT calculus, which generalizes DOT to support types that depend on paths of arbitrary length, as well as singleton types to track path equality. We show that naive approaches to add paths to DOT make it inherently unsound, and present necessary conditions for such a calculus to be sound. We discuss the key changes necessary to adapt the techniques of the DOT soundness proofs so that they can be applied to pDOT. Our paper comes with a Coq-mechanized type-safety proof of pDOT. With support for paths of arbitrary length, pDOT can realize DOT's full potential for formalizing Scala-like calculi.
△ Less
Submitted 13 August, 2019; v1 submitted 15 April, 2019;
originally announced April 2019.
-
A Simple Soundness Proof for Dependent Object Types
Authors:
Marianna Rapoport,
Ifaz Kabir,
Paul He,
Ondřej Lhoták
Abstract:
Dependent Object Types (DOT) is intended to be a core calculus for modelling Scala. Its distinguishing feature is abstract type members, fields in objects that hold types rather than values. Proving soundness of DOT has been surprisingly challenging, and existing proofs are complicated, and reason about multiple concepts at the same time (e.g. types, values, evaluation). To serve as a core calculu…
▽ More
Dependent Object Types (DOT) is intended to be a core calculus for modelling Scala. Its distinguishing feature is abstract type members, fields in objects that hold types rather than values. Proving soundness of DOT has been surprisingly challenging, and existing proofs are complicated, and reason about multiple concepts at the same time (e.g. types, values, evaluation). To serve as a core calculus for Scala, DOT should be easy to experiment with and extend, and therefore its soundness proof needs to be easy to modify.
This paper presents a simple and modular proof strategy for reasoning in DOT. The strategy separates reasoning about types from other concerns. It is centred around a theorem that connects the full DOT type system to a restricted variant in which the challenges and paradoxes caused by abstract type members are eliminated. Almost all reasoning in the proof is done in the intuitive world of this restricted type system. Once we have the necessary results about types, we observe that the other aspects of DOT are mostly standard and can be incorporated into a soundness proof using familiar techniques known from other calculi.
Our paper comes with a machine-verified version of the proof in Coq.
△ Less
Submitted 12 June, 2017;
originally announced June 2017.
-
Who you gonna call? Analyzing Web Requests in Android Applications
Authors:
Marianna Rapoport,
Philippe Suter,
Erik Wittern,
Ondřej Lhoták,
Julian Dolby
Abstract:
Relying on ubiquitous Internet connectivity, applications on mobile devices frequently perform web requests during their execution. They fetch data for users to interact with, invoke remote functionalities, or send user-generated content or meta-data. These requests collectively reveal common practices of mobile application development, like what external services are used and how, and they point…
▽ More
Relying on ubiquitous Internet connectivity, applications on mobile devices frequently perform web requests during their execution. They fetch data for users to interact with, invoke remote functionalities, or send user-generated content or meta-data. These requests collectively reveal common practices of mobile application development, like what external services are used and how, and they point to possible negative effects like security and privacy violations, or impacts on battery life. In this paper, we assess different ways to analyze what web requests Android applications make. We start by presenting dynamic data collected from running 20 randomly selected Android applications and observing their network activity. Next, we present a static analysis tool, Stringoid, that analyzes string concatenations in Android applications to estimate constructed URL strings. Using Stringoid, we extract URLs from 30, 000 Android applications, and compare the performance with a simpler constant extraction analysis. Finally, we present a discussion of the advantages and limitations of dynamic and static analyses when extracting URLs, as we compare the data extracted by Stringoid from the same 20 applications with the dynamically collected data.
△ Less
Submitted 18 May, 2017; v1 submitted 18 May, 2017;
originally announced May 2017.
-
Mutable WadlerFest DOT
Authors:
Marianna Rapoport,
Ondřej Lhoták
Abstract:
The Dependent Object Types (DOT) calculus aims to model the essence of Scala, with a focus on abstract type members, path-dependent types, and subtyping. Other Scala features could be defined by translation to DOT. Mutation is a fundamental feature of Scala currently missing in DOT. Mutation in DOT is needed not only to model effectful computation and mutation in Scala programs, but even to precis…
▽ More
The Dependent Object Types (DOT) calculus aims to model the essence of Scala, with a focus on abstract type members, path-dependent types, and subtyping. Other Scala features could be defined by translation to DOT. Mutation is a fundamental feature of Scala currently missing in DOT. Mutation in DOT is needed not only to model effectful computation and mutation in Scala programs, but even to precisely specify how Scala initializes immutable variables and fields (vals). We present an extension to DOT that adds typed mutable reference cells. We have proven the extension sound with a mechanized proof in Coq. We present the key features of our extended calculus and its soundness proof, and discuss the challenges that we encountered in our search for a sound design and the alternative solutions that we considered.
△ Less
Submitted 22 November, 2016;
originally announced November 2016.