### Transforming your thinking from OOP to FOP with Java 8 examples

One needs to get used to the transformation from imperative programming to functional programming. You like it or not, you will be using functional programming in Java, and interviewers are going to quiz you on functional programming. Fortunately, Java is not a fully functional programming language, and hence one does not require the full leap to functional programming. Java 8 supports both imperative and functional programming approaches.

**Q**. What are the differences between OOP and FOP?

**A**.

In OOP, x = x+ 5 makes sense, but in mathematics or functional programming, you can't say x = x + 5 because if x were to be 2, you can't say that 2 = 2 + 5. In functional programming you need to say f(x) -> x + 5.

**Q**. What are the characteristics of functional programming you need to be familiar with?

**A**.

- A focus on what is to be computed rather then how to compute it.
- Function Closure Support
- Higher-order functions
- Use of recursion as a mechanism for flow control
- Referential transparency
- No side-effects

Let's look at these one by one:

**1. A focus on what is to be computed rather then how to compute it****This was discussed with the following example in the post entitled -- When to use Java 8 functional programming, and where does it shine?**

Integer[] numbers = {1,2,3,4,5,6}; //focusses on what to do as opposed to how to do it //no fluff like for loops, mutations, etc Arrays.asList(numbers) .stream() .filter((e) -> (e % 2 != 0)) .map((e) -> (e * 2)) .forEach(System.out::println);

**2. Function closure support**

In order to create closures, you need a language where the function type is a 1st class citizen, where a function can be assigned to a variable, and then passed around like any other variables like a string, int or boolean. closure is basically a snapshot of the stack at the point that the lambda function is created. Then when the function is re-executed or called back the stack is restored to that state before executing the function.

The

**java.util.function**package provides a number of functional interfaces like Consumer<T>, Function<T, U>, etc to define closures or you can define your own functional interfaces.

package com.java8.examples; import java.util.function.Function; public class ClosureTest { public static void main(String[] args) { //closure 1 that adds 5 to a given number Function<Integer, Integer> plus5 = (i) -> (i+5); //closure 2 that times by 2 a given number Function<Integer, Integer> times2 = (i) -> (i*2); //closure 3 that adds 5 and then multiply the result by 2 Function<Integer, Integer> plus5AndThenTimes2 = plus5.andThen(times2); //closure 4 that times by 2 and then adds 5 Function<Integer, Integer> times2AndThenplus5 = times2.andThen(plus5); //callback or execute closure //functions plus5, times2, etc can be passed as arguments System.out.println("9+5=" + execute(plus5, 9)); System.out.println("9*2=" + execute(times2, 9)); System.out.println("(9+5)*2=" + execute(plus5AndThenTimes2, 9)); System.out.println("9*2+5=" + execute(times2AndThenplus5, 9)); } //functions can be used as method parameters private static Integer execute(Function<Integer, Integer> function, Integer number){ return function.apply(number); //execute the function } }

**Output**:

9+5=14

9*2=18

(9+5)*2=28

9*2+5=23

In pre Java 8, you can use a

**nonymous inner classes**to define closures. In Java 8, lambda operators like (i) -> (i+5) are used to denote anonymous functions.

**Is currying possible in Java 8?**

Currying (named after Haskell Curry) is the fact of evaluating function arguments one by one, producing a new function with one argument less on each step.

Java 8 still does not have first class functions, but currying is “practically” possible with verbose type signatures, which is less than ideal. Here is a very simple example:

package com.java8.examples; import java.util.function.Function; public class CurryTest { public static void main(String[] args) { Function<Integer,Function<Integer,Integer>> add = (a) -> (b) -> a + b; Function<Integer,Integer> addOne = add.apply(1); Function<Integer,Integer> addFive = add.apply(5); Function<Integer,Integer> addTen = add.apply(10); Integer result1 = addOne.apply(2); // returns 3 Integer result2 = addFive.apply(2); // returns 7 Integer result3 = addTen.apply(2); // returns 12 System.out.println("result1 = " + result1); System.out.println("result2 = " + result2); System.out.println("result3 = " + result3); } }

The

**output**is

result1 = 3

result2 = 7

result3 = 12

**3. Higher order functions**

In mathematics and computer science, a

**higher-order function**(aka functional form) is a function that does at least one of the following:

- takes one or more functions as an input -- for example g(f(x)), where f and g are functions, and function g composes the function f.
**outputs a function**-- for example, in the code aboveand*plus5**plus2*outputs a function

Function<Integer, Integer> plus5 = (i) -> (i+5); //closure 2 that times by 2 a given number Function<Integer, Integer> times2 = (i) -> (i*2);

also

Function<integer integer> plus5AndThenTimes2 = plus5.andThen(times2);

outputs another function, where the

**plus5**function takes

**plus2**function as an input.

**4. Use of recursion as a mechanism for flow control**

Java is a stack based language that supports

**reentrant (**a method can call itself)

**methods. This means recursion is possible in Java. Using recursion you don't need a mutable state, hence the problems can be solved in a much simpler fashion compared to using an iterative approach with a loop.**

package com.java8.examples; import java.util.function.Function; public class RecursionTest { static Function<Integer, Integer> factorial = x -> { return ( x == 0) ? 1 : x * factorial.apply(x-1); }; public static void main(String[] args) { int result = factorial.apply(3); System.out.println("factorial of 3 = " + result); } }

Recursion is used in the Lambda expression to calculate the factorial.

**5. Referential Transparency**

Referential transparency is a term commonly used in

**functional programming**, which means that given a function and an input value, you will always receive the same output. There is no external state used in the function. In other words, a referentially transparent function is one which only depends on its input. The

**and**

*plus5***functions shown above are referentially transparent.**

*times2*A function that reads from a text file and prints the output is not referentially transparent. The external text file could change at any time so the function would be referentially

**opaque**

**6. No side-effects**

One way to do programming without side effects is to use only immutable classes. In real world, you try to minimize the mutations, but can't eliminate them. Lambdas can refer to local variables that are not declared final but are never modified. This is known as "

**effectively final**".
When you are using methods like

**reduce**on a stream, you need to be aware of the side effects due to parallelism. For example, the following code will have no side effects when run in serial mode.public static void main(String[] args) { Integer[] numbers = {10, 6}; Integer result = Arrays.asList(numbers).stream() .reduce(20, (a,b) -> (a - b)); System.out.println(result); }

**Outputs**:

4

It starts with 20, and then subtracts 10 and 6.

**20 - 10 - 6 = 4**; But if you run it again in parallel mode as shown below

public static void main(String[] args) { Integer[] numbers = {10, 6}; Integer result = Arrays.asList(numbers).parallelStream() .reduce(20, (a,b) -> (a - b)); System.out.println(result); }

The

**output**will be:

-4

**What happened here?**10 - (20 - 6) = -4;

This means the

**reduce**method on a stream produce side effects when run in parallel for

**non-associative**operations.

**Q**. What is an associative property?

**A**. Associative operations are operations where the order in which the operations were performed does not matter. For example.

**Associative**:

3 + (2 + 1) = (3+ 2) + 1

3 * (2 * 1) = (3 * 2) * 1

**Non-associative**:

3 - (2 - 1) != (3 - 2) - 1

(4/2)/2 != 4/(2/2)

Pure functions are functions with no side effects. In computers,

**idempotence**means that applying an operation once or applying it multiple times has the same effect. For example

**Idempotent operations**

- Multiplying a number by zero. No matter how many times you do it, the result is still zero.
- Setting a boolean flag. No matter how many times you do it, the flag stays set.
- Deleting a row from a database with a given ID. If you try it again, the row is still gone.
- Removing an element from a collection.

In real life where you have concurrent operations going on, you may find that operations you thought were idempotent cease to be so. For example, another thread could unset the value of the boolean flag.

Labels: functional programming, Java 8

## 0 Comments:

## Post a Comment

Subscribe to Post Comments [Atom]

<< Home