Referential Transparency in Java Programming

Reading Time: 4 minutes

what is functional programming ?

It is a declarative style of programming rather than imperative. The basic objective of this programming is to make code more concise, less complex, more predictable, and easy to test.

Functional programming deals with certain key concepts such as pure function immutable, state, assignment-less programming etc.

Imperative Vs Declarative Programming

In the imperative style of coding, we define what to do a task and how to do it. Whereas, in the declarative style of coding, we only specify what to do. Let’s understand this with an example.

// Java program to find the sum
// using imperative style of coding
import java.util.Arrays;
import java.util.List;
public class ImperativeMainTest {
	public static void main(String[] args)
	{
		List<Integer> numbers
			= Arrays.asList(11, 22, 33, 44,
							55, 66, 77, 88,
							99, 100);

		int result = 0;
		for (Integer n : numbers) {
			if (n % 2 == 0) {
				result += n * 2;
			}
		}
		System.out.println(result);
	}
}


// Java program to find the sum
// using declarative style of coding
import java.util.Arrays;
import java.util.List;
public class DeclarativeMainTest {
	public static void main(String[] args)
	{
		List<Integer> numbers
			= Arrays.asList(11, 22, 33, 44,
							55, 66, 77, 88,
							99, 100);

		System.out.println(
			numbers.stream()
				.filter(number -> number % 2 == 0)
				.mapToInt(e -> e * 2)
				.sum());
	}
}

Functional programming contains the following key concepts:

  • Functions as first class objects
  • Pure functions
  • Higher order functions

Functions as First Class Objects

In the functional programming , functions are first class objects in the language. This means the language supports passing functions as arguments to other functions, returning them as the values from other functions, and assigning them to variables or storing them in data structures. In Java, methods are not first class objects. The closest we get is Java Lambda Expressions.

Higher Order Functions

A function is a higher order function if at least one of the following conditions are met:

  • The function takes one or more functions as parameters.
  • The function returns another function as result.

In Java, the closest we can get to a higher order function is a function (method) that takes one or more lambda expressions as parameters, and returns another lambda expression. Here is an example of a higher order function in Java:

public class HigherOrderFunctionClass {

    public <T> IFactory<T> createFactory(IProducer<T> producer, IConfigurator<T> configurator) {
        return () -> {
           T instance = producer.produce();
           configurator.configure(instance);
           return instance;
        }
    }
}

Notice that the createFactory() method returns a lambda expression as result. This is the first condition of a higher order function.

Notice also that the createFactory() method takes two instances as parameters which are both implementations of interfaces (Iproducer and IConfigurator).

Imagine the interfaces looks like this:

public interface IFactory<T> {
   T create();
}
public interface IProducer<T> {
   T produce();
}
public interface IConfigurator<T> {
   void configure(T t);
}


As you can see, all of these interfaces are functional interfaces. Therefore they can be implemented by Java lambda expressions – and therefore the createFactory() method is a higher order function.

How to Implement Functional Programming in Java?

// Java 8 program to demonstrate
// a lambda expression
import java.util.Arrays;
import java.util.List;
public class FPMainTest {
	public static void main(String[] args)
	{
		Runnable r
			= ()
			-> System.out.println(
				"Running in Runnable thread");

		r.run();

		System.out.println(
			"Running in main thread");
	}
}

What is pure function ?

A function is a pure function if:

  • The execution of the function has no side effects.
  • The return value of the function depends only on the input parameters passed to the function.

Here is an example of a pure function (method) in Java:

public class ObjectWithPureFunction{

    public int sum(int a, int b) {
        return a + b;
    }
}

here is an example of a non-pure function:

public class ObjectWithNonPureFunction{
    private int value = 0;

    public int add(int nextValue) {
        this.value += nextValue;
        return this.value;
    }
}

Notice that the method add() uses a member variable to calculate its return value, and it also modifies the state of the value member variable, so it has a side effect.

Pure functional programming has a set of rules to follow too:

  • No state
  • No side effects
  • Immutable variables
  • Favour recursion over looping

What is referential transparency ?

A function is called referential transparent if it always return the same result value when called with the same argument value.

For referential transparency, we need our function to be pure and immutable.

Example : The method `String.replace()` is referential transparent because if `shaurav.replace(`s`,`S`)` will always produce the same result because the `replace` method return the new object rather than updaing the original object.

A pure function is referentially transparent expression and a pure function should return value based on the arguments passed and should not affect or depend on global state.

Ex : Below is the example of pure function

public static int sum(int a, int b){
  return a + b;
}

So, this function is referentially transparent as well.

Referential transparency make each subprogram independent which is very helpful at time of implementing unit testing and refactoring. Also, referential transparency program are easier to read and understand which is also one reason why referential transparency need in function programming.


Knoldus-blog-footer-image

Written by 

I am a java developer having 6 years of experience. I have worked on Core Java, Spring, Spring boot, Kafka, Spark, MySQL. I am curious about learning new technologies.

Leave a Reply