Screen Shot 2014-10-17 at 11.08.47

How do Java 8 and Scala lambdas compare? And why do people find the latter language so brain-bending? Softwaremill co-founder Adam Warski walks Voxxed through the latest dispatches from planet Scala, and offers a snapshot of JVM related JavaOne talks. 

Voxxed: You develop in both Scala and Java:  Have there been changes in the Scala community since the launch of Java 8, with its Scala flavoured features?

Adam: From what I see I would say the impact of Java 8 on Scala has been quite small. A simple experiment, searching the scala-user mailing list for “Java 8” doesn’t reveal a lot of recent discussions. For sure there is some interest, but grouped mainly around questions on interoperability.

Java and Scala are quite separate (JVM-based) ecosystems; while you can call one from the other, in reality you rather end up using Scala libraries in a Scala project and Java libraries in a Java project, as it is simply much more convenient, or writing adapters. The main impact of Java 8 on Scala, or rather of JVM updates on Scala, will be visible in Scala 2.12, which will target Java 8 and generate Java 8-style closures during compilation. But these won’t be user-facing, API changes.

Scala already had lambdas, stream-like operations, default methods (implemented as methods on traits) for a long time, and in richer versions. Moreover, there’s much more to functional programming than lambdas! The emphasis on immutability is especially important.

I think a community that might see more changes is the Groovy community; unlike Scala, Groovy is much more of a “better Java,” building on Java’s syntax and standard library. For example: most of Java’s source code is valid Groovy. Groovy also uses Java’s standard collection interfaces, while Scala has its own library. Hence while Scala can be seen as an ecosystem replacement for Java, Groovy may appear less attractive as a “better Java” with the new Java 8 features.

How do Java 8 and Scala lambdas compare in your opinion?

Conceptually they are the same construct, but the Scala implementation is more powerful. I think the main point where Scala wins is proper function types. For example, I can say that I want my method to accept a parameter of type (Person, String, Int) => Double, while in Java I would have to create my own interface, and declare the parameter as a type of this interface (I could also use the `BiFunction`/`Function` interfaces for one- and two-parameter functions, but still the syntax is far from ideal).

Scala also has things such as by-name parameters or partially applied functions, which are very useful in everyday Scala programming, but simply absent from Java. The one thing that Java does, but Scala doesn’t, is the ability to use a lambda expression where a single-abstract-method interface is expected.

While this is great in Java where, thanks to that feature, you can use lambdas in a lot of places from day one, this isn’t really a problem in Scala, which has libraries designed with function types and closures in mind. The only time I wish Scala had this feature is when interfacing with Java. There are also technical differences, Java 8 closures are compiled differently and can be called more efficiently, but, as I already mentioned, that is going to be part of the Scala 2.12 release.

In your talk, “Keep It Simple with Scala”, you demonstrated that Scala perhaps doesn’t deserve its bad rap for complexity. Why does it have this reputation your opinion?

One of the reasons might be that Scala originated from an academic environment and is only making its way into the enterprise now, unlike some of the other languages, which have emerged from the enterprise. I think we tend to label anything coming from academia as “complicated” and “hard to understand.” Scala does have quite a lot of novel features, or combined in a novel way, but at the core the language is quite simple.

Also, Scala is still a young language, and the patterns on how to use Scala in a good way are only emerging. While it is possible to abuse Scala and create monstrous, unreadable code, nothing in the language forces you to do that. On the contrary, using Scala we can write elegant, readable and intention-revealing code, but as with everything and in every language, it’s something that you have to learn. There are also things you simply shouldn’t do in Scala, and we are discovering what they are now.

I think Java went through a similar process. Next year Java will be 20, and that’s quite a lot of time to find out what’s wrong and right. Looking at some early Java code, a lot of people would probably exclaim in horror. Scala marked its 10th anniversary, but widespread industry usage came much later, so I think it’s only coming through the learning process now.

Can you walk us through some of the coding examples from this talk here?

Sure. The talk consisted of three parts, each showing how using a Scala library you can write elegant, readable (which is always very important!) and compact code, containing minimal boilerplate, so let me include three examples here as well. Note that “simple” doesn’t necessarily mean basic examples, or easy problems. Rather, it refers to the result being clear, not entangled with accidental complexity.

Firstly, take a look at this Spray.io (soon-to-be akka-http) snippet:

object SprayComplete extends App with SimpleRoutingApp {
  startServer(interface = "localhost", port = 8080) {
    get {
      path("hello") {
        complete { “Hello world!” }
      }
    }
  }
}

That’s all you need to write a runnable HTTP service with a single endpoint. No annotations, run-time reflection, containers, handler classes. Can it get any simpler? Not only simple, it’s asynchronous and scalable as well – both when it comes to handling more requests, or when it comes to adding more endpoints.

Secondly, Scala Async let’s you write asynchronous code as if it was synchronous. Take a look at this snippet:

val result: Future[Int] = async {
  val f1 = Future { /* complex computations */ random.nextBoolean() }
  val f2 = Future { /* complex computations */ 42 }

  if (await(f1)) await(f2) else 0
}

The `await(…)` method takes a `Future[T]` and returns the wrapped `T` – it looks like a blocking call! However, by wrapping the block with async, the code is transformed at compile time (async is a macro), to a non-blocking version. Hence the result is also a Future.

Working with Futures is very common when writing asynchronous code. Using for-comprehensions makes this task easier, however still expressing complex logic like the conditional above results in hard-to-read code. Here, the intent is expressed clearly, it is easy to understand what it does.

Finally, for my third example, MacWire generates class instantiation code when doing manual Dependency Injection. Especially when coming for the Java world, it seems natural to use a container for DI. However, very often that is not needed, and instead we can do DI by hand, simply writing the code to create the object graph. This has a number of benefits: compile-time type safety, less frameworks, higher flexibility, no containers, run-time reflection, while retaining the testability.

Still, writing the new instance creation code and enumerating all dependencies can be tedious. MacWire helps with that:

class DatabaseAccess()
class SecurityFilter()
class UserFinder(databaseAccess: DatabaseAccess, securityFilter: SecurityFilter)
class UserStatusReader(userFinder: UserFinder)

// Will expand to new DatabaseAccess()
lazy val theDatabaseAccess = wire[DatabaseAccess]
lazy val theSecurityFilter = wire[SecurityFilter]
lazy val theUserFinder = wire[UserFinder]
// Will expand to new UserStatusReader(theUserFinder)
lazy val theUserStatusReader = wire[UserStatusReader]

Like `async` before, `wire[]` is a macro, so there’s no run-time overhead. At least for me, the result is readable code, with as little boilerplate as possible, in other words: simple. If you are interested, you can find a bit more developed examples on GitHub, or in my guide to DI in Scala.

Can you run us through the basics of your second talk, “Scala Macros: What Are They, How Do They Work, and Who Uses Them?”

Scala Macros are a relatively new feature of Scala. They were introduced in Scala 2.10, and still carry “experimental” status. However, there’s a lot of libraries using macros today, and overall I think it is a successful experiment.

Using macros you can do compile-time metaprogramming. Macros provide a replacement for many usages of run-time reflection, with the additional benefit of producing type-checked code, and no runtime overhead. They also allow to create internal DSLs which have an even more natural feel, as well as provide compile-time parsing for external DSLs.

Macros are written in Scala, so the macro-language is the same as the host language. In a macro you have access to a part of your code’s abstract syntax tree (AST). Currently Scala supports `def` macros, and you can manipulate the DSL of any code that the method-macro invocation contains.

Looking towards the future, Scala 2.12 should contain macros in the current form, and a successor is also in development, Project Palladium (Scala Meta). Scala Meta will provide more accessible API for macro writing, better IDE integration and a lot of other improvements.

Can you give us some code examples?

As a very basic example of what a macro can do, let’s see what it takes to write a ‘debug(exp)’ macro. Such a macro should generate the following code: ‘println(“exp = “ + exp)’, where ‘exp’;  is an arbitrary expression. This macro can be in fact very useful in “println-debugging”, where you often need to print the value of the variable together with the name of the variable.

Note that writing such a method is not possible without macros, as we need to convert the **code** passed to the method to a string representation.

A complete macro implementing the above:

object Step4Complete {
  def debug(param: Any): Unit = macro debug_impl

  def debug_impl(c: Context)(param: c.Expr[Any]): c.Expr[Unit] = {
    import c.universe._

    val paramRep = show(param.tree)
    c.Expr[Unit](q"""println($paramRep + "=" + $param)""")
  }
}

We can see that  although `debug` looks like a normal method invocation to the API user, the implementations specifies that it is a macro. The macro implementation itself first converts code to a string (using the `c.universe.show` method), and the using quasi-quotes – a string-interpolation-like construct for generating Scala ASTs – creates the println method invocation.

If you’d like to find out more about macros, take a look at my Scala macros tutorial.

Are there any other up-and-coming JVM languages you think we should be keeping an eye on?

There are a lot of new languages, however they all seem very similar. When Java was introduced it offered a combination of features which resulted in a radically new approach to development. With Scala, the leap wasn’t that big maybe, but still the one significant feature of Scala was creating a practical blend of the object-oriented and functional approaches, and bringing functional back to the mainstream.

Most of the new languages don’t differ that much. Not that they don’t have interesting features, like Ceylon’s sum&intersection types and flow-typing or Dotty’s unification of type parameters and abstract type members, but they don’t seem to be major breakthroughs. Evolution rather than revolution.

Maybe the next big thing will be pure-FP on the JVM, like Frege? I also heard predictions that Prolog-based languages will be the next hit. There are also a lot of interesting things happening outside the JVM, like Elm – a functional language for client-side programming, which seemed like an oxymoron not long ago.

What do you see for the future of Scala?

Scala is transitioning from a start-up, research language towards a wide-audience, enterprise one. Hence I would expect less new features, and more stabilisation and standardisation, and I think that is where Typesafe is heading. Part of this process is establishing the “Scala best practices” as I mentioned before, but also the community build efforts, addressing binary compatibility and others.

I think Scala has a lot of potential to show people that things can be done in a simpler way. I come from the Java world, and the amount of boilerplate and ceremony required to do even simple things is really surprising. It did get better with the introduction of annotations and a move towards embedded containers, though still, creating simple web apps, transforming & manipulating data should be much easier than it is. With Scala you can do a lot using just the base language and a carefully selected set of helping libraries (an important distinction – libraries, not frameworks).

I’m not sure where the more “radical” and “pure” FP Scala movement will head, represented e.g. by the Typelevel family of projects. While there’s certainly a lot of value in writing side-effect-free, immutable code, and I try to code in that style as much as possible myself, I don’t know if it’s practical to do this exclusively. A lot of Scala’s value comes from its unique blend of OO and FP features. I know it is possible to code using Mondas, Functors, Trampolines etc., but at least with the current syntax and the encoding of these concepts in Scala, I’m not sure if the end result is readable, maintainable and if the benefits of such constructs justify the costs. But maybe I’m just not used enough to that style of coding.

Scala is a great language, and there’s still a lot of work ahead to show people what can be done with it, either by simply writing projects using the Scala ecosystem, as we do at SoftwareMill, taking part in developing one of the great open-source projects or by taking part in the community life (such as our Central-European Scalar conference).

Image by Paolo Campioni 

 

 

 

 

 

 

 

‘Java 8 & JVM Update impacts will be visible in Scala 2.12’

| Programming Languages| 2,151 views | 1 Comment
About The Author
- Editor of Voxxed.com, focusing on all things Java, JVM, cloud-y, methodical, future-fantastic, and everything in between. Got a piece of news, article or tutorial you'd like to share with your fellow Voxxians? Drop us a line at info@voxxed.com

1 Comment

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>