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
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
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.
Yeah, do not check for
null unless you are interacting with Java.
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
@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
... 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.
You’re right, i meant Option, my mistake. Thanks.
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.
It is not a safe assumption that null does not exist.
Welcome to Scala 2.13.2 (OpenJDK 64-Bit Server VM, Java 11.0.7).
Type in expressions for evaluation. Or try :help.
... 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.
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: https://github.com/scala/scala/pull/9054
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.