« Return to Thread: Nonnullability

Nonnullability

by Naftoli Gugenheim :: Rate this Message:

Reply to Author | View in Thread

I am trying to understand the position of defining nonnullability as a property of a type rather that of a val/var/def.
For instance, I am writing a (so far very simple) app in Lift. There are tons of warnings everywhere an external method is called that returns a type that doesn't extend NotNull. I have an entity, called Nature. I made it extend NotNull. Now everywhere that had a valid possibility of a null Nature has to be changed to store an Option. Not the end of the world, although whether to use None or null to indicate emptiness should be the decision of the storage site, not the class -- why should such a decision be all or nothing? If the language would not have a concept of null it would be one thing. Okay. Now I want my helper lookup to return Seq[Nature] with NotNull. Now if nullability were a property of the site, you could check if the API lookup returns null and return Nil etc. instead. But being that Seq (or any type in a parallel situation) wasn't defined by me and the return value isn't instantiated by me, (and even if it was it wouldn't help for a final type) I can't ensure to return a subtype of NotNull. You can't just cast to NotNull. So for Seq you can use a SeqProxy as a hacky workaround.
Another use case is nonnullable Strings (that have to be java.lang.Strings for one reason or another, e.g. AppEngine JPA entities). (Anyway, for e.g. RichString to extend NotNull again imposes an arbitrary restriction across the board.)
But what's the logic? If there was a general mechanism to Not any type (specify that a value must not extend it) and that mechanism allowed one to Not(Null), I would understand. But the primary purpose is to provide null safety, which means a "recursive" guarantee of non-null-ness at a given point in code. So that seems to logically be a property of the code site. In other words, given a type T that extends AnyRef, since Null _is_ a subtype of every AnyRef, and a dangerous one, we want to know where we can guarantee that it doesn't actually get returned. So for example, there should be a way (i.e. an annotation or proof) for e.g. a method to tell the compiler that it guarantees not to return null, and every time a property of the method's return value is referenced the compiler no longer has to consider the possibility of null. Perhaps optional proof of null-less-ness would generate an annotation that could be written by hand instead. This would allow for gradual development of this feature (which can exist side-by-side with NotNull)--at first do not warn if a value is of a type that extends NotNull OR if it is annotated with @nonnull etc. Then, over time the compiler could generate the @nonull etc. annotation automatically based on various proofs. In fact, NotNull could be one kind of proof.
I wonder what will be different in 2.8 about NotNull, but I can't see the logic of specifying across the board what to do with a type, as long as the language doesn't prohibit null.
P.S. In any case, it would be nice if the concept of NotNull -- a filter in a complex type definition -- would be generalized to allow e.g. Seq with Not(mutable.Seq) or Person with Not(Employee). I know that this idea was brought up before, as well as ORing types.

Thanks, and waiting to hear what others have to say,
NG

 « Return to Thread: Nonnullability