January 19, 2006
Bruno Medeiros wrote:

> John Demme wrote:
>> 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
>> 
> 
> 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.
> 

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 Demme
March 09, 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();
}


March 10, 2006
Walter Bright wrote:
> 
> "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();
> }

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 Demme
March 10, 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.


March 10, 2006
Walter Bright wrote:
> "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.

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


March 10, 2006
Kris wrote:
> 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).

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.

> 
> 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
March 12, 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.


March 12, 2006
Walter Bright wrote:
> "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. 
> 
> 

!!!!!

WOW!

Okay, I got to calm down now.... :D

-JJR
March 12, 2006
Walter Bright wrote:

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

Great; thanks.

Just out of curiosity, what made you take this issue up now instead of
earlier (or later)?

~John Demme