Switching to Scala

I heard about Scala a while back and got excited about it, but it wasn't until I started reading Programming in Scala by Martin Odersky (creator of the language) et al. that I realized what an absolutely brilliant language it is.  I'm not even halfway through this book and my take on it so far is that I have wasted an immense amount of time in the half my programming career that I have focused predominantly on Java.

The exciting thing is that Scala produces standard (and valid) JVM bytecodes, which (I believe) can be compiled to Javascript by GWT, work fine with Google App Engine, and can be cross-compiled to Dalvik bytecodes for use on Android.  I'm excited to try Scala with each of those platforms.

At the same time as being really excited about Scala, I wanted to document here my initial growing pains with using the language.  I am finding Scala to be awesome in concept, but a little frustrating in practice, at least initially. The reasons for that include:

  • Poor IDE support compared to Java -- no Shift-Alt-R for rename in Eclipse, for example, and compilation takes a few seconds longer than Java which can be a bit frustrating when you don't know the language well and you're having to try a zillion things to get something to work.  I know there's a daemon version of the compiler that shortens compilation from cold to warm startup time, but I think the latest versions of Eclipse uses it and the Netbeans IDE purports to have moved to it in the latest release -- but it still feels like it takes as long as a cold startup of the compiler (8 secs for a Hello World program), which is unacceptable in my opinion for incremental hacking.  (Update, see below)
  • There is a slight impedance mismatch between Java and Scala libraries, e.g. Scala implements its own collections framework, and things can get a little confusing if you try to mix Scala code with Java code that heavily relies on collections. (Of course you can always call all the Java methods to handle collections, but then you can't rely on Scala's nice syntax for working with the contents of collections, so the code looks different.) Best to stick with 100% one or the other probably. (Update, see below.)
  • I'm starting to discover a couple of tiny warts in Scala that are due to trying too hard to map onto the Java/JVM world. I had heard they exist, but now have experienced a couple of them. Nothing major and the benefits of the language will probably outweigh this in the long run, but it was something interesting to note.
  • Thinking in functional style screws with your brain -- it feels really really good, like a hard workout, but it hurts like a hard workout too. I have already adopted lots of functional paradigms in my own programming from previous forays into the FP world (in Lisp, Scheme and Haskell) and I'm a much better programmer for it, but I still need to change my algorithm design paradigms significantly to be really good at using Scala the way it potentially can be used. The lack of FP features is one of my biggest complaints about Java, so this is all welcome frustration.
  • The syntax is close enough to Java but subtly different enough that the syntax screws with your brain too if you have done a lot of Java. I haven't learned to "see" the name:Type parameter syntax without thinking about it yet, for example, so my subconscious keeps thinking of name as Type and Type as name, and I just get confused until my conscious brain talks my subconscious out of it :-) There are a lot of subtle differences between the two languages that have this effect.
  • The language encompasses a huge number of older-but-not-mainstream as well as new (as in modern) language features, absorbing the best parts of a number of languages, including ML, Scheme, Haskell, Erlang and C#, mixed into a Java-like syntax in a (surprisingly) mostly self-consistent way. However to fit all that into the language, one of the most remarkable things that Scala accomplishes is that it deconstructs the Java syntax, builds several layers of abstraction and generalization below them, and then re-builds the syntax on top of these generic layers so that the syntax is not a special case, but rather the application of a general prinicple. For example, a method call a.b(c) and an operator expression (x - y) can only be called in those ways in Java, but in Scala you could write x.-(y) or (a b c) to achieve the same effects, because infix operators are just method calls, and you can define methods using symbols. This deconstruct-generalize-reconstruct pattern is pervasive in the difference between Java and Scala, affecting everything from type inference to the handling of built-in types (int etc.) to even control flow: you can define your own control flow operators (for, while, if, try-catch etc.) -- they are just functions operating on blocks.

All in all despite the frustrations with inadequate IDE support and some minor Java/Scala impedance mismatch warts, I think my main problem with Scala right now is just unfamiliarity. It takes me 10 times longer to write anything in Scala -- but I write sometimes 10 times less code, so maybe it's worth it. As I get proficient in the language I'm sure I'll become more productive. I just hope I can learn to switch back and forth without too many brain thinkos.  (Similarly, I switched to Dvorak years ago and going back to qwerty just confuses me now :-) )

UPDATE: Peter 'kovac' Hausel (pk11 on Twitter) pointed out:

Thanks Peter!