www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - interface reference not compatible to Object?

reply "Frank Benoit (keinfarbton)" <benoit tionex.removethispart.de> writes:
interface I{
    void func();
}
class C : I {
    void func(){
    }
}
void main(){
    C c = new C;
    c.toHash(); // from class Object
    I i = c;
    i.toHash(); // line 14
}
/////////////////////////////
t.d(14): no property 'toHash' for type 't.I'
t.d(14): function expected before (), not 1 of type int


Is this the intended behaviour? If *every* object in D is a Object, then
every interface reference refers to an Object also. This said, the above
should compile?
Oct 21 2006
next sibling parent reply Alexander Panek <a.panek brainsware.org> writes:
As already said in #d, this one compiles:

interface IObject {
    void print();
    char[] toString();
    hash_t toHash();
    int opCmp(Object o);
    int opEquals(Object o);
}

interface I : IObject {
    void func();
}

class C : I {
    void func(){
    }
}

void main(){
    C c = new C;
    c.toHash();
    I i = c;
    i.toHash();
}

..without given errors. Might be an option to add it into object.d or
such.

Best regards,
Alex

On Sat, 2006-10-21 at 11:44 +0200, Frank Benoit (keinfarbton) wrote:
 interface I{
     void func();
 }
 class C : I {
     void func(){
     }
 }
 void main(){
     C c = new C;
     c.toHash(); // from class Object
     I i = c;
     i.toHash(); // line 14
 }
 /////////////////////////////
 t.d(14): no property 'toHash' for type 't.I'
 t.d(14): function expected before (), not 1 of type int
 
 
 Is this the intended behaviour? If *every* object in D is a Object, then
 every interface reference refers to an Object also. This said, the above
 should compile?

Oct 21 2006
parent reply "Frank Benoit (keinfarbton)" <benoit tionex.removethispart.de> writes:
 Is this the intended behaviour? If *every* object in D is a Object, then
 every interface reference refers to an Object also. This said, the above
 should compile?


And as already said in #d : I wonder why this even compiles. Why is C not enforced to "reimplement" the methods from IObject? Wouldn't it be consistent if the compiler implicitly inherit all interfaces without a super-interface from this IObject?
Oct 21 2006
parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Frank Benoit (keinfarbton) wrote:
 Is this the intended behaviour? If *every* object in D is a Object, then
 every interface reference refers to an Object also. This said, the above
 should compile?


And as already said in #d : I wonder why this even compiles. Why is C not enforced to "reimplement" the methods from IObject?

I guess because the interface only requires the methods to be implemented, but allows them to be implemented in a base class as well as the class itself.
 Wouldn't it be consistent if the compiler implicitly inherit all
 interfaces without a super-interface from this IObject?

Maybe Object itself as well? That way functions can accept any object (whether referenced by class or interface) as an IObject. Though I would prefer it if all interface references would just be implicitly convertible to Object. Java does this, IIRC.
Oct 21 2006
next sibling parent =?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= <jmjmak utu.fi.invalid> writes:
Frits van Bommel wrote:
 Frank Benoit (keinfarbton) wrote:
 Wouldn't it be consistent if the compiler implicitly inherit all
 interfaces without a super-interface from this IObject?

Maybe Object itself as well? That way functions can accept any object (whether referenced by class or interface) as an IObject. Though I would prefer it if all interface references would just be implicitly convertible to Object. Java does this, IIRC.

AFAIK it's the basis for developing high level software architectures in languages that lack multiple inheritance of objects but allow multiple inheritance of interfaces, e.g. Java. It's pretty cool that someone came up with this in #d, but seriously irc is not the best place for documenting things. This information should be in the official documentation. The official documentation clearly tells how you can write classes that implement interfaces and that the compiler bugs you, if the class does not implement all abstract methods. This is very good, but the documentation is dead silent about dereferencing objects via interfaces. I guess it's because Walter is mainly a C++ guy and does not yet understand how interfaces work in Java. D has the same mechanism for interfaces as Java does. Why then should interfaces in D work like they work in C++, i.e. they do not work because C++ does not have any interfaces!
Oct 21 2006
prev sibling parent reply Max Samuha <maxter i.com.ua> writes:
On Sat, 21 Oct 2006 15:11:59 +0200, Frits van Bommel
<fvbommel REMwOVExCAPSs.nl> wrote:

Frank Benoit (keinfarbton) wrote:
 Is this the intended behaviour? If *every* object in D is a Object, then
 every interface reference refers to an Object also. This said, the above
 should compile?


And as already said in #d : I wonder why this even compiles. Why is C not enforced to "reimplement" the methods from IObject?

I guess because the interface only requires the methods to be implemented, but allows them to be implemented in a base class as well as the class itself.
 Wouldn't it be consistent if the compiler implicitly inherit all
 interfaces without a super-interface from this IObject?

Maybe Object itself as well? That way functions can accept any object (whether referenced by class or interface) as an IObject. Though I would prefer it if all interface references would just be implicitly convertible to Object. Java does this, IIRC.

The problem is that not all objects in D are D objects. An interface may be a com interface that cannot be cast to Object or inherit from IObject. It was discussed somewhere in the NG, IIRC
Oct 21 2006
parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Max Samuha wrote:
 On Sat, 21 Oct 2006 15:11:59 +0200, Frits van Bommel
 <fvbommel REMwOVExCAPSs.nl> wrote:
 
 Frank Benoit (keinfarbton) wrote:
 Wouldn't it be consistent if the compiler implicitly inherit all
 interfaces without a super-interface from this IObject?

That way functions can accept any object (whether referenced by class or interface) as an IObject. Though I would prefer it if all interface references would just be implicitly convertible to Object. Java does this, IIRC.

The problem is that not all objects in D are D objects. An interface may be a com interface that cannot be cast to Object or inherit from IObject. It was discussed somewhere in the NG, IIRC

Can non-COM interfaces be implemented by COM objects? (I'm pretty sure they at least can't be implemented by non-d objects, so does it matter?) Since whether an interface is a COM interface can easily determined (they inherit from std.c.windows.com.IUnknown) can't we at least make it so that all non-COM interfaces are convertible to Object?
Oct 21 2006
parent Max Samuha <maxter i.com.ua> writes:
On Sat, 21 Oct 2006 21:54:03 +0200, Frits van Bommel
<fvbommel REMwOVExCAPSs.nl> wrote:

Max Samuha wrote:
 On Sat, 21 Oct 2006 15:11:59 +0200, Frits van Bommel
 <fvbommel REMwOVExCAPSs.nl> wrote:
 
 Frank Benoit (keinfarbton) wrote:
 Wouldn't it be consistent if the compiler implicitly inherit all
 interfaces without a super-interface from this IObject?

That way functions can accept any object (whether referenced by class or interface) as an IObject. Though I would prefer it if all interface references would just be implicitly convertible to Object. Java does this, IIRC.

The problem is that not all objects in D are D objects. An interface may be a com interface that cannot be cast to Object or inherit from IObject. It was discussed somewhere in the NG, IIRC

Can non-COM interfaces be implemented by COM objects? (I'm pretty sure they at least can't be implemented by non-d objects, so does it matter?)

Since whether an interface is a COM interface can easily determined 
(they inherit from std.c.windows.com.IUnknown) can't we at least make it 
so that all non-COM interfaces are convertible to Object?

One more special case rule in the language. Though I wouldn't mind if it was there.
Oct 23 2006
prev sibling next sibling parent reply Walter Bright <newshound digitalmars.com> writes:
Frank Benoit (keinfarbton) wrote:
 interface I{
     void func();
 }
 class C : I {
     void func(){
     }
 }
 void main(){
     C c = new C;
     c.toHash(); // from class Object
     I i = c;
     i.toHash(); // line 14
 }
 /////////////////////////////
 t.d(14): no property 'toHash' for type 't.I'
 t.d(14): function expected before (), not 1 of type int
 
 
 Is this the intended behaviour? If *every* object in D is a Object, then
 every interface reference refers to an Object also.
 This said, the above should compile?

Replace: i.toHash(); with: (cast(Object)i).toHash(); and it will work, *provided* that i is actually an instance of an Object. If it is not, for example if it came from some COM DLL, the cast will fail.
Oct 21 2006
parent reply =?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= <jmjmak utu.fi.invalid> writes:
Walter Bright wrote:
 Frank Benoit (keinfarbton) wrote:
 Is this the intended behaviour? If *every* object in D is a Object, then
 every interface reference refers to an Object also.
 This said, the above should compile?

Replace: i.toHash(); with: (cast(Object)i).toHash(); and it will work, *provided* that i is actually an instance of an Object. If it is not, for example if it came from some COM DLL, the cast will fail.

Is there much hope that the compiler will make the cast implicitly in the future releases?
Oct 22 2006
parent reply Lionello Lunesu <lio lunesu.remove.com> writes:
Jari-Matti Mäkelä wrote:
 Walter Bright wrote:
 Frank Benoit (keinfarbton) wrote:
 Is this the intended behaviour? If *every* object in D is a Object, then
 every interface reference refers to an Object also.
 This said, the above should compile?

i.toHash(); with: (cast(Object)i).toHash(); and it will work, *provided* that i is actually an instance of an Object. If it is not, for example if it came from some COM DLL, the cast will fail.

Is there much hope that the compiler will make the cast implicitly in the future releases?

An interface's vftbl doesn't have toString and others. It does however have some RTTI which means a (dynamic_) cast can be used to find the pointer to the Object class, but only if it is part of an Object. This information is only available at run-time. It should not be implicit, since it might not succeed. L.
Oct 23 2006
parent =?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= <jmjmak utu.fi.invalid> writes:
Lionello Lunesu wrote:
 Jari-Matti Mäkelä wrote:
 Walter Bright wrote:
 Frank Benoit (keinfarbton) wrote:
 Is this the intended behaviour? If *every* object in D is a Object,
 then
 every interface reference refers to an Object also.
 This said, the above should compile?

i.toHash(); with: (cast(Object)i).toHash(); and it will work, *provided* that i is actually an instance of an Object. If it is not, for example if it came from some COM DLL, the cast will fail.

Is there much hope that the compiler will make the cast implicitly in the future releases?

An interface's vftbl doesn't have toString and others. It does however have some RTTI which means a (dynamic_) cast can be used to find the pointer to the Object class, but only if it is part of an Object. This information is only available at run-time. It should not be implicit, since it might not succeed.

Yeah, I know that. But from a *nix users point of view this is annoying. As there are no COM-objects available, basically everything is an Object. Some consider that explicit typecast is an ugly hack. Java wins D here 10-0. If I make programs with 50+ classes/interfaces, I have to write at least 200 of those typecasts. Still I cannot get any speed advantage over Java since it caches the lookups. Since D syntax does not distinguish between interfaces and classes when implementing/extending: interface b; class c; class a : b, c versus interface b class c class a implements b extends c it becomes hard to look for correct signatures. Basically I have to print the signatures to paper, recursively grep the source tree or compile every now and then, fix something and try again since there are no good IDE's for D with syntax checking. Ok, I might need to write 30% less lines with D but it takes 400% more time to figure out those types :(
Oct 23 2006
prev sibling parent BCS <BCS pathlink.com> writes:
Frank Benoit (keinfarbton) wrote:
 
 Is this the intended behaviour? If *every* object in D is a Object, then
 every interface reference refers to an Object also. This said, the above
 should compile?

I wouldn't count on that. I for some time have been wanting D to allow an interface to be formed any were you can form a delegate. This would include structs, functions, literals and who only knowns what else. If you look at an interface as a collection of methods and enough data to give them a context, then above is not to difficult to imagine.
Oct 23 2006