Edson Hilios
September 29, 2017
750

# Either, Some or None: An introduction to monadic structures and functional programming

We will discuss and understand the monadic structures, going through the most important monads, it's operations and main advantages of the functional programming using Scala, Kotlin, Swift, a little bit of Clojure and why not JavaScript.

During the talk we should also realize why concepts as laziness and immutable data are the cornerstone of high throughput threaded systems and how its guarantee reliability and performance.

By the end of the day you should know by heart the main monads and how to use them solve different day-by-day problems and deeply in love with functional programming.

## Edson Hilios

September 29, 2017

## Transcript

1. ### Either, Some or None An introduction to monadic structures and

functional programming September 29th, São Paulo, Brazil #monads #functional_programming #category_theory_applied

at _____

4. ### Why talk about monads? • Implemented in major modern languages:

• Provides simple ways of express complex computation; • They are hard to read about because of specific vocabulary;
5. ### Goals • A soft theory of Monad • Monodic structures

and operations • Some common monads • Real use cases • Recap

7. ### If this than that Monads express decisions about how and

which conditions a software should execute. It allows you to handle and route different inputs/outputs without repeating yourself.

data
9. ### Useful monad properties • Composable • Polymorphic • Immutable •

Lazily evaluated

• Group
11. ### The 3 Monadic laws trait Monoid[A] { // The identity

def get[A]: A // The functor def map[B](f: A => B): Monad[B] // The bind def flatMap[B](f: A => Monad[B]): Monad[B] } Scala

13. ### The optional pattern val aString: String = "Hello, world!" val

len: Int = aString.length Scala
14. ### The optional pattern val aString: String = null val len:

Int = aString.length //=> java.lang.NullPointerException Scala
15. ### The optional pattern val maybeString: Option[String] = Some("Hello, world!") val

maybeLen: Int = maybeString.map(_.length).getOrElse(-1) Scala
16. ### The optional pattern val maybeString: String? = "Hello, world!" val

maybeLen = maybeString?.length ?: -1 Kotlin
17. ### The optional pattern let maybeString: String? = "Hello, world!" let

maybeLen = maybeString.length ?? -1 Swift
18. ### The continuation monad (some-> (maybe-a-result from-db) (then-do-something) (then-another) (and-finishes)) Clojure

Execute if last result is not nil It will return the value or nil Pass the result to the next fn
19. ### Call me Maybe s::String -> Maybe String s "" =

Nothing s x = Just x Haskell
20. ### The identity monad val query: Option[String] = Option(myNullableOutput) query match

{ case Some(q) => myTable.filter(_.name == q) case None => myTable.all() } Scala
21. ### Exception handling val maybeAnOperation: Try[Any] = Try { potentiallyHarmfulOperation() }

match { case Success(s: Any) => ??? case Failure(e: ArithmeticException) => ??? case Failure(e: Exception) => ??? } Scala
22. ### The functor def firstFunctor(x: Any): Try[String] = ??? def secondFunctor(y:

String): Try[Int] = ??? def thirdFunctor(z: Int): Try[MyType] = ??? maybeAnException .map(firstFunctor) .map(secondFunctor) .map(thirdFunctor) Try[Any] Try[Try[String]] Try[Try[Try[Int]]] Try[Try[Try[Try[MyType]]]] Scala
23. ### Bind operations def firstFunctor(x: Any): Try[String] = ??? def secondFunctor(y:

String): Try[Int] = ??? def thirdFunctor(z: Int): Try[MyType] = ??? maybeAnException .flatMap(firstFunctor) .flatMap(secondFunctor) .flatMap(thirdFunctor) Try[Any] Try[String] Try[Int] Try[MyType] Scala
24. ### Either this or that val json: Either[JsError, JsSuccess] = parse("""{"foo":

"bar"}""") json match { case JsSuccess(o) => println("OK") case JsError(err) => println(err.list) } Scala
25. ### Applicative functor def nonEmpty(s: Option[String]): Validated[Invalid, Valid] val isValid =

( nonEmpty("Some string") |@| nonEmpty("") |@| nonEmpty("Other str") |@| nonEmpty(null) ).fold(left => false, rigth => true) Cats
26. ### Valid Invalid("Cannot be blank") Valid Invalid("Cannot be null") Holomorphism {

"1": "Some string", "2": "", "3": "Other str", "4": null } JSON
27. ### Right or left identity def httpRequest(input: Either[Valid, Invalid]): HttpResponse =

input.fold( left => HttpResponse(StatusCodes.BadRequest), right => HttpResponse(StatusCodes.OK)) Scala
28. ### Future pattern (def eventualString (future (Thread/sleep 1000) "Hello, async!") @eventualString

;; => Returns Hello, async after 1s Clojure

async!" } map { result => result.length } eventualLength.run() // => Eventually returns 13 after 1s Scalaz

side effects case Failure(e) => // Do something on failure } Scalaz
32. ### It's all about Promises let eventualResponse = new Promise(function() {

setTimeout(() => resolve("Hello, world!"), 2000) }) eventualResponse .then(applyFunctor) .then(msg => console.log("Apply side-effects!")) ES2016
33. ### The observable pattern val observer = new Observer[Any] { def

onNext(elem: Any): Future[Ack] = Continue def onError(ex: Throwable): Unit = ex.printStackTrace() def onComplete(): Unit = println("Completed") } Monix
34. ### Observable operations • Group by batches or time intervals; •

Fork and merge streams; • Handle errors and apply retry strategies; • Delay execution and back-pressure.
35. ### Becoming reactive Rx.Observable.webSocket('ws://localhost:8000') .retryWhen((errors) => { return Rx.Observable.timer(5000) // retry

in 5 secs }) .groupBy((msg) => msg.category) .throttle(1000) // One message per sec and discard the rest .subscribe((msgs) => console.log(msgs)) ES2016
36. ### Recapping the monads • Maybe is useful to handle failures

scenarios; • Either for validations and data deserialization; • Future lets you create asynchronous operations;
37. ### Monads FTW • SwiftZ and Runes for Swift • Kathegory

for Kotlin • Scalaz, Cats and Monix for Scala • ReactiveX (aka Rx): Scala, C#, C++, Kotlin, Swift and many others