Dynamic types and virtual inner types

The concept based polymorphism I tried to explain in my previous post can be more conveniently expressed with another syntax which avoids concepts at all.

The key observation is that runtime polymorphism and F-bounded polymorphism are very similar in nature, and, to some extent, the latter can be implemented using the former. If I have understood correctly, that is exactly how the Java virtual machine implements generics.

For example, suppose you have an abstract class Shape with a virtual function draw, and several concrete classes like Square, Circle, Triangle, which override draw.
Client code using runtime polymorphism would look like:

Using the generic code in such situations should probably be considered a mistake, because if one wants to use template based polymorphism, defining the abstract class Shape is pointless. It would be better to directly define a ShapeConcept having a member function draw.

However, the example suggests that a syntax resembling templates could be used to express runtime polymorphism:

template <Shape! S>
void render(S* s)
{
s->draw();
}

the idea being that S is the runtime type of s. The compiler could instantiate the template immediately and implement the body just like a Shape pointer were used instead of S. Here S is not really a type, since for example expressions like

new S

should be rejected; let’s call things like Sdynamic types. They behave much like incomplete types (cannot be instantiated directy, sizeof cannot be called on them), but are a different beast: for the purpose of typechecking they are just subtypes of their parent concept (Shape, in this example), but for code generation they are considered equivalent to it.

Why could all of this syntax be possibly useful? Well, when using ordinary abstract classes, it does not really add anything to the language, but it shows its power when another (more than syntactical) extension is introduced: virtual inner types.

Just like the name suggests, virtual inner types are inner types which behave polymorphically. The typical (and motivating) example here is still that of the abstract factory. So suppose you have the following abstract factory:

As explained in my previous posts [1] [2], there’s no way to explain to the compiler that the Food that an animal is able to eat is only that created by the same factory which created that very animal.
Virtual inner types could be used to solve the problem:

The idea is that virtual typedef Base X forces inherited class to define an inner type X inheriting from Base. Furthermore, this type behaves polymorphically (the type itself, not only instances!). That means that if A is a dynamic type with parent AbstractAnimal, then A::Factory is the correct dynamic type with parent AbstractFactory.

notice that we have defined inner types corresponding to the virtual typedefs of parent classes. Besides, the argument to eat is Grass and not AbstractFood.
Client code, in fact, cannot simply pass an AbstractFood object to the eat member function. The following function should not compile:

expressing the fact that both animal and food come from the same factory of dynamic type Factory. The food parameter (actually stored in an AbstractFood variable), is statically downcasted to Grass before being passed to the eat member function. The static typechecking via dynamic types ensures that such a downcast is always safe, so there is no need to perform a dynamic cast.

These ideas for a language extension are essentially equivalent to the ones expressed in the previous post, but seem to require less drastic changes in compiler implementations. Furthermore, they don’t use concepts, so it could be even implemented on top of the existing gcc.