1

Scala has notion of "variance position" and fancy rules around it, especially when variance is combined with method type bounds. Rules ensure type safety, one can read them in Scala lang spec, or see briefed in "Programming in Scala" 5ed:

To classify the positions, the compiler starts from the declaration of a type parameter and then moves inward through deeper nesting levels. Positions at the top level of the declaring class are classified as positive. By default, positions at deeper nesting levels are classified the same as that at enclosing levels, but there are a handful of exceptions where the classification changes. Method value parameter positions are classified to the flipped classification relative to positions outside the method, where the flip of a positive classification is negative, the flip of a negative classification is positive, and the flip of a neutral classification is still neutral.

Here we see some sort of "variance positions algebra". I understand those flipping, nesting - by trying in code, so my question is different.

Question:

imagine I want to create my language that supports variance (as rich as Scala, or rudimentary like Java's wildcard generics). Which theory (type theory?), which section of that theory I need to grasp to understand all the "mechanics" behind this "variance positions algebra"?

I seek for kind of more abstract, more general knowledge (not just list of given rules in Scala lang spec) that would permit me to see particular languages' variance implementations simply as special cases?

Max
  • 1,741
  • 3
  • 23
  • 40
  • 1
    https://en.wikipedia.org/wiki/Subtyping covers the ground fairly well. – Levi Ramsey May 11 '22 at 13:45
  • 1
    This is an interesting question, but it's more one to ask a type theorist than to pose in a programming forum. That being said, https://stackoverflow.com/questions/36672986/covariance-and-variance-flip-in-scala might help – ComDubh May 11 '22 at 15:38
  • @ComDubh, thanks for pointing to url, i'll read it... i'm still confused with those numerous very segmented forums old SO has been split into... – Max May 11 '22 at 15:55
  • 1
    I wrote a bit about co- and contra-variance here: https://stackoverflow.com/a/50303536/2988. In the penultimate paragraph, where I write "it is not always obvious whether a type is an input or an output once you get to more complex types. For example, when your type parameter is used as the upper or lower bound of an abstract type member, or when you have a method which takes a function that returns a function whose argument type is your type parameter", I am basically deliberately ignoring the issue that the rules you are asking about are trying to address :-D – Jörg W Mittag May 11 '22 at 18:57
  • @JörgWMittag , cheers for your very comprehensive post. – Max May 12 '22 at 05:16
  • You're welcome! The basic intuition behind all of those "flip" rules is always this idea of "inputs are contra variant, outputs are covariant". But, for example, if you have a function which takes another function as an argument, then the output of the argument function becomes an input to the higher-order function, etc. The "flip" rules are just keeping track of all of that. – Jörg W Mittag May 12 '22 at 06:21
  • 1
    https://antoine-doeraene.medium.com/how-type-variance-fits-into-category-theory-e662d2c7f522 https://www.atlassian.com/blog/software-teams/covariance-and-contravariance-in-scala – Dmytro Mitin Feb 12 '23 at 17:49

0 Answers0