A lot of the generics&#x2F;covariance complaints seem to be rooted in a misunderstanding of covariance.<p><pre><code>  class Fruit {}
  class Peach: Fruit {}

  protocol FruitHolder {
      var fruits: [Fruit] { get }
  }

  class PeachBasket: FruitHolder {
      var fruits: [Peach] = []
  }
</code></pre>
This doesn&#x27;t compile because it is not type-safe.  Even though &quot;Peach&quot; is a subtype of &quot;Fruit&quot;, &quot;[Peach]&quot; is not a subtype of &quot;[Fruit]&quot;.<p>If the above code were allowed, we could circumvent the type system:<p><pre><code>  var h: FruitHolder = PeachBasket();
  var fruits = h.fruits;
  fruits.append(Fruit());
</code></pre>
I just added a non-Peach to a &quot;PeachBasket&quot;.  When someone iterates through it later, expecting it to be all &quot;Peach&quot; instances, they&#x27;re going to be surprised.<p>This reminds me of when Java 1.5 introduced generics.  People were used to arrays being covariant even though that&#x27;s not type-safe.  The language designers decided not to carry that particular type system loophole over to generics, and people (including me) were surprised by the new behavior.  (And then once we wrapped our heads around it, even more surprised we had never noticed the issue before!)<p>Objective-C had a bunch of holes in the type system and people got used to them.  Swift is trying to be more type-safe.  Interestingly, Dart made the conscious decision to retain this particular type system hole; their generics are always covariant.<p>BTW, Java&#x27;s &quot;wildcards&quot; (existential types) get you roughly what you want in a type-safe way:<p><pre><code>  protocol FruitHolder {
      var fruits: [? : Fruit] { get }
  }
</code></pre>
This roughly means that &quot;fruits&quot; is an array of some subtype &quot;Fruit&quot;, but it might not necessarily be &quot;Fruit&quot;.  Then, doing &quot;fruits.append(Fruit())&quot; would fail to compile but you could still read from the array.