Limitations on generics
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.