Slide 1

Slide 1 text

Patterns vs Abstractions Code Motivating Examples Applications SCALAZ BY EXAMPLE Figure: Credit http://www.flickr.com/photos/slambo_42 Susan Potter @SusanPotter ScalaPDX January 2014 https://github.com/mbbx6spp/funalgebra 1

Slide 2

Slide 2 text

PATTERNS VS ABSTRACTIONS

Slide 3

Slide 3 text

Patterns vs Abstractions Code Motivating Examples Applications OO PATTERNS VS FP ABSTRACTIONS → More (Subjective -> Objective) → More (Ambiguous -> Precise) → "Fluffy" Interfaces -> Generic Functions 3

Slide 4

Slide 4 text

Patterns vs Abstractions Code Motivating Examples Applications LAYING BRICKS 4

Slide 5

Slide 5 text

Patterns vs Abstractions Code Motivating Examples Applications WARNING → Abstract Algebra -> (Continuous, Infinite) → Real World -> usually (Discrete, Finite) 5

Slide 6

Slide 6 text

CODE

Slide 7

Slide 7 text

Patterns vs Abstractions Code Motivating Examples Applications EXAMPLE UNIX PIPE 1 find . -name "*.rb" \ 2 | xargs egrep "#.*?TODO:" \ 3 | wc -l Character-based, through file descriptors 7

Slide 8

Slide 8 text

Patterns vs Abstractions Code Motivating Examples Applications EXAMPLE FUNCTION COMPOSITION 1 (length . mapToUpper . sanitize) input Value based, through functions 8

Slide 9

Slide 9 text

Patterns vs Abstractions Code Motivating Examples Applications VALUING VALUES IN REAL WORLD 1 final case class Somefink[A](a: A) extends PossiblyMaybe[A] 2 final case object Nowt extends PossiblyMaybe[ Nothing] 3 4 sealed trait PossiblyMaybe[+A] 5 object PossiblyMaybeOps { 6 def noneDefault[A](pm: PossiblyMaybe[A])(a: A): A = pm match { 7 case Somefink(x) => x 8 case _ => a 9 } 10 } Note _ in second match, caters for nulls with Java interop 9

Slide 10

Slide 10 text

Patterns vs Abstractions Code Motivating Examples Applications START WITH "CLOSED" MODEL 1 final case object Production extends Env 2 final case object Staging extends Env 3 final case class QA(n: Int) extends Env 4 final case class Dev(u: String) extends Env 5 final case object Integration extends Env 6 sealed trait Env 7 object Env { 8 /* companion object code... "instances" */ 9 } 10

Slide 11

Slide 11 text

Patterns vs Abstractions Code Motivating Examples Applications EXTEND VIA ADHOC POLYMORPHISM 1 // companion object for Env 2 object Env { 3 // default "instances" over type Env 4 // for typeclasses below 5 implicit val EnvRead: Read[Env] = ??? 6 implicit val EnvShow: Show[Env] = ??? 7 8 // maybe you want ability to use 9 // one of two implementations of Order[Env] 10 // as well as Equal[Env]. Anyone? 11 implicit val EnvOrder: Order[Env] = ??? 12 implicit val EnvEqual: Equal[Env] = ??? 13 } 11

Slide 12

Slide 12 text

MOTIVATING EXAMPLES

Slide 13

Slide 13 text

Patterns vs Abstractions Code Motivating Examples Applications WHY USE IO MONAD? → Construct I/O "programs" from parts → Control error handling at runtime → Much easier to test various scenarios → And more … 13

Slide 14

Slide 14 text

Patterns vs Abstractions Code Motivating Examples Applications IO: "CONSTRUCTION" (1/2) 1 import scalaz._, Scalaz._, effect._ 2 3 trait MyApp { 4 def start(env: Env): IO[Unit] 5 } 6 7 def readConfig(env: Env): 8 IO[BufferedSource] = ??? 9 10 def parseConfig(bs: BufferedSource): 11 IO[Map[String, String]] = ??? 12 13 def setupMyApp(pool: ConnectionPool): 14 IO[MyApp] = ??? 14

Slide 15

Slide 15 text

Patterns vs Abstractions Code Motivating Examples Applications IO: "CONSTRUCTION" (2/2) 1 def initialize(env: Env): IO[MyApp] = for { 2 bs <- readConfig(env) 3 map <- parseConfig(bs) 4 app <- setupMyApp(pool) 5 } yield app 6 7 def withCookieSessions(app: MyApp): 8 IO[MyApp] = ??? 9 10 def withServerSessions(app: MyApp): 11 IO[MyApp] = ??? 12 13 def run(env: Env): IO[Unit] = for { 14 app <- initialize(env) 15 app2 <- withCookieSessions(app) 16 } yield app2.start(env) 15

Slide 16

Slide 16 text

Patterns vs Abstractions Code Motivating Examples Applications IO: ERROR HANDLING (1/2) 1 import scalaz._, Scalaz._, effect._ 2 3 def process(rq: Request): 4 IO[Response] = ??? 5 6 def showErrorTrace: 7 Throwable => IO[Response] = ??? 8 9 def logErrorTrace: 10 Throwable => IO[Response] = ??? 11 12 def reportErrorTrace: 13 Throwable => IO[Response] = ??? 16

Slide 17

Slide 17 text

Patterns vs Abstractions Code Motivating Examples Applications IO: ERROR HANDLING (2/2) 1 def handleReq(rq: Request)(implicit e: Env) = 2 env match { 3 case Production => 4 process(rq).except(logErrorTrace) 5 6 case Staging => 7 process(rq).except(reportErrorTrace) 8 9 case _ => 10 process(rq).except(showErrorTrace) 11 } 17

Slide 18

Slide 18 text

Patterns vs Abstractions Code Motivating Examples Applications IO: TESTING EXAMPLE 1 import scala.io.{BufferedSource , Codec} 2 import scalaz._, Scalaz._, effect._ 3 import java.io.{ByteArrayInputStream => JBAIS } 4 5 implicit val codec = Codec("UTF-8") 6 IO(new BufferedSource(new JBAIS("""{ 7 "host": "localhost", 8 "port": "5432", 9 "driver": "my.awesome.PostgresDriver", 10 "protocol": "postgres", 11 "name": "contactsdb" 12 }""".getBytes(codec.charSet)))) 18

Slide 19

Slide 19 text

Patterns vs Abstractions Code Motivating Examples Applications IO: TESTING EXAMPLE 1 // At the end of the universe we then do... 2 run(env).unsafePerformIO 3 4 // or whatever your starting point is, e.g. 5 main(args).unsafePerformIO 6 7 // only ONCE... most of the time ;) 19

Slide 20

Slide 20 text

Patterns vs Abstractions Code Motivating Examples Applications SAME TYPE, MANY "INTERFACES" A type defined as a Monad (think: (>>=)) can also be used as: → A Functor (think: fmap) → An Applicative (think: <*>, pure) → And possibly others though not necessarily 20

Slide 21

Slide 21 text

APPLICATIONS

Slide 22

Slide 22 text

Patterns vs Abstractions Code Motivating Examples Applications KNOWN USES → Monoids: Accumulators are everywhere, almost → Functors: Lots of uses with common and user defined types → Monads: Effects, "linear happy path", and more → Applicatives: "validations", safer Java interop, and more → More: e.g. Arrows, Zippers, Lenses, Tagged Types, … 22

Slide 23

Slide 23 text

Patterns vs Abstractions Code Motivating Examples Applications THINKING ALGEBRAICALLY → Properties: property based testing: quickcheck, scalacheck → Data Types: start closed, extend using "type classes", dependent types, etc when relevant → Abstractions: build small building blocks, use motar to build solid walls → Dist Systems: using algebraic abstractions, properties to build more useful distributed systems 23

Slide 24

Slide 24 text

Patterns vs Abstractions Code Motivating Examples Applications QUESTIONS? 24