As I mentioned in the first article in this series, if a programming language’s type system supports certain features, such as generic types, or union types, it can safely represent nullable types. When Java was created, in 1996, it didn’t have either of these features which is why it has the problem with null-safety that it does today. Generics were added later in Java 5, in 2004, but the fact that null was a subtype of all objects didn’t change. When Scala was created, around the same time as Java 5, it had generics from the start, which is why Option existed from the beginning and has been the default way to handle potentially absent values.

Fun fact: Martin Odersky, the creator of Scala, was one of the people who helped create the initial design for generics in Java.

With the coming of a new major version of Scala, Scala 3 AKA Dotty, Scala will be introducing Union Types. Union types allow for the description of types that are the union (in set theory terms) of two or more types. For example:

val x: String|Int = 3

println(x match {
    case i: Int => "It's an Int"
    case s: String => "It's a String"
})

This will open up a lot of interesting opportunities for expressiveness in the type system. One such possibility, which is actually being added to Scala 3 as an opt-in feature, is to change where Null fits into the type hierarchy so that reference types are not nullable by default.

The modified version would look like this:

New Scala type hierarchy with explicit null enabled
New Scala type hierarchy with explicit null enabled

Which would mean the following code would no longer typecheck

val x: String = null // error: found `Null`,  but required `String`

Instead, you would have to use a type union to assign null here

val x: String|Null = null // ok

Which is great! Because this solves the original and fundamental problem we were discussing in part 1, which is being able to distinguish between nullable and non-nullable references.

I could go in depth about the exciting changes in this project and how it would work, but I’d just be reiterating the project description, so I’ll just encourage you to check that out. There’s also the description of this feature on the dotty website. I’m very excited to see these features getting added to Scala, and I think it’s a big step forward for the language.

Hopefully you’ve found this series useful, and you will find the ScalaNullSafe macro useful for the rest of the time you’re using Scala 2 :grin:. If you have any feedback, feel free to leave a comment, or open an issue on the ScalaNullSafe repo. Thanks!