« Return to Thread: Nonnullability

Re: Nonnullability

by Martin Odersky :: Rate this Message:

Reply to Author | View in Thread

On Thu, Jun 4, 2009 at 12:55 AM, Naftoli Gugenheim<naftoligug@...> wrote:

> 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.
>
NotNull is really work in progress, or I should rather say work in
suspension. As you noted, it needs much more refined analyses to avoid
having errors in lots of cases which are clearly
safe. So I cannot recommend to use NotNull right now. The planis to
come back to that eventually, but there are some other things on my
plate before that will happen.

Cheers

 -- Martin

 « Return to Thread: Nonnullability