How does the NotNull trait work in 2.8 and does anyone actually use it?
Asked Answered
G

2

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

Gahl answered 25/2, 2010 at 16:8 Comment(6)
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 <console>Anaemic
NotNull doesn't really work yet. As far as I know, it is work in progress, much like Manifest in Scala 2.7.Funchal
@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!Gahl
Started 05/01/07 : lampsvn.epfl.ch/trac/scala/changeset/10892Anaemic
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.Funchal
It appears that NotNull is being deprecated: issues.scala-lang.org/browse/SI-7247Fibrous
A
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.

Anaemic answered 25/2, 2010 at 16:21 Comment(4)
The corollary to this is, then. Why do scala's own classes (such as List not extend the NotNull trait?Gahl
And the other question, which is "do you use this trait?"Gahl
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.Anaemic
Do you use this trait? No. Have missed this part of the question.Anaemic
S
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.

Saturday answered 4/3, 2010 at 22:42 Comment(3)
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.Gahl
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.Invocation
Addition: It was removed in PR #5683, included in 2.13.0 Milestone 1 from April 2017: github.com/scala/scala/pull/5683Invocation
A
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.

Anaemic answered 25/2, 2010 at 16:21 Comment(4)
The corollary to this is, then. Why do scala's own classes (such as List not extend the NotNull trait?Gahl
And the other question, which is "do you use this trait?"Gahl
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.Anaemic
Do you use this trait? No. Have missed this part of the question.Anaemic

© 2022 - 2024 — McMap. All rights reserved.