The Artima Developer Community
Sponsored Link

Java Community News
David Pollak on Scala's Option Class

14 replies on 1 page. Most recent reply: Jun 19, 2008 2:44 PM by David López

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 14 replies on 1 page
Frank Sommers

Posts: 2642
Nickname: fsommers
Registered: Jan, 2002

David Pollak on Scala's Option Class Posted: Apr 18, 2007 6:02 PM
Reply to this message Reply
Summary
In Java, developers often return null from a method to indicate that the method call succeeded, albeit without any meaningful return value. Scala, an object-oriented functional language that runs on the JVM, has a more elegant way to deal with null-like returns: The Option class.
Advertisement

Scala is an object-oriented functional language that targets the JVM. As developers search for languages that allow them to use the JVM and, at the same time, boost programmer productivity compared with the Java language, Scala emerged as a strong, although somewhat academic, contender.

David Pollak, who pioneered applying Scala to enterprise Web development with the lift framework, highlights a convenient Scala language feature in his recent blog post, The Scala Option class and how lift uses it.

Pollak's starting point for introducing Scala's Option class is the frequently encountered Java pattern of using null to indicate that, while a method call didn't fail, it also produced no meaningful results. For instance, null might be returned to indicate that a user with a specified user name was not found.

While preferable to an exception—not finding a user is hardly an exceptional condition—Java does not define a type and, consequently, methods for null. Code that can reasonably expect to receive a null response but does not check for null can easily generate NullPointerExceptions, for instance.

Those working with languages that treat null as a more equal-footed participant in the type system, such as in Ruby, can appreciate the convenience of being able to invoke nil? on a null value, for instance.

David Pollak shows in his blog post how Scala's Option class takes this concept even further. According to Pollak,

Scala does something different. There's an abstract class, called Option. Options are strongly typed. They are declared Option[T]. This means an Option can be of any type, but once its type is defined, it does not change. There are two subclasses of Option: Some and None. None is a singleton (like nil). Some is a container around the actual answer. So, you might have a method that looks like:

 def findUser(name: String): Option[User] = {
  val query = buildQuery(name)
  val resultSet = performQuery(query)
  val retVal = if (resultSet.next) Some(createUser(resultSet))
               else None
  resultSet.close
  retVal
}

Pollak shows that Options are especially useful in the context of Scala's rich collection's API, because:

Turns out that Option implements map, flatMap, and filter (the methods necessary for the Scala compiler to use in the 'for' comprehension...) So... you can use this construct very effectively. [Editor's note: The for comprehension is basically an iteration over elements of a collection, passing some code to each element.]

Pollak shows how he uses Options to simplify coding in his lift framework:

That means you get code that looks like:

  def confirmDelete {
    (for (val id <- param("id"); // get the ID
          val user <- User.find(id)) // find the user                                                                          
     yield {
         user.delete_!
         notice("User deleted")
         redirectTo("/simple/index.html")
       }) getOrElse {error("User not found"); redirectTo("/simple/index.html")}
   }

There's no explicit guard/test to see if the "id" parameter was passed in and there's no explicit test to see if the user was found. If the id isn't supplied or the id doesn't match a user in the system, the "else" clause will execute. Note also that this code is completely type-safe. While there was no explicit type declarations, the compiler was able to figure out what types the various objects were.

What do you think of Scala's Option class?


Rafael Ferreira

Posts: 8
Nickname: rafaeldff
Registered: Feb, 2006

Re: David Pollak on Scala's Option Class Posted: Apr 18, 2007 7:32 PM
Reply to this message Reply
While using Option with for comprehensions looks like an useful idiom, I thought I should point out that the more trivial, obvious, way of dealing with Options is through pattern matching, like this:


User.find(id) match {
case Some(user) => user.delete_!
case None => error("Not found")
}

Morel Xavier

Posts: 73
Nickname: masklinn
Registered: Sep, 2005

Re: David Pollak on Scala's Option Class Posted: Apr 19, 2007 3:07 AM
Reply to this message Reply
> <p>What do you think of Scala's <code>Option</code> class?
> </p>

Never used it, but it's of course a reimplementation of Haskell's Maybe monad which I really like. So I dig it.

And as Rafael Ferreira mentioned it, Maybe (and by extension Option) really shine when used together with pattern-matching.

nes

Posts: 137
Nickname: nn
Registered: Jul, 2004

Re: David Pollak on Scala's Option Class Posted: Apr 19, 2007 12:08 PM
Reply to this message Reply
As others said it’s Maybe with a different name. On a somewhat related note I prefer exceptions to nulls. I don’t see why you couldn’t have a UserNotFound exception. For me exceptions are just a mechanism that allow me to return values of different types from a function and handle them differently on the callers end.

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: David Pollak on Scala's Option Class Posted: Apr 19, 2007 1:05 PM
Reply to this message Reply
> As others said it’s Maybe with a different name. On a
> somewhat related note I prefer exceptions to nulls. I
> don’t see why you couldn’t have a UserNotFound exception.
> For me exceptions are just a mechanism that allow me to
> return values of different types from a function and
> handle them differently on the callers end.

I prefer to reserve Exceptions for abnormal conditions. User not found doesn't necessarily imply that some thing odd has happened. I would want an exception if the code was unable to determine whether the user exists.

I can definitely see that this can be useful but neither the original example nor the case example are fundamentally different than a check for null. There is an explicit handling of the not found condition. In the case class it's an explicit code branch. In the original example, I fail to see how this is superior to checking for a null. It seems quite a bit more complex. There may be other benefits but they are not apparent from this example.

Where I see the advantage of this is when you don't want to do anything special when nothing is found. The common approach in Java is to return empty collections instead of nulls for this reason. This approach isn't optimal when the method will return 1 or 0 elements which is where Scala approach shines. This is also the reason I don't want to have an exception thrown. I don't want to be forced to write error handling that does nothing. This is a common problem with Integer.parse in Java. It throws an exception when the input is not a valid number. Often the caller wants to do something if the input is a valid number but if it's not, just move on.

nes

Posts: 137
Nickname: nn
Registered: Jul, 2004

Re: David Pollak on Scala's Option Class Posted: Apr 19, 2007 2:20 PM
Reply to this message Reply
One benefit of using exceptions for this is that you are documenting alternate return types, but the biggest gain from exceptions comes not from the actual text of the code written but from the good compile-time/runtime error messages. A good example is comparing the API for Java’s Hashmaps versus Python dictionaries:

Example 1:

result=hm.get(food)
…some code…
if(result.equals(foodType)) doSomething();


Example 2:

result=hm[food]
…some code…
if result==foodType: doSomething()


Example 3:

result=hm.get(food,”default”)
…some code…
if result==foodType: doSomething()


Example 1 is a typical example of the kind of error I would do as a beginning Java programmer. You get a null pointer exception on the last line and have to start working your way up in the code until you find the problem.

Example 2 is the same thing in Python: you get hm[food] KeyError: 'apple' on the first line, it doesn’t get any clearer than that.

Example 3 is probably the most flexible and allows you to choose any default value even null.

This is one example of an API where I think the decision to use an exception is better than returning null.

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: David Pollak on Scala's Option Class Posted: Apr 19, 2007 2:31 PM
Reply to this message Reply
> Example 1 is a typical example of the kind of error I
> would do as a beginning Java programmer. You get a null
> pointer exception on the last line and have to start
> working your way up in the code until you find the
> problem.

Right but as I understand it, Option class in Scala resolves this issue.

> Example 2 is the same thing in Python: you get hm[food]
> KeyError: 'apple' on the first line, it doesn’t get any
> clearer than that.
>
> Example 3 is probably the most flexible and allows you to
> choose any default value even null.
>
> This is one example of an API where I think the decision
> to use an exception is better than returning null.

The problem I have with the Python approach is that I often want to retrieve a value from the map if it's there but if it's not, add a new value and use that. I suppose the exception works fine for that but it's odd to me, probably because I'm so used to the Java way of doing it. Also, I suppose the default could be used to do this.

nes

Posts: 137
Nickname: nn
Registered: Jul, 2004

Re: David Pollak on Scala's Option Class Posted: Apr 19, 2007 3:34 PM
Reply to this message Reply
BTW returning null for hash lookups in Java has another problem that you would not have with exceptions: that is when you have keys that map to null values. In those cases the sane way to do a hash lookup is:


If (hm.containsKey(food)) result=hm.get(food) else result=”default”;


As far as adding values to hash entries, another approach is to set the default in the constructor instead of the retrieve method:


from collections import defaultdict
hm=defaultdict(lambda x:"default")
result=hm[food]
if result==foodType: doSomething()

nes

Posts: 137
Nickname: nn
Registered: Jul, 2004

Re: David Pollak on Scala's Option Class Posted: Apr 19, 2007 3:36 PM
Reply to this message Reply
>
>
> from collections import defaultdict
> hm=defaultdict(lambda x:"default")
> result=hm[food]
> if result==foodType: doSomething()
>


sorry that should have been:


from collections import defaultdict
hm=defaultdict(lambda:"default")
result=hm[food]
if result==foodType: doSomething()

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: David Pollak on Scala's Option Class Posted: Apr 19, 2007 4:05 PM
Reply to this message Reply
> BTW returning null for hash lookups in Java has another
> problem that you would not have with exceptions: that is
> when you have keys that map to null values. In those cases
> the sane way to do a hash lookup is:
>
>
> If (hm.containsKey(food)) result=hm.get(food) else
> result=”default”;
>


I've actually been doing the reverse (inverse?) of that in Python to keep from getting exceptions. You've made my realize that I was trying to write Java in Python. Thanks. I like Python a lot but I've got a long way to go. Do you know of any good books? I read "Learning Python" which I thought was an excellent book for getting started fast and I still use it from time to time but now I want something a little more in-depth.

Achilleas Margaritis

Posts: 674
Nickname: achilleas
Registered: Feb, 2005

Re: David Pollak on Scala's Option Class Posted: Apr 20, 2007 8:05 AM
Reply to this message Reply
Null should be a type, just like in FP languages. Algebraic types should then be used to make pointers nullable.

nes

Posts: 137
Nickname: nn
Registered: Jul, 2004

Re: David Pollak on Scala's Option Class Posted: Apr 20, 2007 10:36 AM
Reply to this message Reply
> Null should be a type, just like in FP languages.
> Algebraic types should then be used to make pointers
> nullable.

C.J.Date of database fame prefers even more specific types of inapplicable, undefined, unknown, etc. In java the term gets used for all kind of semantics. It could be worse: In C, integral constant expressions with the value 0 in a pointer context are converted into a null pointer at compile time.

nes

Posts: 137
Nickname: nn
Registered: Jul, 2004

Re: David Pollak on Scala's Option Class Posted: Apr 20, 2007 11:40 AM
Reply to this message Reply
> >
> >
> > If (hm.containsKey(food)) result=hm.get(food) else
> > result=”default”;
> >


If food in hm:
...result=hm[food]
else:
...result=”default”

>
> I've actually been doing the reverse (inverse?) of that in
> Python to keep from getting exceptions. You've made my
> realize that I was trying to write Java in Python.
> Thanks. I like Python a lot but I've got a long way to
> o go. Do you know of any good books? I read "Learning
> Python" which I thought was an excellent book for getting
> started fast and I still use it from time to time but now
> I want something a little more in-depth.

The closest I can suggest to what you are looking for is the "Python cookbook" from O'Reilly. It not only contains real code written by hundreds of different people trying to solve problems but also insightful annotations about the code from Alex Martelli (an experienced programmer).

Ramzi BEN YAHIA

Posts: 5
Nickname: rby
Registered: Apr, 2004

Re: David Pollak on Scala's Option Class Posted: May 10, 2007 2:14 PM
Reply to this message Reply
> I can definitely see that this can be useful but neither
> the original example nor the case example are
> fundamentally different than a check for null.
the check is required by the compiler + the intention is explicit in the API (not in the javadoc)

David López

Posts: 4
Nickname: daviti
Registered: Apr, 2006

Re: David Pollak on Scala's Option Class Posted: Jun 19, 2008 2:44 PM
Reply to this message Reply
I devised another sollution that could be possibly better. The options pointed out are useful but redirect the task of dealing with the null pointer exception OUTSIDE the class itself. What about using OO to solve the problem INSIDE the class?

Considering the example code that is trying to compare equality of the variable with a constant, the problem arises when this variable is null. But let that null variable be an actual object of the expected class, and determine the correct behaviour in this situation.

That is, the language could provide a special signature for the method "equals" for that class, when the value is null. For instance "equalsNULL" or something. That method would simply return true when the param is null as well.

What do you think of this feature?

Flat View: This topic has 14 replies on 1 page
Topic: Sun Releases NetBeans 6.1 Previous Topic   Next Topic Topic: Donald Knuth on Multi-Core, Unit Testing, Literate Programming, and XP


Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2017 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us