Monix, a functional library a substitute cum extension to Monix, download this slides which highlight major modules of it and some places where Monix offers functional and cleaner APIs for both Java and Scala wrt existing concurrency APIs in both of the above languages.
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Monix : A Birds’ eye view
1. How to be functional in
concurrent programming
with Monix
Presented By: Shubham Verma
Senior Software Consultant
Knoldus Inc.
2. 01 What is FP
02 Terminology
03 Scala Future API
04 Monix
05 Magic of Monix
Our Agenda
3. What is FP aka Functional programming?
● Functions - First class citizens
● Lazy Evaluation
● Immutability or avoid using shared mutable
state
● No Side-effects
● Referential Transparency
4. Scala Future API
● Scala’s inbuilt concurrency mechanism which enables us programming using
threads, which is built to provide functional programming essence using monad
pattern.
● Does not provide good approach for dealing with side effects which breaks the
pattern for functional programming.
● Uses shared mutable state, as in sharing the Execution context
5. Monix
● Monix is a high-performance Scala /
Scala.js library for composing
asynchronous, event-based
programs.
● Clean modular API and helps us in
writing our code using functional
constructs.
● Exposes different types of
mechanism and utilities for the
building concurrent or event based
programs .
● Nice interoperability with futures.
https://monix.io/docs/current/intro/usage.html#sub-modules--dependencies-graph
6. Lazy Evaluation
Future API
val eagerFuture: Future[Int] =
Future {
println("========== You just started
me ==============")
34
}
7. Lazy Evaluation
Future API
val eagerFuture: Future[Int] =
Future {
println("========== You just
started me ==============")
34
}
Fix
def theLazyIllusion: Future[Int] =
Future {
println("========== You get the idea
==============")
34
}
8. Lazy Evaluation
Future API
val eagerFuture: Future[Int] =
Future {
println("========== You just
started me ==============")
34
}
Fix
def theLazyIllusion: Future[Int] =
Future {
println("========== You get the idea
==============")
34
}
9. Lazy Evaluation
Future API
val eagerFuture: Future[Int] =
Future {
println("========== You just
started me ==============")
34
}
Fix
def theLazyIllusion: Future[Int] =
Future {
println("========== You get the idea
==============")
34
}
Monix
val iAmLazy: Task[Int] = Task(34)
10. Lazy Evaluation
Future API
val eagerFuture: Future[Int] =
Future {
println("========== You just
started me ==============")
34
}
Fix
def theLazyIllusion: Future[Int] =
Future {
println("========== You get the idea
==============")
34
}
Monix
val iAmLazy: Task[Int] = Task(34)
val nowTask: Task[Int] = Task.now(45)
11. Lazy Evaluation
Future API
val eagerFuture: Future[Int] =
Future {
println("========== You just
started me ==============")
34
}
Fix
def theLazyIllusion: Future[Int] =
Future {
println("========== You get the idea
==============")
34
}
Monix
val iAmLazy: Task[Int] = Task(34)
val nowTask: Task[Int] = Task.now(45)
val evalOnce = Task.evalOnce {
println("Only gets executed once")
67
}
12. Shared State
Future API
def apply[T]
(body: =>T)
(implicit @deprecatedName('execctx) executor: ExecutionContext)
: Future[T]
def flatMap[S]
(f: T => Future[S])
(implicit executor: ExecutionContext)
: Future[S]
13. Shared State
Future API (Problem)
import scala.concurrent.ExecutionContext.Implicits.global
Without the above statement the below code would show a demand for an implicit parameter for
execution context
val eagerFuture: Future[Int] = Future {
println("========== You just started me ==============")
34
}
def theLazyIllusion: Future[Int] = Future {
println("========== You get the idea ==============")
34
}
14. Shared State
Monix
object MonixSharedState extends App {
val ec : ExecutionContextExecutorService =
ExecutionContext. fromExecutorService(Executors.newFixedThreadPool(8))
def future(ec: ExecutionContext) = Future {
println("Started executing" )
34
}(ec)
val task = Task.fromFuture(future(ec))
val taskDelayed = Task.deferFuture(future(ec))
//Or
val suspended = Task.suspend(task)
}
15. Shared State
Monix
object MonixSharedState extends App {
val ec : ExecutionContextExecutorService =
ExecutionContext. fromExecutorService(Executors.newFixedThreadPool(8))
def future(ec: ExecutionContext) = Future {
println("Started executing" )
34
}(ec)
val task = Task.fromFuture(future(ec))
val taskDelayed = Task.deferFuture(future(ec))
//Or
val suspended = Task.suspend(task)
}
Is monix solving the
problem ??
16. Shared State
Monix
object MonixSharedState extends App {
val ec : ExecutionContextExecutorService =
ExecutionContext.fromExecutorService(Executors.newFixedThreadPool(8))
def future(ec: ExecutionContext) = Future {
println("Started executing")
34
}(ec)
val task = Task.fromFuture(future(ec))
val taskDelayed = Task.deferFuture(future(ec))
//Or
val suspended = Task.suspend(task)
//Let’s us define pure functions
def edSolution: Task[Int] = Task.deferFutureAction { scheduler =>
future(scheduler)
}
17. No Side effects
Future API
def read(implicit ec:ExecutionContext): Future[Option[String]] = Future
{
Try{
val file = new FileInputStream(new File("some file.txt"))
val str = file.toString
file.close()
str
}.toOption
}
18. No Side effects
Monix
val task = Task(new FileInputStream(new File("some
file.txt")))
val looksCool: Task[String] = task.bracket{ stream =>
Task.evalOnce(stream.toString)
} { doneWithStream =>
Task(doneWithStream.close())
}
19. Modules at glance
● Monix-execution - the lower level primitives for dealing with asynchronous
execution, thus exposing Scheduler and Cancelable.
● Monix-catnap - You can use just monix-catnap (see API Docs), the high-level
primitives building on top of Cats Effect.
● Monix-eval - You can use just monix-eval, the sub-project that exposes Task and
Coeval:
● Monix-reactive - You can use just monix-reactive, the sub-project that exposes the
Observable pattern.
● Monix-tail - You can use just monix-tail, the sub-project that exposes Iterant for
pull based streaming.
○