What's a pity _interface_ is a keyword so it can't be used for declaring interfaces.
Interfaces can become particularly handy if used as a result type, it seems to me. Either way, it would be great to provide interface inheritance: createInterface HealthGenerator: proc genHealth(g: HealthGenerator): Health createInterface EnergyGenerator: proc genEnergy(g: EnergyGenerator): Energy createInterface BeautyGenerator of HealthGenerator, EnergyGenerator: proc genBeauty(g: BeautyGenerator): Beauty type Pear = ... proc genHealth(g: Pear): Health = ... proc genEnergy(g: Pear): Energy = ... proc genBeauty(g: Pear): Beauty = ... let pear = Pear(...) let beautifier: BeautyGenerator = pear # vtable's pointer points at p echo beautifier.genEnergy() echo beautifier.genHealth() echo beautifier.genBeauty() let energiser: EnergyGenerator = beautifier # new vtable's pointer still points at p echo energiser.genEnergy() #echo energiser.genHealth() # but has other procedure pointers #let other: BeautyGenerator = energiser # so the information is lost Making the converter interfaces-aware so that vtables aren't pointed but partially copied sounds easy as all the converter has to do is: * recognize the argument as an interface (interfaces inheriting from common type, easy) * check if all of the input interface's subroutines are present in the output interface A simple compile-time procedure returning bool value is all the converter needs. A runtime time label for interfaces sounds like an interesting idea but let's see what happens when we provide them: let pear = Pear(...) beautifier: BeautyGenerator = pear energiser: EnergyGenerator = beautifier other: BeautyGenerator = energiser.getType() if beautifier.realType of Pear: pearLover.eat(cast[ptr Pear](beautifier.obj)[]) getType() can't return the real type but a mere label. Still, if it can be used to retrieve the full type through a pointer cast, why not convert it to another (possibly wider) interface? proc burn(g: EnergyGenerator): Energy = result = g.genEnergy() if g.getType of SmokeGenerator: toSmokeGenerator(g).genSmoke() Well, it looks good, right? Well, it does if we forgot about memory usage. Notice that if any cast between the label and an interface label's type fulfils is valid at runtime, then it means all the subroutine pointers for that type must reside in memory. Not so funny if using a "popular" type. Which is why it sounds more reasonable to either not provide any type label at all or provide it only for explicit type casts, NOT conversions to other interfaces, which isn't obvious and may be confusing for some users if type-switch or similar transparent real-type-getters will be available.