Why not set covariant as default when define subtype in Scala?

127 Views Asked by At

It means define trait Option[T] is same as trait Option[+T].

It's easy to consider val humanOpt: Option[Human] can point to a Option[Student] instance just like val humanOpt: Human can point to a Student instance.

Maybe it seems some strange but why I consider this?

Java variable default as polymorphism which compare with c++ that it should use virtual keyword.I think its a important point to simplify OO in Java.

Scala use high order type in many use case that is more frequently compare to Java, such as Option, Try or define a Cache[T] by ourselves.

Besides, it still comply with Liskov Substitution principle.

I just want to know why not simplify covariant as default behavior?

1

There are 1 best solutions below

4
On BEST ANSWER

or define a Cache[T] by ourselves

If your Cache has a put(T) method, it can't be covariant, exactly because of the Liskov substitution principle.

val humanCache: Cache[Human] = new Cache[Student] // legal if cache is covariant
humanCache.put(new Professor) // oops, we put a Professor into a Cache[Student]

So making all types covariant by default simply won't work.

You could use variance inference instead: if type can be covariant make it covariant, if it can be contravariant make if contravariant, if neither make it invariant. But then just adding a method can change the variance and break a lot of code using your type. By making all variance explicit you are forced to notice when you do that.