May 25, 2005
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...


January 14, 2006
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
January 14, 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

January 14, 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

January 14, 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

January 18, 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:
> 
> 
>>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
> 
> 

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."
January 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
January 18, 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
January 18, 2006
John Reimer wrote:

> 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

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 Demme

January 18, 2006
See below.

John Reimer wrote:

> 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.

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.

> 
> 
>> 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 sMYSQL_STRAIGHT_UPGRADE=1ure 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.

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 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

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 Demme
« First   ‹ Prev
1 2 3 4
Top | Discussion index | About this forum | D home