SlideShare a Scribd company logo
victor.rentea@gmail.com ♦ ♦ @victorrentea ♦ VictorRentea.ro
The Hitchhiker Guider to
Victor Rentea
Best Talks, Goodies, Blog:
VictorRentea.ro
Independent Trainer & Consultant
Founder of
Bucharest Software Craftsmanship Community
Java Champion
❤️ Simple Design, Refactoring, Unit Testing ❤️
Technical Training
Hibernate
Spring Func Prog in Java
300+ days
2000 devs
8 years
Training for you or your company: VictorRentea.ro
40 companies
Follow me:
35K 4K 3K
Java Performance
Reactive-X
Design Patterns
Clean Code
Refactoring
Unit Testing
TDD
any
lang
174 © VictorRentea.ro
a training by
Life
175 © VictorRentea.ro
a training by
checkCustomer(customer);
checkOrder(customer, order);
Mock-full tests
Race Bugs
A method changes a parameter: Surprise!
Unexpected Different Results for Same Inputs
customer.setActive(true);
Temporal Coupling
176 © VictorRentea.ro
a training by
do side-effects
return void sendEmail(Email):void
Command-Query Separation
setActive(true):void
return results
search(criteria):List
computePrice(flight):int
in 1994, by Bertrand Meyer
Pure Functions
177 © VictorRentea.ro
a training by
No side effects
No INSERTs, POSTs, queues, files, fields,…
= 𝑀𝑎𝑡ℎ𝑒𝑚𝑎𝑡𝑖𝑐𝑎𝑙 𝐹𝑢𝑛𝑐𝑡𝑖𝑜𝑛𝑠: 𝑓 𝑥, 𝑦 = 𝑥2
+ 𝑦
(logging doesn't count)
Referential Transparent
Same Inputs ➔ Same Output
No current time, random, GET, SELECT…
≠ Idempotent
Pure Functions
178 © VictorRentea.ro
a training by
Referential Transparent Idempotent
≠
f(1,2) = 3
f(1,2) can be replaced with 3 everywhere
After calling f once
Calling it again n times
will not produce any extra changes
Can Have Side Effects
eg: DELETE FROM X WHERE ID =
f(1,2)
f(1,2)
f(1,2)
179 © VictorRentea.ro
a training by
Pure Functions : Quiz
f1(int x) {return x + 1;}
f2(Data d) {return ++d.x;}
f3() {d.incrementX(); return d.x;}
f4() {return querySQL(...);}
f5(int y) { return this.x + y; }
f6(Data d, int y) { return d.getX() + y; }
f7(int i) { if (i<0) throw new WrongInputException(); }
is this immutable?
Probable side effects
Expected to be pure
180 © VictorRentea.ro
a training by
throw new E(); is pure
f(x) {
try {
//
}
}
catch (E) is pure?
if it always throws for the same inputs
it depends ...
* Some slightly disagree
on E
NO, if E can happen randomly
eg. IOException, OutOfMemory
YES, if E is thrown deterministically*
➔ Catch unexpected exceptions
in the outskirts of your code
181 © VictorRentea.ro
a training by
Why we Love Pure Functions
➢No hidden inputs, only plain-sight return values and parameters
➢Easier to understand
➢No temporal coupling
➢Testable with less setup
➢Fast & Composable: free to call them n times ➔
➢Parallelizable
(careful with instance functions on mutable objects)
r=f();
a=g(r);
182 © VictorRentea.ro
a training by
Replace Temp Variable with Query
If a function is pure + fast, it's safe to call it multiple times:
Replace Parameter with Query
var data = f(a,b);
data
data
f(a,b)
f(a,b)
big(..., f(a,b));
param
param
void big(..., param) {
f(a,b)
f(a,b)
they typically are
183 © VictorRentea.ro
a training by
you don't care how many times
(and if) you call a pure function
184 © VictorRentea.ro
a training by
185 © VictorRentea.ro
a training by
That's it!
I'll make all my functions pure
that's usually impossible
What kind of app doesn't change anything?
186 © VictorRentea.ro
a training by
In Java there's no way to strictly enforce purity
➔ We have to live with both pure and impure functions
How do we distinguish them?
187 © VictorRentea.ro
a training by
do side-effects
return void sendEmail(Email):void
Command-Query Separation
setActive(true):void
return results
pure functions
search():List
computePrice(movie):int
Highlight Side Effects
computePriceAndAdjustMetrics(movie):int
188 © VictorRentea.ro
a training by
You can do better!
189 © VictorRentea.ro
a training by
190 © VictorRentea.ro
a training by
functional core
Side-effects (Writes) +
Non-deterministic Reads
Expose them
Purify the most complex parts of your logic!
191 © VictorRentea.ro
a training by
Purify the most complex parts of your logic!
193 © VictorRentea.ro
a training by
Purifying Logic
Time and Random
Amount of time-dependent logic:
➢None (e.setCreationDate(now());) ➔ tolerate
➢Very little ➔ Inject a Clock / TimeProvider
➢Heavy (x-rare) ➔ expose a ..., time); parameter
194 © VictorRentea.ro
a training by
No Files in Functional Core
196 © VictorRentea.ro
a training by
Initial Read
Intermediary
(conditional?)
➔ Pass as Parameters
➔ Split-Phase Refactor f();
r=read();
f(r);
Writing Results ➔ Return Changes w=f();
persist(w);
r=read()
Expose DB and HTTP calls
imperative shell
197 © VictorRentea.ro
a training by
Expose DB and HTTP calls
Initial Read
Intermediary
(conditional?)
➔ Pass as Parameters
➔ Split-Phase Refactor
r=read();
f(r);
r1=phase1(...)
phase2(r,r1...)
expose impurity
Writing Results ➔ Return Changes w=f();
persist(w);
r=read()
imperative shell
Create new classes 💪
198 © VictorRentea.ro
a training by
Implement most complex logic
as internal pure functions
exposing impurity to the surface
199 © VictorRentea.ro
a training by
Pure Functions don't
Change Objects' State
Immutable Objects
200 © VictorRentea.ro
a training by
Immutable Objects
201 © VictorRentea.ro
a training by
void f(Data data) {
...
if (data.getX() == 1) {
// will this run ?
}
}
void h() {
Data data = new Data(1);
obj.setData(data);
g(data);
}
obj
void g(Data data) {
data.setX(2);
mutateParam(data);
obj.mutateField();
f(data);
}
void setData(Data data) {
this.data = data;
}
void mutateField() {
this.data.setX(2);
}
same obj
in h() and g()
void mutateParam(Data data) {
data.setX(1);
}
x=
Long-lived mutable data
A Code Inspection Session
What code ran before,
having a reference
to my data instance?!
Mutable Data
...
...
202 © VictorRentea.ro
a training by
void f(Data data) {
...
if (data.getX() == 1) {
// will this run ?
}
}
void h() {
Data data = new Data(1);
obj.setData(data);
g(data);
}
obj
void g(Data data) {
data.setX(2);
mutateParam(data);
obj.mutateField();
f(data);
}
void setData(Data data) {
this.data = data;
}
void mutateField() {
this.data.setX(2);
}
same obj
in h() and g()
void mutateParam(Data data) {
data.setX(1);
}
x=
Long-lived mutable data
A Code Inspection Session
What code ran before,
having a reference
to my data instance?!
Mutable Data
Immutable Data
...
...
203 © VictorRentea.ro
a training by
void f(Data data) {
...
if (data.getX() == 1) {
// will this run ?
}
}
void g(Data data) {
f(data);
}
void h() {
Data data = new Data(1);
g(data);
}
A Code Inspection Session
Immutable Data
Who created
the instance?!
Easier to trace
data changes
x=
204 © VictorRentea.ro
a training by
Designing Immutable Classes
public class A {
private final String s;
private final B b;
private final List<String> list;
public A(String s, B b, List<String> list) {
this.s = s;
this.b = b;
this.list = new ArrayList<>(list);
// validation ...
}
public List<String> getList() {
return unmodifiableList(list);
}
// getters
// hashCode, equals on all fields = Value Object
// bits of LOGIC 💪
public A withS(String newS) {
return new A(newS, b, list);
}
}
Mutates by creating a new instance
Stops creator keeping a reference
Overkill, as problem is not the creator but the "man-in-the-middle"
Oh, so
we CAN mutate them!
@lombok.With
Iterable<String> getList() {
List<? extends String> getList() {
or
final fields,
but not strictly required
record
(java 15)
Java collections are mutable😞
final
Afraid of hackers? 😨
@lombok.Value
or, until then...
205 © VictorRentea.ro
a training by
Oh, so
we CAN mutate them!
206 © VictorRentea.ro
a training by
A function changing an immutable object has to return it:
data = updx(data);
Imagine data
has 20 fields
... every time
data = updy(data);
data = updz(data);
The mess is still here!
🎵 Who changed the field X?
How to fix?
207 © VictorRentea.ro
a training by
data = updx(data);
data = updy(data);
data = updz(data);
final variables won't allow this
IntelliJ underlines
reassigned variables ❤️
By the way, there are ways to add final automatically at code cleanup
Real Problem
Too Large Immutable Objects
data.xyz = createXYZ(...);
➔ break them
If they change together,
they stick together
= clutter; Extreme:
Mark only the non-final with @Var
(errorprone Java compiler from Google)
208 © VictorRentea.ro
a training by
Wait a second,
I know...
209 © VictorRentea.ro
a training by
void f(VO[] arr) {
arr[0] = arr[0].withX(-99);
}
void f(List<String> list) {
list.removeIf(String::isBlank);
}
void f(Map<Integer, VO> map) {
map.put(1, map.get(1).withX(-99));
}
map.get(1).withX(-99)
210 © VictorRentea.ro
a training by
Don't
ever
mutate
collections!
➔ Create new ones
211 © VictorRentea.ro
a training by
Why we Immutable objects
Easier to trace data changes
Can enforce validation in constructor
Safe to put in Set or Map(as keys)
Thread-safe ➔ no race bugs, since they can't be changed
➔ their hashCode
doesn't change
212 © VictorRentea.ro
a training by
All right cowboy!
Only immutable objects from now on!
usually that's too much!
214 © VictorRentea.ro
a training by
instead,
Extract immutable Value Objects from their fields
Leaving the root Entity mutable
NO*
*there are few cases when it pays to, but those apps typically don't persist their data
Should Entities be immutable?
215 © VictorRentea.ro
a training by
@Entity
(mutable)
Persistent
Immutable Leaf
eg. FullName
Immutable Objects in Real Life
Non-Persistent
Runtime Objects
that you write heavy logic with
continuously break
Large Entities
@Embeddable
216 © VictorRentea.ro
a training by
Non-Persistent
Runtime Objects
that you write heavy logic with
Always Immutable
218 © VictorRentea.ro
a training by
The Big Deal
219 © VictorRentea.ro
a training by
The Big Deal
Don't mutate objects on long workflows!
a(e) b(x) c(x) d(x) e(x) f(x) g(e) {
e.setField(...);
}
a(e) {
String s = b(vo);
e.setField(s);
}
b(…) c(…) d(…) e(…) f(…) g(…) {return ...;}
1) vavr.Tuple3<String,String,Integer>
2) NewConceptVO #kudos if you can find a good name!
can be pure functions
Immutable Arguments
Return the change to the surface, and apply it there
Return multiple changes:
220 © VictorRentea.ro
a training by
The Big Deal
Is when immutable objects travel lots of code
221 © VictorRentea.ro
a training by
Performance of Immutability
222 © VictorRentea.ro
a training by
Concerned of Performance?
Measure it !
(and you might have a surprise)
224 © VictorRentea.ro
a training by
Avoid Immutable Objects If
- Trashing millions of instances/second
- Cloning Lost of Collections
- Trivial logic (overkill)
- Persistent Entities or DTOs
225 © VictorRentea.ro
a training by
Take-Aways
➢ Complex logic ➔ pure functions using immutable objects
➢ Functional Core / Imperative Shell
➢ Pull impure remote/DB calls in the shell
➢ We'll change it in there ➔ compute and return
➢ Without proper mindset, immutability can hurt
➢ Don't mutate: argument state, variables or collections
➢ Immutable: runtime data or persistent leaves
➢ We'll change it in there ➔ compute and return
And no, I'm against OOP; but not in huge logic code ➔
226 © VictorRentea.ro
a training by
victorrentea@gmail.com ♦ ♦ Training: VictorRentea.ro
➢We'll change it in there ➔ compute and return

More Related Content

PDF
Pure Functions and Immutable Objects
PDF
The Art of Unit Testing - Towards a Testable Design
PDF
Definitive Guide to Working With Exceptions in Java - takj at Java Champions ...
PDF
Integration testing with spring @snow one
PDF
Evolving a Clean, Pragmatic Architecture at JBCNConf 2019
PDF
Integration testing with spring @JAX Mainz
PDF
Don't Be Mocked by your Mocks - Best Practices using Mocks
PDF
The Proxy Fairy and the Magic of Spring @JAX Mainz 2021
Pure Functions and Immutable Objects
The Art of Unit Testing - Towards a Testable Design
Definitive Guide to Working With Exceptions in Java - takj at Java Champions ...
Integration testing with spring @snow one
Evolving a Clean, Pragmatic Architecture at JBCNConf 2019
Integration testing with spring @JAX Mainz
Don't Be Mocked by your Mocks - Best Practices using Mocks
The Proxy Fairy and the Magic of Spring @JAX Mainz 2021

What's hot (20)

PDF
Evolving a Clean, Pragmatic Architecture - A Craftsman's Guide
PDF
Definitive Guide to Working With Exceptions in Java
PDF
Clean pragmatic architecture @ devflix
PDF
Hibernate and Spring - Unleash the Magic
PDF
Unit Testing like a Pro - The Circle of Purity
PDF
Clean Lambdas & Streams in Java8
PDF
Refactoring Games - 15 things to do after Extract Method
PDF
關於測試,我說的其實是......
PDF
Pharo Optimising JIT Internals
PDF
Frege - consequently functional programming for the JVM
PPTX
TDD Training
PPTX
The Art of Clean code
PDF
Ad-hoc Runtime Object Structure Visualizations with MetaLinks
PDF
Frege Tutorial at JavaOne 2015
PDF
Testing most things in JavaScript - LeedsJS 31/05/2017
PDF
Code lifecycle in the jvm - TopConf Linz
ODP
Intro To Spring Python
PDF
JavaScript Test-Driven Development with Jasmine 2.0 and Karma
PDF
What to expect from Java 9
PDF
AOP in Python API design
Evolving a Clean, Pragmatic Architecture - A Craftsman's Guide
Definitive Guide to Working With Exceptions in Java
Clean pragmatic architecture @ devflix
Hibernate and Spring - Unleash the Magic
Unit Testing like a Pro - The Circle of Purity
Clean Lambdas & Streams in Java8
Refactoring Games - 15 things to do after Extract Method
關於測試,我說的其實是......
Pharo Optimising JIT Internals
Frege - consequently functional programming for the JVM
TDD Training
The Art of Clean code
Ad-hoc Runtime Object Structure Visualizations with MetaLinks
Frege Tutorial at JavaOne 2015
Testing most things in JavaScript - LeedsJS 31/05/2017
Code lifecycle in the jvm - TopConf Linz
Intro To Spring Python
JavaScript Test-Driven Development with Jasmine 2.0 and Karma
What to expect from Java 9
AOP in Python API design
Ad

Similar to Pure functions and immutable objects @dev nexus 2021 (20)

ODP
Java 5 6 Generics, Concurrency, Garbage Collection, Tuning
PDF
Unit testing - 9 design hints
ODP
Java Generics
PPTX
EcmaScript unchained
PDF
FP in Java - Project Lambda and beyond
PPT
Groovy Introduction - JAX Germany - 2008
PDF
T3chFest 2016 - The polyglot programmer
ODP
Building and Incredible Machine with Pipelines and Generators in PHP (IPC Ber...
ODP
The why and how of moving to php 5.4/5.5
PPTX
C++ theory
PDF
How do you create a programming language for the JVM?
PPTX
NDC 2011, C++ 프로그래머를 위한 C#
PPTX
Working effectively with legacy code
PDF
ES6 - Next Generation Javascript
PDF
Evolving The Java Language
ODP
The craft of meta programming on JVM
PDF
Silicon Valley JUG: JVM Mechanics
PDF
function* - ES6, generators, and all that (JSRomandie meetup, February 2014)
PPT
Java Performance Tuning
PDF
JVM Mechanics: When Does the JVM JIT & Deoptimize?
Java 5 6 Generics, Concurrency, Garbage Collection, Tuning
Unit testing - 9 design hints
Java Generics
EcmaScript unchained
FP in Java - Project Lambda and beyond
Groovy Introduction - JAX Germany - 2008
T3chFest 2016 - The polyglot programmer
Building and Incredible Machine with Pipelines and Generators in PHP (IPC Ber...
The why and how of moving to php 5.4/5.5
C++ theory
How do you create a programming language for the JVM?
NDC 2011, C++ 프로그래머를 위한 C#
Working effectively with legacy code
ES6 - Next Generation Javascript
Evolving The Java Language
The craft of meta programming on JVM
Silicon Valley JUG: JVM Mechanics
function* - ES6, generators, and all that (JSRomandie meetup, February 2014)
Java Performance Tuning
JVM Mechanics: When Does the JVM JIT & Deoptimize?
Ad

More from Victor Rentea (20)

PDF
Top REST API Desgin Pitfalls @ Devoxx 2024
PDF
The Joy of Testing - Deep Dive @ Devoxx Belgium 2024
PDF
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
PDF
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
PDF
Microservice Resilience Patterns @VoxxedCern'24
PDF
Distributed Consistency.pdf
PDF
Clean Code @Voxxed Days Cluj 2023 - opening Keynote
PDF
Testing Microservices @DevoxxBE 23.pdf
PPTX
From Web to Flux @DevoxxBE 2023.pptx
PPTX
Test-Driven Design Insights@DevoxxBE 2023.pptx
PDF
Profiling your Java Application
PPTX
OAuth in the Wild
PPTX
The tests are trying to tell you something@VoxxedBucharest.pptx
PPTX
Vertical Slicing Architectures
PDF
Software Craftsmanship @Code Camp Festival 2022.pdf
PPTX
Extreme Professionalism - Software Craftsmanship
PDF
Clean architecture - Protecting the Domain
PDF
Refactoring blockers and code smells @jNation 2021
PDF
TDD Mantra
PDF
Extreme Professionalism - Software Craftsmanship
Top REST API Desgin Pitfalls @ Devoxx 2024
The Joy of Testing - Deep Dive @ Devoxx Belgium 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Microservice Resilience Patterns @VoxxedCern'24
Distributed Consistency.pdf
Clean Code @Voxxed Days Cluj 2023 - opening Keynote
Testing Microservices @DevoxxBE 23.pdf
From Web to Flux @DevoxxBE 2023.pptx
Test-Driven Design Insights@DevoxxBE 2023.pptx
Profiling your Java Application
OAuth in the Wild
The tests are trying to tell you something@VoxxedBucharest.pptx
Vertical Slicing Architectures
Software Craftsmanship @Code Camp Festival 2022.pdf
Extreme Professionalism - Software Craftsmanship
Clean architecture - Protecting the Domain
Refactoring blockers and code smells @jNation 2021
TDD Mantra
Extreme Professionalism - Software Craftsmanship

Recently uploaded (20)

PPTX
CH1 Production IntroductoryConcepts.pptx
PPTX
FINAL REVIEW FOR COPD DIANOSIS FOR PULMONARY DISEASE.pptx
PPTX
UNIT 4 Total Quality Management .pptx
PPTX
Geodesy 1.pptx...............................................
PPTX
Welding lecture in detail for understanding
PPTX
MCN 401 KTU-2019-PPE KITS-MODULE 2.pptx
PDF
TFEC-4-2020-Design-Guide-for-Timber-Roof-Trusses.pdf
PDF
Digital Logic Computer Design lecture notes
PPTX
KTU 2019 -S7-MCN 401 MODULE 2-VINAY.pptx
PPTX
Foundation to blockchain - A guide to Blockchain Tech
PPTX
OOP with Java - Java Introduction (Basics)
PPT
Mechanical Engineering MATERIALS Selection
PPT
CRASH COURSE IN ALTERNATIVE PLUMBING CLASS
PDF
Mohammad Mahdi Farshadian CV - Prospective PhD Student 2026
PDF
PRIZ Academy - 9 Windows Thinking Where to Invest Today to Win Tomorrow.pdf
PPTX
additive manufacturing of ss316l using mig welding
PPTX
web development for engineering and engineering
PPTX
MET 305 2019 SCHEME MODULE 2 COMPLETE.pptx
PDF
SM_6th-Sem__Cse_Internet-of-Things.pdf IOT
PPTX
Sustainable Sites - Green Building Construction
CH1 Production IntroductoryConcepts.pptx
FINAL REVIEW FOR COPD DIANOSIS FOR PULMONARY DISEASE.pptx
UNIT 4 Total Quality Management .pptx
Geodesy 1.pptx...............................................
Welding lecture in detail for understanding
MCN 401 KTU-2019-PPE KITS-MODULE 2.pptx
TFEC-4-2020-Design-Guide-for-Timber-Roof-Trusses.pdf
Digital Logic Computer Design lecture notes
KTU 2019 -S7-MCN 401 MODULE 2-VINAY.pptx
Foundation to blockchain - A guide to Blockchain Tech
OOP with Java - Java Introduction (Basics)
Mechanical Engineering MATERIALS Selection
CRASH COURSE IN ALTERNATIVE PLUMBING CLASS
Mohammad Mahdi Farshadian CV - Prospective PhD Student 2026
PRIZ Academy - 9 Windows Thinking Where to Invest Today to Win Tomorrow.pdf
additive manufacturing of ss316l using mig welding
web development for engineering and engineering
MET 305 2019 SCHEME MODULE 2 COMPLETE.pptx
SM_6th-Sem__Cse_Internet-of-Things.pdf IOT
Sustainable Sites - Green Building Construction

Pure functions and immutable objects @dev nexus 2021

  • 1. victor.rentea@gmail.com ♦ ♦ @victorrentea ♦ VictorRentea.ro The Hitchhiker Guider to
  • 2. Victor Rentea Best Talks, Goodies, Blog: VictorRentea.ro Independent Trainer & Consultant Founder of Bucharest Software Craftsmanship Community Java Champion ❤️ Simple Design, Refactoring, Unit Testing ❤️
  • 3. Technical Training Hibernate Spring Func Prog in Java 300+ days 2000 devs 8 years Training for you or your company: VictorRentea.ro 40 companies Follow me: 35K 4K 3K Java Performance Reactive-X Design Patterns Clean Code Refactoring Unit Testing TDD any lang
  • 4. 174 © VictorRentea.ro a training by Life
  • 5. 175 © VictorRentea.ro a training by checkCustomer(customer); checkOrder(customer, order); Mock-full tests Race Bugs A method changes a parameter: Surprise! Unexpected Different Results for Same Inputs customer.setActive(true); Temporal Coupling
  • 6. 176 © VictorRentea.ro a training by do side-effects return void sendEmail(Email):void Command-Query Separation setActive(true):void return results search(criteria):List computePrice(flight):int in 1994, by Bertrand Meyer Pure Functions
  • 7. 177 © VictorRentea.ro a training by No side effects No INSERTs, POSTs, queues, files, fields,… = 𝑀𝑎𝑡ℎ𝑒𝑚𝑎𝑡𝑖𝑐𝑎𝑙 𝐹𝑢𝑛𝑐𝑡𝑖𝑜𝑛𝑠: 𝑓 𝑥, 𝑦 = 𝑥2 + 𝑦 (logging doesn't count) Referential Transparent Same Inputs ➔ Same Output No current time, random, GET, SELECT… ≠ Idempotent Pure Functions
  • 8. 178 © VictorRentea.ro a training by Referential Transparent Idempotent ≠ f(1,2) = 3 f(1,2) can be replaced with 3 everywhere After calling f once Calling it again n times will not produce any extra changes Can Have Side Effects eg: DELETE FROM X WHERE ID = f(1,2) f(1,2) f(1,2)
  • 9. 179 © VictorRentea.ro a training by Pure Functions : Quiz f1(int x) {return x + 1;} f2(Data d) {return ++d.x;} f3() {d.incrementX(); return d.x;} f4() {return querySQL(...);} f5(int y) { return this.x + y; } f6(Data d, int y) { return d.getX() + y; } f7(int i) { if (i<0) throw new WrongInputException(); } is this immutable? Probable side effects Expected to be pure
  • 10. 180 © VictorRentea.ro a training by throw new E(); is pure f(x) { try { // } } catch (E) is pure? if it always throws for the same inputs it depends ... * Some slightly disagree on E NO, if E can happen randomly eg. IOException, OutOfMemory YES, if E is thrown deterministically* ➔ Catch unexpected exceptions in the outskirts of your code
  • 11. 181 © VictorRentea.ro a training by Why we Love Pure Functions ➢No hidden inputs, only plain-sight return values and parameters ➢Easier to understand ➢No temporal coupling ➢Testable with less setup ➢Fast & Composable: free to call them n times ➔ ➢Parallelizable (careful with instance functions on mutable objects) r=f(); a=g(r);
  • 12. 182 © VictorRentea.ro a training by Replace Temp Variable with Query If a function is pure + fast, it's safe to call it multiple times: Replace Parameter with Query var data = f(a,b); data data f(a,b) f(a,b) big(..., f(a,b)); param param void big(..., param) { f(a,b) f(a,b) they typically are
  • 13. 183 © VictorRentea.ro a training by you don't care how many times (and if) you call a pure function
  • 15. 185 © VictorRentea.ro a training by That's it! I'll make all my functions pure that's usually impossible What kind of app doesn't change anything?
  • 16. 186 © VictorRentea.ro a training by In Java there's no way to strictly enforce purity ➔ We have to live with both pure and impure functions How do we distinguish them?
  • 17. 187 © VictorRentea.ro a training by do side-effects return void sendEmail(Email):void Command-Query Separation setActive(true):void return results pure functions search():List computePrice(movie):int Highlight Side Effects computePriceAndAdjustMetrics(movie):int
  • 18. 188 © VictorRentea.ro a training by You can do better!
  • 20. 190 © VictorRentea.ro a training by functional core Side-effects (Writes) + Non-deterministic Reads Expose them Purify the most complex parts of your logic!
  • 21. 191 © VictorRentea.ro a training by Purify the most complex parts of your logic!
  • 22. 193 © VictorRentea.ro a training by Purifying Logic Time and Random Amount of time-dependent logic: ➢None (e.setCreationDate(now());) ➔ tolerate ➢Very little ➔ Inject a Clock / TimeProvider ➢Heavy (x-rare) ➔ expose a ..., time); parameter
  • 23. 194 © VictorRentea.ro a training by No Files in Functional Core
  • 24. 196 © VictorRentea.ro a training by Initial Read Intermediary (conditional?) ➔ Pass as Parameters ➔ Split-Phase Refactor f(); r=read(); f(r); Writing Results ➔ Return Changes w=f(); persist(w); r=read() Expose DB and HTTP calls imperative shell
  • 25. 197 © VictorRentea.ro a training by Expose DB and HTTP calls Initial Read Intermediary (conditional?) ➔ Pass as Parameters ➔ Split-Phase Refactor r=read(); f(r); r1=phase1(...) phase2(r,r1...) expose impurity Writing Results ➔ Return Changes w=f(); persist(w); r=read() imperative shell Create new classes 💪
  • 26. 198 © VictorRentea.ro a training by Implement most complex logic as internal pure functions exposing impurity to the surface
  • 27. 199 © VictorRentea.ro a training by Pure Functions don't Change Objects' State Immutable Objects
  • 28. 200 © VictorRentea.ro a training by Immutable Objects
  • 29. 201 © VictorRentea.ro a training by void f(Data data) { ... if (data.getX() == 1) { // will this run ? } } void h() { Data data = new Data(1); obj.setData(data); g(data); } obj void g(Data data) { data.setX(2); mutateParam(data); obj.mutateField(); f(data); } void setData(Data data) { this.data = data; } void mutateField() { this.data.setX(2); } same obj in h() and g() void mutateParam(Data data) { data.setX(1); } x= Long-lived mutable data A Code Inspection Session What code ran before, having a reference to my data instance?! Mutable Data ... ...
  • 30. 202 © VictorRentea.ro a training by void f(Data data) { ... if (data.getX() == 1) { // will this run ? } } void h() { Data data = new Data(1); obj.setData(data); g(data); } obj void g(Data data) { data.setX(2); mutateParam(data); obj.mutateField(); f(data); } void setData(Data data) { this.data = data; } void mutateField() { this.data.setX(2); } same obj in h() and g() void mutateParam(Data data) { data.setX(1); } x= Long-lived mutable data A Code Inspection Session What code ran before, having a reference to my data instance?! Mutable Data Immutable Data ... ...
  • 31. 203 © VictorRentea.ro a training by void f(Data data) { ... if (data.getX() == 1) { // will this run ? } } void g(Data data) { f(data); } void h() { Data data = new Data(1); g(data); } A Code Inspection Session Immutable Data Who created the instance?! Easier to trace data changes x=
  • 32. 204 © VictorRentea.ro a training by Designing Immutable Classes public class A { private final String s; private final B b; private final List<String> list; public A(String s, B b, List<String> list) { this.s = s; this.b = b; this.list = new ArrayList<>(list); // validation ... } public List<String> getList() { return unmodifiableList(list); } // getters // hashCode, equals on all fields = Value Object // bits of LOGIC 💪 public A withS(String newS) { return new A(newS, b, list); } } Mutates by creating a new instance Stops creator keeping a reference Overkill, as problem is not the creator but the "man-in-the-middle" Oh, so we CAN mutate them! @lombok.With Iterable<String> getList() { List<? extends String> getList() { or final fields, but not strictly required record (java 15) Java collections are mutable😞 final Afraid of hackers? 😨 @lombok.Value or, until then...
  • 33. 205 © VictorRentea.ro a training by Oh, so we CAN mutate them!
  • 34. 206 © VictorRentea.ro a training by A function changing an immutable object has to return it: data = updx(data); Imagine data has 20 fields ... every time data = updy(data); data = updz(data); The mess is still here! 🎵 Who changed the field X? How to fix?
  • 35. 207 © VictorRentea.ro a training by data = updx(data); data = updy(data); data = updz(data); final variables won't allow this IntelliJ underlines reassigned variables ❤️ By the way, there are ways to add final automatically at code cleanup Real Problem Too Large Immutable Objects data.xyz = createXYZ(...); ➔ break them If they change together, they stick together = clutter; Extreme: Mark only the non-final with @Var (errorprone Java compiler from Google)
  • 36. 208 © VictorRentea.ro a training by Wait a second, I know...
  • 37. 209 © VictorRentea.ro a training by void f(VO[] arr) { arr[0] = arr[0].withX(-99); } void f(List<String> list) { list.removeIf(String::isBlank); } void f(Map<Integer, VO> map) { map.put(1, map.get(1).withX(-99)); } map.get(1).withX(-99)
  • 38. 210 © VictorRentea.ro a training by Don't ever mutate collections! ➔ Create new ones
  • 39. 211 © VictorRentea.ro a training by Why we Immutable objects Easier to trace data changes Can enforce validation in constructor Safe to put in Set or Map(as keys) Thread-safe ➔ no race bugs, since they can't be changed ➔ their hashCode doesn't change
  • 40. 212 © VictorRentea.ro a training by All right cowboy! Only immutable objects from now on! usually that's too much!
  • 41. 214 © VictorRentea.ro a training by instead, Extract immutable Value Objects from their fields Leaving the root Entity mutable NO* *there are few cases when it pays to, but those apps typically don't persist their data Should Entities be immutable?
  • 42. 215 © VictorRentea.ro a training by @Entity (mutable) Persistent Immutable Leaf eg. FullName Immutable Objects in Real Life Non-Persistent Runtime Objects that you write heavy logic with continuously break Large Entities @Embeddable
  • 43. 216 © VictorRentea.ro a training by Non-Persistent Runtime Objects that you write heavy logic with Always Immutable
  • 44. 218 © VictorRentea.ro a training by The Big Deal
  • 45. 219 © VictorRentea.ro a training by The Big Deal Don't mutate objects on long workflows! a(e) b(x) c(x) d(x) e(x) f(x) g(e) { e.setField(...); } a(e) { String s = b(vo); e.setField(s); } b(…) c(…) d(…) e(…) f(…) g(…) {return ...;} 1) vavr.Tuple3<String,String,Integer> 2) NewConceptVO #kudos if you can find a good name! can be pure functions Immutable Arguments Return the change to the surface, and apply it there Return multiple changes:
  • 46. 220 © VictorRentea.ro a training by The Big Deal Is when immutable objects travel lots of code
  • 47. 221 © VictorRentea.ro a training by Performance of Immutability
  • 48. 222 © VictorRentea.ro a training by Concerned of Performance? Measure it ! (and you might have a surprise)
  • 49. 224 © VictorRentea.ro a training by Avoid Immutable Objects If - Trashing millions of instances/second - Cloning Lost of Collections - Trivial logic (overkill) - Persistent Entities or DTOs
  • 50. 225 © VictorRentea.ro a training by Take-Aways ➢ Complex logic ➔ pure functions using immutable objects ➢ Functional Core / Imperative Shell ➢ Pull impure remote/DB calls in the shell ➢ We'll change it in there ➔ compute and return ➢ Without proper mindset, immutability can hurt ➢ Don't mutate: argument state, variables or collections ➢ Immutable: runtime data or persistent leaves ➢ We'll change it in there ➔ compute and return And no, I'm against OOP; but not in huge logic code ➔
  • 51. 226 © VictorRentea.ro a training by victorrentea@gmail.com ♦ ♦ Training: VictorRentea.ro ➢We'll change it in there ➔ compute and return