From Java to Scala: A New Paradigm

Erik Lundqvist
Binary Dreams
Published in
5 min readJan 6, 2014

--

Ruby and Objective-C are the last two new programming languages I learned. Both are very different from my core language, Java, when it comes to style and syntax, but they are both imperative languages. This time I wanted something different. I wanted to learn a new way of thinking, a new paradigm.

A developer solves problems all day long, and sometimes all night. Usually, it is the developer with the most knowledge and context for a problem who will solve it the quickest, and produce the most elegant solution. In my last role, where we used both Java and Ruby, I picked up a few functional programming tricks, which required a lot less code than the imperative equivalent.

Functional programming is not a new paradigm, it’s been around since the 1930s, but it is not as popular as object oriented programming (OOP) and other derivatives of imperative programming. At least not from a commercial perspective, but this is all changing, and several ‘new’ functional languages have popped up lately.

I choose Scala, which supports both functional programming and OOP. This way, I can learn a new paradigm and a new language at the same time.

Why Scala?

If you want to learn a functional programming language there are a number of other options than Scala. Clojure, another member of the JVM family, has a fantastic community and immutability is built into the language. Haskell and Erlang are another two popular functional languages, but neither runs inside the JVM.

One of the key advantages offered by JVM membership is interoperability with Java. It means you can start using Scala in a legacy Java application without having to make any changes to the old code. New, leaner and more coherent modules can be written in Scala.

Scala supports both functional programming and OOP. To a purist functional programmer this might be a big no no, but for someone who wants to introduce a new paradigm into a organisation this is a big benefit. It will be easier to win over a sceptical team if you can drip feed them elegant and succinct solutions to problems using functional programming paradigms. Remember what I told you earlier about expanding your toolset to solve problems easier? If OOP offers a better solution to a problem, then use that, and vice versa. Scala makes all this possible.

Type-safety is to some a curse word, but it is hard to ignore the benefits it provides. For smaller applications it makes less of a difference, but when you are working on larger systems catching silly type errors at compile time saves a lot of time. Not to mention how much easier it makes refactoring when a type is known. Scala is of course statically typed.

From a commercial point of view Scala is now considered a ‘safe’ language to use. A number of large organisations have proven it can be used successfully to produce scalable solutions. As a programmer you learn a lot of things you never get a chance to use, but it is nice to know there is a glimmer of hope.

What is functional programming?

“Functional programming is a programming paradigm that treats computation as the evaluation of mathematical functions and avoids state and mutable data.”

Excerpt From: Nilanjan Raychaudhuri. “Scala in Action.”.

  • functions not objects, classes or procedures are the basic building blocks
  • higher order functions can accept another function as an argument and/or return a function.
  • pure functions only rely on their input to compute a result and have no memory or IO related side effects. Calling a pure function over and over again with the same arguments will produce the same result.
  • immutability once a value is assigned it cannot be reassigned, and to change the state of an object you have to create a new instance of it.

The above are a brief explanation of the fundamentals behind functional programming. Meaning, if not supported by a language it is not a functional programming language. Below, as a teaser for future articles, is a list of often supported features.

  • tail call optimisation
  • pattern matching
  • closures
  • list comprehensions
  • type inference
  • monads

Why do you need all that?

  • immutability is important for several reasons. First of all it ensures trust. Once created you know your object won’t change and you can safely let others use it. More importantly, an immutable object is thread-safe. Since its state cannot change it can be accessed by multiple threads without risk of dead locks or race conditions.
  • pure functions are easily testable as they are guaranteed to produce the same result when called with the same arguments. Trust, is again a factor as you know calling a pure function won’t have any side effects. They also promote separation of concerns, meaning a pure function only has one meaning. This makes them shorter, easier to understand and ideal building blocks.
  • higher order functions reduces the amount of boiler plate code a programmer has to write. A Java developer is guaranteed to notice the difference. The end result is more readable code which favours intent over step by step instructions. Steve Yegge’s Execution in the Kingdom of Nouns, is an insightful and funny article on the topic.

A Practical Demonstration

Let’s see how higher order functions reduces boiler plate code when creating a JButton with an ActionListener.

JButton pressMe = new JButton(“Press Me”); pressMe.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
System.out.println(“You pressed me!”);
}
});

If addActionListener was a higher order function which would accept another function as a parameter we could have in Scala written:

val pressMe = new JButton(“Press Me”)
pressMe.addActionListener(
(e:ActionEvent) => println(“You pressed me!”))

This could be reduced even further as Scala’s type-inference is clever enough to figure out the type for you.

(e) => println(“You pressed me!”)

The last example demonstrates how Scala is inherently less verbose than Java and how intent is favoured over needlessly detailing every step. Imagine a very simple e-commerce system with only two classes: Orders and Items. For the purpose of displaying the total cost of an order we can call totalCost.

First in Java:

public class Item { 
private int cost;
public Item(int cost) {
this.cost = cost;
}
public int getCost() {
return cost;
}
}
public class Order {
private List<Item> items;
public Order(List<Item> items) {
this.items = items;
}
public List<Item> getItems() {
return items;
}
public int totalCost() {
int totalCost = 0;
for (Item item : getItems()) {
totalCost += item.getCost();
}
return totalCost;
}
}

Then in Scala:

class Item(val cost: Int)
class Order(val items: List[Item]) {
def totalCost(): Int = items.map(e => e.cost).sum
}

What’s important here is instead of a for loop we use the map function, which applies the function supplied to each element in the list of items. The result is a list of costs, which is then added together by the sum function.

Stay tuned for more examples as I progress with Scala and functional programming.

--

--

Erik Lundqvist
Binary Dreams

35, Swedish, book reviewer, avid reader of fantasy/Sci-Fi/Crime, Software Developer