SlideShare a Scribd company logo
:clojure/south - São Paulo, 2019
From Java to parallel Clojure
Leonardo Borges

@leonardo_borges

www.leonardoborges.com

www.recordpoint.com
A bit about me
• Head of Engineering at RecordPoint

• Founder of the Sydney Clojure User Group

• Open-source contributor 

• Author of bouncer and imminent

• Author of Clojure Reactive Programming
A bit about me
• 2nd edition is out now!
What about you?
What we’ll talk about
• Being a Lisp on the JVM

• Functional Programming strengths

• Concurrency and parallelism
Java has come a long way…
• ForkJoin;

• Lambda Expressions;

• Method References;

• CompletableFutures;

• JShell;

• Reactive Streams / Stream API;

• …and more!
So why would you invest in
Clojure?
Here’s a few reasons
Here’s a few reasons
Classes and Interfaces

• Minimize the accessibility of
classes and members

• In public classes, use
accessor methods, not public
fields

• Minimize mutability
Immutability
(def ages [10 20 30])
(def names ["Leo" "Liv" "Bruce"])
Immutability
(def ages [10 20 30])
(def names ["Leo" "Liv" "Bruce"])
(defrecord Person [fname age])
(def leo (->Person "Leo" 10))
;; {:fname "Leo", :age 10}
Immutability
(def ages [10 20 30])
(def names ["Leo" "Liv" "Bruce"])
(defrecord Person [fname age])
(map (fn [fname age]
(->Person fname age)) names ages)
;; ({:fname "Leo", :age 10}
;; {:fname "Liv", :age 20}
;; {:fname "Bruce", :age 30})
Immutability
(def ages [10 20 30])
(def names ["Leo" "Liv" "Bruce"])
(defrecord Person [fname age])
(map ->Person names ages)
;; ({:fname "Leo", :age 10}
;; {:fname "Liv", :age 20}
;; {:fname "Bruce", :age 30})
What if we want to add new
ages and names?
Adding new elements to vectors
(def new-ages (conj ages 40)) ;; [10 20 30 40]
ages ;; [10 20 30]
(def new-names (conj names "Gwen")) ;; ["Leo" "Liv"
"Bruce" "Gwen"]
names ;; ["Leo" "Liv" "Bruce"]
Is that slow?
Persistent data structures
(def xs ‘(0 1 2))
(def ys ‘(3 4 5))
Persistent data structures
(def xs ‘(0 1 2))
(def ys ‘(3 4 5))
(def zs (concat xs ys))
Persistent data structures
(def xs ‘(0 1 2))
(def ys ‘(3 4 5))
(def zs (concat xs ys))
Here’s a few reasons
Lambdas and Streams

• Prefer lambdas to anonymous
classes

• Prefer method references to
lambdas

• Favor the use of standard
functional interfaces
Prefer lambdas to anonymous classes
Collections.sort(names, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
Prefer lambdas to anonymous classes
Collections.sort(names, (o1, o2) -> o1.compareTo(o2));
Collections.sort(names, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
Prefer method references to lambdas
Collections.sort(names, String::compareTo);
Collections.sort(names, (o1, o2) -> o1.compareTo(o2));
The Clojure way
(sort names) ;; ("Bruce" "Leo" “Liv”)
(sort-by #(count %) names) ;; ("Bruce" "Leo" “Liv")
(sort-by count names) ;; ("Bruce" "Leo" "Liv")
Anonymous functions
(sort-by (fn [s] (count s)) names) ;; ("Bruce" "Leo" "Liv")
(sort-by #(count %) names) ;; ("Bruce" "Leo" "Liv")
(sort-by count names) ;; ("Bruce" "Leo" "Liv")
Concurrency

• Synchronize access to shared
mutable data

• Avoid excessive
synchronization
Here’s a few reasons
Synchronise access to shared mutable data
class StopThread {
private static boolean stopRequested;
private static synchronized void requestStop() {
stopRequested = true;
}
private static synchronized boolean stopRequested() {
return stopRequested;
}
public static void example3() throws InterruptedException {
Thread backgroundThread = new Thread(() -> {
while (!stopRequested())
System.out.println("going....");
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
requestStop();
}
}
Synchronise access to shared mutable references
(def stop-requested (atom false))
(defn request-stop! []
(reset! stop-requested true))
(defn stop-requested? []
@stop-requested)
(defn example-3 []
(let [background-thread (java.lang.Thread. (fn []
(while (not (stop-requested?))
(prn "going..."))))]
(.start background-thread)
(Thread/sleep 1000)
(request-stop!)))
What about multiple shared
references?
STM - Software Transactional Memory
(def account-a (ref 100))
(def account-b (ref 250))
(defn transfer [amount from to]
(dosync
(alter from #(- % amount))
(alter to #(+ % amount))))
(transfer 25 account-a account-b)
@account-a ;; 75
@account-b ;; 275
Clojure makes it easy to do the
right thing
Let’s revisit example-3
(defn example-3 []
(let [background-thread (java.lang.Thread. (fn []
(while (not @stop-requested)
(prn "going..."))))]
(.start background-thread)
(Thread/sleep 1000)
(request-stop!)))
(defn example-3[]
(future
(while (not @stop-requested)
(prn "going...")))
(Thread/sleep 1000)
(request-stop!))
Concurrency with futures
(def doubler (partial * 2))
(defn service-a [n]
(future
(Thread/sleep 1000)
n))
(defn service-b [n]
(future
(Thread/sleep 1000)
(Math/pow n 2)))
(defn service-c [n]
(future
(Thread/sleep 1000)
(Math/pow n 3)))
(defn service-d [n]
(future
(Thread/sleep 1000)
(Math/pow n 4)))
(let [doubled (doubler @(service-a 10))]
(+ @(service-b doubled)
@(service-c doubled)
@(service-d doubled)))
;; Elapsed time: 4013.746558 msecs
(let [a (service-a 10)
doubled (doubler @a)
b (service-b doubled)
c (service-c doubled)
d (service-d doubled)]
(+ @b @c @d))
Concurrency with futures
(def doubler (partial * 2))
(defn service-a [n]
(future
(Thread/sleep 1000)
n))
(defn service-b [n]
(future
(Thread/sleep 1000)
(Math/pow n 2)))
(defn service-c [n]
(future
(Thread/sleep 1000)
(Math/pow n 3)))
(defn service-d [n]
(future
(Thread/sleep 1000)
(Math/pow n 4)))
(let [doubled (doubler @(service-a 10))]
(+ @(service-b doubled)
@(service-c doubled)
@(service-d doubled)))
;; Elapsed time: 4013.746558 msecs
(let [a (service-a 10)
doubled (doubler @a)
b (service-b doubled)
c (service-c doubled)
d (service-d doubled)]
(+ @b @c @d))
Blocks main thread!
Concurrency with CompletableFutures
static Integer doubler(Integer n) {
return 2 * n;
}
static CompletableFuture<Integer> serviceA(Integer n) {
return CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
return n;
});
}
static CompletableFuture<Integer> serviceB(Integer n) {
return CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
return Double.valueOf(Math.pow(n, 2)).intValue();
});
}
static CompletableFuture<Integer> serviceC(Integer n) {
return CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
return Double.valueOf(Math.pow(n, 3)).intValue();
});
}
Concurrency with CompletableFutures
final CompletableFuture<Integer> doubled = serviceA(10).thenApply(CompletableFutures::doubler);
final CompletableFuture<Integer> resultB = doubled.thenCompose(CompletableFutures::serviceB);
final CompletableFuture<Integer> resultC = doubled.thenCompose(CompletableFutures::serviceC);
CompletableFuture<Void> allFutures = CompletableFuture.allOf(resultB, resultC);
allFutures.whenComplete((v, ex) -> {
try {
System.out.println("Result: " + resultB.get() + " - " + resultC.get());
} catch (Exception e) {
}
});
Concurrency with CompletableFutures
final CompletableFuture<Integer> doubled = serviceA(10).thenApply(CompletableFutures::doubler);
final CompletableFuture<Integer> resultB = doubled.thenCompose(CompletableFutures::serviceB);
final CompletableFuture<Integer> resultC = doubled.thenCompose(CompletableFutures::serviceC);
CompletableFuture<Void> allFutures = CompletableFuture.allOf(resultB, resultC);
allFutures.whenComplete((v, ex) -> {
try {
System.out.println("Result: " + resultB.get() + " - " + resultC.get());
} catch (Exception e) {
}
});
What about Clojure?
What if?
;; Wouldn't it be great to be able to write:
(let [doubled (doubler (service-a 10))
b (service-b doubled)
c (service-c doubled)
d (service-d doubled)]
;; then once that's all done concurrently...
(+ b c d))
Concurrency with imminent
(require '[imminent.core :as i])
(defn service-a [n]
(i/future
(Thread/sleep 1000)
n))
(defn service-b [n]
(i/future
(Thread/sleep 1000)
(Math/pow n 2)))
(defn service-c [n]
(i/future
(Thread/sleep 1000)
(Math/pow n 3)))
(defn service-d [n]
(i/future
(Thread/sleep 1000)
(Math/pow n 4)))
Concurrency with imminent
(let [doubled (i/map (service-a 10) doubler)
b (i/bind doubled service-b)
c (i/bind doubled service-c)
d (i/bind doubled service-d)
result (i/sequence [b c d])]
(i/map result
(fn [[b c d]]
(+ b c d))))
;; Elapsed time: 2025.446899 msecs
Concurrency with imminent
(let [doubled (i/map (service-a 10) doubler)
b (i/bind doubled service-b)
c (i/bind doubled service-c)
d (i/bind doubled service-d)
result (i/sequence [b c d])]
(i/map result
(fn [[b c d]]
(+ b c d))))
;; Elapsed time: 2025.446899 msecs
Concurrency with imminent
(defn f-doubler [n]
(i/const-future (* n 2)))
(i/mdo [a (service-a 10)
doubled (f-doubler a)
b (service-b doubled)
c (service-c doubled)
d (service-d doubled)]
(i/return (+ b c d)))
Concurrency with imminent
(bind
(service-a 10)
(fn* ([a]
(bind
(f-doubler a)
(fn* ([doubled]
(bind
(service-b doubled)
(fn* ([b]
(bind
(service-c doubled) (fn* ([c]
(bind
(service-d doubled)
(fn* ([d]
(i/return (+ b c d))))))))))))))))))
Concurrency with imminent
(bind
(service-a 10)
(fn* ([a]
(bind
(f-doubler a)
(fn* ([doubled]
(bind
(service-b doubled)
(fn* ([b]
(bind
(service-c doubled) (fn* ([c]
(bind
(service-d doubled)
(fn* ([d]
(i/return (+ b c d))))))))))))))))))
;; Elapsed time: 4017.578654 msecs
Concurrency with imminent
(def a+ (i/alift +))
(i/mdo [a (service-a 10)
doubled (f-doubler a)]
(a+ (service-b doubled)
(service-c doubled)
(service-d doubled)))
;; Elapsed time: 2010.171729 msecs
Concurrency with imminent
(def a+ (i/alift +))
(i/mdo [a (service-a 10)
doubled (f-doubler a)]
(a+ (service-b doubled)
(service-c doubled)
(service-d doubled)))
;; Elapsed time: 2010.171729 msecs
What’s with map, bind and
alift?
The algebra of library design
i/map => Functor
i/bind => Monad
i/alift => Applicative
References
• Clojure Reactive Programming - http://bit.ly/cljRp
• Imminent - http://bit.ly/immi-clj
• The Algebra of Library Design - http://bit.ly/2HBBJwJ
• Purely Functional Data Structures - https://amzn.to/2zGZizS
• Java 8 CompletableFuture - http://bit.ly/j8Future
• Java 8 Streams - http://bit.ly/j8stream
• Category Theory - http://amzn.to/1NfL08U
Thank you!
Leonardo Borges

@leonardo_borges

www.leonardoborges.com

www.recordpoint.com
:clojure/south - São Paulo, 2019

More Related Content

What's hot

JavaOne 2013 - Clojure for Java Developers
JavaOne 2013 - Clojure for Java DevelopersJavaOne 2013 - Clojure for Java Developers
JavaOne 2013 - Clojure for Java Developers
Jan Kronquist
 
If You Think You Can Stay Away from Functional Programming, You Are Wrong
If You Think You Can Stay Away from Functional Programming, You Are WrongIf You Think You Can Stay Away from Functional Programming, You Are Wrong
If You Think You Can Stay Away from Functional Programming, You Are Wrong
Mario Fusco
 
(Greach 2015) Dsl'ing your Groovy
(Greach 2015) Dsl'ing your Groovy(Greach 2015) Dsl'ing your Groovy
(Greach 2015) Dsl'ing your Groovy
Alonso Torres
 
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
Jacek Laskowski
 
A Sceptical Guide to Functional Programming
A Sceptical Guide to Functional ProgrammingA Sceptical Guide to Functional Programming
A Sceptical Guide to Functional Programming
Garth Gilmour
 
Why rust?
Why rust?Why rust?
Why rust?
Mats Kindahl
 
Concurrency Concepts in Java
Concurrency Concepts in JavaConcurrency Concepts in Java
Concurrency Concepts in Java
Doug Hawkins
 
C++ Boot Camp Part 2
C++ Boot Camp Part 2C++ Boot Camp Part 2
C++ Boot Camp Part 2
Jesse Talavera-Greenberg
 
Turtle Graphics in Groovy
Turtle Graphics in GroovyTurtle Graphics in Groovy
Turtle Graphics in Groovy
Jim Driscoll
 
Zero-Overhead Metaprogramming: Reflection and Metaobject Protocols Fast and w...
Zero-Overhead Metaprogramming: Reflection and Metaobject Protocols Fast and w...Zero-Overhead Metaprogramming: Reflection and Metaobject Protocols Fast and w...
Zero-Overhead Metaprogramming: Reflection and Metaobject Protocols Fast and w...
Stefan Marr
 
groovy rules
groovy rulesgroovy rules
groovy rules
Paul King
 
core.logic introduction
core.logic introductioncore.logic introduction
core.logic introduction
Norman Richards
 
Building High-Performance Language Implementations With Low Effort
Building High-Performance Language Implementations With Low EffortBuilding High-Performance Language Implementations With Low Effort
Building High-Performance Language Implementations With Low Effort
Stefan Marr
 
Clojure made-simple - John Stevenson
Clojure made-simple - John StevensonClojure made-simple - John Stevenson
Clojure made-simple - John Stevenson
JAX London
 
C# - What's next
C# - What's nextC# - What's next
C# - What's next
Christian Nagel
 
Logic programming a ruby perspective
Logic programming a ruby perspectiveLogic programming a ruby perspective
Logic programming a ruby perspective
Norman Richards
 
OracleCode One 2018: Java 5, 6, 7, 8, 9, 10, 11: What Did You Miss?
OracleCode One 2018: Java 5, 6, 7, 8, 9, 10, 11: What Did You Miss?OracleCode One 2018: Java 5, 6, 7, 8, 9, 10, 11: What Did You Miss?
OracleCode One 2018: Java 5, 6, 7, 8, 9, 10, 11: What Did You Miss?
Henri Tremblay
 
Hw09 Hadoop + Clojure
Hw09   Hadoop + ClojureHw09   Hadoop + Clojure
Hw09 Hadoop + Clojure
Cloudera, Inc.
 
Return of c++
Return of c++Return of c++
Return of c++
Yongwei Wu
 
JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6
Solution4Future
 

What's hot (20)

JavaOne 2013 - Clojure for Java Developers
JavaOne 2013 - Clojure for Java DevelopersJavaOne 2013 - Clojure for Java Developers
JavaOne 2013 - Clojure for Java Developers
 
If You Think You Can Stay Away from Functional Programming, You Are Wrong
If You Think You Can Stay Away from Functional Programming, You Are WrongIf You Think You Can Stay Away from Functional Programming, You Are Wrong
If You Think You Can Stay Away from Functional Programming, You Are Wrong
 
(Greach 2015) Dsl'ing your Groovy
(Greach 2015) Dsl'ing your Groovy(Greach 2015) Dsl'ing your Groovy
(Greach 2015) Dsl'ing your Groovy
 
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
 
A Sceptical Guide to Functional Programming
A Sceptical Guide to Functional ProgrammingA Sceptical Guide to Functional Programming
A Sceptical Guide to Functional Programming
 
Why rust?
Why rust?Why rust?
Why rust?
 
Concurrency Concepts in Java
Concurrency Concepts in JavaConcurrency Concepts in Java
Concurrency Concepts in Java
 
C++ Boot Camp Part 2
C++ Boot Camp Part 2C++ Boot Camp Part 2
C++ Boot Camp Part 2
 
Turtle Graphics in Groovy
Turtle Graphics in GroovyTurtle Graphics in Groovy
Turtle Graphics in Groovy
 
Zero-Overhead Metaprogramming: Reflection and Metaobject Protocols Fast and w...
Zero-Overhead Metaprogramming: Reflection and Metaobject Protocols Fast and w...Zero-Overhead Metaprogramming: Reflection and Metaobject Protocols Fast and w...
Zero-Overhead Metaprogramming: Reflection and Metaobject Protocols Fast and w...
 
groovy rules
groovy rulesgroovy rules
groovy rules
 
core.logic introduction
core.logic introductioncore.logic introduction
core.logic introduction
 
Building High-Performance Language Implementations With Low Effort
Building High-Performance Language Implementations With Low EffortBuilding High-Performance Language Implementations With Low Effort
Building High-Performance Language Implementations With Low Effort
 
Clojure made-simple - John Stevenson
Clojure made-simple - John StevensonClojure made-simple - John Stevenson
Clojure made-simple - John Stevenson
 
C# - What's next
C# - What's nextC# - What's next
C# - What's next
 
Logic programming a ruby perspective
Logic programming a ruby perspectiveLogic programming a ruby perspective
Logic programming a ruby perspective
 
OracleCode One 2018: Java 5, 6, 7, 8, 9, 10, 11: What Did You Miss?
OracleCode One 2018: Java 5, 6, 7, 8, 9, 10, 11: What Did You Miss?OracleCode One 2018: Java 5, 6, 7, 8, 9, 10, 11: What Did You Miss?
OracleCode One 2018: Java 5, 6, 7, 8, 9, 10, 11: What Did You Miss?
 
Hw09 Hadoop + Clojure
Hw09   Hadoop + ClojureHw09   Hadoop + Clojure
Hw09 Hadoop + Clojure
 
Return of c++
Return of c++Return of c++
Return of c++
 
JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6
 

Similar to From Java to Parellel Clojure - Clojure South 2019

Clojure And Swing
Clojure And SwingClojure And Swing
Clojure And Swing
Skills Matter
 
Clojure 1.1 And Beyond
Clojure 1.1 And BeyondClojure 1.1 And Beyond
Clojure 1.1 And Beyond
Mike Fogus
 
Getting started with Clojure
Getting started with ClojureGetting started with Clojure
Getting started with Clojure
John Stevenson
 
Exploring Clojurescript
Exploring ClojurescriptExploring Clojurescript
Exploring Clojurescript
Luke Donnet
 
Pune Clojure Course Outline
Pune Clojure Course OutlinePune Clojure Course Outline
Pune Clojure Course Outline
Baishampayan Ghose
 
Lobos Introduction
Lobos IntroductionLobos Introduction
Lobos Introduction
Nicolas Buduroi
 
ClojureScript for the web
ClojureScript for the webClojureScript for the web
ClojureScript for the web
Michiel Borkent
 
Introduction to clojure
Introduction to clojureIntroduction to clojure
Introduction to clojure
Abbas Raza
 
Clojure for Java developers
Clojure for Java developersClojure for Java developers
Clojure for Java developers
John Stevenson
 
Clojure concurrency
Clojure concurrencyClojure concurrency
Clojure concurrency
Alex Navis
 
Kotlin @ Coupang Backend 2017
Kotlin @ Coupang Backend 2017Kotlin @ Coupang Backend 2017
Kotlin @ Coupang Backend 2017
Sunghyouk Bae
 
Clojure+ClojureScript Webapps
Clojure+ClojureScript WebappsClojure+ClojureScript Webapps
Clojure+ClojureScript Webapps
Falko Riemenschneider
 
TorqueBox: The beauty of Ruby with the power of JBoss. Presented at Devnexus...
TorqueBox: The beauty of Ruby with the power of JBoss.  Presented at Devnexus...TorqueBox: The beauty of Ruby with the power of JBoss.  Presented at Devnexus...
TorqueBox: The beauty of Ruby with the power of JBoss. Presented at Devnexus...
bobmcwhirter
 
Coding in Style
Coding in StyleCoding in Style
Coding in Style
scalaconfjp
 
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
tobiascrawley
 
ClojureScript: The Good Parts
ClojureScript: The Good PartsClojureScript: The Good Parts
ClojureScript: The Good Parts
Kent Ohashi
 
Practical REPL-driven Development with Clojure
Practical REPL-driven Development with ClojurePractical REPL-driven Development with Clojure
Practical REPL-driven Development with Clojure
Kent Ohashi
 
A Survey of Concurrency Constructs
A Survey of Concurrency ConstructsA Survey of Concurrency Constructs
A Survey of Concurrency Constructs
Ted Leung
 
Spock: Test Well and Prosper
Spock: Test Well and ProsperSpock: Test Well and Prosper
Spock: Test Well and Prosper
Ken Kousen
 
Clojure - A new Lisp
Clojure - A new LispClojure - A new Lisp
Clojure - A new Lisp
elliando dias
 

Similar to From Java to Parellel Clojure - Clojure South 2019 (20)

Clojure And Swing
Clojure And SwingClojure And Swing
Clojure And Swing
 
Clojure 1.1 And Beyond
Clojure 1.1 And BeyondClojure 1.1 And Beyond
Clojure 1.1 And Beyond
 
Getting started with Clojure
Getting started with ClojureGetting started with Clojure
Getting started with Clojure
 
Exploring Clojurescript
Exploring ClojurescriptExploring Clojurescript
Exploring Clojurescript
 
Pune Clojure Course Outline
Pune Clojure Course OutlinePune Clojure Course Outline
Pune Clojure Course Outline
 
Lobos Introduction
Lobos IntroductionLobos Introduction
Lobos Introduction
 
ClojureScript for the web
ClojureScript for the webClojureScript for the web
ClojureScript for the web
 
Introduction to clojure
Introduction to clojureIntroduction to clojure
Introduction to clojure
 
Clojure for Java developers
Clojure for Java developersClojure for Java developers
Clojure for Java developers
 
Clojure concurrency
Clojure concurrencyClojure concurrency
Clojure concurrency
 
Kotlin @ Coupang Backend 2017
Kotlin @ Coupang Backend 2017Kotlin @ Coupang Backend 2017
Kotlin @ Coupang Backend 2017
 
Clojure+ClojureScript Webapps
Clojure+ClojureScript WebappsClojure+ClojureScript Webapps
Clojure+ClojureScript Webapps
 
TorqueBox: The beauty of Ruby with the power of JBoss. Presented at Devnexus...
TorqueBox: The beauty of Ruby with the power of JBoss.  Presented at Devnexus...TorqueBox: The beauty of Ruby with the power of JBoss.  Presented at Devnexus...
TorqueBox: The beauty of Ruby with the power of JBoss. Presented at Devnexus...
 
Coding in Style
Coding in StyleCoding in Style
Coding in Style
 
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
 
ClojureScript: The Good Parts
ClojureScript: The Good PartsClojureScript: The Good Parts
ClojureScript: The Good Parts
 
Practical REPL-driven Development with Clojure
Practical REPL-driven Development with ClojurePractical REPL-driven Development with Clojure
Practical REPL-driven Development with Clojure
 
A Survey of Concurrency Constructs
A Survey of Concurrency ConstructsA Survey of Concurrency Constructs
A Survey of Concurrency Constructs
 
Spock: Test Well and Prosper
Spock: Test Well and ProsperSpock: Test Well and Prosper
Spock: Test Well and Prosper
 
Clojure - A new Lisp
Clojure - A new LispClojure - A new Lisp
Clojure - A new Lisp
 

More from Leonardo Borges

Realtime collaboration with Clojure - EuroClojure - Barcelona, 2015
Realtime collaboration with Clojure - EuroClojure - Barcelona, 2015Realtime collaboration with Clojure - EuroClojure - Barcelona, 2015
Realtime collaboration with Clojure - EuroClojure - Barcelona, 2015
Leonardo Borges
 
Parametricity - #cljsyd - May, 2015
Parametricity - #cljsyd - May, 2015Parametricity - #cljsyd - May, 2015
Parametricity - #cljsyd - May, 2015
Leonardo Borges
 
The algebra of library design
The algebra of library designThe algebra of library design
The algebra of library design
Leonardo Borges
 
Futures e abstração - QCon São Paulo 2015
Futures e abstração - QCon São Paulo 2015Futures e abstração - QCon São Paulo 2015
Futures e abstração - QCon São Paulo 2015
Leonardo Borges
 
Functional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsFunctional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event Systems
Leonardo Borges
 
High Performance web apps in Om, React and ClojureScript
High Performance web apps in Om, React and ClojureScriptHigh Performance web apps in Om, React and ClojureScript
High Performance web apps in Om, React and ClojureScript
Leonardo Borges
 
Programação functional reativa: lidando com código assíncrono
Programação functional reativa: lidando com código assíncronoProgramação functional reativa: lidando com código assíncrono
Programação functional reativa: lidando com código assíncrono
Leonardo Borges
 
Monads in Clojure
Monads in ClojureMonads in Clojure
Monads in Clojure
Leonardo Borges
 
Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013
Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013
Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013
Leonardo Borges
 
Intro to Clojure's core.async
Intro to Clojure's core.asyncIntro to Clojure's core.async
Intro to Clojure's core.async
Leonardo Borges
 
Functional Reactive Programming in Clojurescript
Functional Reactive Programming in ClojurescriptFunctional Reactive Programming in Clojurescript
Functional Reactive Programming in Clojurescript
Leonardo Borges
 
Clojure/West 2013 in 30 mins
Clojure/West 2013 in 30 minsClojure/West 2013 in 30 mins
Clojure/West 2013 in 30 mins
Leonardo Borges
 
Clojure Reducers / clj-syd Aug 2012
Clojure Reducers / clj-syd Aug 2012Clojure Reducers / clj-syd Aug 2012
Clojure Reducers / clj-syd Aug 2012
Leonardo Borges
 
The many facets of code reuse in JavaScript
The many facets of code reuse in JavaScriptThe many facets of code reuse in JavaScript
The many facets of code reuse in JavaScript
Leonardo Borges
 
Continuation Passing Style and Macros in Clojure - Jan 2012
Continuation Passing Style and Macros in Clojure - Jan 2012Continuation Passing Style and Macros in Clojure - Jan 2012
Continuation Passing Style and Macros in Clojure - Jan 2012
Leonardo Borges
 
Heroku addons development - Nov 2011
Heroku addons development - Nov 2011Heroku addons development - Nov 2011
Heroku addons development - Nov 2011
Leonardo Borges
 
Clouds against the Floods (RubyConfBR2011)
Clouds against the Floods (RubyConfBR2011) Clouds against the Floods (RubyConfBR2011)
Clouds against the Floods (RubyConfBR2011)
Leonardo Borges
 
Clouds Against the Floods
Clouds Against the FloodsClouds Against the Floods
Clouds Against the Floods
Leonardo Borges
 
Arel in Rails 3
Arel in Rails 3Arel in Rails 3
Arel in Rails 3
Leonardo Borges
 
Testing with Spring
Testing with SpringTesting with Spring
Testing with Spring
Leonardo Borges
 

More from Leonardo Borges (20)

Realtime collaboration with Clojure - EuroClojure - Barcelona, 2015
Realtime collaboration with Clojure - EuroClojure - Barcelona, 2015Realtime collaboration with Clojure - EuroClojure - Barcelona, 2015
Realtime collaboration with Clojure - EuroClojure - Barcelona, 2015
 
Parametricity - #cljsyd - May, 2015
Parametricity - #cljsyd - May, 2015Parametricity - #cljsyd - May, 2015
Parametricity - #cljsyd - May, 2015
 
The algebra of library design
The algebra of library designThe algebra of library design
The algebra of library design
 
Futures e abstração - QCon São Paulo 2015
Futures e abstração - QCon São Paulo 2015Futures e abstração - QCon São Paulo 2015
Futures e abstração - QCon São Paulo 2015
 
Functional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsFunctional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event Systems
 
High Performance web apps in Om, React and ClojureScript
High Performance web apps in Om, React and ClojureScriptHigh Performance web apps in Om, React and ClojureScript
High Performance web apps in Om, React and ClojureScript
 
Programação functional reativa: lidando com código assíncrono
Programação functional reativa: lidando com código assíncronoProgramação functional reativa: lidando com código assíncrono
Programação functional reativa: lidando com código assíncrono
 
Monads in Clojure
Monads in ClojureMonads in Clojure
Monads in Clojure
 
Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013
Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013
Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013
 
Intro to Clojure's core.async
Intro to Clojure's core.asyncIntro to Clojure's core.async
Intro to Clojure's core.async
 
Functional Reactive Programming in Clojurescript
Functional Reactive Programming in ClojurescriptFunctional Reactive Programming in Clojurescript
Functional Reactive Programming in Clojurescript
 
Clojure/West 2013 in 30 mins
Clojure/West 2013 in 30 minsClojure/West 2013 in 30 mins
Clojure/West 2013 in 30 mins
 
Clojure Reducers / clj-syd Aug 2012
Clojure Reducers / clj-syd Aug 2012Clojure Reducers / clj-syd Aug 2012
Clojure Reducers / clj-syd Aug 2012
 
The many facets of code reuse in JavaScript
The many facets of code reuse in JavaScriptThe many facets of code reuse in JavaScript
The many facets of code reuse in JavaScript
 
Continuation Passing Style and Macros in Clojure - Jan 2012
Continuation Passing Style and Macros in Clojure - Jan 2012Continuation Passing Style and Macros in Clojure - Jan 2012
Continuation Passing Style and Macros in Clojure - Jan 2012
 
Heroku addons development - Nov 2011
Heroku addons development - Nov 2011Heroku addons development - Nov 2011
Heroku addons development - Nov 2011
 
Clouds against the Floods (RubyConfBR2011)
Clouds against the Floods (RubyConfBR2011) Clouds against the Floods (RubyConfBR2011)
Clouds against the Floods (RubyConfBR2011)
 
Clouds Against the Floods
Clouds Against the FloodsClouds Against the Floods
Clouds Against the Floods
 
Arel in Rails 3
Arel in Rails 3Arel in Rails 3
Arel in Rails 3
 
Testing with Spring
Testing with SpringTesting with Spring
Testing with Spring
 

Recently uploaded

在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
mz5nrf0n
 
Top Benefits of Using Salesforce Healthcare CRM for Patient Management.pdf
Top Benefits of Using Salesforce Healthcare CRM for Patient Management.pdfTop Benefits of Using Salesforce Healthcare CRM for Patient Management.pdf
Top Benefits of Using Salesforce Healthcare CRM for Patient Management.pdf
VALiNTRY360
 
What next after learning python programming basics
What next after learning python programming basicsWhat next after learning python programming basics
What next after learning python programming basics
Rakesh Kumar R
 
How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?
ToXSL Technologies
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
Łukasz Chruściel
 
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
kalichargn70th171
 
Requirement Traceability in Xen Functional Safety
Requirement Traceability in Xen Functional SafetyRequirement Traceability in Xen Functional Safety
Requirement Traceability in Xen Functional Safety
Ayan Halder
 
Odoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
Odoo ERP Vs. Traditional ERP Systems – A Comparative AnalysisOdoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
Odoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
Envertis Software Solutions
 
Microservice Teams - How the cloud changes the way we work
Microservice Teams - How the cloud changes the way we workMicroservice Teams - How the cloud changes the way we work
Microservice Teams - How the cloud changes the way we work
Sven Peters
 
WWDC 2024 Keynote Review: For CocoaCoders Austin
WWDC 2024 Keynote Review: For CocoaCoders AustinWWDC 2024 Keynote Review: For CocoaCoders Austin
WWDC 2024 Keynote Review: For CocoaCoders Austin
Patrick Weigel
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
Philip Schwarz
 
All you need to know about Spring Boot and GraalVM
All you need to know about Spring Boot and GraalVMAll you need to know about Spring Boot and GraalVM
All you need to know about Spring Boot and GraalVM
Alina Yurenko
 
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
Bert Jan Schrijver
 
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
dakas1
 
Oracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptxOracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptx
Remote DBA Services
 
Malibou Pitch Deck For Its €3M Seed Round
Malibou Pitch Deck For Its €3M Seed RoundMalibou Pitch Deck For Its €3M Seed Round
Malibou Pitch Deck For Its €3M Seed Round
sjcobrien
 
Fundamentals of Programming and Language Processors
Fundamentals of Programming and Language ProcessorsFundamentals of Programming and Language Processors
Fundamentals of Programming and Language Processors
Rakesh Kumar R
 
How to write a program in any programming language
How to write a program in any programming languageHow to write a program in any programming language
How to write a program in any programming language
Rakesh Kumar R
 
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian CompaniesE-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
Quickdice ERP
 
Oracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptxOracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptx
Remote DBA Services
 

Recently uploaded (20)

在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
 
Top Benefits of Using Salesforce Healthcare CRM for Patient Management.pdf
Top Benefits of Using Salesforce Healthcare CRM for Patient Management.pdfTop Benefits of Using Salesforce Healthcare CRM for Patient Management.pdf
Top Benefits of Using Salesforce Healthcare CRM for Patient Management.pdf
 
What next after learning python programming basics
What next after learning python programming basicsWhat next after learning python programming basics
What next after learning python programming basics
 
How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
 
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
 
Requirement Traceability in Xen Functional Safety
Requirement Traceability in Xen Functional SafetyRequirement Traceability in Xen Functional Safety
Requirement Traceability in Xen Functional Safety
 
Odoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
Odoo ERP Vs. Traditional ERP Systems – A Comparative AnalysisOdoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
Odoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
 
Microservice Teams - How the cloud changes the way we work
Microservice Teams - How the cloud changes the way we workMicroservice Teams - How the cloud changes the way we work
Microservice Teams - How the cloud changes the way we work
 
WWDC 2024 Keynote Review: For CocoaCoders Austin
WWDC 2024 Keynote Review: For CocoaCoders AustinWWDC 2024 Keynote Review: For CocoaCoders Austin
WWDC 2024 Keynote Review: For CocoaCoders Austin
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
 
All you need to know about Spring Boot and GraalVM
All you need to know about Spring Boot and GraalVMAll you need to know about Spring Boot and GraalVM
All you need to know about Spring Boot and GraalVM
 
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
 
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
 
Oracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptxOracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptx
 
Malibou Pitch Deck For Its €3M Seed Round
Malibou Pitch Deck For Its €3M Seed RoundMalibou Pitch Deck For Its €3M Seed Round
Malibou Pitch Deck For Its €3M Seed Round
 
Fundamentals of Programming and Language Processors
Fundamentals of Programming and Language ProcessorsFundamentals of Programming and Language Processors
Fundamentals of Programming and Language Processors
 
How to write a program in any programming language
How to write a program in any programming languageHow to write a program in any programming language
How to write a program in any programming language
 
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian CompaniesE-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
 
Oracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptxOracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptx
 

From Java to Parellel Clojure - Clojure South 2019

  • 1. :clojure/south - São Paulo, 2019 From Java to parallel Clojure Leonardo Borges @leonardo_borges www.leonardoborges.com www.recordpoint.com
  • 2. A bit about me • Head of Engineering at RecordPoint • Founder of the Sydney Clojure User Group • Open-source contributor • Author of bouncer and imminent • Author of Clojure Reactive Programming
  • 3. A bit about me • 2nd edition is out now!
  • 5. What we’ll talk about • Being a Lisp on the JVM • Functional Programming strengths • Concurrency and parallelism
  • 6. Java has come a long way… • ForkJoin; • Lambda Expressions; • Method References; • CompletableFutures; • JShell; • Reactive Streams / Stream API; • …and more!
  • 7. So why would you invest in Clojure?
  • 8. Here’s a few reasons
  • 9. Here’s a few reasons Classes and Interfaces • Minimize the accessibility of classes and members • In public classes, use accessor methods, not public fields • Minimize mutability
  • 10. Immutability (def ages [10 20 30]) (def names ["Leo" "Liv" "Bruce"])
  • 11. Immutability (def ages [10 20 30]) (def names ["Leo" "Liv" "Bruce"]) (defrecord Person [fname age]) (def leo (->Person "Leo" 10)) ;; {:fname "Leo", :age 10}
  • 12. Immutability (def ages [10 20 30]) (def names ["Leo" "Liv" "Bruce"]) (defrecord Person [fname age]) (map (fn [fname age] (->Person fname age)) names ages) ;; ({:fname "Leo", :age 10} ;; {:fname "Liv", :age 20} ;; {:fname "Bruce", :age 30})
  • 13. Immutability (def ages [10 20 30]) (def names ["Leo" "Liv" "Bruce"]) (defrecord Person [fname age]) (map ->Person names ages) ;; ({:fname "Leo", :age 10} ;; {:fname "Liv", :age 20} ;; {:fname "Bruce", :age 30})
  • 14. What if we want to add new ages and names?
  • 15. Adding new elements to vectors (def new-ages (conj ages 40)) ;; [10 20 30 40] ages ;; [10 20 30] (def new-names (conj names "Gwen")) ;; ["Leo" "Liv" "Bruce" "Gwen"] names ;; ["Leo" "Liv" "Bruce"]
  • 17. Persistent data structures (def xs ‘(0 1 2)) (def ys ‘(3 4 5))
  • 18. Persistent data structures (def xs ‘(0 1 2)) (def ys ‘(3 4 5)) (def zs (concat xs ys))
  • 19. Persistent data structures (def xs ‘(0 1 2)) (def ys ‘(3 4 5)) (def zs (concat xs ys))
  • 20. Here’s a few reasons Lambdas and Streams • Prefer lambdas to anonymous classes • Prefer method references to lambdas • Favor the use of standard functional interfaces
  • 21. Prefer lambdas to anonymous classes Collections.sort(names, new Comparator<String>() { @Override public int compare(String o1, String o2) { return o1.compareTo(o2); } });
  • 22. Prefer lambdas to anonymous classes Collections.sort(names, (o1, o2) -> o1.compareTo(o2)); Collections.sort(names, new Comparator<String>() { @Override public int compare(String o1, String o2) { return o1.compareTo(o2); } });
  • 23. Prefer method references to lambdas Collections.sort(names, String::compareTo); Collections.sort(names, (o1, o2) -> o1.compareTo(o2));
  • 24. The Clojure way (sort names) ;; ("Bruce" "Leo" “Liv”) (sort-by #(count %) names) ;; ("Bruce" "Leo" “Liv") (sort-by count names) ;; ("Bruce" "Leo" "Liv")
  • 25. Anonymous functions (sort-by (fn [s] (count s)) names) ;; ("Bruce" "Leo" "Liv") (sort-by #(count %) names) ;; ("Bruce" "Leo" "Liv") (sort-by count names) ;; ("Bruce" "Leo" "Liv")
  • 26. Concurrency • Synchronize access to shared mutable data • Avoid excessive synchronization Here’s a few reasons
  • 27. Synchronise access to shared mutable data class StopThread { private static boolean stopRequested; private static synchronized void requestStop() { stopRequested = true; } private static synchronized boolean stopRequested() { return stopRequested; } public static void example3() throws InterruptedException { Thread backgroundThread = new Thread(() -> { while (!stopRequested()) System.out.println("going...."); }); backgroundThread.start(); TimeUnit.SECONDS.sleep(1); requestStop(); } }
  • 28. Synchronise access to shared mutable references (def stop-requested (atom false)) (defn request-stop! [] (reset! stop-requested true)) (defn stop-requested? [] @stop-requested) (defn example-3 [] (let [background-thread (java.lang.Thread. (fn [] (while (not (stop-requested?)) (prn "going..."))))] (.start background-thread) (Thread/sleep 1000) (request-stop!)))
  • 29. What about multiple shared references?
  • 30. STM - Software Transactional Memory (def account-a (ref 100)) (def account-b (ref 250)) (defn transfer [amount from to] (dosync (alter from #(- % amount)) (alter to #(+ % amount)))) (transfer 25 account-a account-b) @account-a ;; 75 @account-b ;; 275
  • 31. Clojure makes it easy to do the right thing
  • 33. (defn example-3 [] (let [background-thread (java.lang.Thread. (fn [] (while (not @stop-requested) (prn "going..."))))] (.start background-thread) (Thread/sleep 1000) (request-stop!)))
  • 34. (defn example-3[] (future (while (not @stop-requested) (prn "going..."))) (Thread/sleep 1000) (request-stop!))
  • 35. Concurrency with futures (def doubler (partial * 2)) (defn service-a [n] (future (Thread/sleep 1000) n)) (defn service-b [n] (future (Thread/sleep 1000) (Math/pow n 2))) (defn service-c [n] (future (Thread/sleep 1000) (Math/pow n 3))) (defn service-d [n] (future (Thread/sleep 1000) (Math/pow n 4))) (let [doubled (doubler @(service-a 10))] (+ @(service-b doubled) @(service-c doubled) @(service-d doubled))) ;; Elapsed time: 4013.746558 msecs (let [a (service-a 10) doubled (doubler @a) b (service-b doubled) c (service-c doubled) d (service-d doubled)] (+ @b @c @d))
  • 36. Concurrency with futures (def doubler (partial * 2)) (defn service-a [n] (future (Thread/sleep 1000) n)) (defn service-b [n] (future (Thread/sleep 1000) (Math/pow n 2))) (defn service-c [n] (future (Thread/sleep 1000) (Math/pow n 3))) (defn service-d [n] (future (Thread/sleep 1000) (Math/pow n 4))) (let [doubled (doubler @(service-a 10))] (+ @(service-b doubled) @(service-c doubled) @(service-d doubled))) ;; Elapsed time: 4013.746558 msecs (let [a (service-a 10) doubled (doubler @a) b (service-b doubled) c (service-c doubled) d (service-d doubled)] (+ @b @c @d)) Blocks main thread!
  • 37. Concurrency with CompletableFutures static Integer doubler(Integer n) { return 2 * n; } static CompletableFuture<Integer> serviceA(Integer n) { return CompletableFuture.supplyAsync(() -> { try { Thread.sleep(1000); } catch (InterruptedException e) { } return n; }); } static CompletableFuture<Integer> serviceB(Integer n) { return CompletableFuture.supplyAsync(() -> { try { Thread.sleep(1000); } catch (InterruptedException e) { } return Double.valueOf(Math.pow(n, 2)).intValue(); }); } static CompletableFuture<Integer> serviceC(Integer n) { return CompletableFuture.supplyAsync(() -> { try { Thread.sleep(1000); } catch (InterruptedException e) { } return Double.valueOf(Math.pow(n, 3)).intValue(); }); }
  • 38. Concurrency with CompletableFutures final CompletableFuture<Integer> doubled = serviceA(10).thenApply(CompletableFutures::doubler); final CompletableFuture<Integer> resultB = doubled.thenCompose(CompletableFutures::serviceB); final CompletableFuture<Integer> resultC = doubled.thenCompose(CompletableFutures::serviceC); CompletableFuture<Void> allFutures = CompletableFuture.allOf(resultB, resultC); allFutures.whenComplete((v, ex) -> { try { System.out.println("Result: " + resultB.get() + " - " + resultC.get()); } catch (Exception e) { } });
  • 39. Concurrency with CompletableFutures final CompletableFuture<Integer> doubled = serviceA(10).thenApply(CompletableFutures::doubler); final CompletableFuture<Integer> resultB = doubled.thenCompose(CompletableFutures::serviceB); final CompletableFuture<Integer> resultC = doubled.thenCompose(CompletableFutures::serviceC); CompletableFuture<Void> allFutures = CompletableFuture.allOf(resultB, resultC); allFutures.whenComplete((v, ex) -> { try { System.out.println("Result: " + resultB.get() + " - " + resultC.get()); } catch (Exception e) { } });
  • 41. What if? ;; Wouldn't it be great to be able to write: (let [doubled (doubler (service-a 10)) b (service-b doubled) c (service-c doubled) d (service-d doubled)] ;; then once that's all done concurrently... (+ b c d))
  • 42. Concurrency with imminent (require '[imminent.core :as i]) (defn service-a [n] (i/future (Thread/sleep 1000) n)) (defn service-b [n] (i/future (Thread/sleep 1000) (Math/pow n 2))) (defn service-c [n] (i/future (Thread/sleep 1000) (Math/pow n 3))) (defn service-d [n] (i/future (Thread/sleep 1000) (Math/pow n 4)))
  • 43. Concurrency with imminent (let [doubled (i/map (service-a 10) doubler) b (i/bind doubled service-b) c (i/bind doubled service-c) d (i/bind doubled service-d) result (i/sequence [b c d])] (i/map result (fn [[b c d]] (+ b c d)))) ;; Elapsed time: 2025.446899 msecs
  • 44. Concurrency with imminent (let [doubled (i/map (service-a 10) doubler) b (i/bind doubled service-b) c (i/bind doubled service-c) d (i/bind doubled service-d) result (i/sequence [b c d])] (i/map result (fn [[b c d]] (+ b c d)))) ;; Elapsed time: 2025.446899 msecs
  • 45. Concurrency with imminent (defn f-doubler [n] (i/const-future (* n 2))) (i/mdo [a (service-a 10) doubled (f-doubler a) b (service-b doubled) c (service-c doubled) d (service-d doubled)] (i/return (+ b c d)))
  • 46. Concurrency with imminent (bind (service-a 10) (fn* ([a] (bind (f-doubler a) (fn* ([doubled] (bind (service-b doubled) (fn* ([b] (bind (service-c doubled) (fn* ([c] (bind (service-d doubled) (fn* ([d] (i/return (+ b c d))))))))))))))))))
  • 47. Concurrency with imminent (bind (service-a 10) (fn* ([a] (bind (f-doubler a) (fn* ([doubled] (bind (service-b doubled) (fn* ([b] (bind (service-c doubled) (fn* ([c] (bind (service-d doubled) (fn* ([d] (i/return (+ b c d)))))))))))))))))) ;; Elapsed time: 4017.578654 msecs
  • 48. Concurrency with imminent (def a+ (i/alift +)) (i/mdo [a (service-a 10) doubled (f-doubler a)] (a+ (service-b doubled) (service-c doubled) (service-d doubled))) ;; Elapsed time: 2010.171729 msecs
  • 49. Concurrency with imminent (def a+ (i/alift +)) (i/mdo [a (service-a 10) doubled (f-doubler a)] (a+ (service-b doubled) (service-c doubled) (service-d doubled))) ;; Elapsed time: 2010.171729 msecs
  • 50. What’s with map, bind and alift?
  • 51. The algebra of library design i/map => Functor i/bind => Monad i/alift => Applicative
  • 52. References • Clojure Reactive Programming - http://bit.ly/cljRp • Imminent - http://bit.ly/immi-clj • The Algebra of Library Design - http://bit.ly/2HBBJwJ • Purely Functional Data Structures - https://amzn.to/2zGZizS • Java 8 CompletableFuture - http://bit.ly/j8Future • Java 8 Streams - http://bit.ly/j8stream • Category Theory - http://amzn.to/1NfL08U