Byzantine Reality

Searching for Byzantine failures in the world around us

First Thoughts on Scala

Another side project I’m exploring this summer is the Scala programming language. It’s got a ton of wild and wacky features and is interesting enough to merit further exploration. That being said, I’ve used Scala on and off for a few weeks and have come up with the following thoughts on Scala:

For those not familiar with Scala, it’s object-oriented (objects are “first-class”) and functional (functions are “first-class”). These have been here for a while independently, with Smalltalk from 1980 (in terms of OO languages) and Lisp from 1958 (in terms of functional languages). They’ve also been here for a while together: a notable one I’ve used in the past is O’Caml, and a library for Java exists that provides the language with closures (Functional Java). So what makes Scala special?

Scala runs on the Java Virtual Machine, and can use your current Java libraries effortlessly. There’s a lot to be said already for that, since it’s well known that academic and functional languages suffer from lack of good library support (something Java has in spades). Others have claimed that Scala can compile to MSIL and run on via the .NET Framework, but even with the official instructions I’ve had nothing but problems across several architectures and operating systems.

The other big difference between Scala and other functional, object-oriented languages (asides from the library support) is the syntax style. Languages like O’Caml and O’Haskell give you OO in the style of their original language (e.g., ML for O’Caml and Haskell for O’Haskell), which is great if you’re already an amazing functional programmer. But arguably the biggest reason functional languages haven’t been accepted is that it’s so hard to train an imperative, OO programmer (who likely was brought up on C, C++, or Java) to program in an ML/Lisp/Haskell-like language. The syntax/symantics learning curve to jump to these three languages is just too daunting for most programmers. Since Scala is closer to the C-like languages in terms of syntax and semantics, it’s inherently an order of magnitude (at least!) easier to learn than the traditional functional languages. And since it still has some minor remnants of functional syntax and semantics in it (e.g. the last statement in a function is its return value), it’s easy for functional language users to pick up.

If you’ve believed every word I’ve written blindly so far you may think Scala is the best thing since, let’s say, sliced bread. Scala’s got its weaknesses, for sure, but it’s oddly enough also its strengths (possibly…).

The first language I really got to know well was Java. And I’d venture to say that Scala is the lazy programmer’s Java in many ways. Much of the syntax is aimed at getting rid of all the repetitive, boiler-plate code that you had to write over and over and copy and paste (and violate the DRY principle). You can also do operator overloading, which isn’t immediately useful in many circumstances but looks interesting to us particularly for reasons I’ll discuss in a future post. Finally, the set of characters you can’t use when naming functions is pretty small, at least compared to Java. Your function names can have “!”, “?”, “+” and pretty much anything you like. Again, this isn’t immediately useful, but can be made more useful through the use of coding standards (e.g., functions that return boolean values can always end in a question mark ala “isServerLive?()”).

Like in Perl, with Scala, there’s more than one way to do anything. But the fact that I just drew parallels between Perl and Scala may scare you (it certainly scared me). Scala code has the potential to be incredibly readable and incredibly writable if good coding practices are used, but just like Perl, the majority of code will likely be crap without it. You skip over a whole class of Perl-based problems with Scala since there’s no dynamic typing (all typing is statically inferred), which could possibly save the language. But the obscene number of choices still makes me suspicious.

Consider: Statements can be delimited by a newline or a semi-colon (and you don’t have to be consistent about it throughout your code). Any operator can be overloaded. Functions can have almost any character in their names. Functions with no parameters can be called without the parentheses. Functions can becurried. Functions can be called in the same million ways that Perl did plus more, the key example being the following:

Suppose I write 3 + 2. This is syntactically the same as writing 3.+(2), namely calling the Integer’s plus function and passing it in the value two. There’s a little bit of weirdness going on in this specific example since it sees “3.” as “3.0″ and thus as a Double instead of an Int, but in cases where there’s actual variable names this works in the previously described manner.

Not the longest example, but you can extrapolate and see all the possibly crazy combinations of code that can pop up. And if you don’t believe me, go ask an experienced Perl developer how many orders of magnitude separate the best Perl code from the worst.

So there’s a bit of possible danger in Scala-land. But I’m still pretty excited about it. Being able to store functions in arrays and pass them and their arguments around is pretty cool (and much faster for me to write coming from Java and C).

The thing that sold me on Scala is the following code snippet, which took me about an hour to write. I was reading a paper on the Chapel programming language and their “cobegin” blocks that would automatically run the inside of the block in parallel (FYI “cobegin” was not invented by Chapel) and wanted to see if I could whip it up in Scala. The fact that I could in such a small amount of time is why I’m so excited about Scala. Granted, this version only does “println” in parallel, but presumably could be extended without mountains of work involved.

object Kata {
def main(args: Array[String]) {
var stuff = new Array[String => Unit](10)
for (i <- 0 to stuff.length – 1) {
stuff(i) = (j:String) => println(j)
}

cobegin(stuff)
}

def cobegin(parallelStatements: Array[String => Unit]) {
for (i <- 0 to parallelStatements.length – 1) {
spawn { parallelStatements(i)(i.toString) }
}
}

def spawn(p: => Unit) {
val t = new Thread() { override def run() = p }
t.start()
}
}

Of course if you don’t know Scala you’re not expected to know what this does and why it works, but this gives a good example of the syntax you’ll see in it and what it’s like. If you haven’t learned a new programming language in a while (let’s say a year) go learn Scala! The tutorial is amazing and it’ll keep you busy until C++0x comes out (which I’m certainly looking forward to) or whatever type of language you’re into shows up.