[swift-evolution] Make generics covariant and add generics to protocols

Howard Lovatt howard.lovatt at gmail.com
Wed Jan 13 17:02:23 CST 2016


Yes you can annotate in a C#/Scala fashion. But you have burdened the
programmer and haven't added much. In almost all cases you want covariant
and I am proposing that that requirement is so pervasive that we can just
ignore the rest. At present in Swift you only have invariant and that is
usable, if inconvenient at times.

Lets take your example of IComparable<in T> from C#. On the web page for
this, https://msdn.microsoft.com/en-us/library/4d7sx9hd(v=vs.110).aspx,
there is an example of temperature comparisons. Their own example is
invariant, because almost all comparisons will be invariant.

Furthermore Microsoft chose to make Equatable<T> invariant. A strange
choice heh. How come comparing using IComparable behaves differently than
using Equatable? If you implement both, which Microsoft recommends, then
you get invariance, because Equatable is invariant.

In Swift there is a strong emphasis on final classes and structs (that are
final). Therefore you can't use contravariance with these final types.
Therefore virtually everything is covered by covariance and I am proposing
that this should be the default. If it is found latter that there are uses
for invariant and contra variant then annotations for these could be added,
however I am suggesting that since covariant is overwhelmingly the most
useful then it should be the default.

Hope this explains my reasoning,

 -- Howard.

On 14 January 2016 at 07:10, Sune Foldager <cyano at me.com> wrote:

> On 12 Jan 2016, at 10:45, Howard Lovatt via swift-evolution <
> swift-evolution at swift.org> wrote:
> Currently you generics are invariant whereas function arguments etc. are
> covariant. I am suggesting that if the way generics are implemented is
> changed then they can be made covariant and that this will add considerable
> utility to Swift generics.
> What about contravariant scenarios? Examples from C#:
> IEnumerable<out T> // covariant
> since if S : T then we want IEnumerable<S> : IEnumerable<T>
> because IEnumerable<T> only returns T’s.
> but then
> IComparable<in T> // contravariant
> since if S : T we definitely want IComparable<T> : IComparable<S>
> because IComparable<T> only takes T’s as input.
> reversing either of the above would make the type system unsound.
> Any variance be default can’t be sound, and I am strongly opposed to that.
> -Sune

  -- Howard.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160114/ff4c0f1d/attachment.html>

More information about the swift-evolution mailing list