This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Some(null)?

8 replies
Michael Fortin
Joined: 2010-02-16,
User offline. Last seen 42 years 45 weeks ago.

Hello everyone,
Is my understanding of the Option class wrong is or this a bug? Some should never have a null value, right? It should be None. What's the correct way to check for null values? In a debugger, It's failing on 'case s: Some[…]' and and Some has a null value. It works if I change "repositories" -> null to a List(). I'm using Scala 2.8 RC2.

scala> case class Repository(m:Map[String,AnyRef])
defined class Repository

scala> class Demo(map:Map[String,AnyRef]) {
| val name: Option[String] = map.get("name").asInstanceOf[Option[String]].orElse(None)
| val repositories: Option[List[Repository]] = map.get("repositories") match {
| case s: Some[List[Map[String, AnyRef]]] => Option(s.get.map(i => new Repository(i)).toList)
| case _ => None
| }
| }
warning: there were unchecked warnings; re-run with -unchecked for details
defined class Demo

scala> val map = Map("name" -> "test", "repositories" -> null)
map: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map((name,test), (repositories,null))

scala> val demo = new Demo(map)
java.lang.NullPointerException
at Demo.(:10)
at .(:9)
at .()
at RequestResult$.(:9)
at RequestResult$.()
at RequestResult$scala_repl_result()
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at scala.tools.nsc.Interpreter$Request$$anonfun$loadAndRun$1$$anonfun$apply$18.apply(Interpreter.scala:984)
at scala.tools.nsc.Interpreter$Request$$anonfun$loadAndRun$1$$anonfun$apply$18.apply(Interpreter.scala:984)
at scala.util.control.Exception$Catch.apply(Exception...
scala>

_Mike
_404_964_5337

Viktor Klang
Joined: 2008-12-17,
User offline. Last seen 1 year 27 weeks ago.
Re: Some(null)?


On Mon, May 24, 2010 at 4:22 PM, Michael Fortin <michael@m410.us> wrote:
Hello everyone,
Is my understanding of the Option class wrong is or this a bug?  Some should never have a null value, right?  It should be None.  What's the correct way to check for null values?  In a debugger, It's failing on 'case s: Some[…]' and and Some has a null value.  It works if I change "repositories" -> null to a List().  I'm using Scala 2.8 RC2.

No, you got it wrong.

Some(null) <-- There's a value, and it's value is null
None <-- There's no value

Also, if you're on Scala 2.8:

scala> val s = Option(null)
s: Option[Null] = None

 

scala> case class Repository(m:Map[String,AnyRef])
defined class Repository

scala> class Demo(map:Map[String,AnyRef]) {
    | val name: Option[String] = map.get("name").asInstanceOf[Option[String]].orElse(None)
    | val repositories: Option[List[Repository]] = map.get("repositories") match {
    |     case s: Some[List[Map[String, AnyRef]]] => Option(s.get.map(i => new Repository(i)).toList)
    |     case _ => None
    | }
    | }
warning: there were unchecked warnings; re-run with -unchecked for details
defined class Demo

scala> val map = Map("name"  -> "test", "repositories" -> null)
map: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map((name,test), (repositories,null))

scala> val demo = new Demo(map)
java.lang.NullPointerException
       at Demo.<init>(<console>:10)
       at .<init>(<console>:9)
       at .<clinit>(<console>)
       at RequestResult$.<init>(<console>:9)
       at RequestResult$.<clinit>(<console>)
       at RequestResult$scala_repl_result(<console>)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:597)
       at scala.tools.nsc.Interpreter$Request$$anonfun$loadAndRun$1$$anonfun$apply$18.apply(Interpreter.scala:984)
       at scala.tools.nsc.Interpreter$Request$$anonfun$loadAndRun$1$$anonfun$apply$18.apply(Interpreter.scala:984)
       at scala.util.control.Exception$Catch.apply(Exception...
scala>


_Mike
_404_964_5337




--
Viktor Klang
| "A complex system that works is invariably
| found to have evolved from a simple system
| that worked." - John Gall

Akka - the Actor Kernel: Akkasource.org
Twttr: twitter.com/viktorklang
ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
Re: Some(null)?
If you store a null value in a map, and you ask for it, you'll get the null value back; if you ask for it using get, which returns an option, you get Some(null).

What are you trying to accomplish with having the entry "repositories" -> null in the map in the first place?

Regardless, if you have a null you have to deal with it in standard ways (e.g. test for "eq null").  Note also that if you're wrapping things yourself,  Some(null) does indeed return a wrapped null, but Option(null) gives None.

  --Rex

On Mon, May 24, 2010 at 10:22 AM, Michael Fortin <michael@m410.us> wrote:
Hello everyone,
Is my understanding of the Option class wrong is or this a bug?  Some should never have a null value, right?  It should be None.  What's the correct way to check for null values?  In a debugger, It's failing on 'case s: Some[…]' and and Some has a null value.  It works if I change "repositories" -> null to a List().  I'm using Scala 2.8 RC2.

scala> case class Repository(m:Map[String,AnyRef])
defined class Repository

scala> class Demo(map:Map[String,AnyRef]) {
    | val name: Option[String] = map.get("name").asInstanceOf[Option[String]].orElse(None)
    | val repositories: Option[List[Repository]] = map.get("repositories") match {
    |     case s: Some[List[Map[String, AnyRef]]] => Option(s.get.map(i => new Repository(i)).toList)
    |     case _ => None
    | }
    | }
warning: there were unchecked warnings; re-run with -unchecked for details
defined class Demo

scala> val map = Map("name"  -> "test", "repositories" -> null)
map: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map((name,test), (repositories,null))

scala> val demo = new Demo(map)
java.lang.NullPointerException
       at Demo.<init>(<console>:10)
       at .<init>(<console>:9)
       at .<clinit>(<console>)
       at RequestResult$.<init>(<console>:9)
       at RequestResult$.<clinit>(<console>)
       at RequestResult$scala_repl_result(<console>)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:597)
       at scala.tools.nsc.Interpreter$Request$$anonfun$loadAndRun$1$$anonfun$apply$18.apply(Interpreter.scala:984)
       at scala.tools.nsc.Interpreter$Request$$anonfun$loadAndRun$1$$anonfun$apply$18.apply(Interpreter.scala:984)
       at scala.util.control.Exception$Catch.apply(Exception...
scala>


_Mike
_404_964_5337


Michael Fortin
Joined: 2010-02-16,
User offline. Last seen 42 years 45 weeks ago.
Re: Some(null)?
Thanks Rex & Viktor for the clarifications.  
All the values in the class are optional so while trying to unit test it, I got the error, but clearly my understanding was wrong.  
Thanks again._Mike
On May 24, 2010, at 10:29 AM, Rex Kerr wrote:
If you store a null value in a map, and you ask for it, you'll get the null value back; if you ask for it using get, which returns an option, you get Some(null).

What are you trying to accomplish with having the entry "repositories" -> null in the map in the first place?

Regardless, if you have a null you have to deal with it in standard ways (e.g. test for "eq null").  Note also that if you're wrapping things yourself,  Some(null) does indeed return a wrapped null, but Option(null) gives None.

  --Rex

On Mon, May 24, 2010 at 10:22 AM, Michael Fortin <michael@m410.us> wrote:
Hello everyone,
Is my understanding of the Option class wrong is or this a bug?  Some should never have a null value, right?  It should be None.  What's the correct way to check for null values?  In a debugger, It's failing on 'case s: Some[…]' and and Some has a null value.  It works if I change "repositories" -> null to a List().  I'm using Scala 2.8 RC2.

scala> case class Repository(m:Map[String,AnyRef])
defined class Repository

scala> class Demo(map:Map[String,AnyRef]) {
    | val name: Option[String] = map.get("name").asInstanceOf[Option[String]].orElse(None)
    | val repositories: Option[List[Repository]] = map.get("repositories") match {
    |     case s: Some[List[Map[String, AnyRef]]] => Option(s.get.map(i => new Repository(i)).toList)
    |     case _ => None
    | }
    | }
warning: there were unchecked warnings; re-run with -unchecked for details
defined class Demo

scala> val map = Map("name"  -> "test", "repositories" -> null)
map: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map((name,test), (repositories,null))

scala> val demo = new Demo(map)
java.lang.NullPointerException
       at Demo.<init>(<console>:10)
       at .<init>(<console>:9)
       at .<clinit>(<console>)
       at RequestResult$.<init>(<console>:9)
       at RequestResult$.<clinit>(<console>)
       at RequestResult$scala_repl_result(<console>)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:597)
       at scala.tools.nsc.Interpreter$Request$$anonfun$loadAndRun$1$$anonfun$apply$18.apply(Interpreter.scala:984)
       at scala.tools.nsc.Interpreter$Request$$anonfun$loadAndRun$1$$anonfun$apply$18.apply(Interpreter.scala:984)
       at scala.util.control.Exception$Catch.apply(Exception...
scala>


_Mike
_404_964_5337



H-star Development
Joined: 2010-04-14,
User offline. Last seen 2 years 26 weeks ago.
Re: Some(null)?

Some(null) is something that should not exists because the programmer
doesn't put it there
my understanding of Option[T] is that a method may return a value
(option.get) or nothing (None). neither Some(null) nor null itself are
valid return values. they are technically possible, but always caused by
a bug.
the benefit of this is that by NOT using an option, i implicitly know
that if null is returned, it is a bug and i do not need to check if the
result is null - and for methods that return an option, i know that null
or Some(null) is always caused by a bug.

using the java null, i cannot differentiate between "oops, null" and
"null is a valid return value and means xy"

Michael Fortin schrieb:
> Hello everyone,
> Is my understanding of the Option class wrong is or this a bug? Some should never have a null value, right? It should be None. What's the correct way to check for null values? In a debugger, It's failing on 'case s: Some[…]' and and Some has a null value. It works if I change "repositories" -> null to a List(). I'm using Scala 2.8 RC2.
>
> scala> case class Repository(m:Map[String,AnyRef])
> defined class Repository
>
> scala> class Demo(map:Map[String,AnyRef]) {
> | val name: Option[String] = map.get("name").asInstanceOf[Option[String]].orElse(None)
> | val repositories: Option[List[Repository]] = map.get("repositories") match {
> | case s: Some[List[Map[String, AnyRef]]] => Option(s.get.map(i => new Repository(i)).toList)
> | case _ => None
> | }
> | }
> warning: there were unchecked warnings; re-run with -unchecked for details
> defined class Demo
>
> scala> val map = Map("name" -> "test", "repositories" -> null)
> map: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map((name,test), (repositories,null))
>
> scala> val demo = new Demo(map)
> java.lang.NullPointerException
> at Demo.(:10)
> at .(:9)
> at .()
> at RequestResult$.(:9)
> at RequestResult$.()
> at RequestResult$scala_repl_result()
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> at java.lang.reflect.Method.invoke(Method.java:597)
> at scala.tools.nsc.Interpreter$Request$$anonfun$loadAndRun$1$$anonfun$apply$18.apply(Interpreter.scala:984)
> at scala.tools.nsc.Interpreter$Request$$anonfun$loadAndRun$1$$anonfun$apply$18.apply(Interpreter.scala:984)
> at scala.util.control.Exception$Catch.apply(Exception...
> scala>
>
>
> _Mike
> _404_964_5337
>
>

H-star Development
Joined: 2010-04-14,
User offline. Last seen 2 years 26 weeks ago.
Re: Some(null)?

that is possible, but i wouldn't do it. intentionally returning "null"
always forces the caller to be in possession of secret knowlege.

Viktor Klang schrieb:
>
>
> On Mon, May 24, 2010 at 4:22 PM, Michael Fortin > wrote:
>
> Hello everyone,
> Is my understanding of the Option class wrong is or this a bug?
> Some should never have a null value, right? It should be None.
> What's the correct way to check for null values? In a debugger,
> It's failing on 'case s: Some[…]' and and Some has a null value.
> It works if I change "repositories" -> null to a List(). I'm
> using Scala 2.8 RC2.
>
>
> No, you got it wrong.
>
> Some(null) <-- There's a value, and it's value is null
> None <-- There's no value
>
> Also, if you're on Scala 2.8:
>
> scala> val s = Option(null)
> s: Option[Null] = None
>
>
>
>
> scala> case class Repository(m:Map[String,AnyRef])
> defined class Repository
>
> scala> class Demo(map:Map[String,AnyRef]) {
> | val name: Option[String] =
> map.get("name").asInstanceOf[Option[String]].orElse(None)
> | val repositories: Option[List[Repository]] =
> map.get("repositories") match {
> | case s: Some[List[Map[String, AnyRef]]] =>
> Option(s.get.map(i => new Repository(i)).toList)
> | case _ => None
> | }
> | }
> warning: there were unchecked warnings; re-run with -unchecked for
> details
> defined class Demo
>
> scala> val map = Map("name" -> "test", "repositories" -> null)
> map:
> scala.collection.immutable.Map[java.lang.String,java.lang.String]
> = Map((name,test), (repositories,null))
>
> scala> val demo = new Demo(map)
> java.lang.NullPointerException
> at Demo.(:10)
> at .(:9)
> at .()
> at RequestResult$.(:9)
> at RequestResult$.()
> at RequestResult$scala_repl_result()
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> at java.lang.reflect.Method.invoke(Method.java:597)
> at
> scala.tools.nsc.Interpreter$Request$$anonfun$loadAndRun$1$$anonfun$apply$18.apply(Interpreter.scala:984)
> at
> scala.tools.nsc.Interpreter$Request$$anonfun$loadAndRun$1$$anonfun$apply$18.apply(Interpreter.scala:984)
> at scala.util.control.Exception$Catch.apply(Exception...
> scala>
>
>
> _Mike
> _404_964_5337
>
>
>
>

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: Some(null)?

On Mon, May 24, 2010 at 10:22:38AM -0400, Michael Fortin wrote:
> Is my understanding of the Option class wrong is or this a bug? Some
> should never have a null value, right? It should be None.

Mr. Googly says we've discussed this a bunch of times. It is not
possible to disallow Some(null) given current API and semantics.

http://scala-programming-language.1934581.n4.nabble.com/Option-T-and-nul...

Viktor Klang
Joined: 2008-12-17,
User offline. Last seen 1 year 27 weeks ago.
Re: Some(null)?


On Mon, May 24, 2010 at 5:25 PM, Paul Phillips <paulp@improving.org> wrote:
On Mon, May 24, 2010 at 10:22:38AM -0400, Michael Fortin wrote:
> Is my understanding of the Option class wrong is or this a bug?  Some
> should never have a null value, right?  It should be None.

Mr. Googly says we've discussed this a bunch of times.  It is not
possible to disallow Some(null) given current API and semantics.

http://scala-programming-language.1934581.n4.nabble.com/Option-T-and-null-td2008053.html


A bit unnerving to see that I participated in that one as well...
 
--
Paul Phillips      | Where there's smoke, there's mirrors!
Imperfectionist    |
Empiricist         |
up hill, pi pals!  |----------* http://www.improving.org/paulp/ *----------



--
Viktor Klang
| "A complex system that works is invariably
| found to have evolved from a simple system
| that worked." - John Gall

Akka - the Actor Kernel: Akkasource.org
Twttr: twitter.com/viktorklang
Kevin Wright
Joined: 2009-06-09,
User offline. Last seen 49 weeks 4 days ago.
Re: Some(null)?
All the best people were :)

On 24 May 2010 16:28, Viktor Klang <viktor.klang@gmail.com> wrote:


On Mon, May 24, 2010 at 5:25 PM, Paul Phillips <paulp@improving.org> wrote:
On Mon, May 24, 2010 at 10:22:38AM -0400, Michael Fortin wrote:
> Is my understanding of the Option class wrong is or this a bug?  Some
> should never have a null value, right?  It should be None.

Mr. Googly says we've discussed this a bunch of times.  It is not
possible to disallow Some(null) given current API and semantics.

http://scala-programming-language.1934581.n4.nabble.com/Option-T-and-null-td2008053.html


A bit unnerving to see that I participated in that one as well...
 
--
Paul Phillips      | Where there's smoke, there's mirrors!
Imperfectionist    |
Empiricist         |
up hill, pi pals!  |----------* http://www.improving.org/paulp/ *----------



--
Viktor Klang
| "A complex system that works is invariably
| found to have evolved from a simple system
| that worked." - John Gall

Akka - the Actor Kernel: Akkasource.org
Twttr: twitter.com/viktorklang



--
Kevin Wright

mail/google talk: kev.lee.wright@googlemail.com
wave: kev.lee.wright@googlewave.com
skype: kev.lee.wright
twitter: @thecoda

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland