“Nothing” else matters… *

What’s Nothing, my precious?

Nothing is a kind of special type in Scala’s class hierarchy.

To begin with, it is not instantiable: we cannot generate an instance from it by any means.

Weird, isn’t it? This is understood a bit better with the second peculiarity: it is a type that extends aaaaall classes. Even those that are user defined? Even those.

scala-hierarchy

Then, what’s the use in it? The better example is None. If Option[T] weren’t covariant, we would need to define a None[T] for every T. And then, None[Int] would be different from em>None[String]… you can imagine what a mess would that be!

But since Option[+T] is covariant*, and Nothing a subtype of every class, we needn’t declare a None for every T in the list, but there’s only one None with the following signature:

object None extends Option[Nothing]
  //...with Product with Serializable

Same thing applies to Nil.

Type inference

When we define methods or values in Scala, at first and being quite purist, we define their type:

val myVal: String = "hi"
def myMethod(n: String): Boolean =
  (n % 2 == 0)

But it is quite likely that, as time goes by and after a lot of lines of code, we start forgetting to add the type that these expressions return:

val myVal = "hi"
def myMethod(n: String) =
  (n % 2 == 0)

Nothing happens, compiler is capable of inferring the returned types… as long as there are enough hints to figure them out. It’s in this case when the “Nothing” bogeyman menace arises.

Nothing’s coming

Imagine we have a generic method like this:

def getFirstElement[T](list: List[T]): Option[T] =
  list.headOption

What this method does is to return the first element in a list (if there’s some). Where can all start to go wrong?

Suppose we want to test our method on an empty list. Our experience tells us that the best way to do that is by using List’s apply method with no argument: List().
However, if we pass this as a parameter to our method:

val first = getFirstElement(List())

Let’s see what is returned:

first: Option[Nothing] = None

We shouldn’t be mean to the compiler, let’s face that we have given no facility for it to infer the correct type. We could do it simply by using the empty method of the List object:

val first = getFirstElement(List.empty[Int])
first: Option[Int] = None

though the type could also be inferred by adding the parameter type in the method call:

val first = getFirstElement[Int](List())
first: Option[Int] = None

Done! Now I think about it, this post looks a bit dull without any memes in it…

60965939

* Covariance: C[T] is said to be covariant in T, if given a certainV<:T, then C[V]<:C[T] . This issue will be treated in detail in future (but not that remote) posts 🙂

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s