I have recently come to realize that a number of problems I had a few years ago trying to implement various mathematical theories in Java came down to the fact that the typing system in Java is not sufficiently strong to model all of Martin-Löf dependent type theory.
Prior to Java 5 and generics, the only type theory you could do was through classes and interfaces, which give you arbitrary types built out of the ground types int
,double
,char
and so on using product and function types. You can also build recursive types such as List
s, though not in a uniform way.
Using generics, you can do a bit more. You can now define List<T>
as a function
$$
\DeclareMathOperator{\Type}{Type}\Type\to\Type
$$
and so we get higher order types.
This is not the end of the story, though. Using a generics trick, we can model some dependent product types. For example, we can define types of the form $$ \prod_{T\colon\Type}f(T) $$ using the syntax
public interface f<T extends f<T>>
{
// We can now refer to T as much as we like
// inside the class. T has type f<T>.
}
As an example, we can model the basic underlying structure of a monoid (but not the associativity and unitality conditions) using a term of type $$ \prod_{T\colon\Type}T\times (T\to T\to T) $$ (i.e., a set $T$ with a designated unit element and a binary operation on $T$). Using Java generics, we can model this type:
public interface MonoidElement<T extends MonoidElement<T>>
{
public T unit();
public T mul(T op1, T op2);
}
However, when we try to model more complicated concepts, the type theory breaks down.
Is there a simple description of the fragment of MLTT corresponding to the types that can be built in the Java typing system?