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
Ad

More Related Content

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
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
 
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
 
Concurrency Concepts in Java
Concurrency Concepts in JavaConcurrency Concepts in Java
Concurrency Concepts in Java
Doug Hawkins
 
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
 
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
 
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
 
JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6
Solution4Future
 

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

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
 
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
 
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
 
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
 
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
 
Ad

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
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
 
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
 
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
 
Ad

Recently uploaded (20)

Wilcom Embroidery Studio Crack Free Latest 2025
Wilcom Embroidery Studio Crack Free Latest 2025Wilcom Embroidery Studio Crack Free Latest 2025
Wilcom Embroidery Studio Crack Free Latest 2025
Web Designer
 
sequencediagrams.pptx software Engineering
sequencediagrams.pptx software Engineeringsequencediagrams.pptx software Engineering
sequencediagrams.pptx software Engineering
aashrithakondapalli8
 
How to Troubleshoot 9 Types of OutOfMemoryError
How to Troubleshoot 9 Types of OutOfMemoryErrorHow to Troubleshoot 9 Types of OutOfMemoryError
How to Troubleshoot 9 Types of OutOfMemoryError
Tier1 app
 
Download MathType Crack Version 2025???
Download MathType Crack  Version 2025???Download MathType Crack  Version 2025???
Download MathType Crack Version 2025???
Google
 
The Elixir Developer - All Things Open
The Elixir Developer - All Things OpenThe Elixir Developer - All Things Open
The Elixir Developer - All Things Open
Carlo Gilmar Padilla Santana
 
Sequence Diagrams With Pictures (1).pptx
Sequence Diagrams With Pictures (1).pptxSequence Diagrams With Pictures (1).pptx
Sequence Diagrams With Pictures (1).pptx
aashrithakondapalli8
 
Adobe InDesign Crack FREE Download 2025 link
Adobe InDesign Crack FREE Download 2025 linkAdobe InDesign Crack FREE Download 2025 link
Adobe InDesign Crack FREE Download 2025 link
mahmadzubair09
 
Wilcom Embroidery Studio Crack 2025 For Windows
Wilcom Embroidery Studio Crack 2025 For WindowsWilcom Embroidery Studio Crack 2025 For Windows
Wilcom Embroidery Studio Crack 2025 For Windows
Google
 
Mobile Application Developer Dubai | Custom App Solutions by Ajath
Mobile Application Developer Dubai | Custom App Solutions by AjathMobile Application Developer Dubai | Custom App Solutions by Ajath
Mobile Application Developer Dubai | Custom App Solutions by Ajath
Ajath Infotech Technologies LLC
 
Best HR and Payroll Software in Bangladesh - accordHRM
Best HR and Payroll Software in Bangladesh - accordHRMBest HR and Payroll Software in Bangladesh - accordHRM
Best HR and Payroll Software in Bangladesh - accordHRM
accordHRM
 
Download 4k Video Downloader Crack Pre-Activated
Download 4k Video Downloader Crack Pre-ActivatedDownload 4k Video Downloader Crack Pre-Activated
Download 4k Video Downloader Crack Pre-Activated
Web Designer
 
Reinventing Microservices Efficiency and Innovation with Single-Runtime
Reinventing Microservices Efficiency and Innovation with Single-RuntimeReinventing Microservices Efficiency and Innovation with Single-Runtime
Reinventing Microservices Efficiency and Innovation with Single-Runtime
Natan Silnitsky
 
Programs as Values - Write code and don't get lost
Programs as Values - Write code and don't get lostPrograms as Values - Write code and don't get lost
Programs as Values - Write code and don't get lost
Pierangelo Cecchetto
 
From Vibe Coding to Vibe Testing - Complete PowerPoint Presentation
From Vibe Coding to Vibe Testing - Complete PowerPoint PresentationFrom Vibe Coding to Vibe Testing - Complete PowerPoint Presentation
From Vibe Coding to Vibe Testing - Complete PowerPoint Presentation
Shay Ginsbourg
 
wAIred_LearnWithOutAI_JCON_14052025.pptx
wAIred_LearnWithOutAI_JCON_14052025.pptxwAIred_LearnWithOutAI_JCON_14052025.pptx
wAIred_LearnWithOutAI_JCON_14052025.pptx
SimonedeGijt
 
Autodesk Inventor Crack (2025) Latest
Autodesk Inventor    Crack (2025) LatestAutodesk Inventor    Crack (2025) Latest
Autodesk Inventor Crack (2025) Latest
Google
 
NYC ACE 08-May-2025-Combined Presentation.pdf
NYC ACE 08-May-2025-Combined Presentation.pdfNYC ACE 08-May-2025-Combined Presentation.pdf
NYC ACE 08-May-2025-Combined Presentation.pdf
AUGNYC
 
[gbgcpp] Let's get comfortable with concepts
[gbgcpp] Let's get comfortable with concepts[gbgcpp] Let's get comfortable with concepts
[gbgcpp] Let's get comfortable with concepts
Dimitrios Platis
 
Deploying & Testing Agentforce - End-to-end with Copado - Ewenb Clark
Deploying & Testing Agentforce - End-to-end with Copado - Ewenb ClarkDeploying & Testing Agentforce - End-to-end with Copado - Ewenb Clark
Deploying & Testing Agentforce - End-to-end with Copado - Ewenb Clark
Peter Caitens
 
GC Tuning: A Masterpiece in Performance Engineering
GC Tuning: A Masterpiece in Performance EngineeringGC Tuning: A Masterpiece in Performance Engineering
GC Tuning: A Masterpiece in Performance Engineering
Tier1 app
 
Wilcom Embroidery Studio Crack Free Latest 2025
Wilcom Embroidery Studio Crack Free Latest 2025Wilcom Embroidery Studio Crack Free Latest 2025
Wilcom Embroidery Studio Crack Free Latest 2025
Web Designer
 
sequencediagrams.pptx software Engineering
sequencediagrams.pptx software Engineeringsequencediagrams.pptx software Engineering
sequencediagrams.pptx software Engineering
aashrithakondapalli8
 
How to Troubleshoot 9 Types of OutOfMemoryError
How to Troubleshoot 9 Types of OutOfMemoryErrorHow to Troubleshoot 9 Types of OutOfMemoryError
How to Troubleshoot 9 Types of OutOfMemoryError
Tier1 app
 
Download MathType Crack Version 2025???
Download MathType Crack  Version 2025???Download MathType Crack  Version 2025???
Download MathType Crack Version 2025???
Google
 
Sequence Diagrams With Pictures (1).pptx
Sequence Diagrams With Pictures (1).pptxSequence Diagrams With Pictures (1).pptx
Sequence Diagrams With Pictures (1).pptx
aashrithakondapalli8
 
Adobe InDesign Crack FREE Download 2025 link
Adobe InDesign Crack FREE Download 2025 linkAdobe InDesign Crack FREE Download 2025 link
Adobe InDesign Crack FREE Download 2025 link
mahmadzubair09
 
Wilcom Embroidery Studio Crack 2025 For Windows
Wilcom Embroidery Studio Crack 2025 For WindowsWilcom Embroidery Studio Crack 2025 For Windows
Wilcom Embroidery Studio Crack 2025 For Windows
Google
 
Mobile Application Developer Dubai | Custom App Solutions by Ajath
Mobile Application Developer Dubai | Custom App Solutions by AjathMobile Application Developer Dubai | Custom App Solutions by Ajath
Mobile Application Developer Dubai | Custom App Solutions by Ajath
Ajath Infotech Technologies LLC
 
Best HR and Payroll Software in Bangladesh - accordHRM
Best HR and Payroll Software in Bangladesh - accordHRMBest HR and Payroll Software in Bangladesh - accordHRM
Best HR and Payroll Software in Bangladesh - accordHRM
accordHRM
 
Download 4k Video Downloader Crack Pre-Activated
Download 4k Video Downloader Crack Pre-ActivatedDownload 4k Video Downloader Crack Pre-Activated
Download 4k Video Downloader Crack Pre-Activated
Web Designer
 
Reinventing Microservices Efficiency and Innovation with Single-Runtime
Reinventing Microservices Efficiency and Innovation with Single-RuntimeReinventing Microservices Efficiency and Innovation with Single-Runtime
Reinventing Microservices Efficiency and Innovation with Single-Runtime
Natan Silnitsky
 
Programs as Values - Write code and don't get lost
Programs as Values - Write code and don't get lostPrograms as Values - Write code and don't get lost
Programs as Values - Write code and don't get lost
Pierangelo Cecchetto
 
From Vibe Coding to Vibe Testing - Complete PowerPoint Presentation
From Vibe Coding to Vibe Testing - Complete PowerPoint PresentationFrom Vibe Coding to Vibe Testing - Complete PowerPoint Presentation
From Vibe Coding to Vibe Testing - Complete PowerPoint Presentation
Shay Ginsbourg
 
wAIred_LearnWithOutAI_JCON_14052025.pptx
wAIred_LearnWithOutAI_JCON_14052025.pptxwAIred_LearnWithOutAI_JCON_14052025.pptx
wAIred_LearnWithOutAI_JCON_14052025.pptx
SimonedeGijt
 
Autodesk Inventor Crack (2025) Latest
Autodesk Inventor    Crack (2025) LatestAutodesk Inventor    Crack (2025) Latest
Autodesk Inventor Crack (2025) Latest
Google
 
NYC ACE 08-May-2025-Combined Presentation.pdf
NYC ACE 08-May-2025-Combined Presentation.pdfNYC ACE 08-May-2025-Combined Presentation.pdf
NYC ACE 08-May-2025-Combined Presentation.pdf
AUGNYC
 
[gbgcpp] Let's get comfortable with concepts
[gbgcpp] Let's get comfortable with concepts[gbgcpp] Let's get comfortable with concepts
[gbgcpp] Let's get comfortable with concepts
Dimitrios Platis
 
Deploying & Testing Agentforce - End-to-end with Copado - Ewenb Clark
Deploying & Testing Agentforce - End-to-end with Copado - Ewenb ClarkDeploying & Testing Agentforce - End-to-end with Copado - Ewenb Clark
Deploying & Testing Agentforce - End-to-end with Copado - Ewenb Clark
Peter Caitens
 
GC Tuning: A Masterpiece in Performance Engineering
GC Tuning: A Masterpiece in Performance EngineeringGC Tuning: A Masterpiece in Performance Engineering
GC Tuning: A Masterpiece in Performance Engineering
Tier1 app
 

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
  翻译: