www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Interfaces Suck [Plz read, Walter]

reply John Demme <me teqdruid.com> writes:
My experience with D's interfaces thus far is that they're useless for
all but the simplest of designs.  Since D doesn't support multiple
inheritance like C++, it's interface support MUST improve significantly
if it is to be used for enterprise-class projects.

The issues I've bumped into so far (or heard others complain about) are:

-Covariance.  I've been told that this simply cannot work with the
current D compiler implementation, and given a technical reason that I
don't really understand, but I don't buy it.  We've got some pretty
smart guys here, and I'm pretty confident that it could work.  (in other
news, if anyone could point me at some resources to help me understand
the mechanisms involved in "preventing" this from working, I'd
appreciate it.  I don't really have any footing to stand on if I don't
understand the issue.)  This one is a really big issue.  Try designing a
good containers library with interfaces without support for this.  Not
possible.

-Interface arrays.  Casting from Interface arrays to Object arrays
doesn't work.  This issue I understand, and wouldn't consider it to be a
bug.  That being said, it IS an issue that there is no easy way to do an
operation like this, short of iterating through the entire array, and
running the cast on each object before inserting it into a new array.
This has bit me a few times

-Interfaces as AA keys.  This doesn't seem to work at all.  I dunno why.

-Interfaces are not implicitly castable to objects.  All interfaces
instances are Objects, so this should work!

These are just the points I could come up with off the top 'o my head.
Anybody else got any complaints?

There was another thread concerning interfaces about a week ago started
by xs0, but it didn't go very far.  Are people not using interfaces?  Is
that because we've just accepted that they're nearly useless?

D's interface support MUST improve if D wants to be a real OO language,
and advance past a more convenient C.  As xs0 said, using interfaces
should be transparent.  I agree.  Is anyone else willing to make a
racket on this issue?

-John Demme
May 30 2005
next sibling parent clayasaurus <clayasaurus gmail.com> writes:
The lastest post in d.D.dtl says something about them too.

John Demme wrote:
 My experience with D's interfaces thus far is that they're useless for
 all but the simplest of designs.  Since D doesn't support multiple
 inheritance like C++, it's interface support MUST improve significantly
 if it is to be used for enterprise-class projects.
 
 The issues I've bumped into so far (or heard others complain about) are:
 
 -Covariance.  I've been told that this simply cannot work with the
 current D compiler implementation, and given a technical reason that I
 don't really understand, but I don't buy it.  We've got some pretty
 smart guys here, and I'm pretty confident that it could work.  (in other
 news, if anyone could point me at some resources to help me understand
 the mechanisms involved in "preventing" this from working, I'd
 appreciate it.  I don't really have any footing to stand on if I don't
 understand the issue.)  This one is a really big issue.  Try designing a
 good containers library with interfaces without support for this.  Not
 possible.
 
 -Interface arrays.  Casting from Interface arrays to Object arrays
 doesn't work.  This issue I understand, and wouldn't consider it to be a
 bug.  That being said, it IS an issue that there is no easy way to do an
 operation like this, short of iterating through the entire array, and
 running the cast on each object before inserting it into a new array.
 This has bit me a few times
 
 -Interfaces as AA keys.  This doesn't seem to work at all.  I dunno why.
 
 -Interfaces are not implicitly castable to objects.  All interfaces
 instances are Objects, so this should work!
 
 These are just the points I could come up with off the top 'o my head.
 Anybody else got any complaints?
 
 There was another thread concerning interfaces about a week ago started
 by xs0, but it didn't go very far.  Are people not using interfaces?  Is
 that because we've just accepted that they're nearly useless?
 
 D's interface support MUST improve if D wants to be a real OO language,
 and advance past a more convenient C.  As xs0 said, using interfaces
 should be transparent.  I agree.  Is anyone else willing to make a
 racket on this issue?
 
 -John Demme
 

May 30 2005
prev sibling next sibling parent "Regan Heath" <regan netwin.co.nz> writes:
It would help me, and likely anyone else who hasn't had much experience  
using interfaces in another language or in D to see some example problems  
and their ideal solution using interfaces.

I would suggest anyone with a problem with D's interfaces, post the  
problem you encountered in a thread entitled "Interface Support: <name>"  
where 'name' can be what we will use to identify that particular problem.

Then anyone who wants to can attempt to solve the problem using the  
current capabilities of D.

I believe this will clearly show where and why D is deficient, if indeed  
it is.

Regan

On Mon, 30 May 2005 14:40:47 -0400, John Demme <me teqdruid.com> wrote:

 My experience with D's interfaces thus far is that they're useless for
 all but the simplest of designs.  Since D doesn't support multiple
 inheritance like C++, it's interface support MUST improve significantly
 if it is to be used for enterprise-class projects.

 The issues I've bumped into so far (or heard others complain about) are:

 -Covariance.  I've been told that this simply cannot work with the
 current D compiler implementation, and given a technical reason that I
 don't really understand, but I don't buy it.  We've got some pretty
 smart guys here, and I'm pretty confident that it could work.  (in other
 news, if anyone could point me at some resources to help me understand
 the mechanisms involved in "preventing" this from working, I'd
 appreciate it.  I don't really have any footing to stand on if I don't
 understand the issue.)  This one is a really big issue.  Try designing a
 good containers library with interfaces without support for this.  Not
 possible.

 -Interface arrays.  Casting from Interface arrays to Object arrays
 doesn't work.  This issue I understand, and wouldn't consider it to be a
 bug.  That being said, it IS an issue that there is no easy way to do an
 operation like this, short of iterating through the entire array, and
 running the cast on each object before inserting it into a new array.
 This has bit me a few times

 -Interfaces as AA keys.  This doesn't seem to work at all.  I dunno why.

 -Interfaces are not implicitly castable to objects.  All interfaces
 instances are Objects, so this should work!

 These are just the points I could come up with off the top 'o my head.
 Anybody else got any complaints?

 There was another thread concerning interfaces about a week ago started
 by xs0, but it didn't go very far.  Are people not using interfaces?  Is
 that because we've just accepted that they're nearly useless?

 D's interface support MUST improve if D wants to be a real OO language,
 and advance past a more convenient C.  As xs0 said, using interfaces
 should be transparent.  I agree.  Is anyone else willing to make a
 racket on this issue?

 -John Demme

May 30 2005
prev sibling next sibling parent reply "Walter" <newshound digitalmars.com> writes:
"John Demme" <me teqdruid.com> wrote in message
news:1117478447.19815.73.camel localhost.localdomain...
 -Covariance.  I've been told that this simply cannot work with the
 current D compiler implementation, and given a technical reason that I
 don't really understand, but I don't buy it.  We've got some pretty
 smart guys here, and I'm pretty confident that it could work.  (in other
 news, if anyone could point me at some resources to help me understand
 the mechanisms involved in "preventing" this from working, I'd
 appreciate it.  I don't really have any footing to stand on if I don't
 understand the issue.)  This one is a really big issue.  Try designing a
 good containers library with interfaces without support for this.  Not
 possible.

Covariance can mean different things. Exactly what meaning are you using - please provide an example.
 -Interface arrays.  Casting from Interface arrays to Object arrays
 doesn't work.  This issue I understand, and wouldn't consider it to be a
 bug.  That being said, it IS an issue that there is no easy way to do an
 operation like this, short of iterating through the entire array, and
 running the cast on each object before inserting it into a new array.
 This has bit me a few times

 -Interfaces as AA keys.  This doesn't seem to work at all.  I dunno why.

To work in an AA, it needs to be sortable and hashable. How would interfaces be sorted?
 -Interfaces are not implicitly castable to objects.  All interfaces
 instances are Objects, so this should work!

Implicit casting is a powerful tool, but if the language allows too many implicit casts, then things just start becoming unglued. Where the line is, I don't know. But to add this implicit cast to interfaces, I need a strong argument.
May 30 2005
next sibling parent reply zwang <nehzgnaw gmail.com> writes:
Walter wrote:
 To work in an AA, it needs to be sortable and hashable. How would interfaces
 be sorted?

Why is sortability required for a hashed AA?
May 30 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"zwang" <nehzgnaw gmail.com> wrote in message
news:d7gp4d$ml7$1 digitaldaemon.com...
 Walter wrote:
 To work in an AA, it needs to be sortable and hashable. How would


 be sorted?

Why is sortability required for a hashed AA?

To deal with the inevitable hash collisions.
May 31 2005
next sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Walter wrote:
 "zwang" <nehzgnaw gmail.com> wrote in message 
 news:d7gp4d$ml7$1 digitaldaemon.com...
 
 Walter wrote:
 
 To work in an AA, it needs to be sortable and hashable. How would 
 interfaces be sorted?

Why is sortability required for a hashed AA?

To deal with the inevitable hash collisions.

Doesn't follow: (a) Last time I checked the AA implementation worked perfectly well on classes (but not structs) where unequal objects can rank equally in order. (b) Java's HashMap manages perfectly well without this "required" "feature". Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Jun 01 2005
next sibling parent reply zwang <nehzgnaw gmail.com> writes:
Stewart Gordon wrote:
 Walter wrote:
 
 "zwang" <nehzgnaw gmail.com> wrote in message 
 news:d7gp4d$ml7$1 digitaldaemon.com...

 Walter wrote:

 To work in an AA, it needs to be sortable and hashable. How would 
 interfaces be sorted?

Why is sortability required for a hashed AA?

To deal with the inevitable hash collisions.

Doesn't follow: (a) Last time I checked the AA implementation worked perfectly well on classes (but not structs) where unequal objects can rank equally in order. (b) Java's HashMap manages perfectly well without this "required" "feature". Stewart.

It seems to me that Walter is using a binary tree for each bucket of a hashed AA, while Java's HashMap probably using a list structure.
Jun 01 2005
parent reply Matthias Becker <Matthias_member pathlink.com> writes:
 To work in an AA, it needs to be sortable and hashable. How would 
 interfaces be sorted?

Why is sortability required for a hashed AA?

To deal with the inevitable hash collisions.

Doesn't follow: (a) Last time I checked the AA implementation worked perfectly well on classes (but not structs) where unequal objects can rank equally in order. (b) Java's HashMap manages perfectly well without this "required" "feature". Stewart.

It seems to me that Walter is using a binary tree for each bucket of a hashed AA, while Java's HashMap probably using a list structure.

So D's AAs are faster than Java's HashMaps, but therefor you can only store objects that can be ordered. Wouldn't it be better if by default a list is used and only if you explicitly support ordering a tree is used? -- Matthias Becker
Jun 01 2005
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Matthias Becker wrote:
<snip>
It seems to me that Walter is using a binary tree for each bucket of
a hashed AA, while Java's HashMap probably using a list structure.

So D's AAs are faster than Java's HashMaps, but therefor you can only store objects that can be ordered.

Try it yourself. Define a class having appropriate opEquals and toHash functions, but always returning zero for opCmp. Now try using it in an AA. Here's a working example: ---------- import std.stream; import std.stdio; import std.conv; alias std.stream.stdin stdin; class UintBox { uint value; this(uint v) { value = v; } uint toHash() { return value; } int opEquals(Object o) { return value == (cast(UintBox) o).value; } int opCmp(Object o) { return 0; } } void main() { int[UintBox] aa; for (int i = 0; i < 10; i++) { UintBox key = new UintBox(toUint(stdin.readLine)); int value = toInt(stdin.readLine); aa[key] = value; } writefln("Now query"); while (true) { UintBox key = new UintBox(toUint(stdin.readLine)); writefln(aa[key]); } } ----------
 Wouldn't it be better if by default a list is used and only if you explicitly
 support ordering a tree is used?

Indeed. It's one of the main arguments for getting rid of Object.opCmp. digitalmars.D/10558 Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Jun 01 2005
parent reply zwang <nehzgnaw gmail.com> writes:
Stewart Gordon wrote:
 Matthias Becker wrote:
 <snip>
 
 It seems to me that Walter is using a binary tree for each bucket of
 a hashed AA, while Java's HashMap probably using a list structure.

So D's AAs are faster than Java's HashMaps, but therefor you can only store objects that can be ordered.

Try it yourself. Define a class having appropriate opEquals and toHash functions, but always returning zero for opCmp. Now try using it in an AA. Here's a working example: ---------- import std.stream; import std.stdio; import std.conv; alias std.stream.stdin stdin; class UintBox { uint value; this(uint v) { value = v; } uint toHash() { return value; } int opEquals(Object o) { return value == (cast(UintBox) o).value; } int opCmp(Object o) { return 0; } } void main() { int[UintBox] aa; for (int i = 0; i < 10; i++) { UintBox key = new UintBox(toUint(stdin.readLine)); int value = toInt(stdin.readLine); aa[key] = value; } writefln("Now query"); while (true) { UintBox key = new UintBox(toUint(stdin.readLine)); writefln(aa[key]); } } ----------
 Wouldn't it be better if by default a list is used and only if you 
 explicitly
 support ordering a tree is used?

Indeed. It's one of the main arguments for getting rid of Object.opCmp. digitalmars.D/10558 Stewart.

What do you want to prove by this example? The compiler does not care how you implement the opCmp operator at all.
Jun 01 2005
parent Stewart Gordon <smjg_1998 yahoo.com> writes:
zwang wrote:
<snip>
 What do you want to prove by this example?
 The compiler does not care how you implement the opCmp operator at all.

Oops. That code example was a red herring, as there were no hash collisions. I reported this bug a while back digitalmars.D.bugs/2643 and was sure I had discovered that the bug doesn't apply to classes. However, it seems that either (a) I was imagining it (b) it's just GDC 0.11 (c) there's been a regression somewhere. Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Jun 01 2005
prev sibling parent reply "Walter" <newshound digitalmars.com> writes:
"Stewart Gordon" <smjg_1998 yahoo.com> wrote in message
news:d7juh4$1387$1 digitaldaemon.com...
 Walter wrote:
 "zwang" <nehzgnaw gmail.com> wrote in message
 news:d7gp4d$ml7$1 digitaldaemon.com...

 Walter wrote:

 To work in an AA, it needs to be sortable and hashable. How would
 interfaces be sorted?

Why is sortability required for a hashed AA?

To deal with the inevitable hash collisions.

Doesn't follow: (a) Last time I checked the AA implementation worked perfectly well on classes (but not structs) where unequal objects can rank equally in order.

It'll appear to work if the hashes don't collide.
 (b) Java's HashMap manages perfectly well without this "required"

You can resolve collisions by using a linear list. D's AA implementation uses a binary tree to resolve collisions, which is much faster.
Jun 01 2005
parent Stewart Gordon <smjg_1998 yahoo.com> writes:
Walter wrote:
 "Stewart Gordon" <smjg_1998 yahoo.com> wrote in message
 news:d7juh4$1387$1 digitaldaemon.com...

 (a) Last time I checked the AA implementation worked perfectly well on
 classes (but not structs) where unequal objects can rank equally in order.

It'll appear to work if the hashes don't collide.

At least I *thought* it worked - but see my reply to zwang. But try this modification to the code example I posted that way: ---------- class UintBox { uint value; this(uint v) { value = v; } uint toHash() { writefln("toHash: %d", value); return 0; } int opEquals(Object o) { writefln("opEquals: %d", value); return value == (cast(UintBox) o).value; } int opCmp(Object o) { writefln("opCmp: %d", value); return 0; } } ---------- (main function as before) It calls opEquals during both assignment and lookup. What does it use the result for? How about using it to check that the match it's found really is a match, and if not then look further down the tree?
 (b) Java's HashMap manages perfectly well without this "required" "feature".

You can resolve collisions by using a linear list. D's AA implementation uses a binary tree to resolve collisions, which is much faster.

You mean reimplement D's AAs to use a linear list instead? Why not have this built in as well? The answer seems to be because the presence of Object.opCmp makes it practically impossible to tell when you need to. Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Jun 02 2005
prev sibling parent reply Sean Kelly <sean f4.ca> writes:
In article <d7j4u7$bjs$2 digitaldaemon.com>, Walter says...
"zwang" <nehzgnaw gmail.com> wrote in message
news:d7gp4d$ml7$1 digitaldaemon.com...
 Walter wrote:
 To work in an AA, it needs to be sortable and hashable. How would


 be sorted?

Why is sortability required for a hashed AA?

To deal with the inevitable hash collisions.

All this requires is an equality check. Sorting just allows for more optimal worst-case performance (O(log N) vs. O(N)). Sean
Jun 01 2005
parent Nick <Nick_member pathlink.com> writes:
In article <d7khl9$1rh5$1 digitaldaemon.com>, Sean Kelly says...
 Why is sortability required for a hashed AA?

To deal with the inevitable hash collisions.

All this requires is an equality check. Sorting just allows for more optimal worst-case performance (O(log N) vs. O(N)). Sean

Here is a proposal: If objects are unequal according to opEquals, then why can't it just sort objects according to their memory location/pointer value, or some other low-level value guaranteed to be different for different objects? This should be much faster than calling opCmp, and it always works. Nick
Jun 01 2005
prev sibling next sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Walter wrote:
 "John Demme" <me teqdruid.com> wrote in message
 news:1117478447.19815.73.camel localhost.localdomain...
 
-Covariance.  I've been told that this simply cannot work with the
current D compiler implementation, and given a technical reason that I
don't really understand, but I don't buy it.  We've got some pretty
smart guys here, and I'm pretty confident that it could work.  (in other
news, if anyone could point me at some resources to help me understand
the mechanisms involved in "preventing" this from working, I'd
appreciate it.  I don't really have any footing to stand on if I don't
understand the issue.)  This one is a really big issue.  Try designing a
good containers library with interfaces without support for this.  Not
possible.

Covariance can mean different things. Exactly what meaning are you using - please provide an example.

At first glance it would appear that the OP's talking about one or other of these bugs: digitalmars.D.bugs/1726 digitalmars.D.bugs/3287 What other meanings did you have in mind? <snip>
-Interfaces as AA keys.  This doesn't seem to work at all.  I dunno why.

To work in an AA, it needs to be sortable and hashable. How would interfaces be sorted?

Aside from the same old question, no doubt somebody has written an interface and documented ordering semantics for it. If not in D, then in Java or something. Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
May 31 2005
parent reply pragma <pragma_member pathlink.com> writes:
In article <d7i5m7$276i$1 digitaldaemon.com>, Stewart Gordon says...

Aside from the same old question, no doubt somebody has written an 
interface and documented ordering semantics for it.  If not in D, then 
in Java or something.

It's funny you mention Java. Doesn't it have/mandate the "IComparable" interface for collections? Seems that particular design move solves more problems than meets the eye. - EricAnderton at yahoo
May 31 2005
parent Stewart Gordon <smjg_1998 yahoo.com> writes:
pragma wrote:
 In article <d7i5m7$276i$1 digitaldaemon.com>, Stewart Gordon says...
 
 [snip]
 
Aside from the same old question, no doubt somebody has written an 
interface and documented ordering semantics for it.  If not in D, then 
in Java or something.

It's funny you mention Java. Doesn't it have/mandate the "IComparable" interface for collections? Seems that particular design move solves more problems than meets the eye.

It has a Comparable interface. This merely stipulates the presence of an ordering, and nothing about what the ordering should mean. OTOH, the specification of an interface may mandate implementation of opEquals and/or opCmp to have certain semantics. For example, look at the specs of Java's List and Set interfaces. And only a handful of Java's collections require their elements to be Comparable. TreeMap, TreeSet, any others? Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
May 31 2005
prev sibling next sibling parent reply Matthias Becker <Matthias_member pathlink.com> writes:
 -Covariance.  I've been told that this simply cannot work with the
 current D compiler implementation, and given a technical reason that I
 don't really understand, but I don't buy it.  We've got some pretty
 smart guys here, and I'm pretty confident that it could work.  (in other
 news, if anyone could point me at some resources to help me understand
 the mechanisms involved in "preventing" this from working, I'd
 appreciate it.  I don't really have any footing to stand on if I don't
 understand the issue.)  This one is a really big issue.  Try designing a
 good containers library with interfaces without support for this.  Not
 possible.

Covariance can mean different things. Exactly what meaning are you using - please provide an example.

Can it? I thought it would be just the opposit of contravariance. e.g. class Base { Base foo () {...} } class Derived : Base { Derived foo () {...} // covariant return type } class Base2 { void foo (Derived derived) {...} } class Derived2 : Base2 { void foo (Base base) {...} // contravariant argument type (currently not supported) } These are the main usages of variant typing I know from other languages.
May 31 2005
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Matthias Becker wrote:
<snip>
Covariance can mean different things. Exactly what meaning are you using -
please provide an example.

Can it? I thought it would be just the opposit of contravariance.

But how many meanings does contravariance have? <snip>
 class Derived2 : Base2 {
 void foo (Base base) {...}  // contravariant argument type (currently not
 supported)
 }

So that's what this is called! Do you know of a language that supports this? Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
May 31 2005
parent Matthias Becker <Matthias_member pathlink.com> writes:
Covariance can mean different things. Exactly what meaning are you using -
please provide an example.

Can it? I thought it would be just the opposit of contravariance.

But how many meanings does contravariance have?

Right, co- and contravarince are a bit complicated sometimes. E.g. there are languages, where you can do this: class Foo [+T] { .. } where the plus in front of the T means that T is a covariant type. It can only be used in covariant positions (as return type and some other positions that doesn't exist in D, so I won't explain them here). So if some type D is derived from some type B than Foo[D] is derived from Foo[B].
<snip>
 class Derived2 : Base2 {
 void foo (Base base) {...}  // contravariant argument type (currently not
 supported)
 }

So that's what this is called! Do you know of a language that supports this?

AFAIK Sather supports this. -- Matthias Becker
Jun 01 2005
prev sibling parent "Walter" <newshound digitalmars.com> writes:
Thanks for the explanation. I'll have to do some thinking about it.
May 31 2005
prev sibling next sibling parent John Demme <me teqdruid.com> writes:
On Mon, 2005-05-30 at 21:12 -0700, Walter wrote:
 "John Demme" <me teqdruid.com> wrote in message
 news:1117478447.19815.73.camel localhost.localdomain...
 -Covariance.  I've been told that this simply cannot work with the
 current D compiler implementation, and given a technical reason that I
 don't really understand, but I don't buy it.  We've got some pretty
 smart guys here, and I'm pretty confident that it could work.  (in other
 news, if anyone could point me at some resources to help me understand
 the mechanisms involved in "preventing" this from working, I'd
 appreciate it.  I don't really have any footing to stand on if I don't
 understand the issue.)  This one is a really big issue.  Try designing a
 good containers library with interfaces without support for this.  Not
 possible.

Covariance can mean different things. Exactly what meaning are you using - please provide an example.

Example:
 interface I {
         I myMeth();
 }
 class A : I {
         A myMeth(); //Obviously, this won't link
 }

because it doesn't support interface-class return type covariance. (I think that's the right verbiage) The big problem here surfaces in Containers APIs. See example below:
 interface List {
         List opSlice(int a, int b);
 }
 
 class MySpecialList : List {
         MySpecialList opSlice(int a, int b); //These won't link.
         MySpecialList specialSort();
 }
 
 MySpecialList someFunc(MySpecialList msl) {
         return msl[0..3].specialSort();
 }

understand why one would want this supported, and how severely it cripples D's interface support?
 
 -Interface arrays.  Casting from Interface arrays to Object arrays
 doesn't work.  This issue I understand, and wouldn't consider it to be a
 bug.  That being said, it IS an issue that there is no easy way to do an
 operation like this, short of iterating through the entire array, and
 running the cast on each object before inserting it into a new array.
 This has bit me a few times

 -Interfaces as AA keys.  This doesn't seem to work at all.  I dunno why.

To work in an AA, it needs to be sortable and hashable. How would interfaces be sorted?

The Object class has .toHash() and .opCmp() methods. Since all interface instances are children of Object, they've got the methods. I might also add that the interface I've been trying to use as a key has both the .toHash() and .opCmp() methods in it, to force implementors to re-implement them from Object.
 
 -Interfaces are not implicitly castable to objects.  All interfaces
 instances are Objects, so this should work!

Implicit casting is a powerful tool, but if the language allows too many implicit casts, then things just start becoming unglued. Where the line is, I don't know. But to add this implicit cast to interfaces, I need a strong argument.

If implicitly casting from interfaces to Objects were possible, the above AA key problem of what hash and compare methods to use would go away... at least on the logical side. I've no idea how this would affect the innards. Also, all classes are implicitly castable to their parents (including Object) and, logically, all interface instances are children of Object because they are classes. Therefore, since all class instances are implicitly castable to Object, all interfaces should be implicitly castable to Object. Am I explaining my reasoning well? -John Demme
May 31 2005
prev sibling parent John Demme <me teqdruid.com> writes:
Sorry to reply to myself, but I was just playing around and realized
that interface-interface return type covariance isn't even supported.
So the following (although it should be perfectly legit) won't compile:
 interface Container {
         Container dup();
 }
 interface List: Container {
 }
 class LinkedList: List {
         List dup();
 }

me that this wouldn't work. This problem is much, much worse than I thought! -John Demme On Tue, 2005-05-31 at 16:56 -0400, John Demme wrote:
 On Mon, 2005-05-30 at 21:12 -0700, Walter wrote:
 "John Demme" <me teqdruid.com> wrote in message
 news:1117478447.19815.73.camel localhost.localdomain...
 -Covariance.  I've been told that this simply cannot work with the
 current D compiler implementation, and given a technical reason that I
 don't really understand, but I don't buy it.  We've got some pretty
 smart guys here, and I'm pretty confident that it could work.  (in other
 news, if anyone could point me at some resources to help me understand
 the mechanisms involved in "preventing" this from working, I'd
 appreciate it.  I don't really have any footing to stand on if I don't
 understand the issue.)  This one is a really big issue.  Try designing a
 good containers library with interfaces without support for this.  Not
 possible.

Covariance can mean different things. Exactly what meaning are you using - please provide an example.

Example:
 interface I {
         I myMeth();
 }
 class A : I {
         A myMeth(); //Obviously, this won't link
 }

because it doesn't support interface-class return type covariance. (I think that's the right verbiage) The big problem here surfaces in Containers APIs. See example below:
 interface List {
         List opSlice(int a, int b);
 }
 
 class MySpecialList : List {
         MySpecialList opSlice(int a, int b); //These won't link.
         MySpecialList specialSort();
 }
 
 MySpecialList someFunc(MySpecialList msl) {
         return msl[0..3].specialSort();
 }

understand why one would want this supported, and how severely it cripples D's interface support?
 
 -Interface arrays.  Casting from Interface arrays to Object arrays
 doesn't work.  This issue I understand, and wouldn't consider it to be a
 bug.  That being said, it IS an issue that there is no easy way to do an
 operation like this, short of iterating through the entire array, and
 running the cast on each object before inserting it into a new array.
 This has bit me a few times

 -Interfaces as AA keys.  This doesn't seem to work at all.  I dunno why.

To work in an AA, it needs to be sortable and hashable. How would interfaces be sorted?

The Object class has .toHash() and .opCmp() methods. Since all interface instances are children of Object, they've got the methods. I might also add that the interface I've been trying to use as a key has both the .toHash() and .opCmp() methods in it, to force implementors to re-implement them from Object.
 
 -Interfaces are not implicitly castable to objects.  All interfaces
 instances are Objects, so this should work!

Implicit casting is a powerful tool, but if the language allows too many implicit casts, then things just start becoming unglued. Where the line is, I don't know. But to add this implicit cast to interfaces, I need a strong argument.

If implicitly casting from interfaces to Objects were possible, the above AA key problem of what hash and compare methods to use would go away... at least on the logical side. I've no idea how this would affect the innards. Also, all classes are implicitly castable to their parents (including Object) and, logically, all interface instances are children of Object because they are classes. Therefore, since all class instances are implicitly castable to Object, all interfaces should be implicitly castable to Object. Am I explaining my reasoning well? -John Demme

May 31 2005