Generic type modifiers "in" and "out"

My understanding is:

The “in” modifier for a generic type, e.g. <in T>, is used when T can only be the type of an argument to a function.

The “out” modifier, e.g. <out T>, is used when T can only be the type of a function result, or when T is the type of a constructor argument.

What I don’t get is why “out” applies to constructor argument types. Those aren’t outputs, are they? Was that a convenience to avoid the need for creating a third modifier?

Let’s define

class Wrapper<out T>(val item: T)

The out attribute allows the following:

val wrapper: Wrapper<Any> = Wrapper<String>("hi" )

Now, can you call Wrapper's constructor on property wrapper? No, which is why it’s safe there. Constructor parameters don’t affect the type safety of assignment.

Maybe I’m dense, but I don’t understand how your reply answers my question. I.e., what does “out” have to do with a constructor parameter?

The “out” keyword is just an inexact but mostly intuitive shorthand to declare covariance.

Covariance is the ability for a type C<Derived> to be used anywhere a C<Base> is expected.

Using an “out” type parameter as a constructor parameter does not break covariance so it’s allowed.

Thanks. I’ll review covariance and contravariance. It seems like I used to know what those terms meant. But I found some good articles about them. :thinking: