SlideShare a Scribd company logo
1 of 46
Download to read offline
victor.rentea@gmail.com ♦ ♦ @victorrentea ♦ VictorRentea.ro
The Hitchhiker Guider to
Victor Rentea
Best Talks:
VictorRentea.ro
Independent Trainer & Consultant
Founder of
Bucharest Software Craftsmanship Community
Java Champion
❤️ Simple Design, Refactoring, Unit Testing ❤️
Technical Training
HibernateSpring Func Prog in Java
300+ days2000 devs8 years
Details for you or your company: VictorRentea.ro
40 companies
Follow me:
35K 4K 3K
Java PerformanceReactive-X
Design Patterns
Clean Code
Refactoring
Unit Testing
TDD
any
lang
162 © VictorRentea.ro
a training by
Life
163 © VictorRentea.ro
a training by
checkCustomer(customer);
checkOrder(customer, order);
Mock-full tests
Race Bugs
A method changes a parameter: Surprise!
Different Results for Same Inputs
customer.setActive(true);
Temporal Coupling
164 © VictorRentea.ro
a training by
do side-effects
return void sendEmail(Email):void
Command-Query Separation
setActive(true):void
return resultssearch(criteria):List
computePrice(movie):int
in 1994, by Bertrand Meyer
Pure Functions
165 © VictorRentea.ro
a training by
No side effects
No INSERTs, POSTs, queues, files, fields,…
= 𝑀𝑎𝑡ℎ𝑒𝑚𝑎𝑡𝑖𝑐𝑎𝑙 𝐹𝑢𝑛𝑐𝑡𝑖𝑜𝑛𝑠: 𝑓 𝑥, 𝑦 = 𝑥2
+ 𝑦
(logging doesn't count)
Referential Transparent
Same arguments ➔ same result
No current time, random, GET, SELECT…
≠ Idempotent
Pure Functions
167 © 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
168 © 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
169 © VictorRentea.ro
a training by
Why we Love Pure Functions
➢No hidden inputs, only plain-sight return values and parameters
➢Easier to understand
➢Testable (less setup)
➢Fast & Composable: free to call them n times
➢No temporal coupling
➢Parallelizable
170 © VictorRentea.ro
a training by
That's it!
I'll only write pure functions from now!
impossible
What kind of app doesn't change anything?
172 © VictorRentea.ro
a training by
In Java there's no way to strictly enforce purity
So we'll live with both pure and impure functions
But how do we distinguish them?
173 © 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
174 © VictorRentea.ro
a training by
You can do better!
178 © VictorRentea.ro
a training by
179 © VictorRentea.ro
a training by
functional core
Side-effects (Writes) +
Non-deterministic Reads
Expose them
Purify the most complex parts of your logic!
180 © VictorRentea.ro
a training by
Purify the most complex parts of your logic!
182 © 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
183 © VictorRentea.ro
a training by
Purifying Logic
No Files in Functional Core
185 © VictorRentea.ro
a training by
Purifying Logic
Expose Read/Write from DB/APIs
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()
186 © VictorRentea.ro
a training by
Purifying Logic
Expose Read/Write from DB/APIs
Initial Read
Intermediary
(conditional?)
➔ Pass as Parameters
➔ Split-Phase Refactor
r=read();
f(r);
r1=f1()
f2(r,r1...)
expose impurity
Writing Results ➔ Return Changes w=f();
persist(w);
r=read()
187 © VictorRentea.ro
a training by
Implement as much logic
as pure functions
exposing impurity to the surface
188 © VictorRentea.ro
a training by
Purifying Logic
Changing Objects' State
Immutable Objects
190 © 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
191 © 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 DataImmutable Data
192 © 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
Real-world: 4+ functions in between
...
Real-world: 4+
...
x=
193 © 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);
}
// other 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
record
(java 15)
Java collections are mutable😞
final
Afraid of hackers? 😨
@lombok.Value
or, until then...
194 © VictorRentea.ro
a training by
195 © VictorRentea.ro
a training by
A function changing the object has to return it:
data = f(data);
Imagine data has 20 fields
When did data.x change?
... every time
data = g(data);
data = h(data);
The mess is still here!
196 © VictorRentea.ro
a training by
data = f(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
smallerData = f(...);
➔ break them
If they change together,
they stick together
data = g(data);
data = h(data);
withX
withY
withZ
197 © VictorRentea.ro
a training by
Wait a second,
I know...
198 © 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)
199 © VictorRentea.ro
a training by
Don't
ever
mutate
collections!
➔ Create new ones
200 © 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
201 © VictorRentea.ro
a training by
All right cowboy!
Only immutable objects from now on!
usually that's too much!
202 © VictorRentea.ro
a training by
Value Object vs Reference Object
class Customer {
id // PK in DB
name
phone
}
class Money {
amount
currency
}
equals(): using what fields ?
idamount, currency
final
final
Make VOs immutable!
Should Entities
be immutable?
No matter how different two instances are,
if they have the same id, it's the same Customer
203 © VictorRentea.ro
a training by
instead,
Extract immutable Value Objects from them
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?
204 © VictorRentea.ro
a training by
Entity
(mutable)
Persistent Leaf
eg. FullName
Immutable Objects in Real Life
Runtime Objects
(non-persistent data)
continuously
break XL entities
Hibernate: @Embeddable
206 © VictorRentea.ro
a training by
The Big Deal
207 © 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
How to return changes
to multiple fields:
208 © VictorRentea.ro
a training by
The Big Deal
Is when immutable objects travel lots of code
209 © VictorRentea.ro
a training by
Performance of Immutability
210 © VictorRentea.ro
a training by
Performance of Immutability
Measure it !
(and you might have a surprise)
212 © VictorRentea.ro
a training by
Avoid Immutable Objects If
- Trashing millions of instances/second
- Cloning Lots of Lists
- Trivial logic
- Persistent Entities
213 © 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 ➔
214 © VictorRentea.ro
a training by
victorrentea@gmail.com ♦ ♦ Training: VictorRentea.ro
➢We'll change it in there ➔ compute and return

More Related Content

What's hot

What's hot (20)

Clean Lambdas & Streams in Java8
Clean Lambdas & Streams in Java8Clean Lambdas & Streams in Java8
Clean Lambdas & Streams in Java8
 
Integration testing with spring @snow one
Integration testing with spring @snow oneIntegration testing with spring @snow one
Integration testing with spring @snow one
 
Clean pragmatic architecture @ devflix
Clean pragmatic architecture @ devflixClean pragmatic architecture @ devflix
Clean pragmatic architecture @ devflix
 
Refactoring Games - 15 things to do after Extract Method
Refactoring Games - 15 things to do after Extract MethodRefactoring Games - 15 things to do after Extract Method
Refactoring Games - 15 things to do after Extract Method
 
Clean architecture - Protecting the Domain
Clean architecture - Protecting the DomainClean architecture - Protecting the Domain
Clean architecture - Protecting the Domain
 
The Proxy Fairy, and The Magic of Spring Framework
The Proxy Fairy, and The Magic of Spring FrameworkThe Proxy Fairy, and The Magic of Spring Framework
The Proxy Fairy, and The Magic of Spring Framework
 
Integration testing with spring @JAX Mainz
Integration testing with spring @JAX MainzIntegration testing with spring @JAX Mainz
Integration testing with spring @JAX Mainz
 
Definitive Guide to Working With Exceptions in Java
Definitive Guide to Working With Exceptions in JavaDefinitive Guide to Working With Exceptions in Java
Definitive Guide to Working With Exceptions in Java
 
Unit Testing like a Pro - The Circle of Purity
Unit Testing like a Pro - The Circle of PurityUnit Testing like a Pro - The Circle of Purity
Unit Testing like a Pro - The Circle of Purity
 
Clean Code with Java 8 - Functional Patterns and Best Practices
Clean Code with Java 8 - Functional Patterns and Best PracticesClean Code with Java 8 - Functional Patterns and Best Practices
Clean Code with Java 8 - Functional Patterns and Best Practices
 
Clean Pragmatic Architecture - Avoiding a Monolith
Clean Pragmatic Architecture - Avoiding a MonolithClean Pragmatic Architecture - Avoiding a Monolith
Clean Pragmatic Architecture - Avoiding a Monolith
 
Functional Patterns with Java8 at Devoxx UK - Slides
Functional Patterns with Java8 at Devoxx UK - SlidesFunctional Patterns with Java8 at Devoxx UK - Slides
Functional Patterns with Java8 at Devoxx UK - Slides
 
Refactoring blockers and code smells @jNation 2021
Refactoring   blockers and code smells @jNation 2021Refactoring   blockers and code smells @jNation 2021
Refactoring blockers and code smells @jNation 2021
 
The Art of Clean code
The Art of Clean codeThe Art of Clean code
The Art of Clean code
 
Clean Code
Clean CodeClean Code
Clean Code
 
Functional Patterns with Java8 @Bucharest Java User Group
Functional Patterns with Java8 @Bucharest Java User GroupFunctional Patterns with Java8 @Bucharest Java User Group
Functional Patterns with Java8 @Bucharest Java User Group
 
關於測試,我說的其實是......
關於測試,我說的其實是......關於測試,我說的其實是......
關於測試,我說的其實是......
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy Code
 
Spring @Transactional Explained
Spring @Transactional ExplainedSpring @Transactional Explained
Spring @Transactional Explained
 
Pharo Optimising JIT Internals
Pharo Optimising JIT InternalsPharo Optimising JIT Internals
Pharo Optimising JIT Internals
 

Similar to Pure Functions and Immutable Objects

Java 5 6 Generics, Concurrency, Garbage Collection, Tuning
Java 5 6 Generics, Concurrency, Garbage Collection, TuningJava 5 6 Generics, Concurrency, Garbage Collection, Tuning
Java 5 6 Generics, Concurrency, Garbage Collection, Tuning
Carol McDonald
 
Is your C# optimized
Is your C# optimizedIs your C# optimized
Is your C# optimized
Woody Pewitt
 
Towards JVM Dynamic Languages Toolchain
Towards JVM Dynamic Languages ToolchainTowards JVM Dynamic Languages Toolchain
Towards JVM Dynamic Languages Toolchain
Attila Szegedi
 
Google Developer Fest 2010
Google Developer Fest 2010Google Developer Fest 2010
Google Developer Fest 2010
Chris Ramsdale
 

Similar to Pure Functions and Immutable Objects (20)

Java 5 6 Generics, Concurrency, Garbage Collection, Tuning
Java 5 6 Generics, Concurrency, Garbage Collection, TuningJava 5 6 Generics, Concurrency, Garbage Collection, Tuning
Java 5 6 Generics, Concurrency, Garbage Collection, Tuning
 
Nalinee java
Nalinee javaNalinee java
Nalinee java
 
How do you create a programming language for the JVM?
How do you create a programming language for the JVM?How do you create a programming language for the JVM?
How do you create a programming language for the JVM?
 
How much performance can you get out of Javascript? - Massimiliano Mantione -...
How much performance can you get out of Javascript? - Massimiliano Mantione -...How much performance can you get out of Javascript? - Massimiliano Mantione -...
How much performance can you get out of Javascript? - Massimiliano Mantione -...
 
Is your C# optimized
Is your C# optimizedIs your C# optimized
Is your C# optimized
 
Unit testing - 9 design hints
Unit testing - 9 design hintsUnit testing - 9 design hints
Unit testing - 9 design hints
 
Priming Java for Speed at Market Open
Priming Java for Speed at Market OpenPriming Java for Speed at Market Open
Priming Java for Speed at Market Open
 
Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#
 
Category theory, Monads, and Duality in the world of (BIG) Data
Category theory, Monads, and Duality in the world of (BIG) DataCategory theory, Monads, and Duality in the world of (BIG) Data
Category theory, Monads, and Duality in the world of (BIG) Data
 
Towards JVM Dynamic Languages Toolchain
Towards JVM Dynamic Languages ToolchainTowards JVM Dynamic Languages Toolchain
Towards JVM Dynamic Languages Toolchain
 
EcmaScript unchained
EcmaScript unchainedEcmaScript unchained
EcmaScript unchained
 
Classes and objects
Classes and objectsClasses and objects
Classes and objects
 
Building and Incredible Machine with Pipelines and Generators in PHP (IPC Ber...
Building and Incredible Machine with Pipelines and Generators in PHP (IPC Ber...Building and Incredible Machine with Pipelines and Generators in PHP (IPC Ber...
Building and Incredible Machine with Pipelines and Generators in PHP (IPC Ber...
 
JavaScript Web Workers
JavaScript Web WorkersJavaScript Web Workers
JavaScript Web Workers
 
Max Koretskyi "Why are Angular and React so fast?"
Max Koretskyi "Why are Angular and React so fast?"Max Koretskyi "Why are Angular and React so fast?"
Max Koretskyi "Why are Angular and React so fast?"
 
Django for IoT: From hackathon to production (DjangoCon US)
Django for IoT: From hackathon to production (DjangoCon US)Django for IoT: From hackathon to production (DjangoCon US)
Django for IoT: From hackathon to production (DjangoCon US)
 
Java Generics
Java GenericsJava Generics
Java Generics
 
Google Developer Fest 2010
Google Developer Fest 2010Google Developer Fest 2010
Google Developer Fest 2010
 
To inject or not to inject: CDI is the question
To inject or not to inject: CDI is the questionTo inject or not to inject: CDI is the question
To inject or not to inject: CDI is the question
 
Good code
Good codeGood code
Good code
 

More from Victor Rentea

Vertical Slicing Architectures
Vertical Slicing ArchitecturesVertical Slicing Architectures
Vertical Slicing Architectures
Victor Rentea
 

More from Victor Rentea (16)

Microservice Resilience Patterns @VoxxedCern'24
Microservice Resilience Patterns @VoxxedCern'24Microservice Resilience Patterns @VoxxedCern'24
Microservice Resilience Patterns @VoxxedCern'24
 
Distributed Consistency.pdf
Distributed Consistency.pdfDistributed Consistency.pdf
Distributed Consistency.pdf
 
Clean Code @Voxxed Days Cluj 2023 - opening Keynote
Clean Code @Voxxed Days Cluj 2023 - opening KeynoteClean Code @Voxxed Days Cluj 2023 - opening Keynote
Clean Code @Voxxed Days Cluj 2023 - opening Keynote
 
Testing Microservices @DevoxxBE 23.pdf
Testing Microservices @DevoxxBE 23.pdfTesting Microservices @DevoxxBE 23.pdf
Testing Microservices @DevoxxBE 23.pdf
 
From Web to Flux @DevoxxBE 2023.pptx
From Web to Flux @DevoxxBE 2023.pptxFrom Web to Flux @DevoxxBE 2023.pptx
From Web to Flux @DevoxxBE 2023.pptx
 
Test-Driven Design Insights@DevoxxBE 2023.pptx
Test-Driven Design Insights@DevoxxBE 2023.pptxTest-Driven Design Insights@DevoxxBE 2023.pptx
Test-Driven Design Insights@DevoxxBE 2023.pptx
 
Profiling your Java Application
Profiling your Java ApplicationProfiling your Java Application
Profiling your Java Application
 
OAuth in the Wild
OAuth in the WildOAuth in the Wild
OAuth in the Wild
 
The tests are trying to tell you something@VoxxedBucharest.pptx
The tests are trying to tell you something@VoxxedBucharest.pptxThe tests are trying to tell you something@VoxxedBucharest.pptx
The tests are trying to tell you something@VoxxedBucharest.pptx
 
Vertical Slicing Architectures
Vertical Slicing ArchitecturesVertical Slicing Architectures
Vertical Slicing Architectures
 
Software Craftsmanship @Code Camp Festival 2022.pdf
Software Craftsmanship @Code Camp Festival 2022.pdfSoftware Craftsmanship @Code Camp Festival 2022.pdf
Software Craftsmanship @Code Camp Festival 2022.pdf
 
Extreme Professionalism - Software Craftsmanship
Extreme Professionalism - Software CraftsmanshipExtreme Professionalism - Software Craftsmanship
Extreme Professionalism - Software Craftsmanship
 
TDD Mantra
TDD MantraTDD Mantra
TDD Mantra
 
Extreme Professionalism - Software Craftsmanship
Extreme Professionalism - Software CraftsmanshipExtreme Professionalism - Software Craftsmanship
Extreme Professionalism - Software Craftsmanship
 
Engaging Isolation - What I've Learned Delivering 250 Webinar Hours during CO...
Engaging Isolation - What I've Learned Delivering 250 Webinar Hours during CO...Engaging Isolation - What I've Learned Delivering 250 Webinar Hours during CO...
Engaging Isolation - What I've Learned Delivering 250 Webinar Hours during CO...
 
Clean Code - The Next Chapter
Clean Code - The Next ChapterClean Code - The Next Chapter
Clean Code - The Next Chapter
 

Recently uploaded

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
giselly40
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
Earley Information Science
 

Recently uploaded (20)

🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 

Pure Functions and Immutable Objects

  • 1. victor.rentea@gmail.com ♦ ♦ @victorrentea ♦ VictorRentea.ro The Hitchhiker Guider to
  • 2. Victor Rentea Best Talks: VictorRentea.ro Independent Trainer & Consultant Founder of Bucharest Software Craftsmanship Community Java Champion ❤️ Simple Design, Refactoring, Unit Testing ❤️
  • 3. Technical Training HibernateSpring Func Prog in Java 300+ days2000 devs8 years Details for you or your company: VictorRentea.ro 40 companies Follow me: 35K 4K 3K Java PerformanceReactive-X Design Patterns Clean Code Refactoring Unit Testing TDD any lang
  • 4. 162 © VictorRentea.ro a training by Life
  • 5. 163 © VictorRentea.ro a training by checkCustomer(customer); checkOrder(customer, order); Mock-full tests Race Bugs A method changes a parameter: Surprise! Different Results for Same Inputs customer.setActive(true); Temporal Coupling
  • 6. 164 © VictorRentea.ro a training by do side-effects return void sendEmail(Email):void Command-Query Separation setActive(true):void return resultssearch(criteria):List computePrice(movie):int in 1994, by Bertrand Meyer Pure Functions
  • 7. 165 © VictorRentea.ro a training by No side effects No INSERTs, POSTs, queues, files, fields,… = 𝑀𝑎𝑡ℎ𝑒𝑚𝑎𝑡𝑖𝑐𝑎𝑙 𝐹𝑢𝑛𝑐𝑡𝑖𝑜𝑛𝑠: 𝑓 𝑥, 𝑦 = 𝑥2 + 𝑦 (logging doesn't count) Referential Transparent Same arguments ➔ same result No current time, random, GET, SELECT… ≠ Idempotent Pure Functions
  • 8. 167 © 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
  • 9. 168 © 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
  • 10. 169 © VictorRentea.ro a training by Why we Love Pure Functions ➢No hidden inputs, only plain-sight return values and parameters ➢Easier to understand ➢Testable (less setup) ➢Fast & Composable: free to call them n times ➢No temporal coupling ➢Parallelizable
  • 11. 170 © VictorRentea.ro a training by That's it! I'll only write pure functions from now! impossible What kind of app doesn't change anything?
  • 12. 172 © VictorRentea.ro a training by In Java there's no way to strictly enforce purity So we'll live with both pure and impure functions But how do we distinguish them?
  • 13. 173 © 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
  • 14. 174 © VictorRentea.ro a training by You can do better!
  • 16. 179 © VictorRentea.ro a training by functional core Side-effects (Writes) + Non-deterministic Reads Expose them Purify the most complex parts of your logic!
  • 17. 180 © VictorRentea.ro a training by Purify the most complex parts of your logic!
  • 18. 182 © 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
  • 19. 183 © VictorRentea.ro a training by Purifying Logic No Files in Functional Core
  • 20. 185 © VictorRentea.ro a training by Purifying Logic Expose Read/Write from DB/APIs 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()
  • 21. 186 © VictorRentea.ro a training by Purifying Logic Expose Read/Write from DB/APIs Initial Read Intermediary (conditional?) ➔ Pass as Parameters ➔ Split-Phase Refactor r=read(); f(r); r1=f1() f2(r,r1...) expose impurity Writing Results ➔ Return Changes w=f(); persist(w); r=read()
  • 22. 187 © VictorRentea.ro a training by Implement as much logic as pure functions exposing impurity to the surface
  • 23. 188 © VictorRentea.ro a training by Purifying Logic Changing Objects' State Immutable Objects
  • 24. 190 © 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
  • 25. 191 © 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 DataImmutable Data
  • 26. 192 © 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 Real-world: 4+ functions in between ... Real-world: 4+ ... x=
  • 27. 193 © 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); } // other 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 record (java 15) Java collections are mutable😞 final Afraid of hackers? 😨 @lombok.Value or, until then...
  • 29. 195 © VictorRentea.ro a training by A function changing the object has to return it: data = f(data); Imagine data has 20 fields When did data.x change? ... every time data = g(data); data = h(data); The mess is still here!
  • 30. 196 © VictorRentea.ro a training by data = f(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 smallerData = f(...); ➔ break them If they change together, they stick together data = g(data); data = h(data); withX withY withZ
  • 31. 197 © VictorRentea.ro a training by Wait a second, I know...
  • 32. 198 © 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)
  • 33. 199 © VictorRentea.ro a training by Don't ever mutate collections! ➔ Create new ones
  • 34. 200 © 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
  • 35. 201 © VictorRentea.ro a training by All right cowboy! Only immutable objects from now on! usually that's too much!
  • 36. 202 © VictorRentea.ro a training by Value Object vs Reference Object class Customer { id // PK in DB name phone } class Money { amount currency } equals(): using what fields ? idamount, currency final final Make VOs immutable! Should Entities be immutable? No matter how different two instances are, if they have the same id, it's the same Customer
  • 37. 203 © VictorRentea.ro a training by instead, Extract immutable Value Objects from them 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?
  • 38. 204 © VictorRentea.ro a training by Entity (mutable) Persistent Leaf eg. FullName Immutable Objects in Real Life Runtime Objects (non-persistent data) continuously break XL entities Hibernate: @Embeddable
  • 39. 206 © VictorRentea.ro a training by The Big Deal
  • 40. 207 © 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 How to return changes to multiple fields:
  • 41. 208 © VictorRentea.ro a training by The Big Deal Is when immutable objects travel lots of code
  • 42. 209 © VictorRentea.ro a training by Performance of Immutability
  • 43. 210 © VictorRentea.ro a training by Performance of Immutability Measure it ! (and you might have a surprise)
  • 44. 212 © VictorRentea.ro a training by Avoid Immutable Objects If - Trashing millions of instances/second - Cloning Lots of Lists - Trivial logic - Persistent Entities
  • 45. 213 © 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 ➔
  • 46. 214 © VictorRentea.ro a training by victorrentea@gmail.com ♦ ♦ Training: VictorRentea.ro ➢We'll change it in there ➔ compute and return