twins: object oriented programming and functional programming
DESCRIPTION
Object-Oriented Programming has well established design principles, such as SOLID. For many developers architecture and functional programming are at odds with each other: they don’t know how their existing tricks of the trade convert into functional design. This problem becomes worse as hybrid languages such as Java 8 or Scala become common. We’ll talk about how functional programming helps you implement the SOLID principles, and how a functional mindset can actually help you achieve cleaner and simpler OO design.TRANSCRIPT
![Page 1: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/1.jpg)
OOP and FPRichard Warburton
![Page 2: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/2.jpg)
What on earth are you talking about?
SOLID Principles
Design Patterns
Anthropology
![Page 3: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/3.jpg)
![Page 4: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/4.jpg)
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
![Page 5: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/5.jpg)
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'"
![Page 6: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/6.jpg)
![Page 7: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/7.jpg)
Caveat: some unorthodox definitions may be provided
![Page 8: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/8.jpg)
What on earth are you talking about?
SOLID Principles
Design Patterns
Anthropology
![Page 9: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/9.jpg)
SOLID Principles
● Basic Object Oriented Programming Principles
● Make programs easier to maintain
● Guidelines to remove code smells
![Page 10: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/10.jpg)
Single Responsibility Principle
● Each class/method should have single responsibility
● Responsibility means “reason to change”
● The responsibility should be encapsulated
![Page 11: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/11.jpg)
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;
}
![Page 12: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/12.jpg)
![Page 13: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/13.jpg)
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;
}
![Page 14: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/14.jpg)
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);
}
![Page 15: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/15.jpg)
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
![Page 16: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/16.jpg)
Open Closed Principle
![Page 17: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/17.jpg)
"software entities should be open for extension, but closed for modification"
- Bertrand Meyer
![Page 18: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/18.jpg)
Example: Graphing Metric Data
![Page 19: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/19.jpg)
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
![Page 20: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/20.jpg)
// 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 High Order Function
![Page 21: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/21.jpg)
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
![Page 22: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/22.jpg)
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
![Page 23: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/23.jpg)
![Page 24: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/24.jpg)
A subclass behaves like its parent.
* This is a conscious simplification
![Page 25: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/25.jpg)
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.
![Page 26: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/26.jpg)
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
![Page 27: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/27.jpg)
Interface Segregation Principle
"The dependency of one class to another one should depend on the smallest possible interface"
- Robert Martin
![Page 28: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/28.jpg)
Factory Exampleinterface Worker {
public void goHome();
public void work();
}
AssemblyLine requires instances of Worker: AssemblyWorker and Manager
![Page 29: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/29.jpg)
The factories start using robots...
… but a Robot doesn’t goHome()
![Page 30: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/30.jpg)
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++
![Page 31: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/31.jpg)
class AssemblyWorker implements Worker
class Manager implements Worker
class Robot implements Worker
![Page 32: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/32.jpg)
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;}
![Page 33: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/33.jpg)
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)
![Page 34: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/34.jpg)
class StructuralWorker {
def work(step:ProductionStep) { println( "I'm working on: " + step.getName) }
}
![Page 35: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/35.jpg)
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
}
![Page 36: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/36.jpg)
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
}
![Page 37: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/37.jpg)
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
![Page 38: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/38.jpg)
Thoughts on ISP
● Structural Subtyping removes the need for Interface Segregation Principle
● Functional Interfaces provide a nominal-structural bridge
● ISP != implementing 500 interfaces
![Page 39: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/39.jpg)
Dependency Inversion Principle
![Page 40: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/40.jpg)
● 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
Dependency Inversion Principle
![Page 41: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/41.jpg)
Streams Library
album.getMusicians()
.filter(artist -> artist.name().contains(“The”))
.map(artist -> artist.getNationality())
.collect(toList());
![Page 42: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/42.jpg)
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);
}
}
![Page 43: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/43.jpg)
Business Logic
private List<String> findHeadings() {
return withLinesOf(file,
lines -> lines.filter(isHeading)
.collect(toList()),
HeadingLookupException::new);
}
![Page 44: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/44.jpg)
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);
}
}
![Page 45: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/45.jpg)
DIP Summary
● Higher Order Functions also provide Inversion of Control
● Abstraction != interface
● Functional resource handling, eg withFile in haskell
![Page 46: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/46.jpg)
All the solid patterns have a functional equivalent
![Page 47: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/47.jpg)
The same idea expressed in different ways
![Page 48: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/48.jpg)
What on earth are you talking about?
SOLID Principles
Design Patterns
Anthropology
![Page 49: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/49.jpg)
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
![Page 50: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/50.jpg)
Macro: take something that’s long and make it short
![Page 51: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/51.jpg)
public interface Editor {
public void save();
public void open();
public void close();
}
![Page 52: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/52.jpg)
public interface Action {
public void perform();
}
![Page 53: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/53.jpg)
public class Open implements Action {
private final Editor editor;
public Open(Editor editor) {
this.editor = editor;
}
public void perform() {
editor.open();
}
}
![Page 54: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/54.jpg)
public class Macro {
private final List<Action> actions;
…
public void record(Action action) {
actions.add(action);
}
public void run() {
actions.forEach(Action::perform);
}
}
![Page 55: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/55.jpg)
Macro macro = new Macro();macro.record(new Open(editor));macro.record(new Save(editor));macro.record(new Close(editor));macro.run();
![Page 56: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/56.jpg)
The Command Object is a Function
Macro macro = new Macro();macro.record(() -> editor.open());macro.record(() -> editor.save());macro.record(() -> editor.close());macro.run();
![Page 57: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/57.jpg)
Observer Pattern
![Page 58: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/58.jpg)
![Page 59: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/59.jpg)
Concrete Example: Profiler
public interface ProfileListener {
public void accept(Profile profile);
}
![Page 60: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/60.jpg)
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)
}
}
![Page 61: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/61.jpg)
Previously you needed to write this EVERY time.
![Page 62: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/62.jpg)
Consumer<T> === T → ()ProfileListener === Profile → ()ActionListener === Action → ()
![Page 63: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/63.jpg)
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));
}
![Page 64: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/64.jpg)
public ProfileListener provide(
FlatViewModel flatModel,
TreeViewModel treeModel) {
Listeners<Profile> listener = new
Listeners<Profile>()
.of(flatModel::accept)
.of(treeModel::accept);
return listener::accept;
}
![Page 65: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/65.jpg)
Existing Design Patterns don’t need to be thrown away.
![Page 66: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/66.jpg)
Existing Design Patterns can be improved.
![Page 67: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/67.jpg)
What on earth are you talking about?
SOLID Principles
Design Patterns
Anthropology
![Page 68: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/68.jpg)
Popular programming language evolution follows Arnie’s career.
![Page 69: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/69.jpg)
The 1980s were great!
![Page 70: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/70.jpg)
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.
![Page 71: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/71.jpg)
The 1990s ruined everything
![Page 72: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/72.jpg)
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
![Page 73: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/73.jpg)
Now everyone is friends
![Page 74: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/74.jpg)
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
![Page 75: Twins: Object Oriented Programming and Functional Programming](https://reader033.vdocuments.net/reader033/viewer/2022052322/557c08a9d8b42aef788b511e/html5/thumbnails/75.jpg)
http://java8training.com
http://is.gd/javalambdas
@richardwarburtohttp://insightfullogic.com