digitalmars.D.dtl - interfaces :-(
- Ben Hinkle (5/5) May 24 2005 Well so far the interfaces in D are too clunky to be useful for MinTL
- John Reimer (4/11) Jan 13 2006 What's the status of D interfaces right now? Are there still troubles
- John Demme (12/26) Jan 13 2006 I've been watching the changelog and AFAIK nothing's changed, and I don'...
- John Reimer (14/24) Jan 13 2006 Okay... so that's the status. :( For my sake, could you explain what
- John Demme (44/79) Jan 14 2006 I'm not sure that I fully understand covariance either, but that's the w...
- Bruno Medeiros (21/117) Jan 18 2006 I didn't understand these posts, so I learned about Covariance and
- John Reimer (7/26) Jan 18 2006 I don't believe John Demme was misusing the term "covariance." I
- John Demme (5/36) Jan 18 2006 Actually, the error message doesn't use the term. Yes, I probably was
- Bruno Medeiros (24/67) Jan 19 2006 Me? Well, implementation-wise, I have no ideia. Usage-wise, it is like I...
- John Demme (5/75) Jan 19 2006 You don't know me personally, but I tend to exaggerate everything. Am I
- John Reimer (21/72) Jan 18 2006 I don't get this. The two methods have different signatures, don't
- John Demme (70/160) Jan 18 2006 There are no potential ambiguities involved since A extends I. The prob...
- John Reimer (16/188) Jan 18 2006 I think I'm starting to see what you're getting at.
- John Demme (9/33) Jan 18 2006 The casting isn't just ackward, it's not safe through code changes, sinc...
- =?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= (8/42) Jan 19 2006 Why doesn't Walter want to fix this? I have already three stalled
- xs0 (20/25) Jan 19 2006 Well, AFAIK, the main problem here is that an object reference is not
- xs0 (7/17) Jan 19 2006 For what it's worth - I just tested it, and in Java calling the same
- =?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= (9/27) Jan 19 2006 Sounds very cool. Does this 70% mean that the time used between calling
- xs0 (8/36) Jan 19 2006 Well, the method was empty, but I guess the way you put it would show
- =?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= (10/48) Jan 19 2006 As far as I understand it, the current interfaces can only be used on
- John Demme (16/25) Jan 19 2006 Interface don't even work too well in single inheritance structures.
- sean.fritz gmail.com (35/40) Jun 15 2006 Well, FWIW I've been using invariant return type Java interfaces for yea...
- michal.minich gmail.com (42/84) Jun 20 2006 This is now possible in D, here's example, hope it's helpful
- Sean Fritz (3/38) Jun 20 2006 Does B also have a method/function (which do I use with D?) compareTo(A ...
- Kirk McDonald (13/15) Jun 20 2006 "A virtual member function is sometimes called a /method/." -Bjarne
- michal.minich gmail.com (28/78) Jun 21 2006 You have to write:
- Walter Bright (11/22) Mar 09 2006 It'll work if you rewrite it as:
- John Demme (15/43) Mar 09 2006 Fine. I'll give you a harder example:
- Walter Bright (6/19) Mar 09 2006 Ok, but it will still work if Map.copy() is defined to return an Object
- John Demme (9/32) Mar 10 2006 C'mon... Can't we do better than this? And actually, it'll only work
- Kris (10/17) Mar 10 2006 Exactly. It's unfortunate that Interfaces are still something of a red-h...
- =?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= (33/53) Mar 10 2006 Very true. Semantically these uses guarantee the minimal functionality
- Walter Bright (3/7) Mar 11 2006 I think I've found a way to make the covariance thing work, so stay tune...
- John Reimer (5/15) Mar 11 2006 !!!!!
- John Demme (5/14) Mar 12 2006 Great; thanks.
- John Reimer (7/23) Mar 12 2006 Uh... it's okay Walter, um... don't listen to him... he didn't mean it,
- John Demme (8/37) Mar 12 2006 I'm sorry... I didn't mean anything by it... Should I reword to:
- John Reimer (8/48) Mar 12 2006 I, in turn, apologize for being rediculous. It was all in good fun,
Well so far the interfaces in D are too clunky to be useful for MinTL (imho). They don't interact with objects very well so I'm going to test out using only abstract classes instead of interfaces. That way == will work and covariance becomes possible. So basically I imagine that the API would be the last thing I posted minus the interfaces. Anyway, the saga continues...
May 24 2005
Ben Hinkle wrote:Well so far the interfaces in D are too clunky to be useful for MinTL (imho). They don't interact with objects very well so I'm going to test out using only abstract classes instead of interfaces. That way == will work and covariance becomes possible. So basically I imagine that the API would be the last thing I posted minus the interfaces. Anyway, the saga continues...What's the status of D interfaces right now? Are there still troubles with them in any areas such as above? -JJR
Jan 13 2006
I've been watching the changelog and AFAIK nothing's changed, and I don't think Walter's planning on changing anything. The efficiency issues are still there (according to Kris) and interfaces still aren't covariant with ANYTHING making them utterly worthless. I don't know if you've been watching my (slow) progress, but I've choosen to nearly ignore interfaces altogether in mango.containers as Ben has for MinTL. Sure it'd be nice if Walter would fix some of these issues, but first he has to be convinced that there are issues, something which I've had no success in doing. ~John Demme John Reimer wrote:Ben Hinkle wrote:Well so far the interfaces in D are too clunky to be useful for MinTL (imho). They don't interact with objects very well so I'm going to test out using only abstract classes instead of interfaces. That way == will work and covariance becomes possible. So basically I imagine that the API would be the last thing I posted minus the interfaces. Anyway, the saga continues...What's the status of D interfaces right now? Are there still troubles with them in any areas such as above? -JJR
Jan 13 2006
John Demme wrote:I've been watching the changelog and AFAIK nothing's changed, and I don't think Walter's planning on changing anything. The efficiency issues are still there (according to Kris) and interfaces still aren't covariant with ANYTHING making them utterly worthless.Okay... so that's the status. :( For my sake, could you explain what "covariant" means. I've seen this message before but don't fully comprehend its definition.I don't know if you've been watching my (slow) progress, but I've choosen to nearly ignore interfaces altogether in mango.containers as Ben has for MinTL.I've taken a peek in mango.containers and, now that you mention it, recall that you were quite at odds with the interface implementation in D. But I hadn't really investigated much further. I'm trying to use interfaces in another project (converting C++ code). I'm not sure how far it will work. I've had to use an abstract class as a replacement in one context; but then a sub-class cannot "multiply inherit" from abstract classes as they can from interfaces, so to speak. So, if this is an issue, the design of the C++ project will need to be modified.Sure it'd be nice if Walter would fix some of these issues, but first he has to be convinced that there are issues, something which I've had no success in doing.I agree that this is important. I hope we get noticed! Thanks, John. -JJR
Jan 13 2006
I'm not sure that I fully understand covariance either, but that's the word that Walter used to say why the following doesn't work. interface I { I clone(); } class A: I { A clone(); } Semantically, it works. If you have a reference to an A: A a = new A() and want to make a clone that still uses an A reference: A anotherA = a.clone() It should work. However, DMD does not support this (because I is not covariant with A) and A's clone method has to return an I, so the previous line of code has to be: A anotherA = cast(A)a.clone(); Instead. What's even worse is that interfaces aren't covariant with each other, so the following doesn't work: interface I { I clone(); } interface BabyI: I { } class A: BabyI { BabyI clone(); } Since BabyI extends I, logically this should work. But it doesn't for implementation reasons which I don't understand (I think it's due to the way DMD handles interfaces and vtables). In short, because of this and the poor interface codegen D's interfaces are pretty much shyte and mostly worthless for mostly everything. It's unfortunate, I like interfaces a lot, but given these HUGE limitations, I can't use interfaces for anything with any measure of complexity whatsoever. I aplogize for any rants on this subject, I just find it VERY frusterating- in the past I've considered going back to Java for most of my development due to these issues, but then I started the JVM (and waited...) and decided I'd just invent some ugly design hacks to get around D's impotence instead. ~John Demme John Reimer wrote:John Demme wrote:I've been watching the changelog and AFAIK nothing's changed, and I don't think Walter's planning on changing anything. The efficiency issues are still there (according to Kris) and interfaces still aren't covariant with ANYTHING making them utterly worthless.Okay... so that's the status. :( For my sake, could you explain what "covariant" means. I've seen this message before but don't fully comprehend its definition.I don't know if you've been watching my (slow) progress, but I've choosen to nearly ignore interfaces altogether in mango.containers as Ben has for MinTL.I've taken a peek in mango.containers and, now that you mention it, recall that you were quite at odds with the interface implementation in D. But I hadn't really investigated much further. I'm trying to use interfaces in another project (converting C++ code). I'm not sure how far it will work. I've had to use an abstract class as a replacement in one context; but then a sub-class cannot "multiply inherit" from abstract classes as they can from interfaces, so to speak. So, if this is an issue, the design of the C++ project will need to be modified.Sure it'd be nice if Walter would fix some of these issues, but first he has to be convinced that there are issues, something which I've had no success in doing.I agree that this is important. I hope we get noticed! Thanks, John. -JJR
Jan 14 2006
John Demme wrote:I'm not sure that I fully understand covariance either, but that's the word that Walter used to say why the following doesn't work. interface I { I clone(); } class A: I { A clone(); } Semantically, it works. If you have a reference to an A: A a = new A() and want to make a clone that still uses an A reference: A anotherA = a.clone() It should work. However, DMD does not support this (because I is not covariant with A) and A's clone method has to return an I, so the previous line of code has to be: A anotherA = cast(A)a.clone(); Instead. What's even worse is that interfaces aren't covariant with each other, so the following doesn't work: interface I { I clone(); } interface BabyI: I { } class A: BabyI { BabyI clone(); } Since BabyI extends I, logically this should work. But it doesn't for implementation reasons which I don't understand (I think it's due to the way DMD handles interfaces and vtables). In short, because of this and the poor interface codegen D's interfaces are pretty much shyte and mostly worthless for mostly everything. It's unfortunate, I like interfaces a lot, but given these HUGE limitations, I can't use interfaces for anything with any measure of complexity whatsoever. I aplogize for any rants on this subject, I just find it VERY frusterating- in the past I've considered going back to Java for most of my development due to these issues, but then I started the JVM (and waited...) and decided I'd just invent some ugly design hacks to get around D's impotence instead. ~John Demme John Reimer wrote:I didn't understand these posts, so I learned about Covariance and Contravariance (http://en.wikipedia.org/wiki/Parameter_covariance) , which I had only superficially heard about so far. This is another field where the terminology is *very* tricky, and subsequently, I now think that you are using an unclear, or even incorrect notion of covariance in your posts. (unless there some more idioms I'm not familiar with) In particular, I don't think the statement "because I is not covariant with A" is correct, since one does not speak of covariance as a relationship of an instance of something against an instance of something else (confusing, yes). Anyway, are you sure Walter said that? Covariance (and contravariance) is said of the inputs (parameters) or outputs (return types or exceptions) of something (methods in this case). I suspect that the issue you were speaking of was that D does not support covariant return types for methods of interfaces (as it does with classes). -- Bruno Medeiros - CS/E student "Certain aspects of D are a pathway to many abilities some consider to be... unnatural."John Demme wrote:I've been watching the changelog and AFAIK nothing's changed, and I don't think Walter's planning on changing anything. The efficiency issues are still there (according to Kris) and interfaces still aren't covariant with ANYTHING making them utterly worthless.Okay... so that's the status. :( For my sake, could you explain what "covariant" means. I've seen this message before but don't fully comprehend its definition.I don't know if you've been watching my (slow) progress, but I've choosen to nearly ignore interfaces altogether in mango.containers as Ben has for MinTL.I've taken a peek in mango.containers and, now that you mention it, recall that you were quite at odds with the interface implementation in D. But I hadn't really investigated much further. I'm trying to use interfaces in another project (converting C++ code). I'm not sure how far it will work. I've had to use an abstract class as a replacement in one context; but then a sub-class cannot "multiply inherit" from abstract classes as they can from interfaces, so to speak. So, if this is an issue, the design of the C++ project will need to be modified.Sure it'd be nice if Walter would fix some of these issues, but first he has to be convinced that there are issues, something which I've had no success in doing.I agree that this is important. I hope we get noticed! Thanks, John. -JJR
Jan 18 2006
Bruno Medeiros wrote:I didn't understand these posts, so I learned about Covariance and Contravariance (http://en.wikipedia.org/wiki/Parameter_covariance) , which I had only superficially heard about so far. This is another field where the terminology is *very* tricky, and subsequently, I now think that you are using an unclear, or even incorrect notion of covariance in your posts. (unless there some more idioms I'm not familiar with) In particular, I don't think the statement "because I is not covariant with A" is correct, since one does not speak of covariance as a relationship of an instance of something against an instance of something else (confusing, yes). Anyway, are you sure Walter said that? Covariance (and contravariance) is said of the inputs (parameters) or outputs (return types or exceptions) of something (methods in this case). I suspect that the issue you were speaking of was that D does not support covariant return types for methods of interfaces (as it does with classes).I don't believe John Demme was misusing the term "covariance." I believe he was just trying to restate what was given by the error message. That said, I do believe you are correct that the covariance issue relates to support for covariant return types for methods of interfaces. This is a good topic for further investigation. Thanks for the wiki link. -JJR
Jan 18 2006
John Reimer wrote:Bruno Medeiros wrote:Actually, the error message doesn't use the term. Yes, I probably was misusing it- as I previously said, I don't fully understand it. Either way, do you now understand the problem with DMD's interfaces, Bruno? ~John DemmeI didn't understand these posts, so I learned about Covariance and Contravariance (http://en.wikipedia.org/wiki/Parameter_covariance) , which I had only superficially heard about so far. This is another field where the terminology is *very* tricky, and subsequently, I now think that you are using an unclear, or even incorrect notion of covariance in your posts. (unless there some more idioms I'm not familiar with) In particular, I don't think the statement "because I is not covariant with A" is correct, since one does not speak of covariance as a relationship of an instance of something against an instance of something else (confusing, yes). Anyway, are you sure Walter said that? Covariance (and contravariance) is said of the inputs (parameters) or outputs (return types or exceptions) of something (methods in this case). I suspect that the issue you were speaking of was that D does not support covariant return types for methods of interfaces (as it does with classes).I don't believe John Demme was misusing the term "covariance." I believe he was just trying to restate what was given by the error message. That said, I do believe you are correct that the covariance issue relates to support for covariant return types for methods of interfaces. This is a good topic for further investigation. Thanks for the wiki link. -JJR
Jan 18 2006
John Demme wrote:John Reimer wrote:Me? Well, implementation-wise, I have no ideia. Usage-wise, it is like I said: apparently D doesn't support covariant return types for methods of interfaces, yet it does for classes. That's why your abstract class examples work. Here's a simpler example: class Foo { Animal func(); } class FooBar: Foo { // override Animal func(); // would override (is invariant) override Monkey func(); // successfully overrides (is covariant) // override Object func(); // would not override (is contravariant) } When implementing interfaces methods, only invariants are allowed. I wonder what Walter's view on this is. Also, your comments that D's interfaces are highly useless because of this are quite exaggerated, or badly phrased. Java only had covariant return types (both for classes and interfaces) in the recent 1.5 version, but it's interfaces weren't useless before, obviously. -- Bruno Medeiros - CS/E student "Certain aspects of D are a pathway to many abilities some consider to be... unnatural."Bruno Medeiros wrote:Actually, the error message doesn't use the term. Yes, I probably was misusing it- as I previously said, I don't fully understand it. Either way, do you now understand the problem with DMD's interfaces, Bruno? ~John DemmeI didn't understand these posts, so I learned about Covariance and Contravariance (http://en.wikipedia.org/wiki/Parameter_covariance) , which I had only superficially heard about so far. This is another field where the terminology is *very* tricky, and subsequently, I now think that you are using an unclear, or even incorrect notion of covariance in your posts. (unless there some more idioms I'm not familiar with) In particular, I don't think the statement "because I is not covariant with A" is correct, since one does not speak of covariance as a relationship of an instance of something against an instance of something else (confusing, yes). Anyway, are you sure Walter said that? Covariance (and contravariance) is said of the inputs (parameters) or outputs (return types or exceptions) of something (methods in this case). I suspect that the issue you were speaking of was that D does not support covariant return types for methods of interfaces (as it does with classes).I don't believe John Demme was misusing the term "covariance." I believe he was just trying to restate what was given by the error message. That said, I do believe you are correct that the covariance issue relates to support for covariant return types for methods of interfaces. This is a good topic for further investigation. Thanks for the wiki link. -JJR
Jan 19 2006
Bruno Medeiros wrote:John Demme wrote:You don't know me personally, but I tend to exaggerate everything. Am I exaggerating here? Yeah, probably. I do use interfaces on occasion, but they've got so much potential to be so much more useful, and I want it! ~John DemmeJohn Reimer wrote:Me? Well, implementation-wise, I have no ideia. Usage-wise, it is like I said: apparently D doesn't support covariant return types for methods of interfaces, yet it does for classes. That's why your abstract class examples work. Here's a simpler example: class Foo { Animal func(); } class FooBar: Foo { // override Animal func(); // would override (is invariant) override Monkey func(); // successfully overrides (is covariant) // override Object func(); // would not override (is contravariant) } When implementing interfaces methods, only invariants are allowed. I wonder what Walter's view on this is. Also, your comments that D's interfaces are highly useless because of this are quite exaggerated, or badly phrased. Java only had covariant return types (both for classes and interfaces) in the recent 1.5 version, but it's interfaces weren't useless before, obviously.Bruno Medeiros wrote:Actually, the error message doesn't use the term. Yes, I probably was misusing it- as I previously said, I don't fully understand it. Either way, do you now understand the problem with DMD's interfaces, Bruno? ~John DemmeI didn't understand these posts, so I learned about Covariance and Contravariance (http://en.wikipedia.org/wiki/Parameter_covariance) , which I had only superficially heard about so far. This is another field where the terminology is *very* tricky, and subsequently, I now think that you are using an unclear, or even incorrect notion of covariance in your posts. (unless there some more idioms I'm not familiar with) In particular, I don't think the statement "because I is not covariant with A" is correct, since one does not speak of covariance as a relationship of an instance of something against an instance of something else (confusing, yes). Anyway, are you sure Walter said that? Covariance (and contravariance) is said of the inputs (parameters) or outputs (return types or exceptions) of something (methods in this case). I suspect that the issue you were speaking of was that D does not support covariant return types for methods of interfaces (as it does with classes).I don't believe John Demme was misusing the term "covariance." I believe he was just trying to restate what was given by the error message. That said, I do believe you are correct that the covariance issue relates to support for covariant return types for methods of interfaces. This is a good topic for further investigation. Thanks for the wiki link. -JJR
Jan 19 2006
John Demme wrote:I'm not sure that I fully understand covariance either, but that's the word that Walter used to say why the following doesn't work. interface I { I clone(); } class A: I { A clone(); } Semantically, it works. If you have a reference to an A: A a = new A() and want to make a clone that still uses an A reference: A anotherA = a.clone()I don't get this. The two methods have different signatures, don't they? The interface: I clone(); is not the same as A clone() { return this; } // return "this" just to make it compile Thus, when you try to compile with dmd 0.143 you'll get function interface I.clone isn't implemented, a message that seems correct (or else there would be no way to differentiate a method that returned I or A) If you add an I clone() {} to class A, you get a compile error because there's a conflict between the two methods, which basically means that clone can't be overloaded this way due the potential ambiguities involved.It should work. However, DMD does not support this (because I is not covariant with A) and A's clone method has to return an I, so the previous line of code has to be: A anotherA = cast(A)a.clone(); Instead. What's even worse is that interfaces aren't covariant with each other, so the following doesn't work: interface I { I clone(); } interface BabyI: I { } class A: BabyI { BabyI clone(); } Since BabyI extends I, logically this should work. But it doesn't for implementation reasons which I don't understand (I think it's due to the way DMD handles interfaces and vtables). In short, because of this and the poor interface codegen D's interfaces are pretty much shyte and mostly worthless for mostly everything. It's unfortunate, I like interfaces a lot, but given these HUGE limitations, I can't use interfaces for anything with any measure of complexity whatsoever.I'm not so sure these things are supposed to work quite like the above examples. It seems that there are more issues here than meet the eye. I think D's interface implementation might need some more thought, but it's no picnic no matter how one looks at the whole thing.I aplogize for any rants on this subject, I just find it VERY frusterating- in the past I've considered going back to Java for most of my development due to these issues, but then I started the JVM (and waited...) and decided I'd just invent some ugly design hacks to get around D's impotence instead.Hey, no problem. I know how you feel. It would be nice to get a lot of things sorted out in D. :) -JJR
Jan 18 2006
See below. John Reimer wrote:John Demme wrote:There are no potential ambiguities involved since A extends I. The problem with the current behavior is illustrated quite well by similar example as given above: interface IClonable { IClonable clone(); } class Foo: IClonable { IClonable clone(); } This compiles, however now if one has a reference to Foo and wants to clone it, they have to run the clone method and cast it to a Foo. However, if Foo.clone() was allowed to return a Foo reference, if one had a reference to a Foo and they clone it, they get a Foo. The interface also works as expected as if someone has an IClonable reference (which is actually a Foo) and they call the clone method they get a Foo referred to as an IClonable- which is perfectly valid considering that Foo extends IClonable. Also keep in mind that the following code DOES work: abstract class IClonable { IClonable clone(); } class Foo: IClonable { Foo clone(); } But what happens if Foo needs to inherient methods from a different class? Interfaces won't work properly to fill the gap here. Thus, they are worthless.I'm not sure that I fully understand covariance either, but that's the word that Walter used to say why the following doesn't work. interface I { I clone(); } class A: I { A clone(); } Semantically, it works. If you have a reference to an A: A a = new A() and want to make a clone that still uses an A reference: A anotherA = a.clone()I don't get this. The two methods have different signatures, don't they? The interface: I clone(); is not the same as A clone() { return this; } // return "this" just to make it compile Thus, when you try to compile with dmd 0.143 you'll get function interface I.clone isn't implemented, a message that seems correct (or else there would be no way to differentiate a method that returned I or A) If you add an I clone() {} to class A, you get a compile error because there's a conflict between the two methods, which basically means that clone can't be overloaded this way due the potential ambiguities involved.quite like the aboveIt should work. However, DMD does not support this (because I is not covariant with A) and A's clone method has to return an I, so the previous line of code has to be: A anotherA = cast(A)a.clone(); Instead. What's even worse is that interfaces aren't covariant with each other, so the following doesn't work: interface I { I clone(); } interface BabyI: I { } class A: BabyI { BabyI clone(); } Since BabyI extends I, logically this should work. But it doesn't for implementation reasons which I don't understand (I think it's due to the way DMD handles interfaces and vtables). In short, because of this and the poor interface codegen D's interfaces are pretty much shyte and mostly worthless for mostly everything. It's unfortunate, I like interfaces a lot, but given these HUGE limitations, I can't use interfaces for anything with any measure of complexity whatsoever.I'm not so sMYSQL_STRAIGHT_UPGRADE=1ure these things are supposed to workexamples. It seems that there are more issues here than meet the eye. I think D's interface implementation might need some more thought, but it's no picnic no matter how one looks at the whole thing.The fact that something works as expected with an abstract class whereas it doesn't work with an interface is a good indication that there's just plain something wrong with DMD. Also note with the "BabyI" example, that if you change "interface" to "abstract class", it works properly. The way I see it is that interfaces should nearly be drop in replacements for abstract classes, but without method body inheritance, and allows multiple inheritance.I've actually run in to this issue a whole lot. In the hopes that examples help clarify and convince (I find they help me a lot) here's some of the problems I had with this issue in DMD: In designing mango.containers, I wanted to make Container, List, MutableList and such all interfaces so that the implementations, such as ArrayList could extend anything they want. I thought it might, for instance, be able to create an MMArrayList which extends MemoryMappedFile (or something like this). However, a lot of the methods in these abstract classes return their type: abstract class Container { Container dup(); } But a Container itself isn't very useful, so whenever you call the dup() method you have to cast it to something useful- and having to cast like that is a HACK! I've had the same issue with neuralNexus (unreleased project). interface INode { INode getNameNode(); } class NNClientNode: XmlRpcObject, INode { INode getNameNode(); bit isConnected(); } Here if someone calls the getNameNode method on an NNClientNode, they can't use any special functionality of NNClientNode (like isConnected()) unless they cast back to it. It's a real PITA and it needs to get fixed. ~John DemmeI aplogize for any rants on this subject, I just find it VERY frusterating- in the past I've considered going back to Java for most of my development due to these issues, but then I started the JVM (and waited...) and decided I'd just invent some ugly design hacks to get around D's impotence instead.Hey, no problem. I know how you feel. It would be nice to get a lot of things sorted out in D. :) -JJR
Jan 18 2006
John Demme wrote:See below. John Reimer wrote:I think I'm starting to see what you're getting at. Let me try to summarize what you are saying to see if I'm following this correctly: 1) We can use abstract classes to do what the interface should be able to do. But this is not good, because abstract classes don't function completely like interfaces. The fact that abstract classes can do what we expect interfaces to do reveals a defect in the current interface implementation. 2) In order to use the features of a class that extends an interface (as returned from a cloning function), we need to cast the returned interface reference to the class in question, which is awkward. example: NNClientNode node1 = cast(NNClientNode) specialNode.getNameNode(); Correct? -JJRJohn Demme wrote:There are no potential ambiguities involved since A extends I. The problem with the current behavior is illustrated quite well by similar example as given above: interface IClonable { IClonable clone(); } class Foo: IClonable { IClonable clone(); } This compiles, however now if one has a reference to Foo and wants to clone it, they have to run the clone method and cast it to a Foo. However, if Foo.clone() was allowed to return a Foo reference, if one had a reference to a Foo and they clone it, they get a Foo. The interface also works as expected as if someone has an IClonable reference (which is actually a Foo) and they call the clone method they get a Foo referred to as an IClonable- which is perfectly valid considering that Foo extends IClonable. Also keep in mind that the following code DOES work: abstract class IClonable { IClonable clone(); } class Foo: IClonable { Foo clone(); } But what happens if Foo needs to inherient methods from a different class? Interfaces won't work properly to fill the gap here. Thus, they are worthless.I'm not sure that I fully understand covariance either, but that's the word that Walter used to say why the following doesn't work. interface I { I clone(); } class A: I { A clone(); } Semantically, it works. If you have a reference to an A: A a = new A() and want to make a clone that still uses an A reference: A anotherA = a.clone()I don't get this. The two methods have different signatures, don't they? The interface: I clone(); is not the same as A clone() { return this; } // return "this" just to make it compile Thus, when you try to compile with dmd 0.143 you'll get function interface I.clone isn't implemented, a message that seems correct (or else there would be no way to differentiate a method that returned I or A) If you add an I clone() {} to class A, you get a compile error because there's a conflict between the two methods, which basically means that clone can't be overloaded this way due the potential ambiguities involved.quite like the aboveIt should work. However, DMD does not support this (because I is not covariant with A) and A's clone method has to return an I, so the previous line of code has to be: A anotherA = cast(A)a.clone(); Instead. What's even worse is that interfaces aren't covariant with each other, so the following doesn't work: interface I { I clone(); } interface BabyI: I { } class A: BabyI { BabyI clone(); } Since BabyI extends I, logically this should work. But it doesn't for implementation reasons which I don't understand (I think it's due to the way DMD handles interfaces and vtables). In short, because of this and the poor interface codegen D's interfaces are pretty much shyte and mostly worthless for mostly everything. It's unfortunate, I like interfaces a lot, but given these HUGE limitations, I can't use interfaces for anything with any measure of complexity whatsoever.I'm not so sMYSQL_STRAIGHT_UPGRADE=1ure these things are supposed to workexamples. It seems that there are more issues here than meet the eye. I think D's interface implementation might need some more thought, but it's no picnic no matter how one looks at the whole thing.The fact that something works as expected with an abstract class whereas it doesn't work with an interface is a good indication that there's just plain something wrong with DMD. Also note with the "BabyI" example, that if you change "interface" to "abstract class", it works properly. The way I see it is that interfaces should nearly be drop in replacements for abstract classes, but without method body inheritance, and allows multiple inheritance.I've actually run in to this issue a whole lot. In the hopes that examples help clarify and convince (I find they help me a lot) here's some of the problems I had with this issue in DMD: In designing mango.containers, I wanted to make Container, List, MutableList and such all interfaces so that the implementations, such as ArrayList could extend anything they want. I thought it might, for instance, be able to create an MMArrayList which extends MemoryMappedFile (or something like this). However, a lot of the methods in these abstract classes return their type: abstract class Container { Container dup(); } But a Container itself isn't very useful, so whenever you call the dup() method you have to cast it to something useful- and having to cast like that is a HACK! I've had the same issue with neuralNexus (unreleased project). interface INode { INode getNameNode(); } class NNClientNode: XmlRpcObject, INode { INode getNameNode(); bit isConnected(); } Here if someone calls the getNameNode method on an NNClientNode, they can't use any special functionality of NNClientNode (like isConnected()) unless they cast back to it. It's a real PITA and it needs to get fixed. ~John DemmeI aplogize for any rants on this subject, I just find it VERY frusterating- in the past I've considered going back to Java for most of my development due to these issues, but then I started the JVM (and waited...) and decided I'd just invent some ugly design hacks to get around D's impotence instead.Hey, no problem. I know how you feel. It would be nice to get a lot of things sorted out in D. :) -JJR
Jan 18 2006
John Reimer wrote: [Edited out old stuff]I think I'm starting to see what you're getting at. Let me try to summarize what you are saying to see if I'm following this correctly: 1) We can use abstract classes to do what the interface should be able to do. But this is not good, because abstract classes don't function completely like interfaces. The fact that abstract classes can do what we expect interfaces to do reveals a defect in the current interface implementation. 2) In order to use the features of a class that extends an interface (as returned from a cloning function), we need to cast the returned interface reference to the class in question, which is awkward. example: NNClientNode node1 = cast(NNClientNode) specialNode.getNameNode(); Correct? -JJRThe casting isn't just ackward, it's not safe through code changes, since it essentially eliminates compile-time type checking. And in addition to the fact the this stuff works with abstract classes and not with interfaces, it just plain makes sense (IMO). But you've essentially got it right... I may have had more examples and/arguments in the past, but I don't recall them at the moment. ~John Demme
Jan 18 2006
John Demme wrote:John Reimer wrote: [Edited out old stuff]Why doesn't Walter want to fix this? I have already three stalled projects because of this. First I tried to use abstract classes, but D doesn't support multiple inheritance so now I cannot continue anymore. Isn't it a bit ironic that D ought to be practical language, but one must use C++/Java to circumvent these interface issues. -- Jari-MattiI think I'm starting to see what you're getting at. Let me try to summarize what you are saying to see if I'm following this correctly: 1) We can use abstract classes to do what the interface should be able to do. But this is not good, because abstract classes don't function completely like interfaces. The fact that abstract classes can do what we expect interfaces to do reveals a defect in the current interface implementation. 2) In order to use the features of a class that extends an interface (as returned from a cloning function), we need to cast the returned interface reference to the class in question, which is awkward. example: NNClientNode node1 = cast(NNClientNode) specialNode.getNameNode(); Correct? -JJRThe casting isn't just ackward, it's not safe through code changes, since it essentially eliminates compile-time type checking. And in addition to the fact the this stuff works with abstract classes and not with interfaces, it just plain makes sense (IMO). But you've essentially got it right... I may have had more examples and/arguments in the past, but I don't recall them at the moment.
Jan 19 2006
Why doesn't Walter want to fix this? I have already three stalled projects because of this. First I tried to use abstract classes, but D doesn't support multiple inheritance so now I cannot continue anymore. Isn't it a bit ironic that D ought to be practical language, but one must use C++/Java to circumvent these interface issues.Well, AFAIK, the main problem here is that an object reference is not the same as an interface reference, even if they point to the same object (in other words, they point to different addresses). So, there is an important consequence that a method that returns an interface ref must return something else than a method that returns an object ref (even if the object otherwise implements the interface), meaning they're not covariant (or whatever it's called :) This is the same reason why casting from ISomething[] to Object[] doesn't work. I'm not sure what a good solution'd be, though.. If the two types of references are unified (made equal), simplifying a lot of things, all methods calls through interfaces will have to be resolved in runtime, and I'm not sure what the impact would be on speed etc., as it would require another level of indirection in method calls -- now its iref->vtable->method(), then it would be something like objref->getIface(...)->vtable->method(). It's the only thing I can think of, though, that would make interfaces work like in Java.. It wouldn't even be too hard to implement, I think, but getting Walter convinced is another issue :) xs0
Jan 19 2006
I'm not sure what a good solution'd be, though.. If the two types of references are unified (made equal), simplifying a lot of things, all methods calls through interfaces will have to be resolved in runtime, and I'm not sure what the impact would be on speed etc., as it would require another level of indirection in method calls -- now its iref->vtable->method(), then it would be something like objref->getIface(...)->vtable->method(). It's the only thing I can think of, though, that would make interfaces work like in Java.. It wouldn't even be too hard to implement, I think, but getting Walter convinced is another issue :)For what it's worth - I just tested it, and in Java calling the same "void method() {}" through an interface reference takes about 70% longer than through a class reference, and nobody seems to mind :) And an optimizing compiler would notice that the object in my test case was always the same, and could even do the method lookup only once, making them equally fast.. xs0
Jan 19 2006
xs0 wrote:Sounds very cool. Does this 70% mean that the time used between calling the method and executing the first line of the method is 70% longer? If it's so, this only hurts some recursive functions (assuming we have a stupid optimizer) since most of the time is spent _inside_ the methods, right? Besides, I like the Java interface implementation, it's very practical. -- Jari-MattiI'm not sure what a good solution'd be, though.. If the two types of references are unified (made equal), simplifying a lot of things, all methods calls through interfaces will have to be resolved in runtime, and I'm not sure what the impact would be on speed etc., as it would require another level of indirection in method calls -- now its iref->vtable->method(), then it would be something like objref->getIface(...)->vtable->method(). It's the only thing I can think of, though, that would make interfaces work like in Java.. It wouldn't even be too hard to implement, I think, but getting Walter convinced is another issue :)For what it's worth - I just tested it, and in Java calling the same "void method() {}" through an interface reference takes about 70% longer than through a class reference, and nobody seems to mind :) And an optimizing compiler would notice that the object in my test case was always the same, and could even do the method lookup only once, making them equally fast..
Jan 19 2006
Jari-Matti Mäkelä wrote:xs0 wrote:Well, the method was empty, but I guess the way you put it would show about the same results.Sounds very cool. Does this 70% mean that the time used between calling the method and executing the first line of the method is 70% longer?I'm not sure what a good solution'd be, though.. If the two types of references are unified (made equal), simplifying a lot of things, all methods calls through interfaces will have to be resolved in runtime, and I'm not sure what the impact would be on speed etc., as it would require another level of indirection in method calls -- now its iref->vtable->method(), then it would be something like objref->getIface(...)->vtable->method(). It's the only thing I can think of, though, that would make interfaces work like in Java.. It wouldn't even be too hard to implement, I think, but getting Walter convinced is another issue :)For what it's worth - I just tested it, and in Java calling the same "void method() {}" through an interface reference takes about 70% longer than through a class reference, and nobody seems to mind :) And an optimizing compiler would notice that the object in my test case was always the same, and could even do the method lookup only once, making them equally fast..If it's so, this only hurts some recursive functions (assuming we have a stupid optimizer) since most of the time is spent _inside_ the methods, right? Besides, I like the Java interface implementation, it's very practical.I agree it's very practical :) I'm not sure who else agrees, but many people (me included) would seem to think that the whole interface thing in D is currently not particularly useful, so it might be worth to rethink it a bit... xs0
Jan 19 2006
xs0 wrote:Jari-Matti Mäkelä wrote:As far as I understand it, the current interfaces can only be used on simple single inheritance structures and on closed source products that want to hide the implementation from end users. At least I cannot come up with any creative ways in using them. I really hope Walter could think this over, maybe someone (like me) could help writing the docs or something. I fear after 1.0 release it would be too late to fix this anymore. -- Jari-Mattixs0 wrote:Well, the method was empty, but I guess the way you put it would show about the same results.Sounds very cool. Does this 70% mean that the time used between calling the method and executing the first line of the method is 70% longer?I'm not sure what a good solution'd be, though.. If the two types of references are unified (made equal), simplifying a lot of things, all methods calls through interfaces will have to be resolved in runtime, and I'm not sure what the impact would be on speed etc., as it would require another level of indirection in method calls -- now its iref->vtable->method(), then it would be something like objref->getIface(...)->vtable->method(). It's the only thing I can think of, though, that would make interfaces work like in Java.. It wouldn't even be too hard to implement, I think, but getting Walter convinced is another issue :)For what it's worth - I just tested it, and in Java calling the same "void method() {}" through an interface reference takes about 70% longer than through a class reference, and nobody seems to mind :) And an optimizing compiler would notice that the object in my test case was always the same, and could even do the method lookup only once, making them equally fast..If it's so, this only hurts some recursive functions (assuming we have a stupid optimizer) since most of the time is spent _inside_ the methods, right? Besides, I like the Java interface implementation, it's very practical.I agree it's very practical :) I'm not sure who else agrees, but many people (me included) would seem to think that the whole interface thing in D is currently not particularly useful, so it might be worth to rethink it a bit...
Jan 19 2006
Jari-Matti Mäkelä wrote:As far as I understand it, the current interfaces can only be used on simple single inheritance structures and on closed source products that want to hide the implementation from end users. At least I cannot come up with any creative ways in using them.Interface don't even work too well in single inheritance structures. They're really only OK if they don't extend anything and something that implements them doesn't add any functionality.I really hope Walter could think this over, maybe someone (like me) could help writing the docs or something. I fear after 1.0 release it would be too late to fix this anymore.1.0 would be far too late to fix this. In my opinion, this issue has hampered D library development for some time and has already been ar large detriment to D. As for implementation, changing objects to always refer to the object (not an offset) to fix this problem (as xs0 suggests) is probably the best solution. "Make it right before you make it fast". Would it slow down interfaces? Yes, but if they're not very good, what's the point of using them anyway? I also suspect that there a a good deal of compiler optimizations that would significantly reduce the speed hit. I guess we'll see if Walter buys any of this (if he happens to be paying attention to this thread) ~John Demme
Jan 19 2006
In article <dqoho0$bmh$1 digitaldaemon.com>, =?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= says...xs0 wrote: As far as I understand it, the current interfaces can only be used on simple single inheritance structures and on closed source products that want to hide the implementation from end users. At least I cannot come up with any creative ways in using them.Well, FWIW I've been using invariant return type Java interfaces for years without realizing it was even a problem. I don't use abstract classes on a regular basis, because I tend to practice inversion of control and other design patterns that promote the use of interfaces as the only name coupling between classes wherever possible. I don't really, at this time understand the need for covariant return types. My first reaction to learning about them was to view them as needlessly complex, mostly useful in order to save one or two pointer lookups at method dispatch time in certain select situations. They are nice in that they do allow for compile time type checking, which leads into my second reaction. My second reaction was that all of these issues should be solvable by parameterizing(is that the correct D term for putting a type parameter on an interface?) the interface in a similar way to the way Comparable<T> is parameterized in Java. That is if D allows for overloading based on return types (which I do not know the answer to). While implementing parameter covariance through Comparable<T> has some serious issues, most notably you can never write the following code, it is one possible solution to this problem. //example illegal code -- you can't implement the same interface with //different type arguments in Java class A implements Comparable<A> { compareTo(A o) { .. } } class B extends A implements Comparable<B> { //compile time error B cannot //implement Comparable<A> and //Comparable<B> simultaneously .. } PS: Sorry if these points have already been made. I realize this is an old post. I just happened across this newsgroup and was reading from the beginning. Sean Fritz
Jun 15 2006
This is now possible in D, here's example, hope it's helpful interface Comparable (T) { void compareTo(T o); } class A : Comparable!(A) { char[] textA; void compareTo(A o) { printf ("A.compareTo: " ~ o.textA ~\n); printf ( \n ); } } class B : A, Comparable!(B) { char[] textB; void compareTo(B o) { printf ("B.compareTo: " ~ o.textA ~\n); printf ("B.compareTo: " ~ o.textB ~\n); printf ( \n ); } } void main () { A a = new A(); B b = new B(); a.textA = "TextA in instance of A"; b.textA = "TextA in instance of B"; b.textB = "TextB in instance of B"; a.compareTo(a); a.compareTo(b); b.compareTo(b); } /* the output is: A.compareTo: TextA in instance of A A.compareTo: TextA in instance of B B.compareTo: TextA in instance of B B.compareTo: TextB in instance of B */ In article <e6rg4h$1a9v$1 digitaldaemon.com>, sean.fritz gmail.com says...In article <dqoho0$bmh$1 digitaldaemon.com>, =?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= says...xs0 wrote: As far as I understand it, the current interfaces can only be used on simple single inheritance structures and on closed source products that want to hide the implementation from end users. At least I cannot come up with any creative ways in using them.Well, FWIW I've been using invariant return type Java interfaces for years without realizing it was even a problem. I don't use abstract classes on a regular basis, because I tend to practice inversion of control and other design patterns that promote the use of interfaces as the only name coupling between classes wherever possible. I don't really, at this time understand the need for covariant return types. My first reaction to learning about them was to view them as needlessly complex, mostly useful in order to save one or two pointer lookups at method dispatch time in certain select situations. They are nice in that they do allow for compile time type checking, which leads into my second reaction. My second reaction was that all of these issues should be solvable by parameterizing(is that the correct D term for putting a type parameter on an interface?) the interface in a similar way to the way Comparable<T> is parameterized in Java. That is if D allows for overloading based on return types (which I do not know the answer to). While implementing parameter covariance through Comparable<T> has some serious issues, most notably you can never write the following code, it is one possible solution to this problem. //example illegal code -- you can't implement the same interface with //different type arguments in Java class A implements Comparable<A> { compareTo(A o) { .. } } class B extends A implements Comparable<B> { //compile time error B cannot //implement Comparable<A> and //Comparable<B> simultaneously .. } PS: Sorry if these points have already been made. I realize this is an old post. I just happened across this newsgroup and was reading from the beginning. Sean Fritz
Jun 20 2006
In article <e798bq$2gmi$1 digitaldaemon.com>, michal.minich gmail.com says...This is now possible in D, here's example, hope it's helpful interface Comparable (T) { void compareTo(T o); } class A : Comparable!(A) { char[] textA; void compareTo(A o) { printf ("A.compareTo: " ~ o.textA ~\n); printf ( \n ); } } class B : A, Comparable!(B) { char[] textB; void compareTo(B o) { printf ("B.compareTo: " ~ o.textA ~\n); printf ("B.compareTo: " ~ o.textB ~\n); printf ( \n ); } } void main () { A a = new A(); B b = new B(); a.textA = "TextA in instance of A"; b.textA = "TextA in instance of B"; b.textB = "TextB in instance of B"; a.compareTo(a); a.compareTo(b); b.compareTo(b); }Does B also have a method/function (which do I use with D?) compareTo(A o)? Sean
Jun 20 2006
Sean Fritz wrote:Does B also have a method/function (which do I use with D?) compareTo(A o)?"A virtual member function is sometimes called a /method/." -Bjarne Stroustrup, The C++ Programming Language 3rd ed, section 12.2.6 In D, whether or not a member function is virtual is typically up to the compiler. In a sense, the distinction does not matter in D, unless you start declaring member functions as "final," which is basically saying "this is not virtual." This behavior is functionally similar to Java, in which all member functions are virtual; thus the term "method" is preferred in that language. "Member function" will always work, and "method" is usually fine in D. You'll usually catch me using "member function" by default, as I come from a C++ background. -Kirk McDonald
Jun 20 2006
You have to write: (cast(A)b).compareTo(a); In case you use only b.compareTo(a); D issues an error, because the method comparetTo in class B hides the implementation of this method in class a, so the parameters of type B cannot be casted to A. class with the same method signature. I don't know if this is possible in Java...? interface IA { void foo() } interface IB { void foo() } interface IC { void foo() } class D : IA, IB, IC { void IA.foo () {} // explicitly implements foo() in interface IA void foo () {} // implicitly implements foo() in interface IB void IC.foo () {} // explicitly implements foo() in interface IC } void main () { D d = new D(); d.foo() // calls foo implementing IB interface ((IA)d).foo () // calls foo implementing IA interface ((IB)d).foo () // calls foo implementing IA interface } implement two absolutely different interface, but it happens that they have the same method signature. It would be nice to have this possiblity in D. In article <e79q4g$c4d$1 digitaldaemon.com>, Sean Fritz says...In article <e798bq$2gmi$1 digitaldaemon.com>, michal.minich gmail.com says...This is now possible in D, here's example, hope it's helpful interface Comparable (T) { void compareTo(T o); } class A : Comparable!(A) { char[] textA; void compareTo(A o) { printf ("A.compareTo: " ~ o.textA ~\n); printf ( \n ); } } class B : A, Comparable!(B) { char[] textB; void compareTo(B o) { printf ("B.compareTo: " ~ o.textA ~\n); printf ("B.compareTo: " ~ o.textB ~\n); printf ( \n ); } } void main () { A a = new A(); B b = new B(); a.textA = "TextA in instance of A"; b.textA = "TextA in instance of B"; b.textB = "TextB in instance of B"; a.compareTo(a); a.compareTo(b); b.compareTo(b); }Does B also have a method/function (which do I use with D?) compareTo(A o)? Sean
Jun 21 2006
"John Demme" <me teqdruid.com> wrote in message news:dqae9p$2bhh$1 digitaldaemon.com...I'm not sure that I fully understand covariance either, but that's the word that Walter used to say why the following doesn't work. interface I { I clone(); } class A: I { A clone(); }It'll work if you rewrite it as: interface I { Object clone(); } class A: I { A clone(); }
Mar 09 2006
Walter Bright wrote:"John Demme" <me teqdruid.com> wrote in message news:dqae9p$2bhh$1 digitaldaemon.com...Fine. I'll give you a harder example: interface Map (K,V) { V get (K k); Map copy(); } class HashMap (K,V): Map!(K,V) { V get(K k) {} void rehash() {} HashMap copy() {} } ... And I've actually run into this problem. ~John DemmeI'm not sure that I fully understand covariance either, but that's the word that Walter used to say why the following doesn't work. interface I { I clone(); } class A: I { A clone(); }It'll work if you rewrite it as: interface I { Object clone(); } class A: I { A clone(); }
Mar 09 2006
"John Demme" <me teqdruid.com> wrote in message news:dur87c$2m44$1 digitaldaemon.com...Fine. I'll give you a harder example: interface Map (K,V) { V get (K k); Map copy(); } class HashMap (K,V): Map!(K,V) { V get(K k) {} void rehash() {} HashMap copy() {} } ... And I've actually run into this problem.Ok, but it will still work if Map.copy() is defined to return an Object rather than a Map. I concede it isn't as typesafe, in that whatever is derived from Object won't necessarilly be implementing Map, but it should work without ugly casting.
Mar 09 2006
Walter Bright wrote:"John Demme" <me teqdruid.com> wrote in message news:dur87c$2m44$1 digitaldaemon.com...C'mon... Can't we do better than this? And actually, it'll only work without ugly casting if you're working with a HashMap: Map!(char[], int) myMap = new HashMap!(char[],int)(); Map!(char[], int) originalMap = cast(Map!(char[],int)) myMap.clone(); The whole point of the interface, in this case, is to encourage people to disconnect their code from the implemantation of the map; encourage them to use the interface instead. ~John DemmeFine. I'll give you a harder example: interface Map (K,V) { V get (K k); Map copy(); } class HashMap (K,V): Map!(K,V) { V get(K k) {} void rehash() {} HashMap copy() {} } ... And I've actually run into this problem.Ok, but it will still work if Map.copy() is defined to return an Object rather than a Map. I concede it isn't as typesafe, in that whatever is derived from Object won't necessarilly be implementing Map, but it should work without ugly casting.
Mar 10 2006
In article <durcu5$2ulj$1 digitaldaemon.com>, John Demme says... [snip]C'mon... Can't we do better than this? And actually, it'll only work without ugly casting if you're working with a HashMap: Map!(char[], int) myMap = new HashMap!(char[],int)(); Map!(char[], int) originalMap = cast(Map!(char[],int)) myMap.clone(); The whole point of the interface, in this case, is to encourage people to disconnect their code from the implemantation of the map; encourage them to use the interface instead.Exactly. It's unfortunate that Interfaces are still something of a red-headed stepchild in D ~ It's not entirely clear that Walter uses Interfaces, or fully appreciates their powerful 'contractual' and decoupling aspects. There's no need for such tools when you're not working in a reasonably-sized team, or trying to build some kind of extensible library (or whatever). D interfaces have 'just enough' to make them useful in simple cases. For that, they are just fine ~ there's enough functionality there. Perhaps it'll mature? - Kris
Mar 10 2006
Kris wrote:In article <durcu5$2ulj$1 digitaldaemon.com>, John Demme says... [snip]Very true. Semantically these uses guarantee the minimal functionality of a class instance. That's very valuable property in a proprietary software library, because the implementation is going to be hidden from the end user. It's a essential thing in other types of software too. Think of a RPG world full of players and monsters - it's full of subclasses and different interfaces. Creatures can cross-breed and do very complicated things to every possible object. What kind of object should a class method return then? This "advanced" use of interfaces prevents the coder from doing anything nasty in a class that knows nothing special about a passed object reference. The interfaces work as a greatest common denominator thus preventing the access to any properties that are "private" on a completely different abstraction level. Currently very simple operations require awfully lot of casting. It's definitely not practical to pass only Object references and then do a heavy amount of test&casting to find out the basic types of the objects. One other alternative would be to do a switch(class.getTypeInfo) { ... } to find out the correct casting, but it really makes the whole concept of interfaces rather pointless. We can already "emulate" some the functionality of these "advanced" interfaces by using abstract classes instead of interfaces, but the problem is that there's no way to emulate multiple inheritance with them.C'mon... Can't we do better than this? And actually, it'll only work without ugly casting if you're working with a HashMap: Map!(char[], int) myMap = new HashMap!(char[],int)(); Map!(char[], int) originalMap = cast(Map!(char[],int)) myMap.clone(); The whole point of the interface, in this case, is to encourage people to disconnect their code from the implemantation of the map; encourage them to use the interface instead.Exactly. It's unfortunate that Interfaces are still something of a red-headed stepchild in D ~ It's not entirely clear that Walter uses Interfaces, or fully appreciates their powerful 'contractual' and decoupling aspects. There's no need for such tools when you're not working in a reasonably-sized team, or trying to build some kind of extensible library (or whatever).D interfaces have 'just enough' to make them useful in simple cases. For that, they are just fine ~ there's enough functionality there. Perhaps it'll mature?I really hope so. If Walter doesn't provide any valid alternative or fix these, I must stop using D and switch to Java or Ruby. I know there are few people here who appreciate properly implemented interfaces, but I think a majority of us still don't get this. E.g. simply sorting an array of interface-type objects should be possible, but it isn't: Interface[] a; a ~= new instanceOfInterfaceAndAClass(); a ~= new instanceOfInterfaceAndASecondClass(); a.sort; // segfaults -- Jari-Matti
Mar 10 2006
"John Demme" <me teqdruid.com> wrote in message news:dq9r0a$1u46$1 digitaldaemon.com...Sure it'd be nice if Walter would fix some of these issues, but first he has to be convinced that there are issues, something which I've had no success in doing.I think I've found a way to make the covariance thing work, so stay tuned.
Mar 11 2006
Walter Bright wrote:"John Demme" <me teqdruid.com> wrote in message news:dq9r0a$1u46$1 digitaldaemon.com...!!!!! WOW! Okay, I got to calm down now.... :D -JJRSure it'd be nice if Walter would fix some of these issues, but first he has to be convinced that there are issues, something which I've had no success in doing.I think I've found a way to make the covariance thing work, so stay tuned.
Mar 11 2006
Walter Bright wrote:"John Demme" <me teqdruid.com> wrote in message news:dq9r0a$1u46$1 digitaldaemon.com...Great; thanks. Just out of curiosity, what made you take this issue up now instead of earlier (or later)? ~John DemmeSure it'd be nice if Walter would fix some of these issues, but first he has to be convinced that there are issues, something which I've had no success in doing.I think I've found a way to make the covariance thing work, so stay tuned.
Mar 12 2006
John Demme wrote:Walter Bright wrote:Uh... it's okay Walter, um... don't listen to him... he didn't mean it, honest! <* grabs John Demme, stuffs a sock in his mouth, and drags him away... before Walter changes his mind *> ;) -JJR"John Demme" <me teqdruid.com> wrote in message news:dq9r0a$1u46$1 digitaldaemon.com...Great; thanks. Just out of curiosity, what made you take this issue up now instead of earlier (or later)? ~John DemmeSure it'd be nice if Walter would fix some of these issues, but first he has to be convinced that there are issues, something which I've had no success in doing.I think I've found a way to make the covariance thing work, so stay tuned.
Mar 12 2006
John Reimer wrote:John Demme wrote:I'm sorry... I didn't mean anything by it... Should I reword to: Great! Thanks! I thought that the exclamation marks might seem sarcastic. And I really was just curious what prompted Walter to bring up the issue now, considering that I haven't mentioned in awhile.... Didn't mean anything by my post-- certainly not anything negative. ~John DemmeWalter Bright wrote:Uh... it's okay Walter, um... don't listen to him... he didn't mean it, honest! <* grabs John Demme, stuffs a sock in his mouth, and drags him away... before Walter changes his mind *> ;) -JJR"John Demme" <me teqdruid.com> wrote in message news:dq9r0a$1u46$1 digitaldaemon.com...Great; thanks. Just out of curiosity, what made you take this issue up now instead of earlier (or later)? ~John DemmeSure it'd be nice if Walter would fix some of these issues, but first he has to be convinced that there are issues, something which I've had no success in doing.I think I've found a way to make the covariance thing work, so stay tuned.
Mar 12 2006
John Demme wrote:John Reimer wrote:I, in turn, apologize for being rediculous. It was all in good fun, John. You had a valid question. I just couldn't help playing on it a bit. I think I over did it! I'm curious too what prompted Walter's response, but I imagine it just had to do with him finally catching up to this post after all this time. :P Sorry, man. I must have been just a little too giddy. -JJRJohn Demme wrote:I'm sorry... I didn't mean anything by it... Should I reword to: Great! Thanks! I thought that the exclamation marks might seem sarcastic. And I really was just curious what prompted Walter to bring up the issue now, considering that I haven't mentioned in awhile.... Didn't mean anything by my post-- certainly not anything negative. ~John DemmeWalter Bright wrote:Uh... it's okay Walter, um... don't listen to him... he didn't mean it, honest! <* grabs John Demme, stuffs a sock in his mouth, and drags him away... before Walter changes his mind *> ;) -JJR"John Demme" <me teqdruid.com> wrote in message news:dq9r0a$1u46$1 digitaldaemon.com...Great; thanks. Just out of curiosity, what made you take this issue up now instead of earlier (or later)? ~John DemmeSure it'd be nice if Walter would fix some of these issues, but first he has to be convinced that there are issues, something which I've had no success in doing.I think I've found a way to make the covariance thing work, so stay tuned.
Mar 12 2006