Scala, day three. A diversion

So for day three of scala, I decided to go on a completely different path than the exercises suggested in the book. In my work I do a fair amount of graphical programming and one of my prefered tools for prototyping is the wonderful processing.org project. As the website says "Processing is an open source programming language and environment for people who want to create images, animations, and interactions." From a languages perspective, it is a language that sits on top of Java, simplifying some things and providing some useful abstractions for graphics programming. It doesn't completely mask java and lets your drop into full-fledged java whenever you feel that would be most appropriate. Recently I have had success in using the ruby-processing library that lets you use processing from the comfort and (development) speed of the ruby language. Spde is a similar project for scala and I thought that this would be a good opportunity to experiment with something closer to what I would end up using a 'java-replacement' for.

So I wrote a small sketch using spde. It simulates some balls attached to a spring that you can displace. When displaced a ball will play a random musical note and then wait for a random period of time before displacing its neighbours with a smaller force than it originally received. This results in a chain of balls pushing each other and playing random notes until the springs bring the balls to rest again. Click the image below to see the sketch (a java applet). There is also a link at the bottom of this post.

Spde sketch: Ball & Chain

Here is all the code first and then we can look at parts I found particularly interesting.

Sliding

First handy thing is the 'sliding' method. I do absolutely love the collection handling methods like each/foreach, map, fold etc that come in languages Scala and Ruby, but every now and again I revert back to a regular for loop because i need to process more than one element at a time (or at least base a calculation on other objects within the collection). I was pretty pleased to find the sliding method in scala, which creates a sliding window, of a size and step that you can specify over the collection you want to iterate over. Its like functional loop unrolling.

nodes.sliding(2).foreach(pair => {
  pair.head.rightNeighbour = pair.last
  pair.last.leftNeighbour = pair.head
})

nodes.head.leftNeighbour = nodes.last
nodes.last.rightNeighbour = nodes.head

I use it here to build a quick linked list of nodes to easily move from one to the next (and trigger the neighbour interactions). Winning!

Function Objects

The next interesting thing I wanted to point to was function objects as a way to create a closure like thing (closed over a very small scope) and some of scala's syntax for higher order functions. Here is the code snippet.

//We can replace this with the more generic reusable version
//below
//
// var lastCalled = System.currentTimeMillis();
//   def onlyAfter(time:Int, function: () => Unit):Unit = {
//     if((System.currentTimeMillis() - lastCalled) > time){
//       function()
//       lastCalled = System.currentTimeMillis()
//     }
//   }

//basically returns a function that captures the lastCalled var
//we can have as many debouncers as we want without having to explicitly
//manage a map of timers to track when the functions they watch over were
//last called
def makeDebouncer():Function2[Int, () => Unit,Unit] = {
  return new Function2[Int, () => Unit,Unit]() {
    var lastCalled = System.currentTimeMillis();
    
    def apply(time:Int, function: () => Unit):Unit = {
      if((System.currentTimeMillis() - lastCalled) > time) {
        function()
        lastCalled = System.currentTimeMillis()
      }
    }
  }
}

val onlyAfter = makeDebouncer()

The intention behind this was to do the following, each ball should only try to play one note at time even if it gets triggered multiple times before its done playing. To do this I wanted to create a function that could take another function and make sure to call it at most once every X milliseconds. The first pass at this is in the commented out portion of the code. What I did was very straightforward, I made a variable to store the last time this 'limiting' function was used and if it exceeded the threshold, it triggers the function it was passed. This first version of onlyAfter, takes a time (in milliseconds) and a function and works just fine for this program, each ball has its own timer and can use that to track the last time it made a sound.

But I started thinking, that is all well and good for one function, but what if each object wanted to do a similar thing for a whole set of different functions? If i were to continue the initial approach I may have created a map that holds a timer for each function that one wants to limit in this fashion. But experience with languages like Javascript and more recently Io, tell me that there is a better way. I want something closure like. So I went to figure out how I could do this in scala.

What I ended up with was function objects, makeDebouncer is a function that returns another function, it just so happens that functions are objects in scala so we can make one with a constructor just like we would for a regular object. Function2 is a constructor for a function that takes two params. We specify the types of the arguments and the return type in the square brackets (like when making a list or array). The apply method is what will be called when we call this function, it is effectively the function definition for the function we are creating. Note that this apply method also happens to take a function :-). Now because we are creating an object, it can have internal state just like any other object, in this case the last time this function was used will be stored in the function itself! Finally we can create as many of these limiter functions as we want, we assign one to the onlyAfter val that we then use to limit the note playing.

Actors

The other thing that may catch your eye is the use of actors, I explored actors a bit in my day 3++ of Io post so I wont go in too much detail here. Suffice it to say, this program was originally written without actors and it was very easy to add some actor based functionality (the triggers from one ball to its neighbours are sent as messages) though my need for actors did not run terribly deep in this example they are handy. However I did run into a small issue when exporting my sketch into an applet I could put onto the web. It seems that actors do not play well with unsigned applets :-(. So to get this to work in a browser I had to replace the actors with manually created threads. This was easy to do but it did expose some of the things that actors hide for you, in particular I ran into a situation where I was creating too many threads. They are pretty short-lived but in this program each thread calls two functions that potentially create more threads. The actor model manages this with a threadpool which is what i would have to do myself if i wanted this applet to be more robust; still its nice to have this handled for you by an abstraction.

See it!

Enough text, onto lights and sound! Click this link to see the applet.

The source for this is on Github as usual, it requires spde and sbt (simple build tool) to compile. The actual modified source for the applet is there too, in the spdeapplet branch.

Posted On 13th June 2011

comments powered by Disqus