Sunday, June 17, 2012

Error handling with Scala’s Try

Scala 2.10 will introduce a new class called Try for representing the results of computations that might fail. Try neatly encodes the concept of success and failure with a subclass for each concept: Success objects hold values and Failure objects hold exceptions.

Try is a nice little utility class. It isn’t terribly exciting, but it certainly comes in handy. Its simplicity reduces confusion, and error handling is an area where confusion is common.

Of course it is not necessary to explain to the enlightened reader the danger of using special values such as -1 or null to represent errors. Programmers are famous for misusing such values and crashing their programs (and rockets). Separating success and error results into two distinct types means the compiler can make sure they’re never mixed. A bit of type checking really can help to avoid problems.

Similar type-checking assistance was available in Scala 2.9 with Either. However Either is considerably more flexible and abstract than Try. Either can represent any two possibilities, not just success and failure. Either needs a little thought to understand, whereas Try needs almost none.

Try also provides useful methods for operating on return values.

  • t.get – Get the result or throw an exception.
  • t.getOrElse(x) – Get the result or a default value.
  • t.isSuccess / t.isFailure – Check for success or failure.
  • t.map / t.flatMap – Use in a for loop and never check for failures manually again!

Scala 2.10 is going to bring lots of great stuff and it will be easy to overlook Try. But Try is a valuable addition to any programmer’s toolkit.

See also:

Thursday, January 28, 2010

Scala 2.8.0 beta 1 released

The first Scala 2.8 beta has been released. It has a lot of new features. I'm particularly looking forward to using the improved collections, type specialization, default arguments, and of course continuations!

The continuations plugin hasn't been merged into the default distribution yet. If you'd like to use continuations with the beta then you'll need to build it yourself.

Building the plugin

The process for building the plugin is pretty much as I described in my original post. One of the JAR files has been moved out of the standard Scala distribution, so you'll need to download it manually (using the second wget below).

First download the Scala 2.8 beta.

$ wget http://www.scala-lang.org/downloads/distrib/files/scala-2.8.0.Beta1-prerelease.tgz
$ tar xzf scala-2.8.0.Beta1-prerelease.tgz
$ wget http://scala-tools.org/repo-releases/org/scala-lang/scala-partest/2.8.0.Beta1/scala-partest-2.8.0.Beta1.jar -O scala-2.8.0.Beta1-prerelease/lib/scala-partest.jar
$ export SCALA_HOME=`pwd`/scala-2.8.0.Beta1-prerelease

Next get the source for the continuations plugin.

$ svn co http://lampsvn.epfl.ch/svn-repos/scala/compiler-plugins/continuations/trunk continuations

Then build it and run the tests.

$ cd continuations
$ ANT_OPTS=-Xmx512m ant test

Finally set an environment variable to point to the continuations code.

$ export CONT_HOME=`pwd`

Compiling and running a program that uses continuations

Here's a short example program that uses continuations.

$ cat > example.scala
import scala.continuations.ControlContext._

object Example {
  def main(args: Array[String]) {
    reset {
      println("first")
      shift { k: (Unit => Unit) => k(k(())) }
      println("last")
    }
  }
}

To compile it you'll need to load the continuations plugin into the compiler.

$ $SCALA_HOME/bin/scalac -Xplugin:$CONT_HOME/build/pack/selectivecps-plugin.jar -classpath $CONT_HOME/build/build.library example.scala

To run it just make sure you include the continuations runtime library.

$ $SCALA_HOME/bin/scala -classpath $CONT_HOME/build/build.library:. Example
first
last
last

And that's it.

Friday, January 22, 2010

Continuations plugin for Scala 2.8 beta

The first Scala 2.8 beta is due to be released soon. Unfortunately the continuations code won't be merged in time for the beta. In the meantime if you want to try out the continuations features then you'll need to build the continuations compiler plugin and support library yourself. In preparation for the beta release I thought I'd post some updated instructions for building the continuations plugin.

Building the plugin

These instructions are based on a recent beta release candidate, but they should also work fine for the actual beta. The process for building the plugin is pretty much as I described in my previous post. The only real change is that you now need to download an additional JAR from the Maven repository, because the JAR is no longer included in the standard Scala distribution.

First download the Scala 2.8 beta. If you want to use a newer release then you'll of course need to update the URLs.

$ wget http://www.scala-lang.org/downloads/distrib/files/scala-2.8.0.Beta1-RC8.tgz
$ tar xzf scala-2.8.0.Beta1-RC8.tgz
$ wget http://scala-tools.org/repo-releases/org/scala-lang/scala-partest/2.8.0.Beta1-RC8/scala-partest-2.8.0.Beta1-RC8.jar -O scala-2.8.0.Beta1-RC8/lib/scala-partest.jar
$ export SCALA_HOME=`pwd`/scala-2.8.0.Beta1-RC8

Next get the source for the continuations plugin.

$ svn co http://lampsvn.epfl.ch/svn-repos/scala/compiler-plugins/continuations/trunk continuations

Then build it and run the tests.

$ cd continuations
$ ANT_OPTS=-Xmx512m ant test

Compiling and running a program that uses continuations

Set an environment variable to point to the continuations code.

$ export CONT_HOME=.../continuations

Here's a short example program that uses continuations.

$ cat > example.scala
import scala.continuations.ControlContext._

object Example {
  def main(args: Array[String]) {
    reset {
      println("first")
      shift { k: (Unit => Unit) => k(k(())) }
      println("last")
    }
  }
}

To compile it you'll need to load the continuations plugin into the compiler.

$ $SCALA_HOME/bin/scalac -Xplugin:$CONT_HOME/build/pack/selectivecps-plugin.jar -classpath $CONT_HOME/build/build.library example.scala

To run it just make sure you include the continuations runtime library.

$ $SCALA_HOME/bin/scala -classpath $CONT_HOME/build/build.library:. Example
first
last
last

Enjoy!