Thread overview
Templates convariance
Jun 20, 2006
michal.minich
Jun 20, 2006
Sean Fritz
Jun 21, 2006
Boris Wang
Jun 21, 2006
Bruno Medeiros
Jun 21, 2006
michal.minich
Jul 02, 2006
Bruno Medeiros
June 20, 2006
Now we have interfaces covariance working in D, but Templates covariance is not implemented yet. Simply:

while you can write this:
Shape s = new Circle();

This fails to compile:
List!(Shape) sList = new List!(Circle)();

To show usefullness of this functionality, here is an example:

class Shape
{
void render()
{
printf ("Shape\n");
}
}

class Circle : Shape
{
void render()
{
printf ("Circle\n");
}
}


class List (T)
{
T item; // for simplicity, just one item possible in this list
}

void renderShapes (List!(Shape) shapesList)
{
shapesList.item.render();
}

void main()
{
List!(Shape) shapesList = new List!(Shape) ();
shapesList.item = new Shape();

List!(Circle) circlesList = new List!(Circle) ();
circlesList.item = new Circle();

renderShapes ( shapesList ); // this works
//renderShapes ( circlesList ); // *1 - does not compile
renderShapes ( cast(List!(Shape))circlesList ); // *2 - access violation

}

// *1
//test.d(37): function test.renderShapes (List) does not match argument types
(List)
//test.d(37): cannot implicitly convert expression (circlesList) of type
test.List!(Circle).List to test.List!(Shape).List

// *2 application compiles, but when run, crashes with access violation


I think that implementation of this functionality can be very difficult, but simply said, templates should be covariant if all its instantiation parameters are covariant.


June 20, 2006
In article <e799ce$2idm$1@digitaldaemon.com>, michal.minich@gmail.com says...

A list!(Shape) is not the same a a list!(Square).  It sounds like you want some
sort of wildcard matching or something to enforce type bounding like Java/C#
have, but casts are definitely unsafe.

Example code (I'm going to blotch various syntax, sorry in advance):

void foo(List!(Shape) ls) {
ls.add(new Circle) //passes type check locally?
}

..
List!(Square) ls = new List!(Square);
foo(ls);
//but ls now contains a Circle?  Circles don't go in List!(Square)?
,,.


June 21, 2006
"Sean Fritz" <Sean_member@pathlink.com> дÈëÏûÏ¢ÐÂÎÅ:e79r79$f64$1@digitaldaemon.com...
> In article <e799ce$2idm$1@digitaldaemon.com>, michal.minich@gmail.com says...
>
> A list!(Shape) is not the same a a list!(Square).  It sounds like you want
> some
> sort of wildcard matching or something to enforce type bounding like
> Java/C#
> have, but casts are definitely unsafe.
>

agreed.

'cast' and 'static if' should not be a solution for this problem, if we want a good programming language.


> Example code (I'm going to blotch various syntax, sorry in advance):
>
> void foo(List!(Shape) ls) {
> ls.add(new Circle) //passes type check locally?
> }
>
> ..
> List!(Square) ls = new List!(Square);
> foo(ls);
> //but ls now contains a Circle?  Circles don't go in List!(Square)?
> ,,.
>
>
> 


June 21, 2006
Sean Fritz wrote:
> In article <e799ce$2idm$1@digitaldaemon.com>, michal.minich@gmail.com says...
> 
> A list!(Shape) is not the same a a list!(Square).  It sounds like you want some
> sort of wildcard matching or something to enforce type bounding like Java/C#
> have, but casts are definitely unsafe.
> 
> Example code (I'm going to blotch various syntax, sorry in advance):
> 
> void foo(List!(Shape) ls) {
> ls.add(new Circle) //passes type check locally?
> }
> 
> ...
> List!(Square) ls = new List!(Square);
> foo(ls);
> //but ls now contains a Circle?  Circles don't go in List!(Square)?
> ,,.
> 
> 

Indeed. I was about to mention that too, because this is a more general problem concerning parameterized collections (Lists, arrays, etc.) in that a parameterized collection type is only covariant with another parameterized collection type if the parameter is invariant. (because the parameter is both an input and an ouput)
So for example an array of Numbers can not be (safely) typed as an array of Integers, nor it cannot be typed as an array of Objects.
Still, an array of Numbers can be seen as a readonly array of Objects, and as a writeonly array of Integers.

-- 
Bruno Medeiros - CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
June 21, 2006
Maybe this is the way how to solve this http://lambda-the-ultimate.org/node/1573

..and a publication linked from this blog entry http://research.microsoft.com/research/pubs/view.aspx?type=inproceedings&id=1215



In article <e7b3q2$22m5$1@digitaldaemon.com>, Bruno Medeiros says...
>
>Sean Fritz wrote:
>> In article <e799ce$2idm$1@digitaldaemon.com>, michal.minich@gmail.com says...
>> 
>> A list!(Shape) is not the same a a list!(Square).  It sounds like you want some
>> sort of wildcard matching or something to enforce type bounding like Java/C#
>> have, but casts are definitely unsafe.
>> 
>> Example code (I'm going to blotch various syntax, sorry in advance):
>> 
>> void foo(List!(Shape) ls) {
>> ls.add(new Circle) //passes type check locally?
>> }
>> 
>> ...
>> List!(Square) ls = new List!(Square);
>> foo(ls);
>> //but ls now contains a Circle?  Circles don't go in List!(Square)?
>> ,,.
>> 
>> 
>
>Indeed. I was about to mention that too, because this is a more general
>problem concerning parameterized collections (Lists, arrays, etc.) in
>that a parameterized collection type is only covariant with another
>parameterized collection type if the parameter is invariant. (because
>the parameter is both an input and an ouput)
>So for example an array of Numbers can not be (safely) typed as an array
>of Integers, nor it cannot be typed as an array of Objects.
>Still, an array of Numbers can be seen as a readonly array of Objects,
>and as a writeonly array of Integers.
>
>-- 
>Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D


July 02, 2006
michal.minich@gmail.com wrote:
> Maybe this is the way how to solve this
> http://lambda-the-ultimate.org/node/1573
> 
> ...and a publication linked from this blog entry
> http://research.microsoft.com/research/pubs/view.aspx?type=inproceedings&id=1215
> 
> 

Interesting article (I read chapters 1&2&5) (chapter 3 scared me away :P ).
Well, that's one way to solve it, but there are other ways surely, and we don't know which one is better. (for starters: D's template mechanism is very different than C# and Java.)
This is a very complex and advanced issue, but not as critical as many other D issues which are likely to get more attention first (and justifiedly so).
That said, I want to check out the Java generics semantics, I still haven't look much into Java 1.5 .


> 
> In article <e7b3q2$22m5$1@digitaldaemon.com>, Bruno Medeiros says...
>> Sean Fritz wrote:
>>> In article <e799ce$2idm$1@digitaldaemon.com>, michal.minich@gmail.com says...
>>>
>>> A list!(Shape) is not the same a a list!(Square).  It sounds like you want some
>>> sort of wildcard matching or something to enforce type bounding like Java/C#
>>> have, but casts are definitely unsafe.
>>>
>>> Example code (I'm going to blotch various syntax, sorry in advance):
>>>
>>> void foo(List!(Shape) ls) {
>>> ls.add(new Circle) //passes type check locally?
>>> }
>>>
>>> ...
>>> List!(Square) ls = new List!(Square);
>>> foo(ls);
>>> //but ls now contains a Circle?  Circles don't go in List!(Square)?
>>> ,,.
>>>
>>>
>> Indeed. I was about to mention that too, because this is a more general problem concerning parameterized collections (Lists, arrays, etc.) in that a parameterized collection type is only covariant with another parameterized collection type if the parameter is invariant. (because the parameter is both an input and an ouput)
>> So for example an array of Numbers can not be (safely) typed as an array of Integers, nor it cannot be typed as an array of Objects.
>> Still, an array of Numbers can be seen as a readonly array of Objects, and as a writeonly array of Integers.
>>
>> -- 
>> Bruno Medeiros - CS/E student
>> http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
> 
> 

Oops, a mistake above, this problem concerns any parameterized (templated) type, not just parameterized collections.

-- 
Bruno Medeiros - CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D