Yakhya DABO
Software craftsman && DevOps Engineer
@yakhyadabo
(Birmingham, United Kingdom)
Work & Interests
Continuous Delivery
Work and Interests
Software craftsmanship
Work and Interests
Don't just code Monkey (M. Fowler)
→ Knowledge
→ Responsibility
→ Impact
Work and Interests
Devoxx France
Paris Jug
Socrates Germany
London Software craftsmanship
Communities
Work and Interests
Functional Programming in Java 8
Avoid technical debt
Java 7 is no longer supported
Java 9 coming soon
A programming paradigm that ...
● Treats function as primitive
● Avoids state and mutable data
● Is declarative
Definition of Functional Programming
To be a function
function succ(int y){
return y++;
}
Definition
int x = 1;
function dummy(int y){
x++;
return x+y;
}
Not to be a function
Definition
int x = 1;
function dummy(int y){
x++;
return x+y;
}
Not to be a function
Definition
Functions as First-Class Citizens
- High-Order Functions
- Lambda
- Top-Level Functions
Immutable data
(Hadi Hariri Devoxx France 2015)
Functional Language
Write less and expressive code
Why do we need it ?
The Context
“Software product is embedded in a cultural matrix of
applications, users, laws, and machines vehicles.
These all change continually, and their changes inexorably
force change upon the software product.”
Frederic brooks
The context
Every 18 months a CPU's transistors will
shrink in size by a factor of two.
Moor Law
The context
- In 2002, limitations in a CPU's circuitry.
- The multi-core processor was born.
Moor Law (New Context)
The context
Lambda project
“Reduce the gap between the serial and parallel
versions of the same computation”
Brian Goetz (Lambda project leader)
The context
public List<Output> processInputs(List<Input> inputs)
throws InterruptedException, ExecutionException {
int threads = Runtime.getRuntime().availableProcessors();
ExecutorService service = Executors.newFixedThreadPool(threads);
List<Future<Output>> futures = new ArrayList<Future<Output>>();
for (final Input input : inputs) {
Callable<Output> callable = new Callable<Output>() {
public Output call() throws Exception {
Output output = new Output();
// process your input here and compute the output
return output;
}
};
futures.add(service.submit(callable));
}
service.shutdown();
List<Output> outputs = new ArrayList<Output>();
for (Future<Output> future : futures) {
outputs.add(future.get());
}
return outputs;
}
Pallelizing with OOP
The context
Output out = input.process(treatment);
Output out = Input.processInParallel(treatment);
Pallelizing with FP
The context
=> Lambda expression
=> Functional Interface
=> Optional API
=> Stream API
….
Java 8 main new features
Lambda expressions
(argument_list) -> function_body
Lambda expression
x -> x + 1 ;
(int x, int y) -> x + y ;
() -> System.out.println("I am a lambda");
Lambda expressions
Lambda expressions
X= (int x) -> x + 1 ;
(int x, int y) -> {
z = x + y ;
z++;
}
Lambda expression
Lambda expressions
Functional Interface
Provide target types for lambda expressions ...
Has a single abstract method, ..., to which the
lambda expression's parameter and return types are
matched or adapted.
Functional Interface
int x -> x * 2;
public interface IntOperation {
int operate(int i);
}
Functional Interface
- Function
- Consumer
- Supplier
Functional Interface
Common Functional Interfaces
Functions accept one argument and produce a result.
@FunctionalInterface
Interface Function<T,R>{
R apply(T t);
}
Functional Interface
Function
// String to an integer
Function<String, Integer> stringToInt = x -> Integer.valueOf(x);
int toto = stringToInt(“10”);
Functional Interface
Function
Suppliers produce a result of a given generic type.
Unlike Functions, Suppliers don't accept arguments.
@FunctionalInterface
Interface Supplier<T>{
T get()
}
Functional Interface
Supplier
Supplier<Person> personSupplier = () -> new Person();
Person persion = personSupplier.get();
Functional Interface
Supplier
Consumers represents operations to be performed on a single
input argument.
@FunctionalInterface
public interface Consumer<T>{
void accept(T t)
}
Functional Interface
Consumer
Consumer<Person> personPrinter =
(p) -> System.out.println("Hello, " + p.firstName);
personPrinter.accept(new Person("Luke", "Skywalker"));
Functional Interface
Consumer
Predicates are boolean-valued functions of one
argument.
@FunctionalInterface
Interface Predicate<T>{
boolean test(T t)
}
Functional Interface
Predicate
Predicate<String> isNotEmpty = s -> s.isEmpty();
Predicate<String> isNotEmpty = isEmpty.negate();
Functional Interface
Predicate
Type Inference
What is the type of [x -> 2 * x] ?
public interface IntOperation {
int operate(int i);
}
public interface DoubleOperation {
double operate(double i);
}
Type Inference
Type Inference
Java does have type inferencing when using generics.
public <T> T foo(T t) {
return t;
}
Type Inference
Type Inference
● DoubleOperation doubleOp = x -> x * 2;
● IntOperation intOp = x -> x * 2;
Inference by declaration
Type Inference
● DoubleOperation doubleOp ;
doubleOp = x -> x * 2;
● IntOperation intOp ;
intOp = x -> x * 2;
Inference by affectation
Type InferenceType Inference
public Runnable toDoLater() {
return () -> System.out.println("later");
}
Inference by return type
Type Inference
Object runnable = (Runnable) () ->
{ System.out.println("Hello"); };
Object callable = (Callable) () →
{ System.out.println("Hello"); };
Inference by cast
Type Inference
Stream API
Collections support operations that work on a
single element :
add(), remove() and contains()
Stream API
Streams have bulk operations that access all
elements in a sequence.
forEach(), filter(), map(), and reduce()
Stream API
Three central concepts of functional
programming
Map/Filter/Reduce
Stream API
map(f, [d0, d1, d2...]) -> [f(d0), f(d1), f(d2)...]
Map
Stream API
Legacy
List<String> names = …
List<Person> people = ...
for (Person person : people){
names.add(person.getName());
}
Map
Stream API
List<Person> people = ...
List<String> names = people.streams()
.map(person -> person.getName())
.collect(Collectors.toList());
Functional Style
Map
Stream API
filter(is_even, [1, 2, 7, -4, 3, 12.0001]) -> [2, -4]
Filter
Stream API
List<Person> people = …
List<Person> peopleOver50 = ...
for (Person person : people){
if(person.getAge() >= 50){
peopleOver50.add(person.getName());
}
}
Legacy
Filter
Stream API
List<Person> people = …
List<String> peopleOver50 = people.streams()
.filter(person -> person.getAge()>50)
.collect(Collectors.toList());
Functional Style
Filter
Stream API
reduce(add, [1, 2, 4, 8]) -> 15
Reduce
Stream API
List<Integer> salaries = …
int averageSalaries = ...
for (Integer salary : salaries){
…
}
Legacy
Stream API
Reduce
List<Integer> salaries = …
Int averageAge = salaries.streams()
.average();
Functional Style
Stream API
Reduce
int sum = shapes.stream()
.filter(s -> s.getColor() == BLUE)
.mapToInt(s -> s.getWeight())
.sum();
Stream API
Pipeline Structure
Optional API
Forgetting to check for null references is a
common source of bugs in application code. One
way to eliminate NullPointerExceptions is to
make sure that methods always return a non null
value.
Example
User user = userRepository.getUser(“id”);
If (user != null){
user.doSomeThing();
}
Optional API
With Optional
Optional<User> user = userRepository.getUser(“id”);
If (user.isPresent()){
user.doSomeThing();
}
Optional API
Optional API
Functional style
Optional<User> user = userRepository.getUser(“id”);
user.ifPresent(u - > u.doSomeThing());
Optional API
Functional style
Optional<User> user = userRepository.getUser(“id”);
user.ifPresent(u - > u.doSomeThing());
userRepository.getUser(“id”)
.ifPresent(user - > user.doSomeThing());
Optional<SomeObject> opt = Optional.empty();
Optional<SomeObject> opt = Optional.of(notNull);
Optional<SomeObject> opt = Optional.ofNullable(mayBeNull);
Declaration
Optional API
Common Optional patterns
Optional API
if (x != null && x.contains("ab")) {
print(x);
}
Optional API
If (condition) doSomething
if (x != null && x.contains("ab")) {
print(x);
}
Optional API
If (condition) doSomething
opt
.filter(x -> x.contains("ab"))
.ifPresent(x -> print(x));
Optional API
If (condition) return else return
if (x !=null){
return x.length();
} else {
return -1;
}
Optional API
If (condition) return else return
opt
.map(x -> x.length() )
.orElse(-1);
if (x !=null){
return x.length();
} else {
return -1;
}
if (s != null && !s.isEmpty()){
return s.charAt(0);
else
throw new IllegalArgumentException();
}
Optional API
Throwing Exception
if (s != null && !s.isEmpty()){
return s.charAt(0);
else
throw new IllegalArgumentException();
}
Optional API
Throwing Exception
opt
.filter(s -> ! s.isEmpty()).
.map(s -> s.charAt(0)).
.orElseThrow(IllegalArgumentException::new);
if (x !=null){
print(x.length());
} else {
Print(“-1”);
}
Optional API
If (condition) do else … do
if (x !=null){
print(x.length());
} else {
Print(“-1”);
}
Optional API
If (condition) do else … do
???
Avoid having states
Avoid using for, while
Think twice before using if
Summary
Curryfication, partial functions
Dependency injection
Monad ...
Next step ...
Function<Integer,Function<Integer,Integer>> sum =
x -> y -> x + y;
Function<Integer, Integer> plus10 = sum.apply(10);
Integer res = plus10.apply(5);
… Next step
Curryfication
...
… Next step
Monad
...
… Next step
Dependency injection
...
… Next step
Future of GoF
Futher readings
Devoxx
France 2015 : Hadi Hariri (Refactoring to functional)
UK 2014 : Raoul Gabriel Urma && Richard Warburton Pragmatic
Functional Refactoring with Java 8
Books
● Functional programming for Java developers
● Java SE8 for the Really Impatient
● Java 8 in action

SeneJug java_8_prez_122015

  • 1.
    Yakhya DABO Software craftsman&& DevOps Engineer @yakhyadabo (Birmingham, United Kingdom)
  • 2.
  • 3.
  • 4.
  • 5.
    Don't just codeMonkey (M. Fowler) → Knowledge → Responsibility → Impact Work and Interests
  • 6.
    Devoxx France Paris Jug SocratesGermany London Software craftsmanship Communities Work and Interests
  • 7.
  • 8.
    Avoid technical debt Java7 is no longer supported Java 9 coming soon
  • 9.
    A programming paradigmthat ... ● Treats function as primitive ● Avoids state and mutable data ● Is declarative Definition of Functional Programming
  • 10.
    To be afunction function succ(int y){ return y++; } Definition
  • 11.
    int x =1; function dummy(int y){ x++; return x+y; } Not to be a function Definition
  • 12.
    int x =1; function dummy(int y){ x++; return x+y; } Not to be a function Definition
  • 13.
    Functions as First-ClassCitizens - High-Order Functions - Lambda - Top-Level Functions Immutable data (Hadi Hariri Devoxx France 2015) Functional Language
  • 14.
    Write less andexpressive code Why do we need it ?
  • 15.
  • 16.
    “Software product isembedded in a cultural matrix of applications, users, laws, and machines vehicles. These all change continually, and their changes inexorably force change upon the software product.” Frederic brooks The context
  • 17.
    Every 18 monthsa CPU's transistors will shrink in size by a factor of two. Moor Law The context
  • 18.
    - In 2002,limitations in a CPU's circuitry. - The multi-core processor was born. Moor Law (New Context) The context
  • 19.
  • 20.
    “Reduce the gapbetween the serial and parallel versions of the same computation” Brian Goetz (Lambda project leader) The context
  • 21.
    public List<Output> processInputs(List<Input>inputs) throws InterruptedException, ExecutionException { int threads = Runtime.getRuntime().availableProcessors(); ExecutorService service = Executors.newFixedThreadPool(threads); List<Future<Output>> futures = new ArrayList<Future<Output>>(); for (final Input input : inputs) { Callable<Output> callable = new Callable<Output>() { public Output call() throws Exception { Output output = new Output(); // process your input here and compute the output return output; } }; futures.add(service.submit(callable)); } service.shutdown(); List<Output> outputs = new ArrayList<Output>(); for (Future<Output> future : futures) { outputs.add(future.get()); } return outputs; } Pallelizing with OOP The context
  • 22.
    Output out =input.process(treatment); Output out = Input.processInParallel(treatment); Pallelizing with FP The context
  • 23.
    => Lambda expression =>Functional Interface => Optional API => Stream API …. Java 8 main new features
  • 24.
  • 25.
  • 26.
    x -> x+ 1 ; (int x, int y) -> x + y ; () -> System.out.println("I am a lambda"); Lambda expressions Lambda expressions
  • 27.
    X= (int x)-> x + 1 ; (int x, int y) -> { z = x + y ; z++; } Lambda expression Lambda expressions
  • 28.
  • 29.
    Provide target typesfor lambda expressions ... Has a single abstract method, ..., to which the lambda expression's parameter and return types are matched or adapted. Functional Interface
  • 30.
    int x ->x * 2; public interface IntOperation { int operate(int i); } Functional Interface
  • 31.
    - Function - Consumer -Supplier Functional Interface Common Functional Interfaces
  • 32.
    Functions accept oneargument and produce a result. @FunctionalInterface Interface Function<T,R>{ R apply(T t); } Functional Interface Function
  • 33.
    // String toan integer Function<String, Integer> stringToInt = x -> Integer.valueOf(x); int toto = stringToInt(“10”); Functional Interface Function
  • 34.
    Suppliers produce aresult of a given generic type. Unlike Functions, Suppliers don't accept arguments. @FunctionalInterface Interface Supplier<T>{ T get() } Functional Interface Supplier
  • 35.
    Supplier<Person> personSupplier =() -> new Person(); Person persion = personSupplier.get(); Functional Interface Supplier
  • 36.
    Consumers represents operationsto be performed on a single input argument. @FunctionalInterface public interface Consumer<T>{ void accept(T t) } Functional Interface Consumer
  • 37.
    Consumer<Person> personPrinter = (p)-> System.out.println("Hello, " + p.firstName); personPrinter.accept(new Person("Luke", "Skywalker")); Functional Interface Consumer
  • 38.
    Predicates are boolean-valuedfunctions of one argument. @FunctionalInterface Interface Predicate<T>{ boolean test(T t) } Functional Interface Predicate
  • 39.
    Predicate<String> isNotEmpty =s -> s.isEmpty(); Predicate<String> isNotEmpty = isEmpty.negate(); Functional Interface Predicate
  • 40.
  • 41.
    What is thetype of [x -> 2 * x] ? public interface IntOperation { int operate(int i); } public interface DoubleOperation { double operate(double i); } Type Inference Type Inference
  • 42.
    Java does havetype inferencing when using generics. public <T> T foo(T t) { return t; } Type Inference Type Inference
  • 43.
    ● DoubleOperation doubleOp= x -> x * 2; ● IntOperation intOp = x -> x * 2; Inference by declaration Type Inference
  • 44.
    ● DoubleOperation doubleOp; doubleOp = x -> x * 2; ● IntOperation intOp ; intOp = x -> x * 2; Inference by affectation Type InferenceType Inference
  • 45.
    public Runnable toDoLater(){ return () -> System.out.println("later"); } Inference by return type Type Inference
  • 46.
    Object runnable =(Runnable) () -> { System.out.println("Hello"); }; Object callable = (Callable) () → { System.out.println("Hello"); }; Inference by cast Type Inference
  • 47.
  • 48.
    Collections support operationsthat work on a single element : add(), remove() and contains() Stream API
  • 49.
    Streams have bulkoperations that access all elements in a sequence. forEach(), filter(), map(), and reduce() Stream API
  • 50.
    Three central conceptsof functional programming Map/Filter/Reduce Stream API
  • 51.
    map(f, [d0, d1,d2...]) -> [f(d0), f(d1), f(d2)...] Map Stream API
  • 52.
    Legacy List<String> names =… List<Person> people = ... for (Person person : people){ names.add(person.getName()); } Map Stream API
  • 53.
    List<Person> people =... List<String> names = people.streams() .map(person -> person.getName()) .collect(Collectors.toList()); Functional Style Map Stream API
  • 54.
    filter(is_even, [1, 2,7, -4, 3, 12.0001]) -> [2, -4] Filter Stream API
  • 55.
    List<Person> people =… List<Person> peopleOver50 = ... for (Person person : people){ if(person.getAge() >= 50){ peopleOver50.add(person.getName()); } } Legacy Filter Stream API
  • 56.
    List<Person> people =… List<String> peopleOver50 = people.streams() .filter(person -> person.getAge()>50) .collect(Collectors.toList()); Functional Style Filter Stream API
  • 57.
    reduce(add, [1, 2,4, 8]) -> 15 Reduce Stream API
  • 58.
    List<Integer> salaries =… int averageSalaries = ... for (Integer salary : salaries){ … } Legacy Stream API Reduce
  • 59.
    List<Integer> salaries =… Int averageAge = salaries.streams() .average(); Functional Style Stream API Reduce
  • 60.
    int sum =shapes.stream() .filter(s -> s.getColor() == BLUE) .mapToInt(s -> s.getWeight()) .sum(); Stream API Pipeline Structure
  • 61.
    Optional API Forgetting tocheck for null references is a common source of bugs in application code. One way to eliminate NullPointerExceptions is to make sure that methods always return a non null value.
  • 62.
    Example User user =userRepository.getUser(“id”); If (user != null){ user.doSomeThing(); } Optional API
  • 63.
    With Optional Optional<User> user= userRepository.getUser(“id”); If (user.isPresent()){ user.doSomeThing(); } Optional API
  • 64.
    Optional API Functional style Optional<User>user = userRepository.getUser(“id”); user.ifPresent(u - > u.doSomeThing());
  • 65.
    Optional API Functional style Optional<User>user = userRepository.getUser(“id”); user.ifPresent(u - > u.doSomeThing()); userRepository.getUser(“id”) .ifPresent(user - > user.doSomeThing());
  • 66.
    Optional<SomeObject> opt =Optional.empty(); Optional<SomeObject> opt = Optional.of(notNull); Optional<SomeObject> opt = Optional.ofNullable(mayBeNull); Declaration Optional API
  • 67.
  • 68.
    if (x !=null && x.contains("ab")) { print(x); } Optional API If (condition) doSomething
  • 69.
    if (x !=null && x.contains("ab")) { print(x); } Optional API If (condition) doSomething opt .filter(x -> x.contains("ab")) .ifPresent(x -> print(x));
  • 70.
    Optional API If (condition)return else return if (x !=null){ return x.length(); } else { return -1; }
  • 71.
    Optional API If (condition)return else return opt .map(x -> x.length() ) .orElse(-1); if (x !=null){ return x.length(); } else { return -1; }
  • 72.
    if (s !=null && !s.isEmpty()){ return s.charAt(0); else throw new IllegalArgumentException(); } Optional API Throwing Exception
  • 73.
    if (s !=null && !s.isEmpty()){ return s.charAt(0); else throw new IllegalArgumentException(); } Optional API Throwing Exception opt .filter(s -> ! s.isEmpty()). .map(s -> s.charAt(0)). .orElseThrow(IllegalArgumentException::new);
  • 74.
    if (x !=null){ print(x.length()); }else { Print(“-1”); } Optional API If (condition) do else … do
  • 75.
    if (x !=null){ print(x.length()); }else { Print(“-1”); } Optional API If (condition) do else … do ???
  • 76.
    Avoid having states Avoidusing for, while Think twice before using if Summary
  • 77.
    Curryfication, partial functions Dependencyinjection Monad ... Next step ...
  • 78.
    Function<Integer,Function<Integer,Integer>> sum = x-> y -> x + y; Function<Integer, Integer> plus10 = sum.apply(10); Integer res = plus10.apply(5); … Next step Curryfication
  • 79.
  • 80.
  • 81.
  • 82.
    Futher readings Devoxx France 2015: Hadi Hariri (Refactoring to functional) UK 2014 : Raoul Gabriel Urma && Richard Warburton Pragmatic Functional Refactoring with Java 8 Books ● Functional programming for Java developers ● Java SE8 for the Really Impatient ● Java 8 in action