Slide 1

Slide 1 text

Functional Programming in Java Deepu K Sasidharan @deepu105 | deepu.tech

Slide 2

Slide 2 text

About me Deepu K Sasidharan JHipster co-lead developer Developer Advocate @ Adyen OSS aficionado, author, speaker, polyglot dev @deepu105 deepu.tech deepu105

Slide 3

Slide 3 text

Rules of FP

Slide 4

Slide 4 text

Golden rules of FP 1. No Data mutations: A data object should not be changed after it is created. 2. No implicit state: Hidden/Implicit state should be avoided. In functional programming state is not eliminated, instead, it’s made visible and explicit

Slide 5

Slide 5 text

Roughly translates to 1. No side effects: An operation should not change any state outside of its functional scope. I.e, A function should only return a value to the invoker and should not affect any external state. 2. Pure functions only: Functional code is idempotent. A function should return values only based on the arguments passed and should not affect(side-effect) or depend on global state. Such functions always produce the same result for the same arguments.

Slide 6

Slide 6 text

Functional language vs Functional style language

Slide 7

Slide 7 text

What makes a language suitable for FP ● Strong type system ● Functional data structures ● Pure functions ● Higher-order-functions ● Closures ● Currying ● Recursion ● Lazy evaluations ● Referential transparency

Slide 8

Slide 8 text

Java can be a Functional style language We are talking about the latest version of course!

Slide 9

Slide 9 text

FP support in JAVA ● Strong type system 😍 ● Functional data structures ● Pure functions ● Higher-order-functions ● Closures ● Currying ● Recursion ● Lazy evaluations ● Referential transparency

Slide 10

Slide 10 text

Type system Java has a strong type system with generics and local type inference with var keyword and with in lambda arguments var myList = new ArrayList(); var out = mapForEach(list, it -> it.length());

Slide 11

Slide 11 text

FP support in JAVA ● Strong type system 😍 ● Functional data structures 😍 ● Pure functions ● Higher-order-functions ● Closures ● Currying ● Recursion ● Lazy evaluations ● Referential transparency

Slide 12

Slide 12 text

FP support in JAVA ● Strong type system 😍 ● Functional data structures 😍 ● Pure functions 😌 ● Higher-order-functions ● Closures ● Currying ● Recursion ● Lazy evaluations ● Referential transparency

Slide 13

Slide 13 text

FP support in JAVA ● Strong type system 😍 ● Functional data structures 😍 ● Pure functions 😌 ● Higher-order-functions 😐 ● Closures ● Currying ● Recursion ● Lazy evaluations ● Referential transparency

Slide 14

Slide 14 text

Higher-order-function with lambda Objects are first class citizens in Java and we can pass objects initialized inline as well public class LambdaTest { public static void main(String[] args) { var thread = new Thread(new Runnable() { @Override public void run() { System.out.println("Hello from thread"); } }); thread.run(); System.out.println("Hello from main"); } }

Slide 15

Slide 15 text

Higher-order-function with lambda Objects are first class citizens in Java and we can pass objects initialized inline as well public class LambdaTest { public static void main(String[] args) { var thread = new Thread(new Runnable() { @Override public void run() -> { System.out.println("Hello from thread"); } }); thread.run(); System.out.println("Hello from main"); } }

Slide 16

Slide 16 text

Higher-order-function with lambda Objects are first class citizens in Java and we can pass objects initialized inline as well public class LambdaTest { public static void main(String[] args) { var thread = new Thread(() -> { System.out.println("Hello from thread"); }); thread.run(); System.out.println("Hello from main"); } }

Slide 17

Slide 17 text

Higher-order-function with lambda How can we do this for our own stuff? @FunctionalInterface // this doesn't do anything it is just informative. public interface FnFactory { // The interface defines the contract for the anonymous class S execute(T it); }

Slide 18

Slide 18 text

Higher-order-function with lambda How can we do this for our own stuff? // The method takes an array and an instance of FnFactory as arguments static ArrayList mapForEach(List arr, FnFactory fn) { var newArray = new ArrayList(); // We are executing the method from the FnFactory instance arr.forEach(t -> newArray.add( fn.execute(t))); return newArray; }

Slide 19

Slide 19 text

Higher-order-function with lambda How can we do this for our own stuff? var out = mapForEach(list, new FnFactory() { @Override public Object execute(final String it) { return it.length(); } }); System.out.println(out); OR var out = mapForEach(list, it -> it.length()); System.out.println(out);

Slide 20

Slide 20 text

Higher-order-function with lambda Built in functional interfaces under java.util.function ● UnaryOperator - single arg and return of same types ● BinaryOperator - two args and return of same types ● Function - single arg and return of different types ● Consumer - single arg and no return ● Predicate - single arg and boolean return ● Supplier - no args just a return

Slide 21

Slide 21 text

Higher-order-function with lambda Simplify to use built in interface static ArrayList mapForEach(List arr, Function fn) { var newArray = new ArrayList(); // We are executing the method from the Function instance arr.forEach(t -> newArray.add(fn.apply(t))); return newArray; } var out = mapForEach(list, it -> it.length()); System.out.println(out);

Slide 22

Slide 22 text

Higher-order-function with lambda Built in higher order functions, chainable pipelines and monad like stuff ● java.util.Collections ○ Sort, binarySearch, min, max ● Java.util.stream (mostly pure functions) ○ map, reduce, filter, find, forEach, flatMap and so on ● Optional ○ ifPresent, orElse, filter, map and so on ● Anything that accepts anonymous classes

Slide 23

Slide 23 text

FP support in JAVA ● Strong type system 😍 ● Functional data structures 😍 ● Pure functions 😌 ● Higher-order-functions 😌 ● Closures 😐 ● Currying ● Recursion ● Lazy evaluations ● Referential transparency

Slide 24

Slide 24 text

Closures with lambda Lambda closures can memorize its outer context // this is a higher-order-function that returns // an instance of Function interface Function add(final int x) { // this is a closure, i.e, a variable holding // an anonymous inner class instance of the Function interface // which uses variables from the outer scope return new Function() { @Override public Integer apply(Integer y) { // variable x is obtained from the outer // scope of this method which is declared as final return x + y; } }; } OR Function add(final int x) { return y -> x + y; }

Slide 25

Slide 25 text

FP support in JAVA ● Strong type system 😍 ● Functional data structures 😍 ● Pure functions 😌 ● Higher-order-functions 😌 ● Closures 😌 ● Currying 😐 ● Recursion ● Lazy evaluations ● Referential transparency

Slide 26

Slide 26 text

Closures with lambda Lambda closures can be used to create curried/partial functions ClosureSample sample = new ClosureSample(); // we are currying the add method to create more variations Function add10 = sample.add(10); Function add20 = sample.add(20); Function add30 = sample.add(30); System.out.println(add10.apply(5)); // 15 System.out.println(add20.apply(5)); // 25 System.out.println(add30.apply(5)); // 35

Slide 27

Slide 27 text

FP support in JAVA ● Strong type system 😍 ● Functional data structures 😍 ● Pure functions 😌 ● Higher-order-functions 😌 ● Closures 😌 ● Currying 😌 ● Recursion 😐 ● Lazy evaluations ● Referential transparency

Slide 28

Slide 28 text

Recursion Factorial with imperative Iterative approach public class FactorialSample { // benchmark 9.645 ns/op static long factorial(long num) { long result = 1; for (; num > 0; num--) { result *= num; } return result; } public static void main(String[] args) { System.out.println(factorial(20)); // 2432902008176640000 } }

Slide 29

Slide 29 text

Recursion Factorial with recursive approach public class FactorialSample { // benchmark 19.567 ns/op static long factorialRec(long num) { return num == 1 ? 1 : num * factorialRec(num - 1); } public static void main(String[] args) { System.out.println(factorialRec(20)); // 2432902008176640000 } }

Slide 30

Slide 30 text

Recursion Factorial with tail recursive approach public class FactorialSample { // benchmark 16.701 ns/op static long factorialTailRec(long num) { return factorial(1, num); } static long factorial(long accumulator, long val) { return val == 1 ? accumulator : factorial(accumulator * val, val - 1); } public static void main(String[] args) { System.out.println(factorialTailRec(20)); // 2432902008176640000 } }

Slide 31

Slide 31 text

Recursion Factorial with streams public class FactorialSample { // benchmark 59.565 ns/op static long factorialStream(long num) { return LongStream.rangeClosed(1, num) .reduce(1, (n1, n2) -> n1 * n2); } public static void main(String[] args) { System.out.println(factorialStream(20)); // 2432902008176640000 } }

Slide 32

Slide 32 text

FP support in JAVA ● Strong type system 😍 ● Functional data structures 😍 ● Pure functions 😌 ● Higher-order-functions 😌 ● Closures 😌 ● Currying 😌 ● Recursion 😐 ● Lazy evaluations 😐 ● Referential transparency

Slide 33

Slide 33 text

Lazy evaluations public static void main(String[] args) { // This is a lambda expression behaving as a closure UnaryOperator add = t -> { System.out.println("executing add"); return t + t; }; // This is a lambda expression behaving as a closure UnaryOperator multiply = t -> { System.out.println("executing multiply"); return t * t; }; // Lambda closures are passed instead of plain functions System.out.println(addOrMultiply(true, add, multiply, 4)); System.out.println(addOrMultiply(false, add, multiply, 4)); } // This is a higher-order-function static R addOrMultiply( boolean add, Function onAdd, Function onMultiply, T t ) { // Java evaluates expressions on ?: // lazily hence only the required method is executed return (add ? onAdd.apply(t) : onMultiply.apply(t)); }

Slide 34

Slide 34 text

FP support in JAVA ● Strong type system 😍 ● Functional data structures 😍 ● Pure functions 😌 ● Higher-order-functions 😌 ● Closures 😌 ● Currying 😌 ● Recursion 😐 ● Lazy evaluations 😐 ● Referential transparency 😓

Slide 35

Slide 35 text

Java can be a Functional style language If you are patient and disciplined

Slide 36

Slide 36 text

Thank You https://deepu.tech/tags#functional Deepu K Sasidharan @deepu105 | deepu.tech