if you think you can stay away from functional programming, you are wrong
DESCRIPTION
TRANSCRIPT
![Page 1: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/1.jpg)
by Mario [email protected]: @mariofusco
![Page 2: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/2.jpg)
Moore's
law
The number of transistors on integrated
circuits doubles approximately every two years
![Page 3: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/3.jpg)
Moore's
law
The number of transistors on integrated
circuits doubles approximately every two years
Now achieved
by increasing
the number
of cores
![Page 4: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/4.jpg)
Moore's
law
The number of transistors on integrated
circuits doubles approximately every two years
Now achieved
by increasing
the number
of cores
![Page 5: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/5.jpg)
Fortran
C / C++Java
Lisp
MLHaskell
Add abstractions
C#
Algol
Subtract abstractions
Imperative languages
Functional languages
Scala
F#
Hybrid languages
![Page 6: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/6.jpg)
Amdahl's
law
The speedup of a program using multiple processors
in parallel computing is limited by the time needed
for the sequential fraction of the program
![Page 7: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/7.jpg)
Concurrency & Parallelism
Parallel programmingRunning multiple tasks at
the same time
Concurrent programmingManaging concurrent requests
Both are hard!
![Page 8: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/8.jpg)
The cause of the problem …
Mutable state +
Parallel processing =
Non-determinism
![Page 9: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/9.jpg)
The cause of the problem …
Mutable state +
Parallel processing =
Non-determinism
Functional
Programming
![Page 10: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/10.jpg)
Race conditions
Deadlocks
Starvation
Livelocks
… and its effects
![Page 11: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/11.jpg)
Too hard to think about them!
Race conditions
Deadlocks
Starvation
Livelocks
… and its effects
![Page 12: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/12.jpg)
The native Java concurrency model
Based on:
They are sometimes plain evil …
… and sometimes a necessary pain …
… but always the wrong default
Threads
Semaphores
SynchronizationLocks
![Page 13: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/13.jpg)
Different concurrency models
Isolated mutable state (actors)
Purely immutable (pure functions)
Shared mutable state
(threads + locks)
![Page 14: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/14.jpg)
Summing attendants ages (Threads)
class Blackboard {
int sum = 0;
int read() { return sum; }
void write(int value) { sum = value; }
}
class Attendant implements Runnable {
int age;
Blackboard blackboard;
public void run() {
synchronized(blackboard) {
int oldSum = blackboard.read();
int newSum = oldSum + age;
blackboard.write(newSum);
}
}
}
![Page 15: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/15.jpg)
Summing attendants ages (Actors)
class Blackboard extends UntypedActors {
int sum = 0;
public void onReceive(Object message) {
if (message instanceof Integer) {
sum += (Integer)message;
}
}
} class Attendant {
int age;
Blackboard blackboard;
public void sendAge() {
blackboard.sendOneWay(age);
}
}
![Page 16: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/16.jpg)
Summing attendants ages (Functional)
class Blackboard {
final int sum;
Blackboard(int sum) { this.sum = sum; }
}
class Attendant {
int age;
Attendant next;
public Blackboard addMyAge(Blackboard blackboard) {
final Blackboard b = new Blackboard(blackboard.sum + age);
return next == null ? b : next.myAge(b);
}
}
![Page 17: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/17.jpg)
The state quadrantsMutable
Immutable
Shared
Unshared
Actors
Functional
Programming
Threads
Concurrency friendly
Concurrency unfriendly
![Page 18: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/18.jpg)
OOP makes code understandable
by encapsulating moving parts
FP makes code understandable
by minimizing moving parts
- Michael Feathers
OOP vs FP
![Page 19: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/19.jpg)
The OOP/FP dualism - OOPpublic class Bird { }
public class Cat {
private Bird catch;
private boolean full;
public void capture(Bird bird) {
catch = bird;
}
public void eat() {
full = true;
catch = null;
}
}
Cat cat = new Cat();
Bird bird = new Bird();
cat.capture(bird);
cat.eat();
The story
![Page 20: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/20.jpg)
The OOP/FP dualism - FPpublic class Bird { }
public class Cat {
public CatWithCatch capture(Bird bird) { return new CatWithCatch(bird); }
}
public class CatWithCatch {
private final Bird catch;
public CatWithCatch(Bird bird) { catch = bird; }
public FullCat eat() { return new FullCat(); }
}
public class FullCat { }
BiFunction<Cat, Bird, FullCat> story =
((BiFunction<Cat, Bird, CatWithCatch>)Cat::capture)
.compose(CatWithCatch::eat);
FullCat fullCat = story.apply( new Cat(), new Bird() );
![Page 21: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/21.jpg)
The OOP/FP dualism - FPpublic class Bird { }
public class Cat {
public CatWithCatch capture(Bird bird) { return new CatWithCatch(bird); }
}
public class CatWithCatch {
private final Bird catch;
public CatWithCatch(Bird bird) { catch = bird; }
public FullCat eat() { return new FullCat(); }
}
public class FullCat { }
BiFunction<Cat, Bird, FullCat> story =
((BiFunction<Cat, Bird, CatWithCatch>)Cat::capture)
.compose(CatWithCatch::eat);
FullCat fullCat = story.apply( new Cat(), new Bird() );
Immutability
Emphasis on verbs
instead of names
No need to test internal state: correctness enforced by the compiler
![Page 22: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/22.jpg)
for (Employee e : employees) {
e.setSalary(e.getSalary() * 1.03);
}
employees.forEach(e -> e.setSalary(e.getSalary() * 1.03));
Inherently serial
Client has to manage iteration
Nested loops are poorly readable
+ Library is in control � opportunity for internal optimizations as parallelization,
lazy evaluation, out-of-order execution
+ More what, less how � better readability
+ Fluent (pipelined) operations � better readability
+ Client can pass behaviors into the API as data �
possibility to abstract and generalize over behavior �
more powerful, expressive APIs
Not only a syntactic change!
Internal vs External Iteration
![Page 23: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/23.jpg)
� Encourages a pipelined ( "fluent" ) usage style
� Operations are divided between intermediate and terminal
� Lazy in nature: only terminal operations actually trigger a computation
employees.stream()
.filter(e -> e.getIncome() > 50000)
.map(e -> e.getName())
.forEach(System.out::println);
Streams - Efficiency with laziness
![Page 24: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/24.jpg)
� Encourages a pipelined ( "fluent" ) usage style
� Operations are divided between intermediate and terminal
� Lazy in nature: only terminal operations actually trigger a computation
employees.stream()
.filter(e -> e.getIncome() > 50000)
.map(e -> e.getName())
.forEach(System.out::println);
parallelStream()
… and parallelism for free
Streams - Efficiency with laziness
![Page 25: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/25.jpg)
Is there such thing as a free lunch?
![Page 26: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/26.jpg)
Probably yes …
… but we need functional
forks and knives to eat it
![Page 27: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/27.jpg)
�Reassigning a variable
�Modifying a data structure in place
� Setting a field on an object
� Throwing an exception or halting with an error
�Printing to the console
�Reading user input
�Reading from or writing to a file
�Drawing on the screen
A program created using only pure functions
What is a functional program?
No side effects allowed like:
Functional programming is a restriction on how we
write programs, but not on what they can do
}}
![Page 28: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/28.jpg)
What is a (pure) function?
A function with input type A and output type B
is a computation which relates every value a of
type A to exactly one value b of type B such
that b is determined solely by the value of a
But, if it really is a
function, it will do
nothing else
![Page 29: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/29.jpg)
Referential transparency
An expression e is referentially transparent if for all programs p,
all occurrences of e in p can be replaced by the result of
evaluating e, without affecting the observable behavior of p
A function f is pure if the expression f(x) is referentially
transparent for all referentially transparent x
![Page 30: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/30.jpg)
RTString x = "purple";
String r1 = x.replace('p', 't');
String r2 = x.replace('p', 't');
String r1 = "purple".replace('p', 't');
r1: "turtle"
String r2 = "purple".replace('p', 't');
r2: "turtle"
StringBuilder x = new StringBuilder("Hi");
StringBuilder y = x.append(", mom");
String r1 = y.toString();
String r2 = y.toString();
String r1 = x.append(", mom").toString();
r1: "Hi, mom"
String r2 = x.append(", mom").toString();
r1: "Hi, mom, mom"
Non-RT
vs.
![Page 31: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/31.jpg)
RT wins
�Under a developer point of view:
� Easier to reason about since effects of evaluation are
purely local
�Use of the substitution model: it's possible to replace a
term with an equivalent one
�Under a performance point of view:
� The JVM is free to optimize the code by safely reordering
the instructions
�No need to synchronize access to shared data
�Possible to cache the result of time consuming functions
(memoization), e.g. with
Map.computeIfAbsent(K key,
Function<? super K,? extends V> mappingFunction)
![Page 32: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/32.jpg)
Mutability
�Parameter binding is about assigning names to things
�Mutating variables is about assigning things to names
Does that second
one sound weird?
… well it's because
it IS weird
![Page 33: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/33.jpg)
Immutability
� Immutable objects can be shared among
many threads exactly because none of
them can modify it
� In the same way immutable (persistent)
data structures can be shared without any
need to synchronize the different threads
accessing them
![Page 34: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/34.jpg)
5
8
7 9
3
4
EEEEE E
E
Persistent Collections
![Page 35: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/35.jpg)
5
8
7 9
3
4
EEEEE E
E
2
Persistent Collections
![Page 36: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/36.jpg)
5
8
7 9
3
4
EEEEE E
E
5
3
2
EE
Persistent Collections
![Page 37: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/37.jpg)
5
8
7 9
3
4
EEEEE E
E
5
3
2
EE
Shared data
Old Root
New Root
Persistent Collections
![Page 38: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/38.jpg)
Modularityclass Player {
String name;
int score;
}
public void declareWinner(Player p) {
System.out.println(p.name + " wins!");
}
public void winner(Player p1, Player p2) {
if (p1.score > p2.score) declareWinner(p1)
else declareWinner(p2);
}
![Page 39: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/39.jpg)
Modularityclass Player {
String name;
int score;
}
public void declareWinner(Player p) {
System.out.println(p.name + " wins!");
}
public void winner(Player p1, Player p2) {
if (p1.score > p2.score) declareWinner(p1)
else declareWinner(p2);
}
public Player maxScore(Player p1, Player p2) {
return p1.score > p2.score ? p1 : p2;
}
public void winner(Player p1, Player p2) {
declareWinner(maxScore(p1, p2));
}
Separate
computational logic
from side effects
![Page 40: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/40.jpg)
Modularityclass Player {
String name;
int score;
}
public void declareWinner(Player p) {
System.out.println(p.name + " wins!");
}
public void winner(Player p1, Player p2) {
if (p1.score > p2.score) declareWinner(p1)
else declareWinner(p2);
}
public Player maxScore(Player p1, Player p2) {
return p1.score > p2.score ? p1 : p2;
}
public void winner(Player p1, Player p2) {
declareWinner(maxScore(p1, p2));
}
Separate
computational logic
from side effects
declareWinner(players.reduce(maxScore).get())
reuse maxScore to compute the winner among a list of players
![Page 41: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/41.jpg)
A pure functional core
functional
core
Any function with side-effects can be split into a pure function at the
core and a pair of functions with side-effect. This transformation can
be repeated to push side-effects to the outer layers of the program.
![Page 42: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/42.jpg)
Key Takeaways
� Strive for immutability
� Confine side-effects
� Avoid blocking code
� Cede control with higher-order functions
� Leverage referential transparency
� Use FP to design more composable and reusable API
… but there are no dogmas
� Be pragmatic and use the right tool for the job at hand
Poly-paradigm programming is more powerful
and effective than polyglot programming
![Page 43: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/43.jpg)
![Page 44: If You Think You Can Stay Away from Functional Programming, You Are Wrong](https://reader035.vdocument.in/reader035/viewer/2022081516/54b7376c4a7959454e8b4628/html5/thumbnails/44.jpg)
Mario Fusco
Red Hat – Senior Software Engineer
twitter: @mariofusco
Q A
Thanks … Questions?