Humans control computers by writing computer programs, which are
instructions written in artificial languages called programming
languages. Then, the computer does exactly what it was instructed,
regardless of whether or not the instructions made any sense. This is
precisely what makes computer programming very challenging: it is very
different from how humans give and receive instructions to each
other. We often give other humans vague or imprecise instructions,
trusting that our listeners have the intelligence and judgement to
determine what we should have said.
To make it easier to write computer programs, programming language
designers have turned to designing languages with type systems, which
are a set of rules for checking whether a program is self-consistent
before it is executed by a computer. The earliest type systems checked
simple consistency properties, such as checking whether every
multiplication operation in the program was written to multiply two
numbers (a typo might result in a number being multiplied by a date,
for example).
Modern languages can check much more intricate properties of programs,
such as ensuring that all the elements of a list have the same type,
or that no memory is leaked, whether or not a program has the desired
computational complexity, or even whether a program meets a mathematical
specification of its full desired behaviour.
These more elaborate checks can require the programmer to annotate a
progarm with information to guide the type checker, and for complex
properties, these annotations can sometimes be dozens of times the
length of the program itself. Sometimes, these annotations can be
helpful to a human reader reviewing the program, but very often they
are verbose, redundant and obscure the actual structure of the
computer program.
There are algorithms, called type inference algorithms, for eliding
the redundnant annotations and making the computer, rather than the
human, figure out what they should have been. Unfortunately, most such
algorithms are specialized to particular programming languages, which
makes it difficult to transfer ideas from one language to another --
and there are thousands of programming languages!
In the TypeFoundry project, we are working on devising new, general
classes of type inference algorithms, which language designers can use
"off-the-shelf" for their own programming language implementations.
We have targeted both simple type systems, as well as much more
elaborate ones. One of our major focuses, in fact, has been on
devising a very advanced type system to verify the correctness of the
pKVM hypervisor, a low-level component of the Linux operating system
kernel which is critical to the security of every Android phone.