As mentioned in passing at the beginning of a recent article, one of the coolest things made possible by Scala’s expressive type system are anonymous type declarations. The idea was brought to my attention by Neil Bartlett in this article before I even started looking at Scala in any depth. Neil’s short-but-sweet post is most definitely worth reading, but there’s a few more neat tricks to be gleaned from his little example. Let me paraphrase his original code:

def printName(o: { def getName: String }) = Console.println(o.getName)

Here, the printName method can be passed an instance of any type, so long as it implements the anonymous interface we provide here (i.e. “any object with a getName method that returns a String”). Neat.

The most obvious question that occured to me is this: does the statically-checked duck-typing rule hold true for data structures as well as functions? For example, we have a list of objects of any old type, so long as they satisfy the interface constraints of our anonymous type? You bet.

class Foo {
  def getName: String = "Foo"
}

class Bar {
  def getName: String = "Bar"
}

val items = List[{ def getName: String }](new Foo, new Bar)

// despite Foo and Bar being completely types, the compiler "knows"
// that they will both implement our anonymous type declaration
items.map(_.getName).foreach(Console.println)

Very cool stuff. No longer do we need ugly wrapper classes/proxies to work around the shortcomings of more primitive type systems.

Oh and if the anonymous type syntax irks you, fear not: types can be aliased:

// Foo and Bar declared elsewhere ...

type HasName = { def getName: String }

def printName(o: HasName) = Console.println(o.getName)

val items = List[HasName](new Foo, new Bar)
items.foreach(printName)

Irrespective of which side of the dynamic/static fence you sit, you have to admit that Scala is an interesting compromise …