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?

Elazar Leibovich
  • 32,750
  • 33
  • 122
  • 169

1 Answers1

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())
Lachlan
  • 3,744
  • 2
  • 26
  • 29
  • 1
    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(). – Elazar Leibovich Nov 06 '09 at 05:37
  • 6
    `Option.apply` does the same things as your `?` function. – schmmd May 22 '12 at 17:38
  • 2
    Indeed, but this was written before Option.apply existed. – Lachlan Jun 11 '12 at 23:41
  • 2
    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](http://stackoverflow.com/a/18604521/618089). – Mortimer Sep 04 '13 at 11:44