Showing posts with label Scala. Show all posts
Showing posts with label Scala. Show all posts

Sunday, July 6, 2008

Why you should take a look at Scala and where to start?

Scala is advertised as the successor to Java by some and as an experimental ground for new features by others. According to its creator, Martin Odersky, it is supposed to be the swiss army knife of programming languages, something that is a scripting language and yet still offers all that Java has and more. When saying that it is a scripting language, it is referencing the usual characteristics of these languages which is dynamic typing and low verbosity (Scala is NOT dynamically typed, it does type inference which in practice means that you rarely have to declare the type of your variables.). It is very difficult at this point to determine if Scala is going to be widely used, so why should you use time on Scala? Why not Groovy or Ruby? The two latter languages are definitely worth looking at, however they truly are scripting languages and most of their popularity is not so much due to the language itself, but more due to their application in Rails frameworks. If you are already familiar with scripting languages, then these languages have very few new features but mostly polished versions of existing concepts (Ruby is as old as Java, so very few things are actually new in Ruby). Scala on the other side has a number of features that are bit more original or at least cutting edge, so even if Scala doesn’t make it as a mainstream language a lot of the features in the languages are likely to appear in whichever language makes it. So why not get a heads start? Now, I am in no way a language expert, I am practitioner not a theorist, but this is the general feeling I get from the people I talk to and the what I read around the net.

So where should you start? To understand the why of Scala and the principles it was built on, I can recommend the presentation that Martin Odersky gave at JavaOne. Audio and the slides can be found at the Sun Developer Network here (subscription required). I was at the session and I can testify that looking around the room there were quite a few of the big shots of the Java world attending (such as Joshua Bloch and Brian Goetz). A light introduction aimed at Java developers called Scala for the Java Refugee, I found very useful to get a quick start with a mapping from Java concepts to Scala concepts. After that you can move to the more Scala specific features that are appropriately presented in the Scala tutorials from the official site. I found the tutorials very concise and a good introduction to all the major concepts of Scala. As for books, there is only one I know off at this point and it is the Programming in Scala book. It is due out at the end of July, but you can already get a PDF version and preorder the book. I've heard positive things about it and I have preordered the paper version.

So after reading all this, what next? Well as for everything else in computer science, you have to start coding. Starting up is fairly easy, you can follow the documentation on the official site, and you should be compiling and running in no time. There are Ant and Maven targets available so integrating it into an existing project is fairly easy. As for which IDE to use, I've tried Netbeans, Eclipse and IntelliJ IDEA. They all have Scala plugins, at more or less advanced stages. Although I am a big IDEA fan, the Eclipse plugin is for now doing the best job, although it is by no mean very stable. I am, however, going to keep a close eye on IDEA 8 and the Scala plugin that is scheduled to come out shortly after. Scala is completely compatible with existing Java libraries, so you won't have to reinvent the wheel for every part of your program. This goes for all libraries and not just the trivial ones, I've successfully used Scala with Hibernate for example. You should have no problem running inside an application server either. Therefore, there is no reason to start from scratch with Scala, you can just take a component of your application and implement it with Scala, and keep the rest of your existing code.

Personally, I have implemented an Applet using Scala and I found the language very pleasant once you get used to the syntax. You can do some things very efficiently, and I find that the language is generally very readable. Java is definitely very verbose compared to Scala, and I found that having no checked exceptions and closures really make the code focus on the "what" of the program and much less on the "how". The use of Actors for Swing, is also very interesting and made for some really readable event driven code. I can warmly recommend that you give this a shot, if only to get a perspective on different programming constructs.

Saturday, January 19, 2008

What are closures and what do they mean to Java?

I will try and show an example of what closures can be used for and how this functionality looks like if implemented in the current version of Java. I will be using the Scala programming language to demonstrate a closure. Scala is a brand new language that is running on the JVM. I am by no measure a Scala expert, actually prior to writing this post I've only spent a few hours looking at the language. Therefore if you are a Scala guru, please be gentle if commenting about the code.

Before showing you the code, let's first define what a closure is. According to Martin Fowler: A closure is a block of code that can be passed as an argument to a function call. It's not a new idea, it has been around since Scheme in the 60's. It was usually associated with functional programming and not object oriented programming, but it now exists in many OO languages like Ruby and C# (2.0). So what is that you can do with them that you cannot do in Java now?

Let us take an example of what a closure could be used for. File manipulation is a common function in any language and in many languages it requires resource handling of some sort. Doing file operations can usually be abstracted to: Opening the file, so your stuff, close the file. If you forget to close the file, this might lead to your process running out of file pointers. So let's try and abstract resource management a bit and let's write a method on a file that will let you perform an operation on each line of a file without having to worry about opening and closing the file. The example below is as I said in Scala. One of the very nice features is that you can reuse all existing Java classes, so I'll extend the File class and add a forEachLine method to it. This method allows you to pass a block of code that will be executed on each line of the file. So here is the new class:

package ScalaApplication2

import java.io.File
import java.util.Scanner

class ScalaFile(filename: String) extends File(filename: String) {

def forEachLine(parseLine: (String) => Unit) {

val scanner = new Scanner(this)
try {
while ( scanner.hasNextLine() ) {
parseLine(scanner.nextLine())
}
} finally {
scanner.close()
}
}

def compareTo(other: Any): Int = {
0
}

}


So what is going on here? We've extended the File class and added a new method called forEachLine. It takes on parameter named parseLine and it is defined as a function type which takes one parameter of type String and returns nothing (Unit seems to be the synonym of void). As you can see, it is very easy to define a function as a parameter to a method in Scala and it is equally easy to use it inside the while loop. So now that we've implemented this new method let us look at how it can be used.
package ScalaApplication2

object ScalaMain {

def main(args: Array[String]) = {
val file = new ScalaFile("C:\\testFile.txt")
var charCount = 0
file.forEachLine((line: String) => {
println(line)
charCount += line.length()
})
println("Number of characters in File: " + charCount)
}

}


So here we use the forEachLine method to print each line and count the number of characters in the file. To do this we create an anonymous function and as can be seen it is fairly straight forward. Note that the variable charCount is defined outside the scope of the anonymous function and yet can seamlessly be used inside the code block of the anonymous function. Keep that in mind for later.

Our goal of hiding resource management is reached since opening and closing the stream in encapsulated inside the forEachLine method of the ScalaFile class. Now let us look at how we can do this in Java. To get closure like behavior in Java, we need to use interfaces and anonymous classes. Below is the implementation of the new File class that we will us.

package javaapplication1;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;

public class JavaFile extends File {

public JavaFile(String filename) {
super(filename);
}

public void forEachLine(JavaFileCallback callback) {

Scanner scanner = null;
try {
scanner = new Scanner(this);
while(scanner.hasNextLine()) {
callback.parseLine(scanner.nextLine());
}
} catch (FileNotFoundException ex) {
Logger.getLogger(JavaFile.class.getName()).log(Level.SEVERE, null, ex);
} finally {
if(scanner != null) {
scanner.close();
}
}

}

public interface JavaFileCallback {

void parseLine(String line);

}

}



Since we cannot pass functions or methods (at least not in a type safe way) as a parameter to our method we have to use an interface with a callback method. Still our goal is accomplished, the stream is opened and closed inside our forEachLine method. Now let's look at what the caller has to do.

package javaapplication1;

import javaapplication1.JavaFile.JavaFileCallback;

public class JavaMain {

public static void main(String[] args) {

JavaFile javaFile = new JavaFile("C:\\testFile.txt");
final int[] charCount = {0};
javaFile.forEachLine(new JavaFileCallback() {
public void parseLine(String line) {
System.out.println(line);
charCount[0] += line.length();
}
});
System.out.println("Number of characters in File: " + charCount[0]);
}

}


In Java, instead of having an anonymous function, we have an anonymous class that we pass to our forEachLine method. Now we all know that variables from the parent class cannot be accessed inside the anonymous class unless they are declared final. So how do we pass on our charCount variable? Well, we have to use a final object reference which variables we can mutate. In this case, we simply use an array. This adds some overhead but it is the only way to do it.

I've just demonstrated that we can replicate the exact behavior of closures with interfaces and anonymous classes. I will even go as far as saying that anything a closure can do, you can implement using the current version of Java (I will stand by this until proven wrong :-). However, that is not so much the point. This is a very simple example and there are more complex uses of closures which require even more complex code in Java. Therefore, the point is that you can do some fairly complex things with little and simple code in a language that has closures built in. In Java, you can do it but let us be honest it does not look pretty. Yet we do it everyday. Think of how many times you've had to create a runnable or callable to simply pass it on to an execution service. It would be much nicer to simply pass blocks of code around instead of actual classes and interfaces.

This is not intended to add anything new to the debate about closures in Java, just to give you an idea of what they are through a simple example. If you're interested in knowing more about closures and the many problems that need to be resolved if we want them in Java, you should check out Neal Gafter's blog. He is one of the driving forces behind the current proposal for Java and has many more examples and in depth discussions about the pros and cons (let's face it mostly pros, but it's still good reading).