Some(null)

View: New views
8 Messages — Rating Filter:   Alert me  

Some(null)

by Erkki Lindpere-2 :: Rate this Message:

Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message

Hi!

I'm rather new to Scala, but I've been getting familiar with it, having
just finished reading the early version of the book, and also having
read parts of the documentation earlier. I really like the language --
not all the details of it, but overall it seems to be very well designed
and a lot better than Java, while not going too far from it. I'm
starting to gradually replace Java with Scala in personal projects at least.

However, a few things are still confusing to me. For example, I have
some questions about the Option types:

Why is Some(null) allowed? Wouldn't it make more sense that when there's
an actual value for an Option, it should never be null? Currently it
goes against the way Option, None and Some have been advertised -- as
safer replacement for null checks. With the current implementation, you
still have to do the null check to be really sure. And actually, now
there can be two nulls instead of one: the Option itself can be null,
and Some.x can be null
Maybe I'm wrong, but there seem to be two changes that would make it
more typesafe:
1) The constructor Some(x) could at least be made to throw a NPE or IAE
for a null argument. Even better vould be an annotation like @notnull
for the parameters that the compiler could check
2) If possible, Option, Some and None should not have Null as their
subclass, just like AnyVal and its subclasses. Can this be done by
making them extend NotNull?

PS. I've been using Scala 2.6.0 mostly, sorry if this has changed already.

Erkki

Re: Some(null)

by Viktor Klang :: Rate this Message:

Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message

Yes, IMHO Some(null) shouldn't be allowed.

Also, being able to specify non-nullness in a concise and rational way would be awesome.

Cheers,
Viktor

On Jan 2, 2008 7:26 PM, Erkki Lindpere < erkki@...> wrote:
Hi!

I'm rather new to Scala, but I've been getting familiar with it, having
just finished reading the early version of the book, and also having
read parts of the documentation earlier. I really like the language --
not all the details of it, but overall it seems to be very well designed
and a lot better than Java, while not going too far from it. I'm
starting to gradually replace Java with Scala in personal projects at least.

However, a few things are still confusing to me. For example, I have
some questions about the Option types:

Why is Some(null) allowed? Wouldn't it make more sense that when there's
an actual value for an Option, it should never be null? Currently it
goes against the way Option, None and Some have been advertised -- as
safer replacement for null checks. With the current implementation, you
still have to do the null check to be really sure. And actually, now
there can be two nulls instead of one: the Option itself can be null,
and Some.x can be null
Maybe I'm wrong, but there seem to be two changes that would make it
more typesafe:
1) The constructor Some(x) could at least be made to throw a NPE or IAE
for a null argument. Even better vould be an annotation like @notnull
for the parameters that the compiler could check
2) If possible, Option, Some and None should not have Null as their
subclass, just like AnyVal and its subclasses. Can this be done by
making them extend NotNull?

PS. I've been using Scala 2.6.0 mostly, sorry if this has changed already.

Erkki



--
_____________________________________
/                                                                 \
       /lift/ committer (www.liftweb.net)
     SGS member (Scala Group Sweden)
 SEJUG member (Swedish Java User Group)
\_____________________________________/

Re: Some(null)

by Jamie Webb-2 :: Rate this Message:

Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message

On 2008-01-02 19:57:09 Viktor Klang wrote:
> Yes, IMHO Some(null) shouldn't be allowed.

There's a problem with that, in that at present Scala makes a good stab
at being 'null transparent', e.g. you can store nulls in HashMaps.
Disallowing Some(null) would break that.

Bear in mind also that disallowing Some(null) really buys you very
little extra safety. What about all those references that aren't
Options? Sure you don't check every single one for null?

There was an attempt a while back to modify the compiler to implement
Option in terms of null, which would have been great for performance.
Unfortunately there were some complications. I think I saw a way around
those which involves treating Option as a value rather than reference
type (which would permit Some(null) but make the Option itself
non-nullable). But that would probably be a fairly deep compiler
change, and there's been no interest from the relevant people.

/J

Re: Some(null)

by Viktor Klang :: Rate this Message:

Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message



On Jan 2, 2008 9:12 PM, Jamie Webb <j@...> wrote:
On 2008-01-02 19:57:09 Viktor Klang wrote:
> Yes, IMHO Some(null) shouldn't be allowed.

There's a problem with that, in that at present Scala makes a good stab
at being 'null transparent', e.g. you can store nulls in HashMaps.
Disallowing Some(null) would break that.

Bear in mind also that disallowing Some(null) really buys you very
little extra safety. What about all those references that aren't
Options? Sure you don't check every single one for null?

There was an attempt a while back to modify the compiler to implement
Option in terms of null, which would have been great for performance.
Unfortunately there were some complications. I think I saw a way around
those which involves treating Option as a value rather than reference
type (which would permit Some(null) but make the Option itself
non-nullable). But that would probably be a fairly deep compiler
change, and there's been no interest from the relevant people.

/J

Making Some-declarations non-nullable would be awesome.

def strlen( x : Some[String])  = x.get.length

x Can't be null and Some can't be Some(null)

I wouldn't mind this only working for Option so that:

def strlen(x : Option[String]) : ...code goes here //x can be Some(nonnull) or None, but never null
def strlen(x : Some[String]) : ...code goes here //x can only be Some(nonnull)
def strlen(x  : None[String]) : .... x can only be None


Of course it isn't easy to implement, but if everything was easy, we wouldn't be as great now would we?


Cheers,
-- Viktor
_____________________________________
/                                                                 \
       /lift/ committer (www.liftweb.net)
     SGS member (Scala Group Sweden)
 SEJUG member (Swedish Java User Group)
\_____________________________________/

Re: Some(null)

by Erkki Lindpere-2 :: Rate this Message:

Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message

Thanks for the explanation, I can see the point now. It's just too bad
that I can't rely on using Option in APIs and always assume that
everyone will be using it properly.

But isn't making Option itself non-nullable just a matter of mixing in
the NotNull trait? Which is defined so:

package scala
/** A marker thread for things that are not allowed to be null */
trait NotNull {}

And I also think a general @notnull annotation would be quite useful for
things not allowed to be null -- in the context of method arguments
mostly -- but it could also replace the trait NotNull for types IMHO.

Erkki

Jamie Webb wrote:

> On 2008-01-02 19:57:09 Viktor Klang wrote:
>  
>> Yes, IMHO Some(null) shouldn't be allowed.
>>    
>
> There's a problem with that, in that at present Scala makes a good stab
> at being 'null transparent', e.g. you can store nulls in HashMaps.
> Disallowing Some(null) would break that.
>
> Bear in mind also that disallowing Some(null) really buys you very
> little extra safety. What about all those references that aren't
> Options? Sure you don't check every single one for null?
>
> There was an attempt a while back to modify the compiler to implement
> Option in terms of null, which would have been great for performance.
> Unfortunately there were some complications. I think I saw a way around
> those which involves treating Option as a value rather than reference
> type (which would permit Some(null) but make the Option itself
> non-nullable). But that would probably be a fairly deep compiler
> change, and there's been no interest from the relevant people.
>
> /J
>
>  

Re: Some(null)

by Geoffrey Alan Washburn-4 :: Rate this Message:

Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message

Erkki Lindpere wrote:

> Thanks for the explanation, I can see the point now. It's just too bad
> that I can't rely on using Option in APIs and always assume that
> everyone will be using it properly.
>
> But isn't making Option itself non-nullable just a matter of mixing in
> the NotNull trait? Which is defined so:
>
> package scala
> /** A marker thread for things that are not allowed to be null */
> trait NotNull {}

You could use something like this as hint to yourself, but it cannot be
used to enforce anything.  It is not also possible to use it the way you
would like in many cases.  For example,

   scala> val x = new String("foo") with NonNull
   <console>:5: error: illegal inheritance from final class
   val x = new String("foo") with NonNull
               ^

or

   scala> val x = new List with NonNull
   <console>:5: error: illegal inheritance from sealed class List
   val x = new List with NonNull
               ^

We are currently thinking about adding something like this to the
language however.  That way you could write something like

   val x = new String("foo")

and »x« would have type »String with NonNull«.  Writing

   val (x : String with NonNull) = null

would then be a static type error.

That part is relatively straightforward.  The main difficulty is to come
up with a nice way of handling and introducing refinements when a user
writes something like:

   if (x != null) {
     // x has type A with NonNull here
   } else {
     // x just has type A here
   }

Given that the conditional could contain arbitrarily complicated tests,
this is nontrivial.  A less ambitious implementation would only allow
refinement to occur when using the match primitive:

   x match { case null => // x just has type A here
             case ... // x has type A with NonNull for remaining cases  }

This makes it easier for the type checker to keep track of what is being
refined and the scope of the refinement.



Re: Re: Some(null)

by Erkki Lindpere-2 :: Rate this Message:

Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message

Thanks for the info! It's good to know that something to handle this is
considered to be added to the language. But what I meant was that for
the single case of making Option not nullable (but still allowing
Some(null)), isn't it just a matter of changing the current Option class
itself, from:

 sealed abstract class Option[+A] extends Product

to

 sealed abstract class Option[+A] extends Product with NotNull

Erkki

Geoffrey Alan Washburn wrote:

> Erkki Lindpere wrote:
>> Thanks for the explanation, I can see the point now. It's just too
>> bad that I can't rely on using Option in APIs and always assume that
>> everyone will be using it properly.
>>
>> But isn't making Option itself non-nullable just a matter of mixing
>> in the NotNull trait? Which is defined so:
>>
>> package scala
>> /** A marker thread for things that are not allowed to be null */
>> trait NotNull {}
>
> You could use something like this as hint to yourself, but it cannot
> be used to enforce anything.  It is not also possible to use it the
> way you would like in many cases.  For example,
>
>   scala> val x = new String("foo") with NonNull
>   <console>:5: error: illegal inheritance from final class
>   val x = new String("foo") with NonNull
>               ^
>
> or
>
>   scala> val x = new List with NonNull
>   <console>:5: error: illegal inheritance from sealed class List
>   val x = new List with NonNull
>               ^
>
> We are currently thinking about adding something like this to the
> language however.  That way you could write something like
>
>   val x = new String("foo")
>
> and »x« would have type »String with NonNull«.  Writing
>
>   val (x : String with NonNull) = null
>
> would then be a static type error.
>
> That part is relatively straightforward.  The main difficulty is to
> come up with a nice way of handling and introducing refinements when a
> user writes something like:
>
>   if (x != null) {
>     // x has type A with NonNull here
>   } else {
>     // x just has type A here
>   }
>
> Given that the conditional could contain arbitrarily complicated
> tests, this is nontrivial.  A less ambitious implementation would only
> allow refinement to occur when using the match primitive:
>
>   x match { case null => // x just has type A here
>             case ... // x has type A with NonNull for remaining cases  }
>
> This makes it easier for the type checker to keep track of what is
> being refined and the scope of the refinement.
>
>

Re: Some(null)

by Geoffrey Alan Washburn-4 :: Rate this Message:

Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message

Erkki Lindpere wrote:

> Thanks for the info! It's good to know that something to handle this is
> considered to be added to the language. But what I meant was that for
> the single case of making Option not nullable (but still allowing
> Some(null)), isn't it just a matter of changing the current Option class
> itself, from:
>
> sealed abstract class Option[+A] extends Product
>
> to
>
> sealed abstract class Option[+A] extends Product with NotNull

   Okay, yes this is possible.  I had not realized that there was
already a class NotNull in the standard library.  Doing this at present
will still not enforce that instances of type Option[A] are not null,
but it might be worthwhile adding the NotNull trait to some classes as
documentation until nullness checking is implemented.