"External interfaces" or "Interface maps"

Hxal Hxal at freenode.irc
Fri Oct 17 11:06:41 PDT 2008


=========================== 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
|	{
|		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
|		}
|		
|		/* et cetera */
|	}
|
|	void example ()
|	{
|		IFile file = cast(IFile) new ForeignFile ();
|	}

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