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 
> <[email protected]> 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
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to