SlideShare una empresa de Scribd logo
1 de 74
Purely Functional I/O
Rúnar Bjarnason
@runarorama
QCon New York 2013

Thursday, June 13, 13
Watch the video with slide
synchronization on InfoQ.com!
http://www.infoq.com/presentations
/io-functional-side-effects

InfoQ.com: News & Community Site
• 750,000 unique visitors/month
• Published in 4 languages (English, Chinese, Japanese and Brazilian
Portuguese)
• Post content from our QCon conferences
• News 15-20 / week
• Articles 3-4 / week
• Presentations (videos) 12-15 / week
• Interviews 2-3 / week
• Books 1 / month
Presented at QCon New York
www.qconnewyork.com
Purpose of QCon
- to empower software development by facilitating the spread of
knowledge and innovation
Strategy
- practitioner-driven conference designed for YOU: influencers of
change and innovation in your teams
- speakers and topics driving the evolution and innovation
- connecting and catalyzing the influencers and innovators
Highlights
- attended by more than 12,000 delegates since 2007
- held in 9 cities worldwide
Who is this jackass?
•
•
•

Thursday, June 13, 13

Enterprise Java refugee

Author, Functional Programming in Scala
manning.com/bjarnason

Partially responsible for Scalaz and
Functional Java
What you should take
away from this talk
•
•
•

Thursday, June 13, 13

I/O can be done with pure functional
programming.
It really is purely functional.
How it’s done and why it’s done that way.
What is purely functional?

Thursday, June 13, 13
Functional programming is not
about lack of I/O

Thursday, June 13, 13
Functional programming is not
about first-class functions
or higher-order procedures.

Thursday, June 13, 13
Functional programming is not
about immutability.

Thursday, June 13, 13
Functional programming is
programming with pure functions

Thursday, June 13, 13
Functional programming is
programming with functions

Thursday, June 13, 13
A function of type (a → b) maps every value of type a
to exactly one value of type b.

(and nothing else)

Thursday, June 13, 13
No side-effects.

Thursday, June 13, 13
Side-effects
•
•
•
•
•
Thursday, June 13, 13

Reading from a file
Writing to the console
Starting threads
Throwing exceptions
Mutating memory
An expression e is referentially transparent if for all
programs p every occurrence of e in p can be replaced
with the result of evaluating e without changing the
meaning of p.

Thursday, June 13, 13
A function f is pure if f(x) is RT when x is RT.

Thursday, June 13, 13
A pure function always returns the same value
given the same input.

Thursday, June 13, 13
A pure function does not depend on anything
other than its argument.

Thursday, June 13, 13
The result of calling a pure function can be understood
completely by looking at the returned value.

Thursday, June 13, 13
x = 2
y = 4
p = x + y

Thursday, June 13, 13
y = 4
p = 2 + y

Thursday, June 13, 13
p = 2 + 4

Thursday, June 13, 13
p = 6

Thursday, June 13, 13
def x = new Date().getTime
def y = 4
def p = x + y

Thursday, June 13, 13
def y = 4
def p = 1369250684475 + y

Thursday, June 13, 13
A side-effect is anything that violates referential
transparency.

Thursday, June 13, 13
Problems with sideeffecting I/O
•
•
•
•
•
Thursday, June 13, 13

Any function can perform I/O
Monolithic, non-modular, limited reuse
Novel compositions difficult
Difficult to test
Difficult to scale
What we want
•
•
•
•

Thursday, June 13, 13

Clear separation of I/O concern
Modular and compositional API
Easy to test
Scales well
class Cafe {
def buyCoffee(cc: CreditCard): Coffee = {
val cup = new Coffee()
Payments.charge(cc, cup.price)
cup
}
}

Thursday, June 13, 13
class Cafe {
def buyCoffee(cc: CreditCard, p: Payments): Coffee = {
val cup = new Coffee()
p.charge(cc, cup.price)
cup
}
}

Thursday, June 13, 13
class Cafe {
def buyCoffee(cc: CreditCard): (Coffee, Charge) = {
val cup = new Coffee()
(cup, new Charge(cc, cup.price))
}
}

Thursday, June 13, 13
First-class I/O
Instead of performing I/O as a side-effect,
return a value to the caller that describes an
interaction with the external system.

Thursday, June 13, 13
Java

class App {
public static void main(String[] args) {}
}

Thursday, June 13, 13
Java

class App {
public static IO main(String[] args) {}
}

Thursday, June 13, 13
Haskell

main :: IO ()

Thursday, June 13, 13
Haskell

getLine :: IO String
putStrLn :: String -> IO ()

Thursday, June 13, 13
Haskell

getInt :: IO Int
getInt = fmap read getLine
fmap :: (a -> b) -> IO a -> IO b
read :: String -> Int

Thursday, June 13, 13
Haskell

echo = getLine >>= putStrLn
(>>=) :: IO a -> (a -> IO b) -> IO b

Thursday, June 13, 13
Haskell

cat = forever echo
forever x = x >> forever x
(>>) :: IO a -> IO b -> IO b

Thursday, June 13, 13
Haskell

cat = forever do
x <- getLine
putStrLn x
forever x = do { x; forever x }

Thursday, June 13, 13
Scala

println("What is your name?")
println("Hello, " + readLine)

Thursday, June 13, 13
Haskell

do
putStrLn "What is your name?"
putStrLn ("Hello, " ++ getLine)

Thursday, June 13, 13
Haskell
do

putStrLn "What is your name?"
putStrLn ("Hello, " ++ getLine)

Couldn't match expected type `String' with
actual type `IO String'
In the second argument of `(++)', namely
`getLine'

Thursday, June 13, 13
Haskell

putStrLn "What is your name?" >>
getLine >>= greet
greet name = putStrLn ("Hello, " ++ name)

Thursday, June 13, 13
Haskell

do
putStrLn "What is your name?"
name <- getLine
putStrLn ("Hello, " ++ name)

Thursday, June 13, 13
In Haskell, every program is
a single referentially transparent expression.

Thursday, June 13, 13
Benefits of IO
datatype
•
•
•

Thursday, June 13, 13

No side-effects. An IO action is a RT
description.
Effects are external to our program.
Action-manipulating functions!
Library of I/O
functions
sequence
mapM
replicateM
liftM2
forever
while

::
::
::
::
::
::

[IO a] -> IO [a]
(a -> IO b) -> [a] -> IO [b]
Int -> IO a -> IO [a]
(a -> b -> c) -> IO a -> IO b -> IO c
IO a -> IO b
IO Bool -> IO ()

And many more

Thursday, June 13, 13
Novel compositions

getTenLines :: IO [String]
getTenLines = sequence (replicate 10 getLine)

Thursday, June 13, 13
The world-as-state
model
class IO[A](val apply: RealWorld => (A, RealWorld))

Thursday, June 13, 13
The world-as-state
model
class IO[A](val apply: () => A)

Thursday, June 13, 13
The end of the world
sealed trait RealWorld
abstract class Program {
private val realWorld = new RealWorld {}
final def main(args: Array[String]): Unit =
pureMain(args).apply()
def pureMain(args: IndexedSeq[String]): IO[Unit]
}

Thursday, June 13, 13
Example IO actions
def io[A](a: => A): IO[A] =
new IO(() => a)
def putStrLn(s: String): IO[Unit] =
io(println(s))
def getLine: IO[String] =
io(readLine)

Thursday, June 13, 13
Composing actions

main = getLine >>= putStrLn >> main

Thursday, June 13, 13
Composing actions
class IO[A](val apply: () => A) {
def >>=[B](f: A => IO[B]): IO[B] = new IO[B](() => {
apply(rw)
f(a).apply(rw2)
})
def >>[B](b: => IO[B]): IO[B] = >>=(_ => b)
}

Thursday, June 13, 13
Composing actions
new Program {
def pureMain(args: IndexedSeq[String]): IO[Unit] =
(getLine >>= putStrLn) >> pureMain(args)
}

Thursday, June 13, 13
Composing actions
main = do
x <- getLine
putStrLn x
main

Thursday, June 13, 13
Composing actions
new Program {
def pureMain(args: IndexedSeq[String]): IO[Unit] =
for {
line <- getLine
_ <- putStrLn(line)
_ <- pureMain(args)
} yield ()
}

Thursday, June 13, 13
Composing actions
class IO[A](val apply: RealWorld => (A, RealWorld)) {
def >>=[B](f: A => IO[B]): IO[B] = new IO[B] { rw =>
val (a, rw2) = apply(rw)
f(a)
}
def >>[B](b: => IO[B]): IO[B] = >>=(_ => b)

}

Thursday, June 13, 13

def flatMap[B](f: A => IO[B]): IO[B] = >>=(f)
def map[B](f: A => B): IO[B] = >>=(a => io(f(a)))
Issues with
world-as-state
An IO[A] could do anything at all.

Thursday, June 13, 13
Issues with
world-as-state
This implementation overflows the stack in Scala.
Solved with trampolining.

Thursday, June 13, 13
Issues with
world-as-state
main = forever (getLine >>= putStrLn)
main = main

Thursday, June 13, 13
The “free monad”
model
sealed trait IO[A]
case class Pure[A](a: A) extends IO[A]
case class Request[I,A](
req: External[I],
k: I => IO[A]) extends IO[A]

Thursday, June 13, 13
The “free monad”
model
sealed trait IO[F[_],A]
case class Pure[F[_],A](a: A) extends IO[F,A]
case class Request[F[_],I,A](
req: F[I],
k: I => IO[A]) extends IO[A]

Thursday, June 13, 13
Any effect
trait Runnable[A] { def run: A }
def delay[A](a: => A) =
new Runnable[A] {
def run = a
}
type AnyIO[A] = IO[Runnable,A]

Thursday, June 13, 13
Console I/O
trait Console[A]
case object ReadLine extends Console[Option[String]]
case class PrintLn(s: String) extends Console[Unit]
type ConsoleIO[A] = IO[Console,A]

Thursday, June 13, 13
The end of the world
trait Run[F[_]] {
def apply[A](expr: F[A]): (A, Run[F])
}
abstract class App[F[_]](R: Run[F]) {
def main(a: Array[String]): IO[F,Unit] =
run(pureMain(a))
def pureMain(a: Array[String]): IO[F,Unit]

}
Thursday, June 13, 13

def run[A](io: IO[F,A]): A =
io match {
case Pure(a) => a
case Request(req, k) =>
val (e, r2) = R(expr)
run(r2)(k(e))
}
Console I/O
object RunConsole extends Run[Console] {
def apply[A](c: Console[A]) = c match {
case ReadLine => (Option(readLine), RunConsole)
case PrintLn(s) => (println(s), RunConsole)
}
}
IO.run(RunConsole): IO[Console,A] => A

Thursday, June 13, 13
We can use this same model for

•
•
•
•
•
•

Thursday, June 13, 13

file system access
network sockets
HTTP requests
JDBC actions
system clock access
non-blocking I/O
Summary
•
•
•

It really is purely functional.

•
Thursday, June 13, 13

I/O can be done with pure functional
programming.

Now you know how it’s done.

You don’t need a purely functional
language to do it.
Afterword
•
•
•
•
Thursday, June 13, 13

There’s a lot more to be said
This presentation is simplified
Streaming I/O
Mutable arrays and references
Chapter 13
Functional Programming
in Scala
manning.com/bjarnason

Thursday, June 13, 13
Questions?

Thursday, June 13, 13
Watch the video with slide synchronization on
InfoQ.com!
http://www.infoq.com/presentations/iofunctional-side-effects

Más contenido relacionado

La actualidad más candente

La actualidad más candente (6)

Idiomatic Kotlin
Idiomatic KotlinIdiomatic Kotlin
Idiomatic Kotlin
 
Kotlin Slides from Devoxx 2011
Kotlin Slides from Devoxx 2011Kotlin Slides from Devoxx 2011
Kotlin Slides from Devoxx 2011
 
Friendly Functional Programming
Friendly Functional ProgrammingFriendly Functional Programming
Friendly Functional Programming
 
Zio from Home
Zio from Home Zio from Home
Zio from Home
 
Fiber supervision in ZIO
Fiber supervision in ZIOFiber supervision in ZIO
Fiber supervision in ZIO
 
"That scripting language called Prolog"
"That scripting language called Prolog""That scripting language called Prolog"
"That scripting language called Prolog"
 

Destacado

Compositional I/O Stream in Scala
Compositional I/O Stream in ScalaCompositional I/O Stream in Scala
Compositional I/O Stream in ScalaC4Media
 
Reasonable RPC with Remotely
Reasonable RPC with RemotelyReasonable RPC with Remotely
Reasonable RPC with RemotelyTimothy Perrett
 
Peyton jones-2009-fun with-type_functions-slide
Peyton jones-2009-fun with-type_functions-slidePeyton jones-2009-fun with-type_functions-slide
Peyton jones-2009-fun with-type_functions-slideTakayuki Muranushi
 
Extending the Yahoo Streaming Benchmark + MapR Benchmarks
Extending the Yahoo Streaming Benchmark + MapR BenchmarksExtending the Yahoo Streaming Benchmark + MapR Benchmarks
Extending the Yahoo Streaming Benchmark + MapR BenchmarksJamie Grier
 
Livy: A REST Web Service For Apache Spark
Livy: A REST Web Service For Apache SparkLivy: A REST Web Service For Apache Spark
Livy: A REST Web Service For Apache SparkJen Aman
 
The Columnar Era: Leveraging Parquet, Arrow and Kudu for High-Performance Ana...
The Columnar Era: Leveraging Parquet, Arrow and Kudu for High-Performance Ana...The Columnar Era: Leveraging Parquet, Arrow and Kudu for High-Performance Ana...
The Columnar Era: Leveraging Parquet, Arrow and Kudu for High-Performance Ana...DataWorks Summit/Hadoop Summit
 
Introduction to Functional Programming with Scala
Introduction to Functional Programming with ScalaIntroduction to Functional Programming with Scala
Introduction to Functional Programming with Scalapramode_ce
 

Destacado (10)

Beyond Mere Actors
Beyond Mere ActorsBeyond Mere Actors
Beyond Mere Actors
 
Compositional I/O Stream in Scala
Compositional I/O Stream in ScalaCompositional I/O Stream in Scala
Compositional I/O Stream in Scala
 
Reasonable RPC with Remotely
Reasonable RPC with RemotelyReasonable RPC with Remotely
Reasonable RPC with Remotely
 
Peyton jones-2009-fun with-type_functions-slide
Peyton jones-2009-fun with-type_functions-slidePeyton jones-2009-fun with-type_functions-slide
Peyton jones-2009-fun with-type_functions-slide
 
Reactive Design Patterns
Reactive Design PatternsReactive Design Patterns
Reactive Design Patterns
 
Extending the Yahoo Streaming Benchmark + MapR Benchmarks
Extending the Yahoo Streaming Benchmark + MapR BenchmarksExtending the Yahoo Streaming Benchmark + MapR Benchmarks
Extending the Yahoo Streaming Benchmark + MapR Benchmarks
 
Why Play Framework is fast
Why Play Framework is fastWhy Play Framework is fast
Why Play Framework is fast
 
Livy: A REST Web Service For Apache Spark
Livy: A REST Web Service For Apache SparkLivy: A REST Web Service For Apache Spark
Livy: A REST Web Service For Apache Spark
 
The Columnar Era: Leveraging Parquet, Arrow and Kudu for High-Performance Ana...
The Columnar Era: Leveraging Parquet, Arrow and Kudu for High-Performance Ana...The Columnar Era: Leveraging Parquet, Arrow and Kudu for High-Performance Ana...
The Columnar Era: Leveraging Parquet, Arrow and Kudu for High-Performance Ana...
 
Introduction to Functional Programming with Scala
Introduction to Functional Programming with ScalaIntroduction to Functional Programming with Scala
Introduction to Functional Programming with Scala
 

Similar a Purely Functional I/O

How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...Oursky
 
How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...Jane Chung
 
Towards a software ecosystem for java prolog interoperabilty
Towards a software ecosystem for java prolog interoperabiltyTowards a software ecosystem for java prolog interoperabilty
Towards a software ecosystem for java prolog interoperabiltykim.mens
 
Ciconf 2012 - Better than Ad-hoc
Ciconf 2012 - Better than Ad-hocCiconf 2012 - Better than Ad-hoc
Ciconf 2012 - Better than Ad-hocCalvin Froedge
 
First Ride on Rust
First Ride on RustFirst Ride on Rust
First Ride on RustDavid Evans
 
Java 8 new features or the ones you might actually use
Java 8 new features or the ones you might actually useJava 8 new features or the ones you might actually use
Java 8 new features or the ones you might actually useSharon Rozinsky
 
Functional Reactive Programming in Clojurescript
Functional Reactive Programming in ClojurescriptFunctional Reactive Programming in Clojurescript
Functional Reactive Programming in ClojurescriptLeonardo Borges
 
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...Richard McIntyre
 
Having Fun with Kotlin Android - DILo Surabaya
Having Fun with Kotlin Android - DILo SurabayaHaving Fun with Kotlin Android - DILo Surabaya
Having Fun with Kotlin Android - DILo SurabayaDILo Surabaya
 
Introduction to Play 2
Introduction to Play 2Introduction to Play 2
Introduction to Play 2Matteo Depalo
 
Robot Localisation: An Introduction - Luis Contreras 2020.06.09 | RoboCup@Hom...
Robot Localisation: An Introduction - Luis Contreras 2020.06.09 | RoboCup@Hom...Robot Localisation: An Introduction - Luis Contreras 2020.06.09 | RoboCup@Hom...
Robot Localisation: An Introduction - Luis Contreras 2020.06.09 | RoboCup@Hom...robocupathomeedu
 
The Not Java That's Not Scala
The Not Java That's Not ScalaThe Not Java That's Not Scala
The Not Java That's Not ScalaJustin Lee
 
Design Patterns for Mobile Applications
Design Patterns for Mobile ApplicationsDesign Patterns for Mobile Applications
Design Patterns for Mobile ApplicationsC4Media
 

Similar a Purely Functional I/O (20)

How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...
 
How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...
 
Clojure night
Clojure nightClojure night
Clojure night
 
EvoSoft 2013 Presentation
EvoSoft 2013 PresentationEvoSoft 2013 Presentation
EvoSoft 2013 Presentation
 
LogicObjects
LogicObjectsLogicObjects
LogicObjects
 
Issta13 workshop on debugging
Issta13 workshop on debuggingIssta13 workshop on debugging
Issta13 workshop on debugging
 
Towards a software ecosystem for java prolog interoperabilty
Towards a software ecosystem for java prolog interoperabiltyTowards a software ecosystem for java prolog interoperabilty
Towards a software ecosystem for java prolog interoperabilty
 
Ciconf 2012 - Better than Ad-hoc
Ciconf 2012 - Better than Ad-hocCiconf 2012 - Better than Ad-hoc
Ciconf 2012 - Better than Ad-hoc
 
Programação Funcional
Programação FuncionalProgramação Funcional
Programação Funcional
 
First Ride on Rust
First Ride on RustFirst Ride on Rust
First Ride on Rust
 
Java 8 new features or the ones you might actually use
Java 8 new features or the ones you might actually useJava 8 new features or the ones you might actually use
Java 8 new features or the ones you might actually use
 
Exploring Kotlin
Exploring KotlinExploring Kotlin
Exploring Kotlin
 
Functional Reactive Programming in Clojurescript
Functional Reactive Programming in ClojurescriptFunctional Reactive Programming in Clojurescript
Functional Reactive Programming in Clojurescript
 
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
 
Having Fun with Kotlin Android - DILo Surabaya
Having Fun with Kotlin Android - DILo SurabayaHaving Fun with Kotlin Android - DILo Surabaya
Having Fun with Kotlin Android - DILo Surabaya
 
Introduction to Play 2
Introduction to Play 2Introduction to Play 2
Introduction to Play 2
 
Robot Localisation: An Introduction - Luis Contreras 2020.06.09 | RoboCup@Hom...
Robot Localisation: An Introduction - Luis Contreras 2020.06.09 | RoboCup@Hom...Robot Localisation: An Introduction - Luis Contreras 2020.06.09 | RoboCup@Hom...
Robot Localisation: An Introduction - Luis Contreras 2020.06.09 | RoboCup@Hom...
 
Functional programming
Functional programmingFunctional programming
Functional programming
 
The Not Java That's Not Scala
The Not Java That's Not ScalaThe Not Java That's Not Scala
The Not Java That's Not Scala
 
Design Patterns for Mobile Applications
Design Patterns for Mobile ApplicationsDesign Patterns for Mobile Applications
Design Patterns for Mobile Applications
 

Más de C4Media

Streaming a Million Likes/Second: Real-Time Interactions on Live Video
Streaming a Million Likes/Second: Real-Time Interactions on Live VideoStreaming a Million Likes/Second: Real-Time Interactions on Live Video
Streaming a Million Likes/Second: Real-Time Interactions on Live VideoC4Media
 
Next Generation Client APIs in Envoy Mobile
Next Generation Client APIs in Envoy MobileNext Generation Client APIs in Envoy Mobile
Next Generation Client APIs in Envoy MobileC4Media
 
Software Teams and Teamwork Trends Report Q1 2020
Software Teams and Teamwork Trends Report Q1 2020Software Teams and Teamwork Trends Report Q1 2020
Software Teams and Teamwork Trends Report Q1 2020C4Media
 
Understand the Trade-offs Using Compilers for Java Applications
Understand the Trade-offs Using Compilers for Java ApplicationsUnderstand the Trade-offs Using Compilers for Java Applications
Understand the Trade-offs Using Compilers for Java ApplicationsC4Media
 
Kafka Needs No Keeper
Kafka Needs No KeeperKafka Needs No Keeper
Kafka Needs No KeeperC4Media
 
High Performing Teams Act Like Owners
High Performing Teams Act Like OwnersHigh Performing Teams Act Like Owners
High Performing Teams Act Like OwnersC4Media
 
Does Java Need Inline Types? What Project Valhalla Can Bring to Java
Does Java Need Inline Types? What Project Valhalla Can Bring to JavaDoes Java Need Inline Types? What Project Valhalla Can Bring to Java
Does Java Need Inline Types? What Project Valhalla Can Bring to JavaC4Media
 
Service Meshes- The Ultimate Guide
Service Meshes- The Ultimate GuideService Meshes- The Ultimate Guide
Service Meshes- The Ultimate GuideC4Media
 
Shifting Left with Cloud Native CI/CD
Shifting Left with Cloud Native CI/CDShifting Left with Cloud Native CI/CD
Shifting Left with Cloud Native CI/CDC4Media
 
CI/CD for Machine Learning
CI/CD for Machine LearningCI/CD for Machine Learning
CI/CD for Machine LearningC4Media
 
Fault Tolerance at Speed
Fault Tolerance at SpeedFault Tolerance at Speed
Fault Tolerance at SpeedC4Media
 
Architectures That Scale Deep - Regaining Control in Deep Systems
Architectures That Scale Deep - Regaining Control in Deep SystemsArchitectures That Scale Deep - Regaining Control in Deep Systems
Architectures That Scale Deep - Regaining Control in Deep SystemsC4Media
 
ML in the Browser: Interactive Experiences with Tensorflow.js
ML in the Browser: Interactive Experiences with Tensorflow.jsML in the Browser: Interactive Experiences with Tensorflow.js
ML in the Browser: Interactive Experiences with Tensorflow.jsC4Media
 
Build Your Own WebAssembly Compiler
Build Your Own WebAssembly CompilerBuild Your Own WebAssembly Compiler
Build Your Own WebAssembly CompilerC4Media
 
User & Device Identity for Microservices @ Netflix Scale
User & Device Identity for Microservices @ Netflix ScaleUser & Device Identity for Microservices @ Netflix Scale
User & Device Identity for Microservices @ Netflix ScaleC4Media
 
Scaling Patterns for Netflix's Edge
Scaling Patterns for Netflix's EdgeScaling Patterns for Netflix's Edge
Scaling Patterns for Netflix's EdgeC4Media
 
Make Your Electron App Feel at Home Everywhere
Make Your Electron App Feel at Home EverywhereMake Your Electron App Feel at Home Everywhere
Make Your Electron App Feel at Home EverywhereC4Media
 
The Talk You've Been Await-ing For
The Talk You've Been Await-ing ForThe Talk You've Been Await-ing For
The Talk You've Been Await-ing ForC4Media
 
Future of Data Engineering
Future of Data EngineeringFuture of Data Engineering
Future of Data EngineeringC4Media
 
Automated Testing for Terraform, Docker, Packer, Kubernetes, and More
Automated Testing for Terraform, Docker, Packer, Kubernetes, and MoreAutomated Testing for Terraform, Docker, Packer, Kubernetes, and More
Automated Testing for Terraform, Docker, Packer, Kubernetes, and MoreC4Media
 

Más de C4Media (20)

Streaming a Million Likes/Second: Real-Time Interactions on Live Video
Streaming a Million Likes/Second: Real-Time Interactions on Live VideoStreaming a Million Likes/Second: Real-Time Interactions on Live Video
Streaming a Million Likes/Second: Real-Time Interactions on Live Video
 
Next Generation Client APIs in Envoy Mobile
Next Generation Client APIs in Envoy MobileNext Generation Client APIs in Envoy Mobile
Next Generation Client APIs in Envoy Mobile
 
Software Teams and Teamwork Trends Report Q1 2020
Software Teams and Teamwork Trends Report Q1 2020Software Teams and Teamwork Trends Report Q1 2020
Software Teams and Teamwork Trends Report Q1 2020
 
Understand the Trade-offs Using Compilers for Java Applications
Understand the Trade-offs Using Compilers for Java ApplicationsUnderstand the Trade-offs Using Compilers for Java Applications
Understand the Trade-offs Using Compilers for Java Applications
 
Kafka Needs No Keeper
Kafka Needs No KeeperKafka Needs No Keeper
Kafka Needs No Keeper
 
High Performing Teams Act Like Owners
High Performing Teams Act Like OwnersHigh Performing Teams Act Like Owners
High Performing Teams Act Like Owners
 
Does Java Need Inline Types? What Project Valhalla Can Bring to Java
Does Java Need Inline Types? What Project Valhalla Can Bring to JavaDoes Java Need Inline Types? What Project Valhalla Can Bring to Java
Does Java Need Inline Types? What Project Valhalla Can Bring to Java
 
Service Meshes- The Ultimate Guide
Service Meshes- The Ultimate GuideService Meshes- The Ultimate Guide
Service Meshes- The Ultimate Guide
 
Shifting Left with Cloud Native CI/CD
Shifting Left with Cloud Native CI/CDShifting Left with Cloud Native CI/CD
Shifting Left with Cloud Native CI/CD
 
CI/CD for Machine Learning
CI/CD for Machine LearningCI/CD for Machine Learning
CI/CD for Machine Learning
 
Fault Tolerance at Speed
Fault Tolerance at SpeedFault Tolerance at Speed
Fault Tolerance at Speed
 
Architectures That Scale Deep - Regaining Control in Deep Systems
Architectures That Scale Deep - Regaining Control in Deep SystemsArchitectures That Scale Deep - Regaining Control in Deep Systems
Architectures That Scale Deep - Regaining Control in Deep Systems
 
ML in the Browser: Interactive Experiences with Tensorflow.js
ML in the Browser: Interactive Experiences with Tensorflow.jsML in the Browser: Interactive Experiences with Tensorflow.js
ML in the Browser: Interactive Experiences with Tensorflow.js
 
Build Your Own WebAssembly Compiler
Build Your Own WebAssembly CompilerBuild Your Own WebAssembly Compiler
Build Your Own WebAssembly Compiler
 
User & Device Identity for Microservices @ Netflix Scale
User & Device Identity for Microservices @ Netflix ScaleUser & Device Identity for Microservices @ Netflix Scale
User & Device Identity for Microservices @ Netflix Scale
 
Scaling Patterns for Netflix's Edge
Scaling Patterns for Netflix's EdgeScaling Patterns for Netflix's Edge
Scaling Patterns for Netflix's Edge
 
Make Your Electron App Feel at Home Everywhere
Make Your Electron App Feel at Home EverywhereMake Your Electron App Feel at Home Everywhere
Make Your Electron App Feel at Home Everywhere
 
The Talk You've Been Await-ing For
The Talk You've Been Await-ing ForThe Talk You've Been Await-ing For
The Talk You've Been Await-ing For
 
Future of Data Engineering
Future of Data EngineeringFuture of Data Engineering
Future of Data Engineering
 
Automated Testing for Terraform, Docker, Packer, Kubernetes, and More
Automated Testing for Terraform, Docker, Packer, Kubernetes, and MoreAutomated Testing for Terraform, Docker, Packer, Kubernetes, and More
Automated Testing for Terraform, Docker, Packer, Kubernetes, and More
 

Último

What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Ryan Mahoney - Will Artificial Intelligence Replace Real Estate Agents
Ryan Mahoney - Will Artificial Intelligence Replace Real Estate AgentsRyan Mahoney - Will Artificial Intelligence Replace Real Estate Agents
Ryan Mahoney - Will Artificial Intelligence Replace Real Estate AgentsRyan Mahoney
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 

Último (20)

What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Ryan Mahoney - Will Artificial Intelligence Replace Real Estate Agents
Ryan Mahoney - Will Artificial Intelligence Replace Real Estate AgentsRyan Mahoney - Will Artificial Intelligence Replace Real Estate Agents
Ryan Mahoney - Will Artificial Intelligence Replace Real Estate Agents
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 

Purely Functional I/O

  • 1. Purely Functional I/O Rúnar Bjarnason @runarorama QCon New York 2013 Thursday, June 13, 13
  • 2. Watch the video with slide synchronization on InfoQ.com! http://www.infoq.com/presentations /io-functional-side-effects InfoQ.com: News & Community Site • 750,000 unique visitors/month • Published in 4 languages (English, Chinese, Japanese and Brazilian Portuguese) • Post content from our QCon conferences • News 15-20 / week • Articles 3-4 / week • Presentations (videos) 12-15 / week • Interviews 2-3 / week • Books 1 / month
  • 3. Presented at QCon New York www.qconnewyork.com Purpose of QCon - to empower software development by facilitating the spread of knowledge and innovation Strategy - practitioner-driven conference designed for YOU: influencers of change and innovation in your teams - speakers and topics driving the evolution and innovation - connecting and catalyzing the influencers and innovators Highlights - attended by more than 12,000 delegates since 2007 - held in 9 cities worldwide
  • 4. Who is this jackass? • • • Thursday, June 13, 13 Enterprise Java refugee Author, Functional Programming in Scala manning.com/bjarnason Partially responsible for Scalaz and Functional Java
  • 5. What you should take away from this talk • • • Thursday, June 13, 13 I/O can be done with pure functional programming. It really is purely functional. How it’s done and why it’s done that way.
  • 6. What is purely functional? Thursday, June 13, 13
  • 7. Functional programming is not about lack of I/O Thursday, June 13, 13
  • 8. Functional programming is not about first-class functions or higher-order procedures. Thursday, June 13, 13
  • 9. Functional programming is not about immutability. Thursday, June 13, 13
  • 10. Functional programming is programming with pure functions Thursday, June 13, 13
  • 11. Functional programming is programming with functions Thursday, June 13, 13
  • 12. A function of type (a → b) maps every value of type a to exactly one value of type b. (and nothing else) Thursday, June 13, 13
  • 14. Side-effects • • • • • Thursday, June 13, 13 Reading from a file Writing to the console Starting threads Throwing exceptions Mutating memory
  • 15. An expression e is referentially transparent if for all programs p every occurrence of e in p can be replaced with the result of evaluating e without changing the meaning of p. Thursday, June 13, 13
  • 16. A function f is pure if f(x) is RT when x is RT. Thursday, June 13, 13
  • 17. A pure function always returns the same value given the same input. Thursday, June 13, 13
  • 18. A pure function does not depend on anything other than its argument. Thursday, June 13, 13
  • 19. The result of calling a pure function can be understood completely by looking at the returned value. Thursday, June 13, 13
  • 20. x = 2 y = 4 p = x + y Thursday, June 13, 13
  • 21. y = 4 p = 2 + y Thursday, June 13, 13
  • 22. p = 2 + 4 Thursday, June 13, 13
  • 23. p = 6 Thursday, June 13, 13
  • 24. def x = new Date().getTime def y = 4 def p = x + y Thursday, June 13, 13
  • 25. def y = 4 def p = 1369250684475 + y Thursday, June 13, 13
  • 26. A side-effect is anything that violates referential transparency. Thursday, June 13, 13
  • 27. Problems with sideeffecting I/O • • • • • Thursday, June 13, 13 Any function can perform I/O Monolithic, non-modular, limited reuse Novel compositions difficult Difficult to test Difficult to scale
  • 28. What we want • • • • Thursday, June 13, 13 Clear separation of I/O concern Modular and compositional API Easy to test Scales well
  • 29. class Cafe { def buyCoffee(cc: CreditCard): Coffee = { val cup = new Coffee() Payments.charge(cc, cup.price) cup } } Thursday, June 13, 13
  • 30. class Cafe { def buyCoffee(cc: CreditCard, p: Payments): Coffee = { val cup = new Coffee() p.charge(cc, cup.price) cup } } Thursday, June 13, 13
  • 31. class Cafe { def buyCoffee(cc: CreditCard): (Coffee, Charge) = { val cup = new Coffee() (cup, new Charge(cc, cup.price)) } } Thursday, June 13, 13
  • 32. First-class I/O Instead of performing I/O as a side-effect, return a value to the caller that describes an interaction with the external system. Thursday, June 13, 13
  • 33. Java class App { public static void main(String[] args) {} } Thursday, June 13, 13
  • 34. Java class App { public static IO main(String[] args) {} } Thursday, June 13, 13
  • 35. Haskell main :: IO () Thursday, June 13, 13
  • 36. Haskell getLine :: IO String putStrLn :: String -> IO () Thursday, June 13, 13
  • 37. Haskell getInt :: IO Int getInt = fmap read getLine fmap :: (a -> b) -> IO a -> IO b read :: String -> Int Thursday, June 13, 13
  • 38. Haskell echo = getLine >>= putStrLn (>>=) :: IO a -> (a -> IO b) -> IO b Thursday, June 13, 13
  • 39. Haskell cat = forever echo forever x = x >> forever x (>>) :: IO a -> IO b -> IO b Thursday, June 13, 13
  • 40. Haskell cat = forever do x <- getLine putStrLn x forever x = do { x; forever x } Thursday, June 13, 13
  • 41. Scala println("What is your name?") println("Hello, " + readLine) Thursday, June 13, 13
  • 42. Haskell do putStrLn "What is your name?" putStrLn ("Hello, " ++ getLine) Thursday, June 13, 13
  • 43. Haskell do putStrLn "What is your name?" putStrLn ("Hello, " ++ getLine) Couldn't match expected type `String' with actual type `IO String' In the second argument of `(++)', namely `getLine' Thursday, June 13, 13
  • 44. Haskell putStrLn "What is your name?" >> getLine >>= greet greet name = putStrLn ("Hello, " ++ name) Thursday, June 13, 13
  • 45. Haskell do putStrLn "What is your name?" name <- getLine putStrLn ("Hello, " ++ name) Thursday, June 13, 13
  • 46. In Haskell, every program is a single referentially transparent expression. Thursday, June 13, 13
  • 47. Benefits of IO datatype • • • Thursday, June 13, 13 No side-effects. An IO action is a RT description. Effects are external to our program. Action-manipulating functions!
  • 48. Library of I/O functions sequence mapM replicateM liftM2 forever while :: :: :: :: :: :: [IO a] -> IO [a] (a -> IO b) -> [a] -> IO [b] Int -> IO a -> IO [a] (a -> b -> c) -> IO a -> IO b -> IO c IO a -> IO b IO Bool -> IO () And many more Thursday, June 13, 13
  • 49. Novel compositions getTenLines :: IO [String] getTenLines = sequence (replicate 10 getLine) Thursday, June 13, 13
  • 50. The world-as-state model class IO[A](val apply: RealWorld => (A, RealWorld)) Thursday, June 13, 13
  • 51. The world-as-state model class IO[A](val apply: () => A) Thursday, June 13, 13
  • 52. The end of the world sealed trait RealWorld abstract class Program { private val realWorld = new RealWorld {} final def main(args: Array[String]): Unit = pureMain(args).apply() def pureMain(args: IndexedSeq[String]): IO[Unit] } Thursday, June 13, 13
  • 53. Example IO actions def io[A](a: => A): IO[A] = new IO(() => a) def putStrLn(s: String): IO[Unit] = io(println(s)) def getLine: IO[String] = io(readLine) Thursday, June 13, 13
  • 54. Composing actions main = getLine >>= putStrLn >> main Thursday, June 13, 13
  • 55. Composing actions class IO[A](val apply: () => A) { def >>=[B](f: A => IO[B]): IO[B] = new IO[B](() => { apply(rw) f(a).apply(rw2) }) def >>[B](b: => IO[B]): IO[B] = >>=(_ => b) } Thursday, June 13, 13
  • 56. Composing actions new Program { def pureMain(args: IndexedSeq[String]): IO[Unit] = (getLine >>= putStrLn) >> pureMain(args) } Thursday, June 13, 13
  • 57. Composing actions main = do x <- getLine putStrLn x main Thursday, June 13, 13
  • 58. Composing actions new Program { def pureMain(args: IndexedSeq[String]): IO[Unit] = for { line <- getLine _ <- putStrLn(line) _ <- pureMain(args) } yield () } Thursday, June 13, 13
  • 59. Composing actions class IO[A](val apply: RealWorld => (A, RealWorld)) { def >>=[B](f: A => IO[B]): IO[B] = new IO[B] { rw => val (a, rw2) = apply(rw) f(a) } def >>[B](b: => IO[B]): IO[B] = >>=(_ => b) } Thursday, June 13, 13 def flatMap[B](f: A => IO[B]): IO[B] = >>=(f) def map[B](f: A => B): IO[B] = >>=(a => io(f(a)))
  • 60. Issues with world-as-state An IO[A] could do anything at all. Thursday, June 13, 13
  • 61. Issues with world-as-state This implementation overflows the stack in Scala. Solved with trampolining. Thursday, June 13, 13
  • 62. Issues with world-as-state main = forever (getLine >>= putStrLn) main = main Thursday, June 13, 13
  • 63. The “free monad” model sealed trait IO[A] case class Pure[A](a: A) extends IO[A] case class Request[I,A]( req: External[I], k: I => IO[A]) extends IO[A] Thursday, June 13, 13
  • 64. The “free monad” model sealed trait IO[F[_],A] case class Pure[F[_],A](a: A) extends IO[F,A] case class Request[F[_],I,A]( req: F[I], k: I => IO[A]) extends IO[A] Thursday, June 13, 13
  • 65. Any effect trait Runnable[A] { def run: A } def delay[A](a: => A) = new Runnable[A] { def run = a } type AnyIO[A] = IO[Runnable,A] Thursday, June 13, 13
  • 66. Console I/O trait Console[A] case object ReadLine extends Console[Option[String]] case class PrintLn(s: String) extends Console[Unit] type ConsoleIO[A] = IO[Console,A] Thursday, June 13, 13
  • 67. The end of the world trait Run[F[_]] { def apply[A](expr: F[A]): (A, Run[F]) } abstract class App[F[_]](R: Run[F]) { def main(a: Array[String]): IO[F,Unit] = run(pureMain(a)) def pureMain(a: Array[String]): IO[F,Unit] } Thursday, June 13, 13 def run[A](io: IO[F,A]): A = io match { case Pure(a) => a case Request(req, k) => val (e, r2) = R(expr) run(r2)(k(e)) }
  • 68. Console I/O object RunConsole extends Run[Console] { def apply[A](c: Console[A]) = c match { case ReadLine => (Option(readLine), RunConsole) case PrintLn(s) => (println(s), RunConsole) } } IO.run(RunConsole): IO[Console,A] => A Thursday, June 13, 13
  • 69. We can use this same model for • • • • • • Thursday, June 13, 13 file system access network sockets HTTP requests JDBC actions system clock access non-blocking I/O
  • 70. Summary • • • It really is purely functional. • Thursday, June 13, 13 I/O can be done with pure functional programming. Now you know how it’s done. You don’t need a purely functional language to do it.
  • 71. Afterword • • • • Thursday, June 13, 13 There’s a lot more to be said This presentation is simplified Streaming I/O Mutable arrays and references
  • 72. Chapter 13 Functional Programming in Scala manning.com/bjarnason Thursday, June 13, 13
  • 74. Watch the video with slide synchronization on InfoQ.com! http://www.infoq.com/presentations/iofunctional-side-effects