Since my hire at Mentor Graphics, I have spent far less time writing Scala code in the evenings and far more time writing Java code during the day. I’ve found I quickly grew accustomed to some really nice features, patterns, capabilities, etc offered by Scala which simply don’t exist in Java. Even without fully embracing the functional paradigm, these features would be really handy in my day-to-day work. I thought I’d dish out a little of that frustration and disappointment into a blog post for all to enjoy by picking out my top five.
I really miss type inference. It is an outstanding feature that makes static-typing so much better. I really shouldn’t have to tell Java that I’m giving it a
final String str = "Hey Java, this here is a string.";
I especially shouldn’t have to type stuff like this:
Map<String, Map<Pair, Map<Pair, Long>>> map = // Stuff
I didn’t mark my map as
final. It’s pointless. See “Immutability” below.
While we’re talking about declarations, I’ll also point out that I much prefer the way that you define things in Scala with
var. I love how all declarations are essentially the same in Scala. There isn’t special syntax for a field vs. a method/function. The keyword simply modifies the time of evaluation (on declaration, on first evaluation, on every evaluation; respectively) or the legality of reassignment (for the evil
var). Without this, I’m stuck following the idiom of writing accessors for fields that I might otherwise just make public since Java doesn’t offer the flexibility to easily change the evaluation behavior of a member. Heh… I just said “evaluation” and “Java” in the same sentence…
There is a lot that I miss here. First I miss that collections are by default immutable, and optimized for good runtime performance. Secondly, the immutability of collections is also compile-time checked. In Java we can use
Collections.unmodifiableCollection or its variants, but we only get run-time assurance that the collection isn’t modified. I’ve also learned to routinely sprinkle my Java source with
final, but I wish I didn’t have to go through that extra effort. Immutability is sanity and therefore should be the default.
I’d say the biggest challenge I face is helping my teammates understand why it’s worth the trouble to be immutable. While I had some brief moments of self-enlightenment of my own, I never fully appreciated the value of values until my exposure to functional programming. So I understand where they’re coming from, but unfortunately I’m arriving at an even greater understanding of the challenges of evangelizing these principles.
This is worth a blog post in itself. Just like the four declaration types I mentioned previously, this is an area where Scala proves itself to be a well-thought-out language. In Java, you can only import a class into the namespace. With Scala, you can import anything and even rename them. I confess that renaming possesses a touch of evil, but I love it. I especially find this handy when I’m using a class with some long descriptive name that I don’t want to type repeatedly. It certainly behooves authors of articles and such to include any imports in code snippets.
Finally, I really miss traits. For the uninitiated, traits are like Java interfaces because a class can inherit multiple traits, but they’re like abstract classes because while they are uninstantiatable they can include code. As a result, they’re often referred to as “mix-ins”. You can have classes add behavior by slapping a trait on it, or even more interesting, slap a trait on an object when you create it. Fortunately like lambdas, default interface methods are coming in Java 8.
Of course this list is NOT exhaustive. I limited it to five because I found that I was beginning to write a blog post that simply recapped all of my previous Scala posts and added to the list of features I should blog about. Here are the others that I have found I really enjoy: case classes, (?:case)+ objects, pattern matching, monadic types, lambdas, implicit conversions, and last but not least… optional semi-colons.