SlideShare a Scribd company logo
Building a Tagless Final DSL for WebGL
Luka Jacobowitz
Motivation
● We often have to interface with some super imperative
libraries.
● Hard to find anything more imperative than graphics
programming.
● How can we give these libraries a nice and clean functional
API?
Solution #1 Wrap all the things in IO
for {
canvas <- IO(dom.createElement("canvas"))
gl <- IO(canvas.getContext("webgl"))
_ <- IO(gl.clearColor(0,0,0,1))
_ <- IO(println("Initialized GL"))
} yield ()
Solution #1 Wrap all the things in IO
● Breaks separation of concerns
● Really difficult to test
● Hard to keep track of the level of abstraction
It’d be cool if we could use a functional
DSL to access the imperative libraries
Digression: What’s the ‘e’ in eDSL?
● DSLs: GLSL, SQL, Shell scripts
● Embedded DSLs: Embedded into another language, builds
up a tree of expressions that “compile” to the target
language
What kind of eDSLs are there?
● AST as (G)ADTs
● Free Monad/Applicative
● Tagless Final
Tagless Final
● Model our Algebras as traits parametrized with a type
constructor
● Programs constrain the type parameter (e.g. with Monad)
● Interpreters are simply implementations of those traits
Tagless Final - Basic example
trait Console[F[_]] {
def printLine(s: String): F[Unit]
def readLine: F[String]
}
def program[F[_]: Monad](C: Console[F]) = for {
_ <- C.printLine("Please enter your name")
name <- C.readLine
_ <- C.printLine(s"You entered $name")
} yield ()
Tagless Final - Basic example
object ConsoleTaskInterpreter extends Console[Task] {
def printLine(s: String): Task[Unit] =
Task(println(s))
def readLine: Task[String] =
Task(StdIn.readLine())
}
program(ConsoleTaskInterpreter).runAsync
Combining Algebras
trait KVStore[F[_]] {
def put[A](key: String, a: A): F[Unit]
def get[A](key: String): F[Option[A]]
}
def program[F[_]: FlatMap](C: Console[F], K: KVStore[F]) = for {
_ <- C.printLine("Please enter your name")
name <- C.readLine
_ <- K.put("name", name)
} yield ()
Language Layers
trait Prompt[F[_]] {
def prompt(msg: String): F[String]
}
class PromptConsoleInterpreter[F[_]: FlatMap](C: Console[F])
extends Prompt[F] {
def prompt(msg: String): F[String] = for {
_ <- C.printLine(msg)
s <- C.readLine
} yield s
}
Let’s check out some code!
Bonus: Parallelism
def program[M[_]: FlatMap, F[_]](K: KVStore[F])(implicit P: Parallel[M, F]) =
for {
_ <- K.put("A", a)
x <- (K.get("B"), K.get("C")).parMapN(f)
} yield x
Other cool things
● While difficult, it’s totally possible to inspect and optimize
our programs
● With the Mainecoon library we can generically compose
and transform our Algebras
● If we need to guarantee stack safety, we can compile our
Algebras to Free and then interpret
Conclusions
● Tagless Final allows us to use our own Algebras for
defining interactions
● These Algebras can be composed and layered
● We can define multiple interpreters, which gives us great
flexibility and the ability to test and refactor
● Our programs are exactly as powerful as we want them to
be
● We can work at an extra level of abstraction but maintain
flexibility
Thank you for listening!
Twitter: @LukaJacobowitz

More Related Content

PDF
Reactive Programming in the Browser feat. Scala.js and PureScript
PDF
Advanced Tagless Final - Saying Farewell to Free
PDF
Halogen: Past, Present, and Future
PDF
The Design of the Scalaz 8 Effect System
PDF
All Aboard The Scala-to-PureScript Express!
PDF
MTL Versus Free
PDF
Post-Free: Life After Free Monads
PDF
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
Reactive Programming in the Browser feat. Scala.js and PureScript
Advanced Tagless Final - Saying Farewell to Free
Halogen: Past, Present, and Future
The Design of the Scalaz 8 Effect System
All Aboard The Scala-to-PureScript Express!
MTL Versus Free
Post-Free: Life After Free Monads
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...

What's hot (20)

PDF
Orthogonal Functional Architecture
PPTX
Functional Programming in Javascript - IL Tech Talks week
PDF
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
PDF
The Death of Final Tagless
PDF
Functional Programming with JavaScript
PDF
Scalaz 8 vs Akka Actors
PDF
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
PDF
First-Class Patterns
PDF
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional Programming
PPTX
Lua Study Share
PDF
Functor, Apply, Applicative And Monad
PDF
The Next Great Functional Programming Language
PDF
"Немного о функциональном программирование в JavaScript" Алексей Коваленко
PDF
Functional Programming Patterns for the Pragmatic Programmer
PDF
ZIO Queue
PDF
Haskell for data science
PDF
Cocoaheads Meetup / Alex Zimin / Swift magic
PDF
GUL UC3M - Introduction to functional programming
PDF
T3chFest 2016 - The polyglot programmer
PDF
Demystifying functional programming with Scala
Orthogonal Functional Architecture
Functional Programming in Javascript - IL Tech Talks week
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
The Death of Final Tagless
Functional Programming with JavaScript
Scalaz 8 vs Akka Actors
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
First-Class Patterns
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional Programming
Lua Study Share
Functor, Apply, Applicative And Monad
The Next Great Functional Programming Language
"Немного о функциональном программирование в JavaScript" Алексей Коваленко
Functional Programming Patterns for the Pragmatic Programmer
ZIO Queue
Haskell for data science
Cocoaheads Meetup / Alex Zimin / Swift magic
GUL UC3M - Introduction to functional programming
T3chFest 2016 - The polyglot programmer
Demystifying functional programming with Scala
Ad

Viewers also liked (7)

PDF
What Referential Transparency can do for you
PDF
Mining Functional Patterns
PDF
Nelson: Rigorous Deployment for a Functional World
PDF
Impact Mapping - strategische Steuerung agiler Entwicklung
PPTX
Flexible Data Representation with Fixpoint Types
PPTX
Analyzing Functional Programs
PDF
Disorder And Tolerance In Distributed Systems At Scale
What Referential Transparency can do for you
Mining Functional Patterns
Nelson: Rigorous Deployment for a Functional World
Impact Mapping - strategische Steuerung agiler Entwicklung
Flexible Data Representation with Fixpoint Types
Analyzing Functional Programs
Disorder And Tolerance In Distributed Systems At Scale
Ad

Similar to Building a Tagless Final DSL for WebGL (20)

PDF
The best of AltJava is Xtend
PDF
TI1220 Lecture 14: Domain-Specific Languages
PDF
Introduction to Scalding and Monoids
PDF
SE 20016 - programming languages landscape.
PPTX
Mercury: A Functional Review
PDF
Software Language Design & Engineering: Mobl & Spoofax
PDF
Tml for Objective C
PDF
(1) c sharp introduction_basics_dot_net
PDF
Linguistic Abstraction for the Web
PDF
Coding in GO - GDG SL - NSBM
PDF
Kotlin Developer Starter in Android projects
PDF
Kotlin Developer Starter in Android - STX Next Lightning Talks - Feb 12, 2016
PPT
Introduction to c_sharp
PPTX
PPTX
PERTEMUAN 1 - MENGENAL ENVIRONTMENT PROGRAM VISUAL C#.pptx
PDF
Software Language Design & Engineering
PPTX
Microsoft 2014 Dev Plataform - Roslyn -& ASP.NET vNext
KEY
Remix Your Language Tooling (JSConf.eu 2012)
PPT
Smoothing Your Java with DSLs
PDF
Scala is java8.next()
The best of AltJava is Xtend
TI1220 Lecture 14: Domain-Specific Languages
Introduction to Scalding and Monoids
SE 20016 - programming languages landscape.
Mercury: A Functional Review
Software Language Design & Engineering: Mobl & Spoofax
Tml for Objective C
(1) c sharp introduction_basics_dot_net
Linguistic Abstraction for the Web
Coding in GO - GDG SL - NSBM
Kotlin Developer Starter in Android projects
Kotlin Developer Starter in Android - STX Next Lightning Talks - Feb 12, 2016
Introduction to c_sharp
PERTEMUAN 1 - MENGENAL ENVIRONTMENT PROGRAM VISUAL C#.pptx
Software Language Design & Engineering
Microsoft 2014 Dev Plataform - Roslyn -& ASP.NET vNext
Remix Your Language Tooling (JSConf.eu 2012)
Smoothing Your Java with DSLs
Scala is java8.next()

More from Luka Jacobowitz (10)

PDF
Monoids, Monoids, Monoids - ScalaLove 2020
PDF
Monoids, monoids, monoids
PDF
Testing in the World of Functional Programming
PDF
Up and Running with the Typelevel Stack
PDF
Principled Error Handling - Scalapeño
PDF
Principled Error Handling with FP
PDF
Oh, All the things you'll traverse
PDF
Traversals for all ocasions
PDF
Scala UA 2017
PDF
Reactive Programming in the Browser feat. Scala.js and Rx
Monoids, Monoids, Monoids - ScalaLove 2020
Monoids, monoids, monoids
Testing in the World of Functional Programming
Up and Running with the Typelevel Stack
Principled Error Handling - Scalapeño
Principled Error Handling with FP
Oh, All the things you'll traverse
Traversals for all ocasions
Scala UA 2017
Reactive Programming in the Browser feat. Scala.js and Rx

Recently uploaded (20)

PDF
Encapsulation_ Review paper, used for researhc scholars
PPTX
Group 1 Presentation -Planning and Decision Making .pptx
PDF
Approach and Philosophy of On baking technology
PDF
Accuracy of neural networks in brain wave diagnosis of schizophrenia
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
A comparative analysis of optical character recognition models for extracting...
PDF
Machine learning based COVID-19 study performance prediction
PDF
Assigned Numbers - 2025 - Bluetooth® Document
PPTX
1. Introduction to Computer Programming.pptx
PDF
Mushroom cultivation and it's methods.pdf
PPTX
A Presentation on Artificial Intelligence
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
Univ-Connecticut-ChatGPT-Presentaion.pdf
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
A comparative study of natural language inference in Swahili using monolingua...
PDF
NewMind AI Weekly Chronicles - August'25-Week II
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
Encapsulation_ Review paper, used for researhc scholars
Group 1 Presentation -Planning and Decision Making .pptx
Approach and Philosophy of On baking technology
Accuracy of neural networks in brain wave diagnosis of schizophrenia
Unlocking AI with Model Context Protocol (MCP)
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
A comparative analysis of optical character recognition models for extracting...
Machine learning based COVID-19 study performance prediction
Assigned Numbers - 2025 - Bluetooth® Document
1. Introduction to Computer Programming.pptx
Mushroom cultivation and it's methods.pdf
A Presentation on Artificial Intelligence
Digital-Transformation-Roadmap-for-Companies.pptx
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Univ-Connecticut-ChatGPT-Presentaion.pdf
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Per capita expenditure prediction using model stacking based on satellite ima...
A comparative study of natural language inference in Swahili using monolingua...
NewMind AI Weekly Chronicles - August'25-Week II
Building Integrated photovoltaic BIPV_UPV.pdf

Building a Tagless Final DSL for WebGL

  • 1. Building a Tagless Final DSL for WebGL Luka Jacobowitz
  • 2. Motivation ● We often have to interface with some super imperative libraries. ● Hard to find anything more imperative than graphics programming. ● How can we give these libraries a nice and clean functional API?
  • 3. Solution #1 Wrap all the things in IO for { canvas <- IO(dom.createElement("canvas")) gl <- IO(canvas.getContext("webgl")) _ <- IO(gl.clearColor(0,0,0,1)) _ <- IO(println("Initialized GL")) } yield ()
  • 4. Solution #1 Wrap all the things in IO ● Breaks separation of concerns ● Really difficult to test ● Hard to keep track of the level of abstraction
  • 5. It’d be cool if we could use a functional DSL to access the imperative libraries
  • 6. Digression: What’s the ‘e’ in eDSL? ● DSLs: GLSL, SQL, Shell scripts ● Embedded DSLs: Embedded into another language, builds up a tree of expressions that “compile” to the target language
  • 7. What kind of eDSLs are there? ● AST as (G)ADTs ● Free Monad/Applicative ● Tagless Final
  • 8. Tagless Final ● Model our Algebras as traits parametrized with a type constructor ● Programs constrain the type parameter (e.g. with Monad) ● Interpreters are simply implementations of those traits
  • 9. Tagless Final - Basic example trait Console[F[_]] { def printLine(s: String): F[Unit] def readLine: F[String] } def program[F[_]: Monad](C: Console[F]) = for { _ <- C.printLine("Please enter your name") name <- C.readLine _ <- C.printLine(s"You entered $name") } yield ()
  • 10. Tagless Final - Basic example object ConsoleTaskInterpreter extends Console[Task] { def printLine(s: String): Task[Unit] = Task(println(s)) def readLine: Task[String] = Task(StdIn.readLine()) } program(ConsoleTaskInterpreter).runAsync
  • 11. Combining Algebras trait KVStore[F[_]] { def put[A](key: String, a: A): F[Unit] def get[A](key: String): F[Option[A]] } def program[F[_]: FlatMap](C: Console[F], K: KVStore[F]) = for { _ <- C.printLine("Please enter your name") name <- C.readLine _ <- K.put("name", name) } yield ()
  • 12. Language Layers trait Prompt[F[_]] { def prompt(msg: String): F[String] } class PromptConsoleInterpreter[F[_]: FlatMap](C: Console[F]) extends Prompt[F] { def prompt(msg: String): F[String] = for { _ <- C.printLine(msg) s <- C.readLine } yield s }
  • 13. Let’s check out some code!
  • 14. Bonus: Parallelism def program[M[_]: FlatMap, F[_]](K: KVStore[F])(implicit P: Parallel[M, F]) = for { _ <- K.put("A", a) x <- (K.get("B"), K.get("C")).parMapN(f) } yield x
  • 15. Other cool things ● While difficult, it’s totally possible to inspect and optimize our programs ● With the Mainecoon library we can generically compose and transform our Algebras ● If we need to guarantee stack safety, we can compile our Algebras to Free and then interpret
  • 16. Conclusions ● Tagless Final allows us to use our own Algebras for defining interactions ● These Algebras can be composed and layered ● We can define multiple interpreters, which gives us great flexibility and the ability to test and refactor ● Our programs are exactly as powerful as we want them to be ● We can work at an extra level of abstraction but maintain flexibility
  • 17. Thank you for listening! Twitter: @LukaJacobowitz