SlideShare a Scribd company logo
1 of 63
EVALUATING HYPE IN
SCALAPere Villega (@pvillega)
EVALUATING HYPE IN SCALA - @PVILLEGA
EVALUATING HYPE IN SCALA - @PVILLEGA
EVALUATING HYPE IN SCALA - @PVILLEGA
• 2016 - Free Monad
• 2017 - Recursion Schemes
• 2018 - Tagless Final & MTL
• 2019 - ???
EVALUATING HYPE IN SCALA - @PVILLEGA
EVALUATING HYPE IN SCALA - @PVILLEGA
EVALUATING HYPE IN SCALA - @PVILLEGA
• Free Monad
• Tagless Final & MTL
• ZIO
EVALUATING HYPE IN SCALA - @PVILLEGA
A long time ago…
EVALUATING HYPE IN SCALA - @PVILLEGA
EVALUATING HYPE IN SCALA - @PVILLEGA
EVALUATING HYPE IN SCALA - @PVILLEGA
EVALUATING HYPE IN SCALA - @PVILLEGA
trait UserRepositoryComponent {
val userRepository: UserRepository
class UserRepository {
...
}
}
trait UserServiceComponent {
this: UserRepositoryComponent =>
val userService: UserService
class UserService {
...
}
}
object ComponentRegistry extends
UserServiceComponent with
UserRepositoryComponent
{
val userRepository = new UserRepository
val userService = new UserService
}
EVALUATING HYPE IN SCALA - @PVILLEGA
EVALUATING HYPE IN SCALA - @PVILLEGA
EVALUATING HYPE IN SCALA - @PVILLEGA
EVALUATING HYPE IN SCALA - @PVILLEGA
/**
* Trait declaring methods that can be used to register by-name test functions that
* have any result type.
*/
trait TestRegistration { theSuite: Suite =>
/**
* Registers a test.
*
* @param testText the test text
* @param testTags the test tags
* @param testFun the test function
*/
def registerTest(testText: String, testTags: Tag*)(testFun: => Any /* Assertion */)(implicit pos: source.Position)
/**
* Registers an ignored test.
*
* @param testText the test text
* @param testTags the test tags
* @param testFun the test function
*/
def registerIgnoredTest(testText: String, testTags: Tag*)(testFun: => Any /* Assertion */)(implicit pos: source.Position)
}
EVALUATING HYPE IN SCALA - @PVILLEGA
EVALUATING HYPE IN SCALA - @PVILLEGA
2016
EVALUATING HYPE IN SCALA - @PVILLEGA
EVALUATING HYPE IN SCALA - @PVILLEGA
Free Monad
hose domain is the category of Monad
EVALUATING HYPE IN SCALA - @PVILLEGA
Free Monad
hat allows us to build a very simple M
EVALUATING HYPE IN SCALA - @PVILLEGA
EVALUATING HYPE IN SCALA - @PVILLEGA
https://typelevel.org/cats/datatypes/freemonad.html#what-is-free-in-theory
EVALUATING HYPE IN SCALA - @PVILLEGA
• Represent stateful computations as data
• Run recursive computations in a stack-safe way
• Build an embedded DSL (domain-specific langu
• Retarget a computation to another interpreter (u
EVALUATING HYPE IN SCALA - @PVILLEGA
1. Define an algebra of your primitive operations
2. Define your DSL by lifting your algebra into Fr
3. Write some programs in the DSL
4. Write an interpreter
5. Execute a program using the interpreter
EVALUATING HYPE IN SCALA - @PVILLEGA
1. Define an algebra of your primitive operations
sealed trait KVA[A]
case class Put[T](key: String, vl: T) extends KVA[Unit]
case class Get[T](key: String) extends KVA[Option[T]]
case class Delete(key: String) extends KVA[Unit]
EVALUATING HYPE IN SCALA - @PVILLEGA
2. Define your DSL by lifting your algebra into Free monad
import cats.free.Free
import cats.free.Free._
type KV[A] = Free[KVA, A]
def put[T](key: String, value: T): KVStore[Unit] =
liftF[KVStoreA, Unit](Put[T](key, value))
def get[T](key: String): KVStore[Option[T]] =
liftF[KVStoreA, Option[T]](Get[T](key))
def delete(key: String): KVStore[Unit] =
liftF(Delete(key))
EVALUATING HYPE IN SCALA - @PVILLEGA
3. Write some programs in the DSL
def program: KV[Option[Int]] =
for {
_ <- put("wild-cats", 2)
_ <- update[Int]("wild-cats", (_ + 12))
_ <- put("tame-cats", 5)
n <- get[Int]("wild-cats")
_ <- delete("tame-cats")
} yield n
EVALUATING HYPE IN SCALA - @PVILLEGA
4. Write an interpreter
def impureCompiler: KVA ~> Id = new (KVA ~> Id) {
val kvs = mutable.Map.empty[String, Any]
def apply[A](fa: KVA[A]): Id[A] =
fa match {
case Put(key, value) =>
kvs(key) = value
()
case Get(key) =>
kvs.get(key).map(_.asInstanceOf[A])
case Delete(key) =>
kvs.remove(key)
()
}
}
EVALUATING HYPE IN SCALA - @PVILLEGA
5. Execute a program using the interpreter
val result: Option[Int] =
program.foldMap(impureCompiler)
// put(wild-cats, 2)
// get(wild-cats)
// put(wild-cats, 14)
// put(tame-cats, 5)
// get(wild-cats)
// delete(tame-cats)
// result: Option[Int] = Some(14)
EVALUATING HYPE IN SCALA - @PVILLEGA
http://frees.io
EVALUATING HYPE IN SCALA - @PVILLEGA
• Amount of boilerplate
• Performance
• Learning curve (monoid, monad, natural transfo
EVALUATING HYPE IN SCALA - @PVILLEGA
EVALUATING HYPE IN SCALA - @PVILLEGA
doobie programs are values. You can compose s
EVALUATING HYPE IN SCALA - @PVILLEGA
2018
EVALUATING HYPE IN SCALA - @PVILLEGA
https://github.com/debasishg/typed-tagless-final
EVALUATING HYPE IN SCALA - @PVILLEGA
• programs are expressions built from generic
functions
• operations are done directly in the target
monad stack
• potentially less overhead as operations are
not reified as values
EVALUATING HYPE IN SCALA - @PVILLEGA
1. Define an algebra of your primitive operations
2. No need to lift your algebra, that is your DSL
3. Write some programs in the DSL
4. Write an interpreter
5. Execute a program using the interpreter
EVALUATING HYPE IN SCALA - @PVILLEGA
1. Define an algebra of your primitive operations
trait KVA[F[_]] {
def put[T](key: String, value: T): F[Unit]
def get[T](key: String): F[Option[T]]
def delete(key: String): F[Unit]
}
EVALUATING HYPE IN SCALA - @PVILLEGA
3. Write some programs in the DSL
def program[F[_] : Monad](alg: KVA[F]): F[Option[Int]] =
for {
_ <- alg.put(“wild-cats", 2)
_ <- alg.update[Int]("wild-cats", (_ + 12))
_ <- alg.put("tame-cats", 5)
n <- alg.get[Int]("wild-cats")
_ <- alg.delete("tame-cats")
} yield n
EVALUATING HYPE IN SCALA - @PVILLEGA
4. Write an interpreter
class DefaultKVA[F[_]: Monad]() extends KVA[F] {
val kvs = mutable.Map.empty[String, Any]
def put[T](key: String, value: T): F[Unit] = {
kvs(key) = value
().pure[F]
}
def get[T](key: String): F[Option[T]] =
kvs.get(key).map(_.asInstanceOf[A]).pure[F]
def delete(key: String): F[Unit]= {
kvs.remove(key)
().pure[F]
}
}
EVALUATING HYPE IN SCALA - @PVILLEGA
5. Execute a program using the interpreter
val result: Option[Int] =
program[IO](new DefaultKVA()).unsafeRunSync()
// put(wild-cats, 2)
// get(wild-cats)
// put(wild-cats, 14)
// put(tame-cats, 5)
// get(wild-cats)
// delete(tame-cats)
// result: Option[Int] = Some(14)
EVALUATING HYPE IN SCALA - @PVILLEGA
Pawel Szulc - A road trip with Monads:
https://www.youtube.com/watch?v=y_QHSDOVJM8
EVALUATING HYPE IN SCALA - @PVILLEGA
def checkState: EitherT[StateT[List, Int, ?], Exception, String] = for {
currentState <- EitherT.liftF(StateT.get[List, Int])
result <- if (currentState > 10)
EitherT.leftT[StateT[List, Int, ?], String](new Exception("Too large"))
else
EitherT.rightT[StateT[List, Int, ?], Exception]("All good")
} yield result
EVALUATING HYPE IN SCALA - @PVILLEGA
def checkState[F[_]](implicit
S: MonadState[F, Int],
E: MonadError[F, Exception]): F[String] =
for {
currentState <- S.get
result <- if (currentState > 10)
E.raiseError(new Exception("Too large"))
else E.pure("All good")
} yield result
EVALUATING HYPE IN SCALA - @PVILLEGA
class BlazeMetricsExampleApp[F[_]: ConcurrentEffect: Timer] {
val metricsRegistry: MetricRegistry =
new MetricRegistry()
val metrics: HttpMiddleware[F] =
Metrics[F](Dropwizard(metricsRegistry, "server"))
def app: HttpApp[F] =
Router(
"/http4s" -> metrics(new ExampleService[F].routes),
"/http4s/metrics" -> metricsService[F](metricsRegistry)
).orNotFound
def stream: fs2.Stream[F, ExitCode] =
BlazeServerBuilder[F]
.bindHttp(8080)
.withHttpApp(app)
.serve
}
EVALUATING HYPE IN SCALA - @PVILLEGA
EVALUATING HYPE IN SCALA - @PVILLEGA
2019
EVALUATING HYPE IN SCALA - @PVILLEGA
def program[F[_] : Monad](alg: KVA[F]): F[Option[Int]] =
for {
_ <- alg.put(“wild-cats", 2)
_ <- alg.update[Int]("wild-cats", (_ + 12))
_ <- alg.put("tame-cats", 5)
n <- alg.get[Int]("wild-cats")
_ <- alg.delete("tame-cats")
} yield n
EVALUATING HYPE IN SCALA - @PVILLEGA
package object kva {
def put[T](key: String, value: T): ZIO[KVA, Nothing, Unit]
}
def program =
for {
_ <- put(“wild-cats", 2)
_ <- update[Int]("wild-cats", (_ + 12))
_ <- put("tame-cats", 5)
n <- get[Int]("wild-cats")
_ <- delete("tame-cats")
} yield n
EVALUATING HYPE IN SCALA - @PVILLEGA
1. Define an algebra of your primitive operations
trait Console { def console: Console.Service }
object Console {
trait Service {
def println(line: String): UIO[Unit]
val readLine: IO[IOException, String]
}
}
EVALUATING HYPE IN SCALA - @PVILLEGA
2. Define your helper methods
package object console {
def println(line: String): ZIO[Console, Nothing, Unit] =
ZIO.accessM(_.console println line)
val readLine: ZIO[Console, IOException, String] =
ZIO.accessM(_.console.readLine)
}
EVALUATING HYPE IN SCALA - @PVILLEGA
3. Write some programs in the DSL
val program: ZIO[Console, IOException, String] =
for {
_ <- println("Good morning, what is your name?")
name <- readLine
_ <- println(s"Good to meet you, $name!")
} yield name
EVALUATING HYPE IN SCALA - @PVILLEGA
4. Write an interpreter
trait Console { def console: Console.Service }
object Console {
trait Service {
def println(line: String): UIO[Unit]
val readLine: IO[IOException, String]
}
trait Live extends Console.Service {
import scala.io.StdIn.readLine
def println(line: String) =
UIO.effectTotal(scala.io.StdIn.println(line))
val readLine =
IO.effect(readLine()).refineOrDie(JustIOExceptions)
}
object Live extends Live
}
EVALUATING HYPE IN SCALA - @PVILLEGA
5. Execute a program using the interpreter
val programLive: IO[IOException, String] =
program.provide(Console.Live)
EVALUATING HYPE IN SCALA - @PVILLEGA
trait Console { def console: Console.Service }
trait Logging { def logging: Logging.Service }
trait Persistence { def persistence: Persistence.Service }
...
type ProgramEnv = Console with Logging with Persistence
val program1: ZIO[ProgramEnv, AppError, Unit] = ...
val program2: ZIO[ProgramEnv, AppError, String] = ...
EVALUATING HYPE IN SCALA - @PVILLEGA
EVALUATING HYPE IN SCALA - @PVILLEGA
https://blog.softwaremill.com/final-tagless-seen-alive-79a8d884691d
EVALUATING HYPE IN SCALA - @PVILLEGA
EVALUATING HYPE IN SCALA - @PVILLEGA
In conclusion
EVALUATING HYPE IN SCALA - @PVILLEGA
EVALUATING HYPE IN SCALA - @PVILLEGA
EVALUATING HYPE IN SCALA - @PVILLEGA
– QUESTIONS PLEASE
:)

More Related Content

What's hot

OLD VERSION - Understanding the V8 Runtime to Maximize Application Performance
OLD VERSION - Understanding the V8 Runtime to Maximize Application PerformanceOLD VERSION - Understanding the V8 Runtime to Maximize Application Performance
OLD VERSION - Understanding the V8 Runtime to Maximize Application PerformanceDaniel Fields
 
Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Real-time Aggregations, Ap...
Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Real-time Aggregations, Ap...Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Real-time Aggregations, Ap...
Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Real-time Aggregations, Ap...Data Con LA
 
Clean up your code with C#6
Clean up your code with C#6Clean up your code with C#6
Clean up your code with C#6Rui Carvalho
 
A Brief Intro to Scala
A Brief Intro to ScalaA Brief Intro to Scala
A Brief Intro to ScalaTim Underwood
 
LinkedIn TBC JavaScript 100: Functions
 LinkedIn TBC JavaScript 100: Functions LinkedIn TBC JavaScript 100: Functions
LinkedIn TBC JavaScript 100: FunctionsAdam Crabtree
 
Functional aspects of java 8
Functional aspects of java 8Functional aspects of java 8
Functional aspects of java 8Jobaer Chowdhury
 
Scala : language of the future
Scala : language of the futureScala : language of the future
Scala : language of the futureAnsviaLab
 
activity_and_fragment_may_2020_lakopi
activity_and_fragment_may_2020_lakopiactivity_and_fragment_may_2020_lakopi
activity_and_fragment_may_2020_lakopiToru Wonyoung Choi
 
Syntactic Salt and Sugar Presentation
Syntactic Salt and Sugar PresentationSyntactic Salt and Sugar Presentation
Syntactic Salt and Sugar Presentationgrepalex
 
Proxy deep-dive java-one_20151027_001
Proxy deep-dive java-one_20151027_001Proxy deep-dive java-one_20151027_001
Proxy deep-dive java-one_20151027_001Sven Ruppert
 
DI Frameworks - hidden pearls
DI Frameworks - hidden pearlsDI Frameworks - hidden pearls
DI Frameworks - hidden pearlsSven Ruppert
 
Refactoring to Java 8 (Devoxx BE)
Refactoring to Java 8 (Devoxx BE)Refactoring to Java 8 (Devoxx BE)
Refactoring to Java 8 (Devoxx BE)Trisha Gee
 
A Blueprint for Scala Microservices
A Blueprint for Scala MicroservicesA Blueprint for Scala Microservices
A Blueprint for Scala MicroservicesFederico Feroldi
 
Old Oracle Versions
Old Oracle VersionsOld Oracle Versions
Old Oracle VersionsJeffrey Kemp
 
Scala final ppt vinay
Scala final ppt vinayScala final ppt vinay
Scala final ppt vinayViplav Jain
 
JavaScript Functions
JavaScript FunctionsJavaScript Functions
JavaScript FunctionsColin DeCarlo
 
Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Iterative Spark Developmen...
Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Iterative Spark Developmen...Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Iterative Spark Developmen...
Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Iterative Spark Developmen...Data Con LA
 

What's hot (20)

OLD VERSION - Understanding the V8 Runtime to Maximize Application Performance
OLD VERSION - Understanding the V8 Runtime to Maximize Application PerformanceOLD VERSION - Understanding the V8 Runtime to Maximize Application Performance
OLD VERSION - Understanding the V8 Runtime to Maximize Application Performance
 
Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Real-time Aggregations, Ap...
Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Real-time Aggregations, Ap...Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Real-time Aggregations, Ap...
Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Real-time Aggregations, Ap...
 
Clean up your code with C#6
Clean up your code with C#6Clean up your code with C#6
Clean up your code with C#6
 
A Brief Intro to Scala
A Brief Intro to ScalaA Brief Intro to Scala
A Brief Intro to Scala
 
LinkedIn TBC JavaScript 100: Functions
 LinkedIn TBC JavaScript 100: Functions LinkedIn TBC JavaScript 100: Functions
LinkedIn TBC JavaScript 100: Functions
 
Functional aspects of java 8
Functional aspects of java 8Functional aspects of java 8
Functional aspects of java 8
 
Java script
Java scriptJava script
Java script
 
Scala : language of the future
Scala : language of the futureScala : language of the future
Scala : language of the future
 
activity_and_fragment_may_2020_lakopi
activity_and_fragment_may_2020_lakopiactivity_and_fragment_may_2020_lakopi
activity_and_fragment_may_2020_lakopi
 
Syntactic Salt and Sugar Presentation
Syntactic Salt and Sugar PresentationSyntactic Salt and Sugar Presentation
Syntactic Salt and Sugar Presentation
 
Proxy deep-dive java-one_20151027_001
Proxy deep-dive java-one_20151027_001Proxy deep-dive java-one_20151027_001
Proxy deep-dive java-one_20151027_001
 
DI Frameworks - hidden pearls
DI Frameworks - hidden pearlsDI Frameworks - hidden pearls
DI Frameworks - hidden pearls
 
Refactoring to Java 8 (Devoxx BE)
Refactoring to Java 8 (Devoxx BE)Refactoring to Java 8 (Devoxx BE)
Refactoring to Java 8 (Devoxx BE)
 
A Blueprint for Scala Microservices
A Blueprint for Scala MicroservicesA Blueprint for Scala Microservices
A Blueprint for Scala Microservices
 
Old Oracle Versions
Old Oracle VersionsOld Oracle Versions
Old Oracle Versions
 
Scala final ppt vinay
Scala final ppt vinayScala final ppt vinay
Scala final ppt vinay
 
Quick introduction to scala
Quick introduction to scalaQuick introduction to scala
Quick introduction to scala
 
Splat
SplatSplat
Splat
 
JavaScript Functions
JavaScript FunctionsJavaScript Functions
JavaScript Functions
 
Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Iterative Spark Developmen...
Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Iterative Spark Developmen...Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Iterative Spark Developmen...
Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Iterative Spark Developmen...
 

Similar to Evaluating Hype in scala

Kotlin: forse è la volta buona (Trento)
Kotlin: forse è la volta buona (Trento)Kotlin: forse è la volta buona (Trento)
Kotlin: forse è la volta buona (Trento)Davide Cerbo
 
Scala introduction
Scala introductionScala introduction
Scala introductionvito jeng
 
Intro to Apache Spark and Scala, Austin ACM SIGKDD, 7/9/2014
Intro to Apache Spark and Scala, Austin ACM SIGKDD, 7/9/2014Intro to Apache Spark and Scala, Austin ACM SIGKDD, 7/9/2014
Intro to Apache Spark and Scala, Austin ACM SIGKDD, 7/9/2014Roger Huang
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghStuart Roebuck
 
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...Naresha K
 
Terraform day 2
Terraform day 2Terraform day 2
Terraform day 2Kalkey
 
JavaCro 2014 Scala and Java EE 7 Development Experiences
JavaCro 2014 Scala and Java EE 7 Development ExperiencesJavaCro 2014 Scala and Java EE 7 Development Experiences
JavaCro 2014 Scala and Java EE 7 Development ExperiencesPeter Pilgrim
 
Swift: Apple's New Programming Language for iOS and OS X
Swift: Apple's New Programming Language for iOS and OS XSwift: Apple's New Programming Language for iOS and OS X
Swift: Apple's New Programming Language for iOS and OS XSasha Goldshtein
 
A Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to GoA Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to GoMatt Stine
 
Scala for Java Programmers
Scala for Java ProgrammersScala for Java Programmers
Scala for Java ProgrammersEric Pederson
 
Intro to ReactiveCocoa
Intro to ReactiveCocoaIntro to ReactiveCocoa
Intro to ReactiveCocoakleneau
 
TechShift: There’s light beyond LAMP
TechShift: There’s light beyond LAMPTechShift: There’s light beyond LAMP
TechShift: There’s light beyond LAMPStephen Tallamy
 
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017 Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017 Codemotion
 
Kotlin boost yourproductivity
Kotlin boost yourproductivityKotlin boost yourproductivity
Kotlin boost yourproductivitynklmish
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryTatsuhiko Miyagawa
 

Similar to Evaluating Hype in scala (20)

Kotlin: forse è la volta buona (Trento)
Kotlin: forse è la volta buona (Trento)Kotlin: forse è la volta buona (Trento)
Kotlin: forse è la volta buona (Trento)
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
Intro to Apache Spark and Scala, Austin ACM SIGKDD, 7/9/2014
Intro to Apache Spark and Scala, Austin ACM SIGKDD, 7/9/2014Intro to Apache Spark and Scala, Austin ACM SIGKDD, 7/9/2014
Intro to Apache Spark and Scala, Austin ACM SIGKDD, 7/9/2014
 
Scala 20140715
Scala 20140715Scala 20140715
Scala 20140715
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup Edinburgh
 
Scala in a nutshell by venkat
Scala in a nutshell by venkatScala in a nutshell by venkat
Scala in a nutshell by venkat
 
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...
 
Terraform day 2
Terraform day 2Terraform day 2
Terraform day 2
 
JavaCro'14 - Scala and Java EE 7 Development Experiences – Peter Pilgrim
JavaCro'14 - Scala and Java EE 7 Development Experiences – Peter PilgrimJavaCro'14 - Scala and Java EE 7 Development Experiences – Peter Pilgrim
JavaCro'14 - Scala and Java EE 7 Development Experiences – Peter Pilgrim
 
JavaCro 2014 Scala and Java EE 7 Development Experiences
JavaCro 2014 Scala and Java EE 7 Development ExperiencesJavaCro 2014 Scala and Java EE 7 Development Experiences
JavaCro 2014 Scala and Java EE 7 Development Experiences
 
Swift: Apple's New Programming Language for iOS and OS X
Swift: Apple's New Programming Language for iOS and OS XSwift: Apple's New Programming Language for iOS and OS X
Swift: Apple's New Programming Language for iOS and OS X
 
A Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to GoA Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to Go
 
Scala for Java Programmers
Scala for Java ProgrammersScala for Java Programmers
Scala for Java Programmers
 
Intro to ReactiveCocoa
Intro to ReactiveCocoaIntro to ReactiveCocoa
Intro to ReactiveCocoa
 
TechShift: There’s light beyond LAMP
TechShift: There’s light beyond LAMPTechShift: There’s light beyond LAMP
TechShift: There’s light beyond LAMP
 
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017 Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
 
angular fundamentals.pdf
angular fundamentals.pdfangular fundamentals.pdf
angular fundamentals.pdf
 
Kotlin boost yourproductivity
Kotlin boost yourproductivityKotlin boost yourproductivity
Kotlin boost yourproductivity
 
Scala to assembly
Scala to assemblyScala to assembly
Scala to assembly
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
 

Recently uploaded

SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Science&tech:THE INFORMATION AGE STS.pdf
Science&tech:THE INFORMATION AGE STS.pdfScience&tech:THE INFORMATION AGE STS.pdf
Science&tech:THE INFORMATION AGE STS.pdfjimielynbastida
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDGMarianaLemus7
 
Unlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power SystemsUnlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power SystemsPrecisely
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraDeakin University
 
Snow Chain-Integrated Tire for a Safe Drive on Winter Roads
Snow Chain-Integrated Tire for a Safe Drive on Winter RoadsSnow Chain-Integrated Tire for a Safe Drive on Winter Roads
Snow Chain-Integrated Tire for a Safe Drive on Winter RoadsHyundai Motor Group
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 
Bluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdfBluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdfngoud9212
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 

Recently uploaded (20)

SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Science&tech:THE INFORMATION AGE STS.pdf
Science&tech:THE INFORMATION AGE STS.pdfScience&tech:THE INFORMATION AGE STS.pdf
Science&tech:THE INFORMATION AGE STS.pdf
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDG
 
Unlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power SystemsUnlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power Systems
 
The transition to renewables in India.pdf
The transition to renewables in India.pdfThe transition to renewables in India.pdf
The transition to renewables in India.pdf
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning era
 
Snow Chain-Integrated Tire for a Safe Drive on Winter Roads
Snow Chain-Integrated Tire for a Safe Drive on Winter RoadsSnow Chain-Integrated Tire for a Safe Drive on Winter Roads
Snow Chain-Integrated Tire for a Safe Drive on Winter Roads
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 
Bluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdfBluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdf
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptxVulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 

Evaluating Hype in scala

  • 1. EVALUATING HYPE IN SCALAPere Villega (@pvillega)
  • 2. EVALUATING HYPE IN SCALA - @PVILLEGA
  • 3. EVALUATING HYPE IN SCALA - @PVILLEGA
  • 4. EVALUATING HYPE IN SCALA - @PVILLEGA • 2016 - Free Monad • 2017 - Recursion Schemes • 2018 - Tagless Final & MTL • 2019 - ???
  • 5. EVALUATING HYPE IN SCALA - @PVILLEGA
  • 6. EVALUATING HYPE IN SCALA - @PVILLEGA
  • 7. EVALUATING HYPE IN SCALA - @PVILLEGA • Free Monad • Tagless Final & MTL • ZIO
  • 8. EVALUATING HYPE IN SCALA - @PVILLEGA A long time ago…
  • 9. EVALUATING HYPE IN SCALA - @PVILLEGA
  • 10. EVALUATING HYPE IN SCALA - @PVILLEGA
  • 11. EVALUATING HYPE IN SCALA - @PVILLEGA
  • 12. EVALUATING HYPE IN SCALA - @PVILLEGA trait UserRepositoryComponent { val userRepository: UserRepository class UserRepository { ... } } trait UserServiceComponent { this: UserRepositoryComponent => val userService: UserService class UserService { ... } } object ComponentRegistry extends UserServiceComponent with UserRepositoryComponent { val userRepository = new UserRepository val userService = new UserService }
  • 13. EVALUATING HYPE IN SCALA - @PVILLEGA
  • 14. EVALUATING HYPE IN SCALA - @PVILLEGA
  • 15. EVALUATING HYPE IN SCALA - @PVILLEGA
  • 16. EVALUATING HYPE IN SCALA - @PVILLEGA /** * Trait declaring methods that can be used to register by-name test functions that * have any result type. */ trait TestRegistration { theSuite: Suite => /** * Registers a test. * * @param testText the test text * @param testTags the test tags * @param testFun the test function */ def registerTest(testText: String, testTags: Tag*)(testFun: => Any /* Assertion */)(implicit pos: source.Position) /** * Registers an ignored test. * * @param testText the test text * @param testTags the test tags * @param testFun the test function */ def registerIgnoredTest(testText: String, testTags: Tag*)(testFun: => Any /* Assertion */)(implicit pos: source.Position) }
  • 17. EVALUATING HYPE IN SCALA - @PVILLEGA
  • 18. EVALUATING HYPE IN SCALA - @PVILLEGA 2016
  • 19. EVALUATING HYPE IN SCALA - @PVILLEGA
  • 20. EVALUATING HYPE IN SCALA - @PVILLEGA Free Monad hose domain is the category of Monad
  • 21. EVALUATING HYPE IN SCALA - @PVILLEGA Free Monad hat allows us to build a very simple M
  • 22. EVALUATING HYPE IN SCALA - @PVILLEGA
  • 23. EVALUATING HYPE IN SCALA - @PVILLEGA https://typelevel.org/cats/datatypes/freemonad.html#what-is-free-in-theory
  • 24. EVALUATING HYPE IN SCALA - @PVILLEGA • Represent stateful computations as data • Run recursive computations in a stack-safe way • Build an embedded DSL (domain-specific langu • Retarget a computation to another interpreter (u
  • 25. EVALUATING HYPE IN SCALA - @PVILLEGA 1. Define an algebra of your primitive operations 2. Define your DSL by lifting your algebra into Fr 3. Write some programs in the DSL 4. Write an interpreter 5. Execute a program using the interpreter
  • 26. EVALUATING HYPE IN SCALA - @PVILLEGA 1. Define an algebra of your primitive operations sealed trait KVA[A] case class Put[T](key: String, vl: T) extends KVA[Unit] case class Get[T](key: String) extends KVA[Option[T]] case class Delete(key: String) extends KVA[Unit]
  • 27. EVALUATING HYPE IN SCALA - @PVILLEGA 2. Define your DSL by lifting your algebra into Free monad import cats.free.Free import cats.free.Free._ type KV[A] = Free[KVA, A] def put[T](key: String, value: T): KVStore[Unit] = liftF[KVStoreA, Unit](Put[T](key, value)) def get[T](key: String): KVStore[Option[T]] = liftF[KVStoreA, Option[T]](Get[T](key)) def delete(key: String): KVStore[Unit] = liftF(Delete(key))
  • 28. EVALUATING HYPE IN SCALA - @PVILLEGA 3. Write some programs in the DSL def program: KV[Option[Int]] = for { _ <- put("wild-cats", 2) _ <- update[Int]("wild-cats", (_ + 12)) _ <- put("tame-cats", 5) n <- get[Int]("wild-cats") _ <- delete("tame-cats") } yield n
  • 29. EVALUATING HYPE IN SCALA - @PVILLEGA 4. Write an interpreter def impureCompiler: KVA ~> Id = new (KVA ~> Id) { val kvs = mutable.Map.empty[String, Any] def apply[A](fa: KVA[A]): Id[A] = fa match { case Put(key, value) => kvs(key) = value () case Get(key) => kvs.get(key).map(_.asInstanceOf[A]) case Delete(key) => kvs.remove(key) () } }
  • 30. EVALUATING HYPE IN SCALA - @PVILLEGA 5. Execute a program using the interpreter val result: Option[Int] = program.foldMap(impureCompiler) // put(wild-cats, 2) // get(wild-cats) // put(wild-cats, 14) // put(tame-cats, 5) // get(wild-cats) // delete(tame-cats) // result: Option[Int] = Some(14)
  • 31. EVALUATING HYPE IN SCALA - @PVILLEGA http://frees.io
  • 32. EVALUATING HYPE IN SCALA - @PVILLEGA • Amount of boilerplate • Performance • Learning curve (monoid, monad, natural transfo
  • 33. EVALUATING HYPE IN SCALA - @PVILLEGA
  • 34. EVALUATING HYPE IN SCALA - @PVILLEGA doobie programs are values. You can compose s
  • 35. EVALUATING HYPE IN SCALA - @PVILLEGA 2018
  • 36. EVALUATING HYPE IN SCALA - @PVILLEGA https://github.com/debasishg/typed-tagless-final
  • 37. EVALUATING HYPE IN SCALA - @PVILLEGA • programs are expressions built from generic functions • operations are done directly in the target monad stack • potentially less overhead as operations are not reified as values
  • 38. EVALUATING HYPE IN SCALA - @PVILLEGA 1. Define an algebra of your primitive operations 2. No need to lift your algebra, that is your DSL 3. Write some programs in the DSL 4. Write an interpreter 5. Execute a program using the interpreter
  • 39. EVALUATING HYPE IN SCALA - @PVILLEGA 1. Define an algebra of your primitive operations trait KVA[F[_]] { def put[T](key: String, value: T): F[Unit] def get[T](key: String): F[Option[T]] def delete(key: String): F[Unit] }
  • 40. EVALUATING HYPE IN SCALA - @PVILLEGA 3. Write some programs in the DSL def program[F[_] : Monad](alg: KVA[F]): F[Option[Int]] = for { _ <- alg.put(“wild-cats", 2) _ <- alg.update[Int]("wild-cats", (_ + 12)) _ <- alg.put("tame-cats", 5) n <- alg.get[Int]("wild-cats") _ <- alg.delete("tame-cats") } yield n
  • 41. EVALUATING HYPE IN SCALA - @PVILLEGA 4. Write an interpreter class DefaultKVA[F[_]: Monad]() extends KVA[F] { val kvs = mutable.Map.empty[String, Any] def put[T](key: String, value: T): F[Unit] = { kvs(key) = value ().pure[F] } def get[T](key: String): F[Option[T]] = kvs.get(key).map(_.asInstanceOf[A]).pure[F] def delete(key: String): F[Unit]= { kvs.remove(key) ().pure[F] } }
  • 42. EVALUATING HYPE IN SCALA - @PVILLEGA 5. Execute a program using the interpreter val result: Option[Int] = program[IO](new DefaultKVA()).unsafeRunSync() // put(wild-cats, 2) // get(wild-cats) // put(wild-cats, 14) // put(tame-cats, 5) // get(wild-cats) // delete(tame-cats) // result: Option[Int] = Some(14)
  • 43. EVALUATING HYPE IN SCALA - @PVILLEGA Pawel Szulc - A road trip with Monads: https://www.youtube.com/watch?v=y_QHSDOVJM8
  • 44. EVALUATING HYPE IN SCALA - @PVILLEGA def checkState: EitherT[StateT[List, Int, ?], Exception, String] = for { currentState <- EitherT.liftF(StateT.get[List, Int]) result <- if (currentState > 10) EitherT.leftT[StateT[List, Int, ?], String](new Exception("Too large")) else EitherT.rightT[StateT[List, Int, ?], Exception]("All good") } yield result
  • 45. EVALUATING HYPE IN SCALA - @PVILLEGA def checkState[F[_]](implicit S: MonadState[F, Int], E: MonadError[F, Exception]): F[String] = for { currentState <- S.get result <- if (currentState > 10) E.raiseError(new Exception("Too large")) else E.pure("All good") } yield result
  • 46. EVALUATING HYPE IN SCALA - @PVILLEGA class BlazeMetricsExampleApp[F[_]: ConcurrentEffect: Timer] { val metricsRegistry: MetricRegistry = new MetricRegistry() val metrics: HttpMiddleware[F] = Metrics[F](Dropwizard(metricsRegistry, "server")) def app: HttpApp[F] = Router( "/http4s" -> metrics(new ExampleService[F].routes), "/http4s/metrics" -> metricsService[F](metricsRegistry) ).orNotFound def stream: fs2.Stream[F, ExitCode] = BlazeServerBuilder[F] .bindHttp(8080) .withHttpApp(app) .serve }
  • 47. EVALUATING HYPE IN SCALA - @PVILLEGA
  • 48. EVALUATING HYPE IN SCALA - @PVILLEGA 2019
  • 49. EVALUATING HYPE IN SCALA - @PVILLEGA def program[F[_] : Monad](alg: KVA[F]): F[Option[Int]] = for { _ <- alg.put(“wild-cats", 2) _ <- alg.update[Int]("wild-cats", (_ + 12)) _ <- alg.put("tame-cats", 5) n <- alg.get[Int]("wild-cats") _ <- alg.delete("tame-cats") } yield n
  • 50. EVALUATING HYPE IN SCALA - @PVILLEGA package object kva { def put[T](key: String, value: T): ZIO[KVA, Nothing, Unit] } def program = for { _ <- put(“wild-cats", 2) _ <- update[Int]("wild-cats", (_ + 12)) _ <- put("tame-cats", 5) n <- get[Int]("wild-cats") _ <- delete("tame-cats") } yield n
  • 51. EVALUATING HYPE IN SCALA - @PVILLEGA 1. Define an algebra of your primitive operations trait Console { def console: Console.Service } object Console { trait Service { def println(line: String): UIO[Unit] val readLine: IO[IOException, String] } }
  • 52. EVALUATING HYPE IN SCALA - @PVILLEGA 2. Define your helper methods package object console { def println(line: String): ZIO[Console, Nothing, Unit] = ZIO.accessM(_.console println line) val readLine: ZIO[Console, IOException, String] = ZIO.accessM(_.console.readLine) }
  • 53. EVALUATING HYPE IN SCALA - @PVILLEGA 3. Write some programs in the DSL val program: ZIO[Console, IOException, String] = for { _ <- println("Good morning, what is your name?") name <- readLine _ <- println(s"Good to meet you, $name!") } yield name
  • 54. EVALUATING HYPE IN SCALA - @PVILLEGA 4. Write an interpreter trait Console { def console: Console.Service } object Console { trait Service { def println(line: String): UIO[Unit] val readLine: IO[IOException, String] } trait Live extends Console.Service { import scala.io.StdIn.readLine def println(line: String) = UIO.effectTotal(scala.io.StdIn.println(line)) val readLine = IO.effect(readLine()).refineOrDie(JustIOExceptions) } object Live extends Live }
  • 55. EVALUATING HYPE IN SCALA - @PVILLEGA 5. Execute a program using the interpreter val programLive: IO[IOException, String] = program.provide(Console.Live)
  • 56. EVALUATING HYPE IN SCALA - @PVILLEGA trait Console { def console: Console.Service } trait Logging { def logging: Logging.Service } trait Persistence { def persistence: Persistence.Service } ... type ProgramEnv = Console with Logging with Persistence val program1: ZIO[ProgramEnv, AppError, Unit] = ... val program2: ZIO[ProgramEnv, AppError, String] = ...
  • 57. EVALUATING HYPE IN SCALA - @PVILLEGA
  • 58. EVALUATING HYPE IN SCALA - @PVILLEGA https://blog.softwaremill.com/final-tagless-seen-alive-79a8d884691d
  • 59. EVALUATING HYPE IN SCALA - @PVILLEGA
  • 60. EVALUATING HYPE IN SCALA - @PVILLEGA In conclusion
  • 61. EVALUATING HYPE IN SCALA - @PVILLEGA
  • 62. EVALUATING HYPE IN SCALA - @PVILLEGA
  • 63. EVALUATING HYPE IN SCALA - @PVILLEGA – QUESTIONS PLEASE :)

Editor's Notes

  1. Hello, I am Pere Villega, a Scala contractor working in London. First of all, thank you all for being here and to Joost and the organisers for inviting me. Much appreciated
  2. I have to be honest, this talk has been very problematic to assemble. See, initially I wanted to talk about MTL style and Tagless Final. I did a small lightning talk about the subject at Scala Exchange last year, so it was a good topic for a longer talk. Tagless final and MTL are a powerful way to organise your code.
  3. And then John killed tagless final. Thanks John. If you are here you are probably aware of all the noise around ZIO and tagless final, more so as, if I recall correctly, John was here a couple of weeks ago to talk about this. This was a big problem for me, as I prefer to do talks focussed on practical applications of concepts but suddenly I had no concept. :) (Image: https://twitter.com/hmemcpy/status/1104679168720154624?s=20)
  4. So, ok, I needed a new talk. The last weeks have had a lot of noise in the scala community about ZIO and tagless final, opinions in favour and against John's arguments. And then I remembered this slide I had in my original talk, about trends in the Scala community. Hey, I predicted the death of tagless first ;) Looking at the dates, we can say that we developers like new toys, we can't deny it. And the community as a whole is jumping from new technique to new technique with enthusiasm, with plenty of blog posts and libraries and documentation for each new trend.
  5. And the thing is, at a certain level this makes sense. The reason this is happening is the same reason some companies forbid using Cats on their codebases (yes, that is a thing). We want to use idiomatic patterns when we organise our code, so that other developers in our team can identify them and work with them. But, well, as our code grows the patterns we use hit some limitations, things that make our life harder. And we look for solutions in the community, which we get from the better known voices in the community, the ones that talk on each conference and blog weekly and such.
  6. And there is a dark truth in this whole process. We all agree with a principle that we repeat gain and again: there is no silver bullet. Use the right tool for the job. But let's be honest: we don’t act like it, it seems that we do crave the silver bullet. We got a 1h talk + 2 blogpost about a full replacement to Tagless final and I've seen more people jumping wagon than comparing pros and cons. Guys, seriously… if you think something is not great because you have spent hundreds of hours working with it, wouldn’t you need hundreds of hours on the new concept for a decent evaluation? At least a few dozen hours?
  7. So what I want to do today is a quick recap on some of these patterns we, as a community, have experimented with. Revisit all these hype moments and see if they are still useful techniques, if we should really forget them and replace them with the new shiny toy in town. Before I continue, a warning: examples for these patterns will use very simplified domains. We are all aware it's with more complex code that you find the limitations of a pattern, but what we want now is a quick review and direct comparison, where complex code would make this difficult and confusing. Luckily none of these concepts (except ZIO) is new, and you can find plenty of resources out there with more complex examples if you want to explore them in depth.
  8. Let's start with ancient history.
  9. Let's go back to April 2007, where in the Scala Lounge this question was asked. Someone asking for help on how to structure his code, finding these idiomatic patterns we mentioned. (source http://www.scala-archive.org/Inheriting-static-members-td2010292.html )
  10. A certain Jon Pretty, whom you may have heard about, came to his rescue.
  11. The Cake Pattern was created, and history was made
  12. What is the cake pattern? Let me give you a simplified description. The core idea behind the cake pattern is that we can use the language itself, Scala, to do dependency injection instead of having to rely on half-magical libraries like Guice or Spring for DI. A better way to structure our code. This is achieved is through the use of self-types. In this simplified example, we have two components. One is a User Repository component, which is defined as a trait that has an abstract value (userRepository) and code that relies on that value being present. The second component, User Service Component, depends on another abstract value, a userService value. And it also uses a self-type to say: hey, I am also a UserRepositoryComponent, so you get access to any operations defined in UserRepositoryComponent. You can define several of these components and it is at the ‘edge of the world’ where you say: ok, I have a ComponentRegistry which will extend both traits and in here I’ll define the concrete instances for the abstract values, wiring the dependencies now, at compile time. That’s a (very simplified) explanation of the Cake Pattern
  13. And the community loved it. Stack overflow alone has 381 questions or answers that reference this pattern under the 'scala' tag, the most recent from January 2019 (this year!).
  14. You had blog posts from influential people in the community, like Jonas Boner, explaining how to use the cake pattern for dependency injection
  15. But when Jon celebrated the 10th anniversary, these were some of the answers. Cake Pattern is now a days considered an anti pattern. It has many downsides: Adding a new dependency may mean having to modify all the stack of traits as self-types are not inherited You end up at the edge with an object with an extremely large number of traits where you are combining everything together at once: infrastructure, domain services, persistence, business logic… it’s not initialised on a ‘peer need’ basis, but all at once. (sources https://kubuszok.com/2018/cake-antipattern/ and http://www.warski.org/blog/2011/04/di-in-scala-cake-pattern-pros-cons/ )
  16. Note that self-types are a valid solution for some problems. For example, this code belongs to a trait in Scala Test. It relies on self-types for its suites. The pattern is not bad per-se. There is a lesson to be learned that we will see repeated again. Cake was a staple for the Scala community for years, the solution to DI. A compile time solution vs the magic of Spring wiring so prevalent at that time, it was refreshing, new, useful. The community leaders, the ruling voices at the time thought it was a good tool and it was mass adopted, without questions, and it took long for us to realise it was not worth it, that forcing the pattern to embrace the full application and not specific cases (like ScalaTest does) wasn’t a correct solution. As a side note, I’d like to put some kind of ‘bookmark’ in your brains here, don't forget the cake pattern, we may come back to it.
  17. As a bonus, if you ever wondered why was it named 'the cake pattern' I'll leave you with John's explanation here.
  18. Let's move forward in time, to 2016. Better times where Brexit and Trump weren't the only subject in the news.
  19. Free Monads enter the 'mainstream' is the Scala community, appearing in most (if not all) the conferences. I'm guilty as charged to falling into that hype, too! I wrote a long blog post showing a practical approach on using Free with Cats (may be a bit outdated for the current cats version, you have been warned) Why such popularity? Because it was a novel technique (in the Scala world) which helped people organise the code. At a moment in which FP was becoming more mainstream, a way to organise your code boundaries that was ‘compliant’ with FP principles was very appreciated. Remember, we want patterns for our code structure which are useful and other developers can easily identify and work with. (see https://perevillega.com/understanding-free-monads)
  20. What’s a Free Monad? A Free Monad "is a construction that is left adjoint to a forgetful functor whose domain is the category of Monads and whose co-domain is the category of Endofunctors" Yeah, I don't get it either.
  21. A Free Monad is just a clever construction that allows us to build a very simple Monad from any functor. As a consequence, if you can get a Functor, you get a Monad. This is important.
  22. Monads, as well as burritos, are a way to represent and chained computations. If you can represent something as a Functor, you can then obtain for free a monad on it (Free Monad). Which means it can become part of a chain of computations. A Functor is a very simple structure, easy to create. But there is an additional magic trick in play: using Coyoneda (see https://medium.com/@olxc/yoneda-and-coyoneda-trick-f5a0321aeba4 - don’t make me explain it) you can turn any F[_] into a Functor. You can turn any F[_] in your code into a monad and use it in chains of computations, to represent business logic.
  23. This is the non-category-theory explanation. You can get more detailed theory behind the concept in the cats documentation at https://typelevel.org/cats/datatypes/freemonad.html#what-is-free-in-theory
  24. Ok, so a Free Monad is a way to turn an F[_] into a Monad. Why is that useful? Why did it become popular? Because Free provides is separation between the program definition and its execution. In particular, free monads provide a practical way to: • represent stateful computations as data, and run them • run recursive computations in a stack-safe way • build an embedded DSL (domain-specific language) • retarget a computation to another interpreter using natural transformations (see https://typelevel.org/cats/datatypes/freemonad.html) Those are things we, as FP followers, want. Separate execution of a computation from declaration allows us to reason better about it, and we can even do some optimizations before execution. Stack safety is good. Retargeting helps a lot with testing, where we can stub interactions with an external system without 3rd party libraries nor reflection magic.
  25. Now the question is, how do you use it? You can create your Free Monad with these easy 5 steps listed in the slide. So let’s do one, so we can see how it works. (see https://typelevel.org/cats/datatypes/freemonad.html)
  26. We will use the standard example used for Free monads, a key-value store. The first step is to define an algebra for our operations. We define our operations (put, get, delete) as data (case classes). We represent computations as data. Note the trait KVA (our algebra) has a ‘hole’ to look like a Functor, so we can use the magic Coyoneda trick we mentioned and obtain a Functor from it.
  27. The second step is to define our DSL to build applications using our algebra. This is done by lifting our KVA algebra into a Free structure, in a single line. The remaining methods are helpers for our DSL, so it is nicer to use: for example, we will call ‘put’ instead of creating the instance of case class Put[T] in the code
  28. Now that we have the DSL, we can use it to create a program. Note that this is a for-comprehension (requires a Monad, which we lifted our Algebra to) Also note that this code, by itself, does nothing. It just stacks case classes in a sequence of nested flatMaps. That is all. As we said, we are separating declaration of intent from execution
  29. We want that program to do something, so we need an interpreter (or compiler). These are implemented as Natural transformations (the ~>) which are functions that convert from one monad to another. This example maps to the Id monad, but we could map to IO for example As you can see we are pattern matching over the ADT of our algebra. We could apply nice optimisations here, like preprocessing all input and removing redundant Puts (ones with same key and value) or other changes. I mention this one as there is a talk from Luka from Typelevel (see https://typelevel.org/blog/2017/12/27/optimizing-final-tagless.html) where he shows something similar, and it seems to be a common example on capabilities of Free
  30. The last step is to use the interpreter to execute the program we wrote. If we executed this we would execute the operations you see in screen and return Some(14). Execution is basically a `foldMap` using our natural transformation, which means we iterate over the flatMaps of our program and we map each instance of our algebra via the natural transformation we defined before. OK, so this works, but that was a lot of code, a big chunk of boilerplate code. And it get worse if you want to use multiple algebras in your programs, which is what you usually want to do. You can see Free feels a bit cumbersome.
  31. There's been efforts to reduce this boilerplate. For example, FreeStyle (http://frees.io) from 47 Degrees which generates a lot of that boilerplate for you. Unfortunately the last release was on 7th Jun 2018, there’s been low activity in the repo since then, and 47 deg seems focussed on Kotlin, so we can consider it in maintenance mode
  32. As you can expect with Free being mentioned in this talk, after a long while of blog posts, demos, and conference talks, the bad points were pointed out. Kelley Robinson had a talk named ‘Why the Free Monad isn’t Free’ (link in the notes, I’ll share it later) and it summarised some of the negatives of Free. Boilerplate, specially when you are using multiple algebras in your programs. Performance, given you are lifting data types to operations again and again, inside a nested flatMap structure. Stack safe, but slow. And the concepts needed to use it. Yes, you can use it without knowing them all, but you will soon hit a ceiling when the compiler throws some errors at your face. We said we are trying to find "idiomatic patterns when we organise our code, so that other developers in our team can identify and work with”. Steep learning curve defeats the purpose. (see https://www.slideshare.net/KelleyRobinson1/why-the-free-monad-isnt-free-61836547)
  33. All that, the fact the community started pointing the flaws in Free, plus the fact that FreeStyle entered something like maintenance mode last year seems to point that the hype on Free is over. We were shown something new, we were bombarded with blog posts by community leaders, we adopted it, and we discovered it wasn’t a silver bullet. Free Monad is dead, long live Free?
  34. No. Free doesn’t suck. Free is a perfectly useful technique which probably you are using without knowing. How many of you use Slick, or Doobie? They are Free Monads behinds the scenes. Free is useful, but, again, is not a silver bullet and hype won’t make it one. It has its own niche where it excels, but it also has weaknesses.
  35. Let's move forward again, to 2018. 2 years since Free was in the spotlight, we were ready for more hype. The year of Tagless final and MTL style. Yes, you killed a 1 year old baby.
  36. Well, not really 1 year. In 2012 a paper was published: Typed Tagless Final Interpreters (see http://okmij.org/ftp/tagless-final/course/lecture.pdf) along a corresponding course. ``Tagless-final'' style is a general method of embedding domain-specific languages (DSL) in a typed functional language, an alternative to using ADT for this purpose (that is, an alternative to Free Monad). And the Haskell community loved it. And, as it happens, what was loved in Haskell found its way into Scala, as it seemed a better way to organise code than Free. Mind you, both Tagless final and Free Monad are equivalent on expressive power. But, as we will see (and you probably know) Tagless has some advantages By the way, the link at the bottom is not to the course itself but a Scala version Debasish created based on the original one. In case you want to go to the source of all this. (see http://okmij.org/ftp/tagless-final/index.html and https://github.com/debasishg/typed-tagless-final for scala version)
  37. So how does Tagless final work? How does it differ from Free? In Tagless programs are expressions, functions, instead of an ADT In Tagless the operations are executed over a Monad of your choice (IO, Task, etc) instead of having a series of natural transformations Note that in Tagless execution is still separate from program declaration. There is less overhead as you are not operating over values that you pattern match, but executing functions directly.
  38. So, as we did with Free, how do we use Tagless? You just follow these 4 steps. Wait, 4, there are 5 bullet points? Yes, they are the same as with free, but #2 is suddenly ‘Free’ as algebra and DSL are the same, no lifting needed. So, right out of the bat, less work to do :)
  39. We will implement the same logic as before to see the differences with Free more clearly. With Free we defined an ADT for our algebra, which we lifted to more user-friendly operations in step 2. Here we have a single trait with the operations defined. In Free we used an ADT with ‘a hole’ to take advantage of the Coyoneda trick, in here F represents the Monad we will use to execute
  40. We define our program. This is very similar to how we defined our program for Free. But in here we need to pass the algebra as a parameter (alg) and let Scala know that F is a Monad so we can flatMap over the values. The rest is almost identical.
  41. We want that program to do something, so we need an interpreter, as in Free. In Tagless though an interpreter is just a particular implementation of our trait. As seen in the slide. No natural transformation in play, we just execute the operations, only knowing that F is a Monad.
  42. The last step is to use the interpreter to execute the program we wrote. If we executed this we would execute the operations you see in screen and return Some(14). Execution means passing our interpreter (instance of the class that implement the trait) to the program, and selecting a target monad (IO) for execution. OK, so this works, and it was much less code than Free. It has its limitations, like the fact stack safety depends on the monad you use. But using multiple algebras is much simpler than with Free as we have removed all the boilerplate for lifting algebras. In Tagless it is as seamless as when Java coders program against the interface, just pass the definitions of your algebras around and use them. A lower learning curve, which means we are getting closer to the aim of having some patterns for our code structure which are useful and other developers can easily identify and work with. Which is why we tried Free on the first place.
  43. That said, we talked about Tagless, wherea is that MTL part we mentioned at the start? Remember? MTL (monad transformer layer) is the historical name of a concept in Haskell (where else?) that has evolved to now mean 'a final tagless encoding of common effects like state, reading from an environment, and so on.’ Just like Functor abstracts over ‘things that can be mapped’, MTL provides typeclasses abstracting over many useful patterns involving different sorts of “effects”, like ‘reading configuration’. I’d recommend you to watch this talk by Pawel as it provides a very good explanation on the concepts behind it. (see Pawel Szulc - A road trip with Monads: https://www.youtube.com/watch?v=y_QHSDOVJM8 )
  44. In practice, this means that code like the one in this slide which uses stacks of monads can be improved by using MTL. Monad stacks are troublesome for many reasons. The most important one is that some monads can’t compose, which causes a mine field when stacking them, to ensure it’s all proper and lawful. Another issue is code legibility, but you could fix that with some helper functions, just means more boilerplate. Another criticism is performance (each flatMap operation has to unwrap and rewrap the stack). That said, performance arguably is the less relevant issue for most of the code we write, where the slowest component is by far network or data storage. It’s generally cumbersome to use them, at least in Scala, that is why there’s been active effort to replace them.
  45. MTL allows us to write instead this code, in which we replace the monad stack by constraints on our effect F. The functionality is equivalent, but with clearer and more performant code.
  46. Tagless final is very popular. The code above belong to one of the examples of Http4s, a Scala web server in the Typelevel ecosystem. The documentation of many libraries guide you towards working in this way. It’s more user friendly for junior developers than Free. No wonder it got popular. If we want a pattern to structure programs, that is a good one.
  47. Does this mean Tagless has killed Free? No. We already discussed as Free is used in Doobie, for example. In Doobie we take advantage of the fact that programs are values to combine multiple ConnectionIO until we decide to execute them all at once in a single transaction at the end. This would be harder to implement with Tagless (possible as they are equivalent, but probably less convenient for the library author). Tagless is easier to implement, with less boilerplate. Being so convenient it is a great choice for mapping higher level business concepts, in areas where we want to combine multiple algebras easily to define the business rules. With free doing that is painful, but Tagless, it is trivial. That’s why libraries like Http4s, which you’d use as underlying library to implement your business rules onto, use Tagless Final in their examples and not Free. There is no silver bullet. Each technique has its niche.
  48. During all the previous slides we were still in 2018, following the 'pattern of the year'. But John decided 2019 needed a new concept. Tagless was boring after being talked so much about, so he killed it.
  49. Now, I'll be honest: I've not had time to play with ZIO and John's examples since release. It’s been too recent and fiscal year in UK finishes at the end of March (plus Brexit, d’oh). The consequence is that I can’t have an opinion on ZIO, because I’ve not been able to use it as to build one. I understand that ZIO looks interesting as initially it feels like a mechanism to reduce some boilerplate even more. We go from the code above, using Tagless…
  50. … to this code. The program code is much simpler, easier to read. Granted, we are cheating a bit by using some helper methods defined in a package object, like when we lifted our DSL in step 2 in Free, but this step is easier than in Free. It may still be a worthy trade vs Tagless. As I said I didn’t have time to build anything with it, but we can try to follow the 5 step pattern I did before with the code John published in his blog post. Note this may not be 100% correct due to lack of experience with it.
  51. Using John’s example of writing to Console, our algebra would be this one, a service to interact with the Console with 2 methods: println and readLine. I put the code as John shows it in the blog post, thus the nesting in the object. Not trying to make it look more complex by nesting it, it’s a direct copy paste :)
  52. The code itself doesn’t need any lifting, but John explains there is an optional step to make the service easier to use, defining some helper methods. This looks to me similar to step #2 when we use Free, in which we create helper methods to avoid using the ADT algebra directly. Granted, they are much more necessary in Free, but if we count boilerplate this may be equivalent as you will probably end up creating these methods to have cleaner code.
  53. Now that we have the DSL, we can use it to create a program. We use the helper methods to define a program that interact with the console.
  54. Step 4 is to write an interpreter. In the example John writes the interpreter inside the companion object of Console, so I copy the code as is. I would expect this is just a preference, but I am not sure.
  55. The last step is to use the interpreter to execute the program we wrote. This returns a IO monad we can then run, as we get with Tagless Final implementation. From this small experiment, it seems we may need to write some more boilerplate than with Tagless Final (step 2), but that is not mandatory. They feel quite equivalent, and not having to pass F[_] across the algebra may really be a win.
  56. That said, I was reading both of John’s blog posts on ZIO to get some opinion on it, and something caught my eye. This code is from the blog John wrote. Rings a bell? It should. A hint, remember when I said at the start of the talk that I’d like you to put a bookmark on a section of the talk? Yes, it was about this. The stack in ProgramEnv is pretty darn similar to the Cake Pattern. (see http://degoes.net/articles/zio-environment and http://degoes.net/articles/testable-zio) something caught my eye.
  57. And it seems I am not the only one to see it this way. Adam Warski of Software Mill fame also mentioned this in his last blog post. We may have come full circle, Tagless died at the hands of the Cake Pattern. Jon Pretty was right all along.
  58. Don't take me wrong, I'm not saying ZIO is bad, as at the very least ZIO is making people rethink Tagless and the limitations it may have, and how to improve on it. Adam Warski in his excellent post has pointed how ZIO is great for detailed effect tracking, while Tagless Final is great at constraining effect wrappers. Each one is a choice with consequences. For example, as people have pointed out, Using only ZIO types you can not restrict ZIO capabilities. Every method has access to everything, be it concurrency, configuration, etc. On the other hand, ZIO provides capabilities Tagless doesn’t. It’s a trade off. (see https://blog.softwaremill.com/final-tagless-seen-alive-79a8d884691d)
  59. We should stop being driven by hype and looking for silver bullets. John’s talk was released on 25th February 2019. That was Monday, 2 weeks ago (today is 14th March 2019). His tweets about the subject raised a wave of excited developers proclaiming this was a revolution and we should all use it right now. We want to use idiomatic patterns when we organise our code, so that other developers in our team can identify and work with. But, as history has shown (hello Cake Pattern) it may take a while for us to realise the downsides of an approach. We should slow down a bit and devote some time to use this before forming strong opinions. If you have an opinion on Tagless after hundreds of hours of use, maybe you need at least some tens of hours of use of ZIO to understand where it works and where it doesn’t
  60. So, to finish this
  61. If we want to kill something, we should be killing hype and our silver bullet obsession. ZIO may be an amazing library which will change the way we structure applications. And the rotating environment may become a de facto way of coding in Scala. Or maybe (most likely) it will find a niche in which it excels, like Free has done with lower level libraries, or Tagless for domain modelling. And outside of which we won't use it. There is no need to fall onto the hype and rewrite your code base. It's a tool. A new one. Probably a great one. Experiment with it, learn about it, and decide if it fits your needs. Use ZIO as much as you want. But don't dismiss tagless final. Or Free. Don’t limit yourself and stop using them just because ZIO exists. Or because I say so. There is no silver bullet, each tool has a place.
  62. And I’m done, but before I finish, usually people in here they say they are hiring. I am not as I am a freelancer, but we have a team of experienced contractors in UK, some of which you may know. If your company wants expert developers and is open to remote work, contact me and I’ll put you in touch :)
  63. And, now we are done.