A useful pattern in dependently typed programming is to define a state transition system, for example the states and operations in a network protocol, as a parameterised monad. We index each operation by its input and output states, thus guaranteeing that operations satisfy pre- and post-conditions, by typechecking. However, what if we want to write a program using several systems at once? What if we want to define a high level state transition system, such as a network application protocol, in terms of lower level states, such as network sockets and mutable variables? In this paper, I present an architecture for dependently typed applications based on a hierarchy of state transition systems, implemented as a library called

`states`

. Using`states`

, I show: how to implement a state transition system as a dependent type, with type level guarantees on its operations; how to account for operations which could fail; how to combine state transition systems into a larger system; and, how to implement larger systems as a hierarchy of state transition systems. As an example, I implement a simple high level network application protocol.

Comments welcome! You can get the draft here.

]]>

Many programming languages and proof assistants are defined by elaboration from a high-level language with a great deal of implicit information to a highly explicit core language. In many advanced languages, these elaboration facilities contain powerful tools for program construction, but these tools are rarely designed to be repurposed by users. We describe

elaborator reflection, a paradigm for metaprogramming in which the elaboration machinery is made directly available to metaprograms, as well as a concrete realization of elaborator reflection in Idris, a functional language with full dependent types. We demonstrate the applicability of Idris’s reflected elaboration framework to a number of realistic problems, we discuss the motivation for the specific features of its design, and we explore the broader meaning of elaborator reflection as it can relate to other languages.

You can get the PDF here.

]]>

Modern software is often designed to run on a virtual machine, such as the JVM or .NET’s CLR. Increasingly, even the web browser is considered a target platform with the Javascript engine as its virtual machine. The choice of programming language for a project is therefore restricted to the languages which target the desired platform. As a result, an important consideration for a programming language designer is the platform to be targetted. For a language to be truly cross-platform, it must not only support different operating systems (e.g. Windows, OSX and Linux) but it must also target different virtual machine environments such as JVM, .NET, Javascript and others. In this paper, I describe how this problem is addressed in the Idris programming language. The overall compilation process involves a number of intermediate representations and Idris exposes an interface to each of these representations, allowing back ends for different target platforms to decide which is most appropriate. I show how to use these representations to retarget Idris for multiple platforms, and further show how to build a generic foreign function interface supporting multiple platforms.

Constructive comments and suggestions are welcome, particularly if you’ve tried implementing a code generator for Idris.

]]>

Full-spectrum dependently typed languages and tools, such as Idris and Agda, have recently been gaining interest due to the expressive power of their type systems, in particular their ability to describe precise properties of programs which can be verified by type checking.

With full-spectrum dependent types, we can treat types as first- class language constructs: types can be parameterised on values, and types can be computed like any other value. However, this power brings new challenges when compiling to executable code. Without special treatment, values which exist only for compile-time checking may leak into compiled code, even in relatively simple cases. Previous attempts to tackle the problem are unsatisfying in that they either fail to erase all irrelevant information, require user annotation or in some other way restrict the expressive power of the language.

In this paper, we present a new erasure mechanism based on whole-program analysis, currently implemented in the Idris programming language. We give some simple examples of dependently typed functional programs with compile-time guarantees of their properties, but for which existing erasure techniques fall short. We then describe our new analysis method and show that with it, erasure can lead to asymptotically faster code thanks to the ability to erase not only proofs but also indices.

Comments, feedback, questions, etc, all welcome!

]]>

There has been significant interest in recent months in finding new ways to implement composable and modular effectful programs using

handlers of algebraic effects. In my own previous work, I have shown how an algebraic effect system (called “`effects`

“) can be embedded directly in a dependently typed host language. Using dependent types ought to allow precise reasoning about programs; however, the reasoning capabilities of`effects`

have been limited to simple state transitions which are known at compile-time. In this paper, I show how`effects`

can be extended to support reasoning in the presence ofrun-timestate transitions, where the result may depend on run-time information about resource usage (e.g. whether opening a file succeeded). I show how this can be used to build expressive APIs, and to specify and verify the behaviour of interactive, stateful programs. I illustrate the technique using a file handling API, and an interactive game.

I’ve just submitted this, although constructive comments and suggestions are still of course very welcome!

]]>

Dependently-typed languages allow precise types to be used during development, facilitating reasoning about programs. However, stronger types bring a disadvantage that it becomes increasingly difficult to write programs that are accepted by a type checker and additional proofs may have to be specified by a programmer.

Embedded domain-specific languages (EDSLs) can help address this problem by introducing a layer of abstraction over more precise underlying types, allowing domain-specific code to be written in a high-level language which uses dependent types to enforce invariants without imposing additional proof obligations on an application programmer.

In this paper, we apply this technique to web programming. Using the dependently typed programming language Idris, we introduce an EDSL to facilitate the creation and handling of statically checked web forms, reducing the scope for programmer error and attacks such as SQL injection. We also show how to enforce resource usage protocols associated with common web operations such as CGI, database access and session handling.

You can find the accepted draft here. A revised version will appear later.

]]>

Assuming you have an up-to-date Idris installed, install the vim Idris mode. This mode allows vim to communicate with a running Idris REPL instance. It provides the following basic commands:

`\t`

displays the type of the name under the cursor (or a bit more information about its context if it happens to be a metavariable)`\e`

prompts for an expression to evaluate`\r`

reloads and typechecks the file in the current buffer

More interestingly, it provides support for interactive editing:

`\c`

, if the cursor is over a variable in a pattern match clause, splits that variable into all the patterns which are well typed. This also works in`case`

expressions.`\w`

, if the cursor is over a pattern clause of the form`f x y z = ?rhs`

creates a new`with`

clause, i.e. the clause becomes:f x y z with (_) f x y z | with_pat = ?rhs

`\d`

, if the cursor is in a top level function type declaration (right of the`:`

), creates a new clause for that function.

(With all of these, the `\`

(backslash) is your local leader key. I have this rebound to `,`

(comma) but `\`

is the default.)

For example, start up `idris vadd.idr`

(this will create the file if it doesn’t already exist) edit it with `:e`

and type the following:

module vadd vadd : Num a => Vect n a -> Vect n a -> Vect n a

Press ESC, and before moving the cursor anywhere, hit `\d`

. You should see:

module vadd vadd : Num a => Vect n a -> Vect n a -> Vect n a vadd x1 x2 = ?vadd_rhs

Now move the cursor over `x1`

and hit `\c`

to split `x1`

into patterns for `[]`

and `::`

. You should see:

module vadd vadd : Num a => Vect n a -> Vect n a -> Vect n a vadd [] x2 = ?vadd_rhs_1 vadd (_ :: _) x2 = ?vadd_rhs_2

Note that it hasn’t attempted to invent any names for the patterns. This is because I have decided that making no choice is better than making a bad choice! We can type some in ourselves…

module vadd vadd : Num a => Vect n a -> Vect n a -> Vect n a vadd [] x2 = ?vadd_rhs_1 vadd (x :: xs) x2 = ?vadd_rhs_2

Now do the same over the first `x2`

. Move the cursor over it and hit `\c`

. You should see:

module vadd vadd : Num a => Vect n a -> Vect n a -> Vect n a vadd [] [] = ?vadd_rhs_3 vadd (x :: xs) x2 = ?vadd_rhs_2

Note that this has only produced one new pattern, because `vadd [] (_ :: _)`

would not be well typed. Finally, over the remaining `x2`

:

module vadd vadd : Num a => Vect n a -> Vect n a -> Vect n a vadd [] [] = ?vadd_rhs_3 vadd (x :: xs) (_ :: _) = ?vadd_rhs_1

If you move the cursor over the metavariable `?vadd_rhs_1`

and hit `\t`

, you will see the context and the required type of `?vadd_rhs_1`

:

a : Type c : Num a n : Nat x : a xs : Vect n a _ : a _ : Vect n a -------------------------------------- vadd_rhs_1 : Vect (S n) a

The interactive mode will work with any file in the working directory of your REPL instance, so you can edit multiple files at once.

`with`

ruleLet’s try completing the following definition, in a module `elem.idr`

:

module elem import Decidable.Equality using (xs : List a) data Elem : a -> List a -> Type where Here : Elem x (x :: xs) There : Elem x xs -> Elem x (y :: xs) isElem : (x : Nat) -> (xs : List Nat) -> Maybe (Elem x xs)

As before, get a clause for `isElem`

by hitting `\d`

somewhere after the `:`

on the line with `isElem`

. You’ll see

isElem : (x : Nat) -> (xs : List Nat) -> Maybe (Elem x xs) isElem x xs = ?isElem_rhs

Now expand `xs`

using `\c`

and give the pattern variables names:

isElem : (x : Nat) -> (xs : List Nat) -> Maybe (Elem x xs) isElem x [] = ?isElem_rhs_1 isElem x (y :: ys) = ?isElem_rhs_2

We’ll leave the `[]`

case for now and concentrate on the `y :: ys`

case. We’ll do this by attempting to build a proof that `x = y`

using

decEq : DecEq t => (x1 : t) -> (x2 : t) -> Dec (x1 = x2)

(This is why we imported `Decidable.Equality`

.) Move to the line with the `y :: ys`

case and hit `\w`

. This gives:

isElem : (x : Nat) -> (xs : List Nat) -> Maybe (Elem x xs) isElem x [] = ?isElem_rhs_1 isElem x (y :: ys) with (_) isElem x (y :: ys) | with_pat = ?isElem_rhs

The cursor is conveniently in the `with`

argument. Change that to `decEq x y`

, move the cursor over `with_pat`

and hit `\c`

again to split `with_pat`

:

isElem : (x : Nat) -> (xs : List Nat) -> Maybe (Elem x xs) isElem x [] = ?isElem_rhs_1 isElem x (y :: ys) with (decEq x y) isElem x (y :: ys) | (Yes _) = ?isElem_rhs_2 isElem x (y :: ys) | (No _) = ?isElem_rhs_3

The `Yes`

case’s parameter is a proof that `x = y`

. We’ll need to match on this to get a canonical proof. Change it to `Yes p`

, and case split `p`

. You’ll get:

isElem : (x : Nat) -> (xs : List Nat) -> Maybe (Elem x xs) isElem x [] = ?isElem_rhs_1 isElem x (y :: ys) with (decEq x y) isElem x (x :: ys) | (Yes refl) = ?isElem_rhs_4 isElem x (y :: ys) | (No _) = ?isElem_rhs_3

Now that you have the canonical proof, the left hand side has been updated so that `x`

and `y`

are unified to `x`

. I’ll leave the rest of this definition as an exercise — remember to use `\t`

to check the types of `isElem_rhs_3`

and `isElem_rhs_4`

.

When an Idris REPL starts, it also starts up a server running on port 4294 your local machine, responding to requests from a REPL client. This can be queried using the `--client`

flag to Idris. For example, from the shell:

$ idris --client '2+2' 4 : Integer $ idris --client 'vadd [1,2,3] [4,5,6]' [5,7,9] : Vect 3 Integer $ idris --client ':t vadd' vadd.vadd : Num a => (Vect n a) -> (Vect n a) -> Vect n a

Therefore, if the REPL provides appropriate commands for editing a file in place, all an editor has to do is invoke it and reload the file. The REPL now provides:

`:casesplit [line] [name]`

, abbreviated`:cs`

which displays the cases resulting when the variable`[name]`

on line`[line]`

is split, e.g.$ idris --client ':cs 4 x1' vadd [] x2 = ?vadd_rhs_1 vadd (_ :: _) x2 = ?vadd_rhs_2

There is also a destructive version

`:cs!`

which is the same, but updates the source file.`:addclause [line] [name]`

, abbreviated`:ac`

which displays a clause suitable for the function declaration for`[name]`

on line`[line]`

. Similarly,`:ac!`

updates the source file.`:makewith [line] [name]`

, abbreviated`:mw`

which adds a`with`

clause for the definition of`[name]`

on line`[line]`

. Again,`:mw!`

updates the source file.

The vim script is simply a thin wrapper for these functions. It also uses the REPL to invoke the evaluator, and to call `:r`

for quickly type checking a buffer.

Enjoy! If you prefer to use another editor, please consider contributing a similar script to support interactive development in your own editor. More features are planned, in particular automatically solving metavariables where possible.

]]>

Sequential decision problems, dependently typed solutions

Nicola Botta, Cezar Ionescu, Edwin Brady

We propose a dependently typed formalization for a simple class of sequential decision problems. For this class of problems, we implement a generic version of Bellman’s backwards induction algorithm and a machine checkable proof that the proposed implementation is correct. The formalization is generic. It is presented in Idris, but it can be easily translated to other dependently-typed programming languages. We conclude with an informal discussion of the problems we have faced in extending the formalization to generic monadic sequential decision problems.

You can find the full paper here.

]]>

Programming and Reasoning with Algebraic Effects and Dependent Types,

Edwin Brady

One often cited benefit of pure functional programming is that pure code is easier to test and reason about, both formally and informally. However, in order to be useful, programs must interact with the outside world. Haskell solves this problem using monads to capture details of possibly side effecting computations — it provides monads for capturing State, I/O, exceptions, non-determinism, libraries for practical purposes such as CGI and parsing, and many others, as well as monad transformers for combining multiple effects.

Unfortunately, useful as monads are, they do not compose very well. Monad transformers can quickly become unwieldy when there are lots of effects to manage, leading to a temptation in larger programs to combine everything into one coarse-grained state and exception monad. In this paper I describe an alternative approach based on handling algebraic effects, implemented in the Idris programming language. I show how to describe side effecting computations, how to write programs which compose multiple fine-grained effects, and how, using dependent types, we can use this approach to reason about states in effectful programs.

You can find the draft here. As usual, comments are very welcome.

]]>

- Lecture 1, Introduction, slides, video
- Lecture 2, Embedded DSLs, slides, video
- Lecture 3, Effect management, slides, video
- Lecture 4, Implementing Idris, slides, video
- Example code
- Exercises
- Idris web page

]]>