|
View:
New views
9 Messages
—
Rating Filter:
Alert me
|
|
|
NonnullabilityI 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 |
|
|
Re: NonnullabilityThe reason is that we only want to do it once per type, not on every
single declaration. If it bothers you, write a Nullable[T] that behaves like Option[T], but defines n=null to be like n=None, and gives toString appropriately. Don't try to get equals/hashCode semantics right transparently, you won't. 2009/6/3 Naftoli Gugenheim <naftoligug@...>: > 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 > |
|
|
|
|
|
|
|
|
Re: NonnullabilityHi Naftoli,
I use FindBugs (http://findbugs.sourceforge.net/) with JSR-305, and their special annotations (sadly not all available with Scala 2.7.x, hopefully 2.8.x will make them work). Basically that is really helpful for programming. Although Julia might be a better choice for null checks. (http://julia.scienze.univr.it:8080/julia/ http://www.youtube.com/watch?v=3d0YlZbY92U) Bests, gabor Naftoli Gugenheim wrote: > Isn't there anyone else that uses compiler null checks? > Also, in 2.8 do many scala library classes extend NotNull? > > On 6/4/09, Naftoli Gugenheim <naftoligug@...> wrote: >> Hi. I certainly understand how NotNull is much more convenent than >> annotating potentially every definition! However, as I pointed out in my >> message, it does not seem to suffice to prevent nulls in the many places >> that use non-user types. In a simple lift program that for the most part one >> file with two related models and one snippet source file (so far ;)), amost >> the entire snippet file is flooded with warnings about nullability! Pretty >> soon you just filter out the warnings mentally. >> myEntity.name has to be a String, not a Nullable[String]. If any function f >> possibly returns a value that's defined in a library (e.g. a function call), >> there's no way to use properies of the return value of f without getting >> warnings. So I can't keep track of where null is indeed a danger. >> My suggestion was for now, to allow for a definition or type annotation to >> be annotated as a guarantee to the compiler that it will never equal null. >> When the type inherits NotNull, the compiler should add this annotation >> automatically. Eventually, NotNull could be seen as one possible proof of >> nonnullability, and other proofs could be added. For example: >> def getAll = em.createNamedQuery[Author]("findAllAuthors", >> "id"->id).getResultList match { >> case null => Nil >> case seq => seq >> } >> But the various proofs don't need to be added right now. Right now only one >> small change would make a big difference: allow definitions (or type >> annotations) to be annotated with a user guarantee that it won't be null, >> and suppress nullability warnings in such cases. And it could be simplified >> into one rule, by generating such annotations for types inheriting NotNull. >> >> >> -----Original Message----- >> From: Ricky Clarkson <ricky.clarkson@...> >> Sent: Thursday, June 04, 2009 4:21 AM >> To: Naftoli Gugenheim <naftoligug@...> >> Cc: scala-debate@... >> Subject: Re: [scala-debate] Nonnullability >> >> The reason is that we only want to do it once per type, not on every >> single declaration. If it bothers you, write a Nullable[T] that >> behaves like Option[T], but defines n=null to be like n=None, and >> gives toString appropriately. Don't try to get equals/hashCode >> semantics right transparently, you won't. >> >> 2009/6/3 Naftoli Gugenheim <naftoligug@...>: >>> 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 >>> > |
|
|
|
|
|
|
|
|
Re: NonnullabilityOn 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. > 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 |
|
|
|
| Free embeddable forum powered by Nabble | Forum Help |