[SOLVED] Checking for `null`

Coming from Java and being a paranoid developer, I do parameter checks for null in all non-private methods, but in Scala I hardly see those checks.

Is checking for null in Scala part of defensive programming or just not idiomatic and should be omitted?

As a Scala developer you may safely assume null doesn’t exist, if you have an optional parameter you will use Option.

The only moment you need yo care about null is when interacting with a Java library, in such case immediately wrap in Options everything that may be nullable, so you can again forget about that.

In any Scala code if you ask for some type, e.g. String, you are free to assume it won’t be null ever.
And if someone passes a null and the code breaks is their fault, not yours; using null in Scala is a bad practice and whoever follows bad practices is expecting to have a bad time.

TL;DR;
Yeah, do not check for null unless you are interacting with Java.

6 Likes

If you are unsure about a value you could always wrap it up with an option.

val someValue = SomeExternalSource.someValue
Option(someValue).map(..do something with the value..)

Then you could relegate to the caller of your function the job of finding out whether the value was actually null or not.

You meant wrapping in Option instead of Some. Because passing a null to a Some returns a Some(null)

3 Likes

@dubaut Here is how Daniel Westheide puts it in his book Scala from Scratch:

While it’s possible to use null in Scala, it’s strongly discouraged and would take everyone who uses your code by surprise, because the language provides a much safer alternative - and apart from being safer, it’s also much more pleasant to use: Option, a generic data type that serves as a wrapper for possibly absent values.
…
In Scala, null references do exist, but that’s because Scala runs on the JVM, and because of the language interoperability between Scala and Java. Assigning null to a value identifier is perfectly legal in Scala. It’s also legal to pretend that a value is definitely not null. Just as in Java, when you are mistaken, this leads to a NullPointerException at runtime:

scala> val x: String = null
x: String = null

scala> val length = x.length
java.lang.NullPointerException
  ... 36 elided

While this is legal Scala code, it’s far from idiomatic. Scala tries to solve the problem by getting rid of null values altogether. It captures the possibility of an absent value in a container object, which means that it’s also reflected in the type of a value. this is why a NullPointerException is a rare sight in Scala applications.

2 Likes

You’re right, i meant Option, my mistake. Thanks.

Or JavaScript, or some other null-polluted environment.

But that caveat aside: yes. One of the key reasons why Scala focuses on Option, and strongly discourages the use of null, ever, is to allow everybody to forgo defensive coding. null should only exist at uncontrolled external API boundaries, and never make it any deeper into your code. The result is code that is much less ad-hoc and more reliable.

2 Likes

It is not a safe assumption that null does not exist. :slight_smile:


oliverr@GP5EB-A59:~$ scala

Welcome to Scala 2.13.2 (OpenJDK 64-Bit Server VM, Java 11.0.7).
Type in expressions for evaluation. Or try :help.

> scala.io.Source.fromResource("oops").hasNext
java.lang.NullPointerException
  ... 46 elided

Granted, but I usually take that as a sign of an obsolete API that needs improvement / replacement. (There are many reasons why Source is generally considered one of the weaker bits of stdlib, and folks have tended to move to, eg, better-files instead.)

It is never appropriate for null to exist; sadly, our code is still sometimes inappropriate.

1 Like

Ah, thanks for the hint, I just realized that better-files has Resource.asStream(String): Option[InputStream], which returns None when the resource does not exist. Neat!

We merged a fix for that recently: Improve exception thrown by Source.fromResource by nogurenn · Pull Request #9054 · scala/scala · GitHub

1 Like

On top of that, if you’re using a mocking framework in your tests – Mockito, ScalaMock, etc – the stubs will return null when called with an invocation that was not previously prepared by the test.

This behavior will often make your code break with a NullPointerException, which is a good thing, as it indicates that there’s a problem with either the test or the unit being tested.

1 Like