Inspired by a random tweet about their added Scala support, I tried out the Codility sample test. I rather liked my solution and I think it’s a perfect example of some of the niceties of Scala, in a small way, so here it is:

def solution(a: Array[Int]): Int = {
  // Partial sums are Longs to avoid Int overflow.
  val sums = a.scanLeft(0L)(_ + _).tail
  def equilibrium(index: Int) = leftSum(index) == rightSum(index)
  def leftSum(index: Int) = if (index == 0) 0 else sums(index - 1)
  def rightSum(index: Int) = sums.last - sums(index)
  (0 until a.length) find (equilibrium(_)) getOrElse(-1)

The use of scanLeft to build up all the partial sums is particularly handy. Having done that it’s very easy to run through all the indexes until we find one that satisfies us. Note that the find method returns an Option[A] so we use getOrElse to return -1 if no solution was found (as per the requirements).

I've been doing some trivial benchmarking of Play 2 with ab (Apache Bench) just to get an idea of its raw capabilities for serving simple requests – and because it's what I always do when picking up a new framework so I know what I'm dealing with. In doing so I ran into a bit of a puzzler that had me thinking Play 2 was bugged – but my spidey sense soon kicked in and told me it was more likely to be an OS or ab issue. I had done approximately the following, using Play 2.0.1 on OS X 10.7.3, and I'm pretty certain you'll see the same results if you do this on a Mac:

> play new hello  [select option 1 - basic Scala app]
> cd hello
> play start
> ab -c 50 -n 16000 http://localhost:9000/ [Runs fine - about 3700rps]
> ab -c 50 -n 16000 http://localhost:9000/ [Gives up with timeout]
> ab -c 50 -n 16000 http://localhost:9000/ [Runs fine - about 3700rps]
> ab -c 50 -n 16000 http://localhost:9000/ [Gives up with timeout]

It took me a bit of experimentation to establish that it's about 16000 requests that work fine, followed by timeouts, in a reliable pattern. That's a suspicious number, being near enough a power of 2, which is what clued me into it being an OS limit that I was running into. I ran the same ab test (with the same result) against the built in Apache https serving a static file, confirming that Play 2 probably wasn't to blame.

Sure enough, a quick Google turns up the goods. My OS was running out of the approximately 16000 ephemeral ports available and having to wait for them to be released before it could reuse them. So not Play 2 or ab's fault at all. Actually in some senses it is Play 2's fault for being so fast that I've run into this limit.

I'm not going to go into the details of what ephemeral ports really are, as others have done that perfectly well, and there is a good StackOverflow answer with some key ways to work around the problem by modifying parameters of the OS' network stack – but be careful and make sure you understand what you're doing.

However, one very simple way to workaround the issue is to simply pass the -k option to ab, to use HTTP keepalive (assuming the server you're testing supports it). Note that this changes the nature of your test though, as you're no longer really simulating large numbers of separate connections – but for basic sanity check testing it may help. For the record `ab -c 50 -n 100000 -k http://localhost:9000/` benchmarked Play 2 at about 7000 requests per second on my 2.4GHz Core Duo MacBook.

The hype around the Scala programming language just got too much recently and I decided to give it a go. I'm two thirds of the way through Programming in Scala, a massive but very good tome and I've been experimenting with the language and tools, though only a little bit so far. I have also just received the newly published Scala for the Impatient (a deliberately much more compact book) and will be working through that as well.

To put it mildly, Scala is not for the faint hearted, or anyone who just wants to get some stuff done ASAP. There is a big, steep learning curve and the relative immaturity of the language and the small community means you'd better be used to the pains of the bleeding edge. I thought Ruby was hard work, but Scala is frankly more so in my experience so far.

However the language is somewhat addictive – or perhaps I just like the challenge of learning stuff that takes a bit of grokking. It's a big language, with many very clever facilities and features. It's mind-boggling to start with but I think it's starting to sink in. Of course there's the functional paradigm to understand and master, but I did plenty of that at university so it doesn't frighten me.

Enough people have written about the frustrations and wonders of writing code with Scala, so I think I will reflect on a few miscellaneous findings, mostly of a practical bent.

Compiler speed

The Scala compiler is surprisingly slow and it seems to be one of the main bitching points amongst people trying to get up to speed with the language. But seriously, when you're used to instantaneous results with Grails, or even plain old Java (especially with JRebel) then waiting several seconds even for a trivial app is most upsetting. But I'm trying to be Zen about it.

The mailing lists tend to be full of griping about the compiler's speed, usually met with promises that it's getting faster, but the Scala compiler is so much more complicated than the Java compiler that it seems unlikely to do its work in the blink of an eye anytime soon. See Martin Odersky's explanation of why it's slow on Stack Overflow.

Eclipse support

Eclipse supposedly has good Scala support via the Scala-IDE plugin, but I found the out of box experience so terrible that I have given up. Having created a "new Scala project" I still had to manually add the Scala libraries to the project and manually create run configurations, which would very often still not appear in the lists of ways to run the project. I just want to hit "Go" and for my app to run – it should be trivially easy to make this happen. In my experience the best open source projects are the ones that deliver a delightful out-of-box experience and this has disappointed me on that front.

IntelliJ IDEA support

Luckily the Community (i.e. free) edition of IDEA supports Scala. Even though I hadn't used IntelliJ previously, I figured out how to download their Scala plugin and create a Scala app within just a couple of minutes and it was a very smooth experience compared to installing the Scala support into Eclipse (don't get me started).

However compilation of a Hello World app took 7 seconds every time I modified the single file! A bit of Googling led me to discover FSC – the Fast Scala Compiler – which is part of the standard Scala toolset. Support for FSC is built-in to IDEA but that support is turned off by default. Once I turned it on for my project things hotted up and compilation took just 2 seconds. That's still lamentable compared to most other languages, but just about tolerable for now. I have no idea how things go for a big project, though I get the impression from mailing lists that waiting tens of seconds or even minutes for a compile is fairly commonplace. We shall see.

Play 2.0

One of the reasons I decided to try Scala in the first place was the fuss over the Play 2.0 framework, which has just recently been released in its first 'complete' form. I have only messed with a couple of tutorials so far and frankly it's bewildering and strange coming from frameworks like Spring MVC, Grails, and Ramaze (a small Ruby framework).

There is much wailing and gnashing of teeth on the Play mailing list from people upset about its radical new direction, and its emphasis on Scala compared to Play 1. Maybe it's just the pain of change, but there's no doubt Play 2 is hard work to get to grips with.

I get the impression that a lot of people are missing the point though – it's a case of horses for courses. Play 2 is rather exotically architected using cunning non-blocking approaches that require it to abandon the classic Java Servlet container entirely. It also requires you to write obtuse and sometimes verbose code (compared to Grails say – though it's usually less verbose than Java) and partly because of that non-blocking architecture. Reading and understanding the Play 2 docs on Action Composition may very well require a PhD, but Action Composition is a technique that must be used to achieve relatively common ends. It's all a bit overwhelming for newbies.

This clever shenanigans enables it to handle 40,000 requests per second (albeit very very simple requests) using less than 20MB RAM. I saw Guillame Bort demonstrate this at QCon and it's certainly impressive. The point though is that it's all architected for the sort of new-breed web app that's dealing with connected rich-clients rapidly pushing and pulling data. If you want to create a few CRUD pages for a small admin team to look after a database then I very much doubt that Play 2 is for you.