"External interfaces" or "Interface maps"

KennyTM~ kennytm at gmail.com
Sat Oct 18 03:41:23 PDT 2008


Hxal wrote:
> =========================== External interfaces ===============================
> 
> The idea is to allow implementing an interface for a class, outside the
> class' definition. This is possible as I understand, because interfaces are
> "fat" pointers -- they consist of an object reference and the interfaces'
> vtable for the particular class, which is separate from the class' vtable.
> Therefore it should be possible to create an interface vtable outside
> the module that declares the class.
> 
> This would allow us to adapt classes to interfaces from different libraries.
> 
> Example:
> |	import foreign.io : ForeignFile = File;
> |
> |	import my.io : IFile;
> |
> |	interface IFile for ForeignFile

// I like the use of "for" :)

> |	{
> |		void open (args)
> |		{
> |			object.FancyNameForOpen (args);
> |			// typeof(this) == IFile
> |			// typeof(object) == ForeignFile
> |			// (cast(IFile) object) == this
> |			// I've used the name 'object', but that's really arbitrary,
> |			// it's just important that this variable was defined by the compiler
> |			// so that every method invocation didn't perform a dynamic cast

                         super.FancyNameForOpen(args); //?

> |		}
> |		
> |		/* et cetera */
> |	}
> |
> |	void example ()
> |	{
> |		IFile file = cast(IFile) new ForeignFile ();
> |	}
> 

But I wonder if you can do definition like this with a pure interface. I 
mean, is it possible to write a new function like:

interface IFile for ForeignFile {
     // suppose it is in IFile but can only be pretended in ForeignFile
     ulong fileLength (string filename) {
        object.open(filename);
        ulong len = 0;
        while (object.readByte())
          ++ len;
        object.close();
        return len;
     }

     // this contains no states
     void touch (string filename) {
        object.open(filename);
        object.close();
     }
}

? But then this is just equivalent to a wrapper class. I guess only 
existing functions can be mapped?

> Since supposedly D object/interface casts are always dynamic, there should be
> no problem with casting even if the cast site doesn't directly see the external
> interface declaration at compile time.
> 
> External interfaces should be equivalent to regular interface implementations
> in respect to the inheritance hierarchy, and should be freely intermixable.
> 
> AFAIK it's possible to implement, because the mapping of implemented interfaces
> can be built during runtime initialization.
> 
> Potential problems that need to be solved include:
> - Two external interface definitions for the same interface and class pair
>   in different modules; it'd be nice if the compiler could detect that,
>   but I'm not sure if it's at all possible
> 
> Advantages compared to wrapper classes:
> - No additional objects need to be allocated
> 
> Disadvantages compared to wrapper classes:
> - No additional state can be kept
> 
> ======================== Interfaces for other types ===========================
> 
> The same mechanism could be used to implement interfaces for pointers
> to arbitrary types (not for value types themselves, as the object field of
> the interface instance is restricted to pointer size).
> 
> This is would allow, among other things, to fake struct inheritance to a degree
> - although I'm not sure if that degree is satisfactory to proponents of that
> mechanism.
> Limitations:
> - Interface instances can only point to a struct, not contain it, therefore
>   when persistence of data outside the scope is required - heap allocation is
>   still unavoidable
> - Interface casts are dynamic and therefore introduce overhead that might not
>   appeal to people using structs for performance
> 
> If the cast to an interface was static, runtime overhead would be less, but
> problems with scoping arise. Example: external interface mappings for
> a template argument would not be visible inside the template, unless it
> imported the external interface.
> 
> Note that this feature would make casting an interface instance to Object
> virtually impossible (unless you're prepared for it to fail).
> I think it makes sense that an interface is a more abstract construct,
> and Object a more specific one.
> A "root" interface IAnything could be created that any interface or Object was
> castable to, where RTTI information would be kept in the vtable part of
> the interface. Every type that has an interace mapping would implicitly need to
> implement this interface.
> I'm not sure about the practicality of this solution, maybe it could be somehow
> united with TypeInfos. There surely is merit in wanting to have a root type
> that both objects and interfaces can be cast to.
> 
> ===
> 
> Anyway, I'll just leave this here.
> It's not a killer feature, but since it seems possible to implement it,
> I thought I'd write it up. In the future concept maps could mimic this
> mechanism at compile time.
> 



More information about the Digitalmars-d mailing list