Slide 1

Slide 1 text

Monads you are already using in prod Tejas Dinkar nilenso

Slide 2

Slide 2 text

about.me • Hi, I’m Tejas • Nilenso: Partner • twitter: tdinkar • github: gja

Slide 3

Slide 3 text

Serious Pony

Slide 4

Slide 4 text

Online Abuse

Slide 5

Slide 5 text

Trouble at the Koolaid Point http://seriouspony.com/trouble-at-the-koolaid-point/ https://storify.com/adriarichards/telling-my-troll-story-because- kathy-sierra-left-t

Slide 6

Slide 6 text

If you think you understand Monads, you don't understand Monads.

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

This talk is inaccurate and will make a mathematician cry

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

Goal of this talk For you to say “Oh yeah, I’ve used that hack”

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

Monads • Programmable Semicolons • Used to hide plumbing away from you • You can say Monads in almost any sentence and people will think you are smart

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

Values Value

Slide 15

Slide 15 text

Monads Value Box

Slide 16

Slide 16 text

Mysore Masala Monad M onad Value

Slide 17

Slide 17 text

Monads Value Box

Slide 18

Slide 18 text

Monads • Monads define two functions • return takes a value and puts it in a box • bind takes a box & function f, returning f(value) • it is expected that the function returns a box

Slide 19

Slide 19 text

Value Value Another Value Value Function return bind

Slide 20

Slide 20 text

Our Function Signatures Value f(value)

Slide 21

Slide 21 text

Some math (√4) + 5

Slide 22

Slide 22 text

Some math (√4) + 5 3 or 7!

Slide 23

Slide 23 text

Value 4

Slide 24

Slide 24 text

Monad [4]

Slide 25

Slide 25 text

[alive, dead]

Slide 26

Slide 26 text

ruby! x = [1, 2, 3] y = x.map { |x| x + 1 } # y = [2, 3, 4]

Slide 27

Slide 27 text

return Value Value return

Slide 28

Slide 28 text

return def m_return(x) [x] end # m_return(4) => [4]

Slide 29

Slide 29 text

The functions Value f(value)

Slide 30

Slide 30 text

Square Root fn def sqrt(x) s = Math.sqrt(x) [s, -s] end # sqrt(4) => [2, -2]

Slide 31

Slide 31 text

Increment Fn def inc_5(x) [x + 5] end # inc_5(1) => [6]

Slide 32

Slide 32 text

Bind Functions Another Value Value Function bind

Slide 33

Slide 33 text

Bind Function x = m_return(4) y = x.????? { |p| sqrt(p) } # I want [-2, 2]

Slide 34

Slide 34 text

Bind Function x = m_return(4) y = x.map {|p| sqrt(p) } # y => [[2, -2]] # ^—— Box in a box?

Slide 35

Slide 35 text

Bind Function x = m_return(4) y = x.mapcat {|p| sqrt(p) } # y => [2, -2]

Slide 36

Slide 36 text

Putting it together m_return(4) .mapcat {|p| sqrt(p)} .mapcat {|p| inc_5(p)} # => [3, 7]

Slide 37

Slide 37 text

You have invented the List Monad, used to model non-determinism Congrats

Slide 38

Slide 38 text

Turtles all the way down

Slide 39

Slide 39 text

A small constraint • Let’s do a bit of a self imposed constraint on this • Functions must return either 0 or 1 elements • (we’ll only model positive integers here)

Slide 40

Slide 40 text

return - stays the same

Slide 41

Slide 41 text

bind - stays the same x = m_return(4) y = x.mapcat { |p| inc_5(p) } # y => 9

Slide 42

Slide 42 text

Square Root Fn def sqrt(x) if (x < 0) return [] #error else [Math.sqrt(x)] end end # sqrt(4) => [2] # sqrt(-1) => []

Slide 43

Slide 43 text

Describe in English There is a list passed to each step Maybe this list has just one element, or Maybe it has none

Slide 44

Slide 44 text

No content

Slide 45

Slide 45 text

The Maybe Monad • The intent is to short circuit computation • The value of the `box’ is None, or Just(Value) • You can think of it as a type-safe nil / null

Slide 46

Slide 46 text

try def try(x, f) if x == nil return f(x) else return nil end end # 4.try { |x| x + 5 } => 9 # nil.try {|x| x + 5 } => nil

Slide 47

Slide 47 text

No content

Slide 48

Slide 48 text

Let’s start over • The Monad Laws • Left Identity • Right Identity • Associativity

Slide 49

Slide 49 text

Left Identity m_return(a).bind(f) == f(a)

Slide 50

Slide 50 text

Right Identity m.bind(m_return) == m

Slide 51

Slide 51 text

Associativity m.bind(f).bind(g) == m.bind(x -> f(x).bind(g))

Slide 52

Slide 52 text

Store Computation

Slide 53

Slide 53 text

The State Monad • Rest of the world - State Machine (sorta) • The value inside the box f(state) => [r new-state] • Particularly useful in pure languages like Haskell • Let’s build a stack

Slide 54

Slide 54 text

The functions Value f(value)

Slide 55

Slide 55 text

The functions (f(value) state) [new-value, new-state]

Slide 56

Slide 56 text

push def push(val) lambda { |state| new_state = state.push(val) [value, new_state] } end

Slide 57

Slide 57 text

pop def pop() lambda { |state| val = state.pop() [val, state] } end

Slide 58

Slide 58 text

def double_top() lambda { |state| top = state.pop() [2 * top, state.push(2*top)] } end double_top

Slide 59

Slide 59 text

return def m_return(x) lambda { |state| [x, state] } end

Slide 60

Slide 60 text

bind def bind(mv, f) lambda { |state| v, temp_state = mv(state) state_fn = f(v) state_fn(temp_state) } end

Slide 61

Slide 61 text

example # Not working code ! m_return(4) .bind(a -> push(a)) .bind(b -> push(b + 1)) .bind(c -> double_top()) .bind(d -> sum_top2()) .bind(e -> pop())

Slide 62

Slide 62 text

No content

Slide 63

Slide 63 text

Associativity m.bind(f).bind(g) == m.bind(x => f(x).bind(g))

Slide 64

Slide 64 text

turn this # Not working code ! m_return(4) .bind(a -> push(a)) .bind(b -> push(b + 1)) .bind(c -> double_top()) .bind(d -> sum_top2()) .bind(e -> pop())

Slide 65

Slide 65 text

into this m_return(4) .bind(a -> push(a) .bind(b -> push(b + 1) .bind(c -> double_top() .bind(d -> sum_top() .bind(e -> pop())))))

Slide 66

Slide 66 text

done with ruby

Slide 67

Slide 67 text

imagine # Not working code state_monad { a <- m_return(4) b <- push(a) c <- push(b + 1) d <- double_top() e <- sum_top2() pop() }

Slide 68

Slide 68 text

Back to List m_return(4) .mapcat {|p| sqrt(p)} .mapcat {|p| inc_5(p)} # => [3, 7]

Slide 69

Slide 69 text

Back to List m_return(4) .mapcat {|a| sqrt(a) .mapcat {|b| inc_5(b)}} # => [3, 7]

Slide 70

Slide 70 text

Back to List list_monad { a <- m_return(4) b <- sqrt(a) c <- inc_5(b) c }

Slide 71

Slide 71 text

On to Clojure • this is an example from clojure.net • the state is a vector containing every function we’ve called so far

Slide 72

Slide 72 text

(defn inc-s [x] (fn [state] [(inc x) (conj state :inc)]))

Slide 73

Slide 73 text

in clojure (defn inc-s [x] (fn [state] [(inc x) (conj state :inc)])) (defn do-things [x] (domonad state-m [a (inc-s x) b (double-s a) c (dec-s b) d (dec-s c)] d)) ! ((do-things 7) []) => [14 [:inc :double :dec :dec]]

Slide 74

Slide 74 text

state monad in Clojure (defmonad state-m "Monad describing stateful computations. The monadic values have the structure (fn [old-state] [result new-state])." [m-result (fn m-result-state [v] (fn [s] [v s])) m-bind (fn m-bind-state [mv f] (fn [s] (let [[v ss] (mv s)] ((f v) ss)))) ])

Slide 75

Slide 75 text

state monad in Haskell inc = state (\st -> let st' = st +1 in (st’,st')) inc3 = do x <- inc y <- inc z <- inc return z

Slide 76

Slide 76 text

Finally, IO

Slide 77

Slide 77 text

IOMonad • rand-int(100) is non deterministic !

Slide 78

Slide 78 text

ay-yo

Slide 79

Slide 79 text

IOMonad • rand-int(100) is non deterministic • rand-int(100, seed = 42) is deterministic • monadic value: f(world) => [value, world-after-io]

Slide 80

Slide 80 text

IOMonad • puts() just `appends to a buffer’ in the real world • How does gets() return different strings? • gets() returns a fixed value based on the `world’

Slide 81

Slide 81 text

Image Credits http://www.myfoodarama.com/2010/11/masala- dosa.html http://www.clojure.net/2012/02/10/State/ http://www.cafepress.com/ +no_place_like_home_ruby_slippers_3x5_area_rug, 796646161 http://www.netizens-stalbans.co.uk/installs-and- upgrades.html.htm http://www.hpcorporategroup.com/what-is-the-life- box.html

Slide 82

Slide 82 text

Thank You MANY QUESTIONS? VERY MONAD SO FUNCTIONAL Y NO CLOJURE? [email protected] @tdinkar WOW WOW WOW MUCH EASY SUPER SIMPLE