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
