shouldn't this compile?

classic Classic list List threaded Threaded
16 messages Options
Reply | Threaded
Open this post in threaded view
|

shouldn't this compile?

blackdog-2
why can i not pass an array of X to a function requiring an array of Y
if X implements Y?


interface Y {
        var p:Int;
        var q:String;
}


class X implements Y {
        public var p:Int;
        public var q:String;

        public
        function new() {
                p=1;
                q = "woot";
        }
}


class Test {

        public static
        function main() {

                var t1 = new X(),
                t2 = new X();

                testArray([t1,t2]);

        }

        public static
        function testArray(a:Array<Y>) {


        }

}



--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: shouldn't this compile?

Nathan Rixham
nope doesn't work; you'll need to cast it on the way in to array of Y.

always wonder about this actually, surely it should work? are there any
plans to implement it?


ritchie turner wrote:

> why can i not pass an array of X to a function requiring an array of Y
> if X implements Y?
>
>
> interface Y {
> var p:Int;
> var q:String;
> }
>
>
> class X implements Y {
> public var p:Int;
> public var q:String;
>
> public
> function new() {
> p=1;
> q = "woot";
> }
> }
>
>
> class Test {
>
> public static
> function main() {
>
> var t1 = new X(),
> t2 = new X();
>
> testArray([t1,t2]);
>
> }
>
> public static
> function testArray(a:Array<Y>) {
>
>
> }
>
> }
>
>
>


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: shouldn't this compile?

Franco Ponticelli
The problem is in the type of the array itself. This should work:

var arr = new Array<Y>();
arr.push(t1);
arr.push(t2);
testArray(arr);

It would be nice if the compiler should resolve those types more nicely or at least have the option to write:

var arr = new Array<Y>(t1, t2);

Franco

On Wed, Jul 15, 2009 at 6:51 PM, Nathan Rixham <[hidden email]> wrote:
nope doesn't work; you'll need to cast it on the way in to array of Y.

always wonder about this actually, surely it should work? are there any plans to implement it?



ritchie turner wrote:
why can i not pass an array of X to a function requiring an array of Y
if X implements Y?


interface Y {
       var p:Int;
       var q:String;
}


class X implements Y {
       public var p:Int;
       public var q:String;

       public
       function new() {
               p=1;
               q = "woot";
       }
}


class Test {

       public static
       function main() {

               var t1 = new X(),
               t2 = new X();

               testArray([t1,t2]);

       }

       public static        function testArray(a:Array<Y>) {


       }

}





--
haXe - an open source web programming language
http://haxe.org


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: shouldn't this compile?

Owen Durni-2
In reply to this post by blackdog-2
On Wed, Jul 15, 2009 at 1:54 PM, ritchie turner<[hidden email]> wrote:

> why can i not pass an array of X to a function requiring an array of Y
> if X implements Y?
>
>
> interface Y {
>        var p:Int;
>        var q:String;
> }
>
>
> class X implements Y {
>        public var p:Int;
>        public var q:String;
>
>        public
>        function new() {
>                p=1;
>                q = "woot";
>        }
> }
>
>
> class Test {
>
>        public static
>        function main() {
>
>                var t1 = new X(),
>                t2 = new X();
>
>                testArray([t1,t2]);
>
>        }
>
>        public static
>        function testArray(a:Array<Y>) {
>
>
>        }
>
> }
>
>
>
> --
> haXe - an open source web programming language
> http://haxe.org
>

This is correct behavior (the types are not convertible). Consider the
following.

class Y {
  public function y();
}

class X extends Y {
  public function x();
}

class Z extends Y {
  public function z();
}

var ax = new Array<X>();
var ay :Array<Y> = ax;
ay[0] = new Z();
ax[0].x(); // oops, you called x() on an object of class Z, and Z does
not have a x() method.

--Owen

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: shouldn't this compile?

Nathan Rixham
Owen Durni wrote:

> On Wed, Jul 15, 2009 at 1:54 PM, ritchie turner<[hidden email]> wrote:
>> why can i not pass an array of X to a function requiring an array of Y
>> if X implements Y?
>>
>>
>> interface Y {
>>        var p:Int;
>>        var q:String;
>> }
>>
>>
>> class X implements Y {
>>        public var p:Int;
>>        public var q:String;
>>
>>        public
>>        function new() {
>>                p=1;
>>                q = "woot";
>>        }
>> }
>>
>>
>> class Test {
>>
>>        public static
>>        function main() {
>>
>>                var t1 = new X(),
>>                t2 = new X();
>>
>>                testArray([t1,t2]);
>>
>>        }
>>
>>        public static
>>        function testArray(a:Array<Y>) {
>>
>>
>>        }
>>
>> }
>>
>>
>>
>> --
>> haXe - an open source web programming language
>> http://haxe.org
>>
>
> This is correct behavior (the types are not convertible). Consider the
> following.
>
> class Y {
>   public function y();
> }
>
> class X extends Y {
>   public function x();
> }
>
> class Z extends Y {
>   public function z();
> }
>
> var ax = new Array<X>();
> var ay :Array<Y> = ax;
> ay[0] = new Z();
> ax[0].x(); // oops, you called x() on an object of class Z, and Z does
> not have a x() method.
>
> --Owen
>

?? that's classes not interfaces

interface Y {
   public function y();
}

class X implements Y {
   public function y(){}
   public function x(){}
}

class Z implements Y {
   public function y(){}
   public function z(){}
}

var ax = new Array<X>();
var ay :Array<Y> = ax;
ay[0] = new Z();
ax[0].y(); // you wouldn't want to call x() or z()

surely?

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: shouldn't this compile?

Owen Durni-2
>
> ?? that's classes not interfaces
>
> interface Y {
>  public function y();
> }
>
> class X implements Y {
>  public function y(){}
>  public function x(){}
> }
>
> class Z implements Y {
>  public function y(){}
>  public function z(){}
> }
>
> var ax = new Array<X>();
> var ay :Array<Y> = ax;
> ay[0] = new Z();
> ax[0].y(); // you wouldn't want to call x() or z()
>
> surely?
>
> --
> haXe - an open source web programming language
> http://haxe.org
>

The same type theory applies. Array<X> is not a subtype of Array<Y>
even if X is a subtype of Y.

The example illustrates why this must be the case. Here it is again
with more explanation.

var ax :Array<X> = new Array<X>(); //we create an array that can
contain subtypes of X
var ay :Array<Y> = ax; //This step is not valid because Array<X> is
not a subtype of Array<Y>... Let's pretend this were valid.

//Now we have ay, an array that can contain subtypes of Y.
//Under the hood, the ax and ay variables both reference the exact
same object. The new Array<X>() that we constructed.

ay[0] = new Z(); // The compiler must allow this because Z is a subtype of Y

ax[0].x() // Oops. ay[0] is an object of class Z, which means ax[0] is
the same object.
// The type of ax[0] is X, but we've stored an object of class Z (not type X).

Changing the first declaration to be of type Array<Y> works because X
and Z are both subtypes of Y. We can't use a declaration with type
Array<X> and assign that to something of type Array<Y> because even if
X is a subtype of Y, not all subtypes of Y are subtypes of X.

--Owen

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: shouldn't this compile?

Owen Durni-2
Here's a relevant excerpt from the Java Generics tutorial:
http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf

     In general, if Foo is a subtype (subclass or subinterface) of
Bar, and G is some
generic type declaration, it is not the case that G<Foo> is a subtype of G<Bar>.
This is probably the hardest thing you need to learn about generics,
because it goes
against our deeply held intuitions.
    The problem with that intuition is that it assumes that
collections don’t change.
Our instinct takes these things to be immutable.
    For example, if the department of motor vehicles supplies a list
of drivers to the cen-
sus bureau, this seems reasonable. We think that a List<Driver> is a
List<Person>,
assuming that Driver is a subtype of Person. In fact, what is being
passed is a copy
of the registry of drivers. Otherwise, the census bureau could add new
people who are
not drivers into the list, corrupting the DMV’s records.

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: shouldn't this compile?

blackdog-2

thanks for the explanations, makes sense.

bd

On Wed, 2009-07-15 at 20:27 -0400, Owen Durni wrote:

> Here's a relevant excerpt from the Java Generics tutorial:
> http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf
>
>      In general, if Foo is a subtype (subclass or subinterface) of
> Bar, and G is some
> generic type declaration, it is not the case that G<Foo> is a subtype of G<Bar>.
> This is probably the hardest thing you need to learn about generics,
> because it goes
> against our deeply held intuitions.
>     The problem with that intuition is that it assumes that
> collections don’t change.
> Our instinct takes these things to be immutable.
>     For example, if the department of motor vehicles supplies a list
> of drivers to the cen-
> sus bureau, this seems reasonable. We think that a List<Driver> is a
> List<Person>,
> assuming that Driver is a subtype of Person. In fact, what is being
> passed is a copy
> of the registry of drivers. Otherwise, the census bureau could add new
> people who are
> not drivers into the list, corrupting the DMV’s records.
>


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: shouldn't this compile?

Chris Hecker

http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)

Chris

ritchie turner wrote:

> thanks for the explanations, makes sense.
>
> bd
>
> On Wed, 2009-07-15 at 20:27 -0400, Owen Durni wrote:
>> Here's a relevant excerpt from the Java Generics tutorial:
>> http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf
>>
>>      In general, if Foo is a subtype (subclass or subinterface) of
>> Bar, and G is some
>> generic type declaration, it is not the case that G<Foo> is a subtype of G<Bar>.
>> This is probably the hardest thing you need to learn about generics,
>> because it goes
>> against our deeply held intuitions.
>>     The problem with that intuition is that it assumes that
>> collections don’t change.
>> Our instinct takes these things to be immutable.
>>     For example, if the department of motor vehicles supplies a list
>> of drivers to the cen-
>> sus bureau, this seems reasonable. We think that a List<Driver> is a
>> List<Person>,
>> assuming that Driver is a subtype of Person. In fact, what is being
>> passed is a copy
>> of the registry of drivers. Otherwise, the census bureau could add new
>> people who are
>> not drivers into the list, corrupting the DMV’s records.
>>
>
>

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: shouldn't this compile?

Alex Liebert
(I hope this thread addresses the problem I'm having, it's hard to search for the right thing).  But I want to have:

function doSomething(argument:Array<Foo>)

and call doSomething([fooExtender,fooExtender,fooExtender])

Would it be possible to solve the problem if the compiler allowed some syntax like:

function doSomething(argument:Array<extends Foo>)

?

Alex

On Wed, Jul 15, 2009 at 10:01 PM, Chris Hecker <[hidden email]> wrote:

http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)

Chris


ritchie turner wrote:
thanks for the explanations, makes sense.

bd

On Wed, 2009-07-15 at 20:27 -0400, Owen Durni wrote:
Here's a relevant excerpt from the Java Generics tutorial:
http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf

    In general, if Foo is a subtype (subclass or subinterface) of
Bar, and G is some
generic type declaration, it is not the case that G<Foo> is a subtype of G<Bar>.
This is probably the hardest thing you need to learn about generics,
because it goes
against our deeply held intuitions.
   The problem with that intuition is that it assumes that
collections don’t change.
Our instinct takes these things to be immutable.
   For example, if the department of motor vehicles supplies a list
of drivers to the cen-
sus bureau, this seems reasonable. We think that a List<Driver> is a
List<Person>,
assuming that Driver is a subtype of Person. In fact, what is being
passed is a copy
of the registry of drivers. Otherwise, the census bureau could add new
people who are
not drivers into the list, corrupting the DMV’s records.




--
haXe - an open source web programming language
http://haxe.org


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: shouldn't this compile?

Armén
class Fruit
{
}

class Apple extends Fruit
{
}

class Orange extends Fruit
{
}

class Application
{
     static function main()
     {
          var apples = new Array<Apple>();

          add_new_orange(apples); /// Doesn't compile, for a good reason...
     }

     static function add_new_orange(fruits: Array<Fruit>)
     {
          return fruits.push(new Orange());
     }
}

Compiling this successfully would imply that the program may push an
orange object into an array of apples, which clearly is a logical
error regardless how you look at it. There is nothing wrong with
'add_new_orange' function - it simply adds an orange to an array of
fruits. But when you try to force it to accept an array of apples
instead, that's where the typing system is designed to protect you
from yourself, as with an example above.

On Wed, Nov 24, 2010 at 23:09, Alex Liebert <[hidden email]> wrote:

> (I hope this thread addresses the problem I'm having, it's hard to search
> for the right thing).  But I want to have:
> function doSomething(argument:Array<Foo>)
> and call doSomething([fooExtender,fooExtender,fooExtender])
> Would it be possible to solve the problem if the compiler allowed some
> syntax like:
> function doSomething(argument:Array<extends Foo>)
> ?
> Alex
>
> On Wed, Jul 15, 2009 at 10:01 PM, Chris Hecker <[hidden email]> wrote:
>>
>>
>> http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)
>>
>> Chris
>>
>> ritchie turner wrote:
>>>
>>> thanks for the explanations, makes sense.
>>>
>>> bd
>>>
>>> On Wed, 2009-07-15 at 20:27 -0400, Owen Durni wrote:
>>>>
>>>> Here's a relevant excerpt from the Java Generics tutorial:
>>>> http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf
>>>>
>>>>     In general, if Foo is a subtype (subclass or subinterface) of
>>>> Bar, and G is some
>>>> generic type declaration, it is not the case that G<Foo> is a subtype of
>>>> G<Bar>.
>>>> This is probably the hardest thing you need to learn about generics,
>>>> because it goes
>>>> against our deeply held intuitions.
>>>>    The problem with that intuition is that it assumes that
>>>> collections don’t change.
>>>> Our instinct takes these things to be immutable.
>>>>    For example, if the department of motor vehicles supplies a list
>>>> of drivers to the cen-
>>>> sus bureau, this seems reasonable. We think that a List<Driver> is a
>>>> List<Person>,
>>>> assuming that Driver is a subtype of Person. In fact, what is being
>>>> passed is a copy
>>>> of the registry of drivers. Otherwise, the census bureau could add new
>>>> people who are
>>>> not drivers into the list, corrupting the DMV’s records.
>>>>
>>>
>>>
>>
>> --
>> haXe - an open source web programming language
>> http://haxe.org
>
>
> --
> haXe - an open source web programming language
> http://haxe.org
>

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: shouldn't this compile?

Heinz Hölzer-2
In reply to this post by Alex Liebert
What you need in order to compile is are function type parameter constraints like this:

function doSomething<T:Foo>(argument:Array<T>);

but this is currently not supported in haxe, but it's listed in future language features.

http://haxe.org/com/features?lang=en

Are there any news/plans for this?

That would be an awesome feature!!

Am 24.11.2010 23:09, schrieb Alex Liebert:
(I hope this thread addresses the problem I'm having, it's hard to search for the right thing).  But I want to have:

function doSomething(argument:Array<Foo>)

and call doSomething([fooExtender,fooExtender,fooExtender])

Would it be possible to solve the problem if the compiler allowed some syntax like:

function doSomething(argument:Array<extends Foo>)

?

Alex

On Wed, Jul 15, 2009 at 10:01 PM, Chris Hecker <[hidden email]> wrote:

http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)

Chris


ritchie turner wrote:
thanks for the explanations, makes sense.

bd

On Wed, 2009-07-15 at 20:27 -0400, Owen Durni wrote:
Here's a relevant excerpt from the Java Generics tutorial:
http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf

    In general, if Foo is a subtype (subclass or subinterface) of
Bar, and G is some
generic type declaration, it is not the case that G<Foo> is a subtype of G<Bar>.
This is probably the hardest thing you need to learn about generics,
because it goes
against our deeply held intuitions.
   The problem with that intuition is that it assumes that
collections don’t change.
Our instinct takes these things to be immutable.
   For example, if the department of motor vehicles supplies a list
of drivers to the cen-
sus bureau, this seems reasonable. We think that a List<Driver> is a
List<Person>,
assuming that Driver is a subtype of Person. In fact, what is being
passed is a copy
of the registry of drivers. Otherwise, the census bureau could add new
people who are
not drivers into the list, corrupting the DMV’s records.




--
haXe - an open source web programming language
http://haxe.org



--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: shouldn't this compile?

Nathan
In reply to this post by Armén
Apple implements Fruit
Orange implements Fruit

fruitBasket : Array<Fruit> = [new Apple, new Orange];


Armén wrote:

> class Fruit
> {
> }
>
> class Apple extends Fruit
> {
> }
>
> class Orange extends Fruit
> {
> }
>
> class Application
> {
>      static function main()
>      {
>           var apples = new Array<Apple>();
>
>           add_new_orange(apples); /// Doesn't compile, for a good reason...
>      }
>
>      static function add_new_orange(fruits: Array<Fruit>)
>      {
>           return fruits.push(new Orange());
>      }
> }
>
> Compiling this successfully would imply that the program may push an
> orange object into an array of apples, which clearly is a logical
> error regardless how you look at it. There is nothing wrong with
> 'add_new_orange' function - it simply adds an orange to an array of
> fruits. But when you try to force it to accept an array of apples
> instead, that's where the typing system is designed to protect you
> from yourself, as with an example above.
>
> On Wed, Nov 24, 2010 at 23:09, Alex Liebert <[hidden email]> wrote:
>> (I hope this thread addresses the problem I'm having, it's hard to search
>> for the right thing).  But I want to have:
>> function doSomething(argument:Array<Foo>)
>> and call doSomething([fooExtender,fooExtender,fooExtender])
>> Would it be possible to solve the problem if the compiler allowed some
>> syntax like:
>> function doSomething(argument:Array<extends Foo>)
>> ?
>> Alex
>>
>> On Wed, Jul 15, 2009 at 10:01 PM, Chris Hecker <[hidden email]> wrote:
>>>
>>> http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)
>>>
>>> Chris
>>>
>>> ritchie turner wrote:
>>>> thanks for the explanations, makes sense.
>>>>
>>>> bd
>>>>
>>>> On Wed, 2009-07-15 at 20:27 -0400, Owen Durni wrote:
>>>>> Here's a relevant excerpt from the Java Generics tutorial:
>>>>> http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf
>>>>>
>>>>>     In general, if Foo is a subtype (subclass or subinterface) of
>>>>> Bar, and G is some
>>>>> generic type declaration, it is not the case that G<Foo> is a subtype of
>>>>> G<Bar>.
>>>>> This is probably the hardest thing you need to learn about generics,
>>>>> because it goes
>>>>> against our deeply held intuitions.
>>>>>    The problem with that intuition is that it assumes that
>>>>> collections don’t change.
>>>>> Our instinct takes these things to be immutable.
>>>>>    For example, if the department of motor vehicles supplies a list
>>>>> of drivers to the cen-
>>>>> sus bureau, this seems reasonable. We think that a List<Driver> is a
>>>>> List<Person>,
>>>>> assuming that Driver is a subtype of Person. In fact, what is being
>>>>> passed is a copy
>>>>> of the registry of drivers. Otherwise, the census bureau could add new
>>>>> people who are
>>>>> not drivers into the list, corrupting the DMV’s records.
>>>>>
>>>>
>>> --
>>> haXe - an open source web programming language
>>> http://haxe.org
>>
>> --
>> haXe - an open source web programming language
>> http://haxe.org
>>
>


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: shouldn't this compile?

sledorze
To fully understand this issue, you really need to grasp co/contra variance.
following Chris link is a first step (I resend it here because the last parenthesis was lacking):


http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)

As Arrays are mutables, they are both in co and contra positions; which make them invariants.

otherwise, errors will arise, for instance (pseudo code):

class X
class Y extends X

function foo ( xs : Array<X> ) {
  xs.push(X)
}

now if I use foo and passes an array of Y, then after the call, this array will contain a X which is an inconsistency.

Introducing subtyping in the haxe compiler could lead into a lot of consequences.
Language design is about trade offs, I bet Nicolas has considered that already, and there must be good reasons..

Stephane


P.S.:
Personnaly, I think subtyping is flawed; it's not worst the associated complexity.
I think type classes is a lot cleaner design, however this does not translates easily in whatever backend without a (big?) cost.
But that's another topic..
Reply | Threaded
Open this post in threaded view
|

Re: shouldn't this compile?

sledorze
ok, the parenhesis is also lacking -_- ..
click on the correct link in wikipedia.
Again, this is important to understand, it's a general useful concept.
Reply | Threaded
Open this post in threaded view
|

Re: shouldn't this compile?

singmajesty
In reply to this post by Alex Liebert
I haven't tried this, but here's a quick thought ...

I believe that haXe will automatically assign a type to generic arrays. As  
a result, these two are equivalent:


doSomething ([fooExtender, fooExtender, fooExtender]);


var argumentArray:Array <FooExtender> = new Array ();
argumentArray.push (fooExtender);
argumentArray.push (fooExtender);
argumentArray.push (fooExtender);

doSomething (argumentArray);



In the second example, its obvious that Array <FooExtender> != Array  
<Foo>. However, this might work:


var argumentArray:Array <Foo> = new Array <Foo> ();
argumentArray.push (fooExtender);
argumentArray.push (fooExtender);
argumentArray.push (fooExtender);

doSomething (argumentArray);


... or:


doSomething (cast ([fooExtender, fooExtender, fooExtender], Array <Foo>));



If it doesn't work, you can always use Dynamic, or like was suggested, try  
an interface



On Wed, 24 Nov 2010 14:09:04 -0800, Alex Liebert  
<[hidden email]> wrote:

> (I hope this thread addresses the problem I'm having, it's hard to search
> for the right thing).  But I want to have:
>
> function doSomething(argument:Array<Foo>)
>
> and call doSomething([fooExtender,fooExtender,fooExtender])
>
> Would it be possible to solve the problem if the compiler allowed some
> syntax like:
>
> function doSomething(argument:Array<extends Foo>)
>
> ?
>
> Alex
>
> On Wed, Jul 15, 2009 at 10:01 PM, Chris Hecker <[hidden email]> wrote:
>
>>
>>
>> http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)
>>
>> Chris
>>
>>
>> ritchie turner wrote:
>>
>>> thanks for the explanations, makes sense.
>>>
>>> bd
>>>
>>> On Wed, 2009-07-15 at 20:27 -0400, Owen Durni wrote:
>>>
>>>> Here's a relevant excerpt from the Java Generics tutorial:
>>>> http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf
>>>>
>>>>     In general, if Foo is a subtype (subclass or subinterface) of
>>>> Bar, and G is some
>>>> generic type declaration, it is not the case that G<Foo> is a subtype  
>>>> of
>>>> G<Bar>.
>>>> This is probably the hardest thing you need to learn about generics,
>>>> because it goes
>>>> against our deeply held intuitions.
>>>>    The problem with that intuition is that it assumes that
>>>> collections don’t change.
>>>> Our instinct takes these things to be immutable.
>>>>    For example, if the department of motor vehicles supplies a list
>>>> of drivers to the cen-
>>>> sus bureau, this seems reasonable. We think that a List<Driver> is a
>>>> List<Person>,
>>>> assuming that Driver is a subtype of Person. In fact, what is being
>>>> passed is a copy
>>>> of the registry of drivers. Otherwise, the census bureau could add new
>>>> people who are
>>>> not drivers into the list, corrupting the DMV’s records.
>>>>
>>>>
>>>
>>>
>> --
>> haXe - an open source web programming language
>> http://haxe.org
>>


--
Using Opera's revolutionary email client: http://www.opera.com/mail/

--
haXe - an open source web programming language
http://haxe.org