SlideShare a Scribd company logo
Pragmatic Functional
Refactoring with Java 8
Raoul-Gabriel Urma (@raoulUK)
Richard Warburton (@RichardWarburto)
Pragmatic functional refactoring with java 8 (1)
Pragmatic functional refactoring with java 8 (1)
First-class Functions
Currying
Immutability
Optional Data Types
Conclusions
Step 1: filtering invoices from Oracle
public List<Invoice> findInvoicesFromOracle(List<Invoice> invoices) {
List<Invoice> result = new ArrayList<>();
for(Invoice invoice: invoices) {
if(invoice.getCustomer() == Customer.ORACLE) {
result.add(invoice);
}
}
return result;
}
Step 2a: abstracting the customer
public List<Invoice> findInvoicesFromCustomer(List<Invoice> invoices,
Customer customer) {
List<Invoice> result = new ArrayList<>();
for(Invoice invoice: invoices) {
if(invoice.getCustomer() == customer) {
result.add(invoice);
}
}
return result;
}
Step 2b: abstracting the name
public List<Invoice> findInvoicesEndingWith(List<Invoice> invoices,
String suffix) {
List<Invoice> result = new ArrayList<>();
for(Invoice invoice: invoices) {
if(invoice.getName().endsWith(suffix)) {
result.add(invoice);
}
}
return result;
}
Step 3: messy code-reuse!
private List<Invoice> findInvoices(List<Invoice> invoices,
Customer customer,
String suffix,
boolean flag) {
List<Invoice> result = new ArrayList<>();
for(Invoice invoice: invoices) {
if((flag && invoice.getCustomer() == customer)
|| (!flag && invoice.getName().endsWith(suffix))) {
result.add(invoice);
}
}
return result;
}
Step 4a: modeling the filtering criterion
public interface Predicate<T> {
boolean test(T t);
}
Invoice boolean
Predicate<Invoice>
Step 4b: using different criterion with objects
private List<Invoice> findInvoices(List<Invoice> invoices,
Predicate<Invoice> p) {
List<Invoice> result = new ArrayList<>();
for(Invoice invoice: invoices) {
if(p.test(invoice)) {
result.add(invoice);
}
}
return result;
}
Step 4b: using different criterion with objects
List<Invoice> specificInvoices =
findInvoices(invoices, new FacebookTraining());
class FacebookTraining implements Predicate<Invoice> {
@Override
public boolean test(Invoice invoice) {
return invoice.getCustomer() == Customer.FACEBOOK
&& invoice.getName().endsWith("Training");
}
}
Step 5: method references
public boolean isOracleInvoice(Invoice invoice) {
return invoice.getCustomer() == Customer.ORACLE;
}
public boolean isTrainingInvoice(Invoice invoice) {
return invoice.getName().endsWith("Training");
}
List<Invoice> oracleInvoices =
findInvoices(invoices, this::isOracleInvoice);
List<Invoice> trainingInvoices =
findInvoices(invoices, this::isTrainingInvoice);
method references
Step 6: lambdas
List<Invoice> oracleInvoices =
findInvoices(invoices,
invoice -> invoice.getCustomer() == Customer.ORACLE);
List<Invoice> trainingInvoices =
findInvoices(invoices,
invoice -> invoice.getName().endsWith("Training"));
First-class functions
● Common Object Oriented concept: Function Object
● All it means is the ability to use a function just like a regular value
○ Pass it as argument to a method
○ Store it in a variable
● Helps cope with requirement changes
Composing functions
Functions Composing functions
Composing functions: example
import java.util.function.Predicate;
Predicate<Invoice> isFacebookInvoice = this::isFacebookInvoice;
List<Invoice> facebookAndTraining =
invoices.stream()
.filter( isFacebookInvoice.and(this::isTrainingInvoice))
.collect(toList());
List<Invoice> facebookOrGoogle =
invoices.stream()
.filter( isFacebookInvoice.or(this::isGoogleInvoice))
.collect(toList());
creating more complex
functions from building blocks
Composing functions: why does it work?
public interface Predicate<T> {
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
}
returns a new
function that is
the result of
composing two
functions
Creating function pipelines (1)
public class Email {
private final String message;
public Email(String message) {
this.message = message;
}
public Email addHeader() {
return new Email("Dear Sir/Madam:n" + message);
}
public Email checkSpelling() {
return new Email(message.replaceAll("FTW", "for the win"));
}
public Email addSignature() {
return new Email(message + "nKind regards");
}
}
Creating function pipelines (2)
import java.util.function.Function;
Function<Email, Email> addHeader = Email::addHeader;
Function<Email, Email> processingPipeline =
addHeader.andThen(Email::checkSpelling)
.andThen(Email::addSignature);
addHeader checkSpelling addSignature
andThen andThen
Email
{message="Java
8 FTW!"}
Email{message='Dear
Sir/Madam:
Java 8 for the win!
Kind regards'}
composing
functions
Creating function pipelines (3)
import java.util.function.Function;
Function<Email, Email> addHeader = Email::addHeader;
Function<Email, Email> processingPipeline =
addHeader.andThen(Email::addSignature);
addHeader addSignature
andThen
Email
{message="Java
8 FTW!"}
Email{message='Dear
Sir/Madam:
Java 8 FTW!
Kind regards'}
composing
functions
First-class Functions
Currying
Immutability
Optional Data Types
Conclusions
Example: A Conversion Function
double convert(double amount, double factor, double base)
{
return amount * factor + base;
}
// Usage
double result = convert(10, 1.8, 32);
assertEquals(result, 50, 0.0);
Using the conversion function
// Temperatures
double cInF = convert(10, 1.8, 32);
double higherTemp = convert(30, 1.8, 32);
// Currencies
double dollarsInPounds = convert(10, 0.6, 0);
// Distance
double kilometresInMiles = convert(27, 0.62137, 0);
So what’s the problem?
● Abstraction
○ How do you write something that operates on different conversion
functions?
● Reuse
○ How do you use the conversion function in different places?
Pragmatic functional refactoring with java 8 (1)
Currying the conversion function
double convert(double amount, double factor, double base) {
return amount * factor + base;
}
DoubleUnaryOperator convert(double factor, double base) {
return amount -> amount * factor + base;
}
Using the conversion function
DoubleUnaryOperator convert(double factor, double base) {
return amount -> amount * factor + base;
}
DoubleUnaryOperator convertCtoF = convert(1.8, 32);
double result = convertCtoF.applyAsDouble(10);
assertEquals(result, 50, 0.0);
Pragmatic functional refactoring with java 8 (1)
Partial Application Examples
// Temperatures
DoubleUnaryOperator convertCtoF = convert(1.8, 32);
// Currencies
DoubleUnaryOperator convert$to£ = convert(0.6, 0);
// Distance
DoubleUnaryOperator convertKmToMi = convert(0.62137, 0);
Definition
// int -> (int -> int)
IntFunction<IntUnaryOperator>
curry(IntBinaryOperator biFunction) {
return f -> (s -> biFunction.applyAsInt(f, s));
}
Usage
IntFunction<IntUnaryOperator> add
= curry((f, s) -> f + s);
int result = add.apply(1)
.applyAsInt(2);
assertEquals(3, result);
Example currying use cases
● Large factory methods
○ Partially apply some of the arguments and then pass this factory
object around.
● Combinators libraries
○ Parsers
○ HTML templating
Summary
● Currying is about splitting up the arguments of a function.
● Partial Application is a function “eating” some of its arguments and
returning a new function
First-class Functions
Currying
Immutability
Optional Data Types
Conclusions
Mutable objects
public class TrainJourney {
private int price;
private TrainJourney onward;
public TrainJourney(int price, TrainJourney onward) {
this.price = price;
this.onward = onward;
}
public int getPrice() {
return price;
}
public TrainJourney getOnward() {
return onward;
}
public void setPrice(int price) {
this.price = price;
}
public void setOnward(TrainJourney onward) {
this.onward = onward;
}
}
Immutable objects
public final class TrainJourneyImmutable {
private final int price;
private final TrainJourneyImmutable onward;
public TrainJourneyImmutable(int price, TrainJourney onward) {
this.price = price;
this.onward = onward;
}
public int getPrice() {
return price;
}
public TrainJourneyImmutable getOnward() {
return onward;
}
public TrainJourneyImmutable withPrice(int price) {
return new TrainJourneyImmutable(price, getOnward());
}
public TrainJourneyImmutable withOnward(TrainJourneyImmutable onward) {
return new TrainJourneyImmutable(getPrice(), onward);
}
}
Scenario: be able to link together train
journeys to form longer journeys.
Pragmatic functional refactoring with java 8 (1)
Mutable approach
public TrainJourney link(TrainJourney start, TrainJourney continuation) {
if (start == null) {
return continuation;
}
TrainJourney t = start;
while (t.getOnward() != null) {
t = t.getOnward();
}
t.setOnward(continuation);
return start;
}
find the last stop in the first journey
modify it to link to the continuation
journey
return the continuation journey if
there is no start journey
Mutable approach: problem
TrainJourney firstJourney = link(start, continuation);
TrainJourney secondJourney = link(start, continuation);
visit(secondJourney,
tj -> { System.out.print(tj.price + " - "); });
static void visit(TrainJourney journey, Consumer<TrainJourney> c)
{
if (journey != null) {
c.accept(journey);
visit(journey.onward, c);
}
}
java.lang.StackOverflowError
Pragmatic functional refactoring with java 8 (1)
Immutable approach
public TrainJourneyImmutable link(TrainJourneyImmutable start,
TrainJourneyImmutable continuation) {
return start == null ? continuation
: new TrainJourneyImmutable(start.getPrice(),
link(start.getOnward(), continuation));
}
Related topics
● Domain Driven Design
○ Value Classes are Immutable
● Core Java Improvements
○ New date & time library in Java 8 has many Immutable Objects
○ Current Value Types proposal is immutable
● Tooling
○ final keyword only bans reassignment
○ JSR 308 - improved annotation opportunities
○ Mutability Detector
○ Findbugs
Downsides to Immutability
● Increased memory allocation pressure
● Some problems harder to model with immutability
○ Deep object graphs
○ Example: Car simulation
● Library interactions
○ ORMs especially
○ Serialisation usually ok these days
● Alternative: small blobs of simple and localised state
Immutable objects reduce the scope for bugs.
First-class Functions
Currying
Immutability
Optional Data Types
Conclusions
Don’t we all love it?
Exception in thread "main" java.lang.NullPointerException
public String getCarInsuranceName(Person person) {
return person.getCar().getInsurance().getName();
}
Where’s the NPE?
Defensive checking
public String getCarInsuranceName(Person person) {
if (person != null) {
Car car = person.getCar();
if (car != null) {
Insurance insurance = car.getInsurance();
if (insurance != null) {
return insurance.getName();
}
}
}
return "No Insurance";
}
Optional
● Java 8 introduces a new class java.util.Optional<T>
○ a single-value container
● Explicit modelling
○ Immediately clear that its an optional value
○ better maintainability
● You need to actively unwrap an Optional
○ force users to think about the absence case
○ fewer errors
Updating model
public class Person {
private Optional<Car> car;
public Optional<Car> getCar() { return car; }
}
public class Car {
private Optional<Insurance> insurance;
public Optional<Insurance> getInsurance() { return insurance; }
}
public class Insurance {
private String name;
public String getName() { return name; }
}
Optional.map
Why it doesn’t work?
Optional<People> optPerson = Optional.ofNullable(person);
Optional<String> name =
optPeople.map(Person::getCar)
.map(Car::getInsurance)
.map(Insurance::getName);
returns Optional<Optional<Car>>
Invalid, the inner Optional object
doesn’t support the method
getInsurance!
public class Person {
private Optional<Car> car;
public Optional<Car> getCar() { return car; }
}
Pragmatic functional refactoring with java 8 (1)
Optional.flatMap
Chaining methods with flatMap
public String getCarInsuranceName(Person person) {
return Optional.ofNullable(person)
.flatMap(Person::getCar)
.flatMap(Car::getInsurance)
.map(Insurance::getName)
.orElse("Unknown");
}
default value if the resulting
Optional is empty
A comment on naming
public String getCarInsuranceName(Person person) {
Set<Person> personSet = person == null
? emptySet()
: singleton(person);
return personSet.stream()
.flatMap(Person::getCar)
.flatMap(Car::getInsurance)
.map(Insurance::getName)
.orElse("Unknown");
}
Optional in Fields
● Should it be used for fields, or just public methods?
● Pros
○ Explicit modelling
○ Null-safe access
○ Simple getters
● Cons
○ More indirection and GC overhead in Java 8
○ Not every library understands Optional yet
○ Some libraries require Serializable fields
Consistent use of Optional replaces the use of null
First-class Functions
Currying
Immutability
Optional Data Types
Conclusions
Summary of benefits
● First-class functions let you cope for requirement changes
● Currying lets you split the parameters of a function to re-use code logic
● Immutability reduces the scope for bugs
● Optional data types lets you reduce null checking boilerplate and
prevent bugs
Pragmatic functional refactoring with java 8 (1)
http://java8training.com
http://manning.com/urma http://tinyurl.com/java8lambdas
Any Questions?
Richard Warburton
@richardwarburto
Raoul-Gabriel Urma
@raoulUK
Generalised curry function
// F -> (S -> R)
<F, S, R> Function<F, Function<S, R>>
curry(BiFunction<F, S, R> biFunction) {
return f -> s -> biFunction.apply(f, s);
}
Ad

More Related Content

What's hot (20)

Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Mario Fusco
 
Scala is java8.next()
Scala is java8.next()Scala is java8.next()
Scala is java8.next()
daewon jeong
 
The underestimated power of KeyPaths
The underestimated power of KeyPathsThe underestimated power of KeyPaths
The underestimated power of KeyPaths
Vincent Pradeilles
 
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Chris Richardson
 
Fp201 unit5 1
Fp201 unit5 1Fp201 unit5 1
Fp201 unit5 1
rohassanie
 
Fp201 unit4
Fp201 unit4Fp201 unit4
Fp201 unit4
rohassanie
 
FP 201 - Unit 6
FP 201 - Unit 6FP 201 - Unit 6
FP 201 - Unit 6
rohassanie
 
Unlocking the Magic of Monads with Java 8
Unlocking the Magic of Monads with Java 8Unlocking the Magic of Monads with Java 8
Unlocking the Magic of Monads with Java 8
JavaDayUA
 
Jumping-with-java8
Jumping-with-java8Jumping-with-java8
Jumping-with-java8
Dhaval Dalal
 
classes & objects in cpp overview
classes & objects in cpp overviewclasses & objects in cpp overview
classes & objects in cpp overview
gourav kottawar
 
Functional Programming
Functional ProgrammingFunctional Programming
Functional Programming
Olexandra Dmytrenko
 
Composing an App with Free Monads (using Cats)
Composing an App with Free Monads (using Cats)Composing an App with Free Monads (using Cats)
Composing an App with Free Monads (using Cats)
Hermann Hueck
 
FP 201 - Unit 3 Part 2
FP 201 - Unit 3 Part 2FP 201 - Unit 3 Part 2
FP 201 - Unit 3 Part 2
rohassanie
 
Java PRACTICAL file
Java PRACTICAL fileJava PRACTICAL file
Java PRACTICAL file
RACHIT_GUPTA
 
6. Generics. Collections. Streams
6. Generics. Collections. Streams6. Generics. Collections. Streams
6. Generics. Collections. Streams
DEVTYPE
 
Generics in .NET, C++ and Java
Generics in .NET, C++ and JavaGenerics in .NET, C++ and Java
Generics in .NET, C++ and Java
Sasha Goldshtein
 
The Ring programming language version 1.4.1 book - Part 9 of 31
The Ring programming language version 1.4.1 book - Part 9 of 31The Ring programming language version 1.4.1 book - Part 9 of 31
The Ring programming language version 1.4.1 book - Part 9 of 31
Mahmoud Samir Fayed
 
The Ring programming language version 1.5.1 book - Part 30 of 180
The Ring programming language version 1.5.1 book - Part 30 of 180The Ring programming language version 1.5.1 book - Part 30 of 180
The Ring programming language version 1.5.1 book - Part 30 of 180
Mahmoud Samir Fayed
 
Intro to Functional Programming
Intro to Functional ProgrammingIntro to Functional Programming
Intro to Functional Programming
Hugo Firth
 
Class method
Class methodClass method
Class method
kamal kotecha
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Mario Fusco
 
Scala is java8.next()
Scala is java8.next()Scala is java8.next()
Scala is java8.next()
daewon jeong
 
The underestimated power of KeyPaths
The underestimated power of KeyPathsThe underestimated power of KeyPaths
The underestimated power of KeyPaths
Vincent Pradeilles
 
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Chris Richardson
 
FP 201 - Unit 6
FP 201 - Unit 6FP 201 - Unit 6
FP 201 - Unit 6
rohassanie
 
Unlocking the Magic of Monads with Java 8
Unlocking the Magic of Monads with Java 8Unlocking the Magic of Monads with Java 8
Unlocking the Magic of Monads with Java 8
JavaDayUA
 
Jumping-with-java8
Jumping-with-java8Jumping-with-java8
Jumping-with-java8
Dhaval Dalal
 
classes & objects in cpp overview
classes & objects in cpp overviewclasses & objects in cpp overview
classes & objects in cpp overview
gourav kottawar
 
Composing an App with Free Monads (using Cats)
Composing an App with Free Monads (using Cats)Composing an App with Free Monads (using Cats)
Composing an App with Free Monads (using Cats)
Hermann Hueck
 
FP 201 - Unit 3 Part 2
FP 201 - Unit 3 Part 2FP 201 - Unit 3 Part 2
FP 201 - Unit 3 Part 2
rohassanie
 
Java PRACTICAL file
Java PRACTICAL fileJava PRACTICAL file
Java PRACTICAL file
RACHIT_GUPTA
 
6. Generics. Collections. Streams
6. Generics. Collections. Streams6. Generics. Collections. Streams
6. Generics. Collections. Streams
DEVTYPE
 
Generics in .NET, C++ and Java
Generics in .NET, C++ and JavaGenerics in .NET, C++ and Java
Generics in .NET, C++ and Java
Sasha Goldshtein
 
The Ring programming language version 1.4.1 book - Part 9 of 31
The Ring programming language version 1.4.1 book - Part 9 of 31The Ring programming language version 1.4.1 book - Part 9 of 31
The Ring programming language version 1.4.1 book - Part 9 of 31
Mahmoud Samir Fayed
 
The Ring programming language version 1.5.1 book - Part 30 of 180
The Ring programming language version 1.5.1 book - Part 30 of 180The Ring programming language version 1.5.1 book - Part 30 of 180
The Ring programming language version 1.5.1 book - Part 30 of 180
Mahmoud Samir Fayed
 
Intro to Functional Programming
Intro to Functional ProgrammingIntro to Functional Programming
Intro to Functional Programming
Hugo Firth
 

Viewers also liked (7)

How to run a hackday
How to run a hackdayHow to run a hackday
How to run a hackday
RichardWarburton
 
Performance and predictability
Performance and predictabilityPerformance and predictability
Performance and predictability
RichardWarburton
 
Java collections the force awakens
Java collections  the force awakensJava collections  the force awakens
Java collections the force awakens
RichardWarburton
 
Generics Past, Present and Future
Generics Past, Present and FutureGenerics Past, Present and Future
Generics Past, Present and Future
RichardWarburton
 
Twins: Object Oriented Programming and Functional Programming
Twins: Object Oriented Programming and Functional ProgrammingTwins: Object Oriented Programming and Functional Programming
Twins: Object Oriented Programming and Functional Programming
RichardWarburton
 
Jvm profiling under the hood
Jvm profiling under the hoodJvm profiling under the hood
Jvm profiling under the hood
RichardWarburton
 
Performance and predictability (1)
Performance and predictability (1)Performance and predictability (1)
Performance and predictability (1)
RichardWarburton
 
Performance and predictability
Performance and predictabilityPerformance and predictability
Performance and predictability
RichardWarburton
 
Java collections the force awakens
Java collections  the force awakensJava collections  the force awakens
Java collections the force awakens
RichardWarburton
 
Generics Past, Present and Future
Generics Past, Present and FutureGenerics Past, Present and Future
Generics Past, Present and Future
RichardWarburton
 
Twins: Object Oriented Programming and Functional Programming
Twins: Object Oriented Programming and Functional ProgrammingTwins: Object Oriented Programming and Functional Programming
Twins: Object Oriented Programming and Functional Programming
RichardWarburton
 
Jvm profiling under the hood
Jvm profiling under the hoodJvm profiling under the hood
Jvm profiling under the hood
RichardWarburton
 
Performance and predictability (1)
Performance and predictability (1)Performance and predictability (1)
Performance and predictability (1)
RichardWarburton
 
Ad

Similar to Pragmatic functional refactoring with java 8 (1) (20)

From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
Codemotion
 
Working effectively with legacy code
Working effectively with legacy codeWorking effectively with legacy code
Working effectively with legacy code
ShriKant Vashishtha
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Codemotion
 
Programming Fundamentals lecture-10.pptx
Programming Fundamentals lecture-10.pptxProgramming Fundamentals lecture-10.pptx
Programming Fundamentals lecture-10.pptx
singyali199
 
Design patterns in the 21st Century
Design patterns in the 21st CenturyDesign patterns in the 21st Century
Design patterns in the 21st Century
Samir Talwar
 
Operator overloading
Operator overloadingOperator overloading
Operator overloading
Pranali Chaudhari
 
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
Ali Parmaksiz
 
Recompacting your react application
Recompacting your react applicationRecompacting your react application
Recompacting your react application
Greg Bergé
 
react-hooks.pdf
react-hooks.pdfreact-hooks.pdf
react-hooks.pdf
chengbo xu
 
This is a C# project . I am expected to create as this image shows. .pdf
This is a C# project . I am expected to create as this image shows. .pdfThis is a C# project . I am expected to create as this image shows. .pdf
This is a C# project . I am expected to create as this image shows. .pdf
indiaartz
 
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!JS Fest 2019. Glenn Reyes. With great power comes great React hooks!
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!
JSFestUA
 
Being Functional on Reactive Streams with Spring Reactor
Being Functional on Reactive Streams with Spring ReactorBeing Functional on Reactive Streams with Spring Reactor
Being Functional on Reactive Streams with Spring Reactor
Max Huang
 
React JS Hooks Sheet .pdf
React JS Hooks Sheet .pdfReact JS Hooks Sheet .pdf
React JS Hooks Sheet .pdf
nishant078cs23
 
Gwt and Xtend
Gwt and XtendGwt and Xtend
Gwt and Xtend
Sven Efftinge
 
How to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescriptHow to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescript
Katy Slemon
 
Powering code reuse with context and render props
Powering code reuse with context and render propsPowering code reuse with context and render props
Powering code reuse with context and render props
Forbes Lindesay
 
Finagle and Java Service Framework at Pinterest
Finagle and Java Service Framework at PinterestFinagle and Java Service Framework at Pinterest
Finagle and Java Service Framework at Pinterest
Pavan Chitumalla
 
Design Patterns in the 21st Century - Samir Talwar
Design Patterns in the 21st Century - Samir TalwarDesign Patterns in the 21st Century - Samir Talwar
Design Patterns in the 21st Century - Samir Talwar
JAXLondon2014
 
Is your C# optimized
Is your C# optimizedIs your C# optimized
Is your C# optimized
Woody Pewitt
 
Refactoring
RefactoringRefactoring
Refactoring
Tausun Akhtary
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
Codemotion
 
Working effectively with legacy code
Working effectively with legacy codeWorking effectively with legacy code
Working effectively with legacy code
ShriKant Vashishtha
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Codemotion
 
Programming Fundamentals lecture-10.pptx
Programming Fundamentals lecture-10.pptxProgramming Fundamentals lecture-10.pptx
Programming Fundamentals lecture-10.pptx
singyali199
 
Design patterns in the 21st Century
Design patterns in the 21st CenturyDesign patterns in the 21st Century
Design patterns in the 21st Century
Samir Talwar
 
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
Ali Parmaksiz
 
Recompacting your react application
Recompacting your react applicationRecompacting your react application
Recompacting your react application
Greg Bergé
 
react-hooks.pdf
react-hooks.pdfreact-hooks.pdf
react-hooks.pdf
chengbo xu
 
This is a C# project . I am expected to create as this image shows. .pdf
This is a C# project . I am expected to create as this image shows. .pdfThis is a C# project . I am expected to create as this image shows. .pdf
This is a C# project . I am expected to create as this image shows. .pdf
indiaartz
 
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!JS Fest 2019. Glenn Reyes. With great power comes great React hooks!
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!
JSFestUA
 
Being Functional on Reactive Streams with Spring Reactor
Being Functional on Reactive Streams with Spring ReactorBeing Functional on Reactive Streams with Spring Reactor
Being Functional on Reactive Streams with Spring Reactor
Max Huang
 
React JS Hooks Sheet .pdf
React JS Hooks Sheet .pdfReact JS Hooks Sheet .pdf
React JS Hooks Sheet .pdf
nishant078cs23
 
How to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescriptHow to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescript
Katy Slemon
 
Powering code reuse with context and render props
Powering code reuse with context and render propsPowering code reuse with context and render props
Powering code reuse with context and render props
Forbes Lindesay
 
Finagle and Java Service Framework at Pinterest
Finagle and Java Service Framework at PinterestFinagle and Java Service Framework at Pinterest
Finagle and Java Service Framework at Pinterest
Pavan Chitumalla
 
Design Patterns in the 21st Century - Samir Talwar
Design Patterns in the 21st Century - Samir TalwarDesign Patterns in the 21st Century - Samir Talwar
Design Patterns in the 21st Century - Samir Talwar
JAXLondon2014
 
Is your C# optimized
Is your C# optimizedIs your C# optimized
Is your C# optimized
Woody Pewitt
 
Ad

More from RichardWarburton (20)

Fantastic performance and where to find it
Fantastic performance and where to find itFantastic performance and where to find it
Fantastic performance and where to find it
RichardWarburton
 
Production profiling what, why and how technical audience (3)
Production profiling  what, why and how   technical audience (3)Production profiling  what, why and how   technical audience (3)
Production profiling what, why and how technical audience (3)
RichardWarburton
 
Production profiling: What, Why and How
Production profiling: What, Why and HowProduction profiling: What, Why and How
Production profiling: What, Why and How
RichardWarburton
 
Production profiling what, why and how (JBCN Edition)
Production profiling  what, why and how (JBCN Edition)Production profiling  what, why and how (JBCN Edition)
Production profiling what, why and how (JBCN Edition)
RichardWarburton
 
Production Profiling: What, Why and How
Production Profiling: What, Why and HowProduction Profiling: What, Why and How
Production Profiling: What, Why and How
RichardWarburton
 
Generics Past, Present and Future (Latest)
Generics Past, Present and Future (Latest)Generics Past, Present and Future (Latest)
Generics Past, Present and Future (Latest)
RichardWarburton
 
Collections forceawakens
Collections forceawakensCollections forceawakens
Collections forceawakens
RichardWarburton
 
Generics past, present and future
Generics  past, present and futureGenerics  past, present and future
Generics past, present and future
RichardWarburton
 
Introduction to lambda behave
Introduction to lambda behaveIntroduction to lambda behave
Introduction to lambda behave
RichardWarburton
 
Introduction to lambda behave
Introduction to lambda behaveIntroduction to lambda behave
Introduction to lambda behave
RichardWarburton
 
Performance and predictability
Performance and predictabilityPerformance and predictability
Performance and predictability
RichardWarburton
 
Simplifying java with lambdas (short)
Simplifying java with lambdas (short)Simplifying java with lambdas (short)
Simplifying java with lambdas (short)
RichardWarburton
 
Twins: OOP and FP
Twins: OOP and FPTwins: OOP and FP
Twins: OOP and FP
RichardWarburton
 
Twins: OOP and FP
Twins: OOP and FPTwins: OOP and FP
Twins: OOP and FP
RichardWarburton
 
The Bleeding Edge
The Bleeding EdgeThe Bleeding Edge
The Bleeding Edge
RichardWarburton
 
Lambdas myths-and-mistakes
Lambdas myths-and-mistakesLambdas myths-and-mistakes
Lambdas myths-and-mistakes
RichardWarburton
 
Caching in
Caching inCaching in
Caching in
RichardWarburton
 
Lambdas: Myths and Mistakes
Lambdas: Myths and MistakesLambdas: Myths and Mistakes
Lambdas: Myths and Mistakes
RichardWarburton
 
Better than a coin toss
Better than a coin tossBetter than a coin toss
Better than a coin toss
RichardWarburton
 
Devoxx uk lambdas hackday
Devoxx uk lambdas hackdayDevoxx uk lambdas hackday
Devoxx uk lambdas hackday
RichardWarburton
 
Fantastic performance and where to find it
Fantastic performance and where to find itFantastic performance and where to find it
Fantastic performance and where to find it
RichardWarburton
 
Production profiling what, why and how technical audience (3)
Production profiling  what, why and how   technical audience (3)Production profiling  what, why and how   technical audience (3)
Production profiling what, why and how technical audience (3)
RichardWarburton
 
Production profiling: What, Why and How
Production profiling: What, Why and HowProduction profiling: What, Why and How
Production profiling: What, Why and How
RichardWarburton
 
Production profiling what, why and how (JBCN Edition)
Production profiling  what, why and how (JBCN Edition)Production profiling  what, why and how (JBCN Edition)
Production profiling what, why and how (JBCN Edition)
RichardWarburton
 
Production Profiling: What, Why and How
Production Profiling: What, Why and HowProduction Profiling: What, Why and How
Production Profiling: What, Why and How
RichardWarburton
 
Generics Past, Present and Future (Latest)
Generics Past, Present and Future (Latest)Generics Past, Present and Future (Latest)
Generics Past, Present and Future (Latest)
RichardWarburton
 
Generics past, present and future
Generics  past, present and futureGenerics  past, present and future
Generics past, present and future
RichardWarburton
 
Introduction to lambda behave
Introduction to lambda behaveIntroduction to lambda behave
Introduction to lambda behave
RichardWarburton
 
Introduction to lambda behave
Introduction to lambda behaveIntroduction to lambda behave
Introduction to lambda behave
RichardWarburton
 
Performance and predictability
Performance and predictabilityPerformance and predictability
Performance and predictability
RichardWarburton
 
Simplifying java with lambdas (short)
Simplifying java with lambdas (short)Simplifying java with lambdas (short)
Simplifying java with lambdas (short)
RichardWarburton
 
Lambdas myths-and-mistakes
Lambdas myths-and-mistakesLambdas myths-and-mistakes
Lambdas myths-and-mistakes
RichardWarburton
 
Lambdas: Myths and Mistakes
Lambdas: Myths and MistakesLambdas: Myths and Mistakes
Lambdas: Myths and Mistakes
RichardWarburton
 

Recently uploaded (20)

How analogue intelligence complements AI
How analogue intelligence complements AIHow analogue intelligence complements AI
How analogue intelligence complements AI
Paul Rowe
 
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
organizerofv
 
Cybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure ADCybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure AD
VICTOR MAESTRE RAMIREZ
 
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
BookNet Canada
 
Drupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy ConsumptionDrupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy Consumption
Exove
 
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep DiveDesigning Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
ScyllaDB
 
Semantic Cultivators : The Critical Future Role to Enable AI
Semantic Cultivators : The Critical Future Role to Enable AISemantic Cultivators : The Critical Future Role to Enable AI
Semantic Cultivators : The Critical Future Role to Enable AI
artmondano
 
Generative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in BusinessGenerative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in Business
Dr. Tathagat Varma
 
Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.
hpbmnnxrvb
 
AI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global TrendsAI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global Trends
InData Labs
 
Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025
Splunk
 
tecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdftecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdf
fjgm517
 
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptxIncreasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Anoop Ashok
 
TrsLabs - Fintech Product & Business Consulting
TrsLabs - Fintech Product & Business ConsultingTrsLabs - Fintech Product & Business Consulting
TrsLabs - Fintech Product & Business Consulting
Trs Labs
 
Quantum Computing Quick Research Guide by Arthur Morgan
Quantum Computing Quick Research Guide by Arthur MorganQuantum Computing Quick Research Guide by Arthur Morgan
Quantum Computing Quick Research Guide by Arthur Morgan
Arthur Morgan
 
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-UmgebungenHCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
panagenda
 
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath MaestroDev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
UiPathCommunity
 
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
Alan Dix
 
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdfSAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
Precisely
 
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptxDevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
Justin Reock
 
How analogue intelligence complements AI
How analogue intelligence complements AIHow analogue intelligence complements AI
How analogue intelligence complements AI
Paul Rowe
 
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
organizerofv
 
Cybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure ADCybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure AD
VICTOR MAESTRE RAMIREZ
 
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
BookNet Canada
 
Drupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy ConsumptionDrupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy Consumption
Exove
 
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep DiveDesigning Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
ScyllaDB
 
Semantic Cultivators : The Critical Future Role to Enable AI
Semantic Cultivators : The Critical Future Role to Enable AISemantic Cultivators : The Critical Future Role to Enable AI
Semantic Cultivators : The Critical Future Role to Enable AI
artmondano
 
Generative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in BusinessGenerative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in Business
Dr. Tathagat Varma
 
Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.
hpbmnnxrvb
 
AI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global TrendsAI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global Trends
InData Labs
 
Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025
Splunk
 
tecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdftecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdf
fjgm517
 
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptxIncreasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Anoop Ashok
 
TrsLabs - Fintech Product & Business Consulting
TrsLabs - Fintech Product & Business ConsultingTrsLabs - Fintech Product & Business Consulting
TrsLabs - Fintech Product & Business Consulting
Trs Labs
 
Quantum Computing Quick Research Guide by Arthur Morgan
Quantum Computing Quick Research Guide by Arthur MorganQuantum Computing Quick Research Guide by Arthur Morgan
Quantum Computing Quick Research Guide by Arthur Morgan
Arthur Morgan
 
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-UmgebungenHCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
panagenda
 
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath MaestroDev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
UiPathCommunity
 
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
Alan Dix
 
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdfSAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
Precisely
 
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptxDevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
Justin Reock
 

Pragmatic functional refactoring with java 8 (1)

  • 1. Pragmatic Functional Refactoring with Java 8 Raoul-Gabriel Urma (@raoulUK) Richard Warburton (@RichardWarburto)
  • 5. Step 1: filtering invoices from Oracle public List<Invoice> findInvoicesFromOracle(List<Invoice> invoices) { List<Invoice> result = new ArrayList<>(); for(Invoice invoice: invoices) { if(invoice.getCustomer() == Customer.ORACLE) { result.add(invoice); } } return result; }
  • 6. Step 2a: abstracting the customer public List<Invoice> findInvoicesFromCustomer(List<Invoice> invoices, Customer customer) { List<Invoice> result = new ArrayList<>(); for(Invoice invoice: invoices) { if(invoice.getCustomer() == customer) { result.add(invoice); } } return result; }
  • 7. Step 2b: abstracting the name public List<Invoice> findInvoicesEndingWith(List<Invoice> invoices, String suffix) { List<Invoice> result = new ArrayList<>(); for(Invoice invoice: invoices) { if(invoice.getName().endsWith(suffix)) { result.add(invoice); } } return result; }
  • 8. Step 3: messy code-reuse! private List<Invoice> findInvoices(List<Invoice> invoices, Customer customer, String suffix, boolean flag) { List<Invoice> result = new ArrayList<>(); for(Invoice invoice: invoices) { if((flag && invoice.getCustomer() == customer) || (!flag && invoice.getName().endsWith(suffix))) { result.add(invoice); } } return result; }
  • 9. Step 4a: modeling the filtering criterion public interface Predicate<T> { boolean test(T t); } Invoice boolean Predicate<Invoice>
  • 10. Step 4b: using different criterion with objects private List<Invoice> findInvoices(List<Invoice> invoices, Predicate<Invoice> p) { List<Invoice> result = new ArrayList<>(); for(Invoice invoice: invoices) { if(p.test(invoice)) { result.add(invoice); } } return result; }
  • 11. Step 4b: using different criterion with objects List<Invoice> specificInvoices = findInvoices(invoices, new FacebookTraining()); class FacebookTraining implements Predicate<Invoice> { @Override public boolean test(Invoice invoice) { return invoice.getCustomer() == Customer.FACEBOOK && invoice.getName().endsWith("Training"); } }
  • 12. Step 5: method references public boolean isOracleInvoice(Invoice invoice) { return invoice.getCustomer() == Customer.ORACLE; } public boolean isTrainingInvoice(Invoice invoice) { return invoice.getName().endsWith("Training"); } List<Invoice> oracleInvoices = findInvoices(invoices, this::isOracleInvoice); List<Invoice> trainingInvoices = findInvoices(invoices, this::isTrainingInvoice); method references
  • 13. Step 6: lambdas List<Invoice> oracleInvoices = findInvoices(invoices, invoice -> invoice.getCustomer() == Customer.ORACLE); List<Invoice> trainingInvoices = findInvoices(invoices, invoice -> invoice.getName().endsWith("Training"));
  • 14. First-class functions ● Common Object Oriented concept: Function Object ● All it means is the ability to use a function just like a regular value ○ Pass it as argument to a method ○ Store it in a variable ● Helps cope with requirement changes
  • 16. Composing functions: example import java.util.function.Predicate; Predicate<Invoice> isFacebookInvoice = this::isFacebookInvoice; List<Invoice> facebookAndTraining = invoices.stream() .filter( isFacebookInvoice.and(this::isTrainingInvoice)) .collect(toList()); List<Invoice> facebookOrGoogle = invoices.stream() .filter( isFacebookInvoice.or(this::isGoogleInvoice)) .collect(toList()); creating more complex functions from building blocks
  • 17. Composing functions: why does it work? public interface Predicate<T> { boolean test(T t); default Predicate<T> and(Predicate<? super T> other) { Objects.requireNonNull(other); return (t) -> test(t) && other.test(t); } default Predicate<T> or(Predicate<? super T> other) { Objects.requireNonNull(other); return (t) -> test(t) || other.test(t); } } returns a new function that is the result of composing two functions
  • 18. Creating function pipelines (1) public class Email { private final String message; public Email(String message) { this.message = message; } public Email addHeader() { return new Email("Dear Sir/Madam:n" + message); } public Email checkSpelling() { return new Email(message.replaceAll("FTW", "for the win")); } public Email addSignature() { return new Email(message + "nKind regards"); } }
  • 19. Creating function pipelines (2) import java.util.function.Function; Function<Email, Email> addHeader = Email::addHeader; Function<Email, Email> processingPipeline = addHeader.andThen(Email::checkSpelling) .andThen(Email::addSignature); addHeader checkSpelling addSignature andThen andThen Email {message="Java 8 FTW!"} Email{message='Dear Sir/Madam: Java 8 for the win! Kind regards'} composing functions
  • 20. Creating function pipelines (3) import java.util.function.Function; Function<Email, Email> addHeader = Email::addHeader; Function<Email, Email> processingPipeline = addHeader.andThen(Email::addSignature); addHeader addSignature andThen Email {message="Java 8 FTW!"} Email{message='Dear Sir/Madam: Java 8 FTW! Kind regards'} composing functions
  • 22. Example: A Conversion Function double convert(double amount, double factor, double base) { return amount * factor + base; } // Usage double result = convert(10, 1.8, 32); assertEquals(result, 50, 0.0);
  • 23. Using the conversion function // Temperatures double cInF = convert(10, 1.8, 32); double higherTemp = convert(30, 1.8, 32); // Currencies double dollarsInPounds = convert(10, 0.6, 0); // Distance double kilometresInMiles = convert(27, 0.62137, 0);
  • 24. So what’s the problem? ● Abstraction ○ How do you write something that operates on different conversion functions? ● Reuse ○ How do you use the conversion function in different places?
  • 26. Currying the conversion function double convert(double amount, double factor, double base) { return amount * factor + base; } DoubleUnaryOperator convert(double factor, double base) { return amount -> amount * factor + base; }
  • 27. Using the conversion function DoubleUnaryOperator convert(double factor, double base) { return amount -> amount * factor + base; } DoubleUnaryOperator convertCtoF = convert(1.8, 32); double result = convertCtoF.applyAsDouble(10); assertEquals(result, 50, 0.0);
  • 29. Partial Application Examples // Temperatures DoubleUnaryOperator convertCtoF = convert(1.8, 32); // Currencies DoubleUnaryOperator convert$to£ = convert(0.6, 0); // Distance DoubleUnaryOperator convertKmToMi = convert(0.62137, 0);
  • 30. Definition // int -> (int -> int) IntFunction<IntUnaryOperator> curry(IntBinaryOperator biFunction) { return f -> (s -> biFunction.applyAsInt(f, s)); }
  • 31. Usage IntFunction<IntUnaryOperator> add = curry((f, s) -> f + s); int result = add.apply(1) .applyAsInt(2); assertEquals(3, result);
  • 32. Example currying use cases ● Large factory methods ○ Partially apply some of the arguments and then pass this factory object around. ● Combinators libraries ○ Parsers ○ HTML templating
  • 33. Summary ● Currying is about splitting up the arguments of a function. ● Partial Application is a function “eating” some of its arguments and returning a new function
  • 35. Mutable objects public class TrainJourney { private int price; private TrainJourney onward; public TrainJourney(int price, TrainJourney onward) { this.price = price; this.onward = onward; } public int getPrice() { return price; } public TrainJourney getOnward() { return onward; } public void setPrice(int price) { this.price = price; } public void setOnward(TrainJourney onward) { this.onward = onward; } }
  • 36. Immutable objects public final class TrainJourneyImmutable { private final int price; private final TrainJourneyImmutable onward; public TrainJourneyImmutable(int price, TrainJourney onward) { this.price = price; this.onward = onward; } public int getPrice() { return price; } public TrainJourneyImmutable getOnward() { return onward; } public TrainJourneyImmutable withPrice(int price) { return new TrainJourneyImmutable(price, getOnward()); } public TrainJourneyImmutable withOnward(TrainJourneyImmutable onward) { return new TrainJourneyImmutable(getPrice(), onward); } }
  • 37. Scenario: be able to link together train journeys to form longer journeys.
  • 39. Mutable approach public TrainJourney link(TrainJourney start, TrainJourney continuation) { if (start == null) { return continuation; } TrainJourney t = start; while (t.getOnward() != null) { t = t.getOnward(); } t.setOnward(continuation); return start; } find the last stop in the first journey modify it to link to the continuation journey return the continuation journey if there is no start journey
  • 40. Mutable approach: problem TrainJourney firstJourney = link(start, continuation); TrainJourney secondJourney = link(start, continuation); visit(secondJourney, tj -> { System.out.print(tj.price + " - "); }); static void visit(TrainJourney journey, Consumer<TrainJourney> c) { if (journey != null) { c.accept(journey); visit(journey.onward, c); } }
  • 43. Immutable approach public TrainJourneyImmutable link(TrainJourneyImmutable start, TrainJourneyImmutable continuation) { return start == null ? continuation : new TrainJourneyImmutable(start.getPrice(), link(start.getOnward(), continuation)); }
  • 44. Related topics ● Domain Driven Design ○ Value Classes are Immutable ● Core Java Improvements ○ New date & time library in Java 8 has many Immutable Objects ○ Current Value Types proposal is immutable ● Tooling ○ final keyword only bans reassignment ○ JSR 308 - improved annotation opportunities ○ Mutability Detector ○ Findbugs
  • 45. Downsides to Immutability ● Increased memory allocation pressure ● Some problems harder to model with immutability ○ Deep object graphs ○ Example: Car simulation ● Library interactions ○ ORMs especially ○ Serialisation usually ok these days ● Alternative: small blobs of simple and localised state
  • 46. Immutable objects reduce the scope for bugs.
  • 48. Don’t we all love it? Exception in thread "main" java.lang.NullPointerException
  • 49. public String getCarInsuranceName(Person person) { return person.getCar().getInsurance().getName(); } Where’s the NPE?
  • 50. Defensive checking public String getCarInsuranceName(Person person) { if (person != null) { Car car = person.getCar(); if (car != null) { Insurance insurance = car.getInsurance(); if (insurance != null) { return insurance.getName(); } } } return "No Insurance"; }
  • 51. Optional ● Java 8 introduces a new class java.util.Optional<T> ○ a single-value container ● Explicit modelling ○ Immediately clear that its an optional value ○ better maintainability ● You need to actively unwrap an Optional ○ force users to think about the absence case ○ fewer errors
  • 52. Updating model public class Person { private Optional<Car> car; public Optional<Car> getCar() { return car; } } public class Car { private Optional<Insurance> insurance; public Optional<Insurance> getInsurance() { return insurance; } } public class Insurance { private String name; public String getName() { return name; } }
  • 54. Why it doesn’t work? Optional<People> optPerson = Optional.ofNullable(person); Optional<String> name = optPeople.map(Person::getCar) .map(Car::getInsurance) .map(Insurance::getName); returns Optional<Optional<Car>> Invalid, the inner Optional object doesn’t support the method getInsurance! public class Person { private Optional<Car> car; public Optional<Car> getCar() { return car; } }
  • 57. Chaining methods with flatMap public String getCarInsuranceName(Person person) { return Optional.ofNullable(person) .flatMap(Person::getCar) .flatMap(Car::getInsurance) .map(Insurance::getName) .orElse("Unknown"); } default value if the resulting Optional is empty
  • 58. A comment on naming public String getCarInsuranceName(Person person) { Set<Person> personSet = person == null ? emptySet() : singleton(person); return personSet.stream() .flatMap(Person::getCar) .flatMap(Car::getInsurance) .map(Insurance::getName) .orElse("Unknown"); }
  • 59. Optional in Fields ● Should it be used for fields, or just public methods? ● Pros ○ Explicit modelling ○ Null-safe access ○ Simple getters ● Cons ○ More indirection and GC overhead in Java 8 ○ Not every library understands Optional yet ○ Some libraries require Serializable fields
  • 60. Consistent use of Optional replaces the use of null
  • 62. Summary of benefits ● First-class functions let you cope for requirement changes ● Currying lets you split the parameters of a function to re-use code logic ● Immutability reduces the scope for bugs ● Optional data types lets you reduce null checking boilerplate and prevent bugs
  • 66. Generalised curry function // F -> (S -> R) <F, S, R> Function<F, Function<S, R>> curry(BiFunction<F, S, R> biFunction) { return f -> s -> biFunction.apply(f, s); }