View mode: basic / threaded / horizontal-split · Log in · Help
May 25, 2005
interfaces :-(
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
Re: interfaces :-(
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
Re: interfaces :-(
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
Re: interfaces :-(
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
Re: interfaces :-(
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
Re: interfaces :-(
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
Re: interfaces :-(
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
Re: interfaces :-(
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
Re: interfaces :-(
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
Re: interfaces :-(
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