21 Intro To Effects
21 Intro To Effects
21 Intro To Effects
2023
Index
• Pure functional programming
• The Effect Pattern
– Option as an effect
– Future as an effect
• Capturing Arbitrary Side Effects as an Effect
– MyIO
– MyZIO
1
– instead of performing the effect we describe it
Option as a Effect
• Scala allows the use of null values to represent missing values
– But then, the programmer is required to check if a reference is null
before using it, or a NullPointerException will be thrown at runtime
• As we know, Scala has another way to represent optionality, which is the
Option type:
enum Option[+A]:
case Some(a: A)
case None
• Is Option[A] an effect?
Option as a Effect
• Does Option[A] describe the kind of computational concept it represents?
– Yes, it represents the absence of a value
• Does Option[A] describe the type of value it can produce?
– Yes, if there is a value it will be of type A
• Are externally visible side effects involved?
– No, there are no externally visible side effects involved.
• So, Option[A] is an effect !!!
Future as a Effect
• Scala defines the type Future[A] to represent asynchronous compu-
tations that may compute a value of type A or fail with an exception
• Is Future[A] an effect?
2
– It describe the concept of asynchronicity
– If values are produced they are of type A
– In this case, effects are required (allocating and executing threads),
but the execution of this effects is immediate not separated from its
description
• So Futures are not effects !!!
Future as a Effect
• Being not effects, they break referential transparency
• Consider this program
val twice =
Future(println("Hello"))
.flatMap(_ => Future(println("Hello")))
which prints “Hello” twice, but this simple refactoring prints “Hello” only
once
val printHello = Future(println("Hello"))
val twice = printHello.flatMap(_ => printHello)
object MyIO:
def apply[A](a: => A): MyIO[A] =
new MyIO(() => a)
• Is MyIO[A] an effect?
– It describes the computational concept of side effects
– If values are produced they are of type A
3
– In this case, if effects are required we separate the description of the
computations from its execution
def twice =
MyIO(println("Hello"))
.flatMap(_ => MyIO(println("Hello")))
def alsoTwice =
val hello = MyIO(println("Hello"))
hello.flatMap(_ => hello)
Exercises
• Create some MyIOs which:
1. measure the current type of the system
2. measure the duration of a computation
– use exercise 1
– use map/flatMap combinations of MyIO
3. read something from console
– use scala.io.StdIn
4. print something to the console (e.g. “what’s your name”), then read,
then print a welcome message
A Simplified ZIO
• In the MyIO type we’ve defined so far, we only have control over the result
type when the computation succeeds
• When the computation fails, we do not have a functional way to communi-
cate the type of the error.
• And the computation does not have requirements, so let’s also add an
channel for the needed environment
4
case class MyZIO[R, E, A](unsafeRun: R => Either[E, A]):
def map[B](f: A => B): MyZIO[R, E, B] =
MyZIO { r => unsafeRun(r) match
case Left(e) => Left(e)
case Right(a) => Right(f(a))
}
A Simplified ZIO
• And, let’s consider the variances of the type parameters:
case class MyZIO[-R, +E, +A](unsafeRun: R => Either[E, A]):
def map[B](f: A => B): MyZIO[R, E, B] =
MyZIO { r => unsafeRun(r) match
case Left(e) => Left(e)
case Right(a) => Right(f(a))
}
def flatMap[R1 <: R, E1 >: E, B](f: A => MyZIO[R1, E1, B]): MyZIO[R1, E1, B] =
MyZIO { r => unsafeRun(r) match
case Left(e) => Left(e)
case Right(a) => f(a).unsafeRun(r)
}
• The real implementation is not like this, but this implementation gives us
a mental model to better understand it.
Bibliography
• J. De Goes and A. Fraser. Zionomicon. Gumroad, TBP. https://www.zi
onomicon.com/
• D. Ciocîrlan. “ZIO 2.0 Course”. https://rockthejvm.com(Access: 2022-10-
10)
• A. Rosien. Essential Effects. Gumroad, TBP. https://essentialeffects.dev/
• M. Pilquist, R. Bjarnason, and P. Chiusano. Functional Programming in
Scala, Second Edition. Manning, TBP.