Wednesday, June 12, 2013

The Function of Factoring

Short story:

Last night I was fixing an ugly bug in my Scala game engine. It wasn't a particularly interesting piece of code except for the fact that it required to instantiate some user-side objects for witch it used a common Prototype pattern, as inherited from the original Java code.

Problem was quite simple: The object being used as prototype had some initialization code, that wasn't being called by the clone method:

class MyPrototypeClass(arg : ArgType) extends Cloneable {

    // Some fancy initialization code

   val bar = ...

   foo(arg)

   def foo(x : ArgType) = ...

}

...

class PrototypeConsumer(prototype : Cloneable) {

    ...


    def newGuy = prototype.clone

    ...
}

...

val c = new PrototypeConsumer(new MyPrototypeClass(arg))

val g = c.newGuy



Ok, so I know there are hundreds of ways of dealing with this... For example, I could create an initialize method  and just redefine clone to call it:


class MyPrototypeClass(arg : ArgType) {

   initialize(arg)

   def initialize(arg : ArgType) {
       // Some fancy initialization code

       val bar = ...

       foo(arg)
   }

   override def clone : this.type = super.clone.initialize

   def foo(x : ArgType) = ...
}

Problem was prototypes where supposed to be provided by the framework users and I wanted to make it as simple as possible. Plus, I'm really starting to dig this just-leave-your-initialization-code-here philosophy, and I was not about to give it up.

An alternative could have been to just clone the prototype calling it's constructor by reflection; but there again the code for that was way more complex than worthy.

So there I was, with an object with a clone mechanism that didn't behave in one hand and whole lot of object-oriented approaches in the other, when suddenly I realized I didn't need either of them. I didn't really need the user to provide me with an object that I could duplicate, but the duplication mechanism itself. What I needed was a Factory Function:


class MyPrototypeClass(arg : ArgType) {

    // Some fancy initialization code

   val bar = ...

   foo(arg)

   def foo(x : ArgType) = ...
}

...

class PrototypeConsumer(factory : Unit => Any) {

    ...

    def newGuy = factory()

}

...

val c = new PrototypeConsumer(_ => new MyPrototypeClass(arg))

val g = c.newGuy


This was so much easier for everyone. Neither the user has an initialization contract to implement nor it's restricted to Cloneable types.

Well, that's all for now. See you soon.

Sunday, May 12, 2013

Game, Set, Pattern Match

I've been recently revisiting my game engine collision detection logic, which I'm migrating from Java to Scala. I don't want to bore anyone with dull algorithmic details but, as it happens, letting aside the algebraic mumbo-jumbo I like so much, I found a pretty interesting design problem along with a nice Scala solution. It goes like this:

Basically, back then in Java, I had some objects which where responsible for collision detection. I called them "Bounding Boxes". Every collisionable object in the game was associated with one of these to whom they would ask whether or not they where colliding with one another. Code was very much like this:

public interface BoundingBox {

    public abstract boolean collidesWith(BoundingBox box);

    public abstract boolean collidesWithCircle(CircularBoundingBox box);

    public abstract boolean collidesWithRectangle(RectangularBoundingBox box);

        ...
}


public class CircularBoundingBox {

    @Override
    public boolean collidesWith(BoundingBox box) {
        return box.collidesWithCircle(this);
    }

    @Override
    protected boolean collidesWithCircle(CircularBoundingBox box) {

        // Borring Circle-to-Circle collision detection code

    }

    @Override
    public boolean collidesWithRectangle(RectangularBoundingBox box) {

        // Borring Circle-to-Rectangle collision detection code

    }
}


public class RectangularBoundingBox {

    @Override
    public boolean collidesWith(BoundingBox box) {
        return box.collidesWithRectangle(this);
    }

    @Override
    public boolean collidesWithCircle(CircularBoundingBox box) {
        box.collidesWithRectangle(this);
    }

    @Override
    protected boolean collidesWithRectangle(RectangularBoundingBox box) {

        // Borring Rectangle-to-Rectangle collision detection code

    }
}
Nothing really special about that. As you can see, every collisionable shape is model with a class of it's own, and the dual nature of the problem is easily solved using the Double Dispatch pattern. I actually liked this implementation (specially compared to some other engine's aproaches, like providing a monolithic low-level collision library) but it didn't really lived up to my expectations.

I originally wanted BoundingBox to act as an extension point to my engine, so users could extend it to add new crazy shapes to collide with. As it turned out, with the existing implementation there was no way of adding a new Bounding Box without also adding the corresponding methods to all the existing others. This isn't as much of a problem when you have the engine sources, but it was clear that no jar-user would be able to do it.

Also, just adding a couple more of boxes (the engine already had 6...) would get the interfaces really dirty, because of the combinatorial explosion. Double Dispatch is OK for small scenarios, but having dozens of  public methods (most of them only dispatches) just to solve one piece of logic soon turns quite unpleasant.

Here's where Scala comes in.

 trait BoundingBox {
  def apply(target : BoundingBox) = collidesWith(target)(true)
  
  protected def collidesWith(arg : BoundingBox)(shouldDispatch : Boolean) : Boolean =
   if(shouldDispatch) arg.collidesWith(this)(false)
   else throw new MissingCollisionLogic(this,target)
 }
 
 class CircularBoundingBox extends BoundingBox {
  override protected def collidesWith(target : BoundingBox)(shouldDispatch : Boolean) = target match {
   case c : CircularBoundingBox => //Check Circle-Circle collision
   case r : RectangularBoundingBox => // Check Circle-Rectangle collision
   case _ => super.collidesWith(target)(shouldDispatch)
  }
 }
 
 class RectangularBoundingBox extends BoundingBox {
  override protected def collidesWith(target : BoundingBox)(shouldDispatch : Boolean) = target match {
   case r : RectangularBoundingBox => // Check Rectangle-Rectangle collision
   case _ => super.collidesWith(target)(shouldDispatch)
  }
 }

In a nutshell, BoundingBox public apply method calls a protected collidesWith method that only delegates in it's argument. Implementors' responsibility is easy: they just have to override collidesWith providing whatever collision logic they want for any specific box type. In case the argument doesn't match any pattern, a quick call to super will perform the symmetric call on the argument or throw an exception it was the original receiver.

So, what's so special about this solution? Well, for starters, thanks to the magic of Pattern Matching the giant public interface was reduced to a single protected method. This leave us with a much tidier, less verbose classes.
That's alright, but what about extensibility? That's the best part! Let's say that we want to add another box, for complex polygons. All we have to do is extend BoundingBox as follows:


 class ComplexPoligonalBoundingBox extends BoundingBox {
  override protected def collidesWith(target : BoundingBox)(shouldDispatch : Boolean) = target match {
   case c : CircularBoundingBox => //Check ComplexPoligon-Circle collision
   case r : RectangularBoundingBox => // Check ComplexPoligon-Rectangle collision
   case _ => super.collidesWith(target)(shouldDispatch)
  }
 }

Notice that, by providing the collision algorithms against them, booth CircularBoundingBox and RectangularBoundingBox are now able to detect collisions against the new class, without even having to touch them. This allows to extend the boxes provided by the engine in a clean way while, at the same time, providing a full symmetric implementation.

There's no much left to say. I'm quite content with the final result as it has proven to be more flexible and aesthetic than it's predecessor. Guess it's time to go out there and give it a try. See you around.


N.

Wednesday, May 8, 2013

Scaling into a position

Ok, first of all, let's add a bit of context.

Last few years I've been sporadically working on a game engine, in order to give support to some ideas I have about how a game development should be faced. The product in general turn out to be pretty nice but, as I coded it in Java (back then it sounded like a good idea) I ended up realizing that the lovable yet a bit dull single-inheritance approach and the lack of tools like closures eventually leaded me to little uncomfortable design details that made me uneasy.
This was kind of a bummer, because my choice of Java was not arbitrary: I wanted a mature object-oriented language that could be easily deployed and would run in as many hardware platforms as possible and managed it's own damn memory efficiently. Also I wanted to be able to integrate my development tools with mercurial (which I favor before Git for no good reason), some reasonably simple dependency manager and a good, robust IDE.
Making a long and boring story short (and boring) I decided I didn't yet want to part ways with the JVM (wich I'm very fond of) but it was about time to kiss Java goodbye, so now I'm in the process of migrating the whole thing to Scala.

Let me tell you, once you have passed the little Eclipse plug-in glitches it's quite all right! Even so, regardless of my not-so-little experience in booth functional and object oriented programming I had some trouble finding a way of doing things that feels just alright. You know, like a good pair of old slippers, just with partial application and pattern matching.
What do you want me to say? I like the sensation that i'm getting the best out of my code. I know it's a long way to walk, so I figured that writing about interesting cases and the decisions I took and sharing it with the rest of you may lead me to a better understanding, and therefore a better use, of these new tools. 

Anyway, I recently came up with one of these interesting problems with some nice design difficulties. It goes like this:

As I said I'm working on a game engine, which requires quite a lot of vector algebra and 2D computations. It's not just that many objects in my framework require to maintain a position on the screen (which can be  easily represented with an (X,Y) pair); they usually are also in need of similar structures to represent direction versors, area dimensions and other vectorish thingies.

One possibility was to simply use a Scala touple to model a vector. That would have been a simple path (plus they could be instantiated with that nice touple syntactic sugar), but I found touples to be too generic and didn't feel like they would be a proper reification. After all, vectors are some of the objects the engine users would have to manipulate the most, and I would rather give them a nice, well defined interface to do it instead of just two Doubles tied with a bow.

Some may suggest to use the Pimp My Library pattern for this, but there is another catch: I wanted vectors to be mutable (at least those that would be used to represent a position) so the heap won't be saturated every two seconds because of the objects moving around. Don't get me wrong, I'm not a big fan of performance optimization, but in a game engine object's position is constantly changing and my FPS would be very upset if didn't took this one for the team.

Given all this, I decided to start with a classic approach and ended with something like this:

class Vector(var x : Double, var y : Double) extends Cloneable {

 override def toString = "(%.1f, %.1f)" format (x, y)

 override def clone : Vector = super.clone.asInstanceOf[this.type]

 // Immutable operations

 def +(v : Vector) = clone += v
 def -(v : Vector) = clone -= v
 def *(d : Double) = clone *= d
 def /(d : Double) = clone /= d
 def unary_- = clone * -1

 def module = sqrt(x * x + y * y)

 def asVersor = clone / module

 def distanceTo(p : Vector) = (this - p).module

 def squareDistanceTo(p : Vector) = {
  val v = (this - p)
  v.x * v.x + v.y + v.y
 }

  // Mutable operations

 def set(i : Double, j : Double) = {
  x = i
    y = j
  this
 }
 
 def +=(v : Vector) = set (x * v.x, y * v.y)
 def *=(d : Double) = set(x * d, y * d)
 def -=(v : Vector) = set(x - v.x,y - v.y)
 def /=(d : Double) = set(x / d, y / d)

}


Notice how I only included low level operations on this class (no position related code, just plain reusable vector manipulation). I didn't want to overload it's interface, since it was meant to be used for many ends. That leaved me in the need for a place to put my high level positioning related code. As I wanted it to be as reusable as possible and didn't wan't it to be bounded to a specific hierarchy I went for a trait:

trait Positioned {
 def position : Vector
 
 def x = position.x
 def y = position.y
 
 def move(delta : Vector) = position += delta
 def beAt(nextPosition : Vector) = position.set(nextPosition.x,nextPosition.y)
}


I know, that's not much of a movement API, but I'm expecting it to grow soon. Anyway, so far this didn't look so bad: I had my efficient mutable vector and had reified the way of using it as a position in a trait that only requires it's users to provide a position. This could even be nicely done using class parameters on the many classes that would need to be Positioned, so they could be implemented in a short elegant way:

class Ball(val position : Vector) extends Positioned {

 ...

}

val myBall = new Ball(new Vector(12,5))

However, this implementation was far from being good, the main concern being that, despite I wanted to be able to mutate the vector from inside Positioned trait, I didn't want to let that door open for any Ball user. Perhaps it's just me being paranoid, but I prefer to be able to give the Ball control over it's inner state changes. With this implementation the very same val definition that made position available for my trait also made it available for the rest of the world, which felt like an encapsulation rape.
I somehow needed a way to let Positioned manipulate the Vectors in a wider way than the rest of the users, including the class that should receive it as  a constructor argument.

After a bit of thinking I remembered C# approach to a similar situation. I figured that, if there where two ways of working with the same object, I should let them be two ways indeed; so I break the Vector class in two: an immutable logic trait and a mutable class extension.

trait Vector {
 def x : Double
 def y : Double

 def copy(x : Double = x, y : Double = y) : Vector

 def unary_- = this * -1
 def +(v : Vector) = copy(x + v.x, y + v.y)
 def *(d : Double) = copy(x * d, y * d)
 def -(v : Vector) = this + -v
 def /(d : Double) = this * (1 / d)

 def module = sqrt(x * x + y * y)

 def asVersor = clone / module

 def distanceTo(p : Vector) = (this - p).module

 def squareDistanceTo(p : Vector) = {
  val v = (this - p)
  v.x * v.x + v.y + v.y
 }

 override def toString = "(%.1f, %.1f)" format (x, y)
}

 
case class MutableVector(var x : Double, var y : Double) extends Vector {
 def copy(x : Double = x, y : Double = y) = MutableVector(x, y)

 def set(i : Double, j : Double) = {
  x = i
  y = j
  this
 }

 def +=(v : Vector) = set(x * v.x, y * v.y)
 def *=(d : Double) = set(x * d, y * d)
 def -=(v : Vector) = set(x - v.x, y - v.y)
 def /=(d : Double) = set(x / d, y / d)
}
 
trait Positioned {
 protected val _position : MutableVector = MutableVector(0, 0)

 def position : Vector = _position

 def x = position.x
 def y = position.y

 def move(delta : Vector) = _position += delta
 def beAt(nextPosition : Vector) = _position.set(nextPosition.x, nextPosition.y)
}


There where a few interesting changes. First of all, the clone implementation was replaced by a copy method that allows the immutable Vector to create a duplicate with a different (X,Y) set. I find this copy method approach much simpler than the Smalltalk's Species pattern and I often prefer it when possible.
MutableVector was implemented as a case class, in order to get free implementations of the equals and hash methods and a constructor that doesn't require the new keyword.
Also, check a little closer the Positionable implementation. Notice how it only exposes immutable Vectors? This prevents any encapsulation break while, at the same time, leaves the door open to the trait's users to treat the position as mutable.

Although this solution solved the mutable/immutable issue, it was still unclear (now that the position was already being provided by the trait) how the Positioned users could be implemented to support instantiation with a parametrized position. Clearly class value arguments could not be used anymore, because they would override Positionable implementation, and I'm not very fond of code like the following:

class Ball(initialPosition : Vector) extends Positioned {
 beAt(initialPosition)
 
 ...
}

I would much rather having the initialization code for my objects abstracted into a method, instead of throwed around. Besides, what if I want different ways to initialize my objects? Let's say, I want to create a Ball from another Ball. I won't be able to do so with a this method, because they can only be defined as a single call to another this method.

I found that the best approach to this may be to embrace the use of Scala's companion objects; that is objects that act as the class-side method implementors (pretty much like Java static methods).

object Ball {
 def apply(position : Vector) = new Ball().beAt(position)
}
 
class Ball extends Positioned {
 ...
}



As you may be aware, the "apply" message may be invoked by simply evaluating the receiver as if it where a message itself. This (combined with a little tweak on the "beAt" method to make it return the receiver) allows the Ball class to be instantiated like this:
val b = Ball(MutableVector(4,5))


Sweet! We are almost there... The only thing left to do was checking how Scala's singular features could improve the usability of these constructions. This was probably the hardest part because, as I'm relatively new in Scala, I wasn't aware of the whole of it's tools and, those I where, I was not used to applying them. Although, I did knew what details where bothering me: MutableVectors where too verbose to instantiate and some symmetrical operations (like scalar product) where not symmetrical at all.

I found that the answer for almost all of my problems where ussing implicit definitions. What I went after was being able to write a nice looking Touple (you know, something like (12,15)) and let Scala figure out I meant to say a Vector. Also, I wanted to provide an implementation of the *(v : Vector) : Vector method that could be used by Doubles. I ended up doing the following:

object Vector {
 implicit def touple_to_vector[T <% Double, U <% Double](t : (T, U)) : Vector = MutableVector(t._1, t._2)
 implicit class DoubleVectorExtender(val d : Double) {
  def *(v : Vector) = v * d
 }
}

I choose to put the implicits in the Vector companion object, so it would be easy to remember where they are. (I'm not sure if this is a good practice or not, though...). Sadly I couldn't find a way to implement a symmetrical equals between Touple and Vector, and this post convinced me it was not gonna happen :(

Even so, this last changes allowed me to write this sort of code:

val myBall = Ball(4,5)                               

2 * b.position                          
b.move(6,9)

MutableVector(4,5) == (4,5)                 
MutableVector(4,5) != (4,6)                 
 
-(5,7) distanceTo (4,5)                         

I love it! The resulting code is tidy and very expressive and most engine users won't even know MutableVector is there unless they are in the explicit need of a mutable vector. It's certainly quite an improvement from the original versions and much more flexible an reusable than any possible Java implementation.

The complete final code looked like this:


object Vector {
 implicit def touple_to_vector[T <% Double, U <% Double](t : (T, U)) : Vector = MutableVector(t._1, t._2)
 implicit class DoubleVectorExtender(val d : Double) {
  def *(v : Vector) = v * d
 }
}

trait Vector {
 def x : Double
 def y : Double

 def copy(x : Double = x, y : Double = y) : Vector

 def unary_- = this * -1
 def +(v : Vector) = copy(x + v.x, y + v.y)
 def *(d : Double) = copy(x * d, y * d)
 def -(v : Vector) = this + -v
 def /(d : Double) = this * (1 / d)

 def asVersor = copy(x, y) / module
 def module = sqrt(x * x + y * y)
 def distanceTo(v : Vector) = (this - v).module
 def squareDistanceTo(p : Vector) = {
  val v = (this - p)
  v.x * v.x + v.y + v.y
 }

 override def toString = "(%.1f, %.1f)" format (x, y)
}

case class MutableVector(var x : Double, var y : Double) extends Vector {
 def copy(x : Double = x, y : Double = y) = MutableVector(x, y)

 def set(i : Double, j : Double) = {
  x = i
  y = j
  this
 }

 def +=(v : Vector) = set(x * v.x, y * v.y)
 def *=(d : Double) = set(x * d, y * d)
 def -=(v : Vector) = set(x - v.x, y - v.y)
 def /=(d : Double) = set(x / d, y / d)
}

trait Positioned {
 protected val _position : MutableVector = MutableVector(0, 0)

 def position : Vector = _position

 def x = position.x
 def y = position.y

 def move(delta : Vector) = _position += delta
 def beAt(nextPosition : Vector) = {
  _position.set(nextPosition.x, nextPosition.y)
  this
 }
}

object Ball {
 def apply(position : Vector) = new Ball().beAt(position)
}
 
class Ball extends Positioned {
 ...
}


So that's it. I'll try to keep this site updated, posting about other interesting cases as they appear. In the meantime I appreciate any comments or advise about how to improve the code.

See you around,


N.

Don't look now, but there is a handsome programmer behind your browser

Oh, nevermind. It's just me.

Great! So this is right what the internet needs most: yet another programmer's blog!

Anyway, I'm starting this so I can track my progress as I leave the cozy, well known world of the pure Object Oriented and Functional programming to venture into the wild, more exiting new hybrid technologies. Hopefully, this record may be of use for those who, just like me, struggle between neurosis and old habits in the search for new good practices, better more reusable code and that wonderful, wonderful feeling that you made something beautiful out of bytes and Mountain Dew.

Please, feel free to comment. I would actually be thankful for any hint or tip, but good old tap on the back is also appreciated.

Ok, so that's it. Let's get this thing started...


N.