www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - interfaces

reply xs0 <xs0 xs0.com> writes:
I've been porting some Java to D lately, and was surprised how much more 
complicated interfaces are to use in D than in Java. Specifically:

- an interface reference is not implicitly castable to Object. why? 
every interface implementation is obviously an Object..

- casting Interface[] to Object[] or vice-versa doesn't work. There's 
even no error, neither compile-time nor run-time, it just doesn't work 
(ok, in some cases a crash probably occurs, but it in my case, the only 
thing that happened was that the name of the class was outputted on the 
console, don't ask me why :)

I believe this will be a serious WTF? for many Java programmers, and, 
more importantly, Java's handling of interfaces is better. For example, 
in Java you can simply decide that Foo will no longer be a class, but an 
interface, and except instantiation, practically no code needs to be 
changed. This is not the case in D.

One solution could be the following:

- interface arrays become arrays of objptrs, not ifaceptrs
- when writing to such arrays, the object pointer is written
- when reading from such arrays, an implicit dynamic cast is done
- casting to/from void* also uses the objptr
- any interface reference becomes implicitly castable to Object

And the consequences would be the following:
- increased type safety
- possibility of casting between object and interface arrays
- no need to explicitly cast to Object
- potentially significant slowdown because of the need to continually 
dynamically cast all (or in case of optimized code, many) members of 
interface arrays

It should be noted that the slowdown would only apply to arrays, not 
single references, which I'd say are significantly more common, except 
in containers. Additionally, if the compiler made some effort, it could 
determine cases where there is no need to cast back and forth, for 
example in containers that do not expose their private arrays. Finally, 
interfaces could receive virtual member types, which would equal the 
interfaces themselves, with two important differences - assigning to an 
array/pointer of such would not convert the reference to objptr 
(bringing efficiency to what it is now), and, these arrays/pointers 
would not be castable to anything different at all, except maybe their 
superinterface counterparts, if the vtables' structure allows this 
(bringing type safety)

I think such a change would improve D. What do you think?


xs0
May 21 2005
parent reply "Ben Hinkle" <ben.hinkle gmail.com> writes:
"xs0" <xs0 xs0.com> wrote in message news:d6nlc5$7gu$1 digitaldaemon.com...
 I've been porting some Java to D lately, and was surprised how much more 
 complicated interfaces are to use in D than in Java. Specifically:

 - an interface reference is not implicitly castable to Object. why? every 
 interface implementation is obviously an Object..

In particular I run into this with ==. For example interface Foo {} class Bar : Foo {} int main() { Foo x; Bar y; ... if (x == y) // won't compile due to incompatible type ... } It is kindof annoying that once you declare something as an interface it ripples through the code forcing either casts to Object or declaring lots of things as interfaces. As I've been playing around with MinTL class containers I've been getting more and more annoyed with interfaces.
 - casting Interface[] to Object[] or vice-versa doesn't work. There's even 
 no error, neither compile-time nor run-time, it just doesn't work (ok, in 
 some cases a crash probably occurs, but it in my case, the only thing that 
 happened was that the name of the class was outputted on the console, 
 don't ask me why :)

I've never been a fan of implicitly converting arrays of objects to anything - it is a huge type-safety hole since arrays are mutable.
May 24 2005
parent xs0 <xs0 xs0.com> writes:
Ben Hinkle wrote:

I've been porting some Java to D lately, and was surprised how much more 
complicated interfaces are to use in D than in Java. Specifically:

- an interface reference is not implicitly castable to Object. why? every 
interface implementation is obviously an Object..

[snip] It is kindof annoying that once you declare something as an interface it ripples through the code forcing either casts to Object or declaring lots of things as interfaces. As I've been playing around with MinTL class containers I've been getting more and more annoyed with interfaces.

Exactly, they're almost useless in the current state, in the sense they require far too much additional code. Using interfaces should be totally transparent.
- casting Interface[] to Object[] or vice-versa doesn't work. There's even 
no error, neither compile-time nor run-time, it just doesn't work (ok, in 
some cases a crash probably occurs, but it in my case, the only thing that 
happened was that the name of the class was outputted on the console, 
don't ask me why :)

I've never been a fan of implicitly converting arrays of objects to anything - it is a huge type-safety hole since arrays are mutable.

True, but in the solution I proposed, there is no additional type-safety hole (actually, quite the opposite), because every read of an object as an interface would result in a dynamic cast. xs0
May 25 2005