Archive for January, 2010


Expressive or just terse?

This Scala code populates a list with objects:

// fairly standard
var people = List[Person]()
for (i <- 1 to 10) {
	people = new Person(i) :: people
}

So does this.

// slightly more functional
val people = (List[Person]() /: (1 to 10)) {(people, i) =>
	new Person(i) :: people
}

If you’re a Java programmer and just balked, you’re probably not alone. I know what it does and I have to read it from left to right to left to right again. In this case the shortcut’s a Scala mental snag equivalent to Java code like:

boolean empty = (!list.empty()) ? false : true;

There’s always going to be a pause when you read stuff like this. Remove the operator weirdness and you get:

val people = (1 to 10).foldLeft(List[Person]()) {(people, i) =>
	new Person(i) :: people
}

At least here, the reader doesn’t have to catch on to the flipping of the object and the method argument done by the /: method. In time, you probably get used to reading shortcut operators, but more than likely you’re going to be snagging for a while, and so will the next guy reading your code.

Just because you can do something, doesn’t mean you should :)

Update:
Thanks to @jstrachan for this:

val people = (1 to 10).map(new Person(_))

I have much to learn :)

NoSuchMethodException launching Scala App

This is a pretty standard thing to do in Java:

public class App {
	public static void main(String[] args) {
		App app = new App();
		app.start();
	}

	public void start() {
		// do something
	}
}

So you reckon you’d be able to do this in Scala:

object App {
	def main(args: Array[String]) = {
		val app = new App()
		app.start()
	}
}

class App() {
	def start() = {
		// do something
	}
}

You go to run it and:
Exception in thread "main" java.lang.NoSuchMethodException: id.jakubkorab.App.main([Ljava.lang.String;)
at java.lang.Class.getMethod(Class.java:1605)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:107)

Turns out the Scala compiler doesn't treat application launching in the same way that it treats other classes with companion objects. If you rename the object App to another name, it works.

object AppLauncher {
	def main(args: Array[String]) = {
		val app = new App()
		app.start()
	}
}

Go figure.

Running a Scala App in IDEA 9

My first experience with IDEA hasn’t been a good one. In all fairness, not IDEA itself, but with a plugin (isn’t that always the way). I use Eclipse on a day to day basis, but since I heard that the IDEA Scala support is much better, I decided to download the Community Edition and give it a bash.

After following these instructions to hook up a Maven Scala project in IDEA (why not just go all in) I went to run the auto generated app:

package net.jakubkorab

/**
 * Hello world!
 */
object App extends Application {
	println("Hello World!")
}

The instructions were straightforward “just do CTRL SHIFT F10 and it’ll run”. Tried that. Nothing. Huh? To the net…

“Add a new Run configuration – Scala Application”. Nothing.
Maybe it’s a plugin version thing? Google… *muttering*

“you’ll need a different plugin called Scala Application”. Search for the plugin… Doesn’t exist. *more muttering*

Finally I found this post from 2008 – seems the plugin won’t run classes that extend scala.Application – you have to give it a main() method!

NP. Given that not many people have actually met sailors, I’d like to propose “swears like a programmer”.

package net.jakubkorab

/**
 * Hello world!
 */
object App {
	def main(args:Array[String]) {
		println("Hello World!")
	}
}

CTRL SHIFT F10 and it works. If you look in Run configurations, it’s been set up as an Application, not a Scala Application like some of the other sites suggest.

Not a good start with IDEA, but like most systems with plugins, don’t throw the baby out with the bath water. I look forward to happier times from here on.