SlideShare a Scribd company logo
OOP and FP 
Richard Warburton
What on earth are you talking about? 
SOLID Principles 
Design Patterns 
Anthropology
Twins: Object Oriented Programming and Functional Programming
In Quotes ... 
"OOP is to writing a program, what going through airport 
security is to flying" 
- Richard Mansfield 
"TDD replaces a type checker in Ruby in the same way that 
a strong drink replaces sorrows." 
- byorgey
In Quotes ... 
"Brain explosion is like a traditional pasttime in #haskell" 
"Some people claim everything is lisp. One time I was 
eating some spaghetti and someone came by and said: 
'Hey, nice lisp dialect you're hacking in there'"
Twins: Object Oriented Programming and Functional Programming
Caveat: some unorthodox definitions may be 
provided
What on earth are you talking about? 
SOLID Principles 
Design Patterns 
Anthropology
SOLID Principles 
● Basic Object Oriented Programming 
Principles 
● Make programs easier to maintain 
● Guidelines to remove code smells
Single Responsibility Principle 
● Each class/method should have single 
responsibility 
● Responsibility means “reason to change” 
● The responsibility should be encapsulated
int countPrimes(int upTo) { 
int tally = 0; 
for (int i = 1; i < upTo; i++) { 
boolean isPrime = true; 
for (int j = 2; j < i; j++) { 
if (i % j == 0) { 
isPrime = false; 
} 
} 
if (isPrime) { 
tally++; 
} 
} 
return tally; 
}
Twins: Object Oriented Programming and Functional Programming
int countPrimes(int upTo) { 
int tally = 0; 
for (int i = 1; i < upTo; i++) { 
if (isPrime(i)) { 
tally++; 
} 
} 
return tally; 
} 
boolean isPrime(int number) { 
for (int i = 2; i < number; i++) { 
if (number % i == 0) { 
return false; 
} 
} 
return true; 
}
long countPrimes(int upTo) { 
return IntStream.range(1, upTo) 
.filter(this::isPrime) 
.count(); 
} 
boolean isPrime(int number) { 
return IntStream.range(2, number) 
.allMatch(x -> (number % x) != 0); 
}
Higher Order Functions 
● Hard to write single responsibility code in 
Java before 8 
● Single responsibility requires ability to pass 
around behaviour 
● Not just functions, Higher Order Functions
Open Closed Principle
"software entities should be open for extension, 
but closed for modification" 
- Bertrand Meyer
Example: Graphing Metric Data
OCP as Polymorphism 
● Graphing Metric Data 
○ CpuUsage 
○ ProcessDiskWrite 
○ MachineIO 
● GraphDisplay depends upon a 
TimeSeries rather than each individually 
● No need to change GraphDisplay to add 
SwapTime
OCP as High Order Function 
// Example creation 
ThreadLocal<DateFormat> formatter = 
withInitial(() -> new SimpleDateFormat()); 
// Usage 
DateFormat formatter = formatter.get(); 
// Or ... 
AtomicInteger threadId = new AtomicInteger(); 
ThreadLocal<Integer> formatter = 
withInitial(() -> threadId.getAndIncrement());
OCP as Immutability 
● Immutable Object cannot be modified after 
creation 
● Safe to add additional behaviour 
● New pure functions can’t break existing 
functionality because it can’t change state
Liskov Substitution Principle 
Let q(x) be a property provable about objects 
x of type T. Then q(y) should be true for 
objects y of type S where S is a subtype of T. 
* Excuse the informality
Twins: Object Oriented Programming and Functional Programming
A subclass behaves like its parent. 
* This is a conscious simplification
1. Where the parent worked the child should. 
2. Where the parent caused an effect then the 
child should. 
3. Where parent always stuck by something 
then the child should. 
4. Don’t change things your parent didn’t.
Functional Perspective 
● Inheritance isn’t key to FP 
● Lesson: don’t inherit implementation and 
LSP isn’t an issue! 
● Composite Reuse Principle already 
commonly accepted OOP principle
Interface Segregation Principle 
"The dependency of one class to another one 
should depend on the smallest possible 
interface" 
- Robert Martin
Factory Example 
interface Worker { 
public void goHome(); 
public void work(); 
} 
AssemblyLine requires instances of 
Worker: AssemblyWorker and Manager
The factories start using robots... 
… but a Robot doesn’t goHome()
Nominal Subtyping 
● For Foo to extend Bar you need to see Foo 
extends Bar in your code. 
● Relationship explicit between types based 
on the name of the type 
● Common in Statically Typed, OO languages: 
Java, C++
class AssemblyWorker implements 
Worker 
class Manager implements Worker 
class Robot implements Worker
public void addWorker(Worker worker) { 
workers.add(worker); 
} 
public static AssemblyLine newLine() { 
AssemblyLine line = new AssemblyLine(); 
line.addWorker(new Manager()); 
line.addWorker(new AssemblyWorker()); 
line.addWorker(new Robot()); 
return line; 
}
Structural Subtyping 
● Relationship implicit between types based 
on the shape/structure of the type 
● If you call obj.getFoo() then obj needs a 
getFoo method 
● Common in wacky language: Ocaml, Go, 
C++ Templates, Ruby (quack quack)
class StructuralWorker { 
def work(step:ProductionStep) { 
println( 
"I'm working on: " 
+ step.getName) 
} 
}
def addWorker(worker: {def work(step:ProductionStep)}) { 
workers += worker 
} 
def newLine() = { 
val line = new AssemblyLine 
line.addWorker(new Manager()) 
line.addWorker(new StructuralWorker()) 
line.addWorker(new Robot()) 
line 
}
Hypothetically … 
def addWorker(worker) { 
workers += worker 
} 
def newLine() = { 
val line = new AssemblyLine 
line.addWorker(new Manager()) 
line.addWorker(new StructuralWorker()) 
line.addWorker(new Robot()) 
line 
}
Functional Interfaces 
● An interface with a single abstract 
method 
● By definition the minimal interface! 
● Used as the inferred types for lambda 
expressions in Java 8
Thoughts on ISP 
● Structural Subtyping removes the need for 
Interface Segregation Principle 
● Functional Interfaces provide a nominal-structural 
bridge 
● ISP != implementing 500 interfaces
Dependency Inversion Principle
Dependency Inversion Principle 
● Abstractions should not depend on details, 
details should depend on abstractions 
● Decouple glue code from business logic 
● Inversion of Control/Dependency Injection is 
an implementation of DIP
Streams Library 
album.getMusicians() 
.filter(artist -> artist.name().contains(“The”)) 
.map(artist -> artist.getNationality()) 
.collect(toList());
Resource Handling & Logic 
List<String> findHeadings() { 
try (BufferedReader reader 
= new BufferedReader(new FileReader(file))) { 
return reader.lines() 
.filter(isHeading) 
.collect(toList()); 
} catch (IOException e) { 
throw new HeadingLookupException(e); 
} 
}
Business Logic 
private List<String> findHeadings() { 
return withLinesOf(file, 
lines -> lines.filter(isHeading) 
.collect(toList()), 
HeadingLookupException::new); 
}
Resource Handling 
<T> T withLinesOf(String file, 
Function<Stream<String>, T> handler, 
Function<IOException, 
RuntimeException> error) { 
try (BufferedReader reader = 
new BufferedReader(new FileReader(file))) { 
return handler.apply(reader.lines()); 
} catch (IOException e) { 
throw error.apply(e); 
} 
}
DIP Summary 
● Higher Order Functions also provide 
Inversion of Control 
● Abstraction != interface 
● Functional resource handling, eg withFile 
in haskell
All the solid patterns have a functional 
equivalent
The same idea expressed in different ways
What on earth are you talking about? 
SOLID Principles 
Design Patterns 
Anthropology
Command Pattern 
• Receiver - performs the actual work. 
• Command - encapsulates all the information 
required to call the receiver. 
• Invoker - controls the sequencing and 
execution of one or more commands. 
• Client - creates concrete command instances
Macro: take something that’s long and make it short
public interface Editor { 
public void save(); 
public void open(); 
public void close(); 
}
public interface Action { 
public void perform(); 
}
public class Open implements Action { 
private final Editor editor; 
public Open(Editor editor) { 
this.editor = editor; 
} 
public void perform() { 
editor.open(); 
} 
}
public class Macro { 
private final List<Action> actions; 
… 
public void record(Action action) { 
actions.add(action); 
} 
public void run() { 
actions.forEach(Action::perform); 
} 
}
Macro macro = new Macro(); 
macro.record(new Open(editor)); 
macro.record(new Save(editor)); 
macro.record(new Close(editor)); 
macro.run();
The Command Object is a Function 
Macro macro = new Macro(); 
macro.record(() -> editor.open()); 
macro.record(() -> editor.save()); 
macro.record(() -> editor.close()); 
macro.run();
Observer Pattern
Twins: Object Oriented Programming and Functional Programming
Concrete Example: Profiler 
public interface ProfileListener { 
public void accept(Profile profile); 
}
private final List<ProfileListener> listeners; 
public void addListener(ProfileListener listener) { 
listeners.add(listener); 
} 
private void accept(Profile profile) { 
for (ProfileListener listener : listeners) { 
listener.accept(profile) 
} 
}
Previously you needed to write this EVERY 
time.
Consumer<T> === T → () 
ProfileListener === Profile → () 
ActionListener === Action → ()
public class Listeners<T> implements Consumer<T> { 
private final List<Consumer<T>> consumers; 
public Listeners<T> add(Consumer<T> consumer) { 
consumers.add(consumer); 
return this; 
} 
@Override 
public void accept(T value) { 
consumers.forEach(consumer -> consumer.accept(value)); 
}
public ProfileListener provide( 
FlatViewModel flatModel, 
TreeViewModel treeModel) { 
Listeners<Profile> listener = new 
Listeners<Profile>() 
.of(flatModel::accept) 
.of(treeModel::accept); 
return listener::accept; 
}
Existing Design Patterns don’t need to be 
thrown away.
Existing Design Patterns can be improved.
What on earth are you talking about? 
SOLID Principles 
Design Patterns 
Anthropology
Popular programming language evolution 
follows Arnie’s career.
The 1980s were great!
Programming 80s style 
● Strongly multiparadigm languages 
○ Smalltalk 80 had lambda expressions 
○ Common Lisp Object System 
● Polyglot Programmers 
● Fertile Language Research 
● Implementation Progress - GC, JITs, etc.
The 1990s ruined everything
90s and 2000s Market Convergence 
● Huge Java popularity ramp 
○ Javaone in 2001 - 28,000 attendees 
○ Servlets, J2EE then Spring 
● Virtual death of Smalltalk, LISP then Perl 
● Object Oriented Dominance
Now everyone is friends
Increasingly Multiparadigm 
● Established languages going multiparadigm 
○ Java 8 - Generics + Lambdas 
○ C++ - Templates, Lambdas 
● Newer Languages are multi paradigm 
○ F# 
○ Ruby/Python/Groovy can be functional 
○ New JVM languages: 
■ Scala 
■ Ceylon 
■ Kotlin
http://java8training.com 
http://is.gd/javalambdas 
@richardwarburto 
http://insightfullogic.com

More Related Content

What's hot (20)

PPTX
Java generics final
Akshay Chaudhari
 
PPT
JavaScript Objects
Reem Alattas
 
PDF
Kotlin advanced - language reference for android developers
Bartosz Kosarzycki
 
PDF
Scala is java8.next()
daewon jeong
 
PDF
Lazy java
Mario Fusco
 
PPTX
Intro to Javascript
Anjan Banda
 
PPTX
Use of Apache Commons and Utilities
Pramod Kumar
 
PDF
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Mario Fusco
 
PDF
FP in Java - Project Lambda and beyond
Mario Fusco
 
PDF
2 kotlin vs. java: what java has that kotlin does not
Sergey Bandysik
 
ODP
From object oriented to functional domain modeling
Codemotion
 
PPTX
Kotlin
YeldosTanikin
 
ODP
Java Generics
Carol McDonald
 
PPSX
DIWE - Programming with JavaScript
Rasan Samarasinghe
 
PDF
Javaz. Functional design in Java 8.
Vadim Dubs
 
PPTX
Lecture02 class -_templatev2
Hariz Mustafa
 
PDF
Introduction to kotlin
NAVER Engineering
 
PDF
Refactoring to Java 8 (Devoxx BE)
Trisha Gee
 
PPTX
Introduction to kotlin + spring boot demo
Muhammad Abdullah
 
PDF
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Chris Richardson
 
Java generics final
Akshay Chaudhari
 
JavaScript Objects
Reem Alattas
 
Kotlin advanced - language reference for android developers
Bartosz Kosarzycki
 
Scala is java8.next()
daewon jeong
 
Lazy java
Mario Fusco
 
Intro to Javascript
Anjan Banda
 
Use of Apache Commons and Utilities
Pramod Kumar
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Mario Fusco
 
FP in Java - Project Lambda and beyond
Mario Fusco
 
2 kotlin vs. java: what java has that kotlin does not
Sergey Bandysik
 
From object oriented to functional domain modeling
Codemotion
 
Java Generics
Carol McDonald
 
DIWE - Programming with JavaScript
Rasan Samarasinghe
 
Javaz. Functional design in Java 8.
Vadim Dubs
 
Lecture02 class -_templatev2
Hariz Mustafa
 
Introduction to kotlin
NAVER Engineering
 
Refactoring to Java 8 (Devoxx BE)
Trisha Gee
 
Introduction to kotlin + spring boot demo
Muhammad Abdullah
 
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Chris Richardson
 

Viewers also liked (7)

PDF
Performance and predictability (1)
RichardWarburton
 
PDF
Pragmatic functional refactoring with java 8 (1)
RichardWarburton
 
PDF
Jvm profiling under the hood
RichardWarburton
 
PDF
Generics Past, Present and Future
RichardWarburton
 
PDF
Performance and predictability
RichardWarburton
 
PDF
Java collections the force awakens
RichardWarburton
 
PDF
How to run a hackday
RichardWarburton
 
Performance and predictability (1)
RichardWarburton
 
Pragmatic functional refactoring with java 8 (1)
RichardWarburton
 
Jvm profiling under the hood
RichardWarburton
 
Generics Past, Present and Future
RichardWarburton
 
Performance and predictability
RichardWarburton
 
Java collections the force awakens
RichardWarburton
 
How to run a hackday
RichardWarburton
 
Ad

Similar to Twins: Object Oriented Programming and Functional Programming (20)

PDF
TWINS: OOP and FP - Warburton
Codemotion
 
PDF
Twins: OOP and FP
RichardWarburton
 
PDF
Twins: OOP and FP
RichardWarburton
 
PDF
Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)
Ovidiu Farauanu
 
PDF
JavaScript for real men
Ivano Malavolta
 
PPTX
TEMPLATES IN JAVA
MuskanSony
 
PDF
(3) cpp procedural programming
Nico Ludwig
 
PPTX
Clean Code: Chapter 3 Function
Kent Huang
 
PPTX
Advance python
pulkit agrawal
 
PDF
Beyond PITS, Functional Principles for Software Architecture
Jayaram Sankaranarayanan
 
ODP
Functional programming
S M Asaduzzaman
 
PPT
An Overview Of Python With Functional Programming
Adam Getchell
 
PDF
05. haskell streaming io
Sebastian Rettig
 
KEY
Exciting JavaScript - Part I
Eugene Lazutkin
 
PPTX
1P13 Python Review Session Covering various Topics
hussainmuhd1119
 
PDF
SeneJug java_8_prez_122015
senejug
 
PDF
First Steps in Python Programming
Dozie Agbo
 
PPT
02 functions, variables, basic input and output of c++
Manzoor ALam
 
PDF
Reviewing OOP Design patterns
Olivier Bacs
 
PPTX
Workflow Foundation 4
Robert MacLean
 
TWINS: OOP and FP - Warburton
Codemotion
 
Twins: OOP and FP
RichardWarburton
 
Twins: OOP and FP
RichardWarburton
 
Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)
Ovidiu Farauanu
 
JavaScript for real men
Ivano Malavolta
 
TEMPLATES IN JAVA
MuskanSony
 
(3) cpp procedural programming
Nico Ludwig
 
Clean Code: Chapter 3 Function
Kent Huang
 
Advance python
pulkit agrawal
 
Beyond PITS, Functional Principles for Software Architecture
Jayaram Sankaranarayanan
 
Functional programming
S M Asaduzzaman
 
An Overview Of Python With Functional Programming
Adam Getchell
 
05. haskell streaming io
Sebastian Rettig
 
Exciting JavaScript - Part I
Eugene Lazutkin
 
1P13 Python Review Session Covering various Topics
hussainmuhd1119
 
SeneJug java_8_prez_122015
senejug
 
First Steps in Python Programming
Dozie Agbo
 
02 functions, variables, basic input and output of c++
Manzoor ALam
 
Reviewing OOP Design patterns
Olivier Bacs
 
Workflow Foundation 4
Robert MacLean
 
Ad

More from RichardWarburton (20)

PDF
Fantastic performance and where to find it
RichardWarburton
 
PDF
Production profiling what, why and how technical audience (3)
RichardWarburton
 
PDF
Production profiling: What, Why and How
RichardWarburton
 
PDF
Production profiling what, why and how (JBCN Edition)
RichardWarburton
 
PDF
Production Profiling: What, Why and How
RichardWarburton
 
PDF
Generics Past, Present and Future (Latest)
RichardWarburton
 
PDF
Collections forceawakens
RichardWarburton
 
PDF
Generics past, present and future
RichardWarburton
 
PDF
Pragmatic functional refactoring with java 8
RichardWarburton
 
PDF
Introduction to lambda behave
RichardWarburton
 
PDF
Introduction to lambda behave
RichardWarburton
 
PDF
Performance and predictability
RichardWarburton
 
PDF
Simplifying java with lambdas (short)
RichardWarburton
 
PDF
The Bleeding Edge
RichardWarburton
 
PDF
Lambdas myths-and-mistakes
RichardWarburton
 
PDF
Caching in
RichardWarburton
 
PDF
Lambdas: Myths and Mistakes
RichardWarburton
 
PDF
Better than a coin toss
RichardWarburton
 
PDF
Devoxx uk lambdas hackday
RichardWarburton
 
PDF
How to run a hackday
RichardWarburton
 
Fantastic performance and where to find it
RichardWarburton
 
Production profiling what, why and how technical audience (3)
RichardWarburton
 
Production profiling: What, Why and How
RichardWarburton
 
Production profiling what, why and how (JBCN Edition)
RichardWarburton
 
Production Profiling: What, Why and How
RichardWarburton
 
Generics Past, Present and Future (Latest)
RichardWarburton
 
Collections forceawakens
RichardWarburton
 
Generics past, present and future
RichardWarburton
 
Pragmatic functional refactoring with java 8
RichardWarburton
 
Introduction to lambda behave
RichardWarburton
 
Introduction to lambda behave
RichardWarburton
 
Performance and predictability
RichardWarburton
 
Simplifying java with lambdas (short)
RichardWarburton
 
The Bleeding Edge
RichardWarburton
 
Lambdas myths-and-mistakes
RichardWarburton
 
Caching in
RichardWarburton
 
Lambdas: Myths and Mistakes
RichardWarburton
 
Better than a coin toss
RichardWarburton
 
Devoxx uk lambdas hackday
RichardWarburton
 
How to run a hackday
RichardWarburton
 

Recently uploaded (20)

PDF
Kit-Works Team Study_20250627_한달만에만든사내서비스키링(양다윗).pdf
Wonjun Hwang
 
PPTX
Securing Model Context Protocol with Keycloak: AuthN/AuthZ for MCP Servers
Hitachi, Ltd. OSS Solution Center.
 
PDF
What’s my job again? Slides from Mark Simos talk at 2025 Tampa BSides
Mark Simos
 
PDF
FME in Overdrive: Unleashing the Power of Parallel Processing
Safe Software
 
PPTX
Practical Applications of AI in Local Government
OnBoard
 
PPTX
Agentforce World Tour Toronto '25 - Supercharge MuleSoft Development with Mod...
Alexandra N. Martinez
 
PDF
Optimizing the trajectory of a wheel loader working in short loading cycles
Reno Filla
 
PDF
🚀 Let’s Build Our First Slack Workflow! 🔧.pdf
SanjeetMishra29
 
PDF
Draugnet: Anonymous Threat Reporting for a World on Fire
treyka
 
PPTX
Wondershare Filmora Crack Free Download 2025
josanj305
 
PDF
Governing Geospatial Data at Scale: Optimizing ArcGIS Online with FME in Envi...
Safe Software
 
PDF
Bitkom eIDAS Summit | European Business Wallet: Use Cases, Macroeconomics, an...
Carsten Stoecker
 
PDF
GDG Cloud Southlake #44: Eyal Bukchin: Tightening the Kubernetes Feedback Loo...
James Anderson
 
PDF
Quantum Threats Are Closer Than You Think – Act Now to Stay Secure
WSO2
 
PDF
Pipeline Industry IoT - Real Time Data Monitoring
Safe Software
 
PDF
Deploy Faster, Run Smarter: Learn Containers with QNAP
QNAP Marketing
 
PDF
NLJUG Speaker academy 2025 - first session
Bert Jan Schrijver
 
PDF
Understanding The True Cost of DynamoDB Webinar
ScyllaDB
 
PPTX
CapCut Pro PC Crack Latest Version Free Free
josanj305
 
PDF
ICONIQ State of AI Report 2025 - The Builder's Playbook
Razin Mustafiz
 
Kit-Works Team Study_20250627_한달만에만든사내서비스키링(양다윗).pdf
Wonjun Hwang
 
Securing Model Context Protocol with Keycloak: AuthN/AuthZ for MCP Servers
Hitachi, Ltd. OSS Solution Center.
 
What’s my job again? Slides from Mark Simos talk at 2025 Tampa BSides
Mark Simos
 
FME in Overdrive: Unleashing the Power of Parallel Processing
Safe Software
 
Practical Applications of AI in Local Government
OnBoard
 
Agentforce World Tour Toronto '25 - Supercharge MuleSoft Development with Mod...
Alexandra N. Martinez
 
Optimizing the trajectory of a wheel loader working in short loading cycles
Reno Filla
 
🚀 Let’s Build Our First Slack Workflow! 🔧.pdf
SanjeetMishra29
 
Draugnet: Anonymous Threat Reporting for a World on Fire
treyka
 
Wondershare Filmora Crack Free Download 2025
josanj305
 
Governing Geospatial Data at Scale: Optimizing ArcGIS Online with FME in Envi...
Safe Software
 
Bitkom eIDAS Summit | European Business Wallet: Use Cases, Macroeconomics, an...
Carsten Stoecker
 
GDG Cloud Southlake #44: Eyal Bukchin: Tightening the Kubernetes Feedback Loo...
James Anderson
 
Quantum Threats Are Closer Than You Think – Act Now to Stay Secure
WSO2
 
Pipeline Industry IoT - Real Time Data Monitoring
Safe Software
 
Deploy Faster, Run Smarter: Learn Containers with QNAP
QNAP Marketing
 
NLJUG Speaker academy 2025 - first session
Bert Jan Schrijver
 
Understanding The True Cost of DynamoDB Webinar
ScyllaDB
 
CapCut Pro PC Crack Latest Version Free Free
josanj305
 
ICONIQ State of AI Report 2025 - The Builder's Playbook
Razin Mustafiz
 

Twins: Object Oriented Programming and Functional Programming

  • 1. OOP and FP Richard Warburton
  • 2. What on earth are you talking about? SOLID Principles Design Patterns Anthropology
  • 4. In Quotes ... "OOP is to writing a program, what going through airport security is to flying" - Richard Mansfield "TDD replaces a type checker in Ruby in the same way that a strong drink replaces sorrows." - byorgey
  • 5. In Quotes ... "Brain explosion is like a traditional pasttime in #haskell" "Some people claim everything is lisp. One time I was eating some spaghetti and someone came by and said: 'Hey, nice lisp dialect you're hacking in there'"
  • 7. Caveat: some unorthodox definitions may be provided
  • 8. What on earth are you talking about? SOLID Principles Design Patterns Anthropology
  • 9. SOLID Principles ● Basic Object Oriented Programming Principles ● Make programs easier to maintain ● Guidelines to remove code smells
  • 10. Single Responsibility Principle ● Each class/method should have single responsibility ● Responsibility means “reason to change” ● The responsibility should be encapsulated
  • 11. int countPrimes(int upTo) { int tally = 0; for (int i = 1; i < upTo; i++) { boolean isPrime = true; for (int j = 2; j < i; j++) { if (i % j == 0) { isPrime = false; } } if (isPrime) { tally++; } } return tally; }
  • 13. int countPrimes(int upTo) { int tally = 0; for (int i = 1; i < upTo; i++) { if (isPrime(i)) { tally++; } } return tally; } boolean isPrime(int number) { for (int i = 2; i < number; i++) { if (number % i == 0) { return false; } } return true; }
  • 14. long countPrimes(int upTo) { return IntStream.range(1, upTo) .filter(this::isPrime) .count(); } boolean isPrime(int number) { return IntStream.range(2, number) .allMatch(x -> (number % x) != 0); }
  • 15. Higher Order Functions ● Hard to write single responsibility code in Java before 8 ● Single responsibility requires ability to pass around behaviour ● Not just functions, Higher Order Functions
  • 17. "software entities should be open for extension, but closed for modification" - Bertrand Meyer
  • 19. OCP as Polymorphism ● Graphing Metric Data ○ CpuUsage ○ ProcessDiskWrite ○ MachineIO ● GraphDisplay depends upon a TimeSeries rather than each individually ● No need to change GraphDisplay to add SwapTime
  • 20. OCP as High Order Function // Example creation ThreadLocal<DateFormat> formatter = withInitial(() -> new SimpleDateFormat()); // Usage DateFormat formatter = formatter.get(); // Or ... AtomicInteger threadId = new AtomicInteger(); ThreadLocal<Integer> formatter = withInitial(() -> threadId.getAndIncrement());
  • 21. OCP as Immutability ● Immutable Object cannot be modified after creation ● Safe to add additional behaviour ● New pure functions can’t break existing functionality because it can’t change state
  • 22. Liskov Substitution Principle Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T. * Excuse the informality
  • 24. A subclass behaves like its parent. * This is a conscious simplification
  • 25. 1. Where the parent worked the child should. 2. Where the parent caused an effect then the child should. 3. Where parent always stuck by something then the child should. 4. Don’t change things your parent didn’t.
  • 26. Functional Perspective ● Inheritance isn’t key to FP ● Lesson: don’t inherit implementation and LSP isn’t an issue! ● Composite Reuse Principle already commonly accepted OOP principle
  • 27. Interface Segregation Principle "The dependency of one class to another one should depend on the smallest possible interface" - Robert Martin
  • 28. Factory Example interface Worker { public void goHome(); public void work(); } AssemblyLine requires instances of Worker: AssemblyWorker and Manager
  • 29. The factories start using robots... … but a Robot doesn’t goHome()
  • 30. Nominal Subtyping ● For Foo to extend Bar you need to see Foo extends Bar in your code. ● Relationship explicit between types based on the name of the type ● Common in Statically Typed, OO languages: Java, C++
  • 31. class AssemblyWorker implements Worker class Manager implements Worker class Robot implements Worker
  • 32. public void addWorker(Worker worker) { workers.add(worker); } public static AssemblyLine newLine() { AssemblyLine line = new AssemblyLine(); line.addWorker(new Manager()); line.addWorker(new AssemblyWorker()); line.addWorker(new Robot()); return line; }
  • 33. Structural Subtyping ● Relationship implicit between types based on the shape/structure of the type ● If you call obj.getFoo() then obj needs a getFoo method ● Common in wacky language: Ocaml, Go, C++ Templates, Ruby (quack quack)
  • 34. class StructuralWorker { def work(step:ProductionStep) { println( "I'm working on: " + step.getName) } }
  • 35. def addWorker(worker: {def work(step:ProductionStep)}) { workers += worker } def newLine() = { val line = new AssemblyLine line.addWorker(new Manager()) line.addWorker(new StructuralWorker()) line.addWorker(new Robot()) line }
  • 36. Hypothetically … def addWorker(worker) { workers += worker } def newLine() = { val line = new AssemblyLine line.addWorker(new Manager()) line.addWorker(new StructuralWorker()) line.addWorker(new Robot()) line }
  • 37. Functional Interfaces ● An interface with a single abstract method ● By definition the minimal interface! ● Used as the inferred types for lambda expressions in Java 8
  • 38. Thoughts on ISP ● Structural Subtyping removes the need for Interface Segregation Principle ● Functional Interfaces provide a nominal-structural bridge ● ISP != implementing 500 interfaces
  • 40. Dependency Inversion Principle ● Abstractions should not depend on details, details should depend on abstractions ● Decouple glue code from business logic ● Inversion of Control/Dependency Injection is an implementation of DIP
  • 41. Streams Library album.getMusicians() .filter(artist -> artist.name().contains(“The”)) .map(artist -> artist.getNationality()) .collect(toList());
  • 42. Resource Handling & Logic List<String> findHeadings() { try (BufferedReader reader = new BufferedReader(new FileReader(file))) { return reader.lines() .filter(isHeading) .collect(toList()); } catch (IOException e) { throw new HeadingLookupException(e); } }
  • 43. Business Logic private List<String> findHeadings() { return withLinesOf(file, lines -> lines.filter(isHeading) .collect(toList()), HeadingLookupException::new); }
  • 44. Resource Handling <T> T withLinesOf(String file, Function<Stream<String>, T> handler, Function<IOException, RuntimeException> error) { try (BufferedReader reader = new BufferedReader(new FileReader(file))) { return handler.apply(reader.lines()); } catch (IOException e) { throw error.apply(e); } }
  • 45. DIP Summary ● Higher Order Functions also provide Inversion of Control ● Abstraction != interface ● Functional resource handling, eg withFile in haskell
  • 46. All the solid patterns have a functional equivalent
  • 47. The same idea expressed in different ways
  • 48. What on earth are you talking about? SOLID Principles Design Patterns Anthropology
  • 49. Command Pattern • Receiver - performs the actual work. • Command - encapsulates all the information required to call the receiver. • Invoker - controls the sequencing and execution of one or more commands. • Client - creates concrete command instances
  • 50. Macro: take something that’s long and make it short
  • 51. public interface Editor { public void save(); public void open(); public void close(); }
  • 52. public interface Action { public void perform(); }
  • 53. public class Open implements Action { private final Editor editor; public Open(Editor editor) { this.editor = editor; } public void perform() { editor.open(); } }
  • 54. public class Macro { private final List<Action> actions; … public void record(Action action) { actions.add(action); } public void run() { actions.forEach(Action::perform); } }
  • 55. Macro macro = new Macro(); macro.record(new Open(editor)); macro.record(new Save(editor)); macro.record(new Close(editor)); macro.run();
  • 56. The Command Object is a Function Macro macro = new Macro(); macro.record(() -> editor.open()); macro.record(() -> editor.save()); macro.record(() -> editor.close()); macro.run();
  • 59. Concrete Example: Profiler public interface ProfileListener { public void accept(Profile profile); }
  • 60. private final List<ProfileListener> listeners; public void addListener(ProfileListener listener) { listeners.add(listener); } private void accept(Profile profile) { for (ProfileListener listener : listeners) { listener.accept(profile) } }
  • 61. Previously you needed to write this EVERY time.
  • 62. Consumer<T> === T → () ProfileListener === Profile → () ActionListener === Action → ()
  • 63. public class Listeners<T> implements Consumer<T> { private final List<Consumer<T>> consumers; public Listeners<T> add(Consumer<T> consumer) { consumers.add(consumer); return this; } @Override public void accept(T value) { consumers.forEach(consumer -> consumer.accept(value)); }
  • 64. public ProfileListener provide( FlatViewModel flatModel, TreeViewModel treeModel) { Listeners<Profile> listener = new Listeners<Profile>() .of(flatModel::accept) .of(treeModel::accept); return listener::accept; }
  • 65. Existing Design Patterns don’t need to be thrown away.
  • 66. Existing Design Patterns can be improved.
  • 67. What on earth are you talking about? SOLID Principles Design Patterns Anthropology
  • 68. Popular programming language evolution follows Arnie’s career.
  • 69. The 1980s were great!
  • 70. Programming 80s style ● Strongly multiparadigm languages ○ Smalltalk 80 had lambda expressions ○ Common Lisp Object System ● Polyglot Programmers ● Fertile Language Research ● Implementation Progress - GC, JITs, etc.
  • 71. The 1990s ruined everything
  • 72. 90s and 2000s Market Convergence ● Huge Java popularity ramp ○ Javaone in 2001 - 28,000 attendees ○ Servlets, J2EE then Spring ● Virtual death of Smalltalk, LISP then Perl ● Object Oriented Dominance
  • 73. Now everyone is friends
  • 74. Increasingly Multiparadigm ● Established languages going multiparadigm ○ Java 8 - Generics + Lambdas ○ C++ - Templates, Lambdas ● Newer Languages are multi paradigm ○ F# ○ Ruby/Python/Groovy can be functional ○ New JVM languages: ■ Scala ■ Ceylon ■ Kotlin