Question

For example, Exception.allCatch is defined as

def allCatch[T]: Catch[T] 

Why not just

val allCatch: Catch[Nothing]

when Catch is covariant in its argument?

Or, why PartialFunction object defines

def empty[A, B]: PartialFunction[A, B] 

instead of just

val empty: PartialFunction[Any,Nothing]

?

Update: So far it seems that the answers miss the point. So please include a specific examples in your answer that really target the question. For example: Show a piece of code that works with def empty[A, B]: PartialFunction[A, B] but doesn't work (or is less convenient) with val empty: PartialFunction[Any,Nothing].

No correct solution

OTHER TIPS

This saves the need for casting later and allows to treat the args type as T instead of Any, which is usually more convenient.

Here is an example:

scala> def func1[T](arg : T) : T = { arg }
func1: [T](arg : T)T

scala> def func2(arg : Any) : Any = { arg }
func2: (arg: Any)Any

scala> func1(4)
res4: Int = 4

scala> func2(4)
res7: Any = 4

Looking at the source of PartialFunction available here we can see that it in fact calls a private method on the PartialFunction object:

private[this] val empty_pf: PartialFunction[Any, Nothing]

So the return type of empty will always be PartialFunction[Any, Nothing]. As for the reasoning behind I have no idea. Maybe someone else have better insight as to why. You could try the language mailing list as well...

If you hard-code the type, like PartialFunction[Any,Nothing], you cannot restrict your function to take a more specific parameter than Any.

By using a generic type parameter, you can end up with a more flexible satisfying all cases and especially making the function safe.

Let's assume you want a function aiming to take an Animal as parameter and returning an Integer.

Let's assume that function is declared as being:

def myFunction: PartialFunction[Any,Nothing]

Firstly, PartialFunction would not be specialized to Animal at parameter side but to Any. What about if I pass a Human as parameter...., it would pass.. What about safety?

Secondly, If this function is declared as returning Nothing, you can't return from it any value but Nothing! Indeed, Nothing subclasses all classes in Scala. This leads to the known rule that return type parameter must always be covariant in order to make a function interesting, not the case with Nothing.

In fact, Nothing is interesting only when dealing with the empty method of PartialFunction. Logic since an empty PartialFunction by definition involves nothing to return and should be forced to do it :)

You would ask: "So why don't we change the return type to Any?" Answer: Because you'd lose all the benefit of generic erasure time making compiler to add needed casts automatically => You wouldn't retrieve directly the Integer value, but Any. annoying..

Actually, it seems that Scala standard library has some more places where generic type parameter is redundant (because of type variance). For example, see my question about foreach. My guess, based on @Peter's answer, is that these redundant generics make the interface more clear. Thanks to them, we don't have to remember which types are covariant, contravariant and invariant. Also, this makes things way simpler for people who are not familiar with variance, which is rather an advanced feature of Scala.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top