SlideShare una empresa de Scribd logo
1 de 43
Descargar para leer sin conexión
Functional Java,
a practical example
HELLO!
I am Marian Wamsiedel
I work as a Java developer. You can find me at
marian.wamsiedel@gmail.com
2
Motivation
As always, the code examples are rather
naive, they are not meant to be used without
changes in a real life scenario.
Running code examples are available in a
github repository.
3
Functional Java
Java was designed as an object oriented programming
language, but, starting with version 8, it offers also
support for functional programming.
The choice between one of the two programming
paradigms is currently a discussed topic.
I present here an object oriented and some functional
solutions to implement a simple programming task.
The challenge:
Your company is building vehicles that need to be controlled remote by sending
some vocal commands.
The commands look like: “start”, “move forward”, “move left”, “stop” and so on.
Each vehicle implements an interface, that you design. The vehicle is being moved
by calling the interface methods, like: vehicle.moveForward(), or vehicle.stop().
A third-party library takes care of sending the vocal commands to a command
centre
The task is to write the code that runs the vocal commands on a vehicle.
The solution to be implemented
4
One problem, three solutions
5
Object
oriented
Pure
functional
Functional
with
effects
The object oriented
approach
Think solid
6
1
Object oriented approach
7
The Vehicle interface could contain methods like:
void wakeUp();
void moveForward(Distance distance);
void moveLeft(Distance distance);
void moveRight(Distance distance);
void stop();
Coordinate currentPosition();
Each method would throw a runtime exception if something goes wrong.
Object oriented approach
8
The vocal commands could be modelled as Command classes, each one exposing an
execute() method. We end up with mappings like these:
“move forward 6 meter” → new MoveForwardCommand(vehicle, Distance.meter(6))
“move left 3 meter” → new MoveLeftCommand(vehicle, Distance.meter(3))
“stop” → new StopCommand(vehicle)
A list of commands can be executed by iterating over it and calling the execute() method for
each of its items.
Some form of exception handling is expected, for instance: “logging the root cause and the
current vehicle position”.
Object oriented approach
9
Optimization: since the vehicle needs to be started before any move and stopped after the
ride completes, the application should take care automatically of start-stop moves. This can
be done using the template pattern:
Any ride consists of three types of actions: before raid (preparation), main ride and after ride
(clean up). A template superclass implements the before and after functionality and each
ride class provides the mainRide() method, that contains the specific moves.
Executable code examples in this repository:
https://github.com/mw1980/oofunctionalexample the package “oo”
Object oriented approach
10
The code for the vehicle ride would then look like:
new VehicleRide(
new MoveForwardCommand(vehicle, Distance.ONE_METER),
new MoveLeftCommand(vehicle, Distance.inch(2)),
new MoveRightCommand(vehicle, Distance.THREE_METER)
).startRide()
The VehicleRide class implements the main ride logic for the commands received as
parameter, while its parent, the AbstractTemplateRide class takes care of start – stop
operations.
https://github.com/mw1980/oofunctionalexample , the package “oo”
One problem, three solutions
11
Pure
functional
Object
oriented
Functional
with
effects
A pure functional
approach
The joy of purity...
12
2
Pure functional approach
13
The functional programming has other goals, like referential transparency,
immutability and isolation of side effects.
Immutability is a central concept of the functional programming. Therefore the
methods that receive a parameter and return “void” look suspicious, because they
probably modify the state of their input parameter.
For instance, the move methods from the “oo” implementation would modify the
vehicle coordinates, fuel status, temperature and so on.
Therefore the Vehicle interface methods would rather return a new vehicle
instance, instead of void. For example:
Vehicle moveForward(Distance distance)
Vehicle stop()
Pure functional approach
14
The command classes from the object oriented implementation would be replaced
by some functions:
MOVE_FORWARD = distance-> vehicle -> vehicle.moveForward(distance)
MOVE_LEFT = distance-> vehicle -> vehicle.moveLeft(distance)
MOVE_RIGHT = distance-> vehicle -> vehicle.moveRight(distance)
STOP = Vehicle::stop
START = Vehicle::wakeUp
If the code looks weird, read more about currying here.
Pure functional approach
15
By fixing the distance in the above function definitions, the vehicle moves become functions
that depend only on the vehicle (unary operators):
UnaryOperator<Vehicle> moveLeft3 = MOVE_LEFT.apply(Distance.THREE_METER)
UnaryOperator<Vehicle> moveRight10 = MOVE_RIGHT.apply(Distance.TEN_METER)
UnaryOperator<Vehicle> moveForward13 = MOVE_FORWARD.apply(Distance.inch(13))
A simple ride would look like this:
START.andThen(moveLeft3).andThen(moveRight10).andThen(moveForward13)
.andThen(STOP).apply(vehicle)
Pure functional approach
16
The solution is very expressive, but still kind of verbose, requiring a new “andThen” call for
each move. Some functional patterns can make the code even compacter:
The monoid
The term comes from mathematics and it means a semi group with unity element.
To keep things simple, a monoid is a sequence of elements of some type: A, that support an
operation op : (A, A) → A.
There is also a special element of type A (the “unity”), that has no effect in the op
computation: op (unity, a) = op(a, unity) = a;
Read more about it here.
Pure functional approach
17
Examples:
- The strings, having concatenation as operation and the
empty string as unity element.
- The integer numbers, having the sum (the addition) as
operation and zero as unity element.
Since the functions are first class citizens in the
functional programming world, the A elements can be
functions, like the unary operators defined above and the
operation “op” can be the composition of functions:
Pure functional approach
18
a1 is “f1 : Vehicle → Vehicle”,
a2 is “f2 : Vehicle → Vehicle”,
op(a1, a2) is the composition of f1 and f2, also an unary operator for vehicles.
op(a1, a2) = a2 ◦ a1, or more detailed:
op(f1, f2) (vehicle) = f2.apply(f1.apply(vehicle))
The unity element would be the function that simply returns its input parameter:
unity(vehicle) = vehicle, for any vehicle object
Pure functional approach
19
Any monoid supports folding operations, by applying the
operation “op”:
- on unity element and on monoids first element to produce
a result
- then on the result and on monoids second element
- and so on, to end up with a single element.
Example: The folding of a sequence of integers, with
addition as operation and unity element zero would
produce a single value that is the sum of all integers in the
sequence.
Pure functional approach
20
Since the Java 8 Streams API implements already the folding functionality, the sequence of the
vehicle moves can be modelled also this way:
allMoves = Stream.of(moveLeft3, moveRight10, moveForward13)
.reduce(
UnaryOperator.identity(),
(first, second) -> v -> second.apply(first.apply(v))
)
allMoves.apply(vehicle)
https://github.com/mw1980/oofunctionalexample , package functional/pure
Pure functional approach
21
The prefixing and suffixing of some vehicle moves could be modelled as a function, that
replaces the template pattern. The ride function simply wraps a vehicle move between start
and stop actions.
ride: unaryVehicleOperator → start ◦ unaryVehicleOperator ◦ stop.
The code:
Function<UnaryOperator<Vehicle>, UnaryOperator<Vehicle>>
ride = f -> vehicle -> STOP.apply(f.apply(START.apply(vehicle)));
The code that moves the vehicle and returns its coordinate will look like:
ride.apply(allMoves).apply(vehicleInstance).currentPosition();
https://github.com/mw1980/oofunctionalexample , package functional/pure
One problem, three solutions
22
Functional
with
effects
Object
oriented
Pure
functional
Real world
functional approach
Consider also side effects
23
3
Real world functional approach
24
We ignored the potential exceptions so far. They are considered in the functional programming
impure and therefore not supported. The exceptions are possible effects that hurt the
referential transparency of the system and should be isolated from the business logic
implementation.
Throwing and catching exceptions is seen as a glorified form of the “go to” statement, that
should be avoided.
The functional programming way to handle an exception is to wrap the suspect code block in
another component, like a Try, or an IO wrapper class.
The simple presence of Try, or IO components signalizes that the code might deal with side
effects, isolating the pure functional code from the rest.
Real world functional approach
▰ Lazy Try blocks
▰ Simple Try blocks
▰ Try with errors
25
Real world functional approach
26
In the context of vehicle operators, the try component could look like this:
class LazyTry<T> {
//injected in the constructor
private final UnaryOperator<T> f;
public T execute(final T t) {
try {f.apply(t);} // use try – catch only here
catch (RuntimeException exception) { // handle the error case }
}}
The Try class is a generic, lazy evaluated and reusable component.
Real world functional approach
27
The Try blocks can be composed, if they implement a
combine method, like “andThen”
LazyTry.to[f].andThen[g] = LazyTry.to[f ◦ g];
The operation can be repeated:
LazyTry.to[f1].andThen[f2] … andThen[fn] = LazyTry.to[f1 ◦
f2 ◦ … ◦ fn]
public LazyTry<T> andThen(UnaryOperator<T> after)
{
return
new LazyTry<>(t -> after.apply(f.apply(t)));
}
Real world functional approach
28
The vehicle moves could look like:
LazyTry.to(Vehicle::wakeUp)
.andThen(v -> v.moveLeft(FIVE_METER))
.andThen(v -> v.moveForward(THREE_METER))
...
.andThen(Vehicle::stop)
.onError(exception -> System.out.println(“err:”+ exception.getMessage()))
.execute(someVehicleInstance)
Real world functional approach
29
A sequence of lazy try blocks can be seen as a monoid, with:
- identity element = LazyTry.to( UnaryOperator.identity() )
- the lazyTryComposition(LazyTry.to[f], LazyTry.to[g]) = LazyTry.to[f◦g].
It is possible to fold on a sequence of try elements, using the Java 8 streams API. If the vehicle
moves are encapsulated in LazyTry instances, the code for the vehicle ride looks like:
Stream.of(LazyTry.of(firstVehicleMove), … , LazyTry.of(lastVehicleMove))
.reduce(identityElement, lazyTryComposition)
.execute(someVehicle);
The online repository contains an example:
https://github.com/mw1980/oofunctionalexample/ package functional/effects
Real world functional approach
▰ Lazy Try blocks
▰ Simple Try blocks
▰ Try with errors
30
Real world functional approach
31
The expressions that generate effects can also be initialized eagerly. The standard way is to
use a simple Try<T> block, that contains already the evaluated value of type T.
The Try class can have two subclasses: Success and Failure, that cover the successful
execution, or the operation failure.
The Try objects would be instantiated in a factory method:
static <T> Try<T> of(Supplier<T> supplier) {
try {
return new Success<>(supplier.get());
} catch (Exception exception) {
return new Failure<>(exception);
}
}
Real world functional approach
32
The Try<T> class could expose standard “map” and “flat map” methods, that lift some
operations on T type in the Try context:
public interface Try<T> {
...
Try<T> map(UnaryOperator<T> f);
Try<T> flatMap(Function<T, Try<T>> f);
…
}
Real world functional approach
33
The vehicle interface could look like:
public interface Vehicle {
Try<Vehicle> wakeUp();
Try<Vehicle> moveForward(Distance distance);
Try<Vehicle> moveLeft(Distance distance);
Try<Vehicle> moveRight(Distance distance);
Try<Vehicle> stop();
}
Real world functional approach
34
The vehicle moves can be modelled this way:
MOVE_FORWARD = distance -> vehicle -> vehicle.moveForward(distance);
MOVE_LEFT = distance -> vehicle -> vehicle.moveLeft(distance);
START = Vehicle::wakeUp;
STOP = Vehicle::stop;
Try.<Vehicle>of(Vehicle.Default::new)
.flatMap(START)
.flatMap(MOVE_FORWARD.apply(Distance.THREE_METER))
.flatMap(MOVE_LEFT.apply(Distance.FIVE_METER))
.flatMap(MOVE_RIGHT.apply(Distance.TEN_METER))
.flatMap(STOP);
The online repository contains an example.
https://github.com/mw1980/oofunctionalexample/ package “functional/effects/basic”
Real world functional approach
▰ Lazy Try blocks
▰ Simple Try blocks
▰ Try with errors
35
Real world functional approach
36
In some cases it is important to return the exception that might occur. The system could be
required to react differently, according to the exception type. The class Either can be used to
store also the potential error:
public class Either<T, V> {
//injected in the constructor, mutual exclusive
private final T left; //exception comes here, by convention
private final V right;
public static <T, V> Either<T, V> withLeftValue(final T value) {…}
public static <T, V> Either<T, V> withRightValue(final V value) {…}
}
Real world functional approach
37
The Try class could be rewritten to consider also exceptions:
public class TryWithError<T, U> {
private final Function<T, U> f;
public Either<RuntimeException, U> execute(T t) {
try { return Either.withRightValue(f.apply(t));}
catch (RuntimeException exception) {
return Either.withLeftValue(
new RuntimeException(“error message”, exception)
);
}}}
Real world functional approach
38
The code that performs the vehicle actions and returns also the exceptions that might occur
would then look like:
Either<RuntimeException, Vehicle> vehicleMoveResult =
TryWithError.to(Vehicle::wakeUp)
.andThen(v -> v.moveLeft(FIVE_METER))
...
.andThen(Vehicle::stop)
.execute(someVehicleInstance)
Real world functional approach
39
OO against FP, my two cents:
The functional programming:
+ extremely compact
+ handles the exceptions gracefully
+ truly reusable design patterns
- abstract
- requires more discipline
- it gets complex if it handles simultaneously more concerns, like handling exceptions and
missing return values
Real world functional approach
40
OO against FP, my two cents:
Object oriented programming:
+ easier to understand
+ easier to extend
+ its design patterns are a great communications instrument
+ it is trivial to write unit tests
+ the “Gof” design patterns, like Command and Template communicate well the code
intention. They are well known and generally accepted by the Java community
Real world functional approach
41
OO against FP, my two cents:
Object oriented programming:
- explosion of classes
- code verbosity
- difficult to maintain the overview when using template classes, especially if the class
inheritance hierarchy gets long
Read more
42
More documentation:
Functional and Reactive Domain Modeling (Debasish Gosh), Manning 2016
Functional Programming in Java (Pierre-Yves Saumont), Manning 2016
Vavr: http://www.vavr.io/
Eta lang: https://eta-lang.org/
Referential transparency: https://en.wikipedia.org/wiki/Referential_transparency
Currying:
https://hackernoon.com/functional-programming-paradigms-in-modern-javascript-currying-565
2e489cce8
Monoids: https://medium.com/@sjsyrek/five-minutes-to-monoid-fe6f364d0bba
CREDITS
Graphical content:
▰ Presentation template by SlidesCarnival
▰ Photographs by Startup Stock Photos
43

Más contenido relacionado

La actualidad más candente

Evolving a Clean, Pragmatic Architecture - A Craftsman's Guide
Evolving a Clean, Pragmatic Architecture - A Craftsman's GuideEvolving a Clean, Pragmatic Architecture - A Craftsman's Guide
Evolving a Clean, Pragmatic Architecture - A Craftsman's Guide
Victor Rentea
 
A Separation of Concerns: Clean Architecture on Android
A Separation of Concerns: Clean Architecture on AndroidA Separation of Concerns: Clean Architecture on Android
A Separation of Concerns: Clean Architecture on Android
Outware Mobile
 
If You Think You Can Stay Away from Functional Programming, You Are Wrong
If You Think You Can Stay Away from Functional Programming, You Are WrongIf You Think You Can Stay Away from Functional Programming, You Are Wrong
If You Think You Can Stay Away from Functional Programming, You Are Wrong
Mario Fusco
 

La actualidad más candente (20)

Hexagonal architecture with Spring Boot
Hexagonal architecture with Spring BootHexagonal architecture with Spring Boot
Hexagonal architecture with Spring Boot
 
Evolving a Clean, Pragmatic Architecture - A Craftsman's Guide
Evolving a Clean, Pragmatic Architecture - A Craftsman's GuideEvolving a Clean, Pragmatic Architecture - A Craftsman's Guide
Evolving a Clean, Pragmatic Architecture - A Craftsman's Guide
 
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...
 
A Separation of Concerns: Clean Architecture on Android
A Separation of Concerns: Clean Architecture on AndroidA Separation of Concerns: Clean Architecture on Android
A Separation of Concerns: Clean Architecture on Android
 
Functional Design Patterns (DevTernity 2018)
Functional Design Patterns (DevTernity 2018)Functional Design Patterns (DevTernity 2018)
Functional Design Patterns (DevTernity 2018)
 
Clean coding-practices
Clean coding-practicesClean coding-practices
Clean coding-practices
 
Modular Monoliths with Nx
Modular Monoliths with NxModular Monoliths with Nx
Modular Monoliths with Nx
 
Clean Lambdas & Streams in Java8
Clean Lambdas & Streams in Java8Clean Lambdas & Streams in Java8
Clean Lambdas & Streams in Java8
 
Deep dive into Coroutines on JVM @ KotlinConf 2017
Deep dive into Coroutines on JVM @ KotlinConf 2017Deep dive into Coroutines on JVM @ KotlinConf 2017
Deep dive into Coroutines on JVM @ KotlinConf 2017
 
Open Closed Principle kata
Open Closed Principle kataOpen Closed Principle kata
Open Closed Principle kata
 
React js
React jsReact js
React js
 
Writing and using Hamcrest Matchers
Writing and using Hamcrest MatchersWriting and using Hamcrest Matchers
Writing and using Hamcrest Matchers
 
Geecon09: SOLID Design Principles
Geecon09: SOLID Design PrinciplesGeecon09: SOLID Design Principles
Geecon09: SOLID Design Principles
 
If You Think You Can Stay Away from Functional Programming, You Are Wrong
If You Think You Can Stay Away from Functional Programming, You Are WrongIf You Think You Can Stay Away from Functional Programming, You Are Wrong
If You Think You Can Stay Away from Functional Programming, You Are Wrong
 
Clean architecture
Clean architectureClean architecture
Clean architecture
 
Design principles - SOLID
Design principles - SOLIDDesign principles - SOLID
Design principles - SOLID
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with Spring
 
Clean Pragmatic Architecture - Avoiding a Monolith
Clean Pragmatic Architecture - Avoiding a MonolithClean Pragmatic Architecture - Avoiding a Monolith
Clean Pragmatic Architecture - Avoiding a Monolith
 
Java 8 streams
Java 8 streamsJava 8 streams
Java 8 streams
 
Algebraic Data Types for Data Oriented Programming - From Haskell and Scala t...
Algebraic Data Types forData Oriented Programming - From Haskell and Scala t...Algebraic Data Types forData Oriented Programming - From Haskell and Scala t...
Algebraic Data Types for Data Oriented Programming - From Haskell and Scala t...
 

Similar a Design functional solutions in Java, a practical example

Inline function
Inline functionInline function
Inline function
Tech_MX
 

Similar a Design functional solutions in Java, a practical example (20)

Angular performance slides
Angular performance slidesAngular performance slides
Angular performance slides
 
How To Use IO Monads in Scala?
 How To Use IO Monads in Scala? How To Use IO Monads in Scala?
How To Use IO Monads in Scala?
 
Inline function
Inline functionInline function
Inline function
 
Lect 3-4 Zaheer Abbas
Lect 3-4 Zaheer AbbasLect 3-4 Zaheer Abbas
Lect 3-4 Zaheer Abbas
 
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)
 
Angular Optimization Web Performance Meetup
Angular Optimization Web Performance MeetupAngular Optimization Web Performance Meetup
Angular Optimization Web Performance Meetup
 
C++ Program Auto workshop service system
C++ Program Auto workshop service systemC++ Program Auto workshop service system
C++ Program Auto workshop service system
 
JAVA_BASICS.ppt
JAVA_BASICS.pptJAVA_BASICS.ppt
JAVA_BASICS.ppt
 
Generalized Functors - Realizing Command Design Pattern in C++
Generalized Functors - Realizing Command Design Pattern in C++Generalized Functors - Realizing Command Design Pattern in C++
Generalized Functors - Realizing Command Design Pattern in C++
 
OOPS USING C++(UNIT 2)
OOPS USING C++(UNIT 2)OOPS USING C++(UNIT 2)
OOPS USING C++(UNIT 2)
 
Unit Testing Using Mockito in Android (1).pdf
Unit Testing Using Mockito in Android (1).pdfUnit Testing Using Mockito in Android (1).pdf
Unit Testing Using Mockito in Android (1).pdf
 
Angular 16 – the rise of Signals
Angular 16 – the rise of SignalsAngular 16 – the rise of Signals
Angular 16 – the rise of Signals
 
Top 7 Angular Best Practices to Organize Your Angular App
Top 7 Angular Best Practices to Organize Your Angular AppTop 7 Angular Best Practices to Organize Your Angular App
Top 7 Angular Best Practices to Organize Your Angular App
 
Wien15 java8
Wien15 java8Wien15 java8
Wien15 java8
 
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
 
Resolver in Angular
Resolver in AngularResolver in Angular
Resolver in Angular
 
How to write maintainable code without tests
How to write maintainable code without testsHow to write maintainable code without tests
How to write maintainable code without tests
 
Functional programming in Javascript
Functional programming in JavascriptFunctional programming in Javascript
Functional programming in Javascript
 
Appium Automation with Kotlin
Appium Automation with KotlinAppium Automation with Kotlin
Appium Automation with Kotlin
 
[2015/2016] JavaScript
[2015/2016] JavaScript[2015/2016] JavaScript
[2015/2016] JavaScript
 

Último

%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
masabamasaba
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
masabamasaba
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
masabamasaba
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
masabamasaba
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
masabamasaba
 

Último (20)

%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
 
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto
 
WSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - Keynote
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptx
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 

Design functional solutions in Java, a practical example

  • 2. HELLO! I am Marian Wamsiedel I work as a Java developer. You can find me at marian.wamsiedel@gmail.com 2
  • 3. Motivation As always, the code examples are rather naive, they are not meant to be used without changes in a real life scenario. Running code examples are available in a github repository. 3 Functional Java Java was designed as an object oriented programming language, but, starting with version 8, it offers also support for functional programming. The choice between one of the two programming paradigms is currently a discussed topic. I present here an object oriented and some functional solutions to implement a simple programming task.
  • 4. The challenge: Your company is building vehicles that need to be controlled remote by sending some vocal commands. The commands look like: “start”, “move forward”, “move left”, “stop” and so on. Each vehicle implements an interface, that you design. The vehicle is being moved by calling the interface methods, like: vehicle.moveForward(), or vehicle.stop(). A third-party library takes care of sending the vocal commands to a command centre The task is to write the code that runs the vocal commands on a vehicle. The solution to be implemented 4
  • 5. One problem, three solutions 5 Object oriented Pure functional Functional with effects
  • 7. Object oriented approach 7 The Vehicle interface could contain methods like: void wakeUp(); void moveForward(Distance distance); void moveLeft(Distance distance); void moveRight(Distance distance); void stop(); Coordinate currentPosition(); Each method would throw a runtime exception if something goes wrong.
  • 8. Object oriented approach 8 The vocal commands could be modelled as Command classes, each one exposing an execute() method. We end up with mappings like these: “move forward 6 meter” → new MoveForwardCommand(vehicle, Distance.meter(6)) “move left 3 meter” → new MoveLeftCommand(vehicle, Distance.meter(3)) “stop” → new StopCommand(vehicle) A list of commands can be executed by iterating over it and calling the execute() method for each of its items. Some form of exception handling is expected, for instance: “logging the root cause and the current vehicle position”.
  • 9. Object oriented approach 9 Optimization: since the vehicle needs to be started before any move and stopped after the ride completes, the application should take care automatically of start-stop moves. This can be done using the template pattern: Any ride consists of three types of actions: before raid (preparation), main ride and after ride (clean up). A template superclass implements the before and after functionality and each ride class provides the mainRide() method, that contains the specific moves. Executable code examples in this repository: https://github.com/mw1980/oofunctionalexample the package “oo”
  • 10. Object oriented approach 10 The code for the vehicle ride would then look like: new VehicleRide( new MoveForwardCommand(vehicle, Distance.ONE_METER), new MoveLeftCommand(vehicle, Distance.inch(2)), new MoveRightCommand(vehicle, Distance.THREE_METER) ).startRide() The VehicleRide class implements the main ride logic for the commands received as parameter, while its parent, the AbstractTemplateRide class takes care of start – stop operations. https://github.com/mw1980/oofunctionalexample , the package “oo”
  • 11. One problem, three solutions 11 Pure functional Object oriented Functional with effects
  • 12. A pure functional approach The joy of purity... 12 2
  • 13. Pure functional approach 13 The functional programming has other goals, like referential transparency, immutability and isolation of side effects. Immutability is a central concept of the functional programming. Therefore the methods that receive a parameter and return “void” look suspicious, because they probably modify the state of their input parameter. For instance, the move methods from the “oo” implementation would modify the vehicle coordinates, fuel status, temperature and so on. Therefore the Vehicle interface methods would rather return a new vehicle instance, instead of void. For example: Vehicle moveForward(Distance distance) Vehicle stop()
  • 14. Pure functional approach 14 The command classes from the object oriented implementation would be replaced by some functions: MOVE_FORWARD = distance-> vehicle -> vehicle.moveForward(distance) MOVE_LEFT = distance-> vehicle -> vehicle.moveLeft(distance) MOVE_RIGHT = distance-> vehicle -> vehicle.moveRight(distance) STOP = Vehicle::stop START = Vehicle::wakeUp If the code looks weird, read more about currying here.
  • 15. Pure functional approach 15 By fixing the distance in the above function definitions, the vehicle moves become functions that depend only on the vehicle (unary operators): UnaryOperator<Vehicle> moveLeft3 = MOVE_LEFT.apply(Distance.THREE_METER) UnaryOperator<Vehicle> moveRight10 = MOVE_RIGHT.apply(Distance.TEN_METER) UnaryOperator<Vehicle> moveForward13 = MOVE_FORWARD.apply(Distance.inch(13)) A simple ride would look like this: START.andThen(moveLeft3).andThen(moveRight10).andThen(moveForward13) .andThen(STOP).apply(vehicle)
  • 16. Pure functional approach 16 The solution is very expressive, but still kind of verbose, requiring a new “andThen” call for each move. Some functional patterns can make the code even compacter: The monoid The term comes from mathematics and it means a semi group with unity element. To keep things simple, a monoid is a sequence of elements of some type: A, that support an operation op : (A, A) → A. There is also a special element of type A (the “unity”), that has no effect in the op computation: op (unity, a) = op(a, unity) = a; Read more about it here.
  • 17. Pure functional approach 17 Examples: - The strings, having concatenation as operation and the empty string as unity element. - The integer numbers, having the sum (the addition) as operation and zero as unity element. Since the functions are first class citizens in the functional programming world, the A elements can be functions, like the unary operators defined above and the operation “op” can be the composition of functions:
  • 18. Pure functional approach 18 a1 is “f1 : Vehicle → Vehicle”, a2 is “f2 : Vehicle → Vehicle”, op(a1, a2) is the composition of f1 and f2, also an unary operator for vehicles. op(a1, a2) = a2 ◦ a1, or more detailed: op(f1, f2) (vehicle) = f2.apply(f1.apply(vehicle)) The unity element would be the function that simply returns its input parameter: unity(vehicle) = vehicle, for any vehicle object
  • 19. Pure functional approach 19 Any monoid supports folding operations, by applying the operation “op”: - on unity element and on monoids first element to produce a result - then on the result and on monoids second element - and so on, to end up with a single element. Example: The folding of a sequence of integers, with addition as operation and unity element zero would produce a single value that is the sum of all integers in the sequence.
  • 20. Pure functional approach 20 Since the Java 8 Streams API implements already the folding functionality, the sequence of the vehicle moves can be modelled also this way: allMoves = Stream.of(moveLeft3, moveRight10, moveForward13) .reduce( UnaryOperator.identity(), (first, second) -> v -> second.apply(first.apply(v)) ) allMoves.apply(vehicle) https://github.com/mw1980/oofunctionalexample , package functional/pure
  • 21. Pure functional approach 21 The prefixing and suffixing of some vehicle moves could be modelled as a function, that replaces the template pattern. The ride function simply wraps a vehicle move between start and stop actions. ride: unaryVehicleOperator → start ◦ unaryVehicleOperator ◦ stop. The code: Function<UnaryOperator<Vehicle>, UnaryOperator<Vehicle>> ride = f -> vehicle -> STOP.apply(f.apply(START.apply(vehicle))); The code that moves the vehicle and returns its coordinate will look like: ride.apply(allMoves).apply(vehicleInstance).currentPosition(); https://github.com/mw1980/oofunctionalexample , package functional/pure
  • 22. One problem, three solutions 22 Functional with effects Object oriented Pure functional
  • 23. Real world functional approach Consider also side effects 23 3
  • 24. Real world functional approach 24 We ignored the potential exceptions so far. They are considered in the functional programming impure and therefore not supported. The exceptions are possible effects that hurt the referential transparency of the system and should be isolated from the business logic implementation. Throwing and catching exceptions is seen as a glorified form of the “go to” statement, that should be avoided. The functional programming way to handle an exception is to wrap the suspect code block in another component, like a Try, or an IO wrapper class. The simple presence of Try, or IO components signalizes that the code might deal with side effects, isolating the pure functional code from the rest.
  • 25. Real world functional approach ▰ Lazy Try blocks ▰ Simple Try blocks ▰ Try with errors 25
  • 26. Real world functional approach 26 In the context of vehicle operators, the try component could look like this: class LazyTry<T> { //injected in the constructor private final UnaryOperator<T> f; public T execute(final T t) { try {f.apply(t);} // use try – catch only here catch (RuntimeException exception) { // handle the error case } }} The Try class is a generic, lazy evaluated and reusable component.
  • 27. Real world functional approach 27 The Try blocks can be composed, if they implement a combine method, like “andThen” LazyTry.to[f].andThen[g] = LazyTry.to[f ◦ g]; The operation can be repeated: LazyTry.to[f1].andThen[f2] … andThen[fn] = LazyTry.to[f1 ◦ f2 ◦ … ◦ fn] public LazyTry<T> andThen(UnaryOperator<T> after) { return new LazyTry<>(t -> after.apply(f.apply(t))); }
  • 28. Real world functional approach 28 The vehicle moves could look like: LazyTry.to(Vehicle::wakeUp) .andThen(v -> v.moveLeft(FIVE_METER)) .andThen(v -> v.moveForward(THREE_METER)) ... .andThen(Vehicle::stop) .onError(exception -> System.out.println(“err:”+ exception.getMessage())) .execute(someVehicleInstance)
  • 29. Real world functional approach 29 A sequence of lazy try blocks can be seen as a monoid, with: - identity element = LazyTry.to( UnaryOperator.identity() ) - the lazyTryComposition(LazyTry.to[f], LazyTry.to[g]) = LazyTry.to[f◦g]. It is possible to fold on a sequence of try elements, using the Java 8 streams API. If the vehicle moves are encapsulated in LazyTry instances, the code for the vehicle ride looks like: Stream.of(LazyTry.of(firstVehicleMove), … , LazyTry.of(lastVehicleMove)) .reduce(identityElement, lazyTryComposition) .execute(someVehicle); The online repository contains an example: https://github.com/mw1980/oofunctionalexample/ package functional/effects
  • 30. Real world functional approach ▰ Lazy Try blocks ▰ Simple Try blocks ▰ Try with errors 30
  • 31. Real world functional approach 31 The expressions that generate effects can also be initialized eagerly. The standard way is to use a simple Try<T> block, that contains already the evaluated value of type T. The Try class can have two subclasses: Success and Failure, that cover the successful execution, or the operation failure. The Try objects would be instantiated in a factory method: static <T> Try<T> of(Supplier<T> supplier) { try { return new Success<>(supplier.get()); } catch (Exception exception) { return new Failure<>(exception); } }
  • 32. Real world functional approach 32 The Try<T> class could expose standard “map” and “flat map” methods, that lift some operations on T type in the Try context: public interface Try<T> { ... Try<T> map(UnaryOperator<T> f); Try<T> flatMap(Function<T, Try<T>> f); … }
  • 33. Real world functional approach 33 The vehicle interface could look like: public interface Vehicle { Try<Vehicle> wakeUp(); Try<Vehicle> moveForward(Distance distance); Try<Vehicle> moveLeft(Distance distance); Try<Vehicle> moveRight(Distance distance); Try<Vehicle> stop(); }
  • 34. Real world functional approach 34 The vehicle moves can be modelled this way: MOVE_FORWARD = distance -> vehicle -> vehicle.moveForward(distance); MOVE_LEFT = distance -> vehicle -> vehicle.moveLeft(distance); START = Vehicle::wakeUp; STOP = Vehicle::stop; Try.<Vehicle>of(Vehicle.Default::new) .flatMap(START) .flatMap(MOVE_FORWARD.apply(Distance.THREE_METER)) .flatMap(MOVE_LEFT.apply(Distance.FIVE_METER)) .flatMap(MOVE_RIGHT.apply(Distance.TEN_METER)) .flatMap(STOP); The online repository contains an example. https://github.com/mw1980/oofunctionalexample/ package “functional/effects/basic”
  • 35. Real world functional approach ▰ Lazy Try blocks ▰ Simple Try blocks ▰ Try with errors 35
  • 36. Real world functional approach 36 In some cases it is important to return the exception that might occur. The system could be required to react differently, according to the exception type. The class Either can be used to store also the potential error: public class Either<T, V> { //injected in the constructor, mutual exclusive private final T left; //exception comes here, by convention private final V right; public static <T, V> Either<T, V> withLeftValue(final T value) {…} public static <T, V> Either<T, V> withRightValue(final V value) {…} }
  • 37. Real world functional approach 37 The Try class could be rewritten to consider also exceptions: public class TryWithError<T, U> { private final Function<T, U> f; public Either<RuntimeException, U> execute(T t) { try { return Either.withRightValue(f.apply(t));} catch (RuntimeException exception) { return Either.withLeftValue( new RuntimeException(“error message”, exception) ); }}}
  • 38. Real world functional approach 38 The code that performs the vehicle actions and returns also the exceptions that might occur would then look like: Either<RuntimeException, Vehicle> vehicleMoveResult = TryWithError.to(Vehicle::wakeUp) .andThen(v -> v.moveLeft(FIVE_METER)) ... .andThen(Vehicle::stop) .execute(someVehicleInstance)
  • 39. Real world functional approach 39 OO against FP, my two cents: The functional programming: + extremely compact + handles the exceptions gracefully + truly reusable design patterns - abstract - requires more discipline - it gets complex if it handles simultaneously more concerns, like handling exceptions and missing return values
  • 40. Real world functional approach 40 OO against FP, my two cents: Object oriented programming: + easier to understand + easier to extend + its design patterns are a great communications instrument + it is trivial to write unit tests + the “Gof” design patterns, like Command and Template communicate well the code intention. They are well known and generally accepted by the Java community
  • 41. Real world functional approach 41 OO against FP, my two cents: Object oriented programming: - explosion of classes - code verbosity - difficult to maintain the overview when using template classes, especially if the class inheritance hierarchy gets long
  • 42. Read more 42 More documentation: Functional and Reactive Domain Modeling (Debasish Gosh), Manning 2016 Functional Programming in Java (Pierre-Yves Saumont), Manning 2016 Vavr: http://www.vavr.io/ Eta lang: https://eta-lang.org/ Referential transparency: https://en.wikipedia.org/wiki/Referential_transparency Currying: https://hackernoon.com/functional-programming-paradigms-in-modern-javascript-currying-565 2e489cce8 Monoids: https://medium.com/@sjsyrek/five-minutes-to-monoid-fe6f364d0bba
  • 43. CREDITS Graphical content: ▰ Presentation template by SlidesCarnival ▰ Photographs by Startup Stock Photos 43