SlideShare uma empresa Scribd logo
1 de 60
Baixar para ler 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

Mais conteúdo relacionado

Mais procurados

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
 

Mais procurados (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
 

Destaque

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
 

Destaque (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
 

Semelhante a 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
 

Semelhante a 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
 

Mais de 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
 

Mais de 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
 

Último

TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 

Último (20)

TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 

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