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.

Reply via email to