Will Java 8 Kill Scala?

The most anticipated version of Java (Java 8) was released just a few days ago (18 March 2014) with a set of exciting features that is considered to be the largest to Java since the release of Java 5.

The most notable developer-facing changes are:

The most notable non-developer-facing feature is the removal of PermGen

I'm not planning to go into the details of the new features of Java 8 (probably in another post), I want to discuss the question that many people are asking. Is Java 8 going to kill Scala?

Java Folks, Welcome to Planet Lambda!

So, let's start with the new baby coming to the Java world, Lambda Expressions. Lambda functions/expressions are already in a large number of programming languages already and the Java folks are exploring what they can do with that little handy thing.

Lambdas are basically functions that can be passed as function argument, you can think of it as a short hand version of what you was doing as this example

someObject.addClickListener(new ClickListener() {  
    public void onClick(MouseEvent e) { 
        //Event listener implementation goes here...     
    }
});

You couldn't send functions as function arguments so you created an anonymous class of the interface ClickListener which contain a single method onClick that you implement, man, that's a lot of boilerplate.

It's the thing which you can do with the new Java 8 like this

someObject.addClickListener(e -> //implementation);  

Whoa! That's awesome, right? Exactly, that's why programmer using languages that support functions as first class citizens (like Scala) were screaming for similar support in Java, specially for Android development as an example.

Lambda expressions come in different names, don't get confused with naming coming from lambda calculus or functional programming, it's a world full of new names in general. The concept is really simple

(int x) -> x * x 

I will not go into too much details here but I would like to note that lambda functions in Java is not as powerful as in Scala, in fact it's just scratching the surface, for example, you cannot pass any function as first-class to other functions, the function must be explicitly defined as lambda or using Functional Interfaces which is an excellent idea for older java libraries that you can leverage the new syntax to use.

Functional Interfaces

Functional interfaces are interfaces that contain only a single method, like the one I hypothetically used in my previous example ClickListener Similarly you can use the Runnable in the same way since it only contain one method run(). You can pass lambda functions wherever you used to pass anonymous implementations of Functional Interfaces, example:

Runnable r = () -> System.out.println("I am Runnable!");  

The right hand side of this line is a lambda function definition that takes (Unit/void) as input and returns Unit/void and magically you are assigning this to Runnable interface! Got it?

Now you can write this

new Thread(  
    () -> System.out.println("I am Runnable!")
).start();

Now that's really cool, you see how concise your code has become?

Capturing Variables

Just like anonymous classes you cannot capture variables inside a closure/lambda unless it's effectively final which means that it's either local variable that nobody will ever re-assign to, or an explicitly marked final variable.

Scala-like collections

You now can write functional style operations on some of Java collections using the new java.util.stream package. See this:

List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);  
Optional<Integer> a = list.stream().map(x -> x * x).reduce((x, y) -> x + y);  

That's awesome, it looks similar to what we used to do in Scala, like

val list = List(1, 2, 3, 4, 5, 6, 7)  
list.map(x => x * x).reduce((x, y) => x + y)  

Still Scala is more concise and more accurate about the types, the Java version returns Optional<Integer> while Scala version explicitly return Int. By the way Optional<Integer> is similar to Scala's Option[Int]

Edit: It turned out as a few people noted in the comments that the Java case here is actually more type-safe and accurate, since Scala will throw runtime exception on Nil input cases. Thanks to Ricky Clarkson.

Edit 2: You can also achieve the same result as java in scala by calling reduceOption instead of reduce which returns Option[Int]

Why people moved/moving to Scala - What's the point?

Scala is not only about lambda functions, although admittedly it's one of its best selling points in comparison to Java. However, Scala offers a comprehensive functional programming syntax tools that makes writing software (specially reactive, concurrent, real-time) a pleasurable experience with great productivity and excellent running performance.

I still see a huge gap between Java and Scala and I see it clearly that Java is not turning into a functional language, it's still Java and people love Java for what it is already, the Enterpris-y stuff and solid backward compatibility. Scala on the other hand is stretching what can be a future programming language that target multi-core software development. It's multi-paradigm but is mainly winning for its unique combination of functional and object oriented features with the world's most advanced type system that no language can compete with so far.

Why Java 8 is actually good for Scala?

I'm genuinely excited about the Java 8 release because I see that java now suck less and at least I can spend my time writing Java code with less pain/cursing. I also truly believe that the move to more functional style is intellectually beneficial to Scala because it closes the gap between the two languages specially with the similar syntactic hacks. So, it's going to be easier to introduce Scala to Java developers and you don't have to explain closures, Unit, lambdas, etc. to them.

It's also an opportunity for Scala compiler developers to learn how Java actually implement the functional programming constructs to match the JVM and how the JVM will be adapted (like the recently added invokedynamic in Java 7) to support the move. For example the generated bytecode from the Java lambda functions is more efficient than Scala's version.

I think that it's a validation that the switch to more functional style offers you more productivity and with type safety you get higher quality code eventually.

This also can add cleaner support between the two languages, for example in Play Framework you can now see that the Java API of the framework allows you to write more idiomatic code like this

public static F.Promise<Result> foo() {  
    return WS.url("http://www.foo.com").get().map(response -> ok(response.getBody())); 
}

Which looks somehow close to the pure Scala version

def foo() = Action {  
  WS.url("http://www.foo.com").get.map(response => ok(response.body))

Still Scala looks cleaner but the example shows how the coding style is getting closer, somehow.

Is Scala = Java + Lambda?

What about type inference, traits, vals, implicits, case classes, value classes, static objects, pattern matching, type variance, macros, immutable datatypes, lazy vals, existential types, higher-kinded types, type classes. C'mon!

If you are interested in seeing a great example on feature differences between Java and Scala check out this answer on StackOverflow

Conclusion

Java 8 is a great step towards developer productivity and is something everybody is excited about even Scala developers (like me). I see that the goal is not to kill Scala and in fact I see no risk at all. I see two languages that can play even nicer together now and Typesafe (the company pushing Scala) is actually excited about Java 8 as some of us are.

So, I don't think Java 8 will Kill Scala by any means.

Check out this LinkedIn thread if you want to see more people talking about this topic.

Update: There seem to be a very interesting discussion on HN going on this article.

Update: An excellent comment detailing why Java 8 will not kill Scala posted by Eran Medan

comments powered by Disqus