Usages of Null / Nothing / Unit in Scala
I've just read: http://oldfashionedsoftware.com/2008/08/20/a-post-about-nothing/
As far as I understand, Null
is a trait and its only instance is null
.
When a method takes a Null argument, then we can only pass it a Null
reference or null
directly, but not any other reference, even if it is null (nullString: String = null
for example).
I just wonder in which cases using this Null
trait could be useful.
There is also the Nothing trait for which I don't really see any more examples.
I don't really understand either what is the difference between using Nothing and Unit as a return type, since both doesn't return any result, how to know which one to use when I have a method that performs logging for example?
Do you have usages of Unit / Null / Nothing as something else than a return type?
You only use Nothing if the method never returns (meaning it cannot complete normally by returning, it could throw an exception). Nothing is never instantiated and is there for the benefit of the type system (to quote James Iry: "The reason Scala has a bottom type is tied to its ability to express variance in type parameters."). From the article you linked to:
One other use of Nothing is as a return type for methods that never return. It makes sense if you think about it. If a method’s return type is Nothing, and there exists absolutely no instance of Nothing, then such a method must never return.
Your logging method would return Unit. There is a value Unit so it can actually be returned. From the API docs:
Unit is a subtype of scala.AnyVal. There is only one value of type Unit, (), and it is not represented by any object in the underlying runtime system. A method with return type Unit is analogous to a Java method which is declared void.
The article you quote can be misleading. The Null
type is there for compatibility with the Java virtual machine, and Java in particular.
We must consider that Scala:
- is completely object oriented: every value is an object
- is strongly typed: every value must have a type
- needs to handle
null
references to access, for example, Java libraries and code
thus it becomes necessary to define a type for the null
value, which is the Null
trait, and has null
as its only instance.
There is nothing especially useful in the Null
type unless you're the type-system or you're developing on the compiler. In particular I can't see any sensible reason to define a Null
type parameter for a method, since you can't pass anything but null
Do you have usages of Unit / Null / Nothing as something else than a return type?
Unit
can be used like this:
def execute(code: => Unit):Unit = {
// do something before
code
// do something after
}
This allows you to pass in an arbitrary block of code to be executed.
Null
might be used as a bottom type for any value that is nullable. An example is this:
implicit def zeroNull[B >: Null] =
new Zero[B] { def apply = null }
Nothing
is used in the definition of None
object None extends Option[Nothing]
This allows you to assign a None
to any type of Option
because Nothing
'extends' everything.
val x:Option[String] = None