Saturday, January 28, 2012

A day in bed with my laptop...

A day in bed. I got about half way through Thursday, and the shivering/shaking got too much, so I scampered home to recuperate. 15 hours sleep, a chat with NHS Direct and then a GP (amoxycillin), and things started to become bearable. But how to pass the time lolling around under the duvet...?

Scala of course. A brainy relative sent me a link to a chat about how the Guardian has shifted its website from java to scala, and I'd spotted Programming In Scala on a desk at my client's office. Last summer's brief-but-unconsummated flirting with Programming Groovy had left me with a rumbling desire to do something different-yet-the-same with my java experience. Serendipitous, eh?

Anyway, armed with scala 2.9.1 & Intellij IDEA's scala plugin, I ploughed through the Scala chapter in Bruce Tate's Seven Languages in Seven Weeks in pretty short order. The part that really stood out was the concurrency aspect. There's an example script that pulls 4 websites' homepages and counts the size of the content. The script does it sequentially first, and then concurrently - and to to get the concurrency, the code fires off 4 messages to itself, which it then processes (...but magically now in parallel). Here's what that bit looks like:

def getPageConcurrently() = {
  val caller = self

  urls.foreach{ url => actor { caller ! (url, PageLoader.getPageSize(url)) } }

  for (i <- 1 to urls.size) { 
    receive { case (url, size) => println("Size for " + url + ": " + size) }
  }
}

Now you can't tell me that's not beautiful!

There's a lot I don't understand. For instance, my first though was to optimise out that 'caller' var, and just inline 'self' - but that didn't work. Why ever not? How many threads is it using? Does the thread pool expand if messages need to be sent but all current threads are busy? Maybe it contracts when they're idle.

Oh, and the foldLeft operator - that's going to be lots of fun.