How Scala influenced my Java Programming

For a while I have been experimenting in my free time with Scala.

While I don’t believe that I will use Scala at work in the near future I have nevertheless noticed that
Scala has changed the way I think in Java.

Immutables

Since Josh Bloch’s fantastic book Effective Java I have used more and more immutable classes in Java

Scala has really driven home this lesson.

Immutables are great for several reasons:

  • guaranteed thread-safe
  • stable hashCode(), so they never get lost in a Set or Map
  • real encapsulation of the data they contain

Since I am a lazy programmer they really come in handy because once they are written I can forget about them.
They will just work.

In Java you have to be a bit careful to make sure that the class is really immutable.
Here the main points:

  • All fields are final
  • The class is final (or all constructors are private)
  • Constructor must copy arguments that are not immutable (e.g. arrays, collections, maps) before assigning them to fields
  • Never give out references to mutable fields (again arrays, collections, maps)
  • make sure that serialization does not break the immutability (for perfectionists)

For good immutable collections I recommend Google Guava.

Tuples

Scala tuples are very handy in a couple of places.

  • methods that need to return multiple values
  • storing composite values in a collection or map
  • grouping several values in an API, but not important enough to make them a separate class (danger: slippery slope!)

In Java it was easy to implement tuples in a type-safe manner.
It is not possible to completely hide the details in the same way that Scala does, but with static imports we can get pretty close.

We will need a few classes for tuples with 2, 3 or more elements.

// Java example implementing a tuple (with 2 elements)
public final class Tuple2<T1, T2> implements Serializable {

	private static final long serialVersionUID = 0L;

	private final T1 value1;
	private final T2 value2;

	public Tuple2(T1 value1, T2 value2) {
		this.value1 = value1;
		this.value2 = value2;
	}

	public T1 getValue1() {
		return value1;
	}

	public T2 getValue2() {
		return value2;
	}

	@Override
	public int hashCode() {
		int hash = 7;
		hash = 31 * hash + (value1 == null ? 23 : value1.hashCode());
		hash = 31 * hash + (value2 == null ? 23 : value2.hashCode());
		return hash;
	}

	@Override
	public boolean equals(Object object) {
		if (object == this) {
			return true;
		}
		if (!(object instanceof Tuple2)) {
			return false;
		}

		Tuple2<?, ?> other = (Tuple2<?, ?>) object;
		return (value1 == null ? other.value1 == null : value1.equals(other.value1)) &&
			(value2 == null ? other.value2 == null : value2.equals(other.value2));
	}

	@Override
	public String toString() {
		return "(" + value1 + "," + value2 + ")";
	}
}
// Java example constructor methods to create tuples
public class Tuples {
	public static <T1, T2> Tuple2<T1, T2> tuple(T1 value1, T2 value2) {
		return new Tuple2<T1, T2>(value1, value2);
	}
	public static <T1, T2, T3> Tuple3<T1, T2, T3> tuple(T1 value1, T2 value2, T3 value3) {
		return new Tuple3<T1, T2, T3>(value1, value2, value3);
	}
}
// Java example using tuples
import static com.example.tuple.Tuples.tuples;
import com.example.tuple.Tuple2;

public class TupleExample {
	public static Tuple2<String, Integer> doSomething() {
		return tuple("Hello", 999);
	}

	public static void main(String[] arguments) {
		Tuple2<String, Integer> t = doSomething();
		System.out.println(t);
	}
}

Please notice that tuples are immutable (if the contained values are immutable).

Internal DSLs

In Scala it is easy to write what some people call internal DSLs.

In Java you are somewhat limited, but fluent APIs are a thrust in the same direction.
Together with builder pattern und static imports you can get rid of a lot of boilerplate code.

A nice example is the new API to specify grid data layout in SWT:

	// Java Fluent API Example (GridDataFactory for SWT)
	GridDataFactory.fillDefaults().grab(true, true).hint(150, 150).applyTo(listBox);

Here is another code snippet to show how static imports can give you a DSL.

// Java static methods for Expression classes
// Expression classes not shown
public class Expressions {
	public static AndExpression and(Expression... expressions) {
		return new AndExpression(expressions);
	}
	public static OrExpression or(Expression... expressions) {
		return new OrExpression(expressions);
	}
	public static NotExpression not(Expression expression) {
		return new NotExpression(expressions);
	}
	public static EqualExpression equal(Expression left, Expression right) {
		return new EqualExpression(left, right);
	}
	public static EqualExpression equal(String variableName, Expression right) {
		return new EqualExpression(var(variableName), right);
	}
	public static EqualExpression equal(String variableName, int value) {
		return new EqualExpression(var(variableName), val(value));
	}
	public static EqualExpression equal(String variableName, int value) {
		return new EqualExpression(left, right);
	}
	public static IntegerValue value(int value) {
		return new IntegerValue(value);
	}
	public static VariableValue var(String variableName) {
		return new VariableValue(variableName);
	}
}
	// Java static imports
	import static com.example.Expressions.*;

	private static Expression ex1 = and(equal(var("x"), value(5)), not(equal(var("y"), value(6))));
	private static Expression ex2 = equal(var("x"), value(5));
	private static Expression ex3 = equal("x", value(5));
	private static Expression ex4 = equal("x", 5);

Until closures in Java 8 have arrived we will still need to write anonymous subclasses in Java if we want to
specify executable code. This severely limits the possibilities for nice DSLs in Java.

Funnily coding in Scala has trained my eyes to (somewhat) ignore the clutter from anonymous subclasses and only look at the relevant code.

	// Scala example to convert a list of integer values into a list of strings
	List(111, 222, 333) map("X" + _)
	// Java example to convert a list of integer values into a list of strings
	// static methods in Converters and interface Converter not shown
	List<Integer> integerList = Arrays.asList(111, 222, 333);
	List<String> stringList = Converters.convert(integerList, new Converter<Integer, String>() {
		@Override
		public String convert(Integer source) {
			return "X" + source;
		}
	}));

If you squint your eyes really hard it looks almost the same, doesn’t it?

In Java 8 this will look (probably) something like this:

	// Java example to convert a list of integer values into a list of strings (using closure)
	// static methods in Converters and interface Converter not shown
	List<Integer> integerList = Arrays.asList(111, 222, 333);
	List<String> stringList = Converters.convert(integerList, (v => "X" + v));

Functional programming

If you have written Java (or another imperative langague) for a long time you probably have some difficulty adjusting to the functional way of doing things.
I certainly do.

But you don’t have to become a tail-recursion fanatic to gain something valuable from the functional programming approach.

Especially if your code must be thread-safe it is very useful to remember one detail about functions:

If your method only looks at its arguments to calculate a return value it is absolutely thread-safe!

This sounds obvious but it is surprising how often people forget this.

Here the check-list whether your method is a pure function:

  • no access to any fields
  • no calls to other methods (except if they are pure functions)
  • arguments must be immutable or not shared between threads

Pure functions are the executable equivalent of immutable data structures.
Easy to write and easy to reason about.

This entry was posted in Development, Java, Scala and tagged , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *