[swift-evolution] [Proposal] Protocols on Steroids

Howard Lovatt howard.lovatt at gmail.com
Thu Dec 31 19:32:02 CST 2015


There is a significant downside to variance in Java and Scala, you have to annotate your code all over the place. This annotation completely clutters your code, much like Swift is a lot 'cleaner' than Java, all the annotations detract. You see the same effect in code that uses Java arrays which much 'cleaner' that code that uses `List` (which is the generic equivalent of an array and hence requires variance annotations).

Sent from my iPad

> On 31 Dec 2015, at 5:00 PM, Kevin Ballard via swift-evolution <swift-evolution at swift.org> wrote:
> 
> As FĂ©lix said this is a lot of stuff to cram into one proposal, so much so that I admit I haven't even read it. But skimming it very briefly I found the two following suggestions:
>  
>> Allow covariant generic argument types with a runtime check that it is of the correct type
> ...
>> Arrays and a like become covariant (with runtime type check for write) - like Java arrays but not Java Lists
>  
> And this makes no sense. Why would you break variance? The only justification I can see from your email is "because Java Arrays behave this way", but if anything that's an argument not to do it. Java Arrays predate Java Generics, and so the only way to write polymorphic functions that operated on Arrays was to make Array covariant. But this is generally regarded as a mistake (although I suspect a necessary one). As you mentioned Java Lists don't behave this way, and that's because they learned from their mistake (also, with Generics the type could be safely invariant and functions that operate on it could express the variance directly).
>  
> FWIW, Swift Arrays actually _are_ covariant anyway (just try passing a [SubClass] to a function that expects [BaseClass]). But not in the sense that Java Arrays are. Swift's Array is a value type, which means that if that function then appends a BaseClass instance to the array it got, that's perfectly safe as it's really just mutating a copy (whereas Java Arrays are like Obj-C's NSMutableArray i.e. a reference type). I believe this is modeled internally as simply being an implicit coercion from [U] to [T] whenever U <: T (but I'm not sure where this is actually defined in the code). And of course because this is a coercion, it produces a temporary, and you can't use temporaries with inout parameters, so that preserves the invariance of arrays passed as inout parameters such as mutating methods (although if you could pass a temporary it would still be safe because it would write back to that temporary instead of the original array; this would be very confusing though which is why it's disallowed).
>  
> -Kevin Ballard
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160101/858afe58/attachment.html>


More information about the swift-evolution mailing list