slick 3.0 functional programming and db side effects
TRANSCRIPT
Slick 3.0: Functional programming with
database side effects(On short notice…)
Joost de Vries twitter: @jouke
email: [email protected] codestar.nl
github: joost-de-vries
๏ Database actions in Slick 3.0
• Actions in FP: side effects
• A lightweight database action implementation
• Database actions in Slick 3.0 revisited
What is Slick
• Slick is originally a Scala framework that offers flatmappable relational queries
• Comparable to Microsofts Linq to Sql
• Blocking, thread based
var xs = array.Where(x => x >= 1); array filter { _ >= 1 }
var xs = array.Select(x => x + 1); array map { _ + 1 }
var yx = array.SelectMany(x => new [] { x, 3 });
array flatMap { Array(_, 3) }
var results = from x in array where x >= 1 select x;
for (x <- array if x >= 1) yield x
LINQ to Sql: SQL as map, flatmap & filter
Slick offers the same paradigm in Scala JOOQ is an alternative to Slick for the JVM
This talk is not about SQL querying using map and flatmap
What’s new in Slick 3.0
• Non blocking
• (Or is it?)
• Source for reactive streams
DBIO[A] (non streaming)
From: Hello Slick 3.0 example project
A DBIO[R] (simplified)
Type hierarchy
Type hierarchy
Reactive streamsThe goal
Reactive streams feature pure functions to process a stream of events
back pressure
“asynchronous computations that allow separating cpu intensive code from IO intensive code”
So we need a way to deal with db side effects in a purely functional
way
FP vs side effects
• Db manipulation is all about side effects
• So how do you deal with side effects in a purely functional programming model?
• Using flatmappable ‘actions’
• Database actions in Slick 3.0
๏ Actions in FP: side effects
• A lightweight database action implementation
• Database actions in Slick 3.0 revisited
functional stream processing
• Remember we wanted to let db manipulation take part in the purely functional world of stream computing
• Hence we need a flatmappable way of dealing with side effects
Functional stream processing
• In Scala we’re used to flatmappables for
• Null values
• Exceptions
• Latency
• Collections
• But not for
• Input / Output
• Reading from an environment
• Mutating state
I.e. managing side effects
The power of semi colons!
Great for side effects but not streamable
What’s so great about supporting flatmap?
• Put building blocks together into bigger building blocks
• Alternate outcomes are transparantly propagated through parts to the whole
• … depending on the instance
Chaining outcomes in Swift
• Pure functions don’t have side effects
• I.e. a function evaluation has always the same value
• (a.k.a. Substitution principle, referential transparency)
• But a program without f.i. IO is useless
How does Haskell handle side effects?
• Haskell is a pure lazy language
• There’s no ; operator to evaluate sequentially
• To do IO so called actions are used: recognisable from the their type
So writing hello world is in Haskell not the first thing you do
Spot the side effect
def f : Unit => A
def g: A => Unit
f
A
?
g
A
?
Actions• A value of type IO t is an action that, when
performed, may do some input/output before delivering a result of type t.
• Actions are also called computations
• Evaluating an action has no effect; performing an action has effect.
• Actions can be put together into bigger actionsSource: Simon Peyton Jones - Lazy functional
programming for real
Function declaration: type
Function implementation
Haskell to Scala translation
Actions…
Our building blocks
Chaining actions into a programme
The type of >>= : () means: infix operator (ignore the ‘ accent)
flatmap in Scala meaning is similar to ; in Scala
Chaining actions into a programme
In the FP world this is called ‘composition’; ‘composing’ 3 flatmappables into a composite
action
type IO a = World -> (a, World)
Ignore the result of a previous action
Pronounced as andThen
• Database actions in Slick 3.0
• Actions in FP: side effects
๏ A lightweight database action implementation
• Database actions in Slick 3.0 revisited
Resource mgmt with functions
In the early days of the Spring framework it provided this as
JdbcTemplate
From: 2012 talk by Paul Chuisano
Let’s flatmap that
[coding]
Putting actions together into bigger actions
The Reader flatmappable
Anything that takes a context like object to create results is a candidate for a Reader type
of flat mappable
• Database actions in Slick 3.0
• Actions in FP: side effects
• A lightweight database action implementation
๏ Database actions in Slick 3.0 revisited
DBIO[A] (non streaming)
StreamingDBIO
Type of materialised result
Read and/or Write side effect for master/slave
routing
Type of streamed elements
Client code is run in client execution context DB code is run against dedicated thread pool
Separated!
Resources• Stefan Zeigers talk at Scala Days San Fransisco
• slides http://slick.typesafe.com/talks/scaladays2015sf/Reactive_Slick_for_Database_Programming.pdf
• video https://www.parleys.com/tutorial/reactive-slick-database-programming
• Paul Chiusano and Rúnar Bjarnason - Functional programming in Scala
• Activator template hello-slick-3.0
• Let’s take a short break and start hacking!
• The idea is to enhance a scala application that uses Slick and deploy it to Heroku to demonstrate.
• If you’ve forwarded your github handle I’ll add you to the project repo.
• The repo code is for todays use only. Please be responsible and don’t put it on the public internet somewhere.