Iulian Dragos

4

Scala offers many ways to abstract and reuse code, but one area where this is not entirely obvious is exception handling. Sure, when it comes to error handling, there are good ways to write elegant code: use Option or Either and soon Try. But when it comes to exceptions, for instance when interfacing with Java code, one has to write tedious try-catch blocks. In this post I will briefly describe a few utility methods in the standard library that are undeservedly obscure. I got the idea of this blog post when answering this stack overflow question (though my answer is not the most voted, I still think it's the better solution ;-) ).

scala.util.control.Exception

This little utility class and allows the programmer to abstract over common patterns of handling exceptions. Let's start with some code that catches an exception and converts it to Option.

import scala.util.control._

object exceptions {
  import Exception._

  catching(classOf[NoSuchElementException]).opt {
    List().head
  }                                               //> res1: Option[Nothing] = None
}

catching loosely follows the builder pattern and constructs a Catcher object, with user-configurable logic for what to catch and how to handle the exceptions. In our example, we pass an exception type and configure the catcher to convert the result to an option. Obviously, if an exception is thrown the result is None

In exactly the same way we could convert it to Either:

import scala.util.control.Exception._

object exceptions {
  val xs = List(1)

  catching(classOf[NoSuchElementException]).opt {
    xs.head
  }                                               //> res0: Option[Int] = Some(1)

  catching(classOf[NoSuchElementException]).either {
    xs.head
  }                                               //> res1: scala.util.Either[Throwable,Int] = Right(1)
}

Canned logic

catching takes any number of exceptions and it is the most flexible way to use this library, but a few patterns come up often enough to warrant their addition to the standard library:

  • nonFatalCatch is, unsurprisingly, a catcher that re-throws fatal errors. Given that the Scala compiler sometimes relies on exceptions for control flow (like non-local returns), it's a very bad idea to catch any of those
  • ignoring(e1, e2, ..) evaluates a block and catches given exceptions (it returns Unit, so this can be used only for side-effecting code
  • failing(e1, e2, ..) evaluates a block and catches given exceptions, returning None if the block throws an exception, wrapping the resulting value in an Option
  • failAsValue(e1, e2, ..)(default) catches any of the given exceptions and returns a given default value if the block throws. For instance,
      failAsValue(classOf[Exception])(-1) {
        xs(2)
      }                                               //> res3: Int = -1
    

Catchers can be customised even more, and that's what I used in the SO answer. withApply can be used to pass a function that handles the exceptional case. For instance:

  def logError(t: Throwable): Int = {
    println("Error: " + t)
    -1
  }

  catching(classOf[Exception]).withApply(logError _) {
    xs(2)
  }                                               //> Error: java.lang.IndexOutOfBoundsException: 2
                                                  //| res3: Int = -1

This example shows how the exception handling logic can be abstracted in a function. We can take this one step further and reuse entire catchers (since they are plain Scala values, there's not much to be done):

  val loggingExceptions = catching(classOf[Exception]).withApply(logError _)

  loggingExceptions {
    xs(2)
  }                                               //> Error: java.lang.IndexOutOfBoundsException: 2
                                                  //| res3: Int = -1

I've found this utility class very useful when integrating Scala code with an existing Java codebase, and a good example of DSL design.

3

It took me a while to figure this one out, so I'll write it down for future reference.

We're using maven and tycho to manage builds for the Scala IDE. Our dependencies come both from maven and Eclipse P2 repositories, and http://download.eclipse.org is slow as molasses. Every build loses 4-5 seconds connecting to that repository (even when there's nothing to download). I finally made a local mirror (wget didn't work, so I had to use the official way).

The next step was to make this mirror available to my builds, without modifying the existing poms (it's an open source project, with contributors in several locations). Maven conveniently provides mirrors in a per-user settings.xml file, but for some reason P2 repositories didn't pick it up. It turns out you need to explicitly say it's a P2 repository (thanks to good people on this mail thread):

  <mirrors>
    <!-- mirror
     | Specifies a repository mirror site to use instead of a given repository. The repository that
     | this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used
     | for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
     | -->
    <mirror>
      <id>local-helios</id>
      <mirrorOf>Helios</mirrorOf>
      <name>Local Mirror of Eclipse Helips p2 repository.</name>
      <url>http://iulians-imac.local/~dragos/mirrors/helios/</url>
      <layout>p2</layout>
      <mirrorOfLayouts>p2</mirrorOfLayouts>
    </mirror>
  </mirrors>
2

I just spent a wonderful week in California, and attended ScalaDays 2011. One thing that popped up during one of the talks was that 'Java inner classes in Scala are a challenge'. I was pretty surprised since this came from one of the speakers, and someone I'm sure is a very knowledgeable person otherwise. Of course, you can use Java inner classes in Scala. But first..

Using Java inner classes in Java

Let's call nested a class defined inside another class that is static, and let's call inner class a non-static class defined inside another class. Java uses the same syntax to refer to both nested and inner classes: import Outer.Inner. We'll consider the following example throughout this post:

package test;

public class Outer {
    public int base = 10;
    public class Inner {
        public int x = 10 + base;
    }
}

You can use the Inner class either by subclassing Outer, or (less common), by importing and instantiating through an outer instance:

import test.Outer.Inner;
import test.Outer;
...
Outer o = new Outer();
Inner i = o.new Inner();
i.x;

Java does not distinguish between instance and static members, so the import line looks unsurprising. However, the instantiation syntax is rather weird, making the keyword new look like a member of o, instead of making Inner look like a member of o.

An inner class has access to all members of the enclosing class, final and non-final alike. Therefore, whenever an inner class is instantiated it needs to be passed (implicitly) a reference to the outer instance.

Inner classes in Scala

Scala treats inner classes like any class members. Therefore, selection (both for importing and instantiation) proceeds with an outer value and goes on to select the inner type.

  val outer = new Outer
  val inner = new outer.Inner

Note that due to type inference, there was no need to specify the type of inner. What is the type of inner?

  val outer = new Outer
  val inner: outer.Inner = new outer.Inner

We can use the same syntax to import the Inner type in scope: import outer.Inner.

In Scala, types that depend on a value (the object outer in this example) are called path-dependent types. If we had a second instance of Outer, say outer2, the two types would be incompatible:

  val outer2 = new Outer
  val inner2: outer.Inner = new outer2.Inner

We'd get the following error:

outer.scala:7: error: type mismatch;
 found   : Test.outer2.Inner
 required: Test.outer.Inner

This is different behavior from Java, where type Outer.Inner matches any instance of Inner, regardless of the outer object instance. It turns out that Scala does have an equivalent type: Outer#Inner. The hash operator performs a type selection. Unlike Java, Scala reserves the dot exclusively for selection on terms.

  var inner: outer.Inner = new outer.Inner
  var inner2: Outer#Inner = new outer2.Inner

  inner2 = inner // works
  inner = inner2 // fails

And the confusion?

There is still one important difference between the way Scala and Java treat inner classes: mutability. Scala requires paths to be immutable, therefore both instantiation and imports have to mention only vals. The following code doesn't work:

  var outer = new Outer
  val inner = new outer.Inner


outer.scala:9: error: stable identifier required, but outer found.
var inner = new outer.Inner

You may ask yourself why this restriction? It has to do with type members (remember, Scala classes may have abstract type members). If the path to the inner class contains mutable variables, the type of Inner members may change during execution. For example, a field may change from Int to String. In short, it's unsound.

I believe it's this restriction that confuses most people. So what do you do if you need to have mutable outer instances? First of all, you need to use type selection (Outer#Inner) to refer to such types. Second, you need to instantiate them through an immutable alias, for instance by defining a helper method:

  var outer1 = new Outer // outer1 is mutable, we need a factory method
  val inner1 = mkInner(outer1)

  def mkInner(o: Outer): Outer#Inner = new o.Inner // o is immutable

The Outer#Inner syntax is not allowed in imports (it's not a path).

With this observations, it should be always possible to use Java inner classes from Scala. I hope this post clarifies a (sometimes shady) part of the Java and Scala interoperability.

0

Yesterday I finally received my new Apple MacBook Pro, with the new SandyBridge core i7 processor. I was very eager to see how fast it is compared to my work computer (2010 iMac 27''), and what better benchmark than a full build of the Scala compiler?

Here's the result (lower is better)

The first benchmark is the total time for a full build, the following are the bootstrapping steps of the Scala compiler and standard library. For the total time, the laptop is almost 1:30 minutes faster than the desktop!

Here are the two configurations (I ran both builds with a 2.5 GB heap, using Java 1.6/64 bits)

  • MacBook Pro: 2.3 GHz quad-core i7 (sandy bridge) with Intel 320 SSD
  • iMac: 2.96 GHz quad-core i7 (first generation core i7)

For sure the SSD on my MBP helps a lot, but the processor can't be bad either. I repeated the benchmark by having both computers write to a RAM-disk, and the results were very similar. Of course, the JDK, bootstrap compiler and sources were still on disk (HDD on the iMac, SSD on the laptop), so the laptop still has a signifficant advantage.

While this is certainly a flawed benchmark, and no general conclusions can be drawn, it is nevertheless something I do very often. It's great to see that my new laptop can deliver so well!

5

It' been over 3 years since I finished my internship at Google, and lots of things happened in Scala-land since. A couple of days ago I went back to my code I wrote back then, and ported it to Scala 2.9.0.RC1. The project is a Scala client library for Google Data APIs.

The GData Scala Client Library

Google Data (or GData) is an Atom-based publishing protocol that allows CRUD operations over Google services, such as Calendar, YouTube, GMail, etc. It is a very powerful mechanism that allows programatic access to all your Google-based thingies, but being XML-based it is very cumbersome to use directly. Google maintains a bunch of client libraries in different languages that hide all the ugly XML from programmers' eyes.

While at Google, I wrote a Scala client library, and I am still very pleased with the result. I strayed away from their Java client architecture, and for XML handling I wrote a pickler library. However, unlike the original paper that deals with sequential data, I had to make it work with XML trees, which proved a lot more interesting. Briefly, the library allows one to define bi-directional mapping between user types and XML using syntax that's reminiscent of Relax-NG schemas:

def pickler: Pickler[Rating] =
    elem("rating",
          opt(attr("average", doubleVal))
        ~ attr("min", intVal)
        ~ attr("max", intVal)
        ~ opt(attr("numRaters", intVal))
        ~ default(attr("rel", text), "overall")
        ~ opt(attr("value", intVal)))(gdNs)

This code defines an element called 'rating' with an optional attribute average, of type Double, two required attributes of type int (min and max), an attribute with a default string value, and so on. This pickler defines two methods, one from XML to instances of Reminder, and another from Reminder to XML. The library provides type-safe, user-extensible picklers, meaning that the result of unpickling an XML element like

<rating average="2.5" min="1" max="5"/>

will be an instance of the Rating class, and serializing an instance of Rating would generate conforming XML. One of the difficulties I faced was to allow permutation of child elements when parsing (the Atom protocol is very liberal in this regard, and Google servers use this liberty). I won't go further into the details of the implementation, as it is nicely described in the Developer's guide.

The other part of the library deals with HTTP requests and binds together the XML serialization code with the network protocol.

Updating birthday entries

A couple of months ago I decided to organize my birthday calendar, and realized that most of the entries had a reminder, but some did not. This resulted in the suboptimal situation that I forgot some birthdays, but not all. I decided to fix this.. programmatically.

The code to do it in Scala is surprisingly simple:

package anivs

import com.google.gdata.calendar._
import com.google.gdata.data.kinds.Reminder
import Schemas._

object ChangeAnivs extends Application {
  final val calName = "Birthdays"
  val s = new CalendarService("test")
  s.setUserCredentials("username@gmail.com", "secret")

  val cal = s.getOwnedUserCalendars.find(_.title.content.startsWith(calName)) match {
	case Some(bcal) => bcal
	case _ =>
	  println("couldn't find calendar")
	  exit(1)
  }
  var link = cal.link(EVENT_FEED)

  while (link.isDefined) {
    val events = s.getEvents(link.get.href)
    println("* got back " + events.length + " events")
    addReminders(events)
    link = events.link("next")
  }

  implicit def toOpt[T](s: T): Option[T] = Option(s)

  def addReminders(events: s.eventsFeed.Feed) {
    for (event <- events if event.reminders.isEmpty) {
      // alert 10 min before event
      val rem = Reminder(method = "alert", minutes = 10)
      event.reminders = List(rem)
      val e1 = s.updateEvent(event)
      println("Updated event " + e1.title.content)
    }
  }
}

That's it! It adds a popup reminder to each event that has no reminders. Notice that the reminder uses named parameters, and the class has default values for most of its parameters (Atom has plenty of optional elements and attributes). I also added an implicit conversion from Any to Option, so that I don't need to wrap Some around the parameters I passed to Reminder.

Next steps

I plan a number of improvements to the code. GData-scala-client was developed before sbt came to the scene, so I'd like to move the build from ant to sbt and publish it to the scala-tools.org maven repository. I already went through most GData-defined types and added default arguments and plan to more consistently use named parameters where possible. This should make the code much easier to understand. And lastly, I might add support for other services (currently, it supports Calendar, YouTube and Contacts) -- I'm a bit reluctant to say this too loud, though..

0

I managed to import some of my old posts from b2evolution. There's no custom importer for WordPress, but the RSS importer worked like a charm: even formatting looks really good (it didn't import comments, but I didn't have that many anyway). However, the RSS feed had only the most recent 10 posts or so, meaning I could not get about half of my posts. Such is life.

(I could change the size of the RSS feed in b2evolution's settings).

0

I finally decided to have a proper homepage, and blog from time to time. I may import some of my old blog posts, but until then I can leave you with my recent interview on jaxenter about the Scala IDE for Eclipse.

 

My previous blog is here.