SlideShare une entreprise Scribd logo
1  sur  30
Télécharger pour lire hors ligne
Advanced Tagless Final -
Saying farewell to Free
Luka Jacobowitz • flatMap(Oslo)
Software Developer at
codecentric
Co-organizer of ScalaDus
and IdrisDus
Maintainer of cats,
cats-effect, cats-mtl,
OutWatch
Enthusiastic about FP
About me
Overview
● Motivation (Free vs
Tagless Final)
● Program optimization
● Interpreter
transformations
● Stack-safety
● Conclusions
Motivation
● Tagless Final is cool
● Certain problems are still very hard to solve
while staying within the constraints of the
interpreter pattern
● Learn about new libraries to help with these
problems
● Have fun along the way!
Free vs. Tagless
Free vs. Tagless (For interpreter pattern)
Advantage Free
● Free Applicative allows us
to inspect the inner
structure of programs and
optimize
● Stack safe by default
Advantage Tagless Final
● Almost no boilerplate
● Much more performant
● Not married to the
Monad/Applicative
constraint
Program optimization
“Optimization in general requires peek ahead which
requires data structures”
With Free we have a data structure, how could it
possibly work for Tagless Final?
Program optimization
Solution:
Interpret it twice!
With a little help from sphynx!
Program optimization - example
trait KVStore[F[_]] {
def get(key: String): F[Option[String]]
def put(key: String, a: String): F[Unit]
}
def program[F[_]: Applicative](gets: List[String])
(puts: List[(String, String)])
(F: KVStore[F]): F[List[String]] =
puts.traverse(t => F.put(t._1, t._2))
*> gets.traverse(F.get).map(_.flatten)
Program optimization - example
What are some potential optimizations for this
program?
● Run actions in parallel
● Remove duplicates
● Put and then Get with same key should not perform
a Get action
First step: Extracting information from our program
We pre-interpret our program to get the information
we need to optimize
● To do so, we need an Applicative F[_]
● We can “lift” any Monoid into an Applicative
using Const.
● Our pre-interpreter should be of type
KVStore[Const[M, ?]]
Extraction
case class KVStoreInfo(gets: Set[String], puts: Map[String, String])
val extractor = new KVStore[Const[KVStoreInfo, ?]] {
def get(key: String): Const[KVStoreInfo, Option[String]] =
Const(KVStoreInfo(Set(key), Map.empty))
def put(key: String, v: String): Const[KVStoreInfo, Unit] =
Const(KVStoreInfo(Set.empty, Map(key -> v)))
}
val extracted: KVStoreInfo = program(gs, ps)(extractor).getConst
Next step: Defining a new interpreter using our new info
Now that we have the information we desire, we can
use it to define an optimized interpreter
● We could precompute values and store them
● That way our interpreter only has to look up the
values
● Since this will be effectful, it will be of type
IO[KVStore[IO]] meaning an IO that will compute a
new IO-interpreter for KVStore
Optimizing
val optimizedInterp = info.gets.filterNot(info.puts.contains)
.parTraverse(key => interp.get(key).map(_.map(s => (key, s))))
.map { list: List[Option[(String, String)]] =>
val table: Map[String, String] = list.flatten.toMap
new KVStore[IO] {
def get(key: String): IO[Option[String]] =
table.get(key).orElse(info.puts.get(key)) match {
case Some(a) => Option(a).pure[IO]
case None => interp.get(key)
}
def put(key: String, v: String): IO[Unit] = interp.put(key, v)
}
}
Let’s put it all together
val interp: KVStore[IO] = ???
val gets = List("Dog", "Bird", "Mouse", "Bird")
val puts = List("Cat" -> "Cat!", "Dog" -> "Dog!")
val info: KVStoreInfo = program(gets, puts)(extractor).getConst
val result: IO[List[String]] = program(gets, puts)(optimizedInterp)
val naiveResult: IO[List[String]] = program(gets, puts)(interp)
Result: initial naive interpreter
naiveResult.unsafeRunSync()
// Hit Network for: Put Cat -> Cat!
// Hit Network for: Put Dog -> Dog!
// Hit Network for: Get Dog
// Hit Network for: Get Bird
// Hit Network for: Get Mouse
// Hit Network for: Get Bird
Result: optimized interpreter
result.unsafeRunSync()
// Hit Network for: Get Bird
// Hit Network for: Get Mouse
// Hit Network for: Put Cat -> Cat!
// Hit Network for: Put Dog -> Dog!
Can we do better?
More precisely, can we generalize this?
Yes!
The Sphynx Optimizer
trait Optimizer[Alg[_[_]], F[_]: Monad] {
type M: Monoid
def extract: Alg[Const[M, ?]]
def rebuild(m: M, interpreter: Alg[F]): F[Alg[F]]
def optimize[A](p: Alg[F] => F[A]): Alg[F] => F[A] =
{ (interpreter: Alg[F]) =>
val m: M = p(extract).getConst
rebuild(m, interpreter).flatMap(interp => p(interp))
}
}
Lifting into a larger context
import sphynx.Optimizer
import sphynx.syntax._
def monadicProgram[F[_]: Monad](F: KVStore[F])
(implicit O: Optimizer[KVStore, F]): F[Unit] = for {
cat <- F.get("Cat")
list <- program(cat.toList, List.empty).optimize(F)
_ <- F.put("Birds", list.headOption.getOrElse("Finch"))
} yield ()
More cool sphynx features
● StaticOptimizer
● SemigroupalOptimizer
Interpreter transformations
Interpreter transformation
Given an algebra of the form Alg[_[_]] and appropriate
interpreter will have the form Alg[F] where F is the type
we’re interpreting into.
How can we turn an Alg[F] into an Alg[G]?
FunctorK!
Mainecoon - FunctorK
trait FunctorK[A[_[_]] {
def mapK[F[_], G[_]](a: A[F])(n: F ~> G): A[G]
}
@autoFunctorK
trait KVStore[F[_]] {
def get(key: String): F[Option[String]]
def put(key: String, a: String): F[Unit]
}
Mainecoon - FunctorK
val toTask: IO ~> Task = λ[IO ~> Task](_.to[Task])
val taskInterp: KVStore[Task] =
KVStore[IO].mapK(toTask)
Stack safety
Tagless final programs are only stack safe when their target
monad is stack safe.
Free Monads on the other hand guarantee this to be the case.
Solution?
Interpret program into Free
Made super easy with Mainecoon!
Mainecoon - Stack safety
def toFree[F[_]]: F ~> Free[F, ?] =
λ[F ~> Free[F, ?]](t => Free.liftF(t))
program(tryInterp.mapK(toFree))
.foldMap(FunctionK.id)
More cool Mainecoon features
● InvariantK, ContravariantK
● CartesianK (SemigroupalK)
Conclusions
Tagless final is great for separating problem description
from problem solution.
With these additional approaches we can keep this layer of
abstraction, while sacrificing none of the performance or
stack safety.
Scala as a language isn’t quite there yet to make full use
of some of these advanced techniques, but we can find
workarounds.
Thank you for
listening!
Twitter: @LukaJacobowitz
GitHub: LukaJCB

Contenu connexe

Tendances

Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018John De Goes
 
Functor, Apply, Applicative And Monad
Functor, Apply, Applicative And MonadFunctor, Apply, Applicative And Monad
Functor, Apply, Applicative And MonadOliver Daff
 
Post-Free: Life After Free Monads
Post-Free: Life After Free MonadsPost-Free: Life After Free Monads
Post-Free: Life After Free MonadsJohn De Goes
 
One Monad to Rule Them All
One Monad to Rule Them AllOne Monad to Rule Them All
One Monad to Rule Them AllJohn De Goes
 
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsQuark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsJohn De Goes
 
The Next Great Functional Programming Language
The Next Great Functional Programming LanguageThe Next Great Functional Programming Language
The Next Great Functional Programming LanguageJohn De Goes
 
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional Programming
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional ProgrammingZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional Programming
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional ProgrammingJohn De Goes
 
Halogen: Past, Present, and Future
Halogen: Past, Present, and FutureHalogen: Past, Present, and Future
Halogen: Past, Present, and FutureJohn De Goes
 
Refactoring Functional Type Classes
Refactoring Functional Type ClassesRefactoring Functional Type Classes
Refactoring Functional Type ClassesJohn De Goes
 
First-Class Patterns
First-Class PatternsFirst-Class Patterns
First-Class PatternsJohn De Goes
 
Why The Free Monad isn't Free
Why The Free Monad isn't FreeWhy The Free Monad isn't Free
Why The Free Monad isn't FreeKelley Robinson
 
Scalaz 8: A Whole New Game
Scalaz 8: A Whole New GameScalaz 8: A Whole New Game
Scalaz 8: A Whole New GameJohn De Goes
 
7 Habits For a More Functional Swift
7 Habits For a More Functional Swift7 Habits For a More Functional Swift
7 Habits For a More Functional SwiftJason Larsen
 
Hive function-cheat-sheet
Hive function-cheat-sheetHive function-cheat-sheet
Hive function-cheat-sheetDr. Volkan OBAN
 
Scalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with ScalaScalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with ScalaDaniel Sebban
 
GUL UC3M - Introduction to functional programming
GUL UC3M - Introduction to functional programmingGUL UC3M - Introduction to functional programming
GUL UC3M - Introduction to functional programmingDavid Muñoz Díaz
 
Functional Programming in Swift
Functional Programming in SwiftFunctional Programming in Swift
Functional Programming in SwiftSaugat Gautam
 
Side by Side - Scala and Java Adaptations of Martin Fowler’s Javascript Refac...
Side by Side - Scala and Java Adaptations of Martin Fowler’s Javascript Refac...Side by Side - Scala and Java Adaptations of Martin Fowler’s Javascript Refac...
Side by Side - Scala and Java Adaptations of Martin Fowler’s Javascript Refac...Philip Schwarz
 

Tendances (20)

Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
 
Functor, Apply, Applicative And Monad
Functor, Apply, Applicative And MonadFunctor, Apply, Applicative And Monad
Functor, Apply, Applicative And Monad
 
Post-Free: Life After Free Monads
Post-Free: Life After Free MonadsPost-Free: Life After Free Monads
Post-Free: Life After Free Monads
 
MTL Versus Free
MTL Versus FreeMTL Versus Free
MTL Versus Free
 
One Monad to Rule Them All
One Monad to Rule Them AllOne Monad to Rule Them All
One Monad to Rule Them All
 
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsQuark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
 
The Next Great Functional Programming Language
The Next Great Functional Programming LanguageThe Next Great Functional Programming Language
The Next Great Functional Programming Language
 
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional Programming
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional ProgrammingZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional Programming
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional Programming
 
Map, Reduce and Filter in Swift
Map, Reduce and Filter in SwiftMap, Reduce and Filter in Swift
Map, Reduce and Filter in Swift
 
Halogen: Past, Present, and Future
Halogen: Past, Present, and FutureHalogen: Past, Present, and Future
Halogen: Past, Present, and Future
 
Refactoring Functional Type Classes
Refactoring Functional Type ClassesRefactoring Functional Type Classes
Refactoring Functional Type Classes
 
First-Class Patterns
First-Class PatternsFirst-Class Patterns
First-Class Patterns
 
Why The Free Monad isn't Free
Why The Free Monad isn't FreeWhy The Free Monad isn't Free
Why The Free Monad isn't Free
 
Scalaz 8: A Whole New Game
Scalaz 8: A Whole New GameScalaz 8: A Whole New Game
Scalaz 8: A Whole New Game
 
7 Habits For a More Functional Swift
7 Habits For a More Functional Swift7 Habits For a More Functional Swift
7 Habits For a More Functional Swift
 
Hive function-cheat-sheet
Hive function-cheat-sheetHive function-cheat-sheet
Hive function-cheat-sheet
 
Scalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with ScalaScalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with Scala
 
GUL UC3M - Introduction to functional programming
GUL UC3M - Introduction to functional programmingGUL UC3M - Introduction to functional programming
GUL UC3M - Introduction to functional programming
 
Functional Programming in Swift
Functional Programming in SwiftFunctional Programming in Swift
Functional Programming in Swift
 
Side by Side - Scala and Java Adaptations of Martin Fowler’s Javascript Refac...
Side by Side - Scala and Java Adaptations of Martin Fowler’s Javascript Refac...Side by Side - Scala and Java Adaptations of Martin Fowler’s Javascript Refac...
Side by Side - Scala and Java Adaptations of Martin Fowler’s Javascript Refac...
 

Similaire à Advanced Tagless Final - Saying Farewell to Free

Composing an App with Free Monads (using Cats)
Composing an App with Free Monads (using Cats)Composing an App with Free Monads (using Cats)
Composing an App with Free Monads (using Cats)Hermann Hueck
 
Advance Scala - Oleg Mürk
Advance Scala - Oleg MürkAdvance Scala - Oleg Mürk
Advance Scala - Oleg MürkPlanet OS
 
Behm Shah Pagerank
Behm Shah PagerankBehm Shah Pagerank
Behm Shah Pagerankgothicane
 
Talk - Query monad
Talk - Query monad Talk - Query monad
Talk - Query monad Fabernovel
 
PyData NYC 2019
PyData NYC 2019PyData NYC 2019
PyData NYC 2019Li Jin
 
Functional Programming In Java
Functional Programming In JavaFunctional Programming In Java
Functional Programming In JavaAndrei Solntsev
 
Writing DSL with Applicative Functors
Writing DSL with Applicative FunctorsWriting DSL with Applicative Functors
Writing DSL with Applicative FunctorsDavid Galichet
 
C++ unit-1-part-11
C++ unit-1-part-11C++ unit-1-part-11
C++ unit-1-part-11Jadavsejal
 
Functional Programming Patterns for the Pragmatic Programmer
Functional Programming Patterns for the Pragmatic ProgrammerFunctional Programming Patterns for the Pragmatic Programmer
Functional Programming Patterns for the Pragmatic ProgrammerRaúl Raja Martínez
 
Workshop "Can my .NET application use less CPU / RAM?", Yevhen Tatarynov
Workshop "Can my .NET application use less CPU / RAM?", Yevhen TatarynovWorkshop "Can my .NET application use less CPU / RAM?", Yevhen Tatarynov
Workshop "Can my .NET application use less CPU / RAM?", Yevhen TatarynovFwdays
 
Go Programming Language (Golang)
Go Programming Language (Golang)Go Programming Language (Golang)
Go Programming Language (Golang)Ishin Vin
 
Use PEG to Write a Programming Language Parser
Use PEG to Write a Programming Language ParserUse PEG to Write a Programming Language Parser
Use PEG to Write a Programming Language ParserYodalee
 
Golang basics for Java developers - Part 1
Golang basics for Java developers - Part 1Golang basics for Java developers - Part 1
Golang basics for Java developers - Part 1Robert Stern
 
Machine learning with py torch
Machine learning with py torchMachine learning with py torch
Machine learning with py torchRiza Fahmi
 
Introduction to Asynchronous scala
Introduction to Asynchronous scalaIntroduction to Asynchronous scala
Introduction to Asynchronous scalaStratio
 

Similaire à Advanced Tagless Final - Saying Farewell to Free (20)

Composing an App with Free Monads (using Cats)
Composing an App with Free Monads (using Cats)Composing an App with Free Monads (using Cats)
Composing an App with Free Monads (using Cats)
 
Advance Scala - Oleg Mürk
Advance Scala - Oleg MürkAdvance Scala - Oleg Mürk
Advance Scala - Oleg Mürk
 
Behm Shah Pagerank
Behm Shah PagerankBehm Shah Pagerank
Behm Shah Pagerank
 
Talk - Query monad
Talk - Query monad Talk - Query monad
Talk - Query monad
 
PyData NYC 2019
PyData NYC 2019PyData NYC 2019
PyData NYC 2019
 
Dafunctor
DafunctorDafunctor
Dafunctor
 
Functional Programming In Java
Functional Programming In JavaFunctional Programming In Java
Functional Programming In Java
 
Writing DSL with Applicative Functors
Writing DSL with Applicative FunctorsWriting DSL with Applicative Functors
Writing DSL with Applicative Functors
 
C++ unit-1-part-11
C++ unit-1-part-11C++ unit-1-part-11
C++ unit-1-part-11
 
Functional Programming Patterns for the Pragmatic Programmer
Functional Programming Patterns for the Pragmatic ProgrammerFunctional Programming Patterns for the Pragmatic Programmer
Functional Programming Patterns for the Pragmatic Programmer
 
Workshop "Can my .NET application use less CPU / RAM?", Yevhen Tatarynov
Workshop "Can my .NET application use less CPU / RAM?", Yevhen TatarynovWorkshop "Can my .NET application use less CPU / RAM?", Yevhen Tatarynov
Workshop "Can my .NET application use less CPU / RAM?", Yevhen Tatarynov
 
Monads in Swift
Monads in SwiftMonads in Swift
Monads in Swift
 
Go Programming Language (Golang)
Go Programming Language (Golang)Go Programming Language (Golang)
Go Programming Language (Golang)
 
Practical cats
Practical catsPractical cats
Practical cats
 
Use PEG to Write a Programming Language Parser
Use PEG to Write a Programming Language ParserUse PEG to Write a Programming Language Parser
Use PEG to Write a Programming Language Parser
 
Golang basics for Java developers - Part 1
Golang basics for Java developers - Part 1Golang basics for Java developers - Part 1
Golang basics for Java developers - Part 1
 
Machine learning with py torch
Machine learning with py torchMachine learning with py torch
Machine learning with py torch
 
Coding in Style
Coding in StyleCoding in Style
Coding in Style
 
Kpi driven-java-development
Kpi driven-java-developmentKpi driven-java-development
Kpi driven-java-development
 
Introduction to Asynchronous scala
Introduction to Asynchronous scalaIntroduction to Asynchronous scala
Introduction to Asynchronous scala
 

Plus de Luka Jacobowitz

Monoids, monoids, monoids
Monoids, monoids, monoidsMonoids, monoids, monoids
Monoids, monoids, monoidsLuka Jacobowitz
 
Up and Running with the Typelevel Stack
Up and Running with the Typelevel StackUp and Running with the Typelevel Stack
Up and Running with the Typelevel StackLuka Jacobowitz
 
Principled Error Handling - Scalapeño
Principled Error Handling - ScalapeñoPrincipled Error Handling - Scalapeño
Principled Error Handling - ScalapeñoLuka Jacobowitz
 
What Referential Transparency can do for you
What Referential Transparency can do for youWhat Referential Transparency can do for you
What Referential Transparency can do for youLuka Jacobowitz
 
Reactive Programming in the Browser feat. Scala.js and Rx
Reactive Programming in the Browser feat. Scala.js and RxReactive Programming in the Browser feat. Scala.js and Rx
Reactive Programming in the Browser feat. Scala.js and RxLuka Jacobowitz
 
Reactive Programming in the Browser feat. Scala.js and PureScript
Reactive Programming in the Browser feat. Scala.js and PureScriptReactive Programming in the Browser feat. Scala.js and PureScript
Reactive Programming in the Browser feat. Scala.js and PureScriptLuka Jacobowitz
 

Plus de Luka Jacobowitz (7)

Monoids, monoids, monoids
Monoids, monoids, monoidsMonoids, monoids, monoids
Monoids, monoids, monoids
 
Up and Running with the Typelevel Stack
Up and Running with the Typelevel StackUp and Running with the Typelevel Stack
Up and Running with the Typelevel Stack
 
Principled Error Handling - Scalapeño
Principled Error Handling - ScalapeñoPrincipled Error Handling - Scalapeño
Principled Error Handling - Scalapeño
 
What Referential Transparency can do for you
What Referential Transparency can do for youWhat Referential Transparency can do for you
What Referential Transparency can do for you
 
Scala UA 2017
Scala UA 2017Scala UA 2017
Scala UA 2017
 
Reactive Programming in the Browser feat. Scala.js and Rx
Reactive Programming in the Browser feat. Scala.js and RxReactive Programming in the Browser feat. Scala.js and Rx
Reactive Programming in the Browser feat. Scala.js and Rx
 
Reactive Programming in the Browser feat. Scala.js and PureScript
Reactive Programming in the Browser feat. Scala.js and PureScriptReactive Programming in the Browser feat. Scala.js and PureScript
Reactive Programming in the Browser feat. Scala.js and PureScript
 

Dernier

The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...Health
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️anilsa9823
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceanilsa9823
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 

Dernier (20)

The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 

Advanced Tagless Final - Saying Farewell to Free

  • 1. Advanced Tagless Final - Saying farewell to Free Luka Jacobowitz • flatMap(Oslo)
  • 2. Software Developer at codecentric Co-organizer of ScalaDus and IdrisDus Maintainer of cats, cats-effect, cats-mtl, OutWatch Enthusiastic about FP About me
  • 3. Overview ● Motivation (Free vs Tagless Final) ● Program optimization ● Interpreter transformations ● Stack-safety ● Conclusions
  • 4. Motivation ● Tagless Final is cool ● Certain problems are still very hard to solve while staying within the constraints of the interpreter pattern ● Learn about new libraries to help with these problems ● Have fun along the way!
  • 6. Free vs. Tagless (For interpreter pattern) Advantage Free ● Free Applicative allows us to inspect the inner structure of programs and optimize ● Stack safe by default Advantage Tagless Final ● Almost no boilerplate ● Much more performant ● Not married to the Monad/Applicative constraint
  • 7. Program optimization “Optimization in general requires peek ahead which requires data structures” With Free we have a data structure, how could it possibly work for Tagless Final?
  • 8. Program optimization Solution: Interpret it twice! With a little help from sphynx!
  • 9. Program optimization - example trait KVStore[F[_]] { def get(key: String): F[Option[String]] def put(key: String, a: String): F[Unit] } def program[F[_]: Applicative](gets: List[String]) (puts: List[(String, String)]) (F: KVStore[F]): F[List[String]] = puts.traverse(t => F.put(t._1, t._2)) *> gets.traverse(F.get).map(_.flatten)
  • 10. Program optimization - example What are some potential optimizations for this program? ● Run actions in parallel ● Remove duplicates ● Put and then Get with same key should not perform a Get action
  • 11. First step: Extracting information from our program We pre-interpret our program to get the information we need to optimize ● To do so, we need an Applicative F[_] ● We can “lift” any Monoid into an Applicative using Const. ● Our pre-interpreter should be of type KVStore[Const[M, ?]]
  • 12. Extraction case class KVStoreInfo(gets: Set[String], puts: Map[String, String]) val extractor = new KVStore[Const[KVStoreInfo, ?]] { def get(key: String): Const[KVStoreInfo, Option[String]] = Const(KVStoreInfo(Set(key), Map.empty)) def put(key: String, v: String): Const[KVStoreInfo, Unit] = Const(KVStoreInfo(Set.empty, Map(key -> v))) } val extracted: KVStoreInfo = program(gs, ps)(extractor).getConst
  • 13. Next step: Defining a new interpreter using our new info Now that we have the information we desire, we can use it to define an optimized interpreter ● We could precompute values and store them ● That way our interpreter only has to look up the values ● Since this will be effectful, it will be of type IO[KVStore[IO]] meaning an IO that will compute a new IO-interpreter for KVStore
  • 14. Optimizing val optimizedInterp = info.gets.filterNot(info.puts.contains) .parTraverse(key => interp.get(key).map(_.map(s => (key, s)))) .map { list: List[Option[(String, String)]] => val table: Map[String, String] = list.flatten.toMap new KVStore[IO] { def get(key: String): IO[Option[String]] = table.get(key).orElse(info.puts.get(key)) match { case Some(a) => Option(a).pure[IO] case None => interp.get(key) } def put(key: String, v: String): IO[Unit] = interp.put(key, v) } }
  • 15. Let’s put it all together val interp: KVStore[IO] = ??? val gets = List("Dog", "Bird", "Mouse", "Bird") val puts = List("Cat" -> "Cat!", "Dog" -> "Dog!") val info: KVStoreInfo = program(gets, puts)(extractor).getConst val result: IO[List[String]] = program(gets, puts)(optimizedInterp) val naiveResult: IO[List[String]] = program(gets, puts)(interp)
  • 16. Result: initial naive interpreter naiveResult.unsafeRunSync() // Hit Network for: Put Cat -> Cat! // Hit Network for: Put Dog -> Dog! // Hit Network for: Get Dog // Hit Network for: Get Bird // Hit Network for: Get Mouse // Hit Network for: Get Bird
  • 17. Result: optimized interpreter result.unsafeRunSync() // Hit Network for: Get Bird // Hit Network for: Get Mouse // Hit Network for: Put Cat -> Cat! // Hit Network for: Put Dog -> Dog!
  • 18. Can we do better? More precisely, can we generalize this? Yes!
  • 19. The Sphynx Optimizer trait Optimizer[Alg[_[_]], F[_]: Monad] { type M: Monoid def extract: Alg[Const[M, ?]] def rebuild(m: M, interpreter: Alg[F]): F[Alg[F]] def optimize[A](p: Alg[F] => F[A]): Alg[F] => F[A] = { (interpreter: Alg[F]) => val m: M = p(extract).getConst rebuild(m, interpreter).flatMap(interp => p(interp)) } }
  • 20. Lifting into a larger context import sphynx.Optimizer import sphynx.syntax._ def monadicProgram[F[_]: Monad](F: KVStore[F]) (implicit O: Optimizer[KVStore, F]): F[Unit] = for { cat <- F.get("Cat") list <- program(cat.toList, List.empty).optimize(F) _ <- F.put("Birds", list.headOption.getOrElse("Finch")) } yield ()
  • 21. More cool sphynx features ● StaticOptimizer ● SemigroupalOptimizer
  • 23. Interpreter transformation Given an algebra of the form Alg[_[_]] and appropriate interpreter will have the form Alg[F] where F is the type we’re interpreting into. How can we turn an Alg[F] into an Alg[G]? FunctorK!
  • 24. Mainecoon - FunctorK trait FunctorK[A[_[_]] { def mapK[F[_], G[_]](a: A[F])(n: F ~> G): A[G] } @autoFunctorK trait KVStore[F[_]] { def get(key: String): F[Option[String]] def put(key: String, a: String): F[Unit] }
  • 25. Mainecoon - FunctorK val toTask: IO ~> Task = λ[IO ~> Task](_.to[Task]) val taskInterp: KVStore[Task] = KVStore[IO].mapK(toTask)
  • 26. Stack safety Tagless final programs are only stack safe when their target monad is stack safe. Free Monads on the other hand guarantee this to be the case. Solution? Interpret program into Free Made super easy with Mainecoon!
  • 27. Mainecoon - Stack safety def toFree[F[_]]: F ~> Free[F, ?] = λ[F ~> Free[F, ?]](t => Free.liftF(t)) program(tryInterp.mapK(toFree)) .foldMap(FunctionK.id)
  • 28. More cool Mainecoon features ● InvariantK, ContravariantK ● CartesianK (SemigroupalK)
  • 29. Conclusions Tagless final is great for separating problem description from problem solution. With these additional approaches we can keep this layer of abstraction, while sacrificing none of the performance or stack safety. Scala as a language isn’t quite there yet to make full use of some of these advanced techniques, but we can find workarounds.
  • 30. Thank you for listening! Twitter: @LukaJacobowitz GitHub: LukaJCB