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
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
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.
Not that I have a clue about Scala but the caller = self looks very much like a closure
ReplyDeleteI nearly understand it now :). The foreach line creates a new 'actor' for each url. The fragment in the braces is the code that is passed as-is (unexecuted, by-name) to the new actor. Creating actors like this instantiates the actor, and starts it executing in a separate thread. When these actors execute (now in their separate thread), the code is in a new context - and that's why we have to copy the value of the special variable 'self' into 'caller' - if we don't do that, 'self' will be evaluated in the actor code, where it will refer to the actor, not to context that created the actor. I think it's this binding that, as you say, makes it a 'closure'.
DeleteThen, all the actor code is send a message (using the ! method (scala methods can have symbol names)) back to the caller - the message is made of a pair (2-tuple) of values, evaluated in parallel in the actor.
The calling code code just sits in a loop until it has received the requisite number of messages, printing a diagnostic for each, and that's it! Simples!