Making It Easy with Lofty

One of the exciting new features of Scala 2.10 is Dynamic types, which enable you to write code like this:


scala> import scala.language.dynamics
import scala.language.dynamics

scala> class StraightToConsole extends Dynamic {
  |  def applyDynamic(name: String)(args: Any*) = println(name + ": " + args)
   | }
defined class StraightToConsole

scala> var target = new StraightToConsole()
target: StraightToConsole = StraightToConsole@35d3694a

scala> target.a_method_we_never_defined("argument 1", "argument 2")
a_method_we_never_defined: WrappedArray(argument 1, argument 2)

The classic use for this kind of dynamic dispatch is to implement a proxy objects which converts method calls into API requests (for example, binding to an XML/RPC service). More generally, dynamic dispatch can be a way of embedding a small, dynamically interpreted DSL into a typed language like Scala. It is up to the Dynamic target object, rather than the compiler, to decide what each method call “means”, and behave accordingly. For example, we could base our behaviour entirely on the length of the method name:


scala>import scala.language.dynamics

scala> class FizzBuzz extends Dynamic {
  |  def applyDynamic(name: String)(args: Any*) = if (name.length % 2 == 0) println("Fizz") else println("Buzz")
  | }
defined class FizzBuzz

scala> var target = new FizzBuzz()
target: FizzBuzz = FizzBuzz@504c2683

scala> target.fizz()
Fizz

scala> target.fez()
Buzz

The Lofty library uses this approach to implement a DSL for building up templates which can be used to instantiate complex objects. The basic idea is that a template is a collection of name/value pairs which describes the object we would like to build. Each object type has a builder, which knows how to convert this collection of properties into an object of that type. Both templates and objects are immutable, but templates can be built up in stages by adding new properties to (or overriding the existing properties of) an existing template. For example, here is a template for a Person:


val personTemplate = for {
  address <- builder[Address]
  _       <- address lines Seq("12 Maudlin Street", "Manchester")
  _       <- address postcode("VB6 5UX")

  person <- builder[Person]
  _       <- person name "Stephen Patrick"
  _       <- person address address
} yield person

We can create an instance of Person by requesting the object specified by this template, using buildFrom:


val person = buildFrom(personTemplate)

We can also extend the template with new and modified properties:


val newPersonTemplate = for {
  person <- personTemplate
  _      <- person name "John Maher"
  _      <- person age 43
} yield person

Users of tools such as factory_girl and MakeItEasy should recognise the intention here, which is to simplify building objects for test fixtures. The approach taken by Lofty is interesting not only because of the Dynamic magic, but because it embeds an imperative DSL within a pure functional, immutable context. If you’ve ever written any Visual Basic, you’ll be familiar with this pattern of object initialization:


Dim obj As Foo
Set obj = new Foo
with obj
  .property1 = "Apple"
  .property2 = 42
end with

This is a dangerous way to initialize objects, because if you fail to set all the required properties you’re left with a reference to an object in an invalid state. However, it does enable objects to be initialized in stages, with one stage setting up common features and a later stage configuring the object for a particular purpose. In a language where objects have immutable properties, which are initialized in the object’s constructor, this is no longer possible.

Lofty uses the scalaz State Monad to create a DSL in which properties can be written (and read) imperatively. This is what the use of the for syntax (which may look slightly strange to those not used to monadic programming in Scala) is all about. Not only can we write and overwrite values, we can also read values that we’ve previously assigned:


val newPersonTemplate = for {
  person1 <- personTemplate
  person2 <- personTemplate
  _       <- person1 name "Identical twins"
  _       <- person2 name person1.name
} yield (person1, person2)

(There’s a slight wrinkle here, which is that person1.name acts as a link to the name property of person1, rather than a copy of its value. If we subsequently change person1‘s name in the template, person2‘s name will change as well. This is because the actual value of person1.name isn’t known until the entire template is evaluated by buildFrom – the reference to person1.name here acts as a placeholder that is filled in at build-time with the real value, which is always the last value that was assigned to person1‘s name property.)

This illustrates the expressive power of Scala’s monadic for syntax: all of the above code is pure functional code that performs no mutation of any values, and yet we are able to use the State monad to embed an imperative sub-language within this context. Because nothing is really being mutated, we can create a “base” template, create a second that updates some of its values, and continue to use the unmodified “base” without having to worry that its behaviour has been changed.

Lofty is a work in progress; it would be nice in the future to be able to build case classes directly from templates using reflection, rather than having to implement an implicit Builder[T] for each type that we want to construct. However, it’s also a short and nifty demonstration of some “advanced” Scala techniques, employed in the service of making it easy for library users to accomplish a particular type of task. It may be that a Scala project of any size will live or die by its DSLs – by its ability to reduce complexity locally, by inventing an appropriate idiom for each different kind of programming task. Monads and dynamic typing are two of the powerful methods Scala provides to DSL-authors, and the ease with which a library like Lofty could be put together is an encouraging sign of the ability of the language to meet the challenges of programming in the large.

TIM Group Scala Dojo

TIM Group hosts a monthly Scala Dojo as part of the London Scala Users’ Group on Meetup (http://www.meetup.com/london-scala). The dojo is free to attend with drinks and pizza provided to the participants. The dojo always takes place on the third Thursday of the month in the TIM Group London offices.

The dojo is driven by participant in suggesting and choosing shorter programming challenges and collaboratively finding a solution in smaller groups. The atmosphere is relaxed with a focus on fun and learning. The range of scala skills range from total beginners that heard about scala to seasoned enthusiasts that work with scala. Towards the end of the meetup, the different groups present their work and discuss what they have learned.

Example of programming challenges are:

  • Secret Santa problem where the challenge is to find an algorithm for matching people giving each other gifts. No one should get left out and additionally no should be matched with their spouse.
  • finding an approximation of PI using concurrency with akka.
  • using the coursera Scala survey data to find alternatve stats such as ranking countries based on average perceived difficulty.
  • solving the Data Munging Kata from http://codekata.pragprog.com

I have taken my first steps in Scala in the dojo and found it a great learning experience. The time absolutely flies and you often end up with a great feeling of achievement by the end of the night!

The next Scala Dojo is on Thursday Jan 17th.
I hope to see you there!