Friday, July 20, 2012

Scala for Java Refugees Part 1: main(String[])

You know who you are.  You’re the developer who picked up Java years ago, maybe as a second language and better alternative to C++, maybe as your first language coming into the industry.  You’re comfortable with Java, you know its ins and outs, its moods.  It’s like an old girlfriend; you may not feel the vibe anymore, but you know just how to rub it so it smiles.  In short, you’re a craftsman, and Java is your workhorse tool.
You’re starting to to become a bit pragmatic about your language choice though.  To put it mildly, the Java honeymoon is over.  While you can hardly find enough fault with the language to just walk away, you’re certainly open-minded enough to consider alternatives.  You’ve heard of this new-fangled thing called Ruby – how could you not have heard, given the sheer noise level produced by its followers.  You’re impressed by the succinctness of its constructs and the power of its syntax, but you’re not sold on the idea of using a scripting language to build your enterprise app.  Dynamic typing and TextMate are all well and good, but for the real-world iron horse you’re going to need something with a bit more backbone.  As a good pragmatist, you stick with the tool that works: Java.
The good news is that there’s light at the end of the tunnel.  There’s a new language on the scene that’s taking the developer world by storm.  Scala seems to offer everything you’ve been looking for in a language: static typing, compiled to bytecode (so you can run it on all those ancient Java-capable servers), a succinct and expressive syntax.  You’ve seen a few examples which have really caught your eye.  It looks the spitting image of Java, except with half the useless constructs thrown out.  No semi-colons, no public static void method qualifiers; it even seems to have some sort of static type inference mechanism.
The only problem you have now is figuring out where to start.  You’ve tried looking on the Scala website, but what you found stopped you in your tracks.  Everything’s so…functional.  Lamdas, high-order functions, immutable state, recursion out the wazoo.  Suddenly things are looking less promising.
Have no fear, ye refugee of Java EE grid iron, all is not lost.  True, Scala is a functional language, but it’s also imperative and highly object oriented.  What does this mean?  It means that you don’t have to write code with the sole purpose of pleasing Haskell Curry.  You can write code that you can actually read a week from now.  You may even be able to show this code to your Java-loving coworkers and they just might understand it.  You don’t have to curry every function and avoid loops at all costs.  You can write your Java applications in Scala.  You just need the right introduction.

Introductions

If you’re like me and can identify with the above, then this series is for you.  I’ve read a lot of articles and tutorials on Scala (Alex Blewitt’s series is highly recommended, especially if you’re interested in the more functional side of life), but few of these tutorials have even attempted to make things easier for the run-of-the-mill Java developer to make the transition.  I personally have very little FP (Functional Programming) experience, so I don’t think I could write an article about porting Scheme code to Scala even if I wanted to.  Instead, this series will focus on how Scala is just like Java, except better.
Did I mention Alex’s Scala introduction series?  Seriously, this is great reading, and not a bad introduction to Scala in and of itself.  Once you’re done reading my ramblings, you should run over and read some of his more coherent stuff.   The more the merrier!

Getting Started


object HelloWorld extends Application {
  println("Hello, World!")
}
Nothing like getting things rolling with a little code.  Notice the refreshing lack of mandatory semicolons.  We can use them anyway, but they aren’t required unless we need multiple statements on a single line.  This code sample does exactly what it looks like, it defines an application which (when run using the scala interpreter) will print “Hello, World!” to stdout.  If you put this code into a file with a .scala extension, you can then compile it using the scalac compiler.  The result will be a single .class file.  You could technically run the .class using the java interpreter, but you would have to mess with the classpath a bit.  The easiest thing to do is just use the scala command like so:

scalac hello.scala
scala HelloWorld
Notice the name of the file in question?  Unlike Java, Scala doesn’t force you to define all public classes individually in files of the same name.  Scala actually lets you define as many classes as you want per file (think C++ or Ruby).  It’s still good practice to follow the Java naming convention though, so being good programmers we’ll save our HelloWorld example in a file called “HelloWorld.scala”.

Editors

Just a brief note on your first few moments with Scala: using the right editor is key.  As you must have learned from your many years in the Java world, IDEs are your friend.  Scala, being a much younger language doesn’t have very good IDE support yet.  It is a static, general purpose language like Java, so IDE support will be forthcoming.  For the moment however, you’re stuck with a very limited set of options.
  • Eclipse (using one of two shoddy and unstable Scala plugins)
  • Emacs
  • IntelliJ (basically just syntax highlighting support)
  • TextMate
  • VIM
  • jEdit
There are a few other options available, but these are the biggies (to see a full list, look in the misc/scala-tool-support/ directory under the Scala installation root).  My personal recommendation is that you use jEdit or TextMate, though if you’re feeling adventurous you’re free to try one of the Eclipse plugins too.  Scala support in Eclipse has the advantage (at least with the beta plugin) of features like semantic highlighting, code completion (of both Scala and imported Java classes) and other IDE-like features.  In my experience though, both Eclipse plugins were unstable to the point of unusable and as such, not worth the trouble.  Scala is a much cleaner language than Java, so it really does have less of a need for a super powerful IDE.  It would be nice, no question about that, but not essential.

More Hello World


object HelloWorld2 {
  def main(args:Array[String]) = {
    var greeting = ""
    for (i <- 0 until args.length) {
      greeting += (args(i) + " ")
    }
    if (args.length > 0) greeting = greeting.substring(0, greeting.length - 1)
 
    println(greeting)
  }
}
Save this in a new file (we’ll call it “HelloWorld2.scala”), compile and run using the following commands:

scalac HelloWorld2.scala
scala HelloWorld2 Hello, World!
Once again, this prints “Hello, World!” to stdout.  This time we did things a little differently though.  Now we’ve got command line arguments coming into our app.  We define a variable of type String, iterate over an array and then call a bit of string manipulation.  Fairly straightforward, but definitely more complex than the first example.  (Note: Scala mavens will no doubt suggest the use of Array#deepMkString(String) (similar to Ruby’s Array::join method) instead of iterating over the array.  This is the correct approach, but I wanted to illustrate a bit more of the language than just an obscure API feature).
The first thing to notice about this example is that we actually define a main method.  In the first example, we just extended Application and declared everything in the default constructor.  This is nice and succinct, but it has two problems.  First, we can’t parse command line args that way.  Second, such examples are extremely confusing to Scala newbies since it looks more than slightly magical.  Don’t worry, I’ll explain the magic behind our first example in time, but for now just take it on faith.
In the example, we define a main method that looks something like our old Java friend, public static void main.  In fact, this is almost exactly the Scala analog of just that method signature in Java.  With this in mind, an experienced developer will be able to pick out a few things about the language just by inspection.
First off, it looks like all methods are implicitly public.  This is somewhat correct.  Scala methods are public by default, which means there’s no public method modifier (private and protected are both defined).  It also looks like Scala methods are static by default.  This however, is not entirely correct.
Scala doesn’t really have statics.  The sooner you recognize that, the easier the language will be for you.  Instead, it has a special syntax which allows you to easily define and use singleton classes (that’s what object means).  What we’ve really declared is a singleton class with an instance method, main.  I’ll cover this in more detail later, but for now just think of object as a class with only static members.
Upon deeper inspection of our sample, we gain a bit of insight into both Scala array syntax, as well as an idea of how one can explicitly specify variable types.  Specifically, let’s focus on the method declaration line.

def main(args:Array[String]) = {
In this case, args is a method parameter of type Array[String].  That is to say, args is a string array.  In Scala, Array is actually a class (a real class, not like Java arrays) that takes a type parameter defining the type of its elements.  The equivalent Java syntax (assuming Java had an Array class) would be something like this:

public static void main(Array<String> args) {
In Scala, variable type is specified using the variable:Type syntax.  Thus, if I wanted to declare a variable that was explicitly of type Int, it would be done like this:

var myInteger:Int
If you look at the sample, we actually do declare a variable of type String.  However, we don’t explicitly specify any type.  This is because we’re taking advantage of Scala’s type inference mechanism.  These two statements are semanticly equivalent:


var greeting = ""


var greeting:String = ""
In the first declaration, it’s obvious to us that greeting is a String, thus the compiler is able to infer it for us.  Both greetings are staticly type checked, the second one is just 7 characters shorter.  :-)
Observant coders will also notice that we haven’t declared a return type for our main method.  That’s because Scala can infer this for us as well.  If we really did want to say something explicitly, we could declare things like this:

def main(args:Array[String]):Unit = {
Once again, the type antecedes the element, delimited by a colon.  As an aside, Unit is the Scala type for I-really-don’t-care-what-I-return situations.  Think of it like Java’s Object and void types rolled into one.

Iterating Over an Array


var greeting = ""
for (i <- 0 until args.length) {
  greeting += (args(i) + " ")
}
By the way, it’s worth noting at this juncture that the convention for Scala indentation is in fact two spaces, rather than the tabs or the four space convention that’s so common in Java.  Indentation isn’t significant, so you can really do things however you want, but the other four billion, nine hundred, ninety-nine million, nine hundred, ninety-nine thousand, nine hundred and ninety-nine people in the world use the two space convention, so it’s probably worth getting used to it.  The logic behind the convention is that deeply nested structure isn’t a bad sign in Scala like it is in Java, thus the indentation can be more subtle.
This sample of code is a bit less intuitively obvious than the ones we’ve previously examined.  We start out by declaring a variable, greeting of inferred type String.  No hardship there.  The second line is using the rarely-seen Scala for loop, a little more type inference, method invocation on a “primitive” literal and a Range instance.  Developers with Ruby experience will probably recognize this equivalent syntax:

for i in 0..(args.size - 1)
  greeting += args[i] + " "
end
The crux of the Scala for loop is the Range instance created in the RichInt#until method.  We can break this syntax into separate statements like so:

val range = 0.until(args.length)
for (i <- range) {
Oh, that’s not a typo there declaring range using val instead of var.  Using val, we’re declaring a variable range as a constant (in the Java sense, not like C/C++ const).  Think of it like a shorter form of Java’s final modifier.
Scala makes it possible to invoke methods using several different syntaxes.  In this case, we’re seeing the value methodName param syntax, which is literally equivalent to the value.methodName(param) syntax.  Another important action which is taking place here is the implicit conversion of an Int literal (0) to an instance of scala.runtime.RichInt.  How this takes place isn’t important right now, only that RichInt is actually the class declaring the until method, which returns an instance of Range.
Once we have our Range instance (regardless of how it is created), we pass the value into the magic for syntax.  In the for loop declaration, we’re defining a new variable i of inferred type Int.  This variable contains the current value as we walk through the range [0, args.length) - including the lower bound but not the upper.
In short, the for loop given is almost, but not quite equivalent to the following bit of Java:

for (int i = 0; i < args.length; i++) {
Obviously the Java syntax is explicitly defining the range tests, rather than using some sort of Range object, but the point remains.  Fortunately, you almost never have to use this loop syntax in Scala, as we'll see in a bit.
The body of the loop is the one final bit of interesting code in our sample.  Obviously we're appending a value to our greeting String.  What I'm sure struck you funny (I know it did me) is the fact that Scala array access is done with parentheses, not square brackets.  I suppose this makes some sense since Scala type parameters are specified using square brackets (rather than greater-than/less-than symbols), but it still looks a little odd.
To summarize, the upper sample in Scala is logically equivalent to the lower sample in Java:


var greeting = ""
for (i <- 0 until args.length) {
  greeting += (args(i) + " ")
}


String greeting = "";
for (int i = 0; i < args.length; i++) {
    greeting += args[i] + " ";
}

A Better Way to Iterate

In Java 5, we saw the introduction of the so-called for/each iterator syntax.  Thus, in Java we can do something like this:

for (String arg : args) {
    greeting += arg + " ";
}
Much more concise.  Scala has a similar syntax defined as a high-order function - a function which takes another function as a parameter.  I'll touch on these more later, but for the moment you can take it as more magic fairie dust:

args.foreach { arg =>
  greeting += (arg + " ")
}
Here we see that foreach is a method of class Array that takes a closure (anonymous function) as a parameter.  The foreach method then calls that closure once for each element, passing the element as a parameter to the closure (arg).  The arg parameter has an inferred type of String because we're iterating over an array of strings.
Now as we saw earlier, Scala methods can be called in different ways.  In this case we're calling foreach omitting the parentheses for clarity.  We also could have written the sample like this:

args.foreach(arg => {
  greeting += (arg + " ")
})
Scala actually defines an even more concise way to define single-line closures.  We can omit the curly-braces altogether by moving the instruction into the method invocation:

args.foreach(arg => greeting += (arg + " "))
Not bad!  So our fully rewritten sample looks like this:

object HelloWorld2 {
  def main(args:Array[String]) = {
    var greeting = ""
    args.foreach(arg => greeting += (arg + " "))
    if (args.length > 0) greeting = greeting.substring(0, greeting.length - 1)
 
    println(greeting)
  }
}
The syntax looks great, but what is it actually doing?  I don't know about you, but I hate having to use APIs that I don't know how to replicate myself.  With a bit of work, we can recreate the gist of the Scala foreach method in pure Java.  Let's assume for a moment that Java had an Array class.  In that Array class, let's pretend there was a foreach method which took a single instance as a parameter.  Defined in code, it might look like this:

public interface Callback<T> {
    public void operate(T element);
}
 
public class Array<T> {
    // ...
    public void foreach(Callback<T> callback) {
        for (T e : contents) {   // our data structure is called "contents"
            callback.operate(e);
        }
    }
}
I could have defined foreach recursively (as it is defined in Scala), but remember I'm trying to keep these explanations clear of the tangled morass that is FP.  :-)
Sticking with our goal to see an analog to the Scala foreach, here's how we would use the above API in Java:

public class HelloWorld2 {
    public static void main(Array<String> args) {
        final StringBuilder greeting = new StringBuilder();
        args.foreach(new Callback<String>() {
            public void operate(String element) {
                greeting.append(element).append(' ');
            }
        });
        if (args.length() > 0) {
            greeting.setLength(greeting.length() - 1);
        }
 
        System.out.println(greeting.toString());
    }
}
Starting to see why Scala is legitimately appealing?  If you're like me, you just want Scala to be a more concise Java.  In this case, that's exactly what we've got.  No strange functional cruft, no immutable state.  Just solid, hard-working code.

A Word About Built-in Types

Because Scala is built on the JVM, it inherits a lot of its core API directly from Java.  This means you can interact with Java APIs.  More than that, it means that any code you write in Scala is using Java APIs and functions.  For example, our sample HelloWorld2 is using a string variable greeting.  This variable is literally of type java.lang.String.  When you declare an integer variable (type Int) the compiler converts this to the Java primitive type int.
It's also worth noting that there are a number of built-in implicit conversions (just like the Int to RichInt we saw earlier with the Range creation).  For example, Scala's Array[String] will be implicitly converted to a Java String[] when passed to a method which accepts such values.  Even Scala type parameters are available and interoperable with Java generics (in the current development version of Scala and slated for inclusion in 2.6.2).  In short, when you use Scala you’re really using Java, just with a different syntax.

Conclusion

Scala doesn’t have to be complex, needlessly academic or require a master’s degree in CompSci.  Scala can be the language for the common man, the 9-5 developer who’s working on that next enterprise web application.  It has real potential to provide the clear syntax Java never had without forsaking the power and stability of a trusted, first-class language.  Convinced?
Up next, classes, methods and properties: everything you need to know to get rolling with object-oriented programming in Scala.


(codecommit)

Digg Google Bookmarks reddit Mixx StumbleUpon Technorati Yahoo! Buzz DesignFloat Delicious BlinkList Furl

0 comments: on "Scala for Java Refugees Part 1: main(String[])"

Post a Comment