SlideShare a Scribd company logo
1
Blazing Fast, Pure
Effects without
Monads
LambdaConf 2018
By John A. De Goes — @jdegoes
2
1991 1998 2018 - April
Eugenio Moggi John Hughes Flavio Brasil
F R O M M O N A D S T O A R R O W S
A brief history of effects leading to KleisliIO.
KleisliIO
2018 - June
Notions of
computation
and monads
Generalizing
monads to
arrows
TraneIO:
Arrows & tasks
in Scala
3
THE TRINITY OF FP
Total
Deterministic
Free of Side-effects
4
THE TRINITY OF FUNCTIONAL PROGRAMMING
Total
Deterministic
Free of Side-effects
f : A => B
a ∈ A ⇒ f(a) ∈ B
5
THE TRINITY OF FUNCTIONAL PROGRAMMING
Total
Deterministic
Free of Side-effects
def notTotal1(a: Int): String = null
def notTotal2(a: Int): String =
throw new Error(" ")
def notTotal3(a: Int): String = notTotal3(a)
6
THE TRINITY OF FUNCTIONAL PROGRAMMING
Total
Deterministic
Free of Side-effects
f : A => B
b1 = f(a) ∧ b2 = f(a) ⇒ b1 = b2
7
THE TRINITY OF FUNCTIONAL PROGRAMMING
Total
Deterministic
Free of Side-effects
def notDeterministic1(a: Int): String =
if (Math.random() > 0.5) "Hello"
else "Goodbye"
def notDeterministic2(a: Int): String =
scala.io.StdIn.readLine()
def notDeterministic3(a: Int): String =
(System.nanoTime() + a).toString
8
THE TRINITY OF FUNCTIONAL PROGRAMMING
Total
Deterministic
Free of Side-effects
f : A => B
f’s only computational effect is computing B
9
THE TRINITY OF FUNCTIONAL PROGRAMMING
Total
Deterministic
Free of Side-effects
def notEffectFree1(a: Int): String =
{ println("Hello"); a.toString }
def notEffectFree2(a: Int): String = {
val _ = scala.io.StdIn.readLine()
a.toString
}
def notEffectFree3(a: Int): String =
{ Logger.log(a); (a * a).toString }
10
THE RICHES OF PURITY
Type Reasoning
Equality Reasoning
11
Type Reasoning
Equality Reasoning
def foo1[A](a: A): A
def foo2[A](a: A, f: A => A): A
def foo3[A, B](f: (A => A) => B): B
THE RICHES OF PURITY
12
Type Reasoning
Equality Reasoning
def println(line: String): Unit
def readLine(): String
THE RICHES OF PURITY
13
Type Reasoning
Equality Reasoning
def f = (x: Int) => x * x
val b = f(a)
val c = b + b
// c = b + b
// c = f(a) + f(a)
// c = (a * a) + (a * a)
// c = 2 * a * a
THE RICHES OF PURITY
14
Type Reasoning
Equality Reasoning
def readLine = scala.io.StdIn.readLine()
val a = readLine
val b = a + a
// b = a + a
// b = readLine + readLine
// !?!?! readLine + readLine !=
// { val a = readLine; a + a }
THE RICHES OF PURITY
15
MONADIC EFFECTS
Effects Into Values
Values Into Effects
The Cost of Value Effects
16
17
EFFECTS INTO VALUES
def println(line: String): Unit
println
IO[Unit]
String
def println(line: String): IO[Unit]
18
EFFECTS INTO VALUES
IO[A]
Immutable value produced by the effect
Immutable value describing the effect
19
EFFECTS INTO VALUES
sealed trait IO[A] {
def map[B](f: A => B): IO[B] =
flatMap((a: A) => IO.point(f(a)))
def flatMap[B](f: A => IO[B]): IO[B] =
FlatMap(this, f)
}
object IO {
def point[A](a: A): IO[A] = Point(a)
}
final case class PrintLn(line: String) extends IO[Unit]
final case class ReadLine() extends IO[String]
final case class FlatMap[A, B](fa: IO[A], f: A => IO[B]) extends IO[B]
final case class Point[A](a: A) extends IO[A]
20
def readLine(): String
def println(line: String): Unit
val name = readLine()
println("Hello " + name + ", how are you?")
EFFECTS INTO VALUES
println
IO[Unit]
def readLine: IO[String]
def println(line: String): IO[Unit]
val program =
for {
name <- readLine
_ <- println("Hello " + name + ", how are you?")
} yield ()
readLine
IO[String]
String
Unit
21
VALUES INTO EFFECTS
def unsafePerformIO(io: IO[A]): A = io match {
case PrintLn(line) => println(line)
case ReadLine() => readLine()
case FlatMap(fa, f) =>
unsafePerformIO(f(unsafePerformIO(fa)))
case Point(a) => a
}
22
THE COST OF VALUE EFFECTS
println
F[Unit]
class SS {
for {
name <- readLine
_ <- println("Hello " + name +
", how are you?")
} yield ()
readLine
F[String]
String
Unit
23
THE COST OF VALUE EFFECTS
readLine.flatMap(name =>
printLn("Hello, " + name +
", how are you?"))
Allocations
Allocation
Megamorphic
Dispatch
24
THE COST OF VALUE EFFECTS
1 Statement in Procedural
Programming
4 Extra Allocations, 1 Extra
Megamorphic Dispatch in
Functional Programming
=
25
IO.sync {
App.main()
}
THE COST OF VALUE EFFECTS
Monolith Composed
Pure Values
26
THE COST OF VALUE EFFECTS
Future
27
KLEISLI EFFECTS
Effects Into Values
Values Into Effects
The Cost of Value Effects
28
29
EFFECTS INTO VALUES
def println(line: String): Unit
println
FunctionIO[String, Unit]
val println: FunctionIO[String, Unit]
30
EFFECTS INTO VALUES
FunctionIO[A, B]
Immutable input value to the function
Immutable value describing the effectful function
Immutable output value from the function
31
EFFECTS INTO VALUES
final case class FunctionIO[A, B](apply0: A => IO[B])
extends (A => IO[B]) {
def apply(a: A): IO[B] = apply0(a)
def andThen[C](f: FunctionIO[B, C]): FunctionIO[A, C] =
FunctionIO(a => apply(a).flatMap(f.apply))
}
object FunctionIO {
def lift[A, B](f: A => B): FunctionIO[A, B] =
FunctionIO(IO.point.compose(f))
}
32
def readLine(): String
def println(line: String): Unit
val name = readLine()
println("Hello " + name + ", how are you?")
EFFECTS INTO VALUES
val readLine: FunctionIO[Unit, String]
val println: FunctionIO[String, Unit]
val program =
readLine
.andThen(lift((name: String) => "Hello, " + name +
", how are you?"))
.andThen(println)
readLine
FunctionIO[Unit, String]
<anonymous>
FunctionIO[String,String]
println
FunctionIO[String, Unit]
33
VALUES INTO EFFECTS
val program: FunctionIO[Unit, Unit]
unsafePerformIO(program())
34
THE COST OF EFFECT VALUES
readLine.andThen(lift((name: String) =>
"Hello, " + name + ", how are you?"))
.andThen(println)
readLine
FunctionIO[Unit, String]
<anonymous>
FunctionIO[String,String]
println
FunctionIO[String, Unit]
35
Megamorphic
Dispatches
final case class FunctionIO[A, B](apply: A => IO[B])
THE COST OF EFFECT VALUES
readLine.andThen(println)
Allocations Allocations
36
THE COST OF EFFECT VALUES
1 Statement in Procedural
Programming
6 Extra Allocations, 3 Extra
Megamorphic Dispatches in
Functional Programming
=
37
THE PROMISE OF KLEISLIIO
sealed trait FunctionIO[A, B] extends (A => IO[B]) { ... }
final class Pure[A, B](val apply0: A => IO[B])
extends FunctionIO[A, B] {
def apply(a: A): IO[B] = apply0(a)
}
final class Impure[A, B](val apply0: A => B)
extends FunctionIO[A, B] {
def apply(a: A): IO[B] = IO.point(apply0(a))
}
val readLine: FunctionIO[Unit, String] =
new Impure(_ => scala.io.StdIn.readLine())
val printLn: FunctionIO[String, Unit] = new Impure(println)
38
THE PROMISE OF KLEISLIIO
class Impure[A, B](val apply0: A => B)
1 Invocation in Procedural
Programming
0 Extra Allocations,
1 Extra Dispatch in
Functional Programming
=
39
KLEISLIIO
Running KleisliIO
Constructing KleisliIO
Composing KleisliIO
Introducing KleisliIO
Optimizing KleisliIO
Testing KleisliIO
40
KLEISLIIO
sealed trait KleisliIO[E, A, B] extends (A => IO[E, B]) { ... }
object KleisliIO {
class KleisliIOError[E](error: E) extends Throwable {
def unsafeCoerce[E2] = error.asInstanceOf[E2]
}
class Pure[E, A, B](apply0: A => IO[E, B]) extends KleisliIO[E, A, B] {
override final def apply(a: A): IO[E, B] = apply0(a)
}
class Impure[E, A, B](val apply0: A => B) extends KleisliIO[E, A, B] {
override final def apply(a: A): IO[E, B] =
IO.suspend {
try IO.now[E, B](apply0(a))
catch {
case e: KleisliIOError[_] => IO.fail[E, B](e.unsafeCoerce[E])
}
}
}
...
}
41
RUNNING KLEISLIIO
val printLn: KleisliIO[IOException, String, Unit]
printLn("Hello, world!") // IO[IOException, Unit]
42
CONSTRUCTING PURE KLEISLIIO
object KleisliIO {
...
def pure[E, A, B](f: A => IO[E, B]):
KleisliIO[E, A, B] = ???
...
}
val printLn: KleisliIO[Void, String, Unit] =
KleisliIO.pure((a: String) => IO.sync(println(a)))
43
CONSTRUCTING IMPURE KLEISLIIO
object KleisliIO {
...
def impure[E, A, B](catcher: PartialFunction[Throwable, E])(f: A => B)
...
}
val IOExceptions: PartialFunction[Throwable, IOException] = {
case io : IOException => io
}
val printLn: KleisliIO[Void, String, Unit] =
KleisliIO.impure(IOExceptions)(println)
44
CONSTRUCTING IMPURE KLEISLIIO
object KleisliIO {
...
def impureVoid[A, B](f: A => B): KleisliIO[Void, A, B] = ???
...
}
val printLn: KleisliIO[Void, String, Unit] = KleisliIO.impureVoid(println)
45
CONSTRUCTING KLEISLIIO
object KleisliIO {
...
def identity[E, A]: KleisliIO[E, A, A] = ???
...
}
A A
KleisliIO.identity[Void, Int](1) // IO.point(1)
46
COMPOSING KLEISLIIO
trait KleisliIO[E, A, B] extends (A => IO[E, B])
{
...
def >>>[C](that: KleisliIO[E, B, C]):
KleisliIO[E, A, C] = ???
...
}
...
A B C
A C
readLine >>> printLn
47
COMPOSING KLEISLIIO
A
B
C
(B, C) => D
A D
trait KleisliIO[E, A, B] extends (A => IO[E, B]) {
...
def zipWith[C, D](that: KleisliIO[E, A, C])(f: (B, C) => D):
KleisliIO[E, A, D] = ???
...
}
readLine.zipWith(readLine)((l1, l2) => l1 + l2)
48
COMPOSING KLEISLIIO
trait KleisliIO[E, A, B] extends (A => IO[E, B]) {
...
def &&&[C]( that: KleisliIO[E, A, C]):
KleisliIO[E, A, (B, C)] = ???
...
}
A
B
C
A (B,C)
readLine &&& readLine
49
COMPOSING KLEISLIIO
trait KleisliIO[E, A, B] extends (A => IO[E, B]) {
...
def |||[C](that: KleisliIO[E, C, B]):
KleisliIO[E, Either[A, C], B]
...
}
A
B
C
Either[A, C] D
(fancyPrintLn |||
standardPrintLn)(Left("Fancied!"))
50
COMPOSING KLEISLIIO
trait KleisliIO[E, A, B] extends (A => IO[E, B]) {
...
def first: KleisliIO[E, A, (B, A)] =
this &&& KleisliIO.identity[E, A]
...
}
A B
A (B, A)
readLine >>> printLn.first // (Unit, String)
51
COMPOSING KLEISLIIO
trait KleisliIO[E, A, B] extends (A => IO[E, B]) {
...
def second: KleisliIO[E, A, (A, B)] =
KleisliIO.identity[E, A] &&& this
...
}
A B
A (A, B)
readLine >>> printLn.second // (String, Unit)
52
COMPOSING KLEISLIIO
trait KleisliIO[E, A, B] extends (A => IO[E, B]) {
...
def left[C]:
KleisliIO[E, Either[A, C], Either[B, C]] = ???
...
}
Either[A, C] Either[B, C]
A B
printLn.left[String]( Left("Hello")) //
Left[Unit]
53
COMPOSING KLEISLIIO
trait KleisliIO[E, A, B] extends (A => IO[E, B]) {
...
def right[C]:
KleisliIO[E, Either[A, C], Either[B, C]] = ???
...
}
Either[A, C] Either[B, C]
A B
printLn.right[String]( Right("Hello")) // Right[Unit]
54
COMPOSING KLEISLIIO
trait KleisliIO[E, A, B] extends (A => IO[E, B])
{
...
def asEffect: KleisliIO[E, A, A] =
self.first >>> KleisliIO._2
...
}
A A
B
printLn.asEffect // String
55
COMPOSING KLEISLIIO
object KleisliIO {
...
def test[E, A](cond: KleisliIO[E, A, Boolean]):
KleisliIO[E, A, Either[A, A]] = ???
...
}
test(KleisliIO.lift(_ > 2))(4) // IO[Void, Either[Int,
Int]]
cond
A Bool
A Either[A, A]
Right(a)Left(a)
56
COMPOSING KLEISLIIO
object KleisliIO {
...
def ifThenElse[E, A, B](cond : KleisliIO[E, A, Boolean])
(then0: KleisliIO[E, A, B])(else0: KleisliIO[E, A, B]):
KleisliIO[E, A, B] =
test[E, A](cond) >>> (then0 ||| else0)
...
}
ifThenElse(KleisliIO.lift(_ == "John"))(printLn)(const(()))
A B
else0 then0
A BA B
cond
A Bool
57
COMPOSING KLEISLIIO
object KleisliIO {
...
def whileDo[E, A](check: KleisliIO[E, A, Boolean])
(body : KleisliIO[E, A, A]): KleisliIO[E, A, A] = ???
...
}
A A
A Boolean
A Abody
check
readLine >>> whileDo(lift(_ != “John”)) {
KleisliIO.point(“Wrong name”) >>> printLn >>> readLine
}
58
OPTIMIZING KLEISLIIO
final def compose[E, A, B, C](second: KleisliIO[E, B, C], first: KleisliIO[E, A, B]):
KleisliIO[E, A, C] =
(second, first) match {
case (second: Impure[_, _, _], first: Impure[_, _, _]) =>
new Impure(second.apply0.compose(first.apply0))
case _ =>
new Pure((a: A) => first(a).flatMap(second))
}
59
OPTIMIZING KLEISLIIO
final def ifThenElse[E, A, B](cond: KleisliIO[E, A, Boolean])
(then0: KleisliIO[E, A, B])(else0: KleisliIO[E, A, B]): KleisliIO[E, A, B] =
(cond, then0, else0) match {
case (cond: Impure[_, _, _], then0: Impure[_, _, _], else0: Impure[_, _, _]) =>
new Impure[E, A, B](a => if (cond.apply0(a)) then0.apply0(a) else else0.apply0(a))
case _ => test[E, A](cond) >>> (then0 ||| else0)
}
60
OPTIMIZING KLEISLIIO
final def whileDo[E, A](check: KleisliIO[E, A, Boolean])(body: KleisliIO[E, A, A]): KleisliIO[E, A, A] =
(check, body) match {
case (check: Impure[_, _, _], body: Impure[_, _, _]) =>
new Impure[E, A, A]({ (a0: A) =>
val cond = check.apply0
val update = body.apply0
var a = a0
while (cond(a)) { a = update(a) }
a
})
case _ =>
lazy val loop: KleisliIO[E, A, A] =
KleisliIO.pure((a: A) =>
check(a).flatMap((b: Boolean) =>
if (b) body(a).flatMap(loop) else IO.now(a)))
loop
}
61
TESTING KLEISLIIO - ARRAY FILL
Output: An array filled with 10,000 elements in increasing order.
62
TESTING KLEISLIIO - ARRAY FILL
def arrayFill(array: Array[Int]): KleisliIO[Void, Int] = {
val condition = KleisliIO.lift(i => i < array.length)
val update = KleisliIO.impureVoid{ i =>
array.update(i, i); i + 1 }
KleisliIO.whileDo(condition)(update)
}
def arrayFill(array: Array[Int])(i: Int): IO[Unit] =
if (i >= array.length) IO.unit
else IO(array.update(i, i)).flatMap(_ => arrayFill(array)(i + 1))
KleisliIO Array Fill Monadic Array Fill
63
TESTING KLEISLIIO - ARRAY FILL
7958.946 ops/s
3622.744 ops/s
3689.406 ops/s
Array Fill
2.18x Faster!
64
TESTING KLEISLIIO - BUBBLE SORT
Input: Array of 10000 element with reversed order
Output: bubbleSort(array)
bubbleSort(array):
i <- 1 to 10000
j <- i + 1 to 9999
lessThanEqual = array(i) <= array(j)
if (!lessThanEqual) swap(array, i, j)
65
TESTING KLEISLIIO - BUBBLE SORT
val sort: KleisliIO[Void, Int, Unit] =
KleisliIO
.whileDo(outerLoopCheck)(
innerLoopStart >>>
KleisliIO.whileDo(innerLoopCheck)(
extractIJIndexValue >>>
KleisliIO.ifNotThen(lessThanEqual)(swapIJ) >>>
extractIJAndIncrementJ
) >>>
extractIAndIncrementI
)
sort(0)
def outerLoop(i: Int): IO[Unit] =
if (i >= array.length - 1) IO.unit
else innerLoop(i, i + 1).flatMap(_ => outerLoop(i + 1))
def innerLoop(i: Int, j: Int): IO[Unit] =
if (j >= array.length) IO.unit
else IO((array(i), array(j))).flatMap {
case (ia, ja) =>
val maybeSwap = if (lessThanEqual0(ia, ja)) IO.unit
else swapIJ(i, ia, j, ja)
maybeSwap.flatMap(_ => innerLoop(i, j + 1))
}
outerLoop(0)
KleisliIO Bubble sort Monadic Bubble sort
66
TESTING KLEISLIIO - BUBBLE SORT
58.811 ops/s
41.545 ops/s
33.229 ops/s
1.57x Faster!
Bubble Sort
67
W H E R E F R O M H E R E
A brief roadmap for KleisliIO.
?
Infinite
Composition
Recursion
Combinator
Low-Cost
Propagation
68
THANK YOU!
Thanks to the staff, volunteers, and speakers of
LambdaConf, and to Wiem Zine El Abidine for
help with the development and
implementation of KleisliIO.
Follow me @jdegoes
Follow Wiem @wiemzin
Join Scalaz at gitter.im/scalaz/scalaz

More Related Content

What's hot

ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022
Alexander Ioffe
 
The Functional Programming Triad of Map, Filter and Fold
The Functional Programming Triad of Map, Filter and FoldThe Functional Programming Triad of Map, Filter and Fold
The Functional Programming Triad of Map, Filter and Fold
Philip Schwarz
 
The lazy programmer's guide to writing thousands of tests
The lazy programmer's guide to writing thousands of testsThe lazy programmer's guide to writing thousands of tests
The lazy programmer's guide to writing thousands of tests
Scott Wlaschin
 
Functional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorldFunctional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorld
Jorge Vásquez
 
ZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in ScalaZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in Scala
Wiem Zine Elabidine
 
Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Sequence and Traverse - Part 1
Sequence and Traverse - Part 1
Philip Schwarz
 
Kotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is comingKotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is coming
Kirill Rozov
 
Left and Right Folds - Comparison of a mathematical definition and a programm...
Left and Right Folds- Comparison of a mathematical definition and a programm...Left and Right Folds- Comparison of a mathematical definition and a programm...
Left and Right Folds - Comparison of a mathematical definition and a programm...
Philip Schwarz
 
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
Philip Schwarz
 
Implementing the IO Monad in Scala
Implementing the IO Monad in ScalaImplementing the IO Monad in Scala
Implementing the IO Monad in Scala
Hermann Hueck
 
Purely Functional Data Structures in Scala
Purely Functional Data Structures in ScalaPurely Functional Data Structures in Scala
Purely Functional Data Structures in Scala
Vladimir Kostyukov
 
Comparing JVM Web Frameworks - February 2014
Comparing JVM Web Frameworks - February 2014Comparing JVM Web Frameworks - February 2014
Comparing JVM Web Frameworks - February 2014
Matt Raible
 
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
Nat, List and Option Monoids -from scratch -Combining and Folding -an exampleNat, List and Option Monoids -from scratch -Combining and Folding -an example
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
Philip Schwarz
 
Boost your productivity with Scala tooling!
Boost your productivity  with Scala tooling!Boost your productivity  with Scala tooling!
Boost your productivity with Scala tooling!
MeriamLachkar1
 
Implicit parameters, when to use them (or not)!
Implicit parameters, when to use them (or not)!Implicit parameters, when to use them (or not)!
Implicit parameters, when to use them (or not)!
Julien Truffaut
 
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2
Philip Schwarz
 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Philip Schwarz
 
How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021
How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021
How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021
Natan Silnitsky
 
Zio in real world
Zio in real worldZio in real world
Zio in real world
Wiem Zine Elabidine
 
ZIO Queue
ZIO QueueZIO Queue
ZIO Queue
John De Goes
 

What's hot (20)

ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022
 
The Functional Programming Triad of Map, Filter and Fold
The Functional Programming Triad of Map, Filter and FoldThe Functional Programming Triad of Map, Filter and Fold
The Functional Programming Triad of Map, Filter and Fold
 
The lazy programmer's guide to writing thousands of tests
The lazy programmer's guide to writing thousands of testsThe lazy programmer's guide to writing thousands of tests
The lazy programmer's guide to writing thousands of tests
 
Functional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorldFunctional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorld
 
ZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in ScalaZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in Scala
 
Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Sequence and Traverse - Part 1
Sequence and Traverse - Part 1
 
Kotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is comingKotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is coming
 
Left and Right Folds - Comparison of a mathematical definition and a programm...
Left and Right Folds- Comparison of a mathematical definition and a programm...Left and Right Folds- Comparison of a mathematical definition and a programm...
Left and Right Folds - Comparison of a mathematical definition and a programm...
 
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
 
Implementing the IO Monad in Scala
Implementing the IO Monad in ScalaImplementing the IO Monad in Scala
Implementing the IO Monad in Scala
 
Purely Functional Data Structures in Scala
Purely Functional Data Structures in ScalaPurely Functional Data Structures in Scala
Purely Functional Data Structures in Scala
 
Comparing JVM Web Frameworks - February 2014
Comparing JVM Web Frameworks - February 2014Comparing JVM Web Frameworks - February 2014
Comparing JVM Web Frameworks - February 2014
 
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
Nat, List and Option Monoids -from scratch -Combining and Folding -an exampleNat, List and Option Monoids -from scratch -Combining and Folding -an example
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
 
Boost your productivity with Scala tooling!
Boost your productivity  with Scala tooling!Boost your productivity  with Scala tooling!
Boost your productivity with Scala tooling!
 
Implicit parameters, when to use them (or not)!
Implicit parameters, when to use them (or not)!Implicit parameters, when to use them (or not)!
Implicit parameters, when to use them (or not)!
 
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2
 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
 
How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021
How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021
How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021
 
Zio in real world
Zio in real worldZio in real world
Zio in real world
 
ZIO Queue
ZIO QueueZIO Queue
ZIO Queue
 

Similar to Blazing Fast, Pure Effects without Monads — LambdaConf 2018

Berlin meetup
Berlin meetupBerlin meetup
Berlin meetup
Wiem Zine Elabidine
 
Simple IO Monad in 'Functional Programming in Scala'
Simple IO Monad in 'Functional Programming in Scala'Simple IO Monad in 'Functional Programming in Scala'
Simple IO Monad in 'Functional Programming in Scala'
Philip Schwarz
 
Functions Practice Sheet.docx
Functions Practice Sheet.docxFunctions Practice Sheet.docx
Functions Practice Sheet.docx
SwatiMishra364461
 
Scalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with ScalaScalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with Scala
Daniel Sebban
 
Scala Functional Patterns
Scala Functional PatternsScala Functional Patterns
Scala Functional Patterns
league
 
Fp in scala with adts part 2
Fp in scala with adts part 2Fp in scala with adts part 2
Fp in scala with adts part 2
Hang Zhao
 
GoLightly: Building VM-Based Language Runtimes with Google Go
GoLightly: Building VM-Based Language Runtimes with Google GoGoLightly: Building VM-Based Language Runtimes with Google Go
GoLightly: Building VM-Based Language Runtimes with Google Go
Eleanor McHugh
 
ZIO Queue
ZIO QueueZIO Queue
Functional programming
Functional programmingFunctional programming
Functional programming
Prashant Kalkar
 
Un dsl pour ma base de données
Un dsl pour ma base de donnéesUn dsl pour ma base de données
Un dsl pour ma base de données
Romain Lecomte
 
Post-Free: Life After Free Monads
Post-Free: Life After Free MonadsPost-Free: Life After Free Monads
Post-Free: Life After Free Monads
John De Goes
 
Python Unit 3 - Control Flow and Functions
Python Unit 3 - Control Flow and FunctionsPython Unit 3 - Control Flow and Functions
Python Unit 3 - Control Flow and Functions
DhivyaSubramaniyam
 
chapter1.ppt
chapter1.pptchapter1.ppt
chapter1.ppt
SankarTerli
 
Rethink programming: a functional approach
Rethink programming: a functional approachRethink programming: a functional approach
Rethink programming: a functional approach
Francesco Bruni
 
Go a crash course
Go   a crash courseGo   a crash course
Go a crash course
Eleanor McHugh
 
Functional IO and Effects
Functional IO and EffectsFunctional IO and Effects
Functional IO and Effects
Dylan Forciea
 
Basic_analysis.ppt
Basic_analysis.pptBasic_analysis.ppt
Basic_analysis.ppt
SoumyaJ3
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Mario Fusco
 

Similar to Blazing Fast, Pure Effects without Monads — LambdaConf 2018 (20)

Berlin meetup
Berlin meetupBerlin meetup
Berlin meetup
 
Simple IO Monad in 'Functional Programming in Scala'
Simple IO Monad in 'Functional Programming in Scala'Simple IO Monad in 'Functional Programming in Scala'
Simple IO Monad in 'Functional Programming in Scala'
 
Functions Practice Sheet.docx
Functions Practice Sheet.docxFunctions Practice Sheet.docx
Functions Practice Sheet.docx
 
Scalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with ScalaScalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with Scala
 
Scala Functional Patterns
Scala Functional PatternsScala Functional Patterns
Scala Functional Patterns
 
Fp in scala with adts part 2
Fp in scala with adts part 2Fp in scala with adts part 2
Fp in scala with adts part 2
 
GoLightly: Building VM-Based Language Runtimes with Google Go
GoLightly: Building VM-Based Language Runtimes with Google GoGoLightly: Building VM-Based Language Runtimes with Google Go
GoLightly: Building VM-Based Language Runtimes with Google Go
 
ZIO Queue
ZIO QueueZIO Queue
ZIO Queue
 
Functional programming
Functional programmingFunctional programming
Functional programming
 
Un dsl pour ma base de données
Un dsl pour ma base de donnéesUn dsl pour ma base de données
Un dsl pour ma base de données
 
Post-Free: Life After Free Monads
Post-Free: Life After Free MonadsPost-Free: Life After Free Monads
Post-Free: Life After Free Monads
 
Python Unit 3 - Control Flow and Functions
Python Unit 3 - Control Flow and FunctionsPython Unit 3 - Control Flow and Functions
Python Unit 3 - Control Flow and Functions
 
chapter1.ppt
chapter1.pptchapter1.ppt
chapter1.ppt
 
chapter1.ppt
chapter1.pptchapter1.ppt
chapter1.ppt
 
Rethink programming: a functional approach
Rethink programming: a functional approachRethink programming: a functional approach
Rethink programming: a functional approach
 
Go a crash course
Go   a crash courseGo   a crash course
Go a crash course
 
Functional IO and Effects
Functional IO and EffectsFunctional IO and Effects
Functional IO and Effects
 
Basic_analysis.ppt
Basic_analysis.pptBasic_analysis.ppt
Basic_analysis.ppt
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...
 
functions
functionsfunctions
functions
 

More from John De Goes

Refactoring Functional Type Classes
Refactoring Functional Type ClassesRefactoring Functional Type Classes
Refactoring Functional Type Classes
John De Goes
 
One Monad to Rule Them All
One Monad to Rule Them AllOne Monad to Rule Them All
One Monad to Rule Them All
John De Goes
 
Error Management: Future vs ZIO
Error Management: Future vs ZIOError Management: Future vs ZIO
Error Management: Future vs ZIO
John De Goes
 
Atomically { Delete Your Actors }
Atomically { Delete Your Actors }Atomically { Delete Your Actors }
Atomically { Delete Your Actors }
John De Goes
 
The Death of Final Tagless
The Death of Final TaglessThe Death of Final Tagless
The Death of Final Tagless
John De Goes
 
Scalaz Stream: Rebirth
Scalaz Stream: RebirthScalaz Stream: Rebirth
Scalaz Stream: Rebirth
John De Goes
 
Scalaz Stream: Rebirth
Scalaz Stream: RebirthScalaz Stream: Rebirth
Scalaz Stream: Rebirth
John De Goes
 
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional Programming
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional ProgrammingZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional Programming
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional Programming
John De Goes
 
Scalaz 8: A Whole New Game
Scalaz 8: A Whole New GameScalaz 8: A Whole New Game
Scalaz 8: A Whole New Game
John De Goes
 
Scalaz 8 vs Akka Actors
Scalaz 8 vs Akka ActorsScalaz 8 vs Akka Actors
Scalaz 8 vs Akka Actors
John De Goes
 
Orthogonal Functional Architecture
Orthogonal Functional ArchitectureOrthogonal Functional Architecture
Orthogonal Functional Architecture
John De Goes
 
The Design of the Scalaz 8 Effect System
The Design of the Scalaz 8 Effect SystemThe Design of the Scalaz 8 Effect System
The Design of the Scalaz 8 Effect System
John De Goes
 
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsQuark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
John De Goes
 
Streams for (Co)Free!
Streams for (Co)Free!Streams for (Co)Free!
Streams for (Co)Free!
John De Goes
 
MTL Versus Free
MTL Versus FreeMTL Versus Free
MTL Versus Free
John De Goes
 
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
 
Halogen: Past, Present, and Future
Halogen: Past, Present, and FutureHalogen: Past, Present, and Future
Halogen: Past, Present, and Future
John De Goes
 
All Aboard The Scala-to-PureScript Express!
All Aboard The Scala-to-PureScript Express!All Aboard The Scala-to-PureScript Express!
All Aboard The Scala-to-PureScript Express!
John De Goes
 
Getting Started with PureScript
Getting Started with PureScriptGetting Started with PureScript
Getting Started with PureScript
John De Goes
 
SlamData - How MongoDB Is Powering a Revolution in Visual Analytics
SlamData - How MongoDB Is Powering a Revolution in Visual AnalyticsSlamData - How MongoDB Is Powering a Revolution in Visual Analytics
SlamData - How MongoDB Is Powering a Revolution in Visual Analytics
John De Goes
 

More from John De Goes (20)

Refactoring Functional Type Classes
Refactoring Functional Type ClassesRefactoring Functional Type Classes
Refactoring Functional Type Classes
 
One Monad to Rule Them All
One Monad to Rule Them AllOne Monad to Rule Them All
One Monad to Rule Them All
 
Error Management: Future vs ZIO
Error Management: Future vs ZIOError Management: Future vs ZIO
Error Management: Future vs ZIO
 
Atomically { Delete Your Actors }
Atomically { Delete Your Actors }Atomically { Delete Your Actors }
Atomically { Delete Your Actors }
 
The Death of Final Tagless
The Death of Final TaglessThe Death of Final Tagless
The Death of Final Tagless
 
Scalaz Stream: Rebirth
Scalaz Stream: RebirthScalaz Stream: Rebirth
Scalaz Stream: Rebirth
 
Scalaz Stream: Rebirth
Scalaz Stream: RebirthScalaz Stream: Rebirth
Scalaz Stream: Rebirth
 
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional Programming
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional ProgrammingZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional Programming
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional Programming
 
Scalaz 8: A Whole New Game
Scalaz 8: A Whole New GameScalaz 8: A Whole New Game
Scalaz 8: A Whole New Game
 
Scalaz 8 vs Akka Actors
Scalaz 8 vs Akka ActorsScalaz 8 vs Akka Actors
Scalaz 8 vs Akka Actors
 
Orthogonal Functional Architecture
Orthogonal Functional ArchitectureOrthogonal Functional Architecture
Orthogonal Functional Architecture
 
The Design of the Scalaz 8 Effect System
The Design of the Scalaz 8 Effect SystemThe Design of the Scalaz 8 Effect System
The Design of the Scalaz 8 Effect System
 
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsQuark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
 
Streams for (Co)Free!
Streams for (Co)Free!Streams for (Co)Free!
Streams for (Co)Free!
 
MTL Versus Free
MTL Versus FreeMTL Versus Free
MTL Versus Free
 
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...
 
Halogen: Past, Present, and Future
Halogen: Past, Present, and FutureHalogen: Past, Present, and Future
Halogen: Past, Present, and Future
 
All Aboard The Scala-to-PureScript Express!
All Aboard The Scala-to-PureScript Express!All Aboard The Scala-to-PureScript Express!
All Aboard The Scala-to-PureScript Express!
 
Getting Started with PureScript
Getting Started with PureScriptGetting Started with PureScript
Getting Started with PureScript
 
SlamData - How MongoDB Is Powering a Revolution in Visual Analytics
SlamData - How MongoDB Is Powering a Revolution in Visual AnalyticsSlamData - How MongoDB Is Powering a Revolution in Visual Analytics
SlamData - How MongoDB Is Powering a Revolution in Visual Analytics
 

Recently uploaded

"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
Fwdays
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Product School
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
Abida Shariff
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
RTTS
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
Product School
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
Product School
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
Guy Korland
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
Cheryl Hung
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
DianaGray10
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
UiPathCommunity
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
Elena Simperl
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Tobias Schneck
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
Paul Groth
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
Ralf Eggert
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 

Recently uploaded (20)

"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 

Blazing Fast, Pure Effects without Monads — LambdaConf 2018

  • 1. 1 Blazing Fast, Pure Effects without Monads LambdaConf 2018 By John A. De Goes — @jdegoes
  • 2. 2 1991 1998 2018 - April Eugenio Moggi John Hughes Flavio Brasil F R O M M O N A D S T O A R R O W S A brief history of effects leading to KleisliIO. KleisliIO 2018 - June Notions of computation and monads Generalizing monads to arrows TraneIO: Arrows & tasks in Scala
  • 3. 3 THE TRINITY OF FP Total Deterministic Free of Side-effects
  • 4. 4 THE TRINITY OF FUNCTIONAL PROGRAMMING Total Deterministic Free of Side-effects f : A => B a ∈ A ⇒ f(a) ∈ B
  • 5. 5 THE TRINITY OF FUNCTIONAL PROGRAMMING Total Deterministic Free of Side-effects def notTotal1(a: Int): String = null def notTotal2(a: Int): String = throw new Error(" ") def notTotal3(a: Int): String = notTotal3(a)
  • 6. 6 THE TRINITY OF FUNCTIONAL PROGRAMMING Total Deterministic Free of Side-effects f : A => B b1 = f(a) ∧ b2 = f(a) ⇒ b1 = b2
  • 7. 7 THE TRINITY OF FUNCTIONAL PROGRAMMING Total Deterministic Free of Side-effects def notDeterministic1(a: Int): String = if (Math.random() > 0.5) "Hello" else "Goodbye" def notDeterministic2(a: Int): String = scala.io.StdIn.readLine() def notDeterministic3(a: Int): String = (System.nanoTime() + a).toString
  • 8. 8 THE TRINITY OF FUNCTIONAL PROGRAMMING Total Deterministic Free of Side-effects f : A => B f’s only computational effect is computing B
  • 9. 9 THE TRINITY OF FUNCTIONAL PROGRAMMING Total Deterministic Free of Side-effects def notEffectFree1(a: Int): String = { println("Hello"); a.toString } def notEffectFree2(a: Int): String = { val _ = scala.io.StdIn.readLine() a.toString } def notEffectFree3(a: Int): String = { Logger.log(a); (a * a).toString }
  • 10. 10 THE RICHES OF PURITY Type Reasoning Equality Reasoning
  • 11. 11 Type Reasoning Equality Reasoning def foo1[A](a: A): A def foo2[A](a: A, f: A => A): A def foo3[A, B](f: (A => A) => B): B THE RICHES OF PURITY
  • 12. 12 Type Reasoning Equality Reasoning def println(line: String): Unit def readLine(): String THE RICHES OF PURITY
  • 13. 13 Type Reasoning Equality Reasoning def f = (x: Int) => x * x val b = f(a) val c = b + b // c = b + b // c = f(a) + f(a) // c = (a * a) + (a * a) // c = 2 * a * a THE RICHES OF PURITY
  • 14. 14 Type Reasoning Equality Reasoning def readLine = scala.io.StdIn.readLine() val a = readLine val b = a + a // b = a + a // b = readLine + readLine // !?!?! readLine + readLine != // { val a = readLine; a + a } THE RICHES OF PURITY
  • 15. 15 MONADIC EFFECTS Effects Into Values Values Into Effects The Cost of Value Effects
  • 16. 16
  • 17. 17 EFFECTS INTO VALUES def println(line: String): Unit println IO[Unit] String def println(line: String): IO[Unit]
  • 18. 18 EFFECTS INTO VALUES IO[A] Immutable value produced by the effect Immutable value describing the effect
  • 19. 19 EFFECTS INTO VALUES sealed trait IO[A] { def map[B](f: A => B): IO[B] = flatMap((a: A) => IO.point(f(a))) def flatMap[B](f: A => IO[B]): IO[B] = FlatMap(this, f) } object IO { def point[A](a: A): IO[A] = Point(a) } final case class PrintLn(line: String) extends IO[Unit] final case class ReadLine() extends IO[String] final case class FlatMap[A, B](fa: IO[A], f: A => IO[B]) extends IO[B] final case class Point[A](a: A) extends IO[A]
  • 20. 20 def readLine(): String def println(line: String): Unit val name = readLine() println("Hello " + name + ", how are you?") EFFECTS INTO VALUES println IO[Unit] def readLine: IO[String] def println(line: String): IO[Unit] val program = for { name <- readLine _ <- println("Hello " + name + ", how are you?") } yield () readLine IO[String] String Unit
  • 21. 21 VALUES INTO EFFECTS def unsafePerformIO(io: IO[A]): A = io match { case PrintLn(line) => println(line) case ReadLine() => readLine() case FlatMap(fa, f) => unsafePerformIO(f(unsafePerformIO(fa))) case Point(a) => a }
  • 22. 22 THE COST OF VALUE EFFECTS println F[Unit] class SS { for { name <- readLine _ <- println("Hello " + name + ", how are you?") } yield () readLine F[String] String Unit
  • 23. 23 THE COST OF VALUE EFFECTS readLine.flatMap(name => printLn("Hello, " + name + ", how are you?")) Allocations Allocation Megamorphic Dispatch
  • 24. 24 THE COST OF VALUE EFFECTS 1 Statement in Procedural Programming 4 Extra Allocations, 1 Extra Megamorphic Dispatch in Functional Programming =
  • 25. 25 IO.sync { App.main() } THE COST OF VALUE EFFECTS Monolith Composed Pure Values
  • 26. 26 THE COST OF VALUE EFFECTS Future
  • 27. 27 KLEISLI EFFECTS Effects Into Values Values Into Effects The Cost of Value Effects
  • 28. 28
  • 29. 29 EFFECTS INTO VALUES def println(line: String): Unit println FunctionIO[String, Unit] val println: FunctionIO[String, Unit]
  • 30. 30 EFFECTS INTO VALUES FunctionIO[A, B] Immutable input value to the function Immutable value describing the effectful function Immutable output value from the function
  • 31. 31 EFFECTS INTO VALUES final case class FunctionIO[A, B](apply0: A => IO[B]) extends (A => IO[B]) { def apply(a: A): IO[B] = apply0(a) def andThen[C](f: FunctionIO[B, C]): FunctionIO[A, C] = FunctionIO(a => apply(a).flatMap(f.apply)) } object FunctionIO { def lift[A, B](f: A => B): FunctionIO[A, B] = FunctionIO(IO.point.compose(f)) }
  • 32. 32 def readLine(): String def println(line: String): Unit val name = readLine() println("Hello " + name + ", how are you?") EFFECTS INTO VALUES val readLine: FunctionIO[Unit, String] val println: FunctionIO[String, Unit] val program = readLine .andThen(lift((name: String) => "Hello, " + name + ", how are you?")) .andThen(println) readLine FunctionIO[Unit, String] <anonymous> FunctionIO[String,String] println FunctionIO[String, Unit]
  • 33. 33 VALUES INTO EFFECTS val program: FunctionIO[Unit, Unit] unsafePerformIO(program())
  • 34. 34 THE COST OF EFFECT VALUES readLine.andThen(lift((name: String) => "Hello, " + name + ", how are you?")) .andThen(println) readLine FunctionIO[Unit, String] <anonymous> FunctionIO[String,String] println FunctionIO[String, Unit]
  • 35. 35 Megamorphic Dispatches final case class FunctionIO[A, B](apply: A => IO[B]) THE COST OF EFFECT VALUES readLine.andThen(println) Allocations Allocations
  • 36. 36 THE COST OF EFFECT VALUES 1 Statement in Procedural Programming 6 Extra Allocations, 3 Extra Megamorphic Dispatches in Functional Programming =
  • 37. 37 THE PROMISE OF KLEISLIIO sealed trait FunctionIO[A, B] extends (A => IO[B]) { ... } final class Pure[A, B](val apply0: A => IO[B]) extends FunctionIO[A, B] { def apply(a: A): IO[B] = apply0(a) } final class Impure[A, B](val apply0: A => B) extends FunctionIO[A, B] { def apply(a: A): IO[B] = IO.point(apply0(a)) } val readLine: FunctionIO[Unit, String] = new Impure(_ => scala.io.StdIn.readLine()) val printLn: FunctionIO[String, Unit] = new Impure(println)
  • 38. 38 THE PROMISE OF KLEISLIIO class Impure[A, B](val apply0: A => B) 1 Invocation in Procedural Programming 0 Extra Allocations, 1 Extra Dispatch in Functional Programming =
  • 39. 39 KLEISLIIO Running KleisliIO Constructing KleisliIO Composing KleisliIO Introducing KleisliIO Optimizing KleisliIO Testing KleisliIO
  • 40. 40 KLEISLIIO sealed trait KleisliIO[E, A, B] extends (A => IO[E, B]) { ... } object KleisliIO { class KleisliIOError[E](error: E) extends Throwable { def unsafeCoerce[E2] = error.asInstanceOf[E2] } class Pure[E, A, B](apply0: A => IO[E, B]) extends KleisliIO[E, A, B] { override final def apply(a: A): IO[E, B] = apply0(a) } class Impure[E, A, B](val apply0: A => B) extends KleisliIO[E, A, B] { override final def apply(a: A): IO[E, B] = IO.suspend { try IO.now[E, B](apply0(a)) catch { case e: KleisliIOError[_] => IO.fail[E, B](e.unsafeCoerce[E]) } } } ... }
  • 41. 41 RUNNING KLEISLIIO val printLn: KleisliIO[IOException, String, Unit] printLn("Hello, world!") // IO[IOException, Unit]
  • 42. 42 CONSTRUCTING PURE KLEISLIIO object KleisliIO { ... def pure[E, A, B](f: A => IO[E, B]): KleisliIO[E, A, B] = ??? ... } val printLn: KleisliIO[Void, String, Unit] = KleisliIO.pure((a: String) => IO.sync(println(a)))
  • 43. 43 CONSTRUCTING IMPURE KLEISLIIO object KleisliIO { ... def impure[E, A, B](catcher: PartialFunction[Throwable, E])(f: A => B) ... } val IOExceptions: PartialFunction[Throwable, IOException] = { case io : IOException => io } val printLn: KleisliIO[Void, String, Unit] = KleisliIO.impure(IOExceptions)(println)
  • 44. 44 CONSTRUCTING IMPURE KLEISLIIO object KleisliIO { ... def impureVoid[A, B](f: A => B): KleisliIO[Void, A, B] = ??? ... } val printLn: KleisliIO[Void, String, Unit] = KleisliIO.impureVoid(println)
  • 45. 45 CONSTRUCTING KLEISLIIO object KleisliIO { ... def identity[E, A]: KleisliIO[E, A, A] = ??? ... } A A KleisliIO.identity[Void, Int](1) // IO.point(1)
  • 46. 46 COMPOSING KLEISLIIO trait KleisliIO[E, A, B] extends (A => IO[E, B]) { ... def >>>[C](that: KleisliIO[E, B, C]): KleisliIO[E, A, C] = ??? ... } ... A B C A C readLine >>> printLn
  • 47. 47 COMPOSING KLEISLIIO A B C (B, C) => D A D trait KleisliIO[E, A, B] extends (A => IO[E, B]) { ... def zipWith[C, D](that: KleisliIO[E, A, C])(f: (B, C) => D): KleisliIO[E, A, D] = ??? ... } readLine.zipWith(readLine)((l1, l2) => l1 + l2)
  • 48. 48 COMPOSING KLEISLIIO trait KleisliIO[E, A, B] extends (A => IO[E, B]) { ... def &&&[C]( that: KleisliIO[E, A, C]): KleisliIO[E, A, (B, C)] = ??? ... } A B C A (B,C) readLine &&& readLine
  • 49. 49 COMPOSING KLEISLIIO trait KleisliIO[E, A, B] extends (A => IO[E, B]) { ... def |||[C](that: KleisliIO[E, C, B]): KleisliIO[E, Either[A, C], B] ... } A B C Either[A, C] D (fancyPrintLn ||| standardPrintLn)(Left("Fancied!"))
  • 50. 50 COMPOSING KLEISLIIO trait KleisliIO[E, A, B] extends (A => IO[E, B]) { ... def first: KleisliIO[E, A, (B, A)] = this &&& KleisliIO.identity[E, A] ... } A B A (B, A) readLine >>> printLn.first // (Unit, String)
  • 51. 51 COMPOSING KLEISLIIO trait KleisliIO[E, A, B] extends (A => IO[E, B]) { ... def second: KleisliIO[E, A, (A, B)] = KleisliIO.identity[E, A] &&& this ... } A B A (A, B) readLine >>> printLn.second // (String, Unit)
  • 52. 52 COMPOSING KLEISLIIO trait KleisliIO[E, A, B] extends (A => IO[E, B]) { ... def left[C]: KleisliIO[E, Either[A, C], Either[B, C]] = ??? ... } Either[A, C] Either[B, C] A B printLn.left[String]( Left("Hello")) // Left[Unit]
  • 53. 53 COMPOSING KLEISLIIO trait KleisliIO[E, A, B] extends (A => IO[E, B]) { ... def right[C]: KleisliIO[E, Either[A, C], Either[B, C]] = ??? ... } Either[A, C] Either[B, C] A B printLn.right[String]( Right("Hello")) // Right[Unit]
  • 54. 54 COMPOSING KLEISLIIO trait KleisliIO[E, A, B] extends (A => IO[E, B]) { ... def asEffect: KleisliIO[E, A, A] = self.first >>> KleisliIO._2 ... } A A B printLn.asEffect // String
  • 55. 55 COMPOSING KLEISLIIO object KleisliIO { ... def test[E, A](cond: KleisliIO[E, A, Boolean]): KleisliIO[E, A, Either[A, A]] = ??? ... } test(KleisliIO.lift(_ > 2))(4) // IO[Void, Either[Int, Int]] cond A Bool A Either[A, A] Right(a)Left(a)
  • 56. 56 COMPOSING KLEISLIIO object KleisliIO { ... def ifThenElse[E, A, B](cond : KleisliIO[E, A, Boolean]) (then0: KleisliIO[E, A, B])(else0: KleisliIO[E, A, B]): KleisliIO[E, A, B] = test[E, A](cond) >>> (then0 ||| else0) ... } ifThenElse(KleisliIO.lift(_ == "John"))(printLn)(const(())) A B else0 then0 A BA B cond A Bool
  • 57. 57 COMPOSING KLEISLIIO object KleisliIO { ... def whileDo[E, A](check: KleisliIO[E, A, Boolean]) (body : KleisliIO[E, A, A]): KleisliIO[E, A, A] = ??? ... } A A A Boolean A Abody check readLine >>> whileDo(lift(_ != “John”)) { KleisliIO.point(“Wrong name”) >>> printLn >>> readLine }
  • 58. 58 OPTIMIZING KLEISLIIO final def compose[E, A, B, C](second: KleisliIO[E, B, C], first: KleisliIO[E, A, B]): KleisliIO[E, A, C] = (second, first) match { case (second: Impure[_, _, _], first: Impure[_, _, _]) => new Impure(second.apply0.compose(first.apply0)) case _ => new Pure((a: A) => first(a).flatMap(second)) }
  • 59. 59 OPTIMIZING KLEISLIIO final def ifThenElse[E, A, B](cond: KleisliIO[E, A, Boolean]) (then0: KleisliIO[E, A, B])(else0: KleisliIO[E, A, B]): KleisliIO[E, A, B] = (cond, then0, else0) match { case (cond: Impure[_, _, _], then0: Impure[_, _, _], else0: Impure[_, _, _]) => new Impure[E, A, B](a => if (cond.apply0(a)) then0.apply0(a) else else0.apply0(a)) case _ => test[E, A](cond) >>> (then0 ||| else0) }
  • 60. 60 OPTIMIZING KLEISLIIO final def whileDo[E, A](check: KleisliIO[E, A, Boolean])(body: KleisliIO[E, A, A]): KleisliIO[E, A, A] = (check, body) match { case (check: Impure[_, _, _], body: Impure[_, _, _]) => new Impure[E, A, A]({ (a0: A) => val cond = check.apply0 val update = body.apply0 var a = a0 while (cond(a)) { a = update(a) } a }) case _ => lazy val loop: KleisliIO[E, A, A] = KleisliIO.pure((a: A) => check(a).flatMap((b: Boolean) => if (b) body(a).flatMap(loop) else IO.now(a))) loop }
  • 61. 61 TESTING KLEISLIIO - ARRAY FILL Output: An array filled with 10,000 elements in increasing order.
  • 62. 62 TESTING KLEISLIIO - ARRAY FILL def arrayFill(array: Array[Int]): KleisliIO[Void, Int] = { val condition = KleisliIO.lift(i => i < array.length) val update = KleisliIO.impureVoid{ i => array.update(i, i); i + 1 } KleisliIO.whileDo(condition)(update) } def arrayFill(array: Array[Int])(i: Int): IO[Unit] = if (i >= array.length) IO.unit else IO(array.update(i, i)).flatMap(_ => arrayFill(array)(i + 1)) KleisliIO Array Fill Monadic Array Fill
  • 63. 63 TESTING KLEISLIIO - ARRAY FILL 7958.946 ops/s 3622.744 ops/s 3689.406 ops/s Array Fill 2.18x Faster!
  • 64. 64 TESTING KLEISLIIO - BUBBLE SORT Input: Array of 10000 element with reversed order Output: bubbleSort(array) bubbleSort(array): i <- 1 to 10000 j <- i + 1 to 9999 lessThanEqual = array(i) <= array(j) if (!lessThanEqual) swap(array, i, j)
  • 65. 65 TESTING KLEISLIIO - BUBBLE SORT val sort: KleisliIO[Void, Int, Unit] = KleisliIO .whileDo(outerLoopCheck)( innerLoopStart >>> KleisliIO.whileDo(innerLoopCheck)( extractIJIndexValue >>> KleisliIO.ifNotThen(lessThanEqual)(swapIJ) >>> extractIJAndIncrementJ ) >>> extractIAndIncrementI ) sort(0) def outerLoop(i: Int): IO[Unit] = if (i >= array.length - 1) IO.unit else innerLoop(i, i + 1).flatMap(_ => outerLoop(i + 1)) def innerLoop(i: Int, j: Int): IO[Unit] = if (j >= array.length) IO.unit else IO((array(i), array(j))).flatMap { case (ia, ja) => val maybeSwap = if (lessThanEqual0(ia, ja)) IO.unit else swapIJ(i, ia, j, ja) maybeSwap.flatMap(_ => innerLoop(i, j + 1)) } outerLoop(0) KleisliIO Bubble sort Monadic Bubble sort
  • 66. 66 TESTING KLEISLIIO - BUBBLE SORT 58.811 ops/s 41.545 ops/s 33.229 ops/s 1.57x Faster! Bubble Sort
  • 67. 67 W H E R E F R O M H E R E A brief roadmap for KleisliIO. ? Infinite Composition Recursion Combinator Low-Cost Propagation
  • 68. 68 THANK YOU! Thanks to the staff, volunteers, and speakers of LambdaConf, and to Wiem Zine El Abidine for help with the development and implementation of KleisliIO. Follow me @jdegoes Follow Wiem @wiemzin Join Scalaz at gitter.im/scalaz/scalaz