Type Systems for Programming Languages

Course Information

Lecturer: Steffen van Bakel

Lecture time:


You can find the notes as used in the course in the following file:

The notes


Assessed Course Work:

To appear.


The course uses type theory to study design and verification of programs and programming languages. It uses general techniques that are common to many areas in theoretical computer science.

Although the topic of the course sits within the area of theoretical computer science, the course itself does not intend to focus on theoretical aspects. Rather, it aims to focus on design, to show how to set up a formal system; proofs of properties are only shown as illustration. As such, the course introduces students into formalized systems, and the focus of attention is on presentation of a couple of existing approaches. New systems and languages will be introduced, but these will serve mainly to set the context of the course.

Over the past years, this course attracted a small number of students, facilitating a friendly and highly interactive way of teaching. The chosen format for the lectures is that with an integrated tutorial, which allows for focussing on exercises and particular problems, as well as detailed discussions with the student group on the 'why' and 'how' of what appears during the course.

Past students have highly appreciated the course, and did very well in the exam.


The aim of this course is to lay out in detail the design of type assignment systems for (functional) programming languages and focus on the importance of a sound theoretical framework, in order to be able to reason about the properties of a typed program. Students will study and compare a variety of systems and languages.


None; students who have taken Semantics in the second year will have seen the techniques used in the course.


The course sets of with the presentation of the Lambda Calculus, on which most functional languages are based. We will introduce the Curry Type Assignment System for this calculus, for which we show that

We will show how to extend the language and the system of types in order to deal with Polymorphism. To this end, Combinator Systems are introduced as a slight extension of LC. In order to study how to deal with Recursion, the language of CS is extended to allow for recursive definitions, and we will discuss ways of typing this extension. We will then look at Milner's basic ML system, and show that, in this calculus, a solution is present for all the issues discussed separately before.

A disadvantage of ML is that it is, syntactically, very distant from actual programming languages, and it is not easy to see that all properties shown for ML translate to the 'real' languages. In particular, definitions of functions by 'cases' (Pattern Matching) are not present in ML. In order to come to a formal notion of types that relates more closely to actual programming languages, we introduce Term Rewriting Systems, which are much closer to actual programs, and show that we can obtain much of the desired properties.

We will look at abstract data types and recursive types, and compare and confront the various approaches that exist.

To conclude, we will have a brief visit to Haskell's type system; we will see that all issues discussed before return here; we will look at type aspects of how Haskell deals with errors, and I/O, and discuss classes and monads.