"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