Blog

Looking back at Java – After a few years of Scala

29 Nov, 2018
Xebia Background Header Wave

It has been a while for me, after switching from a full time Java developer, to Scala. At the time I was a full blown Java developer. I wrote JavaEE applications but also JavaSE applications. I was keen at writing Java Swing desktop applications but also created Eclipse Rich Client applications. I liked Spring, Apache Camel, Apache Cocoon, Apache ServiceMix, Eclipse Equinox, and tried all of the frameworks. Then microservices happened and we had to integrate, all–of–the–time. First we tried Enterprise Service Buses like Glassfish ESB, then we moved the logic to the applications with Apache Camel. Then we moved the whole application and integrations to an enterprise integration platform like apache ServiceMix, to integrate everything – which was terrible by the way. Then I just gave up….
Well, not exactly, I moved to Scala and Akka and rewrote a whole Apache ServiceMix solution while learning Scala, Akka, Reactive Programming, Spray, and all of the libraries that make creating microservices with Scala so great! And now I’m back, after all those years, taking a look at my old friend, Java.

Java Beans

After creating my first small application with Java 8, I must admit something. I never really missed Java. It is still as verbose as I remember, although it was that long ago, I thought I imagined all of it. But no, it is almost 2019, and we still have to write get-ters and set-ters. Let me show you what I mean, but I’ll leave out all the cruft code that the IDE generates anyway so you get an idea what the code is all about. Its about a person, that has an address.

class Person {
    private String name;
    private int age;
    private Address address;

    // removing cruft 
}

class Address {
    String street;
    int houseNumber;

    // removing cruft 
}

public class JavaExample {
    public static void main(String[] args) {
        Person dennis = new Person("Dennis", 42, new Address("Somewhere", 42));
        System.out.println("Details of " + dennis);
    }    
}

Functional

I’ve heard Java, the old dog, has learned some new tricks, like streams and functions, lets see what it can do! Lets try to curry a function that adds two values with the add function. It takes some syntax but it is possible. We then try to compose some of these curried functions an then apply it with a value and what do you know. Java supports function composition!

import java.util.function.Function;

public class JavaExample {
    static Function<Integer, Integer> add(Integer x) {
        return y -> y + x;
    }
    public static void main(String[] args) {
        // functional
        Function<Integer, Integer> f = add(1);
        Function<Integer, Integer> g = add(2);
        Function<Integer, Integer> h = add(3);
        Function<Integer, Integer> i = f.andThen(g).andThen(h);
        System.out.println("Applying composed functions: " + i.apply(3));
    }
}

Lets try creating a two lists, that contain x'es and y'sthat contain 3 values each. After some tinkering, it is possible. Lets iterate over the xs and that works! Lets try to sum the ys collection and also after some tinkering I can sum a list of integers. Nice!

import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class JavaExample {
    static Function<Integer, Integer> add(Integer x) {
        return y -> y + x;
    }

    static List<Integer> xs = Stream.of(1, 2, 3).collect(Collectors.toList());
    static List<Integer> ys = Arrays.asList(4, 5, 6);

    public static void main(String[] args) {
        // functional
        Function<Integer, Integer> f = add(1);
        Function<Integer, Integer> g = add(2);
        Function<Integer, Integer> h = add(3);
        Function<Integer, Integer> i = f.andThen(g).andThen(h);
        System.out.println("Applying composed functions: " + i.apply(3));

        System.out.println("Iterating xs:");
        xs.forEach(System.out::println);

        System.out.println("Summing ys:");
        System.out.println(ys.stream().mapToInt(x -> x).sum());
    }
}

Scala

If Java is my old friend, then Scala is my first love. I’m spending all my time with Scala. Get to know its ins and outs and try out all the things. Sometimes we argue and get into a fight about why it did not derive my typeclasses correctly. We still fight over Scalaz vs Cats, I like cats, I have 5! Sometimes I think things are very clear, but Scala needs some more (type) information from me. Most of the time I don’t have a clue what its trying to say, because I’m not listening. Sometimes I leave Scala for a while and try something new, but I always come back to my first love, Scala. Lets see why.
Believe it or not, all of the Java code we saw earlier fits on the 25 odd lines below. Isn’t it pretty!
We define two records a Person that has an Address. We then define two lists, containing x'es and y's. We register a function that returns a function and compose functions. Finally we apply the function, iterate and sum the list.
Now with some macros I can do this with a single line! I’m kidding!

package binxio

case class Person(name: String, 
                  age: Int, 
                  address: Address)
case class Address(street: String, 
                   housenr: Int)

object ScalaExample {
  val xs = List(1, 2, 3)
  val ys = List(4, 5, 6)

  val add = (x: Int) => (_: Int) + x

  def main(args: Array[String]): Unit = {
    // functional
    val f = add(1)(_)
    val g = add(2)(_)
    val h = add(3)(_)
    val i = f.compose(g).compose(h)
    println(s"Applying composed functions: ${i(3)}")
    println("Iterating xs:")
    xs.foreach(println)
    println("Summing ys:")
    println(ys.sum)

    // object oriented
    val dennis = Person("Dennis", 42, Address("Somewhere", 42))
    println(s"Details of $dennis")
  }
}

Conclusion

In this blog we’ve seen that Java is evolving. It is difficult to innovate when the release cycles were so few and far apart but all of that is changing. The difficulty for Java is that there are far more expressive languages available on the JVM and it is hard to compete in that space. I really like Groovy, Kotlin, and of course Scala as alternatives that are syntactically like Java, but add features that make developing applications so more fun, safe and productive.
Bye my old friend, until next time!

Questions?

Get in touch with us to learn more about the subject and related solutions

Explore related posts