12
trait NotNull {}

I've been trying to see how this trait can guarantee that something is not null and I can't figure it out:

def main(args: Array[String]) {
  val i = List(1, 2) 
  foo(i) //(*)
}

def foo(a: Any) = println(a.hashCode)

def foo(@NotNull a: Any) = println(a.hashCode) //compile error: trait NotNull is abstract

def foo(a: Any with NotNull) = println(a.hashCode) //compile error: type mismatch at (*)

And:

val i = new Object with NotNull //compile-error illegal inheritance

There is obviously some special compiler treatment going on because this compiles:

trait MyTrait {}

def main(args: Array[String]) {
  val i: MyTrait = null
  println(i)
}

Whereas this does not:

def main(args: Array[String]) {
  val i: NotNull = null //compile error: found Null(null) required NotNull
  println(i)
} 

EDIT: there's nothing about this I can find in programming in Scala

oxbow_lakes
  • 133,303
  • 56
  • 317
  • 449
  • val a : NotNull = "asdf". Crashes the 2.7.5 compiler: Exception in thread "main" java.lang.AssertionError: assertion failed: type erro r: can't convert from REFERENCE(java.lang.String) to REFERENCE(scala.NotNull) in unit – Thomas Jung Feb 25 '10 at 16:17
  • 2
    `NotNull` doesn't really work yet. As far as I know, it is work in progress, much like `Manifest` in Scala 2.7. – Daniel C. Sobral Feb 25 '10 at 17:19
  • 1
    @Daniel - well, it's been in the language since 2.5 according to the docs, so I think it should be working by now or just get removed! – oxbow_lakes Feb 25 '10 at 18:38
  • Started 05/01/07 : https://lampsvn.epfl.ch/trac/scala/changeset/10892 – Thomas Jung Feb 25 '10 at 18:43
  • That's understandable, but, as far as I know, this is something they _do_ want to have in a usable manner. Then again, I might be completely wrong. – Daniel C. Sobral Feb 25 '10 at 23:27
  • It appears that `NotNull` is being deprecated: https://issues.scala-lang.org/browse/SI-7247 – Mike Morearty Jun 30 '13 at 05:52

2 Answers2

19

NotNull is not yet finished. The intention is to evolve this into a usable way to check for non-nullness but it's not yet there. For the moment I would not use it. I have no concrete predictions when it will be done, only that it won't arrive for 2.8.0.

Martin Odersky
  • 20,470
  • 9
  • 51
  • 49
  • 6
    Am I right in saying it's been in the library/language since 2.5? It doesn't reflect well that there are features in scala that just don't work. – oxbow_lakes Mar 04 '10 at 23:32
  • While I can not answer whether it was usable in 2.9.1, I can add that it is deprecated since 2.11.0, scheduled to be removed but still in 2.12.6, and currently removed in the 2.13 branch on GitHub. – Adowrath Aug 13 '18 at 00:11
  • Addition: It was removed in PR #5683, included in 2.13.0 Milestone 1 from April 2017: https://github.com/scala/scala/pull/5683 – Adowrath Aug 13 '18 at 00:27
5

Try and error:

scala> class A extends NotNull
defined class A

scala> val a : A = null
<console>:5: error: type mismatch;
 found   : Null(null)
 required: A
       val a : A = null
                   ^

scala> class B
defined class B

scala> val b : B = null
b: B = null

This works only with Scala 2.7.5:

scala> new Object with NotNull
res1: java.lang.Object with NotNull = $anon$1@39859

scala> val i = new Object with NotNull
i: java.lang.Object with NotNull = $anon$1@d39c9f

And the Scala Language Reference:

If that member has a type which conforms to scala.NotNull, the member’s valuemust be initialized to a value different from null, otherwise a scala.UnitializedError is thrown.

For every class type T such that T <: scala.AnyRef and not T <: scala.NotNull one has scala.Null <: T.

Thomas Jung
  • 32,428
  • 9
  • 84
  • 114
  • 2
    The corollary to this is, then. Why do scala's own classes (such as `List` not extend the `NotNull` trait? – oxbow_lakes Feb 25 '10 at 16:27
  • And the other question, which is "do you use this trait?" – oxbow_lakes Feb 25 '10 at 18:04
  • If you're implementing Scala traits in Java (and other languages) the NotNull trait will be ignored. Another aspect is that a @NotNull annotation and static code analysis will be in Java 7. Don't see other reasons not to use it in Scala libs. – Thomas Jung Feb 25 '10 at 18:33
  • Do you use this trait? No. Have missed this part of the question. – Thomas Jung Feb 25 '10 at 18:34