6 ms·
Variance in Java
- dmitryminkovsky 8y agoGreat post, this is a tricky subject. I find myself referring to these diagrams from time to time: https://stackoverflow.com/a/33246935/741970 https://stackoverflow.com/a/33246935/741970
- ben509 8y agoThat's a good explanation, but I've found it helps to write out examples on paper and test them by hand.
- dmitryminkovsky 8y agoTest them by hand in what sense? If you mean in simple cases on the computer, then why write them on paper? (I do love writing on paper, just not sure why here)
- ben509 8y agoTest them in the sense of thinking it through by working through the cases, it's more to help internalize the idea. And writing things down is forcing my mind to serialize and deserialize ideas, and I think that helps the process. (I'm not actually doing this often for Java generics, but I've been working on some other type theory stuff and I found it helped me get beyond "I understand this" to "I now feel relatively fluent expressing these ideas.")
- dmitryminkovsky 8y agoOh yeah, for sure. Thanks for clarifying.
- noir_lord 8y agoIs there a good general book on type theory as it related to programming languages or a good place to start? I don't have a strong comp-sci background even though I've been a professional programmer for a long time, I've always preferred strongly typed languages with ADT's just from experience but I'd really like to understand this type of stuff better.
- kryptiskt 8y agoTypes and Programming Languages by Benjamin Pierce https://www.cis.upenn.edu/~bcpierce/tapl/ https://www.cis.upenn.edu/~bcpierce/tapl/
- noir_lord 8y agoThank you!, this looks good. Heh, The kindle edition is only 3 quid less than the dead tree (in the UK). That one does make me chuckle, Might have to check if the library has a copy first.
- deleted 8y ago[deleted]
- brianpgordon 8y agoThis covers a lot of the same things as my own blog post on the topic: https://briangordon.github.io/2014/09/covariance-and-contravariance.html https://briangordon.github.io/2014/09/covariance-and-contrav...
- BonesJustice 8y agoJava is interesting in that variance is defined at a reference site. Contrast that to, say, C#, where variance is defined at a type's declaration site. In C#, a type `Function<in T, out R>` is always contravariant with `T` and covariant with `R`. An assignment target of `Function<String, Object>` can always accept a `Function<Object, String>` because the definition of `Function<,>` says that's okay. In Java, there is no way to impose variance rules at a type's declaration site. An assignment target of `Function<String, Object>` can only (barring unchecked cheats) ever refer to a `Function<String, Object>`. However, I can declare a reference of `Function<? super String, ? extends Object>`, and suddenly it can be assigned a `Function<Object, String>`. I always found this difference interesting. C# is much stricter: all members of a type with generic variance must obey that variance, or that type will not compile. The type `List<T>` can only be invariant with `T` because `T` appears as both an input (e.g., in `Add(T)`) and as an output (e.g., `T this[int]`). In Java, enforcement happens at the usage site. If I declare a `List<? extends String>`, the compiler will happily let me call methods for which `T` is an output (e.g., `get(int)`), but it prohibits me from calling methods for which `T` is an input (e.g., `add(T)`). As an interesting consequence of this decision, Java allows for the concept of 'bivariance': it's possible to declare a variable of type `List<?>` in Java and assign any instantiation of `List<>` to it. Moreover, I can still invoke members which do not contain `T` in their signature (e.g., I can call `int size()`). In C#, this is simply not possible. To work around this, some generic interfaces have non-generic counterparts. For example, every `IEnumerable<>` instantiation is also an instance of the non-generic `IEnumerable` type. I am curious which approach is more common across other programming languages.
- zeroimpl 8y agoI always find the ArrayStoreException funny. I've written a lot of Java code over the years, including a fair bit pre-generics, and yet I don't believe I've ever triggered this exception.