SlideShare a Scribd company logo
1 of 60
Download to read offline
LEONARDO BORGES • SENIOR CLOJURE ENGINEER • @LEONARDO_BORGES
O futuro chegou:
Programação concorrente com futures
SOBRE
Um pouco sobre mim
• Senior Clojure Engineer na
Atlassian, Sydney
• Fundador do Grupo de Usuários
Clojure de Sydney
• Autor de Clojure Reactive
Programming - http://bit.ly/cljRp
* QCon discount code: CRP10
CONCORRÊNCIA
FUTURES
O quê?
ABSTRAÇÃO
COMPOSIÇÃO
Futures em Java <= 1.7
FUTURES EM JAVA <= 1.7
static ExecutorService es = Executors.newCachedThreadPool();
static Integer doubler(Integer n) {
return 2 * n;
}
static Future<Integer> serviceA(Integer n) {
return es.submit(() -> {
Thread.sleep(1000);
return n;
});
}
static Future<Integer> serviceB(Integer n) {
return es.submit(() -> {
Thread.sleep(1500);
return Double.valueOf(Math.pow(n, 2)).intValue();
});
}
static Future<Integer> serviceC(Integer n) {
return es.submit(() -> {
Thread.sleep(2000);
return Double.valueOf(Math.pow(n, 3)).intValue();
});
}
FUTURES EM JAVA <= 1.7
Integer doubled = doubler(serviceA(10).get());
System.out.println("Couldn't do anything else while the line above was being executed...");
System.out.println("Result: " + serviceB(doubled).get() + " - " + serviceC(doubled).get());
Bloqueia a thread
Bloqueia a thread Bloqueia a thread
• Desperdício de processamento
Problemas
• Desperdício de processamento
• Baixo nível de composição
Problemas
E no Java 8?
FUTURES NO JAVA 8
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) {}
});
System.out.println("Doing other important things...");
FUTURES NO JAVA 8
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) {}
});
System.out.println("Doing other important things...");
Não bloqueia a thread
Esses
combinadores são
familiares?
STREAMS NO JAVA 8
List<Integer> ns = Arrays.asList(1, 2, 3, 4);
Function<Integer, Integer> doubler = (i) -> i * 2;
System.out.println(ns.stream().map(doubler).collect(Collectors.toList()));
// [2, 4, 6, 8]
Function<Integer, Stream<? extends Integer>> toRange = (i) -> IntStream.range(0, i).boxed();
Stream<Integer> combined = ns.stream()
.map(doubler)
.flatMap(toRange);
System.out.println(combined.collect(Collectors.toList()));
// [0, 1, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7]
Streams vs Futures
Stream<R> map(Function<? super T, ? extends R> mapper) {…}
Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper) {…}
CompletableFuture<U> thenApply(Function<? super T,? extends U> fn) {…}
CompletableFuture<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn) {…}
Streams vs Futures
Stream<R> map(Function<? super T, ? extends R> mapper) {…}
Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper) {…}
CompletableFuture<U> thenApply (Function<? super T,? extends U> fn) {…}
CompletableFuture<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn) {…}
E se quisermos
escrever funções
que funcionem com
Streams e Futures?
SEQUENCING FUTURES
CompletableFuture<Collection<Integer>> result =
sequence(serviceA(10), serviceB(10), serviceC(10));
// java.util.concurrent.CompletableFuture[10, 100, 1000]
SEQUENCING FUTURES
static <A> CompletableFuture<Collection<A>> sequence(CompletableFuture<A>... cfs) {
return Arrays.asList(cfs).stream().reduce(
CompletableFuture.completedFuture(new ArrayList<>()),
(acc, future) ->
acc.thenCompose((xs) ->
future.thenApply((x) -> {
xs.add(x);
return xs;
})),
(a, b) ->
a.thenCompose((xs) ->
b.thenApply((ys) -> {
xs.addAll(ys);
return xs;
})));
}
SEQUENCING FUTURES
static <A> CompletableFuture<Collection<A>> sequence(CompletableFuture<A>... cfs) {
return Arrays.asList(cfs).stream().reduce(
CompletableFuture.completedFuture(new ArrayList<>()),
(acc, future) ->
acc.thenCompose((xs) ->
future.thenApply((x) -> {
xs.add(x);
return xs;
})),
(a, b) ->
a.thenCompose((xs) ->
b.thenApply((ys) -> {
xs.addAll(ys);
return xs;
})));
}
SEQUENCING FUTURES
static <A> CompletableFuture<Collection<A>> sequence(CompletableFuture<A>... cfs) {
return Arrays.asList(cfs).stream().reduce(
CompletableFuture.completedFuture(new ArrayList<>()),
(acc, future) ->
acc.thenCompose((xs) ->
future.thenApply((x) -> {
xs.add(x);
return xs;
})),
(a, b) ->
a.thenCompose((xs) ->
b.thenApply((ys) -> {
xs.addAll(ys);
return xs;
})));
}
SEQUENCING FUTURES
static <A> CompletableFuture<Collection<A>> sequence(CompletableFuture<A>... cfs) {
return Arrays.asList(cfs).stream().reduce(
CompletableFuture.completedFuture(new ArrayList<>()),
(acc, future) ->
acc.thenCompose((xs) ->
future.thenApply((x) -> {
xs.add(x);
return xs;
})),
(a, b) ->
a.thenCompose((xs) ->
b.thenApply((ys) -> {
xs.addAll(ys);
return xs;
})));
}
SEQUENCING FUTURES
static <A> CompletableFuture<Collection<A>> sequence(CompletableFuture<A>... cfs) {
return Arrays.asList(cfs).stream().reduce(
CompletableFuture.completedFuture(new ArrayList<>()),
(acc, future) ->
acc.thenCompose((xs) ->
future.thenApply((x) -> {
xs.add(x);
return xs;
})),
(a, b) ->
a.thenCompose((xs) ->
b.thenApply((ys) -> {
xs.addAll(ys);
return xs;
})));
}
SEQUENCING STREAMS
Stream<Integer> s1 = Arrays.asList(1).stream();
Stream<Integer> s2 = Arrays.asList(2).stream();
Stream<Integer> s3 = Arrays.asList(3).stream();
sequenceS(s1, s2, s3)
// [[1, 2, 3]]
SEQUENCING STREAMS
static <A> Stream<Stream<A>> sequenceS(Stream<A>... cfs) {
return Arrays.asList(cfs).stream().reduce(
Stream.of(Stream.empty()),
(acc, coll) ->
acc.flatMap((xs) ->
coll.map((x) ->
Stream.concat(xs, Stream.of(x)))),
(acc, coll) -> acc.flatMap((xs) ->
coll.map((x) ->
Stream.concat(xs, x))));
}
SEQUENCING STREAMS
static <A> Stream<Stream<A>> sequenceS(Stream<A>... cfs) {
return Arrays.asList(cfs).stream().reduce(
Stream.of(Stream.empty()),
(acc, coll) ->
acc.flatMap((xs) ->
coll.map((x) ->
Stream.concat(xs, Stream.of(x)))),
(acc, coll) -> acc.flatMap((xs) ->
coll.map((x) ->
Stream.concat(xs, x))));
}
SEQUENCING STREAMS
static <A> Stream<Stream<A>> sequenceS(Stream<A>... cfs) {
return Arrays.asList(cfs).stream().reduce(
Stream.of(Stream.empty()),
(acc, coll) ->
acc.flatMap((xs) ->
coll.map((x) ->
Stream.concat(xs, Stream.of(x)))),
(acc, coll) -> acc.flatMap((xs) ->
coll.map((x) ->
Stream.concat(xs, x))));
}
SEQUENCING STREAMS
static <A> Stream<Stream<A>> sequenceS(Stream<A>... cfs) {
return Arrays.asList(cfs).stream().reduce(
Stream.of(Stream.empty()),
(acc, coll) ->
acc.flatMap((xs) ->
coll.map((x) ->
Stream.concat(xs, Stream.of(x)))),
(acc, coll) -> acc.flatMap((xs) ->
coll.map((x) ->
Stream.concat(xs, x))));
}
Perceberam alguma
semelhança?
FUTURES VS STREAMS
static <A> Stream<Stream<A>> sequenceS(Stream<A>... cfs) {
return Arrays.asList(cfs).stream().reduce(
Stream.of(Stream.empty()),
(acc, coll) ->
acc.flatMap((xs) ->
coll.map((x) ->
Stream.concat(xs, Stream.of(x)))),
(acc, coll) -> acc.flatMap((xs) ->
coll.map((x) ->
Stream.concat(xs, x))));
}
static <A> CompletableFuture<Collection<A>> sequence(CompletableFuture<A>... cfs) {
return Arrays.asList(cfs).stream().reduce(
CompletableFuture.completedFuture(new ArrayList<>()),
(acc, future) -> acc.thenCompose((xs) ->
future.thenApply((x) -> {
xs.add(x);
return xs;
})),
(a, b) -> a.thenCompose((xs) ->
b.thenApply((ys) -> {
xs.addAll(ys);
return xs;
})));
}
FUTURES VS STREAMS
static <A> Stream<Stream<A>> sequenceS(Stream<A>... cfs) {
return Arrays.asList(cfs).stream().reduce(
Stream.of(Stream.empty()),
(acc, coll) ->
acc.flatMap((xs) ->
coll.map((x) ->
Stream.concat(xs, Stream.of(x)))),
(acc, coll) -> acc.flatMap((xs) ->
coll.map((x) ->
Stream.concat(xs, x))));
}
static <A> CompletableFuture<Collection<A>> sequence(CompletableFuture<A>... cfs) {
return Arrays.asList(cfs).stream().reduce(
CompletableFuture.completedFuture(new ArrayList<>()),
(acc, future) -> acc.thenCompose((xs) ->
future.thenApply((x) -> {
xs.add(x);
return xs;
})),
(a, b) -> a.thenCompose((xs) ->
b.thenApply((ys) -> {
xs.addAll(ys);
return xs;
})));
}
FlatMappable
FLATMAPPABLE
<M extends FlatMappable, A> M<List<A>> sequence(M<A>... ma) {
…
}
• Java não suporta tipos de alta
espécie (higher kinded types)
• Tipos de alta espécie são
indispensáveis ao se implementar
tais abstrações
Chegando no limite do sistema
de tipos
Colocando nome nos
bois
FlatMappable se chama Monad
trait Monad[F[_]] {
def point[A](a: => A): F[A]
def bind[A, B](a: F[A])(f: A => F[B]): F[B]
def map[A, B](a: F[A])(f: A => B): F[B] = bind(a)(b => point(f(b)))
}
FlatMappable se chama Monad
trait Monad[F[_]] {
def point[A](a: => A): F[A]
def bind[A, B](a: F[A])(f: A => F[B]): F[B]
def map[A, B](a: F[A])(f: A => B): F[B] = bind(a)(b => point(f(b)))
}
Tipos de alta espécie em ação
MONADS EM SCALA
O Monad de Futures
implicit def FutureMonad: Monad[Future] = new Monad[Future] {
def point[A](a: => A) = Future.successful(a)
def bind[A, B](a: Future[A])(f: A => Future[B]): Future[B] = a flatMap f
}
MONADS EM SCALA
O Monad de Listas
implicit def ListMonad: Monad[List] = new Monad[List] {
def point[A](a: => A) = List(a)
def bind[A, B](a: List[A])(f: A => List[B]): List[B] = a flatMap f
}
MONADS EM SCALA
Implementando sequence
def sequence[M[_] : Monad, A](ma: List[M[A]]): M[List[A]] = {
ma.foldLeft(Monad[M].point(List(): List[A]))((acc, m) =>
acc.flatMap((xs) =>
m.map((x) =>
xs :+ x))
)
}
Being abstract is something profoundly
different from being vague … The purpose of
abstraction is not to be vague, but to create a
new semantic level in which one can be
absolutely precise.
EDSGER W. DIJKSTRA
”
“
MONADS EM SCALA
Sequencing
val resultF: Future[List[Integer]] = sequence(List(serviceA(10), serviceB(10), serviceC(10)))
println(Await.result(resultF, Duration(2, "seconds")))
// List(10, 100, 1000)
val resultL: List[List[Int]] = sequence(List(List(1,2,3), List(4,5,6), List(7,8,9)))
println(resultL)
// List(List(1, 4, 7), List(2, 4, 7), List(3, 4, 7), List(1, 5, 7), ...)
Demais! O quê mais
podemos fazer??
Folding
FOLDING
List(2, 3, 4).reduce(_+_)
//9
FOLDING
List(2, 3, 4).reduce(_+_)
//9
val intFutures = List(Future.successful(1),
Future.successful(2),
Future.successful(3))
val result: Future[Int] = sequence(intFurures).map((x) => x.reduce(_ + _))
//…Future[9]
Existe algo em
comum?
Introduzindo Foldable
trait Foldable[F[_]] { self =>
…
def fold[M: Monoid](t: F[M]): M = ???
}
Introduzindo Monoids
trait Monoid[F] { self =>
def zero: F
def append(f1: F, f2: => F): F
}
Introduzindo Monoids: Ints
implicit def intMonoid: Monoid[Int] = new Monoid[Int] {
def zero: Int = 0
def append(f1: Int, f2: => Int): Int = f1 + f2
}
Introduzindo Monoids: Ints
implicit def intMonoid: Monoid[Int] = new Monoid[Int] {
def zero: Int = 0
def append(f1: Int, f2: => Int): Int = f1 + f2
}
Foldable[List].fold(List(2, 3, 4)))
//9
Introduzindo Monoids: Futures
Introduzindo Monoids: Futures
implicit def futureFreeMonoid[A] = new Monoid[Future[List[A]]] {
def zero: Future[List[A]] = Future.successful(List())
def append(f1: Future[List[A]], f2: => Future[List[A]]) = for {
a1 <- f1
a2 <- f2
} yield a1 ++ a2
}
Introduzindo Monoids: Futures
implicit def futureFreeMonoid[A] = new Monoid[Future[List[A]]] {
def zero: Future[List[A]] = Future.successful(List())
def append(f1: Future[List[A]], f2: => Future[List[A]]) = for {
a1 <- f1
a2 <- f2
} yield a1 ++ a2
}
Foldable[List].fold(List(Future.successful(2),
Future.successful(3),
Future.successful(4)))
//…Future[9]
Monad, Foldable e
Monoid são apenas
o começo
Em Scala, muitas
delas já foram
implementadas em
Scalaz
A Teoria das
Categorias pode ter
um impacto grande
na criação de
bibliotecas
Being abstract is something profoundly
different from being vague … The purpose of
abstraction is not to be vague, but to create a
new semantic level in which one can be
absolutely precise.
EDSGER W. DIJKSTRA
”
“
Referências
• Clojure Reactive Programming - http://bit.ly/cljRp
• Java 8 CompletableFuture - http://bit.ly/j8Future
• Java 8 Streams - http://bit.ly/j8stream
• Category Theory - http://amzn.to/1NfL08U
• Free Monoids - http://en.wikipedia.org/wiki/Free_monoid
• Scalaz - https://github.com/scalaz/scalaz
• Fluokitten (Clojure) - https://github.com/uncomplicate/fluokitten
Obrigado!
LEONARDO BORGES • SENIOR CLOJURE DEVELOPER • @LEONARDO_BORGES
Q&A
We are hiring!
LEONARDO BORGES • SENIOR CLOJURE DEVELOPER • @LEONARDO_BORGES

More Related Content

What's hot

TCO in Python via bytecode manipulation.
TCO in Python via bytecode manipulation.TCO in Python via bytecode manipulation.
TCO in Python via bytecode manipulation.lnikolaeva
 
Humble introduction to category theory in haskell
Humble introduction to category theory in haskellHumble introduction to category theory in haskell
Humble introduction to category theory in haskellJongsoo Lee
 
Scala introduction
Scala introductionScala introduction
Scala introductionvito jeng
 
Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)stasimus
 
The best language in the world
The best language in the worldThe best language in the world
The best language in the worldDavid Muñoz Díaz
 
T3chFest 2016 - The polyglot programmer
T3chFest 2016 - The polyglot programmerT3chFest 2016 - The polyglot programmer
T3chFest 2016 - The polyglot programmerDavid Muñoz Díaz
 
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...John De Goes
 
Lambda выражения и Java 8
Lambda выражения и Java 8Lambda выражения и Java 8
Lambda выражения и Java 8Alex Tumanoff
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Jonas Bonér
 
TI1220 Lecture 6: First-class Functions
TI1220 Lecture 6: First-class FunctionsTI1220 Lecture 6: First-class Functions
TI1220 Lecture 6: First-class FunctionsEelco Visser
 
Scala vs Java 8 in a Java 8 World
Scala vs Java 8 in a Java 8 WorldScala vs Java 8 in a Java 8 World
Scala vs Java 8 in a Java 8 WorldBTI360
 
Monadologie
MonadologieMonadologie
Monadologieleague
 
미려한 UI/UX를 위한 여정
미려한 UI/UX를 위한 여정미려한 UI/UX를 위한 여정
미려한 UI/UX를 위한 여정SeungChul Kang
 
GUL UC3M - Introduction to functional programming
GUL UC3M - Introduction to functional programmingGUL UC3M - Introduction to functional programming
GUL UC3M - Introduction to functional programmingDavid Muñoz Díaz
 
Rainer Grimm, “Functional Programming in C++11”
Rainer Grimm, “Functional Programming in C++11”Rainer Grimm, “Functional Programming in C++11”
Rainer Grimm, “Functional Programming in C++11”Platonov Sergey
 
First-Class Patterns
First-Class PatternsFirst-Class Patterns
First-Class PatternsJohn De Goes
 
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵Wanbok Choi
 

What's hot (20)

TCO in Python via bytecode manipulation.
TCO in Python via bytecode manipulation.TCO in Python via bytecode manipulation.
TCO in Python via bytecode manipulation.
 
Humble introduction to category theory in haskell
Humble introduction to category theory in haskellHumble introduction to category theory in haskell
Humble introduction to category theory in haskell
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)
 
The best language in the world
The best language in the worldThe best language in the world
The best language in the world
 
T3chFest 2016 - The polyglot programmer
T3chFest 2016 - The polyglot programmerT3chFest 2016 - The polyglot programmer
T3chFest 2016 - The polyglot programmer
 
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
 
Lambda выражения и Java 8
Lambda выражения и Java 8Lambda выражения и Java 8
Lambda выражения и Java 8
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)
 
TI1220 Lecture 6: First-class Functions
TI1220 Lecture 6: First-class FunctionsTI1220 Lecture 6: First-class Functions
TI1220 Lecture 6: First-class Functions
 
Scala vs Java 8 in a Java 8 World
Scala vs Java 8 in a Java 8 WorldScala vs Java 8 in a Java 8 World
Scala vs Java 8 in a Java 8 World
 
Monadologie
MonadologieMonadologie
Monadologie
 
미려한 UI/UX를 위한 여정
미려한 UI/UX를 위한 여정미려한 UI/UX를 위한 여정
미려한 UI/UX를 위한 여정
 
GUL UC3M - Introduction to functional programming
GUL UC3M - Introduction to functional programmingGUL UC3M - Introduction to functional programming
GUL UC3M - Introduction to functional programming
 
ECMAScript 6
ECMAScript 6ECMAScript 6
ECMAScript 6
 
Joy of scala
Joy of scalaJoy of scala
Joy of scala
 
Rainer Grimm, “Functional Programming in C++11”
Rainer Grimm, “Functional Programming in C++11”Rainer Grimm, “Functional Programming in C++11”
Rainer Grimm, “Functional Programming in C++11”
 
First-Class Patterns
First-Class PatternsFirst-Class Patterns
First-Class Patterns
 
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
 
Eta
EtaEta
Eta
 

Viewers also liked

Amplify - TDD on Android with Robolectric
Amplify - TDD on Android with RobolectricAmplify - TDD on Android with Robolectric
Amplify - TDD on Android with Robolectricjurgiles
 
groovy databases
groovy databasesgroovy databases
groovy databasesPaul King
 
Introduction to functional programming using Ocaml
Introduction to functional programming using OcamlIntroduction to functional programming using Ocaml
Introduction to functional programming using Ocamlpramode_ce
 
Excel virginia.l imprimir
Excel virginia.l imprimirExcel virginia.l imprimir
Excel virginia.l imprimirVirginiaLope
 
Sample Work: Virtual Shaping
Sample Work: Virtual ShapingSample Work: Virtual Shaping
Sample Work: Virtual Shapingscott_stiefvater
 
The algebra of library design
The algebra of library designThe algebra of library design
The algebra of library designLeonardo Borges
 
Functional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsFunctional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsLeonardo Borges
 

Viewers also liked (10)

Amplify - TDD on Android with Robolectric
Amplify - TDD on Android with RobolectricAmplify - TDD on Android with Robolectric
Amplify - TDD on Android with Robolectric
 
Monads in Clojure
Monads in ClojureMonads in Clojure
Monads in Clojure
 
Groovy Monads
Groovy MonadsGroovy Monads
Groovy Monads
 
groovy databases
groovy databasesgroovy databases
groovy databases
 
Introduction to functional programming using Ocaml
Introduction to functional programming using OcamlIntroduction to functional programming using Ocaml
Introduction to functional programming using Ocaml
 
Excel virginia.l imprimir
Excel virginia.l imprimirExcel virginia.l imprimir
Excel virginia.l imprimir
 
Sample Work: Virtual Shaping
Sample Work: Virtual ShapingSample Work: Virtual Shaping
Sample Work: Virtual Shaping
 
Android TDD & CI
Android TDD & CIAndroid TDD & CI
Android TDD & CI
 
The algebra of library design
The algebra of library designThe algebra of library design
The algebra of library design
 
Functional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsFunctional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event Systems
 

Similar to Futures e abstração - QCon São Paulo 2015

Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with ClojureDmitry Buzdin
 
関数潮流(Function Tendency)
関数潮流(Function Tendency)関数潮流(Function Tendency)
関数潮流(Function Tendency)riue
 
Mary Had a Little λ (QCon)
Mary Had a Little λ (QCon)Mary Had a Little λ (QCon)
Mary Had a Little λ (QCon)Stephen Chin
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on AndroidTomáš Kypta
 
SF Scala meet up, lighting talk: SPA -- Scala JDBC wrapper
SF Scala meet up, lighting talk: SPA -- Scala JDBC wrapperSF Scala meet up, lighting talk: SPA -- Scala JDBC wrapper
SF Scala meet up, lighting talk: SPA -- Scala JDBC wrapperChester Chen
 
Transducers in JavaScript
Transducers in JavaScriptTransducers in JavaScript
Transducers in JavaScriptPavel Forkert
 
Luis Atencio on RxJS
Luis Atencio on RxJSLuis Atencio on RxJS
Luis Atencio on RxJSLuis Atencio
 

Similar to Futures e abstração - QCon São Paulo 2015 (20)

Spark_Documentation_Template1
Spark_Documentation_Template1Spark_Documentation_Template1
Spark_Documentation_Template1
 
Spark workshop
Spark workshopSpark workshop
Spark workshop
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
関数潮流(Function Tendency)
関数潮流(Function Tendency)関数潮流(Function Tendency)
関数潮流(Function Tendency)
 
Rxjs marble-testing
Rxjs marble-testingRxjs marble-testing
Rxjs marble-testing
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to Scala
 
Rxjs swetugg
Rxjs swetuggRxjs swetugg
Rxjs swetugg
 
Rxjs vienna
Rxjs viennaRxjs vienna
Rxjs vienna
 
Seminar PSU 10.10.2014 mme
Seminar PSU 10.10.2014 mmeSeminar PSU 10.10.2014 mme
Seminar PSU 10.10.2014 mme
 
Mary Had a Little λ (QCon)
Mary Had a Little λ (QCon)Mary Had a Little λ (QCon)
Mary Had a Little λ (QCon)
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
What is new in Java 8
What is new in Java 8What is new in Java 8
What is new in Java 8
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on Android
 
SF Scala meet up, lighting talk: SPA -- Scala JDBC wrapper
SF Scala meet up, lighting talk: SPA -- Scala JDBC wrapperSF Scala meet up, lighting talk: SPA -- Scala JDBC wrapper
SF Scala meet up, lighting talk: SPA -- Scala JDBC wrapper
 
Millionways
MillionwaysMillionways
Millionways
 
Transducers in JavaScript
Transducers in JavaScriptTransducers in JavaScript
Transducers in JavaScript
 
Luis Atencio on RxJS
Luis Atencio on RxJSLuis Atencio on RxJS
Luis Atencio on RxJS
 

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, 2015Leonardo Borges
 
Parametricity - #cljsyd - May, 2015
Parametricity - #cljsyd - May, 2015Parametricity - #cljsyd - May, 2015
Parametricity - #cljsyd - May, 2015Leonardo Borges
 
From Java to Parellel Clojure - Clojure South 2019
From Java to Parellel Clojure - Clojure South 2019From Java to Parellel Clojure - Clojure South 2019
From Java to Parellel Clojure - Clojure South 2019Leonardo 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 ClojureScriptLeonardo 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íncronoLeonardo 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 2013Leonardo Borges
 
Intro to Clojure's core.async
Intro to Clojure's core.asyncIntro to Clojure's core.async
Intro to Clojure's core.asyncLeonardo Borges
 
Functional Reactive Programming in Clojurescript
Functional Reactive Programming in ClojurescriptFunctional Reactive Programming in Clojurescript
Functional Reactive Programming in ClojurescriptLeonardo Borges
 
Clojure/West 2013 in 30 mins
Clojure/West 2013 in 30 minsClojure/West 2013 in 30 mins
Clojure/West 2013 in 30 minsLeonardo Borges
 
Clojure Reducers / clj-syd Aug 2012
Clojure Reducers / clj-syd Aug 2012Clojure Reducers / clj-syd Aug 2012
Clojure Reducers / clj-syd Aug 2012Leonardo 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 JavaScriptLeonardo Borges
 
Heroku addons development - Nov 2011
Heroku addons development - Nov 2011Heroku addons development - Nov 2011
Heroku addons development - Nov 2011Leonardo 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 FloodsLeonardo Borges
 

More from Leonardo Borges (17)

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
 
From Java to Parellel Clojure - Clojure South 2019
From Java to Parellel Clojure - Clojure South 2019From Java to Parellel Clojure - Clojure South 2019
From Java to Parellel Clojure - Clojure South 2019
 
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
 
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
 
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
 
JRuby in The Enterprise
JRuby in The EnterpriseJRuby in The Enterprise
JRuby in The Enterprise
 

Recently uploaded

Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 

Recently uploaded (20)

Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 

Futures e abstração - QCon São Paulo 2015

  • 1. LEONARDO BORGES • SENIOR CLOJURE ENGINEER • @LEONARDO_BORGES O futuro chegou: Programação concorrente com futures
  • 2. SOBRE Um pouco sobre mim • Senior Clojure Engineer na Atlassian, Sydney • Fundador do Grupo de Usuários Clojure de Sydney • Autor de Clojure Reactive Programming - http://bit.ly/cljRp * QCon discount code: CRP10
  • 5. FUTURES EM JAVA <= 1.7 static ExecutorService es = Executors.newCachedThreadPool(); static Integer doubler(Integer n) { return 2 * n; } static Future<Integer> serviceA(Integer n) { return es.submit(() -> { Thread.sleep(1000); return n; }); } static Future<Integer> serviceB(Integer n) { return es.submit(() -> { Thread.sleep(1500); return Double.valueOf(Math.pow(n, 2)).intValue(); }); } static Future<Integer> serviceC(Integer n) { return es.submit(() -> { Thread.sleep(2000); return Double.valueOf(Math.pow(n, 3)).intValue(); }); }
  • 6. FUTURES EM JAVA <= 1.7 Integer doubled = doubler(serviceA(10).get()); System.out.println("Couldn't do anything else while the line above was being executed..."); System.out.println("Result: " + serviceB(doubled).get() + " - " + serviceC(doubled).get()); Bloqueia a thread Bloqueia a thread Bloqueia a thread
  • 7. • Desperdício de processamento Problemas
  • 8. • Desperdício de processamento • Baixo nível de composição Problemas
  • 10. FUTURES NO JAVA 8 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) {} }); System.out.println("Doing other important things...");
  • 11. FUTURES NO JAVA 8 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) {} }); System.out.println("Doing other important things..."); Não bloqueia a thread
  • 13. STREAMS NO JAVA 8 List<Integer> ns = Arrays.asList(1, 2, 3, 4); Function<Integer, Integer> doubler = (i) -> i * 2; System.out.println(ns.stream().map(doubler).collect(Collectors.toList())); // [2, 4, 6, 8] Function<Integer, Stream<? extends Integer>> toRange = (i) -> IntStream.range(0, i).boxed(); Stream<Integer> combined = ns.stream() .map(doubler) .flatMap(toRange); System.out.println(combined.collect(Collectors.toList())); // [0, 1, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7]
  • 14. Streams vs Futures Stream<R> map(Function<? super T, ? extends R> mapper) {…} Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper) {…} CompletableFuture<U> thenApply(Function<? super T,? extends U> fn) {…} CompletableFuture<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn) {…}
  • 15. Streams vs Futures Stream<R> map(Function<? super T, ? extends R> mapper) {…} Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper) {…} CompletableFuture<U> thenApply (Function<? super T,? extends U> fn) {…} CompletableFuture<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn) {…}
  • 16. E se quisermos escrever funções que funcionem com Streams e Futures?
  • 17. SEQUENCING FUTURES CompletableFuture<Collection<Integer>> result = sequence(serviceA(10), serviceB(10), serviceC(10)); // java.util.concurrent.CompletableFuture[10, 100, 1000]
  • 18. SEQUENCING FUTURES static <A> CompletableFuture<Collection<A>> sequence(CompletableFuture<A>... cfs) { return Arrays.asList(cfs).stream().reduce( CompletableFuture.completedFuture(new ArrayList<>()), (acc, future) -> acc.thenCompose((xs) -> future.thenApply((x) -> { xs.add(x); return xs; })), (a, b) -> a.thenCompose((xs) -> b.thenApply((ys) -> { xs.addAll(ys); return xs; }))); }
  • 19. SEQUENCING FUTURES static <A> CompletableFuture<Collection<A>> sequence(CompletableFuture<A>... cfs) { return Arrays.asList(cfs).stream().reduce( CompletableFuture.completedFuture(new ArrayList<>()), (acc, future) -> acc.thenCompose((xs) -> future.thenApply((x) -> { xs.add(x); return xs; })), (a, b) -> a.thenCompose((xs) -> b.thenApply((ys) -> { xs.addAll(ys); return xs; }))); }
  • 20. SEQUENCING FUTURES static <A> CompletableFuture<Collection<A>> sequence(CompletableFuture<A>... cfs) { return Arrays.asList(cfs).stream().reduce( CompletableFuture.completedFuture(new ArrayList<>()), (acc, future) -> acc.thenCompose((xs) -> future.thenApply((x) -> { xs.add(x); return xs; })), (a, b) -> a.thenCompose((xs) -> b.thenApply((ys) -> { xs.addAll(ys); return xs; }))); }
  • 21. SEQUENCING FUTURES static <A> CompletableFuture<Collection<A>> sequence(CompletableFuture<A>... cfs) { return Arrays.asList(cfs).stream().reduce( CompletableFuture.completedFuture(new ArrayList<>()), (acc, future) -> acc.thenCompose((xs) -> future.thenApply((x) -> { xs.add(x); return xs; })), (a, b) -> a.thenCompose((xs) -> b.thenApply((ys) -> { xs.addAll(ys); return xs; }))); }
  • 22. SEQUENCING FUTURES static <A> CompletableFuture<Collection<A>> sequence(CompletableFuture<A>... cfs) { return Arrays.asList(cfs).stream().reduce( CompletableFuture.completedFuture(new ArrayList<>()), (acc, future) -> acc.thenCompose((xs) -> future.thenApply((x) -> { xs.add(x); return xs; })), (a, b) -> a.thenCompose((xs) -> b.thenApply((ys) -> { xs.addAll(ys); return xs; }))); }
  • 23. SEQUENCING STREAMS Stream<Integer> s1 = Arrays.asList(1).stream(); Stream<Integer> s2 = Arrays.asList(2).stream(); Stream<Integer> s3 = Arrays.asList(3).stream(); sequenceS(s1, s2, s3) // [[1, 2, 3]]
  • 24. SEQUENCING STREAMS static <A> Stream<Stream<A>> sequenceS(Stream<A>... cfs) { return Arrays.asList(cfs).stream().reduce( Stream.of(Stream.empty()), (acc, coll) -> acc.flatMap((xs) -> coll.map((x) -> Stream.concat(xs, Stream.of(x)))), (acc, coll) -> acc.flatMap((xs) -> coll.map((x) -> Stream.concat(xs, x)))); }
  • 25. SEQUENCING STREAMS static <A> Stream<Stream<A>> sequenceS(Stream<A>... cfs) { return Arrays.asList(cfs).stream().reduce( Stream.of(Stream.empty()), (acc, coll) -> acc.flatMap((xs) -> coll.map((x) -> Stream.concat(xs, Stream.of(x)))), (acc, coll) -> acc.flatMap((xs) -> coll.map((x) -> Stream.concat(xs, x)))); }
  • 26. SEQUENCING STREAMS static <A> Stream<Stream<A>> sequenceS(Stream<A>... cfs) { return Arrays.asList(cfs).stream().reduce( Stream.of(Stream.empty()), (acc, coll) -> acc.flatMap((xs) -> coll.map((x) -> Stream.concat(xs, Stream.of(x)))), (acc, coll) -> acc.flatMap((xs) -> coll.map((x) -> Stream.concat(xs, x)))); }
  • 27. SEQUENCING STREAMS static <A> Stream<Stream<A>> sequenceS(Stream<A>... cfs) { return Arrays.asList(cfs).stream().reduce( Stream.of(Stream.empty()), (acc, coll) -> acc.flatMap((xs) -> coll.map((x) -> Stream.concat(xs, Stream.of(x)))), (acc, coll) -> acc.flatMap((xs) -> coll.map((x) -> Stream.concat(xs, x)))); }
  • 29. FUTURES VS STREAMS static <A> Stream<Stream<A>> sequenceS(Stream<A>... cfs) { return Arrays.asList(cfs).stream().reduce( Stream.of(Stream.empty()), (acc, coll) -> acc.flatMap((xs) -> coll.map((x) -> Stream.concat(xs, Stream.of(x)))), (acc, coll) -> acc.flatMap((xs) -> coll.map((x) -> Stream.concat(xs, x)))); } static <A> CompletableFuture<Collection<A>> sequence(CompletableFuture<A>... cfs) { return Arrays.asList(cfs).stream().reduce( CompletableFuture.completedFuture(new ArrayList<>()), (acc, future) -> acc.thenCompose((xs) -> future.thenApply((x) -> { xs.add(x); return xs; })), (a, b) -> a.thenCompose((xs) -> b.thenApply((ys) -> { xs.addAll(ys); return xs; }))); }
  • 30. FUTURES VS STREAMS static <A> Stream<Stream<A>> sequenceS(Stream<A>... cfs) { return Arrays.asList(cfs).stream().reduce( Stream.of(Stream.empty()), (acc, coll) -> acc.flatMap((xs) -> coll.map((x) -> Stream.concat(xs, Stream.of(x)))), (acc, coll) -> acc.flatMap((xs) -> coll.map((x) -> Stream.concat(xs, x)))); } static <A> CompletableFuture<Collection<A>> sequence(CompletableFuture<A>... cfs) { return Arrays.asList(cfs).stream().reduce( CompletableFuture.completedFuture(new ArrayList<>()), (acc, future) -> acc.thenCompose((xs) -> future.thenApply((x) -> { xs.add(x); return xs; })), (a, b) -> a.thenCompose((xs) -> b.thenApply((ys) -> { xs.addAll(ys); return xs; }))); }
  • 32. FLATMAPPABLE <M extends FlatMappable, A> M<List<A>> sequence(M<A>... ma) { … }
  • 33. • Java não suporta tipos de alta espécie (higher kinded types) • Tipos de alta espécie são indispensáveis ao se implementar tais abstrações Chegando no limite do sistema de tipos
  • 35. FlatMappable se chama Monad trait Monad[F[_]] { def point[A](a: => A): F[A] def bind[A, B](a: F[A])(f: A => F[B]): F[B] def map[A, B](a: F[A])(f: A => B): F[B] = bind(a)(b => point(f(b))) }
  • 36. FlatMappable se chama Monad trait Monad[F[_]] { def point[A](a: => A): F[A] def bind[A, B](a: F[A])(f: A => F[B]): F[B] def map[A, B](a: F[A])(f: A => B): F[B] = bind(a)(b => point(f(b))) } Tipos de alta espécie em ação
  • 37. MONADS EM SCALA O Monad de Futures implicit def FutureMonad: Monad[Future] = new Monad[Future] { def point[A](a: => A) = Future.successful(a) def bind[A, B](a: Future[A])(f: A => Future[B]): Future[B] = a flatMap f }
  • 38. MONADS EM SCALA O Monad de Listas implicit def ListMonad: Monad[List] = new Monad[List] { def point[A](a: => A) = List(a) def bind[A, B](a: List[A])(f: A => List[B]): List[B] = a flatMap f }
  • 39. MONADS EM SCALA Implementando sequence def sequence[M[_] : Monad, A](ma: List[M[A]]): M[List[A]] = { ma.foldLeft(Monad[M].point(List(): List[A]))((acc, m) => acc.flatMap((xs) => m.map((x) => xs :+ x)) ) }
  • 40. Being abstract is something profoundly different from being vague … The purpose of abstraction is not to be vague, but to create a new semantic level in which one can be absolutely precise. EDSGER W. DIJKSTRA ” “
  • 41. MONADS EM SCALA Sequencing val resultF: Future[List[Integer]] = sequence(List(serviceA(10), serviceB(10), serviceC(10))) println(Await.result(resultF, Duration(2, "seconds"))) // List(10, 100, 1000) val resultL: List[List[Int]] = sequence(List(List(1,2,3), List(4,5,6), List(7,8,9))) println(resultL) // List(List(1, 4, 7), List(2, 4, 7), List(3, 4, 7), List(1, 5, 7), ...)
  • 42. Demais! O quê mais podemos fazer??
  • 45. FOLDING List(2, 3, 4).reduce(_+_) //9 val intFutures = List(Future.successful(1), Future.successful(2), Future.successful(3)) val result: Future[Int] = sequence(intFurures).map((x) => x.reduce(_ + _)) //…Future[9]
  • 47. Introduzindo Foldable trait Foldable[F[_]] { self => … def fold[M: Monoid](t: F[M]): M = ??? }
  • 48. Introduzindo Monoids trait Monoid[F] { self => def zero: F def append(f1: F, f2: => F): F }
  • 49. Introduzindo Monoids: Ints implicit def intMonoid: Monoid[Int] = new Monoid[Int] { def zero: Int = 0 def append(f1: Int, f2: => Int): Int = f1 + f2 }
  • 50. Introduzindo Monoids: Ints implicit def intMonoid: Monoid[Int] = new Monoid[Int] { def zero: Int = 0 def append(f1: Int, f2: => Int): Int = f1 + f2 } Foldable[List].fold(List(2, 3, 4))) //9
  • 52. Introduzindo Monoids: Futures implicit def futureFreeMonoid[A] = new Monoid[Future[List[A]]] { def zero: Future[List[A]] = Future.successful(List()) def append(f1: Future[List[A]], f2: => Future[List[A]]) = for { a1 <- f1 a2 <- f2 } yield a1 ++ a2 }
  • 53. Introduzindo Monoids: Futures implicit def futureFreeMonoid[A] = new Monoid[Future[List[A]]] { def zero: Future[List[A]] = Future.successful(List()) def append(f1: Future[List[A]], f2: => Future[List[A]]) = for { a1 <- f1 a2 <- f2 } yield a1 ++ a2 } Foldable[List].fold(List(Future.successful(2), Future.successful(3), Future.successful(4))) //…Future[9]
  • 54. Monad, Foldable e Monoid são apenas o começo
  • 55. Em Scala, muitas delas já foram implementadas em Scalaz
  • 56. A Teoria das Categorias pode ter um impacto grande na criação de bibliotecas
  • 57. Being abstract is something profoundly different from being vague … The purpose of abstraction is not to be vague, but to create a new semantic level in which one can be absolutely precise. EDSGER W. DIJKSTRA ” “
  • 58. Referências • Clojure Reactive Programming - http://bit.ly/cljRp • Java 8 CompletableFuture - http://bit.ly/j8Future • Java 8 Streams - http://bit.ly/j8stream • Category Theory - http://amzn.to/1NfL08U • Free Monoids - http://en.wikipedia.org/wiki/Free_monoid • Scalaz - https://github.com/scalaz/scalaz • Fluokitten (Clojure) - https://github.com/uncomplicate/fluokitten
  • 59. Obrigado! LEONARDO BORGES • SENIOR CLOJURE DEVELOPER • @LEONARDO_BORGES Q&A
  • 60. We are hiring! LEONARDO BORGES • SENIOR CLOJURE DEVELOPER • @LEONARDO_BORGES