« Scala for C# programmers, part 1a: mixins and traits, behind the scenes | Main | Scala for C# programmers, part 3: pass by name »
January 08, 2009
Scala for C# programmers, part 2: singletons
In C#, if you want to create a singleton object, you have to create a class, then stop evildoers creating their own instances of that class, then create and provide an instance of that class yourself. While this is hardly a Burma Railway of the programming craft, it does feel like pushing against the grain of the language. Nor is it great for maintainers, who have to be able to recognise a singleton by its spoor ("Private constructor... public static readonly field... hand me the elephant gun, Carruthers."), or for clients, who have to use a slightly clumsy multipart syntax to refer to the singleton (e.g. Universe.Instance).
What would be easier for all concerned would be if you could just declare objects as singletons. That is, instead of writing class Universe and public static readonly Universe Instance, you could just write object Universe.
And that's exactly what Scala allows you to do:
object Universe {
def contains(obj: Any): Boolean = true // duh
}
val v = Universe.contains(42)
What's going on behind the scenes here? It pretty much goes without saying that the Scala compiler is creating a new type for the singleton object. In fact it creates two types, one for the implementation and one for the interface. The interface looks like a .NET static class (actually, the .NET 1.x equivalent, a sealed class with only static members). Thus, a C# program would call the example above as Universe.contains(42).
Singleton objects are first-class citizens in Scala, so they can for example derive from classes. This is a nice way of creating special values with custom behaviour: you don't need to create a whole new type, you just define an instance and override methods in it:
abstract class Cat {
def humiliateSelf()
}
object Slats extends Cat {
def humiliateSelf() { savage(this.tail) }
}
Obviously this is a frivolous example, but "special singletons" turn out to be an important part of the functional idiom, for example for bottoming out recursion. Scala by Example (PDF) describes an implementation of a Set class which is implemented as a tree-like structure ("left subset - member - right subset"), and methods such as contains() work by recursing down to the child sets. For this to work requires an EmptySet whose implementation (state) and behaviour are quite different from non-empty sets -- e.g. contains() just returns false instead of trying to delegate to non-existent child sets. Since EmptySet is logically unique it is both simpler and more efficient to represent it as a singleton: i.e. to declare object EmptySet instead of class EmptySet.
In fact the whole thing can become alarmingly deep: Scala by Example also includes a description of Boolean as an abstract class, and True and False as singleton objects which extend Boolean and provide appropriate implementations of the ifThenElse method. And fans of Giuseppe Peano should definitely check out the hypothetical implementation of Int...
January 8, 2009 in Software | Permalink
TrackBack
TrackBack URL for this entry:
http://www.typepad.com/services/trackback/6a00d8341c5c9b53ef010536b2e93a970b
Listed below are links to weblogs that reference Scala for C# programmers, part 2: singletons: