-
Linearly Qualified Types
A linear parameter must be consumed exactly once in the body of its function. When declaring resources such as file handles and manually managed memory as linear arguments, a linear type system can verify that these resources are used safely. However, writing code with explicit linear arguments requires bureaucracy. This paper presents linear constraints, a front-end feature for linear typing that decreases the bureaucracy of working with linear types. Linear constraints are implicit linear arguments that are filled in automatically by the compiler. We present linear constraints as a qualified type system,together with an inference algorithm which extends GHC's existing constraint solver algorithm. Soundness of linear constraints is ensured by the fact that they desugar into Linear Haskell.
-
Linear Haskell
Since 2016, I’ve been leading the effort to supplement the functional programming language Haskell with linear typing (in the sense of linear logic). That is you can write a type of functions which are allowed to use their arguments just once. The first iteration of this was released as part of GHC 9.0. This may seem like a curious property to require of a function. Originally, linear logic was motivated by proof-theoretic consideration. At first it appeared as a natural decomposition of the coherence-space models of classical logic, but it does have far reaching proof-theoretical considerations. I’m one to take the connection between proof theory and programming languages (the Curry-Howard correspondence) quite seriously. Linear logic has almost immediately been seen, from a programming language standpoint, as giving a way to model resources in types. But what this concretely means is not super clear. In this talk I will describe the sort of practical benefits that we expect from linear types in Haskell today. They are, in particular, related to Rust’s ownership typing, though I don’t know whether I will have time to explain this in detail. At any rate, I am not going to spoil the entire talk here. I’d do a bad job of it in these handful of lines, anyway.
-
Evaluating Linear Functions to Symmetric Monoidal Categories
-
Linear Constraints
In the past few years, I've been involved in extending the type system of the Haskell programming language to support linear types. In one sentence, a linear argument must be consumed exactly once in the body of its function; a linear function is a function whose argument is linear. Such a linear type system comes from linear logic (or, in this particular case, intuitionistic linear logic, but who's counting?) seen through the lens of the Curry-Howard correspondence. Linear typing has two main families of applications: making pure interface to mutable data structures, such as arrays (“pure” means that functions are functions in the sense of mathematics); and enforcing protocol in the type level, for instance making sure file handles are eventually closed and not written to after being closed. An example that combines both aspects is safe manual memory management, much in the style that the Rust programming language allows. This is all possible in the, latest, 9.0 release of GHC. However these applications, using GHC 9.0's linear types require quite a bit of additional syntactic bureaucracy, compared to their unsafe equivalent. In this talk, after introducing Haskell's linear types, I'll presents linear constraints, a front-end feature for linear typing that decreases the bureaucracy of working with linear types. Linear constraints are implicit linear arguments that are to be filled in automatically by the compiler. Linear constraints are presented as a qualified type system, together with an inference algorithm which extends OutsideIn, GHC's existing constraint solver algorithm. Soundness of linear constraints is ensured by the fact that they desugar into Linear Haskell.
-
Linear types for the masses
I’ve been working, in the past few years, at extending a production-grade compiler (namely GHC, the main Haskell compiler) with linear types. This has the potential of letting linear-logic-style type systems touch a wider public. I’ll be speaking about my experience, and will discuss the newest results on making linear typing easier to use: namely linear constraints, by which we extend Haskell’s type class mechanism to linear logic.
-
Thoughts on linear types and compilers
-
Comparing strict and lazy
Strict and lazy languages are often pitted against each other but rarely honestly compared. Let’s take a step back from the slogans and examine the trade-offs between lazy and strict. Not which is best: how they compare. — Most languages are strict. Haskell is very much the odd one out here. So it is not surprising that programmers in strict language sneer at Haskell’s laziness, nor that Haskell programmers feel compelled to defend this choice. But because of the adversarial nature of this debate, it ends up with cheap slogans such as “strict languages are more efficient”, “lazy languages compose better”. This doesn’t tend to be very enlightening. After all, the most likely answer, if maybe unsatisfactory is: it depends. The choice between strictness and laziness is, at the end of the day, as most things in engineering, a trade-off. And to make an informed choice between these two technologies, we need to know what the costs and benefit of each are. My goal, is to provide tools to make such an informed decision, by sharing, based on my experience as a programmer in both lazy languages and strict languages, strengths and weaknesses of both paradigm. If your looking for me to tell you which is best, you will be disappointed. But, on the plus side, there will definitely be some production horror stories.
-
Data vs Control: a tale of two functors
The Haskell base library features the Data and Control module hierarchies. The distinction between data and control is rooted deeply, in computer science: it can already be seen in Turing machines. However, when it comes to Haskell the difference between data and control can be quite muddled. A case in point is functors: there are functor type classes in both hierarchies: Functor and Traversable are in the Data hierarchy, while Applicative and Monad are in the Control hierarchy. This is really confusing! Do functors magically cease to be data and become control structure when I declare a Applicative instance? In this talk, I will show that there are indeed two kinds of functors, which I dub data functors, and control functors. Each fitting in the respective hierarchy. The catch is that you can't tell them apart in regular Haskell. However, with the new linear types extension, we can see them for what they really are. In fact, when programming with linear types, one typically needs both kinds. I'll be explaining a tiny bit of linear types, just enough to expose the two hierarchies for what they are.
-
Binding Types à la carte
Imagine you want to write a data type for an abstract syntax tree with binders. You get started, write a function for substitution. Get lost in the renaming story. Ok. You've heard about this de Bruijn index stuff. You get started. But you get lost again in the shifts and the lifts. Wouldn't it be nice if types could help you get all of this binder story right? After all, you're writing Haskell. Arnaud will present a way to do just that: it's like de Bruijn indices, but with types. It also makes it possible to extend types-with-binders piecewise in the same style as the data type à la carte. Interestingly α-equivalent terms are equal in this representation, which is nice if you want to store the terms in tables, or use memoisation. And it all uses algebra! After all, you're writing Haskell. This story involves functors of functors (not a typo), higher catamorphisms, and Generic1 instances (not a typo either), as well as a brand new feature from GHC 8.6: quantified constraint.
-
Implementing Linear Haskell
As the linear type proposal is underway, and the specifics of how linear types should be exposed in Haskell are being debated, you may wonder: but how is it implemented? Is it easy? Is it hard? Is it small? Is it big? As a GHC developer what would it change for me in practice? This talk will describe our implementation in progress of the linear type feature. How we changed the linear arrow constructor, how type checking is performed, what changes are necessary in Core to account for linearity, etc…
-
Functors which are not functors
The ML family of programming languages have, basically forever, come with a sweet module system (including functors which are not, well, functors, in the mathematical sense; no, seriously, they are completely unrelated, except for the name). I want to run you through a few feature of Ocaml's module system. This includes the aforementioned functors, first-class modules, as well as local namespace imports, which I really love. And why I miss them when I program in Haskell. I'll start with a typology of module and namespace systems. And we'll touch on how differently type-classes and ML functors solve the same problem.