The cake falls

(I’m running out of snappy cake-related puns here, but I’m saving “the cake is a lie” for a special occasion.)

So after thinking about my interface / implementation dilemma for a while (recap: I’m aiming to separate out the implementations of hexmap from their interface), I decided to approach it from a Java vantage point and see how I’d implement the same thing in Java.  The immediately obvious thing that jumped out at me was that the specific problem I was dealing with was sort of a classic application of plain old vanilla inheritance from an abstract class.  Having drunk deeply from the well of Spring over my last several years of Java experience, plain old inheritance had begun to seem in some ways like a quaint relic of a bygone era (having been replaced in many cases by service composition).

At any rate, a quick bit of refactoring to get rid of traits altogether got me back to a fairly sane codebase, where I’ve got this:

abstract class HexMap (h: Int, w: Int) {
  val height = h
  val width = w
  // This is where the magic happens
  def data(addr: Address): HexData
}
abstract class HexData(a: Address) {
  def toJson(): JObject = JObject(List()) // default: empty JSON object
}

case class ColorData(a: Address, color: String) extends HexData (a) {
  override def toJson(): JObject = {
    ("color" -> color)  // json {"color": "foo"} via JsonDSL
  }
}
class RandomColorMap(h: Int, w: Int) extends HexMap(h, w) {
  private val store: Map[Address, ColorData] = createRandomMap()
  def data(addr: Address): ColorData = {
    store(addr)
  }
  // Note, we're able to access width and height here
  private def createRandomMap(): Map[Address, ColorData] = {
    val pairs = for (x <- 0 until width; y <- 0 until height) yield {
      val addr = Address(x, y)
      addr -> ColorData(addr, randomColor())
    }
    pairs toMap
  }
}

I will come back and revisit this later; I’m certain there’s a way traits could be useful in this code, but for now I’m leaving them aside and pressing on with more actual program functionality.

As far as that is concerned, my next worry is persisting the hexmap the user sees in their Scalatra session, so that when the user asks for a random path from the server, he or she gets one within the actual bounds of the actual map he or she is seeing. The Scalatra session docs make this look fairly straightforward; we’ll see.

More delicious cake

I’ve made some progress on both the client and server sides of the hexmap project.  On the client side, there’s now some code to highlight tiles (though it’s still imperfect).  I’ve also updated the map representation some, so it looks like this:

[ {"x":1, "y":1, "data":{"color": "yellow"}},
  {"x":1, "y":2, "data":{"color":"white"}},
  {"x":2, "y":1, "data":{"color":"white"}},
  {"x":2, "y":2, "data":{"color":"lightgreen"}} ]

The idea is that the data object will expand to have more game or application-specific data.  I’m not 100% sure that moving to a sparse representation (versus a 2d matrix) is a good idea, but I don’t think it will hurt me all that much, and it shouldn’t be too difficult to change back if I need to.

On the Scala side of the fence, I’m using the lift-json library to perform serialization to JSON.  I’m still not sure I’ve structured this in a way that really makes sense in the long-term.  One thing I’m hoping to achieve with this project is to wind up with a fairly abstract, generic hexmap library which can be augmented by application-specific code to implement a particular game or the like.  So I’m trying to partition off some of the specific stuff, such as in this case tile colors, into its own conceptual space, but I’m not sure I’m doing it idiomatically.

In particular, I think I’m hitting a slight impedance mismatch between Java and Scala revolving around traits, self-type declarations, and the Cake Pattern versus interfaces and Spring-style dependency injection.  I’d like to separate out the interface of a hexmap from the implementation used to actually implement the hexmap, so what I have is this:

class HexMap (h: Int, w: Int) {
  // Every instance of a HexMap will be mixed in with a HexStore
  self: HexStore =>

  val height = h
  val width = w

  def hex(x: Int, y:Int): Hex // Return data for a specific cell
}

And then HexMapStore implementations derive from this:

abstract class HexData(a: Address) {
  def toJson(): JValue // return a json representation of this data
}
abstract trait HexStore {
  def data(addr: Address): HexData  // Get the specific data from addr
}

My idea for this was that there might be one implementation which uses a MongoDB store, one which uses an in-memory map, etc. The fundamental operation, though, is to pass in a grid address and retrieve the data for that cell. The actual implementation I’ve got now is this:

case class ColorData(a: Address, color: String) extends HexData (a) {
  def toJson(): JValue = {
    ("color" -> color)  // json {"color": "foo"} via JsonDSL
  }
}
trait RandomHexMapStore extends HexStore {
  private lazy val store: Map[Address, ColorData] = createRandomMap()
  def data(addr: Address): ColorData = {
    store(addr)
  }
}

I think where I’m hitting problems most is trying to figure out how exactly the actual instantiation of “a HexMap with a RandomHexMapStore mixed in” should take place, or in other words where the definition of the specific component assembly I’m creating should appear.  In Spring this would be an object graph defined either in a (probably big, crazy, and unwieldy) XML file or via annotations on various class declarations.

What I’ve been trying for starters is just to define a factory method which returns a new random map:

object RandomHexMapStore {
   def create(height: Int, width: Int): HexMap = {
     new HexMap(height, width) with RandomHexMapStore
  }
}

This is working OK for now, and it makes sense to me that different implementations of HexMapStore might have different constructor parameters, so I’m not too bothered by factory methods in general. I’m a little worried by how this approach might or might not scale to much larger class / object graphs, though.

Moreover, so far I’ve been glossing over the most serious immediate problem I have with this: the implementation of the RandomHexMapStore.createRandomMap() method. This method is meant to construct a map composed of randomly selected color elements. The problem is that, being a trait which is mixed in to HexMap, is has no access to HexMap’s height and width class parameters. What I have at the moment is this:

  private def createRandomMap(): Map[Address, ColorData] = {
    // Well, this isn't ideal
    val pairs = for (i <- 1 to 6; j <- 1 to 6) 
                yield Address(i,j) -> 
                      new ColorData(Address(i,j), randomColor())
    pairs toMap
  }

I’m a little baffled by how to get access to class parameters from a trait which is mixed in to that class. When I think about it, I can’t really see a good reason for Scala to allow it, since, after all, RandomHexMapStore could be mixed into any class, not just a descendant of HexMap. This suggests to me that I am probably not using the proper language mechanism for what I’m trying to do. I will have to do some thinking on this, and possibly call on Stack Overflow for help.

The Cake walk

I come from a very Spring-heavy background in Java.  Spring is a bit of a loose, baggy monster, containing probably hundreds of features which aren’t all terribly well-connected to one another, but one thing that became second nature to me in Spring was the dependency-injection and IoC features.  Structuring software into composable components makes sense to me for scalability and ease of testing.

There are a few logical bits in random-album-cover that are clear candidates for components.  In particular,  the three distinct bits of information we’re getting from the web should probably each have a testing implementation and a live one (one which actually connects to the web and scrapes a page).  My Java instincts would probably structure the code something like the following:

interface Cover { ... }
class CoverImpl implements Cover { ... }

interface QuoteService {
    String getQuote();
}
class TestingQuoteServiceImpl implements QuoteService {
    String getQuote() { return "testing"; }
}
class LiveQuoteServiceImpl implements QuoteService {
    String getQuote() {
        // Fire up httpClient, connect to quote page, scrape for quote
        return result;
    }
}

interface CoverFactory {
    Cover generateNewCover();
}
class CoverFactoryImpl {
    QuoteService quoteService;
    Cover generateNewCover() {
        String quote = quoteService.getQuote();
        return new CoverImpl(quote);
    }
    void setImageService(QuoteService imageService) { ... }
}

Not shown: some Spring configuration that would wire up one of the two quote factory implementations into a CoverFactoryImpl instance.

None of this is rocket science. Translating it to idiomatic Scala is a bit trickier than it seemed at first. There are a few libraries which exist to do dependency injection in Scala, but there is also a method which relies on native library features, the Cake Pattern.  Adam Warski’s post from 2010 is a good summary of the idea, with code examples.

Digging a little more deeply into it, though, I found some discussion of the Cake Pattern which gave me pause.  In particular, the discussion on this post from Adam Warski, along with this post by Przemek Pokrywka and this one by Debasish Ghosh made me wonder if my understanding of what exactly the pattern does and how to implement it was not quite up to speed.

This had the salutary effect of driving me back to my primary sources (the Odersky et al “staircase book” and to a lesser extent, the O’Reilly book) for a refresher on self type annotations.  I’m still not entirely sure I grasp what the ultimate purpose of self types are; I can see the pragmatic effect of requiring that a concrete class which mixes in one trait must also mix in the trait that is referred to as a self type, but I don’t exactly see how to generalize this to more than a one-to-one trait relationship.  In some of the larger Spring projects I have worked on, literally hundreds of services (Java singleton instances) were composed and wired together — in the end there was an object graph.  If traits can only declare one self type, though, I don’t quite see how you would use this mechanism for anything other than an object list.  Clearly I’m missing something, but the staircase book is uncharacteristically terse on this point.

In any event, all was not lost, because chapter 29 of the staircase book essentially sets out to solve the exact problem I’d been working on: how best to structure and compose component-based software in Scala.  There seem to be a few ways of going about it, but for now I should have some simple examples to use as the basis for assembling my tiny services.  (It also opens up the possibility of comparing some of the more lightweight Scala DI frameworks down the road, which is something I’d probably enjoy.)