Library support for Scala's NotNull trait
Asked Answered
L

1

14

Notice: As of Scala 2.11, NotNull is deprecated.

As far as I understand, if you want a reference type to be non-nullable you have to mixin the magic NotNull trait, and the compiler will automatically prevent you from putting null-able values in it. See this mailing-list thread for instance.

What lacking is, a decent library support for non-nullable types. If I would like to write a package that don't need to interface java code directly, and I want to prevent all types in this package from using null by default, I have no choice but to redefine all builting variables like so

//can't actually do that, but just to give the general idea
class NString extends String with NotNull
class NMap[X,Y] extends Map[X,Y] with NotNull
...

I expect scala to have (as a compiler plugin, or library) option for me to write

import collections.notnull._

in order to easily disallow null usage in a specific scala file.

Is there an option to easily force many usefull types in the standard library to be not-nullable?

Liuka answered 5/10, 2009 at 21:0 Comment(4)
You can extend String? I thought it was marked final.Lycaonia
Actually you can't. Good point. Need to define NString with implicit conversion to string I guess.Liuka
I guess you look for something like org.jetbrains.annotations.NotNull – and I miss that as well.Tactician
checkout the solution proposed in this answerFreely
G
10

I don't really know what the deal is with NotNull, but I get the impression that Scala hasn't fully worked out how it wants to deal with NotNull/Nullable concepts. My own policy is to never use null in Scala, and if you call a Java API that may return null, immediately convert it to an Option.

This utility method is my best friend:

def ?[A <: AnyRef](nullable: A): Option[A] = if (nullable eq null) None else Some(nullable)

Then you do stuff like this:

val foo: Option[Foo] = ?(getFooFromJavaAPIThatMightReturnNull())

I find this far simplier than trying to track what may or may not be null.

So I didn't answer your question at all, but I pass this on in case it's useful...

Update: more recent Scala versions now support this in the standard API:

val foo: Option[Foo] = Option(getFooFromJavaAPIThatMightReturnNull())
Grossularite answered 6/11, 2009 at 2:20 Comment(4)
The problem with your approach is, that the type system doesn't force me not to use null. So I can forget a Java API call, and have a null sneaking into my code without noticing. If OTOH all types are NotNullable, the compiler would shout if you did val x:String with NotNullable = javaapithatmightreturnNull().Liuka
Option.apply does the same things as your ? function.Roseline
Indeed, but this was written before Option.apply existed.Grossularite
Using Option is the generally accepted method to deal with functions that might return nothing, but it still means that you have to deal with cases where foo returns None and change the code that calls foo to match or map on the Option. If you know that foo will really never return null, then this complicates your code for nothing. The use of a simple tag Foo with NotNull gives you the semantic that the compiler needs for running extra checks without asking you to change anything in the calling code. See a solution in this answer.Freely

© 2022 - 2024 — McMap. All rights reserved.