Limitations on generics

Published on 2008-01-01
Tagged: compilers fenris

View All Posts

This entry was taken from my old Fenris development blog. Although the Fenris project is now defunct, I think these old entries have some general appeal, so I've added them to this blog.

When I first planned to add generics to Fenris, I had no idea how much complexity it would add to the type system and compiler. This is probably due to bad design, but even though it seems like a straightforward feature, there are a surprisingly high number of corner cases. In order to keep the project under control, I'll have to introduce some limitations.

The main thing right now is that recursive generics aren't allowed. These are useful in several special circumstances. For example, the Compareable interface in Java:

interface Compareable<T extends Compareable<T>>
{
    int compareTo( T x );
}

The reason for this is that the type Compareable<T> cannot be safely compiled before the generic parameters for the interface have been added to the environment. This gets more complicated for separate classes that depend on each other in this way.

The need for this may be mitigated by the self type I plan on introducing later (probably not this term), which indicates the current class. I think this would be useful for functional object oriented programming since many methods return a modified copy of the current object rather than causing side effects. These methods are guaranteed to return an object of the same class as the target object, so if we had a self type, we could reduce downcasting when these methods are used on subclasses. However, this would not help with Compareable or binary methods in general since self would not be contravariant.

Speaking on contravariance, Fenris no longer supports it, at least for now. I was reworking the inheritance system last week when I realized that allowing contravariant parameters in overriding methods creates an ambiguity. A method could possibly override multiple methods from superclasses with sufficiently widened parameter types. C++ allows this, and it works as you would expect. Java prohibits this. Eventually we will change to the C++ approach I think.

The other main limitation right now is the inability to create generic arrays (those whose element type is a variable type). This is mainly due to time constraints at this point. Java disallows these for some reason. At first I thought it was because you don't know the size of a generic object, but since you are just creating an array of pointers and not the elements inside it, there should be no problem.