Page 1 of 2

clr array covariance?

PostPosted: Fri Jun 05, 2009 5:11 pm
by gauthier
Is this not meant to work with cobra?

class Sample
shared
def main
Sample.foo = @[Bar(), Bar()]
print Sample.foo

var foo as IFoo*?

interface IFoo
pass

class Bar
implements IFoo
pass


the following c# sample works ok, and c# 4 supports co-contra variance

Code: Select all
using System;
using System.Collections.Generic;
public class Sample{
   public static void Main(){
      foo = new[] {new Bar{}, new Bar{}};
      Console.WriteLine(foo);
   }
   static IEnumerable<IFoo> foo;
}
interface IFoo{}
class Bar : IFoo{}


I'm not sure of the implications for other backends or implementation, but for csharp it seems to be the right thing to do

Re: clr array covariance?

PostPosted: Sat Jun 06, 2009 1:46 pm
by Charles
I haven't had a chance to look into this yet. Will get back to you.

Re: clr array covariance?

PostPosted: Tue Jun 16, 2009 2:40 am
by Charles
gauthier informs me that this feature is not critical so I have recorded it in ticket:162.

Re: clr array covariance?

PostPosted: Mon Jul 06, 2009 10:55 pm
by Charles
This is now fixed via a patch submitted by hopscc. Thanks.

Re: clr array covariance?

PostPosted: Tue Jul 07, 2009 3:14 am
by hopscc
My pleasure

Is there any interest/desire to have similar behavior supported in lists ?

Re: clr array covariance?

PostPosted: Tue Jul 07, 2009 9:25 pm
by Charles
I don't think it will work at run-time with the VM. You cannot generally assign List<of Car> to List<of Shape>. Or did you have something else in mind?

Re: clr array covariance?

PostPosted: Thu Jul 09, 2009 12:42 am
by hopscc
Same as above code but assign from a list rather than from an array
Code: Select all
Sample.foo = [Bar(), Bar()]


Assign a List<of Car> to List<of ICarLike>

Re: clr array covariance?

PostPosted: Fri Jul 10, 2009 12:42 am
by Charles
Do you mean this or something else?
Code: Select all
// C#
using System;
using System.Collections.Generic;

interface ICar {
   
}

class Car : ICar {

}

class Program {
   
   public static void Main() {
      List<ICar> icars = new List<ICar>();
      List<Car> cars = new List<Car>();
      icars = cars;
      TakeICars(cars);
   }
   
   static void TakeICars(List<ICar> icars) {
   }

}


C# doesn't like it:

list-covar.cs(17,11): error CS0029: Cannot implicitly convert type
'System.Collections.Generic.List<Car>' to 'System.Collections.Generic.List<ICar>'
list-covar.cs(18,3): error CS1502: The best overloaded method match for
'Program.TakeICars(System.Collections.Generic.List<ICar>)' has some invalid arguments
list-covar.cs(18,13): error CS1503: Argument '1': cannot convert from
'System.Collections.Generic.List<Car>' to 'System.Collections.Generic.List<ICar>'

And I don't think .NET would allow, for example, the parameter passing at run-time even if you tried to sneak by with reflection.

If you meant something else, just give a complete code example.

Re: clr array covariance?

PostPosted: Wed Jul 15, 2009 3:36 pm
by gauthier
Hi, Thanks Chuck, I'll check that in latests revision.

about the idea from hopscc, I think that would be usefull to mimic something like that:

Sample.foo = [Bar() to IFoo, Bar() to IFoo]

Re: clr array covariance?

PostPosted: Wed Jul 15, 2009 6:48 pm
by Charles
The other thing that comes up is that sometimes I want a more general list:
shapes = [Circle(), Circle()]
shapes.add(Square()) # compile-time error because shapes is List<of Circle>

# currenty, ugly workaround:
shapes = List<of Shape>()
shapes.add(Circle())
shapes.add(Circle())
shapes.add(Square())

# proposal 1:
shapes = List<of Shape> [Circle(), Circle()]
shapes.add(Square)

# proposal 2:
shapes = [Circle(), Circle()] <of Shape>
shapes.add(Square)

This can come up with dictionaries as well which take 2 type arguments.

Let me know what you think.

Regarding hopscc proposal, it either won't work with .NET at run-time or I don't understand it. Hence my earlier message. Maybe he meant just for list literals, which would be doable. If he meant for any expression of type List<of T>, I don't think there's a real way to make that work.

More discussion is welcome.