SlideShare une entreprise Scribd logo
1  sur  68
Télécharger pour lire hors ligne
TheDesignoftheScalaz8
EffectSystem
Scale By The Bay - San Francisco
John A. De Goes
@jdegoes - http://degoes.net
Agenda
· Intro
· Tour
· Versus
· Wrap
AboutMe
· I program with functions
· I contribute types & functions to FLOSS
· I start companies powered by functions
RealityCheck
MostScalaProgrammersDon't
ProgramFunctionally
!
BusinessScenario
4MonsterPains
1. Asynchronous
2. Concurrent
3. Resource-Safe
4. Performant
Scalaz8Effectimport scalaz.effect._
Scalaz 8 effect system is a small, composable collection of data
types and type classes that help developers build principled,
performant, and pragmatic I/O applications that don't leak
resources, don't block, and scale across cores.
Scalaz8IO
TheHeartofScalaz8
IO[A] is an immutable value that describes an effectful program
that either produces an A, fails with a Throwable, or runs forever.
TLDR
Scalaz 8 IO helps you quickly build
asynchronous, concurrent, leak-free, performant
applications.2
2
Which coincidentally happen to be type-safe, purely functional, composable, and easy to reason about.
Tour
Main
SafeApp
object MyApp extends SafeApp {
def run(args: List[String]): IO[Unit] =
for {
_ <- putStrLn("Hello! What is your name?")
n <- getStrLn
_ <- putStrLn("Hello, " + n + ", good to meet you!")
} yield ()
}
Core
PureValues
object IO {
...
def apply[A](a: => A): IO[A] = ???
...
}
...
val answer: IO[Int] = IO(42)
Core
Mapping
trait IO[A] {
...
def map[B](f: A => IO[B]): IO[B] = ???
}
...
IO(2).map(_ * 3) // IO(6)
Core
Chaining
trait IO[A] {
...
def flatMap[B](f: A => IO[B]): IO[B] = ???
}
...
IO(2).flatMap(x => IO(3).flatMap(y => IO(x * y)) // IO(6)
Core
Failure
object IO {
...
def fail[A](t: Throwable): IO[A] = ???
...
}
...
val failure = IO.fail(new Error("Oh noes!"))
Core
Recovery
trait IO[A] {
...
def attempt: IO[Throwable / A] = ???
...
}
...
action.attempt.flatMap {
case -/ (error) => IO("Uh oh!")
case /-(value) => IO("Yay!")
}
Core
DerivingAbsolve
object IO {
...
def absolve[A](io: IO[Throwable / A]): IO[A] = io.flatMap {
case -/ (error) => IO.fail(error)
case /-(value) => IO(value)
}
...
}
...
IO.absolve(action.attempt)
Core
DerivingAlternative
trait IO[A] {
...
def orElse(that: => IO[A]): IO[A] =
self.attempt.flatMap(_.fold(_ => that)(IO(_)))
...
}
...
val openAnything = openFile("primary.data").orElse(openFile("secondary.data"))
Synchronous
ImportingEffects
object IO {
...
def sync[A](a: => A): IO[A] = ???
...
}
Synchronous
ImportingExample
def putStrLn(line: String): IO[Unit] =
IO.sync(scala.Console.println(line))
def getStrLn: IO[String] =
IO.sync(scala.io.StdIn.readLine())
Synchronous
EffectExample
val program: IO[Unit] =
for {
_ <- putStrLn("Hello. What is your name?")
name <- getStrLn
_ <- putStrLn("Hello, " + name + ", good to meet you!")
} yield ()
Asynchronous
EffectImport:Definition
object IO {
...
def async0[A](k: (Throwable / A => Unit) => AsyncReturn[A]): IO[A] = ???
...
}
...
sealed trait AsyncReturn[+A]
object AsyncReturn {
final case object Later extends AsyncReturn[Nothing]
final case class Now[A](value: A) extends AsyncReturn[A]
final case class MaybeLater[A](canceler: Throwable => Unit) extends AsyncReturn[A]
}
Asynchronous
ImportingEffects
def spawn[A](a: => A): IO[A] =
IO.async0 { (callback: Throwable / A => Unit) =>
java.util.concurrent.Executors.defaultThreadFactory.newThread(new Runnable() {
def run(): Unit = callback(/-(a))
})
AsyncReturn.Later
}
def never[A]: IO[A] =
IO.async0 { (callback: Throwable / A => Unit) =>
AsyncReturn.Later
}
Asynchronous
EffectExample
for {
response1 <- client.get("http://e.com")
limit = parseResponse(response1).limit
response2 <- client.get("http://e.com?limit=" + limit)
} yield parseResponse(response2)
Asynchronous
Sleep
IO {
...
def sleep(duration: Duration): IO[Unit] = ???
...
}
Asynchronous
SleepExample
for {
_ <- putStrLn("Time to sleep...")
_ <- IO.sleep(10.seconds)
_ <- putStrLn("Time to wake up!")
} yield ()
Asynchronous
DerivingDelay
trait IO[A] {
...
def delay(duration: Duration): IO[A] =
IO.sleep(duration).flatMap(_ => self)
...
}
...
putStrLn("Time to wake up!").delay(10.seconds)
Concurrency
Models
1. Threads — Java
· OS-level
· Heavyweight
· Dangerous interruption
2. Green Threads — Haskell
· Language-level
· Lightweight
· Efficient
3. Fibers — Scalaz 8
· Application-level
· Lightweight
· Zero-cost for pure FP
· User-defined semantics
Concurrency
Fork/Join
trait IO[A] {
...
def fork: IO[Fiber[A]] = ???
def fork0(h: Throwable => IO[Unit]): IO[Fiber[A]] = ???
...
}
trait Fiber[A] {
def join: IO[A]
def interrupt(t: Throwable): IO[Unit]
}
Concurrency
Fork/JoinExample
def fib(n: Int): IO[BigInt] =
if (n <= 1) IO(n)
else for {
fiberA <- fib(n-1).fork
fiberB <- fib(n-2).fork
a <- fiberA.join
b <- fiberB.join
} yield a + b
Concurrency
raceWith
trait IO[A] {
...
def raceWith[B, C](that: IO[B])(
finish: (A, Fiber[B]) / (B, Fiber[A]) => IO[C]): IO[C] = ???
...
}
Concurrency
DerivingRace
trait IO[A] {
...
def race(that: IO[A]): IO[A] = raceWith(that) {
case -/ ((a, fiber)) => fiber.interrupt(Errors.LostRace( /-(fiber))).const(a)
case /-((a, fiber)) => fiber.interrupt(Errors.LostRace(-/ (fiber))).const(a)
}
...
}
Concurrency
DerivingTimeout
trait IO[A] {
...
def timeout(duration: Duration): IO[A] = {
val err: IO[Throwable / A] =
IO(-/(Errors.TimeoutException(duration)))
IO.absolve(self.attempt.race(err.delay(duration)))
}
...
}
Concurrency
DerivingPar
trait IO[A] {
...
def par[B](that: IO[B]): IO[(A, B)] =
attempt.raceWith(that.attempt) {
case -/ ((-/ (e), fiberb)) => fiberb.interrupt(e).flatMap(_ => IO.fail(e))
case -/ (( /-(a), fiberb)) => IO.absolve(fiberb.join).map(b => (a, b))
case /-((-/ (e), fibera)) => fibera.interrupt(e).flatMap(_ => IO.fail(e))
case /-(( /-(b), fibera)) => IO.absolve(fibera.join).map(a => (a, b))
}
...
}
Concurrency
DerivingRetry
trait IO[A] {
...
def retry: IO[A] = this orElse retry
def retryN(n: Int): IO[A] =
if (n <= 1) this
else this orElse (retryN(n - 1))
def retryFor(duration: Duration): IO[A] =
IO.absolve(
this.retry.attempt race
(IO.sleep(duration) *>
IO(-/(Errors.TimeoutException(duration)))))
...
}
Concurrency
MVar
trait MVar[A] {
def peek: IO[Maybe[A]] = ???
def take: IO[A] = ???
def read: IO[A] = ???
def put(v: A): IO[Unit] = ???
def tryPut(v: A): IO[Boolean] = ???
def tryTake: IO[Maybe[A]] = ???
}
Concurrency
MVarExample
val action =
for {
mvar <- MVar.empty // Fiber 1
_ <- mvar.putVar(r).fork // Fiber 2
result <- mvar.takeVar // Fiber 1
} yield result
ComingSoon:RealSTM
ResourceSafety
Uninterruptible
trait IO[A] {
...
def uninterruptibly: IO[A] = ???
...
}
ResourceSafety
UninterruptibleExample
val action2 = action.uninterruptibly
ResourceSafety
Bracket
trait IO[A] {
...
def bracket[B](
release: A => IO[Unit])(
use: A => IO[B]): IO[B] = ???
...
}
ResourceSafety
BracketExample
def openFile(name: String): IO[File] = ???
def closeFile(file: File): IO[Unit] = ???
openFile("data.json").bracket(closeFile(_)) { file =>
...
// Use file
...
}
ResourceSafety
Bracket
trait IO[A] {
...
def bracket[B](
release: A => IO[Unit])(
use: A => IO[B]): IO[B] = ???
...
}
ResourceSafety
Deriving'Finally'
trait IO[A] {
def ensuring(finalizer: IO[Unit]): IO[A] =
IO.unit.bracket(_ => finalizer)(_ => this)
}
ResourceSafety
BrokenErrorModel
try {
try {
try {
throw new Error("e1")
}
finally {
throw new Error("e2")
}
}
finally {
throw new Error("e3")
}
}
catch { case e4 : Throwable => println(e4.toString()) }
ResourceSafety
FixedErrorModel
IO.fail(new Error("e1")).ensuring(
IO.fail(new Error("e2"))).ensuring(
IO.fail(new Error("e3"))).catchAll(e => putStrLn(e.toString()))
ResourceSafety
Supervision
object IO {
...
def supervise[A](io: IO[A]): IO[A] = ???
...
}
ResourceSafety
SupervisionExample
val action = IO.supervise {
for {
a <- doX.fork
b <- doY.fork
...
} yield z
}
Principles
AlgebraicLaws
fork >=> join = id
let fiber = fork never
in interrupt e fiber >* join fiber = fail e
And many more!
Versus
Versus:Performance
SCALAZ 8 IO FUTURE CATS IO MONIX TASK
Le! Associated flatMap 5061.380 39.088 0.807 3548.260
Narrow flatMap 7131.227 36.504 2204.571 6411.355
Repeated map 63482.647 4599.431 752.771 47235.85
Deep flatMap 1885.480 14.843 131.242 1623.601
Shallow attempt 769.958 CRASHED 643.147 CRASHED
Deep attempt 16066.976 CRASHED 16061.906 12207.417
Scalaz 8 IO is up to 6300x faster than Cats (0.4), 195x faster than
Future (2.12.4), and consistently faster than Monix Task (3.0.0-RC1).
Versus:Safety
SCALAZ 8 IO FUTURE CATS IO MONIX TASK
Sync Stack Safety ✓ ✓ ✓ ✓
Async Stack
Safety
✓ ✓ ! ✓
Bracket Primitive ✓ ! ! !
No Implicit
Executors
✓ ! ! ✓
No Mutable
Implicits
✓ ! ! ✓
Versus:Expressiveness
SCALAZ 8 IO FUTURE CATS IO MONIX TASK
Synchronicity ✓ ! ✓ ✓
Asynchronicity ✓ ✓ ✓ ✓
Concurrency Primitives ✓ ! ! ✓
Async Var ✓ ! ! ✓
Non-Leaky Race ✓ ! ! ✓4
Non-Leaky Timeout ✓ ! ! ✓4
Non-Leaky Parallel ✓ ! ! ✓4
Thread Supervision ✓ ! ! !
4
Cancellation only occurs at async boundaries.
Versus
WhatAboutFS2?
IO is not a stream!
Versus
FS2:MissingFoundations
· Mini-actor library
· Mini-FRP library
· MVar implementation — Ref
· Concurrency primitives
· race, bracket, fork, join
Versus
FS2:LeakyFoundations
package object async {
...
def race[F[_]: Effect, A, B](fa: F[A], fb: F[B])(
implicit ec: ExecutionContext): F[Either[A, B]] =
ref[F, Either[A,B]].flatMap { ref =>
ref.race(fa.map(Left.apply), fb.map(Right.apply)) >> ref.get
}
def start[F[_], A](f: F[A])(implicit F: Effect[F], ec: ExecutionContext): F[F[A]] =
ref[F, A].flatMap { ref => ref.setAsync(F.shift(ec) >> f).as(ref.get) }
def fork[F[_], A](f: F[A])(implicit F: Effect[F], ec: ExecutionContext): F[Unit] =
F.liftIO(F.runAsync(F.shift >> f) { _ => IO.unit })
...
}
Versus
FS2: Non-Compositional Timeout
class Ref[A] {
...
def timedGet(timeout: FiniteDuration, scheduler: Scheduler): F[Option[A]] = ???
...
}
Scalaz 8: Compositional Timeout
mvar.takeVar.timeout(t)
mvar.putVar(2).timeout(t)
...
what.ev.uh.timeout(t)
ThisisWar
ThankYou
Special thanks to Alexy Khrabrov, Twitter, and
the wonderful attendees of Scale By The Bay!

Contenu connexe

Tendances

The Death of Final Tagless
The Death of Final TaglessThe Death of Final Tagless
The Death of Final Tagless
John De Goes
 

Tendances (20)

Scalaz 8 vs Akka Actors
Scalaz 8 vs Akka ActorsScalaz 8 vs Akka Actors
Scalaz 8 vs Akka Actors
 
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
 
First-Class Patterns
First-Class PatternsFirst-Class Patterns
First-Class Patterns
 
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...
 
Building a Tagless Final DSL for WebGL
Building a Tagless Final DSL for WebGLBuilding a Tagless Final DSL for WebGL
Building a Tagless Final DSL for WebGL
 
The Death of Final Tagless
The Death of Final TaglessThe Death of Final Tagless
The Death of Final Tagless
 
Functor, Apply, Applicative And Monad
Functor, Apply, Applicative And MonadFunctor, Apply, Applicative And Monad
Functor, Apply, Applicative And Monad
 
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
 
Introduction to functional programming using Ocaml
Introduction to functional programming using OcamlIntroduction to functional programming using Ocaml
Introduction to functional programming using Ocaml
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
One Monad to Rule Them All
One Monad to Rule Them AllOne Monad to Rule Them All
One Monad to Rule Them All
 
Intro to Functional Programming in Scala
Intro to Functional Programming in ScalaIntro to Functional Programming in Scala
Intro to Functional Programming in Scala
 
RESTful API using scalaz (3)
RESTful API using scalaz (3)RESTful API using scalaz (3)
RESTful API using scalaz (3)
 
Demystifying functional programming with Scala
Demystifying functional programming with ScalaDemystifying functional programming with Scala
Demystifying functional programming with Scala
 
Learning Functional Programming Without Growing a Neckbeard
Learning Functional Programming Without Growing a NeckbeardLearning Functional Programming Without Growing a Neckbeard
Learning Functional Programming Without Growing a Neckbeard
 
The Next Great Functional Programming Language
The Next Great Functional Programming LanguageThe Next Great Functional Programming Language
The Next Great Functional Programming Language
 
Programming in Scala: Notes
Programming in Scala: NotesProgramming in Scala: Notes
Programming in Scala: Notes
 
O caml2014 leroy-slides
O caml2014 leroy-slidesO caml2014 leroy-slides
O caml2014 leroy-slides
 
Joy of scala
Joy of scalaJoy of scala
Joy of scala
 
Scalaz 8: A Whole New Game
Scalaz 8: A Whole New GameScalaz 8: A Whole New Game
Scalaz 8: A Whole New Game
 

En vedette

Airbnb - Braavos - Whered My Money Go
Airbnb - Braavos - Whered My Money GoAirbnb - Braavos - Whered My Money Go
Airbnb - Braavos - Whered My Money Go
Jiang-Ming Yang
 

En vedette (9)

Mining Functional Patterns
Mining Functional PatternsMining Functional Patterns
Mining Functional Patterns
 
Introducing Kafka Streams, the new stream processing library of Apache Kafka,...
Introducing Kafka Streams, the new stream processing library of Apache Kafka,...Introducing Kafka Streams, the new stream processing library of Apache Kafka,...
Introducing Kafka Streams, the new stream processing library of Apache Kafka,...
 
Airbnb - Braavos - Whered My Money Go
Airbnb - Braavos - Whered My Money GoAirbnb - Braavos - Whered My Money Go
Airbnb - Braavos - Whered My Money Go
 
Robot Framework Introduction
Robot Framework IntroductionRobot Framework Introduction
Robot Framework Introduction
 
Introduction to Kafka Streams
Introduction to Kafka StreamsIntroduction to Kafka Streams
Introduction to Kafka Streams
 
Introduction to .net framework
Introduction to .net frameworkIntroduction to .net framework
Introduction to .net framework
 
GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기
 GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기 GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기
GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기
 
失敗と向き合う姿勢を正す話
失敗と向き合う姿勢を正す話失敗と向き合う姿勢を正す話
失敗と向き合う姿勢を正す話
 
reveal.js 3.0.0
reveal.js 3.0.0reveal.js 3.0.0
reveal.js 3.0.0
 

Similaire à The Design of the Scalaz 8 Effect System

"Walk in a distributed systems park with Orleans" Евгений Бобров
"Walk in a distributed systems park with Orleans" Евгений Бобров"Walk in a distributed systems park with Orleans" Евгений Бобров
"Walk in a distributed systems park with Orleans" Евгений Бобров
Fwdays
 
(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?
Tomasz Wrobel
 
Intro to scala
Intro to scalaIntro to scala
Intro to scala
Joe Zulli
 

Similaire à The Design of the Scalaz 8 Effect System (20)

Dallas Scala Meetup
Dallas Scala MeetupDallas Scala Meetup
Dallas Scala Meetup
 
Future vs. Monix Task
Future vs. Monix TaskFuture vs. Monix Task
Future vs. Monix Task
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to Scala
 
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
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)
 
Introduction to Scala for JCConf Taiwan
Introduction to Scala for JCConf TaiwanIntroduction to Scala for JCConf Taiwan
Introduction to Scala for JCConf Taiwan
 
Pune Clojure Course Outline
Pune Clojure Course OutlinePune Clojure Course Outline
Pune Clojure Course Outline
 
Clojure And Swing
Clojure And SwingClojure And Swing
Clojure And Swing
 
Coding in Style
Coding in StyleCoding in Style
Coding in Style
 
Java
JavaJava
Java
 
Scala in Practice
Scala in PracticeScala in Practice
Scala in Practice
 
"Walk in a distributed systems park with Orleans" Евгений Бобров
"Walk in a distributed systems park with Orleans" Евгений Бобров"Walk in a distributed systems park with Orleans" Евгений Бобров
"Walk in a distributed systems park with Orleans" Евгений Бобров
 
(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?
 
Intro to scala
Intro to scalaIntro to scala
Intro to scala
 
JavaScript Editions ES7, ES8 and ES9 vs V8
JavaScript Editions ES7, ES8 and ES9 vs V8JavaScript Editions ES7, ES8 and ES9 vs V8
JavaScript Editions ES7, ES8 and ES9 vs V8
 
BUILDING APPS WITH ASYNCIO
BUILDING APPS WITH ASYNCIOBUILDING APPS WITH ASYNCIO
BUILDING APPS WITH ASYNCIO
 
Introduction to clojure
Introduction to clojureIntroduction to clojure
Introduction to clojure
 
Advanced akka features
Advanced akka featuresAdvanced akka features
Advanced akka features
 
EcmaScript unchained
EcmaScript unchainedEcmaScript unchained
EcmaScript unchained
 
Asynchronous web apps with the Play Framework 2.0
Asynchronous web apps with the Play Framework 2.0Asynchronous web apps with the Play Framework 2.0
Asynchronous web apps with the Play Framework 2.0
 

Plus de John De Goes

Refactoring Functional Type Classes
Refactoring Functional Type ClassesRefactoring Functional Type Classes
Refactoring Functional Type Classes
John De Goes
 

Plus de John De Goes (13)

Refactoring Functional Type Classes
Refactoring Functional Type ClassesRefactoring Functional Type Classes
Refactoring Functional Type Classes
 
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 }
 
Scalaz Stream: Rebirth
Scalaz Stream: RebirthScalaz Stream: Rebirth
Scalaz Stream: Rebirth
 
Streams for (Co)Free!
Streams for (Co)Free!Streams for (Co)Free!
Streams for (Co)Free!
 
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
 
The Dark Side of NoSQL
The Dark Side of NoSQLThe Dark Side of NoSQL
The Dark Side of NoSQL
 
Quirrel & R for Dummies
Quirrel & R for DummiesQuirrel & R for Dummies
Quirrel & R for Dummies
 
In-Database Predictive Analytics
In-Database Predictive AnalyticsIn-Database Predictive Analytics
In-Database Predictive Analytics
 
Analytics Maturity Model
Analytics Maturity ModelAnalytics Maturity Model
Analytics Maturity Model
 
Rise of the scientific database
Rise of the scientific databaseRise of the scientific database
Rise of the scientific database
 
Fun with automata
Fun with automataFun with automata
Fun with automata
 

Dernier

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Dernier (20)

Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
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
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
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
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
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
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 

The Design of the Scalaz 8 Effect System